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