11 GHashTable *callbacks;
14 static void destfunc(struct Callback *c)
20 ObParseInst* parse_startup()
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);
28 void parse_shutdown(ObParseInst *i)
31 g_hash_table_destroy(i->callbacks);
36 void parse_register(ObParseInst *i, const char *tag,
37 ParseCallback func, void *data)
41 if ((c = g_hash_table_lookup(i->callbacks, tag))) {
42 g_warning("tag '%s' already registered", tag);
46 c = g_new(struct Callback, 1);
47 c->tag = g_strdup(tag);
50 g_hash_table_insert(i->callbacks, c->tag, c);
53 gboolean parse_load_rc(xmlDocPtr *doc, xmlNodePtr *root)
58 path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
59 if (parse_load(path, "openbox_config", doc, root)) {
63 path = g_build_filename(RCDIR, "rc3", NULL);
64 if (parse_load(path, "openbox_config", doc, root)) {
70 g_warning("unable to find a valid config file, using defaults");
74 gboolean parse_load(const char *path, const char *rootname,
75 xmlDocPtr *doc, xmlNodePtr *root)
77 xmlLineNumbersDefault(1);
79 if ((*doc = xmlParseFile(path))) {
80 *root = xmlDocGetRootElement(*doc);
84 g_warning("%s is an empty document", path);
86 if (xmlStrcasecmp((*root)->name, (const xmlChar*)rootname)) {
89 g_warning("document %s is of wrong type. root node is "
90 "not '%s'", path, rootname);
99 gboolean parse_load_mem(gpointer data, guint len, const char *rootname,
100 xmlDocPtr *doc, xmlNodePtr *root)
102 xmlLineNumbersDefault(1);
104 if ((*doc = xmlParseMemory(data, len))) {
105 *root = xmlDocGetRootElement(*doc);
109 g_warning("Given memory is an empty document");
111 if (xmlStrcasecmp((*root)->name, (const xmlChar*)rootname)) {
114 g_warning("document in given memory is of wrong type. root "
115 "node is not '%s'", rootname);
124 void parse_close(xmlDocPtr doc)
129 void parse_tree(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
132 struct Callback *c = g_hash_table_lookup(i->callbacks, node->name);
135 c->func(i, doc, node, c->data);
141 char *parse_string(xmlDocPtr doc, xmlNodePtr node)
143 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
144 char *s = g_strdup(c ? (char*)c : "");
149 int parse_int(xmlDocPtr doc, xmlNodePtr node)
151 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
152 int i = atoi((char*)c);
157 gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node)
159 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
161 if (!xmlStrcasecmp(c, (const xmlChar*) "true"))
163 else if (!xmlStrcasecmp(c, (const xmlChar*) "yes"))
165 else if (!xmlStrcasecmp(c, (const xmlChar*) "on"))
171 gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node)
173 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
175 r = !xmlStrcasecmp(c, (const xmlChar*) val);
180 xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node)
183 if (!xmlStrcasecmp(node->name, (const xmlChar*) tag))
190 gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value)
192 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
195 *value = atoi((char*)c);
202 gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value)
204 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
207 *value = g_strdup((char*)c);
214 gboolean parse_attr_contains(const char *val, xmlNodePtr node,
217 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
219 r = !xmlStrcasecmp(c, (const xmlChar*) val);