#include "parse.h"
-#include "config.h"
-static GHashTable *reg = NULL;
-static ParseFunc func = NULL;
+static GHashTable *reg = NULL;
-/* parse tokens from the [openbox] section of the rc file */
-static void parse_rc_token(ParseTokenType type, union ParseToken token);
+struct Functions {
+ ParseFunc f;
+ AssignParseFunc af;
+} *funcs;
-void destkey(gpointer key) { g_free(key); }
+void destshit(gpointer shit) { g_free(shit); }
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);
+ reg = g_hash_table_new_full(g_str_hash, g_str_equal, destshit, destshit);
+ funcs = NULL;
}
void parse_shutdown()
g_hash_table_destroy(reg);
}
-void parse_reg_section(char *section, ParseFunc func)
+void parse_reg_section(char *section, ParseFunc func, AssignParseFunc afunc)
{
- 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);
+ 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);
}
-void parse_free_token(ParseTokenType type, union ParseToken token)
+void parse_free_token(ParseToken *token)
{
- switch (type) {
+ GList *it;
+
+ switch (token->type) {
case TOKEN_STRING:
- g_free(token.string);
+ g_free(token->data.string);
break;
case TOKEN_IDENTIFIER:
- g_free(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);
+ }
+ g_list_free(token->data.list);
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);
+ char *sec;
+ sec = g_ascii_strdown(section, -1);
+ funcs = g_hash_table_lookup(reg, sec);
+ g_free(sec);
}
-void parse_token(ParseTokenType type, union ParseToken token)
+void parse_token(ParseToken *token)
{
- if (func != NULL)
- func(type, token);
+ if (funcs) {
+ if (funcs->f)
+ funcs->f(token);
+ else if (token->type != TOKEN_NEWLINE)
+ yyerror("syntax error");
+ }
}
-static void parse_rc_token(ParseTokenType type, union ParseToken token)
+void parse_assign(char *name, ParseToken *value)
{
- 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 {
+ if (funcs) {
+ if (funcs->af)
+ funcs->af(name, value);
+ 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);
}