1<?xml version="1.0" standalone="no"?>
2<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
3"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
4[
5<!ENTITY listing1 SYSTEM "listing1.xml">
6<!ENTITY listing2 SYSTEM "listing2.xml">
7<!ENTITY listing3 SYSTEM "listing3.xml">
8<!ENTITY listing4 SYSTEM "listing4.xml">
9<!ENTITY listing5 SYSTEM "listing5.xml">
10<!ENTITY listing6 SYSTEM "listing6.xml">
11<!ENTITY listing7 SYSTEM "listing7.xml">
12<!ENTITY listing8 SYSTEM "listing8.xml">
13]>
14<article>
15    <articleinfo>
16        <title>libConfuse tutorial</title>
17        <author><firstname>Martin</firstname> <surname>Hedenfalk</surname></author>
18    </articleinfo>
19    <sect1>
20        <title>Introducing libConfuse in an existing program</title>
21        <para>Consider this simple program:</para>
22        &listing1;
23        <para>
24            Simple enough, but we want to extend the program so we can greet
25            others. Maybe we don't want to greet the whole world, just our
26            neighbour. We use libConfuse to let the user decide whom to greet.
27        </para>
28        &listing2;
29        <para>
30            All programs using libConfuse must first include the
31            <filename>confuse.h</filename> header file.  This is done on line
32            2.
33        </para>
34        <para>
35            On line 6 - 10, the options that should be recognized are defined in an
36            array of cfg_opt_t structs. This is passed to the
37            <function>cfg_init</function> function on line 13. The resulting
38            <structname>cfg_t</structname> context is used by
39            <function>cfg_parse()</function>, which reads the configuration file
40            "hello.conf". When reading the configuration file, only options defined in
41            the array of options passed to <function>cfg_init()</function> are
42            recognized.
43        </para>
44        <para>
45            The friendly greeting is now replaced with a parameter read from the
46            configuration file. The value of the <varname>target</varname> option is retrieved with
47            <function>cfg_getstr(cfg, "target")</function>.
48        </para>
49        <para>
50            Lets take a look at the configuration file hello.conf:
51        </para>
52
53        <programlisting>
54# this is the configuration file for the hello program
55
56target = "Neighbour"
57        </programlisting>
58        <para>
59            Here, the target option is set to the string value "Neighbour".
60            What if the configuration file was empty or didn't exist? Then the
61            default value for the <varname>target</varname> option would be
62            used. When we initialized our options, the second parameter to the
63            <function>CFG_STR()</function> macro specified the default value.
64            Thus, if no <varname>target</varname> option was specified in the
65            configuration file, the hello program would have printed the
66            standard greeting "Hello, World".
67        </para>
68
69        <sect2>
70            <title>Environment variables in values</title>
71
72            <para>
73                What else can we do in the configuration file? We can set the value to an
74                environment variable:
75            </para>
76            <programlisting>
77target = ${USER}
78            </programlisting>
79            <para>
80                This results in the hello program greeting the user who runs it. On some
81                systems, the USER variable might not be available, so we want to specify a
82                default value in those cases:
83            </para>
84            <programlisting>
85target = ${USER:-User}
86            </programlisting>
87            <para>
88                Now, if the USER environment variable is unset, the string "User" will be
89                used instead.
90            </para>
91        </sect2>
92    </sect1>
93    <sect1>
94        <title>Other types of options</title>
95
96        <para>
97            Of course, not only strings can be specified in the configuration file.
98            libConfuse can parse strings, integers, booleans and floating point values.
99            These are the fundamental values, and they are all also available as lists.
100            We'll talk more about lists in the next chapter.
101        </para>
102        <para>
103            The macros used to initialize a string, integer, boolean and a
104            float is, respectively, <function>CFG_STR()</function>,
105            <function>CFG_INT()</function>, <function>CFG_BOOL()</function>,
106            <function>CFG_FLOAT()</function> and
107            <function>CFG_PTR()</function>. All macros take three parameters:
108            the name of the option, a default value and flags. To retrieve the
109            values, use <function>cfg_getstr()</function>,
110            <function>cfg_getint()</function>,
111            <function>cfg_getbool()</function>,
112            <function>cfg_getfloat()</function> or
113            <function>cfg_getptr()</function>, respectively.
114        </para>
115        <para>
116            Let's introduce an integer option that tells us how many times to print the
117            greeting:
118        </para>
119        &listing3;
120        <para>
121            Here we have used the <function>CFG_INT()</function> macro to
122            initialize an integer option named "repeat". The default value is 1
123            as in the standard greeting. The value is retrieved with
124            <function>cfg_getint()</function>.
125        </para>
126        <para id="negative-repeat-problem">
127            But, wait a moment, what if the user specified a negative value for
128            "repeat"?  Or a too large positive value? libConfuse can handle
129            that with a so-called validating callback. We'll come back to this
130            problem later on, but we will first take a look at lists.
131        </para>
132    </sect1>
133
134    <sect1>
135        <title>Introducing lists</title>
136
137        <para>
138            That was easy. Now let's extend the program a bit so we can greet more than one
139            "target". We'd like to be able to specify a list of targets to greet.
140        </para>
141        <para>
142            The list versions of the initialization macros are named
143            <function>CFG_STR_LIST()</function>,
144            <function>CFG_INT_LIST()</function>,
145            <function>CFG_BOOL_LIST()</function> and
146            <function>CFG_FLOAT_LIST()</function>. They take the same
147            parameters as the non-list versions, except the default value must
148            be a string surrounded by curly braces.
149        </para>
150        <para>
151            The modified program is shown below:
152        </para>
153        &listing4;
154        <para>
155            Three things are a bit different here. First, the macro to
156            initialize the "targets" option is
157            <function>CFG_STR_LIST()</function>. This tells libConfuse that
158            "targets" is a list of strings. Second, the default value in the
159            second parameter is surrounded by curly braces. This is needed to
160            indicate to libConfuse where the list of values ends.
161        </para>
162        <para>
163            The third change is in the printing of the greeting. First we print
164            the "Hello" string. Then we loop through all values found for the
165            "targets" option. The number of values is retrieved with the
166            <function>cfg_size()</function> function. The string values are
167            then retrieved with <function>cfg_getnstr()</function>, which is an
168            indexed version of <function>cfg_getstr()</function>. In fact,
169            <function>cfg_getstr()</function> is equivalent to
170            <function>cfg_getnstr()</function> with an index of zero.
171        </para>
172        <para>
173            In the configuration file hello.conf, we can now specify a list of targets to
174            greet:
175        </para>
176        <programlisting>
177# this is the configuration file for the hello program
178
179targets = {"Life", "Universe", "Everything"}
180repeat = 1
181        </programlisting>
182        <para>
183            The output of the hello program, run with the above configuration file, is:
184            "Hello, Life, Universe, Everything!"
185        </para>
186        <para>
187            Again, if no targets were configured, the greeting would have been the standard
188            "Hello, World!".
189        </para>
190
191    </sect1>
192    <sect1>
193        <title>Using sections</title>
194
195        <para>
196            So far, we have only use a flat configuration file. libConfuse can also handle
197            sections to build a hierarchy of options. Sections can be used to group options
198            in logical blocks, and those blocks can (optionally) be specified multiple
199            times.
200        </para>
201        <para>
202            Sections are initialized with the <function>CFG_SEC()</function> macro. It also takes three
203            parameters: the name of the option, an array of options allowed in the section
204            and flags.
205        </para>
206        <para>
207            We'll extend the, now rather complex, hello program so we can do other kinds of
208            greetings, not just "Hello". Each greeting will have its own settings for
209            targets and repeat.
210        </para>
211        &listing5;
212        <para>
213            We have renamed the option array from "opts" to "greet_opts", and introduced a
214            new "opts" array that only has one option: a "greeting" section.
215            The second parameter of the <function>CFG_SEC()</function> macro
216            points to the old greeting options "targets" and "repeat".
217        </para>
218        <para>
219            We have also used a couple of flags to alter the behaviour of the
220            section: CFGF_TITLE means that a greeting section should have a
221            title and the CFGF_MULTI flag tells libConfuse that this section
222            may be specified multiple times in the configuration file. The
223            title of a section is retrieved with the
224            <function>cfg_title()</function> function.
225        </para>
226        <para>
227            The outmost loop (with index j) now loops through all given
228            sections in the configuration file. We retrieve a section with a
229            <function>cfg_getnsec()</function> call. The value returned is a
230            pointer to a cfg_t struct, the same type as returned by
231            <function>cfg_init()</function>. Thus we can use the ordinary value
232            retrieval functions <function>cfg_getstr()</function>,
233            <function>cfg_getint()</function> and so on to retrieve values of
234            options inside the section.
235        </para>
236        <para>
237            Ok, so how does the configuration file look like for this setup?
238        </para>
239        <programlisting>
240# this is the configuration file for the hello program
241
242greeting Hello
243{
244    targets = {"Life", "Universe", "Everything"}
245    repeat = 1
246}
247
248greeting Bye
249{
250    targets = {Adams}
251    repeat = 1
252}
253        </programlisting>
254        <para>
255            The program will loop through the sections in the order specified
256            in the configuration file. First it will find the "Hello" section.
257            It prints the title of the section, "Hello", retrieved with
258            <function>cfg_title()</function>. Then the targets are printed just
259            as in the previous exemples, but this time the values are retrieved
260            from the cfg_greet section. Next, the section titled "Bye" is
261            found, and the values are retrieved from that section.
262        </para>
263        <para>
264            When run, the program produces the following:
265        </para>
266        <programlisting>
267$ ./listing5
268Hello, Life, Universe, Everything!
269Bye, Adams!
270$ 
271        </programlisting>
272
273    </sect1>
274    <sect1>
275        <title>Parsing from internal buffers</title>
276        <para>
277            So far, we have only parsed configuration data from files.
278            libConfuse can also parse buffers, or in-memory character
279            strings. We will use this to fix a problem in the previous code.
280        </para>
281        <para>
282            The problem is that without a configuration file, the hello program
283            will not print anything. We want it to at least print the standard
284            greeting "Hello, World!" if no configuration file is available.
285        </para>
286        <para>
287            We can't have a default value for a section that can be specified
288            multiple times (ie, a section with the CFGF_MULTI flag set).
289            Instead we will parse a default configuration string if no section
290            has been parsed:
291        </para>
292        &listing6;
293        <para>
294            Only the changes from the previous code is shown here. We check if
295            the size of the "greeting" section is zero (ie, no section has been
296            defined). In that case we call <function>cfg_parse_buf()</function>
297            to parse a default in-memory string "greeting Hello {}". This
298            string defines a greeting section with title Hello, but without any
299            sub-options. This way we rely on the default values of the
300            (sub-)options "targets" and "repeat".
301        </para>
302        <para>
303            When this program is run, it issues the well-known standard greeting
304            "Hello, World!" if no configuration file is present.
305        </para>
306    </sect1>
307
308    <sect1>
309        <title>Validating callback functions</title>
310        <para>
311            Remember the problem about a negative or too large "repeat" value
312            in <xref linkend="negative-repeat-problem"/>?  The code that prints
313            the greeting has those lines:
314        </para>
315        <programlisting>
316...
317repeat = cfg_getint(cfg_greet, "repeat");
318while(repeat--)
319...
320        </programlisting>
321        <para>
322            The repeat variable is defined as an int, a signed integer. If the user
323            specified a negative repeat value in the configuration file, this code
324            would continue to decrease the repeat variable until it eventually
325            underflowed.
326        </para>
327        <para>
328            We'll fix this by not allowing a negative value in the configuration
329            file. Of course we could first just check if the value is negative
330            and then abort, using <function>cfg_getint()</function> and a test.
331            But we will use a validating callback function instead. This way
332            <function>cfg_parse()</function> will return an error directly when
333            parsing the file, additionally indicating on which line the error
334            is.
335        </para>
336        <para>
337            A validating callback function is defined as:
338        </para>
339        <programlisting>
340typedef int (*cfg_validate_callback_t)(cfg_t *cfg, cfg_opt_t *opt);
341        </programlisting>
342        <para>
343            This function takes two arguments: the section and the option. It
344            should return 0 on success (ie, the value validated ok). All other
345            values indicates an error, and the parsing is aborted. The callback
346            function should notify the error itself, for example by calling
347            <function>cfg_error()</function>.
348        </para>
349        <para>
350            Here is the code for the callback function:
351        </para>
352        &listing7;
353        <para>
354            Only the last value is validated, because libConfuse will call this
355            function once for every value corresponding to the option. Since
356            the "repeat" option is not a list, we could instead have used
357            <function>cfg_opt_getint(opt)</function> to retrieve the only
358            value. However, if we later want to use this callback to validate
359            an integer list, it is already lists-aware.
360        </para>
361
362        <sect2>
363            <title>Installing the callback</title>
364            <para>
365                The validating callback is installed with
366                <function>cfg_set_validate_func()</function>. It is called with
367                a string specifying which option is affected, and a pointer to
368                the callback function. To specify an option in a subsection,
369                the section and the option must be separated with a vertical
370                bar ("|").
371            </para>
372            <para>
373                We're now also looking at the return code from
374                <function>cfg_parse()</function> to verify that the parsing was
375                successful. The complete program is now:
376            </para>
377            &listing8;
378        </sect2>
379    </sect1>
380
381    <sect1>
382        <title>Value parsing callback</title>
383        <para>
384            A value parsing callback is another kind of callback function
385            available in libConfuse. This function is used to map a string into
386            some other other value. One example is to extend a boolean option
387            to accept the values "yes", "no" and "ask" (or perhaps "true",
388            "false" and "maybe"). Those values should be mapped to the integers
389            1, 2 and 3.
390        </para>
391        <programlisting>
392typedef int (*cfg_callback_t)(cfg_t *cfg, cfg_opt_t *opt,
393                              const char *value, void *result);
394        </programlisting>
395        <para>
396            
397        </para>
398    </sect1>
399
400    <sect1>
401        <title>Functions</title>
402        <para>
403            libConfuse supports functions to parse options that does not fit
404            well in the general syntax. Functions can be called with a variable
405            number of arguments. No data from the function or any arguments are
406            stored by libConfuse after the function has run. It is up to the caller
407            to process and/or save the data.
408        </para>
409        <para>
410            A function is defined with a <function>CFG_FUNC</function> macro.
411            It takes two arguments: the name of the function and a function
412            callback. The callback is defined as:
413        </para>
414        <programlisting>
415typedef int (*cfg_func_t)(cfg_t *cfg, cfg_opt_t *opt,
416                          int argc, const char **argv);
417        </programlisting>
418        <para>
419        </para>
420
421        <sect2>
422            <title>Predefined functions</title>
423            <para>
424                Currently there is only one pre-defined function:
425                <function>cfg_include()</function>. This function includes
426                another configuration file. Configuration data is immediately
427                read from the included file, and is returned to the position
428                right after the include() statement upon end of file.
429            </para>
430            <para>
431                To use this function, include a <function>CFG_FUNC()</function>
432                entry in your options:
433            </para>
434            <programlisting>
435cfg_opt_t opts[] = {
436    CFG_FUNC("include", cfg_include),
437    CFG_END()
438};
439            </programlisting>
440            <para>
441                In the configuration file, it is used in the following way:
442            </para>
443            <programlisting>
444include("included.conf")
445            </programlisting>
446        </sect2>
447    </sect1>
448
449    <sect1>
450        <title>Saving configuration files</title>
451        <para>
452        </para>
453
454        <sect2>
455            <title>Altering the printing of certain options</title>
456            <para>
457            </para>
458        </sect2>
459    </sect1>
460
461</article>
462
463