8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / cmd / hal / hald / property.c
blob2caeb2b24bb5a527d3b874bad1f930b2c2c913c2
1 /***************************************************************************
2 * CVSID: $Id$
4 * property.c : HalProperty methods
6 * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
7 * Copyright (C) 2004 Novell, Inc.
9 * Licensed under the Academic Free License version 2.1
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 **************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include <config.h>
29 #endif
31 #include <string.h>
32 #include <glib.h>
34 #include "logger.h"
35 #include "property.h"
37 struct _HalProperty {
38 char *key;
40 int type;
41 union {
42 char *str_value;
43 dbus_int32_t int_value;
44 dbus_uint64_t uint64_value;
45 dbus_bool_t bool_value;
46 double double_value;
47 GSList *strlist_value;
48 } v;
49 gboolean readonly;
50 gboolean persistence;
51 gboolean callout;
54 void
55 hal_property_free (HalProperty *prop)
58 g_free (prop->key);
60 if (prop->type == HAL_PROPERTY_TYPE_STRING) {
61 g_free (prop->v.str_value);
62 } else if (prop->type == HAL_PROPERTY_TYPE_STRLIST) {
63 GSList *i;
64 for (i = prop->v.strlist_value; i != NULL; i = g_slist_next (i)) {
65 g_free (i->data);
67 g_slist_free (prop->v.strlist_value);
70 g_free (prop);
73 HalProperty *
74 hal_property_new_string (const char *key, const char *value)
76 HalProperty *prop;
77 char *endchar;
78 gboolean validated = TRUE;
80 prop = g_new0 (HalProperty, 1);
82 prop->type = HAL_PROPERTY_TYPE_STRING;
83 prop->key = g_strdup (key);
84 prop->v.str_value = g_strdup (value != NULL ? value : "");
86 while (!g_utf8_validate (prop->v.str_value, -1,
87 (const char **) &endchar)) {
88 validated = FALSE;
89 *endchar = '?';
92 if (!validated) {
93 HAL_WARNING (("Key '%s' has invalid UTF-8 string '%s'",
94 key, prop->v.str_value));
97 return prop;
100 HalProperty *
101 hal_property_new_int (const char *key, dbus_int32_t value)
103 HalProperty *prop;
105 prop = g_new0 (HalProperty, 1);
107 prop->type = HAL_PROPERTY_TYPE_INT32;
108 prop->key = g_strdup (key);
109 prop->v.int_value = value;
111 return prop;
114 HalProperty *
115 hal_property_new_uint64 (const char *key, dbus_uint64_t value)
117 HalProperty *prop;
119 prop = g_new0 (HalProperty, 1);
121 prop->type = HAL_PROPERTY_TYPE_UINT64;
122 prop->key = g_strdup (key);
123 prop->v.uint64_value = value;
125 return prop;
128 HalProperty *
129 hal_property_new_bool (const char *key, dbus_bool_t value)
131 HalProperty *prop;
133 prop = g_new0 (HalProperty, 1);
135 prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
136 prop->key = g_strdup (key);
137 prop->v.bool_value = value;
139 return prop;
142 HalProperty *
143 hal_property_new_double (const char *key, double value)
145 HalProperty *prop;
147 prop = g_new0 (HalProperty, 1);
149 prop->type = HAL_PROPERTY_TYPE_DOUBLE;
150 prop->key = g_strdup (key);
151 prop->v.double_value = value;
153 return prop;
156 const char *
157 hal_property_get_key (HalProperty *prop)
159 g_return_val_if_fail (prop != NULL, NULL);
161 return prop->key;
165 hal_property_get_type (HalProperty *prop)
167 g_return_val_if_fail (prop != NULL, HAL_PROPERTY_TYPE_INVALID);
169 return prop->type;
172 const char *
173 hal_property_get_string (HalProperty *prop)
175 g_return_val_if_fail (prop != NULL, NULL);
176 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING, NULL);
178 return prop->v.str_value;
181 dbus_int32_t
182 hal_property_get_int (HalProperty *prop)
184 g_return_val_if_fail (prop != NULL, -1);
185 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32, -1);
187 return prop->v.int_value;
190 dbus_uint64_t
191 hal_property_get_uint64 (HalProperty *prop)
193 g_return_val_if_fail (prop != NULL, -1);
194 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64, -1);
196 return prop->v.uint64_value;
199 dbus_bool_t
200 hal_property_get_bool (HalProperty *prop)
202 g_return_val_if_fail (prop != NULL, FALSE);
203 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN, FALSE);
205 return prop->v.bool_value;
208 char *
209 hal_property_to_string (HalProperty *prop)
211 g_return_val_if_fail (prop != NULL, NULL);
213 switch (prop->type) {
214 case HAL_PROPERTY_TYPE_STRING:
215 return g_strdup (prop->v.str_value);
216 case HAL_PROPERTY_TYPE_INT32:
217 return g_strdup_printf ("%d", prop->v.int_value);
218 case HAL_PROPERTY_TYPE_UINT64:
219 return g_strdup_printf ("%llu", (long long unsigned int) prop->v.uint64_value);
220 case HAL_PROPERTY_TYPE_BOOLEAN:
221 /* FIXME: Maybe use 1 and 0 here instead? */
222 return g_strdup (prop->v.bool_value ? "true" : "false");
223 case HAL_PROPERTY_TYPE_DOUBLE:
224 return g_strdup_printf ("%f", prop->v.double_value);
225 case HAL_PROPERTY_TYPE_STRLIST:
227 GSList *iter;
228 guint i;
229 char buf[256];
231 i = 0;
232 buf[0] = '\0';
233 for (iter = hal_property_get_strlist (prop);
234 iter != NULL && i < sizeof(buf);
235 iter = g_slist_next (iter)) {
236 guint len;
237 const char *str;
239 str = (const char *) iter->data;
240 len = strlen (str);
241 strncpy (buf + i, str, sizeof(buf) - i);
242 i += len;
244 if (g_slist_next (iter) != NULL && i < sizeof(buf)) {
245 buf[i] = '\t';
246 i++;
249 return g_strdup (buf);
252 default:
253 return NULL;
257 double
258 hal_property_get_double (HalProperty *prop)
260 g_return_val_if_fail (prop != NULL, -1.0);
261 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE, -1.0);
263 return prop->v.double_value;
266 void
267 hal_property_set_string (HalProperty *prop, const char *value)
269 char *endchar;
270 gboolean validated = TRUE;
272 g_return_if_fail (prop != NULL);
273 g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING ||
274 prop->type == HAL_PROPERTY_TYPE_INVALID);
276 prop->type = HAL_PROPERTY_TYPE_STRING;
277 if (prop->v.str_value != NULL)
278 g_free (prop->v.str_value);
279 prop->v.str_value = g_strdup (value);
281 while (!g_utf8_validate (prop->v.str_value, -1,
282 (const char **) &endchar)) {
283 validated = FALSE;
284 *endchar = '?';
287 if (!validated) {
288 HAL_WARNING (("Key '%s' has invalid UTF-8 string '%s'",
289 prop->key, value));
293 void
294 hal_property_set_int (HalProperty *prop, dbus_int32_t value)
296 g_return_if_fail (prop != NULL);
297 g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32 ||
298 prop->type == HAL_PROPERTY_TYPE_INVALID);
300 prop->type = HAL_PROPERTY_TYPE_INT32;
301 prop->v.int_value = value;
304 void
305 hal_property_set_uint64 (HalProperty *prop, dbus_uint64_t value)
307 g_return_if_fail (prop != NULL);
308 g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64 ||
309 prop->type == HAL_PROPERTY_TYPE_INVALID);
311 prop->type = HAL_PROPERTY_TYPE_UINT64;
312 prop->v.uint64_value = value;
315 void
316 hal_property_set_bool (HalProperty *prop, dbus_bool_t value)
318 g_return_if_fail (prop != NULL);
319 g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN ||
320 prop->type == HAL_PROPERTY_TYPE_INVALID);
322 prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
323 prop->v.bool_value = value;
326 void
327 hal_property_set_double (HalProperty *prop, double value)
329 g_return_if_fail (prop != NULL);
330 g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE ||
331 prop->type == HAL_PROPERTY_TYPE_INVALID);
333 prop->type = HAL_PROPERTY_TYPE_DOUBLE;
334 prop->v.double_value = value;
337 void
338 hal_property_set_attribute (HalProperty *prop,
339 enum PropertyAttribute attr,
340 gboolean val)
342 g_return_if_fail (prop != NULL);
344 switch (attr) {
345 case READONLY:
346 prop->readonly = val;
347 break;
348 case PERSISTENCE:
349 prop->persistence = val;
350 break;
351 case CALLOUT:
352 prop->callout = val;
353 break;
357 gboolean
358 hal_property_get_attribute (HalProperty *prop,
359 enum PropertyAttribute attr)
361 g_return_val_if_fail (prop != NULL, -1);
363 switch (attr) {
364 case READONLY:
365 return prop->readonly;
366 case PERSISTENCE:
367 return prop->persistence;
368 case CALLOUT:
369 return prop->callout;
370 default:
371 return -1;
375 HalProperty *
376 hal_property_new_strlist (const char *key)
378 HalProperty *prop;
380 prop = g_new0 (HalProperty, 1);
382 prop->type = HAL_PROPERTY_TYPE_STRLIST;
383 prop->key = g_strdup (key);
384 prop->v.strlist_value = NULL;
386 return prop;
389 GSList *
390 hal_property_get_strlist (HalProperty *prop)
392 g_return_val_if_fail (prop != NULL, NULL);
393 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, NULL);
395 return prop->v.strlist_value;
398 gboolean
399 hal_property_strlist_append (HalProperty *prop, const char *value)
401 g_return_val_if_fail (prop != NULL, FALSE);
402 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
404 prop->v.strlist_value = g_slist_append (prop->v.strlist_value, g_strdup (value));
406 return TRUE;
409 gboolean
410 hal_property_strlist_prepend (HalProperty *prop, const char *value)
412 g_return_val_if_fail (prop != NULL, FALSE);
413 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
415 prop->v.strlist_value = g_slist_prepend (prop->v.strlist_value, g_strdup (value));
417 return TRUE;
420 gboolean
421 hal_property_strlist_remove_elem (HalProperty *prop, guint index)
423 GSList *elem;
425 g_return_val_if_fail (prop != NULL, FALSE);
426 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
428 if (prop->v.strlist_value == NULL)
429 return FALSE;
431 elem = g_slist_nth (prop->v.strlist_value, index);
432 if (elem == NULL)
433 return FALSE;
435 g_free (elem->data);
436 prop->v.strlist_value = g_slist_delete_link (prop->v.strlist_value, elem);
437 return TRUE;
441 gboolean
442 hal_property_strlist_add (HalProperty *prop, const char *value)
444 GSList *elem;
446 g_return_val_if_fail (prop != NULL, FALSE);
447 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
449 for (elem = prop->v.strlist_value; elem != NULL; elem = g_slist_next (elem)) {
450 if (strcmp (elem->data, value) == 0) {
451 return FALSE;
455 return hal_property_strlist_append (prop, value);
458 gboolean
459 hal_property_strlist_remove (HalProperty *prop, const char *value)
461 guint i;
462 GSList *elem;
464 g_return_val_if_fail (prop != NULL, FALSE);
465 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
467 for (elem = prop->v.strlist_value, i = 0; elem != NULL; elem = g_slist_next (elem), i++) {
468 if (strcmp (elem->data, value) == 0) {
469 return hal_property_strlist_remove_elem (prop, i);
473 return FALSE;
476 gboolean
477 hal_property_strlist_clear (HalProperty *prop)
479 GSList *elem;
481 g_return_val_if_fail (prop != NULL, FALSE);
482 g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
484 for (elem = prop->v.strlist_value; elem != NULL; elem = g_slist_next (elem)) {
485 g_free (elem->data);
487 g_slist_free (prop->v.strlist_value);
489 return FALSE;