]> Dogcows Code - chaz/openbox/blob - openbox/parse.c
add y.tab.h to the headers so the yacc shit runs
[chaz/openbox] / openbox / parse.c
1 #include "parse.h"
2 #include "config.h"
3
4 static GHashTable *reg = NULL;
5 static ParseFunc func = NULL;
6
7 /* parse tokens from the [openbox] section of the rc file */
8 static void parse_rc_token(ParseTokenType type, union ParseToken token);
9
10 void destkey(gpointer key) { g_free(key); }
11
12 void parse_startup()
13 {
14 reg = g_hash_table_new_full(g_str_hash, g_str_equal, destkey, NULL);
15 func = NULL;
16
17 parse_reg_section("openbox", parse_rc_token);
18 }
19
20 void parse_shutdown()
21 {
22 g_hash_table_destroy(reg);
23 }
24
25 void parse_reg_section(char *section, ParseFunc func)
26 {
27 if (g_hash_table_lookup(reg, section) != NULL)
28 g_warning("duplicate request for section '%s' in the rc file",
29 section);
30 else
31 g_hash_table_insert(reg, g_ascii_strdown(section, -1), (void*)func);
32 }
33
34 void parse_free_token(ParseTokenType type, union ParseToken token)
35 {
36 switch (type) {
37 case TOKEN_STRING:
38 g_free(token.string);
39 break;
40 case TOKEN_IDENTIFIER:
41 g_free(token.identifier);
42 break;
43 case TOKEN_REAL:
44 case TOKEN_INTEGER:
45 case TOKEN_BOOL:
46 case TOKEN_LBRACKET:
47 case TOKEN_RBRACKET:
48 case TOKEN_LBRACE:
49 case TOKEN_RBRACE:
50 case TOKEN_EQUALS:
51 case TOKEN_COMMA:
52 case TOKEN_NEWLINE:
53 break;
54 }
55 }
56
57 void parse_set_section(char *section)
58 {
59 func = (ParseFunc)g_hash_table_lookup(reg, section);
60 }
61
62 void parse_token(ParseTokenType type, union ParseToken token)
63 {
64 if (func != NULL)
65 func(type, token);
66 }
67
68 static void parse_rc_token(ParseTokenType type, union ParseToken token)
69 {
70 static int got_eq = FALSE;
71 static ParseTokenType got_val = 0;
72 static char *id = NULL, *s = NULL;
73 static int i;
74 static gboolean b;
75
76 if (id == NULL) {
77 if (type == TOKEN_IDENTIFIER) {
78 id = token.identifier;
79 return;
80 } else {
81 yyerror("syntax error");
82 }
83 } else if (!got_eq) {
84 if (type == TOKEN_EQUALS) {
85 got_eq = TRUE;
86 return;
87 } else {
88 yyerror("syntax error");
89 }
90 } else if (!got_val) {
91 if (type == TOKEN_STRING) {
92 s = token.string;
93 got_val = type;
94 return;
95 } else if (type == TOKEN_BOOL) {
96 b = token.bool;
97 got_val = type;
98 return;
99 } else if (type == TOKEN_INTEGER) {
100 i = token.integer;
101 got_val = type;
102 return;
103 } else
104 yyerror("syntax error");
105 } else if (type != TOKEN_NEWLINE) {
106 yyerror("syntax error");
107 } else {
108 ConfigValue v;
109
110 switch (got_val) {
111 case TOKEN_STRING:
112 v.string = s;
113 if (!config_set(id, Config_String, v))
114 yyerror("invalid value type");
115 break;
116 case TOKEN_BOOL:
117 v.bool = b;
118 if (!config_set(id, Config_Bool, v))
119 yyerror("invalid value type");
120 break;
121 case TOKEN_INTEGER:
122 v.integer = i;
123 if (!config_set(id, Config_Integer, v))
124 yyerror("invalid value type");
125 break;
126 default:
127 g_assert_not_reached(); /* unhandled type got parsed */
128 }
129 }
130
131 g_free(id);
132 g_free(s);
133 id = s = NULL;
134 got_eq = FALSE;
135 got_val = 0;
136 parse_free_token(type, token);
137 }
This page took 0.043446 seconds and 4 git commands to generate.