4. Using sections
Prev |  | Next

## 4. Using sections

So far, we have only use a flat configuration file. libConfuse can also handle sections to build a hierarchy of options. Sections can be used to group options in logical blocks, and those blocks can (optionally) be specified multiple times.

Sections are initialized with the `CFG_SEC()` macro. It also takes three parameters: the name of the option, an array of options allowed in the section and flags.

We'll extend the, now rather complex, hello program so we can do other kinds of greetings, not just "Hello". Each greeting will have its own settings for targets and repeat.

    1	#include <stdio.h>
    2	#include <confuse.h>
    3
    4	int main(void)
    5	{
    6	    cfg_opt_t greet_opts[] =
    7	    {
    8	        CFG_STR_LIST("targets", "{World}", CFGF_NONE),
    9	        CFG_INT("repeat", 1, CFGF_NONE),
    10	        CFG_END()
    11	    };
    12	    cfg_opt_t opts[] =
    13	    {
    14	        CFG_SEC("greeting", greet_opts, CFGF_TITLE | CFGF_MULTI),
    15	        CFG_END()
    16	    };
    17	    cfg_t *cfg, *cfg_greet;
    18	    int repeat;
    19	    int i, j;
    20
    21	    cfg = cfg_init(opts, CFGF_NONE);
    22	    if(cfg_parse(cfg, "hello.conf") == CFG_PARSE_ERROR)
    23	        return 1;
    24
    25	    for(j = 0; j < cfg_size(cfg, "greeting"); j++)
    26	    {
    27	        cfg_greet = cfg_getnsec(cfg, "greeting", j);
    28
    29	        repeat = cfg_getint(cfg_greet, "repeat");
    30	        while(repeat--)
    31	        {
    32	            printf("%s", cfg_title(cfg_greet));
    33	            for(i = 0; i < cfg_size(cfg_greet, "targets"); i++)
    34	                printf(", %s", cfg_getnstr(cfg_greet, "targets", i));
    35	            printf("!\n");
    36	        }
    37	    }
    38
    39	    cfg_free(cfg);
    40	    return 0;
    41	}
    42

We have renamed the option array from "opts" to "greet_opts", and introduced a new "opts" array that only has one option: a "greeting" section. The second parameter of the `CFG_SEC()` macro points to the old greeting options "targets" and "repeat".

We have also used a couple of flags to alter the behaviour of the section: CFGF_TITLE means that a greeting section should have a title and the CFGF_MULTI flag tells libConfuse that this section may be specified multiple times in the configuration file. The title of a section is retrieved with the `cfg_title()` function.

The outmost loop (with index j) now loops through all given sections in the configuration file. We retrieve a section with a `cfg_getnsec()` call. The value returned is a pointer to a cfg_t struct, the same type as returned by `cfg_init()`. Thus we can use the ordinary value retrieval functions `cfg_getstr()`, `cfg_getint()` and so on to retrieve values of options inside the section.

Ok, so how does the configuration file look like for this setup?

    # this is the configuration file for the hello program

    greeting Hello
    {
        targets = {"Life", "Universe", "Everything"}
        repeat = 1
    }

    greeting Bye
    {
        targets = {Adams}
        repeat = 1
    }

The program will loop through the sections in the order specified in the configuration file. First it will find the "Hello" section. It prints the title of the section, "Hello", retrieved with `cfg_title()`. Then the targets are printed just as in the previous examples, but this time the values are retrieved from the cfg_greet section. Next, the section titled "Bye" is found, and the values are retrieved from that section.

When run, the program produces the following:

    $ ./listing5
    Hello, Life, Universe, Everything!
    Bye, Adams!
    $

Prev |  | Next
3. Introducing lists | Home | 5. Parsing from internal buffers