4 Libucw contains a parser for configuration files. The syntax of the
5 configuration files is described in <<config:>>, here we explain the
6 interface of the parser.
8 Basically, you write a description of the configuration file syntax,
9 which maps configuration items to variables of your program. Then
10 Then you run the parser and it fills your variables with the values
11 from the configuration file.
13 The descriptions are modular. The configuration can be split to sections,
14 each section declared at a separate place. You can also define your own
18 * <<ex_structure,The structure>>
19 * <<ex_load,Loading configuration>>
20 - <<deep,Getting deeper>>
21 * <<conf_multi,Arrays and lists>>
22 * <<reload,Reloading configuration>>
23 * <<custom_parser,Creating custom parsers>>
25 - <<conf_h,ucw/conf.h>>
26 * <<conf_ctxt,Configuration contexts>>
27 * <<conf_load,Safe configuration loading>>
28 * <<conf_types,Data types>>
29 * <<conf_macros,Convenience macros>>
30 * <<alloc,Memory allocation>>
31 * <<journal,Undo journal>>
32 * <<declare,Section declaration>>
33 * <<bparser,Parsers for basic types>>
34 * <<conf_direct,Direct access>>
35 * <<conf_dump,Debug dumping>>
36 - <<getopt_h,ucw/getopt.h>>
37 * <<conf_getopt,Loading configuration by cf_getopt()>> (obsolete)
38 * <<getopt_example,Example>> (obsolete)
43 If you want to just load simple configuration, this is the part you
44 want to read. This simple example should give you the overview. Look
45 at the <<conf_macros,convenience macros>> section to see list of
46 supported data types, sections, etc.
49 Suppose you have configuration file with the following content and you
60 First, you declare the structure and let the configuration parser know
66 static char *hw_text = "Hello world";
67 static int hw_count = 1;
68 static int hw_wait_answer = 0;
70 static struct cf_section hw_config = {
72 CF_STRING("Text", &hw_text),
73 CF_INT("Count", &hw_count),
74 CF_INT("WaitAnswer", &hw_wait_answer),
79 static void CONSTRUCTOR hw_init(void) {
80 cf_declare_section("HelloWorld", &hw_config, 0);
83 The variables are used to store the loaded values. Their initial
84 values work as defaults, if nothing else is loaded. The hw_config()
85 structure assigns the variables to configuration names. The hw_init()
86 function (because of the `CONSTRUCTOR` macro) is run before main()
87 is called and it tells the parser that the section exists (alternatively,
88 you can call @cf_declare_section() at the start of your main()).
90 You can plug in as many configuration sections as you like, from
91 various places across your code.
96 You can load the configuration explicitly by calling @cf_load().
97 That can be convenient when writing a library, but in normal programs,
98 you can ask the <<opt:,option parser>> to handle it for you.
100 A typical example follows, please see the <<opt:conf,interface between
101 conf and opt>> for details.
106 static struct opt_section options = {
108 // More options can be specified here
109 OPT_HELP("Configuration options:"),
115 int main(int argc, char **argv)
117 cf_def_file = "default.cf";
118 opt_parse(&options, argv+1);
119 // Configuration file is already loaded here
127 Since the configuration system is somehow complicated, this part gives
128 you a little overview of what you can find and where.
134 It is sometime needed to have multiple items of the same type. There
135 are three ways to do that:
138 An array with fixed maximum length. You provide
139 the length and already allocated array which is filled with items.
140 The configuration may contain less than the maximum length items.
142 For example, you can have an static array of five unsigned integers:
144 static uint array[] = { 1, 2, 3, 4, 5 };
146 static struct cf_section section = {
148 CF_UINT_ARY("array", array, 5),
154 Similar to static array, but you provide pointer
155 to pointer to the given item (eg. if you want dynamic array of
156 integers, you give `**int`). The parser allocates a <<gary:,growing array>>
157 of the required size.
159 If you want dynamic array of strings, you would use:
161 static char *array[];
163 static struct cf_section section = {
165 CF_STRING_DYN("array", &array, CF_ANY_NUM),
171 Linked lists based on <<lists:clists,clists>>. You provide description
172 of single node and pointer to the
173 <<lists:struct_clist,`struct clist`>> variable. All the nodes will
174 be created dynamically and put there.
176 First element of your structure must be <<lists:struct_cnode,`cnode`>>.
178 The first example is list of strings and uses <<lists:simple_lists,simple
181 static struct clist list;
183 static struct cf_section section = {
185 CF_LIST("list", &list, &cf_string_list_config),
190 Another example, describing how to create more complicated list node
191 than just a string can be found at the <<def_CF_TYPE,`CF_TYPE`>> macro.
194 Reloading configuration
195 ~~~~~~~~~~~~~~~~~~~~~~~
197 The configuration system allows you to reload configuration at
198 runtime. The new config changes the values against the default values.
199 It means, if the default value for variable `A` is `10`, the currently
200 loaded config sets it to `42` and the new config does not talk about
201 this variable, `A` will have a value of `10` after a successful load.
203 Furthermore, if the loading of a new configuration fails, the current
204 configuration is preserved.
206 All this is done with <<journal,config journalling>>. The load of the
207 first config creates a journal entry. If you try to load some new
208 configuration, it is partially rolled back to defaults (the rollback
209 happens, but instead of removing the journal entry, another journal
210 entry is added for the rollback). If the loading succeeds, the two
211 journal entries are removed and a new one, for the new configuration,
212 is added. If it fails, the first one is replayed and the rollback
218 Creating custom parsers
219 ~~~~~~~~~~~~~~~~~~~~~~~
221 If you need to parse some data type the configuration system can't
222 handle, you can write your own <<xtypes:,extended type>>
223 and use <<def_CF_XTYPE,`CF_XTYPE`>> macro to declare a new option.
225 There is also an obsolete way to write a custom parser.
226 Before you start, you should know a few things.
228 The parser needs to support <<journal,journalling>>. To accomplish that,
229 you have to use the <<alloc,configuration mempool>> for memory allocation.
231 Now, you need a function with the same signature as
232 <<type_cf_parser1,`cf_parser1`>>. Parse the first parameter (the
233 string) and store the data in the second parameter. You may want to
234 write a dumper function, with signature of
235 <<type_cf_dumper1,`cf_dumper1`>> (needed for debug dumps).
237 Fill in a structure <<struct_cf_user_type,cf_user_type>> and use the
238 new data type in your configuration description with
239 <<def_CF_USER,`CF_USER`>> macro as its @t parameter.
241 You do not need to call @cf_journal_block() on the variable you store
242 the result. It is true you change it, but it was stored to journal
243 before your parser function was called.
249 The configuration system supports hooks. They are used to initialize the
250 configuration (if simple default value of variable is not enough) and
251 to check the sanity of loaded data.
253 Each hook is of type <<type_cf_hook,`cf_hook`>> and you can include
254 them in configuration description using <<def_CF_INIT,`CF_INIT`>> and
255 <<def_CF_COMMIT,`CF_COMMIT`>> macros.
257 The hooks should follow similar guidelines as custom parsers (well,
258 init hooks do not need to call @cf_journal_block()) to support
259 journalling. If you change nothing in the commit hook, you do not need
260 to care about the journalling either.
262 You may use the return value to inform about errors. Just return the
263 error message, or NULL if everything went well.
265 Another similar function is a copy function. It is very similar to a
266 hook and is used when the item is copied and is too complicated to use
267 simple memcpy(). Its type is <<type_cf_copier,`cf_copier`>> and is
268 specified by the <<def_CF_COPY,`CF_COPY`>> macro. It's return value is
269 the same as the one of a hook.
275 This header file contains the public interface of the configuration module.
283 This header contains routines for parsing command line arguments and
284 loading the default configuration.
286 In new programs, please consider using the new <<opt:,option parser>>
287 instead. The getopt interface is already considered obsolete and may
288 be removed in the future.
294 Typically, @cf_getopt() is used as follows: it works like
295 the traditional @getopt_long() from the C library, but it also handles
299 #include <ucw/conf.h>
300 #include <ucw/getopt.h>
302 static char short_opts[] = CF_SHORT_OPTS "v";
303 static struct option long_opts[] = {
305 { "verbose", 0, 0, 'v' },
311 int main(int argc, char *argv[]) {
312 cf_def_file = "default.cf";
314 while((opt = cf_getopt(argc, argv, short_opts, long_opts, NULL)) >= 0)
316 case 'v': verbose = 1; break;
317 default: fprintf("Unknown option %c\n", opt); return 1;
321 The `short_opts` and `long_opts` variables describe the command line
322 arguments. Notice the `CF_SHORT_OPTS` and `CF_LONG_OPTS` macros. They
323 add the `-S` and `-C` options for the configuration parser as described
324 in <<config:>>. These options are handled internally by @cf_getopt().
326 You can rely on the configuration files having been loaded before the
327 first of your program's options is parsed.