node processing code/macros, and other fixes
[mikachu/openbox.git] / obcl / process.c
1 #include "obcl.h"
2
3 static void cl_proc_intern_handler(CLNode *node)
4 {
5     CL_ASSERT_NODE(node);
6     g_warning("Unhandled node %s on line %d\n",
7               CL_ID(node), CL_LINE(node));
8 }
9
10 static CLProcHandler *default_handler(void)
11 {
12     static CLProcHandler *ph = 0;
13     if (!ph)
14         ph = cl_proc_handler_new_func(cl_proc_intern_handler);
15     return ph;
16 }
17
18 CLProcHandler *cl_proc_handler_new_func(CLProcFunc f)
19 {
20     CLProcHandler *cph = g_new(CLProcHandler,1);
21     cph->type = CLPROC_FUNC;
22     cph->u.func = f;
23     return cph;
24 }
25
26 CLProcHandler *cl_proc_handler_new_proc(CLProc *cp)
27 {
28     CLProcHandler *cph = g_new(CLProcHandler,1);
29     cph->type = CLPROC_PROC;
30     cph->u.proc = cp;
31     return cph;
32 }
33
34 CLProc *cl_proc_new(void)
35 {
36     CLProc *ret = g_new(CLProc,1);
37     ret->table = g_hash_table_new(g_str_hash,g_str_equal);
38     ret->default_h = default_handler();
39     return ret;
40 }
41
42 void cl_proc_free(CLProc *proc)
43 {
44
45 }
46
47 void cl_proc_add_handler(CLProc *proc, gchar *str,
48                          CLProcHandler *handler)
49 {
50     g_assert(proc != NULL);
51     g_hash_table_replace(proc->table, str, handler);
52 }
53
54 void cl_proc_add_handler_func(CLProc *proc, gchar *str,
55                               CLProcFunc func)
56 {
57     CLProcHandler *ph;
58
59     g_assert(proc != NULL);
60     ph = cl_proc_handler_new_func(func);
61     cl_proc_add_handler(proc, str, ph);
62 }
63
64 void cl_proc_set_default(CLProc *proc, CLProcHandler *ph)
65 {
66     g_assert(proc != NULL);
67     proc->default_h = ph;
68 }
69
70 void cl_proc_register_keywords(CLProc *proc, ...)
71 {
72     va_list args;
73     g_assert(proc != NULL);
74
75     va_start(args,proc);
76     for (;;) {
77         gchar *k = va_arg(args, gchar*);
78         if (k == NULL)
79             break;
80         if (g_hash_table_lookup(proc->table, k) != NULL)
81             g_hash_table_insert(proc->table, k, default_handler());
82     }
83     va_end(args);
84 }
85
86 void cl_process(GList *tree, CLProc *proc)
87 {
88     GList *lst;
89     CLProcHandler *handler;
90
91     g_assert(proc != NULL);
92
93     if (!tree) return;
94
95     for (lst = tree; lst != NULL; lst = lst->next) {
96         CL_ASSERT_NODE(lst->data);
97         handler = g_hash_table_lookup(proc->table, CL_ID(lst->data));
98         if (!handler)
99             handler = default_handler();
100         if (handler->type == CLPROC_FUNC)
101             handler->u.func(CL_NODE(lst->data));
102         else
103             cl_process(CL_BLOCK(lst->data), handler->u.proc);
104     }
105 }