]> Dogcows Code - chaz/openbox/blob - openbox/parse.c
not being developed anymore, maybe in the future...
[chaz/openbox] / openbox / 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 static xmlDocPtr doc_config = NULL;
12
13 static void destfunc(struct Callback *c)
14 {
15 g_free(c->tag);
16 g_free(c);
17 }
18
19 void parse_startup()
20 {
21 callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
22 (GDestroyNotify)destfunc);
23 }
24
25 void parse_shutdown()
26 {
27 xmlFree(doc_config);
28 doc_config = NULL;
29
30 g_hash_table_destroy(callbacks);
31 }
32
33 void parse_register(const char *tag, ParseCallback func, void *data)
34 {
35 struct Callback *c;
36
37 if ((c = g_hash_table_lookup(callbacks, tag))) {
38 g_warning("tag '%s' already registered", tag);
39 return;
40 }
41
42 c = g_new(struct Callback, 1);
43 c->tag = g_strdup(tag);
44 c->func = func;
45 c->data = data;
46 g_hash_table_insert(callbacks, c->tag, c);
47 }
48
49 void parse_config()
50 {
51 char *path;
52 xmlNodePtr node = NULL;
53
54 xmlLineNumbersDefault(1);
55
56 path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
57 if ((doc_config = xmlParseFile(path))) {
58 node = xmlDocGetRootElement(doc_config);
59 if (!node) {
60 xmlFreeDoc(doc_config);
61 doc_config = NULL;
62 g_warning("%s is an empty document", path);
63 } else {
64 if (xmlStrcasecmp(node->name, (const xmlChar*)"openbox_config")) {
65 xmlFreeDoc(doc_config);
66 doc_config = NULL;
67 g_warning("document %s is of wrong type. root node is "
68 "not 'openbox_config'", path);
69 }
70 }
71 }
72 g_free(path);
73 if (!doc_config) {
74 path = g_build_filename(RCDIR, "rc3", NULL);
75 if ((doc_config = xmlParseFile(path))) {
76 node = xmlDocGetRootElement(doc_config);
77 if (!node) {
78 xmlFreeDoc(doc_config);
79 doc_config = NULL;
80 g_warning("%s is an empty document", path);
81 } else {
82 if (xmlStrcasecmp(node->name,
83 (const xmlChar*)"openbox_config")) {
84 xmlFreeDoc(doc_config);
85 doc_config = NULL;
86 g_warning("document %s is of wrong type. root node is "
87 "not 'openbox_config'", path);
88 }
89 }
90 }
91 g_free(path);
92 }
93 if (!doc_config) {
94 g_message("unable to find a valid config file, using defaults");
95 } else {
96 parse_tree(doc_config, node->xmlChildrenNode, NULL);
97 }
98 }
99
100 void parse_tree(xmlDocPtr doc, xmlNodePtr node, void *nothing)
101 {
102 while (node) {
103 struct Callback *c = g_hash_table_lookup(callbacks, node->name);
104
105 if (c)
106 c->func(doc, node->xmlChildrenNode, c->data);
107
108 node = node->next;
109 }
110 }
111
112 char *parse_string(xmlDocPtr doc, xmlNodePtr node)
113 {
114 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
115 char *s = g_strdup((char*)c);
116 xmlFree(c);
117 return s;
118 }
119
120 int parse_int(xmlDocPtr doc, xmlNodePtr node)
121 {
122 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
123 int i = atoi((char*)c);
124 xmlFree(c);
125 return i;
126 }
127
128 gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node)
129 {
130 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
131 gboolean b = FALSE;
132 if (!xmlStrcasecmp(c, (const xmlChar*) "true"))
133 b = TRUE;
134 else if (!xmlStrcasecmp(c, (const xmlChar*) "yes"))
135 b = TRUE;
136 else if (!xmlStrcasecmp(c, (const xmlChar*) "on"))
137 b = TRUE;
138 xmlFree(c);
139 return b;
140 }
141
142 gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node)
143 {
144 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
145 gboolean r;
146 r = !xmlStrcasecmp(c, (const xmlChar*) val);
147 xmlFree(c);
148 return r;
149 }
150
151 xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node)
152 {
153 while (node) {
154 if (!xmlStrcasecmp(node->name, (const xmlChar*) tag))
155 return node;
156 node = node->next;
157 }
158 return NULL;
159 }
160
161 gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value)
162 {
163 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
164 gboolean r = FALSE;
165 if (c) {
166 *value = atoi((char*)c);
167 r = TRUE;
168 }
169 xmlFree(c);
170 return r;
171 }
172
173 gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value)
174 {
175 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
176 gboolean r = FALSE;
177 if (c) {
178 *value = g_strdup((char*)c);
179 r = TRUE;
180 }
181 xmlFree(c);
182 return r;
183 }
184
185 Action *parse_action(xmlDocPtr doc, xmlNodePtr node)
186 {
187 char *actname;
188 Action *act = NULL;
189 xmlNodePtr n;
190
191 if (parse_attr_string("name", node, &actname)) {
192 if ((act = action_from_string(actname))) {
193 if (act->func == action_execute || act->func == action_restart) {
194 if ((n = parse_find_node("execute", node->xmlChildrenNode)))
195 act->data.execute.path = parse_string(doc, n);
196 } else if (act->func == action_showmenu) {
197 if ((n = parse_find_node("menu", node->xmlChildrenNode)))
198 act->data.showmenu.name = parse_string(doc, n);
199 } else if (act->func == action_desktop) {
200 if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
201 act->data.desktop.desk = parse_int(doc, n);
202 if (act->data.desktop.desk > 0) act->data.desktop.desk--;
203 } else if (act->func == action_send_to_desktop) {
204 if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
205 act->data.sendto.desk = parse_int(doc, n);
206 if (act->data.sendto.desk > 0) act->data.sendto.desk--;
207 } else if (act->func == action_move_relative_horz ||
208 act->func == action_move_relative_vert ||
209 act->func == action_resize_relative_horz ||
210 act->func == action_resize_relative_vert) {
211 if ((n = parse_find_node("delta", node->xmlChildrenNode)))
212 act->data.relative.delta = parse_int(doc, n);
213 } else if (act->func == action_desktop_right ||
214 act->func == action_desktop_left ||
215 act->func == action_desktop_up ||
216 act->func == action_desktop_down) {
217 if ((n = parse_find_node("wrap", node->xmlChildrenNode))) {
218 g_message("WRAP %d", parse_bool(doc, n));
219 act->data.desktopdir.wrap = parse_bool(doc, n);
220 }
221 } else if (act->func == action_send_to_desktop_right ||
222 act->func == action_send_to_desktop_left ||
223 act->func == action_send_to_desktop_up ||
224 act->func == action_send_to_desktop_down) {
225 if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
226 act->data.sendtodir.wrap = parse_bool(doc, n);
227 if ((n = parse_find_node("follow", node->xmlChildrenNode)))
228 act->data.sendtodir.follow = parse_bool(doc, n);
229 }
230 }
231 }
232 return act;
233 }
234
235 gboolean parse_attr_contains(const char *val, xmlNodePtr node,
236 const char *name)
237 {
238 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
239 gboolean r;
240 r = !xmlStrcasecmp(c, (const xmlChar*) val);
241 xmlFree(c);
242 return r;
243 }
This page took 0.048177 seconds and 4 git commands to generate.