diff options
Diffstat (limited to 'openbox')
| -rw-r--r-- | openbox/Makefile.am | 25 | ||||
| -rw-r--r-- | openbox/config.c | 268 | ||||
| -rw-r--r-- | openbox/openbox.c | 2 | ||||
| -rw-r--r-- | openbox/parse.c | 267 | ||||
| -rw-r--r-- | openbox/parse.h | 56 | ||||
| -rw-r--r-- | openbox/parse.l | 45 | ||||
| -rw-r--r-- | openbox/parse.y | 146 |
7 files changed, 342 insertions, 467 deletions
diff --git a/openbox/Makefile.am b/openbox/Makefile.am index 4c83005f..ecb72969 100644 --- a/openbox/Makefile.am +++ b/openbox/Makefile.am @@ -6,7 +6,7 @@ binary=openbox3 url=http://icculus.org/openbox CPPFLAGS=$(X_CFLAGS) $(XFT_CFLAGS) $(GLIB_CFLAGS) $(GMODULE_CFLAGS) \ - $(LIBSN_CFLAGS) $(GL_CFLAGS) @CPPFLAGS@ \ + $(LIBSN_CFLAGS) $(GL_CFLAGS) $(XML_CFLAGS) @CPPFLAGS@ \ -DLOCALEDIR=\"$(localedir)\" \ -DRCDIR=\"$(rcdir)\" \ -DPLUGINDIR=\"$(plugindir)\" \ @@ -16,38 +16,25 @@ CPPFLAGS=$(X_CFLAGS) $(XFT_CFLAGS) $(GLIB_CFLAGS) $(GMODULE_CFLAGS) \ INCLUDES=-I.. LIBS=$(X_LIBS) $(XFT_LIBS) $(XINERAMA_LIBS) $(XKB_LIBS) $(XRANDR_LIBS) \ $(VIDMODE_LIBS) $(XSHAPE_LIBS) $(GLIB_LIBS) $(GMODULE_LIBS) \ - $(LIBSN_LIBS) @LIBS@ @LIBINTL@ + $(LIBSN_LIBS) $(XML_LIBS) @LIBS@ @LIBINTL@ bin_PROGRAMS=$(binary) openbox3_LDADD=-lobrender -L../render openbox3_LDFLAGS=-export-dynamic -openbox3_SOURCES=parse.tab.c parse.lex.c action.c client.c config.c \ +openbox3_SOURCES=action.c client.c config.c parse.c \ extensions.c focus.c frame.c grab.c menu.c menu_render.c \ - openbox.c framerender.c parse.c plugin.c prop.c screen.c \ + openbox.c framerender.c plugin.c prop.c screen.c \ stacking.c dispatch.c event.c group.c timer.c xerror.c \ moveresize.c startup.c popup.c dock.c window.c noinst_HEADERS=action.h client.h config.h dispatch.h event.h extensions.h \ focus.h frame.h framerender.h geom.h gettext.h grab.h group.h \ - menu.h openbox.h parse.h parse.tab.h plugin.h prop.h screen.h \ + menu.h openbox.h plugin.h prop.h screen.h \ stacking.h timer.h xerror.h moveresize.h startup.h popup.h \ - dock.h window.h - -# kill the implicit .c.y rule -%.c: %.y - @ - -%.lex.c: %.l - $(FLEX) -o$@ $< - -%.tab.c: %.y - $(BISON) -d -o $@ $< + dock.h window.h parse.h MAINTAINERCLEANFILES=Makefile.in -clean-local: - $(RM) parse.lex.c parse.tab.c parse.tab.h - distclean-local: $(RM) *\~ *.orig *.rej .\#* diff --git a/openbox/config.c b/openbox/config.c index e751f32b..c3fa786c 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -23,182 +23,114 @@ gboolean config_dock_horz; gboolean config_dock_hide; guint config_dock_hide_timeout; -static void parse_focus(char *name, ParseToken *value) +static void parse_focus(xmlDocPtr doc, xmlNodePtr node, void *d) { - if (!g_ascii_strcasecmp(name, "focusnew")) { - if (value->type != TOKEN_BOOL) - yyerror("invalid value"); - else { - config_focus_new = value->data.bool; - } - } else if (!g_ascii_strcasecmp(name, "followmouse")) { - if (value->type != TOKEN_BOOL) - yyerror("invalid value"); - else { - config_focus_follow = value->data.bool; - } - } else if (!g_ascii_strcasecmp(name, "focuslast")) { - if (value->type != TOKEN_BOOL) - yyerror("invalid value"); - else { - config_focus_last = value->data.bool; - } - } else if (!g_ascii_strcasecmp(name, "focuslastondesktop")) { - if (value->type != TOKEN_BOOL) - yyerror("invalid value"); - else { - config_focus_last_on_desktop = value->data.bool; - } - } else if (!g_ascii_strcasecmp(name, "cyclingdialog")) { - if (value->type != TOKEN_BOOL) - yyerror("invalid value"); - else { - config_focus_popup = value->data.bool; - } - } else - yyerror("invalid option"); - parse_free_token(value); + xmlNodePtr n; + + if ((n = parse_find_node("focusNew", node))) + config_focus_new = parse_bool(doc, n); + if ((n = parse_find_node("followMouse", node))) + config_focus_follow = parse_bool(doc, n); + if ((n = parse_find_node("focusLast", node))) + config_focus_last = parse_bool(doc, n); + if ((n = parse_find_node("focusLastOnDesktop", node))) + config_focus_last_on_desktop = parse_bool(doc, n); + if ((n = parse_find_node("cyclingDialog", node))) + config_focus_popup = parse_bool(doc, n); } -static void parse_theme(char *name, ParseToken *value) +static void parse_theme(xmlDocPtr doc, xmlNodePtr node, void *d) { - if (!g_ascii_strcasecmp(name, "theme")) { - if (value->type != TOKEN_STRING) - yyerror("invalid value"); - else { - g_free(config_theme); - config_theme = g_strdup(value->data.string); - } - } else - yyerror("invalid option"); - parse_free_token(value); + xmlNodePtr n; + + if ((n = parse_find_node("theme", node))) { + g_free(config_theme); + config_theme = parse_string(doc, n); + } } -static void parse_desktops(char *name, ParseToken *value) +static void parse_desktops(xmlDocPtr doc, xmlNodePtr node, void *d) { - GList *it; - - if (!g_ascii_strcasecmp(name, "number")) { - if (value->type != TOKEN_INTEGER) - yyerror("invalid value"); - else { - config_desktops_num = value->data.integer; - } - } else if (!g_ascii_strcasecmp(name, "names")) { - if (value->type == TOKEN_LIST) { - for (it = value->data.list; it; it = it->next) - if (((ParseToken*)it->data)->type != TOKEN_STRING) break; - if (it == NULL) { - /* build a string list */ - g_free(config_desktops_names); - for (it = value->data.list; it; it = it->next) - config_desktops_names = - g_slist_append(config_desktops_names, - g_strdup - (((ParseToken*)it->data)->data.string)); - } else { - yyerror("invalid string in names list"); - } - } else { - yyerror("syntax error (expected list of strings)"); - } - } else - yyerror("invalid option"); - parse_free_token(value); + xmlNodePtr n; + + if ((n = parse_find_node("number", node))) + config_desktops_num = parse_int(doc, n); + if ((n = parse_find_node("names", node))) { + GSList *it; + xmlNodePtr nname; + + for (it = config_desktops_names; it; it = it->next) + g_free(it->data); + g_slist_free(config_desktops_names); + config_desktops_names = NULL; + + nname = parse_find_node("name", n->xmlChildrenNode); + while (nname) { + config_desktops_names = g_slist_append(config_desktops_names, + parse_string(doc, nname)); + nname = parse_find_node("name", nname->next); + } + } } -static void parse_moveresize(char *name, ParseToken *value) +static void parse_moveresize(xmlDocPtr doc, xmlNodePtr node, void *d) { - if (!g_ascii_strcasecmp(name, "opaque_move")) { - if (value->type != TOKEN_BOOL) - yyerror("invalid value"); - else { - config_opaque_move = value->data.integer; - } - } else if (!g_ascii_strcasecmp(name, "opaque_resize")) { - if (value->type != TOKEN_BOOL) - yyerror("invalid value"); - else { - config_opaque_resize = value->data.integer; - } - } else - yyerror("invalid option"); - parse_free_token(value); + xmlNodePtr n; + + if ((n = parse_find_node("opaqueMove", node))) + config_opaque_move = parse_bool(doc, n); + if ((n = parse_find_node("opaqueResize", node))) + config_opaque_resize = parse_bool(doc, n); } -static void parse_dock(char *name, ParseToken *value) +static void parse_dock(xmlDocPtr doc, xmlNodePtr node, void *d) { - if (!g_ascii_strcasecmp(name, "stacking")) { - if (value->type != TOKEN_STRING) - yyerror("invalid value"); - else { - if (!g_ascii_strcasecmp(value->data.string, "bottom")) - config_dock_layer = Layer_Below; - else if (!g_ascii_strcasecmp(value->data.string, "normal")) - config_dock_layer = Layer_Normal; - else if (!g_ascii_strcasecmp(value->data.string, "top")) - config_dock_layer = Layer_Top; - else - yyerror("invalid layer"); - } - } else if (!g_ascii_strcasecmp(name, "position")) { - if (value->type != TOKEN_STRING) - yyerror("invalid value"); - else { - if (!g_ascii_strcasecmp(value->data.string, "topleft")) - config_dock_pos = DockPos_TopLeft; - else if (!g_ascii_strcasecmp(value->data.string, "top")) - config_dock_pos = DockPos_Top; - else if (!g_ascii_strcasecmp(value->data.string, "topright")) - config_dock_pos = DockPos_TopRight; - else if (!g_ascii_strcasecmp(value->data.string, "right")) - config_dock_pos = DockPos_Right; - else if (!g_ascii_strcasecmp(value->data.string, "bottomright")) - config_dock_pos = DockPos_BottomRight; - else if (!g_ascii_strcasecmp(value->data.string, "bottom")) - config_dock_pos = DockPos_Bottom; - else if (!g_ascii_strcasecmp(value->data.string, "bottomleft")) - config_dock_pos = DockPos_BottomLeft; - else if (!g_ascii_strcasecmp(value->data.string, "left")) - config_dock_pos = DockPos_Left; - else if (!g_ascii_strcasecmp(value->data.string, "floating")) - config_dock_pos = DockPos_Floating; - else - yyerror("invalid position"); - } - } else if (!g_ascii_strcasecmp(name, "floatingx")) { - if (value->type != TOKEN_INTEGER) - yyerror("invalid value"); - else { - config_dock_x = value->data.integer; - } - } else if (!g_ascii_strcasecmp(name, "floatingy")) { - if (value->type != TOKEN_INTEGER) - yyerror("invalid value"); - else { - config_dock_y = value->data.integer; - } - } else if (!g_ascii_strcasecmp(name, "horizontal")) { - if (value->type != TOKEN_BOOL) - yyerror("invalid value"); - else { - config_dock_horz = value->data.bool; - } - } else if (!g_ascii_strcasecmp(name, "autohide")) { - if (value->type != TOKEN_BOOL) - yyerror("invalid value"); - else { - config_dock_hide = value->data.bool; - } - } else if (!g_ascii_strcasecmp(name, "hidetimeout")) { - if (value->type != TOKEN_INTEGER) - yyerror("invalid value"); - else { - config_dock_hide_timeout = value->data.integer; - } - } else - yyerror("invalid option"); - parse_free_token(value); + xmlNodePtr n; + + if ((n = parse_find_node("position", node))) { + if (parse_contains("TopLeft", doc, n)) + config_dock_pos = DockPos_TopLeft; + else if (parse_contains("Top", doc, n)) + config_dock_pos = DockPos_Top; + else if (parse_contains("TopRight", doc, n)) + config_dock_pos = DockPos_TopRight; + else if (parse_contains("Right", doc, n)) + config_dock_pos = DockPos_Right; + else if (parse_contains("BottomRight", doc, n)) + config_dock_pos = DockPos_BottomRight; + else if (parse_contains("Bottom", doc, n)) + config_dock_pos = DockPos_Bottom; + else if (parse_contains("BottomLeft", doc, n)) + config_dock_pos = DockPos_BottomLeft; + else if (parse_contains("Left", doc, n)) + config_dock_pos = DockPos_Left; + else if (parse_contains("Floating", doc, n)) + config_dock_pos = DockPos_Floating; + } + if (config_dock_pos == DockPos_Floating) { + if ((n = parse_find_node("floatingX", node))) + config_dock_x = parse_int(doc, n); + if ((n = parse_find_node("floatingY", node))) + config_dock_y = parse_int(doc, n); + } + if ((n = parse_find_node("stacking", node))) { + if (parse_contains("top", doc, n)) + config_dock_layer = Layer_Top; + else if (parse_contains("normal", doc, n)) + config_dock_layer = Layer_Normal; + else if (parse_contains("bottom", doc, n)) + config_dock_layer = Layer_Below; + } + if ((n = parse_find_node("direction", node))) { + if (parse_contains("horizontal", doc, n)) + config_dock_horz = TRUE; + else if (parse_contains("vertical", doc, n)) + config_dock_horz = FALSE; + } + if ((n = parse_find_node("autoHide", node))) + config_dock_hide = parse_bool(doc, n); + if ((n = parse_find_node("hideTimeout", node))) + config_dock_hide_timeout = parse_int(doc, n); } void config_startup() @@ -209,21 +141,21 @@ void config_startup() config_focus_last_on_desktop = TRUE; config_focus_popup = TRUE; - parse_reg_section("focus", NULL, parse_focus); + parse_register("focus", parse_focus, NULL); config_theme = NULL; - parse_reg_section("theme", NULL, parse_theme); + parse_register("theme", parse_theme, NULL); config_desktops_num = 4; config_desktops_names = NULL; - parse_reg_section("desktops", NULL, parse_desktops); + parse_register("desktops", parse_desktops, NULL); config_opaque_move = TRUE; config_opaque_resize = TRUE; - parse_reg_section("moveresize", NULL, parse_moveresize); + parse_register("moveresize", parse_moveresize, NULL); config_dock_layer = Layer_Top; config_dock_pos = DockPos_TopRight; @@ -233,7 +165,7 @@ void config_startup() config_dock_hide = FALSE; config_dock_hide_timeout = 3000; - parse_reg_section("dock", NULL, parse_dock); + parse_register("dock", parse_dock, NULL); } void config_shutdown() diff --git a/openbox/openbox.c b/openbox/openbox.c index 3b2a9991..2b4dddce 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -180,7 +180,7 @@ int main(int argc, char **argv) /* set up the kernel config shit */ config_startup(); /* parse/load user options */ - parse_rc(); + parse_config(); /* we're done with parsing now, kill it */ parse_shutdown(); 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; } diff --git a/openbox/parse.h b/openbox/parse.h index abd5bb2d..199e8104 100644 --- a/openbox/parse.h +++ b/openbox/parse.h @@ -1,48 +1,38 @@ #ifndef __parse_h #define __parse_h +#include "action.h" + +#include <libxml/parser.h> #include <glib.h> -#ifndef NO_TAB_H -#include "parse.tab.h" -#endif -typedef enum { - TOKEN_REAL = REAL, - TOKEN_INTEGER = INTEGER, - TOKEN_STRING = STRING, - TOKEN_IDENTIFIER = IDENTIFIER, - TOKEN_BOOL = BOOLEAN, - TOKEN_LIST, - TOKEN_LBRACE = '{', - TOKEN_RBRACE = '}', - TOKEN_COMMA = ',', - TOKEN_NEWLINE = '\n' -} ParseTokenType; - -typedef struct { - ParseTokenType type; - union ParseTokenData data; -} ParseToken; - -typedef void (*ParseFunc)(ParseToken *token); -typedef void (*AssignParseFunc)(char *name, ParseToken *value); +typedef void (*ParseCallback)(xmlDocPtr doc, xmlNodePtr node, void *data); void parse_startup(); void parse_shutdown(); -/* Parse the RC file - found in parse.yacc -*/ -void parse_rc(); +void parse_register(const char *tag, ParseCallback func, void *data); + +void parse_config(); + +void parse_tree(xmlDocPtr doc, xmlNodePtr node, void *nothing); + + +/* helpers */ + +xmlNodePtr parse_find_node(const char *tag, xmlNodePtr node); -void parse_reg_section(char *section, ParseFunc func, AssignParseFunc afunc); +char *parse_string(xmlDocPtr doc, xmlNodePtr node); +int parse_int(xmlDocPtr doc, xmlNodePtr node); +gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node); +gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node); +gboolean parse_attr_contains(const char *val, xmlNodePtr node, + const char *name); -/* Free a parsed token's allocated memory */ -void parse_free_token(ParseToken *token); +gboolean parse_attr_string(const char *name, xmlNodePtr node, char **value); +gboolean parse_attr_int(const char *name, xmlNodePtr node, int *value); -/* Display an error message while parsing. - found in parse.yacc */ -void yyerror(char *err); +Action *parse_action(xmlDocPtr doc, xmlNodePtr node); #endif diff --git a/openbox/parse.l b/openbox/parse.l deleted file mode 100644 index a7cd6c63..00000000 --- a/openbox/parse.l +++ /dev/null @@ -1,45 +0,0 @@ -%{ -#include "parse.h" -#ifdef HAVE_STDLIB_H -# include <stdlib.h> -#endif - -extern int lineno; -%} - -real [-0-9][0-9]*\.[0-9]+ -integer [-0-9][0-9]* -string \"[^"\n]*\" -identifier [a-zA-Z][-.a-zA-Z0-9_]* -bool ([tT][rR][uU][eE]|[fF][aA][lL][sS][eE]|[yY][eE][sS]|[nN][oO]|[oO][nN]|[oO][fF][fF]) - -%% - -^[ \t]*#.*\n /* comment */ { ++lineno; } -^[ \t]*#.* /* comment */ -^[ \t]*\n /* empty lines */ { ++lineno; } -[ \t] /* whitespace */ -{real} { yylval.real = atof(yytext); return REAL; } -{integer} { yylval.integer = atoi(yytext); return INTEGER; } -{string} { yylval.string = g_strdup(yytext+1); /* drop the left quote */ - if (yylval.string[yyleng-2] != '"') - yyerror("improperly terminated string on line %d"); - else - yylval.string[yyleng-2] = '\0'; - return STRING; - } -{bool} { yylval.bool = (!g_ascii_strcasecmp("true", yytext) || - !g_ascii_strcasecmp("yes", yytext) || - !g_ascii_strcasecmp("on", yytext)); - return BOOLEAN; - } -{identifier} { yylval.identifier = g_strdup(yytext); return IDENTIFIER; } -[{}()\[\]=,] { yylval.character = *yytext; return *yytext; } -\n { yylval.character = *yytext; return *yytext; } -. { return INVALID; } - -%% - -int yywrap() { - return 1; -} diff --git a/openbox/parse.y b/openbox/parse.y deleted file mode 100644 index 7e92efd6..00000000 --- a/openbox/parse.y +++ /dev/null @@ -1,146 +0,0 @@ -%{ -#include <glib.h> -#ifdef HAVE_STDIO_H -# include <stdio.h> -#endif - -%} - -%union ParseTokenData { - float real; - int integer; - char *string; - char *identifier; - gboolean bool; - char character; - GList *list; -} - -%{ -#define NO_TAB_H -#include "parse.h" -#undef NO_TAB_H - -extern int yylex(); -extern int yyparse(); -void yyerror(char *err); - -extern int lineno; -extern FILE *yyin; - -static char *path; -static ParseToken t; - -/* in parse.c */ -void parse_token(ParseToken *token); -void parse_assign(char *name, ParseToken *token); -void parse_set_section(char *section); -%} - -%token <real> REAL -%token <integer> INTEGER -%token <string> STRING -%token <identifier> IDENTIFIER -%token <bool> BOOLEAN -%token <character> '(' -%token <character> ')' -%token <character> '{' -%token <character> '}' -%token <character> '=' -%token <character> ',' -%token <character> '\n' -%token INVALID - -%type <list> list -%type <list> listtokens - -%% - -sections: - | sections '[' IDENTIFIER ']' { parse_set_section($3); } '\n' - { ++lineno; } lines - ; - -lines: - | lines tokens { t.type='\n'; t.data.character='\n'; parse_token(&t); } '\n' - { ++lineno; } - | lines IDENTIFIER '=' listtoken { parse_assign($2, &t); } '\n' - { ++lineno; } - ; - -tokens: - tokens token { parse_token(&t); } - | token { parse_token(&t); } - ; - -token: - REAL { t.type = TOKEN_REAL; t.data.real = $1; } - | INTEGER { t.type = TOKEN_INTEGER; t.data.integer = $1; } - | STRING { t.type = TOKEN_STRING; t.data.string = $1; } - | IDENTIFIER { t.type = TOKEN_IDENTIFIER; t.data.identifier = $1; } - | BOOLEAN { t.type = TOKEN_BOOL; t.data.bool = $1; } - | list { t.type = TOKEN_LIST; t.data.list = $1; } - | '{' { t.type = $1; t.data.character = $1; } - | '}' { t.type = $1; t.data.character = $1; } - | ',' { t.type = $1; t.data.character = $1; } - ; - -list: - '(' listtokens ')' { $$ = $2; } - ; - -listtokens: - listtokens listtoken { ParseToken *nt = g_new(ParseToken, 1); - nt->type = t.type; - nt->data = t.data; - $$ = g_list_append($1, nt); - } - | listtoken { ParseToken *nt = g_new(ParseToken, 1); - nt->type = t.type; - nt->data = t.data; - $$ = g_list_append(NULL, nt); - } - ; - -listtoken: - REAL { t.type = TOKEN_REAL; t.data.real = $1; } - | INTEGER { t.type = TOKEN_INTEGER; t.data.integer = $1; } - | STRING { t.type = TOKEN_STRING; t.data.string = $1; } - | IDENTIFIER { t.type = TOKEN_IDENTIFIER; t.data.identifier = $1; } - | BOOLEAN { t.type = TOKEN_BOOL; t.data.bool = $1; } - | list { t.type = TOKEN_LIST; t.data.list = $1; } - | '{' { t.type = $1; t.data.character = $1; } - | '}' { t.type = $1; t.data.character = $1; } - | ',' { t.type = $1; t.data.character = $1; } - ; - - -%% - -int lineno; - -void yyerror(char *err) { - g_message("%s:%d: %s", path, lineno, err); -} - -void parse_rc() -{ - /* try the user's rc */ - path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL); - if ((yyin = fopen(path, "r")) == NULL) { - g_free(path); - /* try the system wide rc */ - path = g_build_filename(RCDIR, "rc3", NULL); - if ((yyin = fopen(path, "r")) == NULL) { - g_warning("No rc2 file found!"); - g_free(path); - return; - } - } - - lineno = 1; - - yyparse(); - - g_free(path); -} |
