1N/A/*************************************************************************** 1N/A * Copyright (C) 2003 David Zeuthen, <david@fubar.dk> 1N/A * Licensed under the Academic Free License version 2.1 1N/A * This program is free software; you can redistribute it and/or modify 1N/A * it under the terms of the GNU General Public License as published by 1N/A * the Free Software Foundation; either version 2 of the License, or 1N/A * (at your option) any later version. 1N/A * This program is distributed in the hope that it will be useful, 1N/A * but WITHOUT ANY WARRANTY; without even the implied warranty of 1N/A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1N/A * GNU General Public License for more details. 1N/A * You should have received a copy of the GNU General Public License 1N/A * along with this program; if not, write to the Free Software 1N/A * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 1N/A **************************************************************************/ 1N/A * @defgroup DeviceInfo Device Info File Parsing 1N/A * @ingroup HalDaemon 1N/A * @brief Parsing of device info files 1N/A/** Maximum nesting depth */ 1N/A/** Maximum amount of CDATA */ 1N/A/** Max length of property key */ 1N/A/** Possible elements the parser can process */ 1N/A /** Not processing a known tag */ 1N/A /** Processing a deviceinfo element */ 1N/A /** Processing a device element */ 1N/A /** Processing a match element */ 1N/A /** Processing a merge element */ 1N/A /** Processing an append element */ 1N/A /** Processing a prepend element */ 1N/A /** Processing a remove element */ 1N/A /** Processing a clear element */ 1N/A /** Processing a spawn element */ 1N/A/** What and how to merge */ 1N/A /** Name of file being parsed */ 1N/A /** Parser object */ 1N/A /** Device we are trying to match*/ 1N/A /** Buffer to put CDATA in */ 1N/A /** Current length of CDATA buffer */ 1N/A /** Current depth we are parsing at */ 1N/A /** Element currently being processed */ 1N/A /** Stack of elements being processed */ 1N/A /** #TRUE if parsing of document have been aborted */ 1N/A /** Depth of match-fail */ 1N/A /** #TRUE if all matches on prior depths have been OK */ 1N/A /** When merging, the key to store the value in */ 1N/A /** Set to #TRUE if a device is matched */ 1N/A/** Resolve a udi-property path as used in .fdi files. 1N/A * Examples of udi-property paths: 1N/A * @param source_udi UDI of source device 1N/A * @param path The given path 1N/A * @param udi_result Where to store the resulting UDI 1N/A * @param udi_result_size Size of UDI string 1N/A * @param prop_result Where to store the resulting property name 1N/A * @param prop_result_size Size of property string 1N/A * @return TRUE if and only if the path resolved. 1N/A /*HAL_INFO (("Looking at '%s' for udi='%s'", path, source_udi));*/ 1N/A /* Split up path into ':' tokens */ 1N/A /* Detect trivial property access, e.g. path='foo.bar' */ 1N/A /* Start with the source udi */ 1N/A /*HAL_INFO (("tokens[%d] = '%s'", i, tokens[i]));*/ 1N/A /* process all but the last tokens as UDI paths */ 1N/A /* Check for indirection */ 1N/A /*HAL_INFO (("new_udi = '%s' (from indirection)", newudi));*/ 1N/A /*HAL_INFO (("new_udi = '%s'", curtoken));*/ 1N/A HAL_INFO (("success = '%s'", rc ? "yes" : "no")); 1N/A HAL_INFO (("udi_result = '%s'", udi_result)); 1N/A HAL_INFO (("prop_result = '%s'", prop_result)); 1N/A/* Compare the value of a property on a hal device object against a string value 1N/A * and return the result. Note that this works for several types, e.g. both strings 1N/A * and integers - in the latter case the given right side string will be interpreted 1N/A * The comparison might not make sense if you are comparing a property which is an integer 1N/A * against a string in which case this function returns FALSE. Also, if the property doesn't 1N/A * exist this function will also return FALSE. 1N/A * @param d hal device object 1N/A * @param key Key of the property to compare 1N/A * @param right_side Value to compare against 1N/A * @param result Pointer to where to store result 1N/A * @return TRUE if, and only if, the comparison could take place 1N/A /* explicit fallthrough */ 1N/A /* explicit blank since this doesn't make sense */ 1N/A/** Called when the match element begins. 1N/A * @param pc Parsing context 1N/A * @return #FALSE if the device in question didn't 1N/A * match the data in the attributes 1N/A /* match string property */ 1N/A /*HAL_INFO(("Checking that key='%s' is a string that " 1N/A "equals '%s'", key, value)); */ 1N/A /*HAL_INFO (("*** string match for key %s", key));*/ 1N/A /* match integer property */ 1N/A /** @todo Check error condition */ 1N/A /*HAL_INFO (("Checking that key='%s' is a int that equals %d", 1N/A /* match integer property */ 1N/A /** @todo Check error condition */ 1N/A /*HAL_INFO (("Checking that key='%s' is a int that equals %d", 1N/A /* match string property */ 1N/A /*HAL_INFO (("Checking that key='%s' is a bool that equals %s", 1N/A key, value ? "TRUE" : "FALSE"));*/ 1N/A /*HAL_INFO (("*** bool match for key %s", key));*/ 1N/A /* explicit fallthrough */ 1N/A for (i = 0;
str[i] !=
'\0'; i++) {
1N/A if (((
unsigned char)
str[i]) >
0x7f)
1N/A /*HAL_INFO (("d->udi='%s', prop_to_check='%s'", d->udi, prop_to_check));*/ 1N/A /*HAL_INFO (("is_absolute=%d, should_be=%d, path='%s'", is_absolute_path, should_be_absolute_path, path));*/ 1N/A/** Called when the merge element begins. 1N/A * @param pc Parsing context 1N/A /* match string property */ 1N/A /* match string property */ 1N/A /* match string property */ 1N/A /* match string property */ 1N/A /* match string property */ 1N/A /* match string property */ 1N/A /* copy another property */ 1N/A/** Called when the append or prepend element begins. 1N/A * @param pc Parsing context 1N/A /* append to a string */ 1N/A /* append to a string list*/ 1N/A /* copy another property */ 1N/A/** Called when the spawn element begins. 1N/A * @param pc Parsing context 1N/A/** Called when the remove element begins. 1N/A * @param pc Parsing context 1N/A /* remove from strlist */ 1N/A/** Called when the clear element begins. 1N/A * @param pc Parsing context 1N/A/** Abort parsing of document 1N/A * @param pc Parsing context 1N/A /* Grr, expat can't abort parsing */ 1N/A/** Called by expat when an element begins. 1N/A * @param pc Parsing context 1N/A * @param el Element name 1N/A for (i = 0; i < pc->depth; i++) 1N/A for (i = 0; attr[i]; i += 2) { 1N/A printf(" %s='%s'", attr[i], attr[i + 1]); 1N/A printf(" curelem=%d\n", pc->curelem); 1N/A "inside <device> and <match>",
1N/A /* don't bother checking if matching at lower depths failed */ 1N/A "inside <device> and <match>",
1N/A /*HAL_INFO(("No merge!")); */ 1N/A "inside <device> and <match>",
1N/A /*HAL_INFO(("No merge!")); */ 1N/A "inside <device> and <match>",
1N/A /*HAL_INFO(("No merge!")); */ 1N/A "inside <device> and <match>",
1N/A /*HAL_INFO(("No merge!")); */ 1N/A "inside <device> and <match>",
1N/A /*HAL_INFO(("No merge!")); */ 1N/A "inside <deviceinfo>",
1N/A "a top-level element",
1N/A /* Move from temporary to global device store */ 1N/A/** Called by expat when an element ends. 1N/A * @param pc Parsing context 1N/A * @param el Element name 1N/A/* printf(" curelem=%d\n", pc->curelem);*/ 1N/A /* As soon as we are merging, we have matched the device... */ 1N/A /* match integer property */ 1N/A /** @todo FIXME: Check error condition */ 1N/A /* match integer property */ 1N/A /** @todo FIXME: Check error condition */ 1N/A /* As soon as we are appending, we have matched the device... */ 1N/A /* As soon as we are prepending, we have matched the device... */ 1N/A /* covers <remove key="foobar" type="strlist">blah</remove> */ 1N/A /* only allow <remove key="foobar"/>, not <remove key="foobar">blah</remove> */ 1N/A HAL_INFO ((
"Spawning new device object '%s' caused by <spawn> on udi '%s'",
1N/A /* maintain curelem */ 1N/A /* maintain pc->match_ok */ 1N/A/** Called when there is CDATA 1N/A * @param pc Parsing context 1N/A * @param s Pointer to data 1N/A * @param len Length of data 1N/A/** Process a device information info file. 1N/A * @param dir Directory file resides in 1N/A * @param filename File name 1N/A * @param device Device to match on 1N/A * @return #TRUE if file matched device and information 1N/A /*HAL_INFO(("analyzing file %s", buf));*/ 1N/A /* open file and read it into a buffer; it's a small file... */ 1N/A /* initialize parsing context */ 1N/A /* TODO: reuse parser 1N/A /*printf("XML_Parse rc=%d\r\n", rc); */ 1N/A /* error parsing document */ 1N/A /* document parsed ok */ 1N/A/** Scan all directories and subdirectories in the given directory and 1N/A * process each *.fdi file 1N/A * @param d Device to merge information into 1N/A * @return #TRUE if information was merged 1N/A /*HAL_INFO(("scan_fdi_files: Processing dir '%s'", dir));*/ 1N/A /*HAL_INFO (("Full path = %s", full_path));*/ 1N/A /* Mmm, d_type can be DT_UNKNOWN, use glib to determine 1N/A /*HAL_INFO (("scan_fdi_files: Processing file '%s'", filename));*/ 1N/A /* Directory; do the recursion thingy but not 1N/A for (; i >= 0; i--) {
1N/A/** Search the device info file repository for a .fdi file to merge 1N/A * more information into the device object. 1N/A * @param d Device to merge information into 1N/A * @return #TRUE if information was merged