]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/doc/conf.txt
Fixed a typo in configuration example.
[libucw.git] / ucw / doc / conf.txt
index a1f2aaf24735a156270f3f315235b171573a0476..71358a81c71344b75851d809f9b71df4c06202d1 100644 (file)
@@ -21,6 +21,7 @@ from command line.
   * <<ex_structure,The structure>>
   * <<ex_load,Loading>>
 - <<deep,Getting deeper>>
   * <<ex_structure,The structure>>
   * <<ex_load,Loading>>
 - <<deep,Getting deeper>>
+  * <<conf_multi,Arrays and lists>>
   * <<reload,Reloading configuration>>
   * <<custom_parser,Creating custom parsers>>
   * <<hooks,Hooks>>
   * <<reload,Reloading configuration>>
   * <<custom_parser,Creating custom parsers>>
   * <<hooks,Hooks>>
@@ -29,6 +30,7 @@ from command line.
   * <<conf_macros,Convenience macros>>
   * <<alloc,Memory allocation>>
   * <<journal,Undo journal>>
   * <<conf_macros,Convenience macros>>
   * <<alloc,Memory allocation>>
   * <<journal,Undo journal>>
+  * <<declare,Section declaration>>
   * <<bparser,Parsers for basic types>>
 - <<getopt_h,ucw/getopt.h>>
   * <<conf_load,Safe configuration loading>>
   * <<bparser,Parsers for basic types>>
 - <<getopt_h,ucw/getopt.h>>
   * <<conf_load,Safe configuration loading>>
@@ -84,7 +86,8 @@ The variables are used to store the loaded values. Their initial
 values work as default, if nothing else is loaded. The hw_config()
 structure assigns the variables to configuration names. The hw_init()
 function (because of the `CONSTRUCTOR` macro) is run before main()
 values work as default, if nothing else is loaded. The hw_config()
 structure assigns the variables to configuration names. The hw_init()
 function (because of the `CONSTRUCTOR` macro) is run before main()
-is called and it plugs in the whole section to the parser.
+is called and it plugs in the whole section to the parser (alternatively,
+you can call @cf_declare_section() at the start of your main()).
 
 You can plug in as many configuration sections as you like, from
 various places across your code.
 
 You can plug in as many configuration sections as you like, from
 various places across your code.
@@ -92,21 +95,23 @@ various places across your code.
 [[ex_load]]
 Loading of the values
 ~~~~~~~~~~~~~~~~~~~~~
 [[ex_load]]
 Loading of the values
 ~~~~~~~~~~~~~~~~~~~~~
-You need to parse the command line arguments and load the
-configuration. You can do it in a similar way to this example.
+Suppose you need to parse the command line arguments and load the
+configuration. Then @cf_getopt() is there for you: it works like
+the the traditional @getopt() from the C library, but it also handles
+configuration files.
 
   #include <ucw/lib.h>
   #include <ucw/conf.h>
   #include <ucw/getopt.h>
 
 
   #include <ucw/lib.h>
   #include <ucw/conf.h>
   #include <ucw/getopt.h>
 
-  static byte short_opts[] = CF_SHORT_OPTS "v";
+  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 struct option long_opts[] = {
     CF_LONG_OPTS
     { "verbose", 0, 0, 'v' },
     { NULL, 0, 0, 0 }
   };
 
-  int verbose;
+  static int verbose;
 
   int main(int argc, char *argv[]) {
     cf_def_file = "default.cf";
 
   int main(int argc, char *argv[]) {
     cf_def_file = "default.cf";
@@ -116,14 +121,15 @@ configuration. You can do it in a similar way to this example.
        case 'v': verbose = 1; break;
        default: fprintf("Unknown option %c\n", opt); return 1;
       }
        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
 
 The `short_opts` and `long_opts` variables describe the command line
 arguments. Notice the `CF_SHORT_OPTS` and `CF_LONG_OPTS` macros. They
-add options for the configuration parser. These options are handled
-internally by @cf_getopt(). It loads the configuration before it starts
-giving you your program's options.
+add the `-S` and `-C` options for the configuration parser as described
+in <<config:>>. These options are handled internally by @cf_getopt().
 
 
-See documentation of unix getopt_long() function.
+You can rely on the configuration files having been loaded before the
+first of your program's options is parsed.
 
 [[deep]]
 Getting deeper
 
 [[deep]]
 Getting deeper
@@ -132,6 +138,69 @@ Getting deeper
 Since the configuration system is somehow complicated, this part gives
 you a little overview of what you can find and where.
 
 Since the configuration system is somehow complicated, this part gives
 you a little overview of what you can find and where.
 
+[[conf_multi]]
+Arrays and lists
+~~~~~~~~~~~~~~~~
+
+It is sometime needed to have multiple items of the same type. There
+are three ways to do that:
+
+*Static arrays*::
+  An array with fixed maximum length. You provide
+  the length and already allocated array which is filled with items.
+  The configuration may contain less than the maximum length items.
++
+For example, you can have an static array of five unsigned integers:
++
+  static uns array[] = { 1, 2, 3, 4, 5 };
++
+  static struct cf_section section = {
+    CF_ITEMS {
+      CF_UNS_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.
++
+If you want dynamic array of strings, you would use:
++
+  static char *array[];
++
+  static struct cf_section section = {
+    CF_ITEMS {
+      CF_STRING_DYN("array", &array, CF_ANY_NUM),
+      CF_END
+    }
+  };
+
+*Lists*::
+  Linked lists based on <<clist:>>. You provide description
+  of single node and pointer to the
+  <<clist: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`>>.
++
+The first example is list of strings and uses <<clist:simple,simple
+lists>>:
+  struct clist list;
++
+  static struct cf_section section = {
+    CF_ITEMS {
+      CF_LIST("list", &list, &cf_string_list_cofnig),
+      CF_END
+    }
+  };
++
+Another example, describing how to create more complicated list node
+than just a string can be found at the <<def_CF_TYPE,`CF_TYPE`>> macro.
+
 [[reload]]
 Reloading configuration
 ~~~~~~~~~~~~~~~~~~~~~~~
 [[reload]]
 Reloading configuration
 ~~~~~~~~~~~~~~~~~~~~~~~