libcfg+: command line and configuration file parsing library
Prev |  | Next

# Chapter 2. Usage

In the core of libcfg+ is a single, carefully designed structure, which makes the uniform and consistent API possible.

# 2.1. Options set

The basic unit of libcfg+ is an option. An option is defined by the cfg_option structure, whose definition is presented below:

    struct cfg_option {
    	const char *cmdline_long_name;
    	const char  cmdline_short_name;
    	const char *cfgfile_name;
    	const enum cfg_option_type type;
    	void *value;
    	int   val;
    };

The first two members of the cfg_option structure, `cmdline_long_name` and `cmdline_short_name`, specify the long and short name of the option when parsing the command line. The third member, `cfgfile_name`, specifies the name of the option in a configuration file. Setting the first two fields to `NULL` and `'\0'` respectively will effectively eliminate the option from taking part in command line parsing. Setting `cfgfile_name` to `NULL` will eliminate this option from taking part in configuration file parsing.

Note also that if `cmdline_long_name` or `cfgfile_name` point to a string containing at least one whitespace character, any non-zero number of whitespace characters will be matched during parsing. For example, if the separator is a space, a tab character will also match, as will two spaces and a tab, two tabs and a space, and so on. This simplifies the configuration for the user because one does not have to pay attention to the number of spaces used in a configuration option. For example, `debug level`, `debug\tlevel` and `debug \tlevel` will match the same option.

The variable `type` is an enumeration defining the type of an option with each member of the enumeration being either a type or a flag. The possible values of `type` are summarized in tables Option types and Option type flags

The variable `value` is a pointer to the argument(s) of an option. The argument(s) must be of the type stored in the `type` member of the cfg_option structure. Note that `value` could also contain a `NULL` value, which would suggest that the option arguments will not be stored.

The last field of the structure is `val`. It defines the exit code of parsing function when this option is found in the token stream. Setting this field to `0` will cause `cfg_get_next_opt()` to proceed to the next option instead of returning. Also, since `cfg_get_next_opt()` also returns negative integers to signal an error, it is a good idea to keep the value of this field in the positive range. You can read more about this in the Parsing section.

Table 2-1. Option types

Value | `value` type | Description
--- | --- | ---
`CFG_BOOL`, `CFG_BOOLEAN` | int | No argument for an option is expected. Boolean datatype with two states.
`CFG_INT`, `CFG_INTEGER` | int | Integer argument
`CFG_UINT`, `CFG_UNSIGNED`, `CFG_UNSIGNED_INT` | unsigned int | Unsigned integer argument
`CFG_LONG` | long int | Long integer argument
`CFG_ULONG`, `CFG_UNSIGNED_LONG` | unsigned long int | Unsigned long integer argument
`CFG_FLOAT` | float | Float argument
`CFG_DOUBLE` | double | Double argument
`CFG_STR`, `CFG_STRING` | char * | String argument

The next table describes the possible "type flags" of an option. The purpose of the flags is to add more variety and thus flexibility to the basic data types presented in the previous table. By combining one of the flags with one of the basic types, a completely new data type can be produced. For example, to define an array of strings, one would use the `CFG_MULTI` flag in addition to the `CFG_STRING` data type. One of the obvious rules of this data type combining is that the flags must always be used in conjunction with the basic types since a flag is only a data type modifier and not a self-contained data type.

Table 2-2. Option type flags

Flag | `value` type | Description
--- | --- | ---
`CFG_MULTI`, `CFG_MULTI_ARRAY` | <type> ** | The Option can be specified more than once and the result is a dynamic array of the defined type.
`CFG_MULTI_SEPARATED` | <type> ** | Same as `CFG_MULTI_ARRAY`, but a dynamic array is also created by splitting the option value according to the defined separators. See the Properties section for more information about the separators that can be used and ways to change them.
`CFG_LAST_ARGS`, `CFG_LAST_ARGUMENTS`, `CFG_LEFTOVER_ARGS`, `CFG_LEFTOVER_ARGUMENTS` | <type> ** | Leftover arguments are stored here.

Of the basic data types, only strings are dynamically allocated and in that case `value` points to a portion of memory allocated with `malloc()` function. Do not forget to free that memory when you do not need it anymore using the `free()` function. If the `CFG_MULTI_ARRAY` or the `CFG_MULTI_SEPARATED` flag was used, `value` will point to a `NULL` terminated array of a basic type. It can be freed using `cfg_strdyn_free()`.

The constants `CFG_END_OPTION` and `CFG_END_OF_LIST` are used to mark the end of an option set. They set all pointer values to `NULL` and all numeric values to `0`.

Example 2-1. Example of options set definition

    #include <cfg+.h>

    /* Option variables */
    int help, verbose, nice;
    char *cfg_file;
    char **command;

    /* Option set */
    struct cfg_option options[] = {
      {"help",    'h', NULL,      CFG_BOOL,          (void *) &help,     0},
      {"nice",    'n', "nice",    CFG_INT,           (void *) &nice,     0},
      {"verbose", 'v', "verbose", CFG_BOOL+CFG_MULTI,(void *) &verbose,  0},
      {NULL,      'f', NULL,      CFG_STR,           (void *) &cfg_file, 0},
      {NULL, '\0', "command", CFG_STR+CFG_MULTI_SEPARATED+CFG_LEFTOVER_ARGS,
        (void *) &command, 0},
      CFG_END_OF_LIST
    };

Prev | Home | Next
Installation |  | Context manipulation