1 Note: this is not really a README but more of a thought dump, for now.
6 obcl wants to be a generic configuration file loader. generic not in
7 the sense that it will parse every single configuration format on the
8 planet, but in the sense that it will parse a versatile, multi purpose
14 this is the part of obcl that when given a configuration file, it will
15 return a parse tree. the parse tree can be mucked with by the
16 programmer, or it can be checked and processed using the handy checker
17 and processor. (for the most part; the programmer will do some
20 GList *config = cl_parse_file("foo.conf");
25 the checker is supposed to help the programmer/application ensure that
26 the configuration file is in the correct format. since obcl has a very
27 general, the parser itself cannot guarantee that the user will enter a
33 will both be parsed, but 'fpp' might be a mistake. the checker is
38 bar 5, "foo", "hi", 43.4;
44 CLChecker *check = cl_checker_new();
45 cl_checker_add(check, "foo", CL_NUM, 0);
46 cl_checker_add(check, "blef", CL_STRING, 0);
47 cl_checker_add(check, "bar", CL_NUM, CL_STRING, CL_STRING, CL_NUM, 0);
48 cl_checker_add(check, "woop", CL_STRING, CL_BLOCK, 0);
49 cl_checker_add_checker(check, "woop", check); /* add checker for block */
51 int val = cl_check(checker, config, stderr); /* write errors to stderr */
53 fprintf(stderr, "Parse errors found. Loading default settings\n");
57 cl_checker_free(check);
62 the processor is intended to be run after the checker, to do actual
63 'stuff' with the parse tree. once the parse tree has been checked, we
64 know that we can just access stuff in the parse tree willy nilly
65 without sprinkling asserts all over the code. the processing is done
68 typedef gpointer (*CLCallback)(CLNode *node, gpointer val);
70 gpointer handle_foo(CLNode *node, gpointer conf)
72 /* here numval is a macro that expands to something like
73 node->u.num. we know we can access this safely since the checker
74 has verified that 'foo' nodes indeed contain numbers.
75 same with NTH. it expands to somethign that we don't have to
77 ((Config*)conf)->foo = NUMVAL(NTH(node, 1));
81 gpointer handle_woop(CLNode *node, gpointer conf, CLProc *proc)
83 Config *conf1 = new_conf();
84 conf1->name = STRVAL(NTH(node,1));
85 cl_process(proc, BLOCK(node), conf1);
86 conf_add_child((Config*)conf, conf1);
92 Config *process_config_file(char *file)
101 parse_tree = cl_parse_file(file);
104 fprintf(stderr, "your config file is completely borked. loading defaults\n");
105 conf_load_defaults(conf);
109 checker = checker_new();
111 /* add checker stuff to checker, as per above */
113 err = cl_check(checker, parse_tree);
116 fprintf(stderr, "you fucked up. loading defaults\n");
117 config_load_defaults(conf);
121 CLProc *proc = cl_proc_new();
122 cl_proc_add(proc, "foo", handle_foo, conf); /* conf will be passed to callback */
124 cl_proc_add_block(proc, "woop", handle_woop, conf, proc);
125 cl_process(proc, parse_tree);
130 something like that. lalala.