all repos — openbox @ b1fe0dbbc2ef4472ac8893d9b3b20e9cb149af6d

openbox fork - make it a bit more like ryudo

obcl/process.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
#include "obcl.h"

static void cl_proc_intern_handler(CLNode *node)
{
    CL_ASSERT_NODE(node);
    g_warning("Unhandled node %s on line %d\n",
              CL_ID(node), CL_LINE(node));
}

static CLProcHandler *default_handler(void)
{
    static CLProcHandler *ph = 0;
    if (!ph)
        ph = cl_proc_handler_new_func(cl_proc_intern_handler);
    return ph;
}

CLProcHandler *cl_proc_handler_new_func(CLProcFunc f)
{
    CLProcHandler *cph = g_new(CLProcHandler,1);
    cph->type = CLPROC_FUNC;
    cph->u.func = f;
    return cph;
}

CLProcHandler *cl_proc_handler_new_proc(CLProc *cp)
{
    CLProcHandler *cph = g_new(CLProcHandler,1);
    cph->type = CLPROC_PROC;
    cph->u.proc = cp;
    return cph;
}

CLProc *cl_proc_new(void)
{
    CLProc *ret = g_new(CLProc,1);
    ret->table = g_hash_table_new(g_str_hash,g_str_equal);
    ret->default_h = default_handler();
    return ret;
}

void cl_proc_free(CLProc *proc)
{

}

void cl_proc_add_handler(CLProc *proc, gchar *str,
                         CLProcHandler *handler)
{
    g_assert(proc != NULL);
    g_hash_table_replace(proc->table, str, handler);
}

void cl_proc_add_handler_func(CLProc *proc, gchar *str,
                              CLProcFunc func)
{
    CLProcHandler *ph;

    g_assert(proc != NULL);
    ph = cl_proc_handler_new_func(func);
    cl_proc_add_handler(proc, str, ph);
}

void cl_proc_add_handler_proc(CLProc *proc, gchar *str,
                              CLProc *hproc)
{
    CLProcHandler *ph;

    g_assert(proc != NULL);
    ph = cl_proc_handler_new_proc(hproc);
    cl_proc_add_handler(proc, str, ph);
}

void cl_proc_set_default(CLProc *proc, CLProcHandler *ph)
{
    g_assert(proc != NULL);
    proc->default_h = ph;
}

void cl_proc_register_keywords(CLProc *proc, ...)
{
    va_list args;
    g_assert(proc != NULL);

    va_start(args,proc);
    for (;;) {
        gchar *k = va_arg(args, gchar*);
        if (k == NULL)
            break;
        if (g_hash_table_lookup(proc->table, k) != NULL)
            g_hash_table_insert(proc->table, k, default_handler());
    }
    va_end(args);
}

void cl_process(GList *tree, CLProc *proc)
{
    GList *lst;
    CLProcHandler *handler;

    g_assert(proc != NULL);

    if (!tree) return;

    for (lst = tree; lst != NULL; lst = lst->next) {
        CL_ASSERT_NODE(lst->data);
        handler = g_hash_table_lookup(proc->table, CL_ID(lst->data));
        if (!handler)
            handler = default_handler();
        if (handler->type == CLPROC_FUNC)
            handler->u.func(CL_NODE(lst->data));
        else
            cl_process(CL_BLOCK(lst->data), handler->u.proc);
    }
}