move the openbox engine into librender and the kernel. the theme is loaded and stored...
[dana/openbox.git] / openbox / parse.y
1 %{
2 #include <glib.h>
3 #ifdef HAVE_STDIO_H
4 #  include <stdio.h>
5 #endif
6
7 %}
8
9 %union ParseTokenData {
10     float real;
11     int integer;
12     char *string;
13     char *identifier;
14     gboolean bool;
15     char character;
16     GList *list;
17 }
18
19 %{
20 #include "parse.h"
21
22 extern int yylex();
23 extern int yyparse();
24 void yyerror(char *err);
25
26 extern int lineno;
27 extern FILE *yyin;
28
29 static char *path;
30 static ParseToken t;
31
32 /* in parse.c */
33 void parse_token(ParseToken *token);
34 void parse_assign(char *name, ParseToken *token);
35 void parse_set_section(char *section);
36 %}
37
38 %token <real> REAL
39 %token <integer> INTEGER
40 %token <string> STRING
41 %token <identifier> IDENTIFIER
42 %token <bool> BOOL
43 %token <character> '('
44 %token <character> ')'
45 %token <character> '{'
46 %token <character> '}'
47 %token <character> '='
48 %token <character> ','
49 %token <character> '\n'
50 %token INVALID
51
52 %type <list> list
53 %type <list> listtokens
54
55 %%
56
57 sections:
58   | sections '[' IDENTIFIER ']' { parse_set_section($3); } '\n'
59     { ++lineno; } lines
60   ;
61
62 lines:
63   | lines tokens { t.type='\n'; t.data.character='\n'; parse_token(&t); } '\n'
64     { ++lineno; }
65   | lines IDENTIFIER '=' listtoken { parse_assign($2, &t); } '\n'
66     { ++lineno; }
67   ;
68
69 tokens:
70     tokens token { parse_token(&t); }
71   | token        { parse_token(&t); }
72   ;
73
74 token:
75     REAL       { t.type = TOKEN_REAL; t.data.real = $1; }
76   | INTEGER    { t.type = TOKEN_INTEGER; t.data.integer = $1; }
77   | STRING     { t.type = TOKEN_STRING; t.data.string = $1; }
78   | IDENTIFIER { t.type = TOKEN_IDENTIFIER; t.data.identifier = $1; }
79   | BOOL       { t.type = TOKEN_BOOL; t.data.bool = $1; }
80   | list       { t.type = TOKEN_LIST; t.data.list = $1; }
81   | '{'        { t.type = $1; t.data.character = $1; }
82   | '}'        { t.type = $1; t.data.character = $1; }
83   | ','        { t.type = $1; t.data.character = $1; }
84   ;
85
86 list:
87     '(' listtokens ')' { $$ = $2; }
88   ;
89
90 listtokens:
91     listtokens listtoken { ParseToken *nt = g_new(ParseToken, 1);
92                            nt->type = t.type;
93                            nt->data = t.data;
94                            $$ = g_list_append($1, nt);
95                          }
96   | listtoken            { ParseToken *nt = g_new(ParseToken, 1);
97                            nt->type = t.type;
98                            nt->data = t.data;
99                            $$ = g_list_append(NULL, nt);
100                          }
101   ;
102
103 listtoken:
104     REAL       { t.type = TOKEN_REAL; t.data.real = $1; }
105   | INTEGER    { t.type = TOKEN_INTEGER; t.data.integer = $1; }
106   | STRING     { t.type = TOKEN_STRING; t.data.string = $1; }
107   | IDENTIFIER { t.type = TOKEN_IDENTIFIER; t.data.identifier = $1; }
108   | BOOL       { t.type = TOKEN_BOOL; t.data.bool = $1; }
109   | list       { t.type = TOKEN_LIST; t.data.list = $1; }
110   | '{'        { t.type = $1; t.data.character = $1; }
111   | '}'        { t.type = $1; t.data.character = $1; }
112   | ','        { t.type = $1; t.data.character = $1; }
113   ;
114
115
116 %%
117
118 int lineno;
119
120 void yyerror(char *err) {
121     g_message("%s:%d: %s", path, lineno, err);
122 }
123
124 void parse_rc()
125 {
126     /* try the user's rc */
127     path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
128     if ((yyin = fopen(path, "r")) == NULL) {
129         g_free(path);
130         /* try the system wide rc */
131         path = g_build_filename(RCDIR, "rc3", NULL);
132         if ((yyin = fopen(path, "r")) == NULL) {
133             g_warning("No rc2 file found!");
134             g_free(path);
135             return;
136         }
137     }
138
139     lineno = 1;
140
141     yyparse();
142
143     g_free(path);
144 }