The basic element of libcfg+ usage is one option. Option is defined like cfg_option structure. Definition follows:
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;
};
First two members of cfg_option structure, cmdline_long_name and cmdline_short_name concern to command line. They specify command line long name and short name. Configuration file option name is specified by third structure member cfgfile_name. Fields cmdline_long_name and cfgfile_name are strings (pointers to char) and may be NULL, what means undefined. Field cmdline_short_name is single character and may be '\0', what means also undefined.
Note that, any whitespace you will use in cmdline_long_name or cfgfile_name will match any non-zero amount of whitespace during parsing. For example if separator is one space, also tab will match, two or more spaces too, etc. This feature is to simplify configuration of your application for your user, as she doesn't have to pay attention to number of spaces used in configurarion option. For example "debug level", "debug\tlevel" and "debug \tlevel" will match the same configuration option.
Next structure member, type, defines an option type with option type flags. They are summarized in tables Option types and Option type flags.
The value member tells the address where option argument or arguments will be stored. It should be address of appropriate datatype defined in type field. Note that NULL can be also used, but then option argument will not be stored. Last field of cfg_option structure is val, which defines exit code from parsing functions when option is found. 0 means no return. It is good idea to keep these values positive to prevent mismatch with cfg_error exit codes.
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 |
Here follows option type flags. These flags can be used in addition to particular options types in option set. They modify value datatype.
Table 2-2. Option type flags
Flag | value type | Description |
---|---|---|
CFG_MULTI, CFG_MULTI_ARRAY | <type> ** | Option can be specified more than once and result is dynamic array of defined type. |
CFG_MULTI_SEPARATED | <type> ** | Same as the CFG_MULTI_ARRAY, but dynamic array is also created by spliting option value according to defined separators. See Properties section for more information about used separators and how to change them. |
CFG_LAST_ARGS, CFG_LAST_ARGUMENTS, CFG_LEFTOVER_ARGS, CFG_LEFTOVER_ARGUMENTS | <type> ** | Leftover arguments are stored here. |
All simple datatypes are stored to defined address as they are. Strings are dynamically allocated using malloc() function and pointer (address) to this string is stored. In this case, don't forget to free allocated memory using free() function. When using CFG_MULTI_ARRAY or CFG_MULTI_SEPARATED type flag, pointer to NULL terminated array of defined datatype is always stored. This array can be freed using strdyn_free() function.
One of the constants CFG_END_OPTION and CFG_END_OF_LIST is used to mark end of an options set. They have set all pointer values to NULL and all arithmetic 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 };