]> Dogcows Code - chaz/openbox/commitdiff
create a generic tokenizer/sectionizer for the config file. pass off the token to...
authorDana Jansens <danakj@orodu.net>
Wed, 2 Apr 2003 07:46:46 +0000 (07:46 +0000)
committerDana Jansens <danakj@orodu.net>
Wed, 2 Apr 2003 07:46:46 +0000 (07:46 +0000)
13 files changed:
engines/openbox/Makefile.am
engines/openbox/obengine.c
engines/openbox/obengine.h
engines/openbox/obtheme.c
openbox/Makefile.am
openbox/config.c
openbox/config.h
openbox/cparse.l [deleted file]
openbox/openbox.c
openbox/parse.c [new file with mode: 0644]
openbox/parse.h [new file with mode: 0644]
openbox/parse.l [new file with mode: 0644]
openbox/parse.yacc [new file with mode: 0644]

index 800956d9e593ba3977a212bfca5f2ce170a307d1..33efbb71e60602010f70d10b17cf588c7a3837d8 100644 (file)
@@ -5,7 +5,6 @@ CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \
 -DENGINEDIR=\"$(enginedir)\" \
 -DTHEMEDIR=\"$(themedir)\" \
 -DDEFAULT_THEME=\"nyz\" \
--DDEFAULT_FONT=\"Sans-7\" \
 -DG_LOG_DOMAIN=\"Openbox-Engine\"
 
 engine_LTLIBRARIES=openbox.la
index b6b9638f3da723c96a997622b98d05b7494d93f1..f98bb36c526b91a0e839e71cf31669e30138510e 100644 (file)
@@ -36,6 +36,7 @@ color_rgb *ob_s_titlebut_unfocused_color;
 int ob_s_winfont_height;
 int ob_s_winfont_shadow;
 int ob_s_winfont_shadow_offset;
+int ob_s_winfont_shadow_tint;
 ObFont *ob_s_winfont;
 /* style settings - masks */
 pixmap_mask *ob_s_max_set_mask;
@@ -495,7 +496,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved, gboolean resized)
         self->icon_x = -1;
         self->desk_x = -1;
         self->shade_x = -1;
-        self->icon_x = -1;
+        self->iconify_x = -1;
         self->label_x = -1;
         self->max_x = -1;
         self->close_x = -1;
@@ -712,10 +713,8 @@ static void layout_title(ObFrame *self)
 
     n = d = i = l = m = c = s = FALSE;
 
-    if (!config_get("titlebar.layout", Config_String, &layout)) {
-        layout.string = "NDSLIMC";
-        config_set("titlebar.layout", Config_String, layout);
-    }
+    if (!config_get("titlebar.layout", Config_String, &layout))
+        g_assert_not_reached();
 
     /* figure out whats being shown, and the width of the label */
     self->label_width = self->width - (ob_s_bevel + 1) * 2;
index 4f9cb5b602c68d980fe364590179bf7e1bd54f11..b4e469834d495e8d23f4c711a82826e62b7b727f 100644 (file)
@@ -30,6 +30,7 @@ extern color_rgb *ob_s_titlebut_unfocused_color;
 extern int ob_s_winfont_height;
 extern int ob_s_winfont_shadow;
 extern int ob_s_winfont_shadow_offset;
+extern int ob_s_winfont_shadow_tint;
 extern ObFont *ob_s_winfont;
 
 extern pixmap_mask *ob_s_max_set_mask;
index ccd17cc0bf7da1ff8f1c629703cf834c274bb38a..3f45c20949ec24e503fc2ee0b8a9571dfe030b47 100644 (file)
@@ -277,7 +277,7 @@ gboolean obtheme_load()
     XrmDatabase db = NULL;
     Justify winjust;
     char *winjuststr;
-    ConfigValue theme, shadow, offset, font;
+    ConfigValue theme, shadow, offset, font, tint;
 
     if (config_get("theme", Config_String, &theme)) {
        db = loaddb(theme.string);
@@ -299,21 +299,21 @@ gboolean obtheme_load()
 
     /* load the font, not from the theme file tho, its in the config */
 
-    if (!config_get("font.shadow", Config_Bool, &shadow)) {
-        shadow.bool = TRUE; /* default */
-        config_set("font.shadow", Config_Bool, shadow);
-    }
+    if (!config_get("font.shadow", Config_Bool, &shadow))
+        g_assert_not_reached();
     ob_s_winfont_shadow = shadow.bool;
-    if (!config_get("font.shadow.offset", Config_Integer, &offset) ||
-        offset.integer < 0 || offset.integer >= 10) {
-        offset.integer = 1; /* default */
-        config_set("font.shadow.offset", Config_Integer, offset);
-    }
+    if (!config_get("font.shadow.offset", Config_Integer, &offset))
+        g_assert_not_reached();
     ob_s_winfont_shadow_offset = offset.integer;
-    if (!config_get("font", Config_String, &font)) {
-        font.string = DEFAULT_FONT;
-        config_set("font", Config_String, font);
-    }
+    if (!config_get("font.shadow.tint", Config_Integer, &tint))
+        g_assert_not_reached();
+    /* XXX put these checks into the config system somehow!!! */
+    if (tint.integer < -100) tint.integer = -100;
+    if (tint.integer > 100) tint.integer = 100;
+    config_set("font.shadow.tint", Config_Integer, tint);
+    ob_s_winfont_shadow_tint = tint.integer;
+    if (!config_get("font", Config_String, &font))
+        g_assert_not_reached();
     ob_s_winfont = font_open(font.string);
     ob_s_winfont_height = font_height(ob_s_winfont, ob_s_winfont_shadow,
                                       ob_s_winfont_shadow_offset);
@@ -495,6 +495,7 @@ gboolean obtheme_load()
     ob_a_focused_label->texture[0].data.text.shadow = ob_s_winfont_shadow;
     ob_a_focused_label->texture[0].data.text.offset =
         ob_s_winfont_shadow_offset;
+    ob_a_focused_label->texture[0].data.text.tint = ob_s_winfont_shadow_tint;
     ob_a_focused_label->texture[0].data.text.color = ob_s_title_focused_color;
 
     ob_a_unfocused_label->texture[0].type = Text;
@@ -503,6 +504,7 @@ gboolean obtheme_load()
     ob_a_unfocused_label->texture[0].data.text.shadow = ob_s_winfont_shadow;
     ob_a_unfocused_label->texture[0].data.text.offset =
         ob_s_winfont_shadow_offset;
+    ob_a_unfocused_label->texture[0].data.text.tint = ob_s_winfont_shadow_tint;
     ob_a_unfocused_label->texture[0].data.text.color =
         ob_s_title_unfocused_color;
 
index d691cbcdcd5f8b08583360e677438e666af76965..33355cb387a895ed9004741b299c4b30f5b7e8a9 100644 (file)
@@ -27,14 +27,18 @@ openbox3_LDADD=@LIBINTL@ ../render/librender.a
 openbox3_LDFLAGS=-export-dynamic
 openbox3_SOURCES=client.c event.c extensions.c focus.c frame.c openbox.c \
        prop.c screen.c stacking.c xerror.c timer.c dispatch.c \
-       engine.c plugin.c action.c grab.c lex.cparse.c config.c menu.c
+       engine.c plugin.c action.c grab.c config.c menu.c \
+       y.tab.c lex.yy.c parse.c
 
 noinst_HEADERS=client.h event.h extensions.h focus.h frame.h geom.h gettext.h \
        openbox.h prop.h screen.h stacking.h xerror.h dispatch.h \
-       timer.h engine.h plugin.h action.h grab.h config.h menu.h
+       timer.h engine.h plugin.h action.h grab.h config.h menu.h parse.h
 
-lex.cparse.c: cparse.l
-       $(FLEX) -Pcparse $^
+lex.yy.c: parse.l
+       $(FLEX) $^
+
+y.tab.c: parse.yacc
+       $(YACC) -d $<
 
 MAINTAINERCLEANFILES= Makefile.in
 
index 6a6bd901019ec2de2c86a2eb1d27b28fde9ec532..a6056ee14d9bad0c205a1783f93975cf53ecb2bd 100644 (file)
@@ -25,26 +25,47 @@ void config_startup()
                                   "Engine",
                                   "The name of the theming engine to be used "
                                   "to decorate windows."));
+
     config_def_set(config_def_new("theme", Config_String,
                                   "Theme",
                                   "The name of the theme to load with the "
                                   "chosen engine."));
+
     config_def_set(config_def_new("font", Config_String,
                                   "Titlebar Font",
                                   "The fontstring specifying the font to "
                                   "be used in window titlebars."));
+    val.string = "Sans-7";
+    config_set("font", Config_String, val);
+
     config_def_set(config_def_new("font.shadow", Config_Bool,
                                   "Titlebar Font Shadow",
                                   "Whether or not the text in the window "
                                   "titlebars gets a drop shadow."));
+    val.bool = FALSE;
+    config_set("font.shadow", Config_Bool, val);
+
     config_def_set(config_def_new("font.shadow.offset", Config_Integer,
                                   "Titlebar Font Shadow Offset",
                                   "The offset of the drop shadow for text "
                                   "in the window titlebars."));
+    val.integer = 1;
+    config_set("font.shadow.offset", Config_Integer, val);
+
+    config_def_set(config_def_new("font.shadow.tint", Config_Integer,
+                                  "Titlebar Font Shadow Tint",
+                                  "The percentage of tint/opacity to give the "
+                                  "the shadow(from -100(white) to "
+                                  "100(black))."));
+    val.integer = 25;
+    config_set("font.shadow.tint", Config_Integer, val);
+
     config_def_set(config_def_new("titlebar.layout", Config_String,
                                   "Titlebar Layout",
                                   "The ordering of the elements in the "
                                   "window titlebars."));
+    val.string = "NDSLIMC";
+    config_set("titlebar.layout", Config_String, val);
 
     config_def_set(config_def_new("focusNew", Config_Bool,
                                   "Focus New Windows",
@@ -66,32 +87,6 @@ void config_shutdown()
     g_datalist_clear(&config_def);
 }
 
-void config_parse()
-{
-    FILE *file;
-    char *path;
-    gboolean load = FALSE;
-
-    /* load the user rc */
-    path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
-    if ((file = fopen(path, "r")) != NULL) {
-        cparse_go(path, file);
-        fclose(file);
-        load = TRUE;
-    }
-    g_free(path);
-
-    if (!load) {
-        /* load the system wide rc */
-        path = g_build_filename(RCDIR, "rc3", NULL);
-        if ((file = fopen(path, "r")) != NULL) {
-            /*cparse_go(path, file);*/
-            fclose(file);
-        }
-        g_free(path);
-    }
-}
-
 gboolean config_set(char *name, ConfigValueType type, ConfigValue value)
 {
     ConfigDefEntry *def;
index 9b62b8e5e009527fb483653290ef34f5d19d45b0..3d82090ba391f39e3198ee6afd463960e0ae4867 100644 (file)
@@ -54,6 +54,4 @@ gboolean config_def_add_value(ConfigDefEntry *entry, char *value);
    FALSE. */
 gboolean config_def_set(ConfigDefEntry *entry);
 
-void config_parse();
-
 #endif
diff --git a/openbox/cparse.l b/openbox/cparse.l
deleted file mode 100644 (file)
index 7052400..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-%{
-#include <glib.h>
-#include "config.h"
-
-static char *filename;
-static int lineno = 1;
-static gboolean haserror = FALSE;
-static gboolean comment = FALSE;
-static ConfigEntry entry = { NULL, -1 };
-
-static void stringvalue();
-static void numbervalue();
-static void boolvalue();
-static void identifier();
-static void newline();
-static int cparsewrap();
-%}
-
-number [0-9]+
-string \"[^"\n]*\"
-identifier [a-zA-Z][a-zA-Z0-9_.]*
-white [ \t]*
-assign {white}={white}
-bool ([tT][rR][uU][eE]|[fF][aA][lL][sS][eE]|[yY][eE][sS]|[nN][oO]|[oO][nN]|[oO][fF][fF])
-
-%%
-
-^{white}# comment = TRUE;
-{bool}/{white}\n boolvalue();
-{string}/{white}\n stringvalue();
-{number}/{white}\n numbervalue();
-^{identifier}/{assign} identifier();
-\n newline();
-=
-[ \t]
-. if (!comment) haserror = TRUE;
-
-%%
-
-static void stringvalue()
-{
-    if (!comment) {
-        if (!haserror && entry.name != NULL && (signed)entry.type < 0) {
-            entry.type = Config_String;
-            entry.value.string = g_strdup(cparsetext+1); /* drop the left quote */
-            if (entry.value.string[cparseleng-2] != '"')
-                g_warning("improperly terminated string on line %d",
-                          lineno);
-            else
-                entry.value.string[cparseleng-2] = '\0';
-        } else
-            haserror = TRUE;
-    }
-}
-
-static void numbervalue()
-{
-    if (!comment) {
-        if (!haserror && entry.name != NULL && (signed)entry.type < 0) {
-            entry.type = Config_Integer;
-            entry.value.integer = atoi(cparsetext);
-        } else
-            haserror = TRUE;
-    }
-}
-
-static void boolvalue()
-{
-    if (!comment) {
-        if (!haserror && entry.name != NULL && (signed)entry.type < 0) {
-            entry.type = Config_Bool;
-            entry.value.bool = (!g_ascii_strcasecmp("true", cparsetext) ||
-                                !g_ascii_strcasecmp("yes", cparsetext) ||
-                                !g_ascii_strcasecmp("on", cparsetext));
-        } else
-            haserror = TRUE;
-    }
-}
-
-static void identifier()
-{
-    if (!comment) {
-        entry.name = g_strdup(cparsetext);
-        entry.type = -1;
-    }
-}
-
-static void newline()
-{
-    if (!comment) {
-        if (!haserror && entry.name != NULL && (signed)entry.type >= 0) {
-            if (!config_set(entry.name, entry.type, entry.value))
-                g_warning("Parser error in '%s' on line %d\n", filename,
-                          lineno);
-        } else if (haserror || entry.name != NULL || (signed)entry.type >= 0) {
-            g_warning("Parser error in '%s' on line %d", filename, lineno);
-        }
-        g_free(entry.name);
-        entry.name = NULL;
-        if (entry.type == Config_String)
-            g_free(entry.value.string);
-        entry.type = -1;
-
-        haserror = FALSE;
-    }
-    comment = FALSE;
-    ++lineno;
-}
-
-static int cparsewrap()
-{
-    g_free(entry.name);
-    entry.name = NULL;
-    if (entry.type == Config_String)
-        g_free(entry.value.string);
-    return 1;
-}
-
-void cparse_go(char *fname, FILE *file)
-{
-    filename = fname;
-    cparsein = file;
-    cparselex();
-}
index 117349f23972910cb05c2f7d3844deb0e94473e2..a7357b2ffe2ff3b2513383b73b01864d66e4dd3d 100644 (file)
@@ -9,6 +9,7 @@
 #include "extensions.h"
 #include "gettext.h"
 #include "config.h"
+#include "parse.h"
 #include "grab.h"
 #include "engine.h"
 #include "plugin.h"
@@ -145,7 +146,7 @@ int main(int argc, char **argv)
 
     prop_startup(); /* get atoms values for the display */
     extensions_query_all(); /* find which extensions are present */
-     
+
     if (screen_annex()) { /* it will be ours! */
        timer_startup();
         config_startup();
@@ -153,10 +154,16 @@ int main(int argc, char **argv)
        font_startup();
         plugin_startup();
 
+        /* startup the parsing so plugins can register sections of the rc */
+        parse_startup();
+
         /* load the plugins specified in the pluginrc */
         plugin_loadall();
         /* parse/load user options */
-        config_parse();
+        parse_rc();
+
+        /* we're done with parsing now, kill it */
+        parse_shutdown();
 
        engine_startup();
        event_startup();
diff --git a/openbox/parse.c b/openbox/parse.c
new file mode 100644 (file)
index 0000000..f8f0cd9
--- /dev/null
@@ -0,0 +1,137 @@
+#include "parse.h"
+#include "config.h"
+
+static GHashTable *reg = NULL;
+static ParseFunc func = NULL;
+
+/* parse tokens from the [openbox] section of the rc file */
+static void parse_rc_token(ParseTokenType type, union ParseToken token);
+
+void destkey(gpointer key) { g_free(key); }
+
+void parse_startup()
+{
+    reg = g_hash_table_new_full(g_str_hash, g_str_equal, destkey, NULL);
+    func = NULL;
+
+    parse_reg_section("openbox", parse_rc_token);
+}
+
+void parse_shutdown()
+{
+    g_hash_table_destroy(reg);
+}
+
+void parse_reg_section(char *section, ParseFunc func)
+{
+    if (g_hash_table_lookup(reg, section) != NULL)
+        g_warning("duplicate request for section '%s' in the rc file",
+                  section);
+    else
+        g_hash_table_insert(reg, g_ascii_strdown(section, -1), (void*)func);
+}
+
+void parse_free_token(ParseTokenType type, union ParseToken token)
+{
+    switch (type) {
+    case TOKEN_STRING:
+        g_free(token.string);
+        break;
+    case TOKEN_IDENTIFIER:
+        g_free(token.identifier);
+        break;
+    case TOKEN_REAL:
+    case TOKEN_INTEGER:
+    case TOKEN_BOOL:
+    case TOKEN_LBRACKET:
+    case TOKEN_RBRACKET:
+    case TOKEN_LBRACE:
+    case TOKEN_RBRACE:
+    case TOKEN_EQUALS:
+    case TOKEN_COMMA:
+    case TOKEN_NEWLINE:
+        break;
+    }
+}
+
+void parse_set_section(char *section)
+{
+    func = (ParseFunc)g_hash_table_lookup(reg, section);
+}
+
+void parse_token(ParseTokenType type, union ParseToken token)
+{
+    if (func != NULL)
+        func(type, token);
+}
+
+static void parse_rc_token(ParseTokenType type, union ParseToken token)
+{
+    static int got_eq = FALSE;
+    static ParseTokenType got_val = 0;
+    static char *id = NULL, *s = NULL;
+    static int i;
+    static gboolean b;
+
+    if (id == NULL) {
+        if (type == TOKEN_IDENTIFIER) {
+            id = token.identifier;
+            return;
+        } else {
+            yyerror("syntax error");
+        }
+    } else if (!got_eq) {
+        if (type == TOKEN_EQUALS) {
+            got_eq = TRUE;
+            return;
+        } else {
+            yyerror("syntax error");
+        }
+    } else if (!got_val) {
+        if (type == TOKEN_STRING) {
+            s = token.string;
+            got_val = type;
+            return;
+        } else if (type == TOKEN_BOOL) {
+            b = token.bool;
+            got_val = type;
+            return;
+        } else if (type == TOKEN_INTEGER) {
+            i = token.integer;
+            got_val = type;
+            return;
+        } else
+            yyerror("syntax error");
+    } else if (type != TOKEN_NEWLINE) {
+        yyerror("syntax error");
+    } else {
+        ConfigValue v;
+
+        switch (got_val) {
+        case TOKEN_STRING:
+            v.string = s;
+            if (!config_set(id, Config_String, v))
+                yyerror("invalid value type");
+            break;
+        case TOKEN_BOOL:
+            v.bool = b;
+            if (!config_set(id, Config_Bool, v))
+                yyerror("invalid value type");
+            break;
+        case TOKEN_INTEGER:
+            v.integer = i;
+            if (!config_set(id, Config_Integer, v))
+                yyerror("invalid value type");
+            break;
+        default:
+            g_assert_not_reached(); /* unhandled type got parsed */
+        }
+    }
+
+    g_free(id);
+    g_free(s);
+    id = s = NULL;
+    got_eq = FALSE;
+    got_val = 0;
+    parse_free_token(type, token);
+}
diff --git a/openbox/parse.h b/openbox/parse.h
new file mode 100644 (file)
index 0000000..3c649db
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef __parse_h
+#define __parse_h
+
+#include <glib.h>
+#include "y.tab.h"
+
+typedef enum {
+    TOKEN_REAL       = REAL,
+    TOKEN_INTEGER    = INTEGER,
+    TOKEN_STRING     = STRING,
+    TOKEN_IDENTIFIER = IDENTIFIER,
+    TOKEN_BOOL       = BOOL,
+    TOKEN_LBRACKET   = '(',
+    TOKEN_RBRACKET   = ')',
+    TOKEN_LBRACE     = '{',
+    TOKEN_RBRACE     = '}',
+    TOKEN_EQUALS     = '=',
+    TOKEN_COMMA      = ',',
+    TOKEN_NEWLINE    = '\n'
+} ParseTokenType;
+
+typedef void (*ParseFunc)(ParseTokenType type, union ParseToken token);
+
+void parse_startup();
+void parse_shutdown();
+
+/* Parse the RC file
+   found in parse.yacc
+*/
+void parse_rc();
+
+void parse_reg_section(char *section, ParseFunc func);
+
+
+/* Free a parsed token's allocated memory */
+void parse_free_token(ParseTokenType type, union ParseToken token);
+
+/* Display an error message while parsing.
+   found in parse.yacc */
+void yyerror(char *err);
+
+#endif
diff --git a/openbox/parse.l b/openbox/parse.l
new file mode 100644 (file)
index 0000000..c888b9f
--- /dev/null
@@ -0,0 +1,48 @@
+%{
+#include <glib.h>
+#include "y.tab.h"
+#ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+#endif
+
+extern void yyerror(char *err);
+
+int yylineno = 1;
+%}
+
+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 */ { ++yylineno; }
+^[ \t]*#.*   /* comment */
+^[ \t]*\n    /* empty lines */ { ++yylineno; }
+[ \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 BOOL;
+             }
+{identifier} { yylval.identifier = g_strdup(yytext); return IDENTIFIER; }
+[{}()\[\]=,] { yylval.character = *yytext; return *yytext; }
+\n           { yylval.character = *yytext; ++yylineno; return *yytext; }
+.            { return INVALID; }
+
+%%
+
+int yywrap() {
+    return 1;
+}
diff --git a/openbox/parse.yacc b/openbox/parse.yacc
new file mode 100644 (file)
index 0000000..e9b469e
--- /dev/null
@@ -0,0 +1,98 @@
+%{
+#include "parse.h"
+#ifdef HAVE_STDIO_H
+#  include <stdio.h>
+#endif
+
+extern int yylex();
+
+extern int yylineno;
+extern FILE *yyin;
+
+static char *path;
+static union ParseToken t;
+
+/* in parse.c */
+void parse_token(ParseTokenType type, union ParseToken token);
+void parse_set_section(char *section);
+%}
+
+%union ParseToken {
+    float real;
+    int integer;
+    char *string;
+    char *identifier;
+    gboolean bool;
+    char character;
+}
+
+%token <real> REAL
+%token <integer> INTEGER
+%token <string> STRING
+%token <identifier> IDENTIFIER
+%token <bool> BOOL
+%token <character> '('
+%token <character> ')'
+%token <character> '{'
+%token <character> '}'
+%token <character> '='
+%token <character> ','
+%token <character> '\n'
+%token INVALID
+
+%%
+
+sections:
+  | sections '[' IDENTIFIER ']' { parse_set_section($3); } '\n' lines
+  ;
+
+lines:
+  | lines tokens '\n' { t.character = $3; parse_token(TOKEN_NEWLINE, t); }
+  ;
+
+tokens:
+    tokens token
+  | token
+  ;
+
+token:
+    REAL       { t.real = $1; parse_token(TOKEN_REAL, t); }
+  | INTEGER    { t.integer = $1; parse_token(TOKEN_INTEGER, t); }
+  | STRING     { t.string = $1; parse_token(TOKEN_STRING, t); }
+  | IDENTIFIER { t.identifier = $1; parse_token(TOKEN_IDENTIFIER, t); }
+  | BOOL       { t.bool = $1; parse_token(TOKEN_BOOL, t); }
+  | '('        { t.character = $1; parse_token(TOKEN_LBRACKET, t); }
+  | ')'        { t.character = $1; parse_token(TOKEN_RBRACKET, t); }
+  | '{'        { t.character = $1; parse_token(TOKEN_LBRACE, t); }
+  | '}'        { t.character = $1; parse_token(TOKEN_RBRACE, t); }
+  | '='        { t.character = $1; parse_token(TOKEN_EQUALS, t); }
+  | ','        { t.character = $1; parse_token(TOKEN_COMMA, t); }
+  ;
+
+%%
+
+void yyerror(char *err) {
+    g_message("%s:%d: %s", path, yylineno, 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;
+        }
+    }
+
+    yylineno = 1;
+
+    yyparse();
+
+    g_free(path);
+}
This page took 0.045662 seconds and 4 git commands to generate.