openbox/parse.c (raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 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); } |