]> Dogcows Code - chaz/openbox/blob - parser/parse.c
* Change xml parsing to pass the parent node, rather than the first
[chaz/openbox] / parser / parse.c
1 #include "parse.h"
2 #include <glib.h>
3
4 struct Callback {
5 char *tag;
6 ParseCallback func;
7 void *data;
8 };
9
10 static GHashTable *callbacks;
11
12 static void destfunc(struct Callback *c)
13 {
14 g_free(c->tag);
15 g_free(c);
16 }
17
18 void parse_startup()
19 {
20 callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
21 (GDestroyNotify)destfunc);
22 }
23
24 void parse_shutdown()
25 {
26 g_hash_table_destroy(callbacks);
27 }
28
29 void parse_register(const char *tag, ParseCallback func, void *data)
30 {
31 struct Callback *c;
32
33 if ((c = g_hash_table_lookup(callbacks, tag))) {
34 g_warning("tag '%s' already registered", tag);
35 return;
36 }
37
38 c = g_new(struct Callback, 1);
39 c->tag = g_strdup(tag);
40 c->func = func;
41 c->data = data;
42 g_hash_table_insert(callbacks, c->tag, c);
43 }
44
45 gboolean parse_load_rc(xmlDocPtr *doc, xmlNodePtr *root)
46 {
47 char *path;
48 gboolean r = FALSE;
49
50 path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
51 if (parse_load(path, "openbox_config", doc, root)) {
52 r = TRUE;
53 } else {
54 g_free(path);
55 path = g_build_filename(RCDIR, "rc3", NULL);
56 if (parse_load(path, "openbox_config", doc, root)) {
57 r = TRUE;
58 }
59 }
60 g_free(path);
61 if (!r)
62 g_message("unable to find a valid config file, using defaults");
63 return r;
64 }
65
66 gboolean parse_load(const char *path, const char *rootname,
67 xmlDocPtr *doc, xmlNodePtr *root)
68 {
69
70 xmlLineNumbersDefault(1);
71
72 if ((*doc = xmlParseFile(path))) {
73 *root = xmlDocGetRootElement(*doc);
74 if (!*root) {
75 xmlFreeDoc(*doc);
76 *doc = NULL;
77 g_warning("%s is an empty document", path);
78 } else {
79 if (xmlStrcasecmp((*root)->name, (const xmlChar*)rootname)) {
80 xmlFreeDoc(*doc);
81 *doc = NULL;
82 g_warning("document %s is of wrong type. root *root is "
83 "not 'openbox_config'", path);
84 }
85 }
86 }
87 if (!*doc)
88 return FALSE;
89 return TRUE;
90 }
91
92 void parse_close(xmlDocPtr doc)
93 {
94 xmlFree(doc);
95 }
96
97 void parse_tree(xmlDocPtr doc, xmlNodePtr node, void *nothing)
98 {
99 while (node) {
100 struct Callback *c = g_hash_table_lookup(callbacks, node->name);
101
102 if (c)
103 c->func(doc, node, c->data);
104
105 node = node->next;
106 }
107 }
108
109 char *parse_string(xmlDocPtr doc, xmlNodePtr node)
110 {
111 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
112 char *s = g_strdup((char*)c);
113 xmlFree(c);
114 return s;
115 }
116
117 int parse_int(xmlDocPtr doc, xmlNodePtr node)
118 {
119 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
120 int i = atoi((char*)c);
121 xmlFree(c);
122 return i;
123 }
124
125 gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node)
126 {
127 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
128 gboolean b = FALSE;
129 if (!xmlStrcasecmp(c, (const xmlChar*) "true"))
130 b = TRUE;
131 else if (!xmlStrcasecmp(c, (const xmlChar*) "yes"))
132 b = TRUE;
133 else if (!xmlStrcasecmp(c, (const xmlChar*) "on"))
134 b = TRUE;
135 xmlFree(c);
136 return b;
137 }
138
139 gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node)
140 {
141 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
142 gboolean r;
143 r = !xmlStrcasecmp(c, (const xmlChar*) val);
144 xmlFree(c);
145 return r;
146 }
147
148 xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node)
149 {
150 while (node) {
151 if (!xmlStrcasecmp(node->name, (const xmlChar*) tag))
152 return node;
153 node = node->next;
154 }
155 return NULL;
156 }
157
158 gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value)
159 {
160 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
161 gboolean r = FALSE;
162 if (c) {
163 *value = atoi((char*)c);
164 r = TRUE;
165 }
166 xmlFree(c);
167 return r;
168 }
169
170 gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value)
171 {
172 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
173 gboolean r = FALSE;
174 if (c) {
175 *value = g_strdup((char*)c);
176 r = TRUE;
177 }
178 xmlFree(c);
179 return r;
180 }
181
182 gboolean parse_attr_contains(const char *val, xmlNodePtr node,
183 const char *name)
184 {
185 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
186 gboolean r;
187 r = !xmlStrcasecmp(c, (const xmlChar*) val);
188 xmlFree(c);
189 return r;
190 }
This page took 0.041883 seconds and 5 git commands to generate.