hal/hald device_info.c,1.19,1.20
David Zeuthen
david at freedesktop.org
Thu Feb 3 14:09:49 PST 2005
Update of /cvs/hal/hal/hald
In directory gabe:/tmp/cvs-serv17509/hald
Modified Files:
device_info.c
Log Message:
2005-02-03 David Zeuthen <davidz at redhat.com>
* hald/device_info.c (handle_match): Handle contains and
contains_ncase for strlist properties. Also allow <merge key="foo"
type="strlist> blah</merge> to create a new strlist; possibly
destroy an existing strlist with the single elem 'blah'.
(handle_append_prepend): Renamed from handle_append since it also
covers prepend now and supports strlist's.
(handle_remove): New function to cover <remove key="foobar"
type="strlist">blah</remove> (removes element 'blah' from strlist
'foobar') and <remove key="foobar"/> to completely remove a
property.
(start): Support <prepend> on both strings and strlists. Support
<remove>
(end): Support the new directives.
Here is an example of the new directives; I'm pasting it here
so it's handy when the spec needs to be updated. Oh, and for
when I get around to adding test cases for this :-)
<append key="bat0" type="string">foo0</append>
<merge key="baz0" type="strlist">foz0</merge>
<append key="bar0" type="strlist">foo0</append>
<append key="bar0" type="strlist">foo1</append>
<append key="bar0" type="strlist">foo2</append>
<append key="bar0" type="strlist">foo3</append>
<prepend key="dat0" type="string">foo0</prepend>
<merge key="daz0" type="strlist">foz0</merge>
<prepend key="dar0" type="strlist">foo0</prepend>
<prepend key="dar0" type="strlist">foo1</prepend>
<prepend key="dar0" type="strlist">foo2</prepend>
<prepend key="dar0" type="strlist">foo3</prepend>
<remove key="t1" type="strlist">val1</remove>
<remove key="t2"/>
<remove key="t3"/>
Index: device_info.c
===================================================================
RCS file: /cvs/hal/hal/hald/device_info.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- device_info.c 31 Jan 2005 20:06:39 -0000 1.19
+++ device_info.c 3 Feb 2005 22:09:47 -0000 1.20
@@ -78,6 +78,12 @@
/** Processing an append element */
CURELEM_APPEND = 4,
+
+ /** Processing an prepend element */
+ CURELEM_PREPEND = 5,
+
+ /** Processing an prepend element */
+ CURELEM_REMOVE = 6
};
/** What and how to merge */
@@ -88,7 +94,9 @@
MERGE_TYPE_INT32,
MERGE_TYPE_UINT64,
MERGE_TYPE_DOUBLE,
- MERGE_TYPE_COPY_PROPERTY
+ MERGE_TYPE_COPY_PROPERTY,
+ MERGE_TYPE_STRLIST,
+ MERGE_TYPE_REMOVE
};
/** Parsing Context
@@ -538,18 +546,33 @@
needle = attr[3];
- if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
- return FALSE;
-
- if (hal_device_has_property (d, prop_to_check)) {
- const char *haystack;
-
- haystack = hal_device_property_get_string (d, prop_to_check);
- if (needle != NULL && haystack != NULL && strstr (haystack, needle)) {
- contains = TRUE;
+ if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRING) {
+ if (hal_device_has_property (d, prop_to_check)) {
+ const char *haystack;
+
+ haystack = hal_device_property_get_string (d, prop_to_check);
+ if (needle != NULL && haystack != NULL && strstr (haystack, needle)) {
+ contains = TRUE;
+ }
+
}
+ } else if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRLIST &&
+ needle != NULL) {
+ GSList *i;
+ GSList *value;
+ value = hal_device_property_get_strlist (d, prop_to_check);
+ for (i = value; i != NULL; i = g_slist_next (i)) {
+ const char *str = i->data;
+ if (strcmp (str, needle) == 0) {
+ contains = TRUE;
+ break;
+ }
+ }
+ } else {
+ return FALSE;
}
+
return contains;
} else if (strcmp (attr[2], "contains_ncase") == 0) {
const char *needle;
@@ -557,22 +580,37 @@
needle = attr[3];
- if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
- return FALSE;
-
- if (hal_device_has_property (d, prop_to_check)) {
- char *needle_lowercase;
- char *haystack_lowercase;
-
- needle_lowercase = g_utf8_strdown (needle, -1);
- haystack_lowercase = g_utf8_strdown (hal_device_property_get_string (d, prop_to_check), -1);
- if (needle_lowercase != NULL && haystack_lowercase != NULL && strstr (haystack_lowercase, needle_lowercase)) {
- contains_ncase = TRUE;
+ if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRING) {
+ if (hal_device_has_property (d, prop_to_check)) {
+ char *needle_lowercase;
+ char *haystack_lowercase;
+
+ needle_lowercase = g_utf8_strdown (needle, -1);
+ haystack_lowercase = g_utf8_strdown (hal_device_property_get_string (d, prop_to_check), -1);
+ if (needle_lowercase != NULL && haystack_lowercase != NULL && strstr (haystack_lowercase, needle_lowercase)) {
+ contains_ncase = TRUE;
+ }
+
+ g_free (needle_lowercase);
+ g_free (haystack_lowercase);
}
+ } else if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRLIST &&
+ needle != NULL) {
+ GSList *i;
+ GSList *value;
- g_free (needle_lowercase);
- g_free (haystack_lowercase);
+ value = hal_device_property_get_strlist (d, prop_to_check);
+ for (i = value; i != NULL; i = g_slist_next (i)) {
+ const char *str = i->data;
+ if (g_ascii_strcasecmp (str, needle) == 0) {
+ contains_ncase = TRUE;
+ break;
+ }
+ }
+ } else {
+ return FALSE;
}
+
return contains_ncase;
} else if (strcmp (attr[2], "compare_lt") == 0) {
dbus_int64_t result;
@@ -652,6 +690,10 @@
/* match string property */
pc->merge_type = MERGE_TYPE_DOUBLE;
return;
+ } else if (strcmp (attr[3], "strlist") == 0) {
+ /* match string property */
+ pc->merge_type = MERGE_TYPE_STRLIST;
+ return;
} else if (strcmp (attr[3], "copy_property") == 0) {
/* copy another property */
pc->merge_type = MERGE_TYPE_COPY_PROPERTY;
@@ -661,13 +703,13 @@
return;
}
-/** Called when the append element begins.
+/** Called when the append or prepend element begins.
*
* @param pc Parsing context
* @param attr Attribute key/value pairs
*/
static void
-handle_append (ParsingContext * pc, const char **attr)
+handle_append_prepend (ParsingContext * pc, const char **attr)
{
int num_attrib;
@@ -688,9 +730,13 @@
return;
if (strcmp (attr[3], "string") == 0) {
- /* match string property */
+ /* append to a string */
pc->merge_type = MERGE_TYPE_STRING;
return;
+ } else if (strcmp (attr[3], "strlist") == 0) {
+ /* append to a string list*/
+ pc->merge_type = MERGE_TYPE_STRLIST;
+ return;
} else if (strcmp (attr[3], "copy_property") == 0) {
/* copy another property */
pc->merge_type = MERGE_TYPE_COPY_PROPERTY;
@@ -700,6 +746,48 @@
return;
}
+/** Called when the append or prepend element begins.
+ *
+ * @param pc Parsing context
+ * @param attr Attribute key/value pairs
+ */
+static void
+handle_remove (ParsingContext * pc, const char **attr)
+{
+ int num_attrib;
+
+ pc->merge_type = MERGE_TYPE_UNKNOWN;
+
+ for (num_attrib = 0; attr[num_attrib] != NULL; num_attrib++) {
+ ;
+ }
+
+ if (num_attrib != 2 && num_attrib != 4)
+ return;
+
+ if (strcmp (attr[0], "key") != 0)
+ return;
+ strncpy (pc->merge_key, attr[1], MAX_KEY_SIZE);
+
+ if (num_attrib == 4) {
+ if (strcmp (attr[2], "type") != 0)
+ return;
+
+ if (strcmp (attr[3], "strlist") == 0) {
+ /* remove from strlist */
+ pc->merge_type = MERGE_TYPE_STRLIST;
+ return;
+ } else {
+ pc->merge_type = MERGE_TYPE_UNKNOWN;
+ return;
+ }
+ } else {
+ pc->merge_type = MERGE_TYPE_REMOVE;
+ }
+
+ return;
+}
+
/** Abort parsing of document
*
* @param pc Parsing context
@@ -790,7 +878,41 @@
pc->curelem = CURELEM_APPEND;
if (pc->match_ok) {
- handle_append (pc, attr);
+ handle_append_prepend (pc, attr);
+ } else {
+ /*HAL_INFO(("No merge!")); */
+ }
+ } else if (strcmp (el, "prepend") == 0) {
+ if (pc->curelem != CURELEM_DEVICE
+ && pc->curelem != CURELEM_MATCH) {
+ HAL_ERROR (("%s:%d:%d: Element <prepend> can only be "
+ "inside <device> and <match>",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser)));
+ parsing_abort (pc);
+ }
+
+ pc->curelem = CURELEM_PREPEND;
+ if (pc->match_ok) {
+ handle_append_prepend (pc, attr);
+ } else {
+ /*HAL_INFO(("No merge!")); */
+ }
+ } else if (strcmp (el, "remove") == 0) {
+ if (pc->curelem != CURELEM_DEVICE
+ && pc->curelem != CURELEM_MATCH) {
+ HAL_ERROR (("%s:%d:%d: Element <remove> can only be "
+ "inside <device> and <match>",
+ pc->file,
+ XML_GetCurrentLineNumber (pc->parser),
+ XML_GetCurrentColumnNumber (pc->parser)));
+ parsing_abort (pc);
+ }
+
+ pc->curelem = CURELEM_REMOVE;
+ if (pc->match_ok) {
+ handle_remove (pc, attr);
} else {
/*HAL_INFO(("No merge!")); */
}
@@ -853,10 +975,18 @@
switch (pc->merge_type) {
case MERGE_TYPE_STRING:
- hal_device_property_set_string (pc->device, pc->merge_key,
- pc->cdata_buf);
+ hal_device_property_set_string (pc->device, pc->merge_key, pc->cdata_buf);
break;
+ case MERGE_TYPE_STRLIST:
+ {
+ int type = hal_device_property_get_type (pc->device, pc->merge_key);
+ if (type == HAL_PROPERTY_TYPE_STRLIST || type == HAL_PROPERTY_TYPE_NIL) {
+ hal_device_property_remove (pc->device, pc->merge_key);
+ hal_device_property_strlist_append (pc->device, pc->merge_key, pc->cdata_buf);
+ }
+ break;
+ }
case MERGE_TYPE_INT32:
{
@@ -933,34 +1063,96 @@
break;
}
} else if (pc->curelem == CURELEM_APPEND && pc->match_ok &&
- hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_STRING) {
+ (hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_STRING ||
+ hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_STRLIST ||
+ hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_NIL)) {
char buf[256];
char buf2[256];
/* As soon as we are appending, we have matched the device... */
pc->device_matched = TRUE;
- switch (pc->merge_type) {
- case MERGE_TYPE_STRING:
- strncpy (buf, pc->cdata_buf, sizeof (buf));
- break;
+ if (pc->merge_type == MERGE_TYPE_STRLIST) {
+ hal_device_property_strlist_append (pc->device, pc->merge_key, pc->cdata_buf);
+ } else {
+ const char *existing_string;
+
+ switch (pc->merge_type) {
+ case MERGE_TYPE_STRING:
+ strncpy (buf, pc->cdata_buf, sizeof (buf));
+ break;
+
+ case MERGE_TYPE_COPY_PROPERTY:
+ hal_device_property_get_as_string (pc->device, pc->cdata_buf, buf, sizeof (buf));
+ break;
+
+ default:
+ HAL_ERROR (("Unknown merge_type=%d='%c'", pc->merge_type, pc->merge_type));
+ break;
+ }
+
+ existing_string = hal_device_property_get_string (pc->device, pc->merge_key);
+ if (existing_string != NULL) {
+ strncpy (buf2, existing_string, sizeof (buf2));
+ strncat (buf2, buf, sizeof (buf2) - strlen(buf2));
+ } else {
+ strncpy (buf2, buf, sizeof (buf2));
+ }
+ hal_device_property_set_string (pc->device, pc->merge_key, buf2);
+ }
+ } else if (pc->curelem == CURELEM_PREPEND && pc->match_ok &&
+ (hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_STRING ||
+ hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_STRLIST ||
+ hal_device_property_get_type (pc->device, pc->merge_key) == HAL_PROPERTY_TYPE_NIL)) {
+ char buf[256];
+ char buf2[256];
- case MERGE_TYPE_COPY_PROPERTY:
- hal_device_property_get_as_string (pc->device, pc->cdata_buf, buf, sizeof (buf));
- break;
+ /* As soon as we are prepending, we have matched the device... */
+ pc->device_matched = TRUE;
- default:
- HAL_ERROR (("Unknown merge_type=%d='%c'",
- pc->merge_type, pc->merge_type));
- break;
+ if (pc->merge_type == MERGE_TYPE_STRLIST) {
+ hal_device_property_strlist_prepend (pc->device, pc->merge_key, pc->cdata_buf);
+ } else {
+ const char *existing_string;
+
+ switch (pc->merge_type) {
+ case MERGE_TYPE_STRING:
+ strncpy (buf, pc->cdata_buf, sizeof (buf));
+ break;
+
+ case MERGE_TYPE_COPY_PROPERTY:
+ hal_device_property_get_as_string (pc->device, pc->cdata_buf, buf, sizeof (buf));
+ break;
+
+ default:
+ HAL_ERROR (("Unknown merge_type=%d='%c'", pc->merge_type, pc->merge_type));
+ break;
+ }
+
+ existing_string = hal_device_property_get_string (pc->device, pc->merge_key);
+ if (existing_string != NULL) {
+ strncpy (buf2, buf, sizeof (buf2));
+ strncat (buf2, existing_string, sizeof (buf2) - strlen(buf2));
+ } else {
+ strncpy (buf2, buf, sizeof (buf2));
+ }
+ hal_device_property_set_string (pc->device, pc->merge_key, buf2);
}
+ } else if (pc->curelem == CURELEM_REMOVE && pc->match_ok) {
- strncpy (buf2, hal_device_property_get_string (pc->device, pc->merge_key), sizeof (buf2));
- strncat (buf2, buf, sizeof (buf2) - strlen(buf2));
- hal_device_property_set_string (pc->device, pc->merge_key, buf2);
+ if (pc->merge_type == MERGE_TYPE_STRLIST) {
+ /* covers <remove key="foobar" type="strlist">blah</remove> */
+ hal_device_property_strlist_remove (pc->device, pc->merge_key, pc->cdata_buf);
+ } else {
+ /* only allow <remove key="foobar"/>, not <remove key="foobar">blah</remove> */
+ if (strlen (pc->cdata_buf) == 0) {
+ hal_device_property_remove (pc->device, pc->merge_key);
+ }
+ }
}
+
pc->cdata_buf_len = 0;
pc->depth--;
More information about the hal-commit
mailing list