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 if ((*doc = xmlParseFile(path))) {
78 *root = xmlDocGetRootElement(*doc);
82 g_warning("%s is an empty document", path);
84 if (xmlStrcasecmp((*root)->name, (const xmlChar*)rootname)) {
87 g_warning("document %s is of wrong type. root node is "
88 "not '%s'", path, rootname);
97 gboolean parse_load_mem(gpointer data, guint len, const char *rootname,
98 xmlDocPtr *doc, xmlNodePtr *root)
100 if ((*doc = xmlParseMemory(data, len))) {
101 *root = xmlDocGetRootElement(*doc);
105 g_warning("Given memory is an empty document");
107 if (xmlStrcasecmp((*root)->name, (const xmlChar*)rootname)) {
110 g_warning("document in given memory is of wrong type. root "
111 "node is not '%s'", rootname);
120 void parse_close(xmlDocPtr doc)
125 void parse_tree(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
128 struct Callback *c = g_hash_table_lookup(i->callbacks, node->name);
131 c->func(i, doc, node, c->data);
137 char *parse_string(xmlDocPtr doc, xmlNodePtr node)
139 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
140 char *s = g_strdup(c ? (char*)c : "");
145 int parse_int(xmlDocPtr doc, xmlNodePtr node)
147 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
148 int i = atoi((char*)c);
153 gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node)
155 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
157 if (!xmlStrcasecmp(c, (const xmlChar*) "true"))
159 else if (!xmlStrcasecmp(c, (const xmlChar*) "yes"))
161 else if (!xmlStrcasecmp(c, (const xmlChar*) "on"))
167 gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node)
169 xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
171 r = !xmlStrcasecmp(c, (const xmlChar*) val);
176 xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node)
179 if (!xmlStrcasecmp(node->name, (const xmlChar*) tag))
186 gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value)
188 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
191 *value = atoi((char*)c);
198 gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value)
200 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
203 *value = g_strdup((char*)c);
210 gboolean parse_attr_contains(const char *val, xmlNodePtr node,
213 xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
215 r = !xmlStrcasecmp(c, (const xmlChar*) val);