all repos — openbox @ 59621c4f41886affe1ff5c477e3ab4d273b9d2d9

openbox fork - make it a bit more like ryudo

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
138
139
140
141
142
143
144
#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(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(ParseToken *token)
{
    GSList *it;

    switch (token->type) {
    case TOKEN_STRING:
        g_free(token->data.string);
        break;
    case 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_slist_free(token->data.list);
        break;
    case TOKEN_REAL:
    case TOKEN_INTEGER:
    case TOKEN_BOOL:
    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(ParseToken *token)
{
    if (func != NULL)
        func(token);
}

static void parse_rc_token(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 (token->type == TOKEN_IDENTIFIER) {
            id = token->data.identifier;
            return;
        } else {
            yyerror("syntax error");
        }
    } else if (!got_eq) {
        if (token->type == TOKEN_EQUALS) {
            got_eq = TRUE;
            return;
        } else {
            yyerror("syntax error");
        }
    } else if (!got_val) {
        if (token->type == TOKEN_STRING) {
            s = token->data.string;
            got_val = token->type;
            return;
        } else if (token->type == TOKEN_BOOL) {
            b = token->data.bool;
            got_val = token->type;
            return;
        } else if (token->type == TOKEN_INTEGER) {
            i = token->data.integer;
            got_val = token->type;
            return;
        } else
            yyerror("syntax error");
    } else if (token->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(token);
}