-Configuration and command line parser
-=====================================
+Configuration parser
+====================
Libucw contains a parser for configuration files. The syntax of the
configuration files is described in <<config:>>, here we explain the
each section declared at a separate place. You can also define your own
data types.
-There is also a simple wrapper around getopt_long(), which processes
-options related to selection of a configuration file, overriding of
-configuration variables and loading of the default configuration.
-
- <<example,Example>>
* <<ex_structure,The structure>>
- * <<ex_load,Loading>>
+ * <<ex_load,Loading configuration>>
- <<deep,Getting deeper>>
* <<conf_multi,Arrays and lists>>
* <<reload,Reloading configuration>>
* <<conf_direct,Direct access>>
* <<conf_dump,Debug dumping>>
- <<getopt_h,ucw/getopt.h>>
- * <<conf_getopt,Loading by cf_getopt()>>
+ * <<conf_getopt,Loading configuration by cf_getopt()>> (obsolete)
+ * <<getopt_example,Example>> (obsolete)
[[example]]
Example
various places across your code.
[[ex_load]]
-Loading of the values
+Loading configuration
~~~~~~~~~~~~~~~~~~~~~
-Suppose you need to parse the command line arguments and load the
-configuration. Then @cf_getopt() is there for you: it works like
-the traditional @getopt_long() from the C library, but it also handles
-configuration files.
+You can load the configuration explicitly by calling @cf_load().
+That can be convenient when writing a library, but in normal programs,
+you can ask the <<opt:,option parser>> to handle it for you.
- #include <ucw/lib.h>
- #include <ucw/conf.h>
- #include <ucw/getopt.h>
+A typical example follows, please see the <<opt:conf,interface between
+conf and opt>> for details.
- static char short_opts[] = CF_SHORT_OPTS "v";
- static struct option long_opts[] = {
- CF_LONG_OPTS
- { "verbose", 0, 0, 'v' },
- { NULL, 0, 0, 0 }
+ #include <ucw/lib.h>
+ #include <ucw/opt.h>
+
+ static struct opt_section options = {
+ OPT_ITEMS {
+ // More options can be specified here
+ OPT_HELP("Configuration options:"),
+ OPT_CONF_OPTIONS,
+ OPT_END
+ }
};
-
- static int verbose;
-
- int main(int argc, char *argv[]) {
+
+ int main(int argc, char **argv)
+ {
cf_def_file = "default.cf";
- int opt;
- while((opt = cf_getopt(argc, argv, short_opts, long_opts, NULL)) >= 0)
- switch(opt) {
- case 'v': verbose = 1; break;
- default: fprintf("Unknown option %c\n", opt); return 1;
- }
+ opt_parse(&options, argv+1);
+ // Configuration file is already loaded here
+ return 0;
}
-The `short_opts` and `long_opts` variables describe the command line
-arguments. Notice the `CF_SHORT_OPTS` and `CF_LONG_OPTS` macros. They
-add the `-S` and `-C` options for the configuration parser as described
-in <<config:>>. These options are handled internally by @cf_getopt().
-
-You can rely on the configuration files having been loaded before the
-first of your program's options is parsed.
-
[[deep]]
Getting deeper
--------------
+
For example, you can have an static array of five unsigned integers:
+
- static uns array[] = { 1, 2, 3, 4, 5 };
+ static uint array[] = { 1, 2, 3, 4, 5 };
+
static struct cf_section section = {
CF_ITEMS {
- CF_UNS_ARY("array", array, 5),
+ CF_UINT_ARY("array", array, 5),
CF_END
}
};
*Dynamic arrays*::
Similar to static array, but you provide pointer
to pointer to the given item (eg. if you want dynamic array of
- integers, you give `**int`). The parser allocates an array of needed
- size. You can use the <<def_DARY_LEN,`DARY_LEN`>> macro to find out
- the number of elements actually loaded.
+ integers, you give `**int`). The parser allocates a <<gary:,growing array>>
+ of the required size.
+
If you want dynamic array of strings, you would use:
+
};
*Lists*::
- Linked lists based on <<clist:>>. You provide description
+ Linked lists based on <<lists:clists,clists>>. You provide description
of single node and pointer to the
- <<clist:struct_clist,`struct clist`>> variable. All the nodes will
+ <<lists:struct_clist,`struct clist`>> variable. All the nodes will
be created dynamically and put there.
+
-First element of your structure must be <<clist:type_cnode,`cnode`>>.
+First element of your structure must be <<lists:struct_cnode,`cnode`>>.
+
-The first example is list of strings and uses <<clist:simple,simple
+The first example is list of strings and uses <<lists:simple_lists,simple
lists>>:
+
static struct clist list;
is added. If it fails, the first one is replayed and the rollback
entry is removed.
-See <<cf_reload()>>.
+See @cf_reload().
[[custom_parser]]
Creating custom parsers
~~~~~~~~~~~~~~~~~~~~~~~
If you need to parse some data type the configuration system can't
-handle, you can write your own parser. But before you start, you
-should know a few things.
+handle, you can write your own <<xtypes:,extended type>>
+and use <<def_CF_XTYPE,`CF_XTYPE`>> macro to declare a new option.
+
+There is also an obsolete way to write a custom parser.
+Before you start, you should know a few things.
The parser needs to support <<journal,journalling>>. To accomplish that,
you have to use the <<alloc,configuration mempool>> for memory allocation.
This header contains routines for parsing command line arguments and
loading the default configuration.
+In new programs, please consider using the new <<opt:,option parser>>
+instead. The getopt interface is already considered obsolete and may
+be removed in the future.
+
!!ucw/getopt.h
+
+Example
+~~~~~~~
+Typically, @cf_getopt() is used as follows: it works like
+the traditional @getopt_long() from the C library, but it also handles
+configuration files.
+
+ #include <ucw/lib.h>
+ #include <ucw/conf.h>
+ #include <ucw/getopt.h>
+
+ static char short_opts[] = CF_SHORT_OPTS "v";
+ static struct option long_opts[] = {
+ CF_LONG_OPTS
+ { "verbose", 0, 0, 'v' },
+ { NULL, 0, 0, 0 }
+ };
+
+ static int verbose;
+
+ int main(int argc, char *argv[]) {
+ cf_def_file = "default.cf";
+ int opt;
+ while((opt = cf_getopt(argc, argv, short_opts, long_opts, NULL)) >= 0)
+ switch(opt) {
+ case 'v': verbose = 1; break;
+ default: fprintf("Unknown option %c\n", opt); return 1;
+ }
+ }
+
+The `short_opts` and `long_opts` variables describe the command line
+arguments. Notice the `CF_SHORT_OPTS` and `CF_LONG_OPTS` macros. They
+add the `-S` and `-C` options for the configuration parser as described
+in <<config:>>. These options are handled internally by @cf_getopt().
+
+You can rely on the configuration files having been loaded before the
+first of your program's options is parsed.