summaryrefslogtreecommitdiff
path: root/openbox/parse.c
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-05-24 15:35:26 +0000
committerDana Jansens <danakj@orodu.net>2003-05-24 15:35:26 +0000
commitd2857b11944146e2e6973b7f7280cb57e1ee260b (patch)
tree51bf06d58f90953842b0e6babc9493f04934d7d9 /openbox/parse.c
parentf7df74b9cc9369fe401d5622c097e258a124f742 (diff)
ECKS EM ELL
Diffstat (limited to 'openbox/parse.c')
-rw-r--r--openbox/parse.c267
1 files changed, 212 insertions, 55 deletions
diff --git a/openbox/parse.c b/openbox/parse.c
index ffb72c03..8f9c82fb 100644
--- a/openbox/parse.c
+++ b/openbox/parse.c
@@ -1,86 +1,243 @@
#include "parse.h"
+#include <glib.h>
-static GHashTable *reg = NULL;
+struct Callback {
+ char *tag;
+ ParseCallback func;
+ void *data;
+};
-struct Functions {
- ParseFunc f;
- AssignParseFunc af;
-} *funcs;
+static GHashTable *callbacks;
+static xmlDocPtr doc_config = NULL;
-void destshit(gpointer shit) { g_free(shit); }
+static void destfunc(struct Callback *c)
+{
+ g_free(c->tag);
+ g_free(c);
+}
void parse_startup()
{
- reg = g_hash_table_new_full(g_str_hash, g_str_equal, destshit, destshit);
- funcs = NULL;
+ callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify)destfunc);
}
void parse_shutdown()
{
- g_hash_table_destroy(reg);
+ xmlFree(doc_config);
+ doc_config = NULL;
+
+ g_hash_table_destroy(callbacks);
}
-void parse_reg_section(char *section, ParseFunc func, AssignParseFunc afunc)
+void parse_register(const char *tag, ParseCallback func, void *data)
{
- struct Functions *f = g_new(struct Functions, 1);
- f->f = func;
- f->af = afunc;
- g_hash_table_insert(reg, g_ascii_strdown(section, -1), f);
+ struct Callback *c;
+
+ if ((c = g_hash_table_lookup(callbacks, tag))) {
+ g_warning("tag '%s' already registered", tag);
+ return;
+ }
+
+ c = g_new(struct Callback, 1);
+ c->tag = g_strdup(tag);
+ c->func = func;
+ c->data = data;
+ g_hash_table_insert(callbacks, c->tag, c);
}
-void parse_free_token(ParseToken *token)
+void parse_config()
{
- GList *it;
-
- switch (token->type) {
- case TOKEN_STRING:
- g_free(token->data.string);
- break;
- case TOKEN_IDENTIFIER:
- g_free(token->data.identifier);
- break;
- case TOKEN_LIST:
- for (it = token->data.list; it; it = it->next) {
- parse_free_token(it->data);
- g_free(it->data);
+ char *path;
+ xmlNodePtr node = NULL;
+
+ xmlLineNumbersDefault(1);
+
+ path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
+ if ((doc_config = xmlParseFile(path))) {
+ node = xmlDocGetRootElement(doc_config);
+ if (!node) {
+ xmlFreeDoc(doc_config);
+ doc_config = NULL;
+ g_warning("%s is an empty document", path);
+ } else {
+ if (xmlStrcasecmp(node->name, (const xmlChar*)"openbox_config")) {
+ xmlFreeDoc(doc_config);
+ doc_config = NULL;
+ g_warning("document %s is of wrong type. root node is "
+ "not 'openbox_config'", path);
+ }
+ }
+ }
+ g_free(path);
+ if (!doc_config) {
+ path = g_build_filename(RCDIR, "rc3", NULL);
+ if ((doc_config = xmlParseFile(path))) {
+ node = xmlDocGetRootElement(doc_config);
+ if (!node) {
+ xmlFreeDoc(doc_config);
+ doc_config = NULL;
+ g_warning("%s is an empty document", path);
+ } else {
+ if (xmlStrcasecmp(node->name,
+ (const xmlChar*)"openbox_config")) {
+ xmlFreeDoc(doc_config);
+ doc_config = NULL;
+ g_warning("document %s is of wrong type. root node is "
+ "not 'openbox_config'", path);
+ }
+ }
}
- g_list_free(token->data.list);
- break;
- case TOKEN_REAL:
- case TOKEN_INTEGER:
- case TOKEN_BOOL:
- case TOKEN_LBRACE:
- case TOKEN_RBRACE:
- case TOKEN_COMMA:
- case TOKEN_NEWLINE:
- break;
+ g_free(path);
}
+ if (!doc_config) {
+ g_message("unable to find a valid config file, using defaults");
+ } else {
+ parse_tree(doc_config, node->xmlChildrenNode, NULL);
+ }
+}
+
+void parse_tree(xmlDocPtr doc, xmlNodePtr node, void *nothing)
+{
+ while (node) {
+ struct Callback *c = g_hash_table_lookup(callbacks, node->name);
+
+ if (c)
+ c->func(doc, node->xmlChildrenNode, c->data);
+
+ node = node->next;
+ }
+}
+
+char *parse_string(xmlDocPtr doc, xmlNodePtr node)
+{
+ xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+ char *s = g_strdup((char*)c);
+ xmlFree(c);
+ return s;
}
-void parse_set_section(char *section)
+int parse_int(xmlDocPtr doc, xmlNodePtr node)
{
- char *sec;
- sec = g_ascii_strdown(section, -1);
- funcs = g_hash_table_lookup(reg, sec);
- g_free(sec);
+ xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+ int i = atoi((char*)c);
+ xmlFree(c);
+ return i;
}
-void parse_token(ParseToken *token)
+gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node)
{
- if (funcs) {
- if (funcs->f)
- funcs->f(token);
- else if (token->type != TOKEN_NEWLINE)
- yyerror("syntax error");
+ xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+ gboolean b = FALSE;
+ if (!xmlStrcasecmp(c, (const xmlChar*) "true"))
+ b = TRUE;
+ else if (!xmlStrcasecmp(c, (const xmlChar*) "yes"))
+ b = TRUE;
+ else if (!xmlStrcasecmp(c, (const xmlChar*) "on"))
+ b = TRUE;
+ xmlFree(c);
+ return b;
+}
+
+gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node)
+{
+ xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE);
+ gboolean r;
+ r = !xmlStrcasecmp(c, (const xmlChar*) val);
+ xmlFree(c);
+ return r;
+}
+
+xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node)
+{
+ while (node) {
+ if (!xmlStrcasecmp(node->name, (const xmlChar*) tag))
+ return node;
+ node = node->next;
+ }
+ return NULL;
+}
+
+gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value)
+{
+ xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
+ gboolean r = FALSE;
+ if (c) {
+ *value = atoi((char*)c);
+ r = TRUE;
}
+ xmlFree(c);
+ return r;
}
-void parse_assign(char *name, ParseToken *value)
+gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value)
{
- if (funcs) {
- if (funcs->af)
- funcs->af(name, value);
- else
- yyerror("syntax error");
+ xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
+ gboolean r = FALSE;
+ if (c) {
+ *value = g_strdup((char*)c);
+ r = TRUE;
}
+ xmlFree(c);
+ return r;
+}
+
+Action *parse_action(xmlDocPtr doc, xmlNodePtr node)
+{
+ char *actname;
+ Action *act = NULL;
+ xmlNodePtr n;
+
+ if (parse_attr_string("name", node, &actname)) {
+ if ((act = action_from_string(actname))) {
+ if (act->func == action_execute || act->func == action_restart) {
+ if ((n = parse_find_node("execute", node->xmlChildrenNode)))
+ act->data.execute.path = parse_string(doc, n);
+ } else if (act->func == action_showmenu) {
+ if ((n = parse_find_node("menu", node->xmlChildrenNode)))
+ act->data.showmenu.name = parse_string(doc, n);
+ } else if (act->func == action_desktop) {
+ if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
+ act->data.desktop.desk = parse_int(doc, n);
+ if (act->data.desktop.desk > 0) act->data.desktop.desk--;
+ } else if (act->func == action_send_to_desktop) {
+ if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
+ act->data.sendto.desk = parse_int(doc, n);
+ if (act->data.sendto.desk > 0) act->data.sendto.desk--;
+ } else if (act->func == action_move_relative_horz ||
+ act->func == action_move_relative_vert ||
+ act->func == action_resize_relative_horz ||
+ act->func == action_resize_relative_vert) {
+ if ((n = parse_find_node("delta", node->xmlChildrenNode)))
+ act->data.relative.delta = parse_int(doc, n);
+ } else if (act->func == action_desktop_right ||
+ act->func == action_desktop_left ||
+ act->func == action_desktop_up ||
+ act->func == action_desktop_down) {
+ if ((n = parse_find_node("wrap", node->xmlChildrenNode))) {
+ g_message("WRAP %d", parse_bool(doc, n));
+ act->data.desktopdir.wrap = parse_bool(doc, n);
+ }
+ } else if (act->func == action_send_to_desktop_right ||
+ act->func == action_send_to_desktop_left ||
+ act->func == action_send_to_desktop_up ||
+ act->func == action_send_to_desktop_down) {
+ if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
+ act->data.sendtodir.wrap = parse_bool(doc, n);
+ if ((n = parse_find_node("follow", node->xmlChildrenNode)))
+ act->data.sendtodir.follow = parse_bool(doc, n);
+ }
+ }
+ }
+ return act;
+}
+
+gboolean parse_attr_contains(const char *val, xmlNodePtr node,
+ const char *name)
+{
+ xmlChar *c = xmlGetProp(node, (const xmlChar*) name);
+ gboolean r;
+ r = !xmlStrcasecmp(c, (const xmlChar*) val);
+ xmlFree(c);
+ return r;
}