give the filename to the parser for errors
[dana/openbox.git] / openbox / cparse.l
1 %{
2 #include <glib.h>
3 #include "config.h"
4
5 static char *yyfilename;
6 static int yylineno = 1;
7 static gboolean haserror = FALSE;
8 static ConfigEntry entry = { NULL, -1 };
9
10 static void stringvalue();
11 static void numbervalue();
12 static void identifier();
13 static void newline();
14 static int yywrap();
15 %}
16
17 number [0-9]+
18 string \"[^"\n]*\"
19 identifier [a-zA-Z][a-zA-Z0-9_]*
20 white [ \t]*
21 assign {white}={white}
22
23 %%
24
25 {string}/{white}\n stringvalue();
26 {number}/{white}\n numbervalue();
27 ^{identifier}/{assign} identifier();
28 \n newline();
29 =
30 [ \t]
31 . haserror = TRUE;
32
33 %%
34
35 static void stringvalue()
36 {
37     if (!haserror && entry.name != NULL && (signed)entry.type < 0) {
38         entry.type = Config_String;
39         entry.value.string = g_strdup(yytext+1); /* drop the left quote */
40         if (entry.value.string[yyleng-2] != '"')
41             printf("warning: improperly terminated string on line %d\n",
42                    yylineno);
43         else
44             entry.value.string[yyleng-2] = '\0';
45     } else
46         haserror = TRUE;
47 }
48
49 static void numbervalue()
50 {
51     if (!haserror && entry.name != NULL && (signed)entry.type < 0) {
52         entry.type = Config_Integer;
53         entry.value.integer = atoi(yytext);
54     } else
55         haserror = TRUE;
56 }
57
58 static void identifier()
59 {
60     entry.name = g_strdup(yytext);
61     entry.type = -1;
62 }
63
64 static void newline()
65 {
66     if (!haserror && entry.name != NULL && (signed)entry.type >= 0) {
67         if (!config_set(entry.name, entry.type, entry.value))
68             g_warning("Invalid option in '%s': '%s'\n",
69                       yyfilename, entry.name);
70     } else {
71         printf("Parser error in '%s' on line %d\n", yyfilename, yylineno);
72     }
73     g_free(entry.name);
74     entry.name = NULL;
75     if (entry.type == Config_String)
76         g_free(entry.value.string);
77     entry.type = -1;
78
79     haserror = FALSE;
80     ++yylineno;
81 }
82
83 static int yywrap()
84 {
85     g_free(entry.name);
86     entry.name = NULL;
87     if (entry.type == Config_String)
88         g_free(entry.value.string);
89     return 1;
90 }
91
92 void cparse_go(char *filename, FILE *file)
93 {
94     yyfilename = filename;
95     yyin = file;
96     yylex();
97 }