Cfg

# 3. Cfg

The cfg(3m) module provides an interface to load and store comments and key/value pairs. A small state machine parser preserves all space tokens and comments in order between loading, manipulating, and storing `cfg` files. The following is a sample of serialized properties (the `cfg` file format):

      # This is a comment
      addr = 192.168.1.15
      !port = 15000
      user.1 = miallen
      user.2 = gchan

Lines beginning with the '#' and '!' characters will be interpreted as comments. Keys are separated from values with '='. Reserved characters, leading and trailing spaces, and Unicode are supported with '\' escapes. If `USE_WCHAR` is defined, strings are `wchar_t`. Otherwise string encoding is locale dependant. See the HTML documentation for the `text` module.

### 3.1. Memory management functions

These functions should be used to manage cfg objects.

The `cfg_init` function
Synopsis

      #include <mba/cfg.h>
      int cfg_init(struct cfg *cfg, struct allocator *al);

Description
The `cfg_init` function initializes a `cfg` object. The object will have no properties. Memory for all `cfg` operations will be allocated from the allocator `al`. It may be necessary to call `cfg_deinit` to release memory allocated from the allocator `al`.
Returns
The `cfg_init` function returns -1 and sets `errno` to an appropriate value if an error occured or 0 if the object was successfully initialized.

The `cfg_deinit` function
Synopsis

      #include <mba/cfg.h>
      int cfg_deinit(struct cfg *cfg);

Description
The `cfg_deinit` function frees any resources associated with this `cfg` object. It is not necessary to deinitialize a `cfg` object if the memory backing it's allocator can be freed separately (e.g. using a `suba`(3m) allocator backed with stack memory is more efficient).
Returns
The `cfg_deinit` function returns -1 and sets `errno` to an appropriate value if an error occured or 0 if resources were successfully freed.

The `cfg_new` function
Synopsis

      #include <mba/cfg.h>
      struct cfg *cfg_new(struct allocator *al);

Description
The `cfg_new` function allocates memory from the allocator specified by the `al` parameter, initializes it with `cfg_init`, and returns a pointer to the new `cfg` object. The object will have no properties. The allocator specified by the `al` parameter will be used for all further memory management associated with this object. It may be necessary to call `cfg_del` to release memory allocated from the allocator `al`.
Returns
The `cfg_new` function returns a new `cfg` object if the operation succeeded or `NULL` if the operation failed in which case `errno` is set appropriately.

The `cfg_del` function
Synopsis

      #include <mba/cfg.h>
      int cfg_del(void *cfg);

Description
The `cfg_del` function frees the `cfg` object and all properties within it. It is not necessary to delete a `cfg` object if the memory backing it's allocator can be freed separately (e.g. using a `suba`(3m) allocator backed with stack memory is more efficent).
Returns
The `cfg_del` function return 0 if the operation was successful or -1 if it failed in which case `errno` will be set accordingly.

### 3.2. Load and store functions

The `cfg_load` function
Synopsis

      #include <mba/cfg.h>
      int cfg_load(struct cfg *cfg, const char *filename);

Description
The `cfg_load` function loads the properties in `filename` into the `cfg` object `cfg`.
Returns
The `cfg_load` function returns -1 and sets `errno` to an appropriate value if the operation failed or 0 if the properties were successfully loaded.

The `cfg_load_str` function
Synopsis

      #include <mba/cfg.h>
      int cfg_load_str(struct cfg *cfg, const tchar *src, const tchar *slim);

Description
The `cfg_load_str` function loads properties into this `cfg` object from the character string at `src` up to but not including the memory at `slim`.

The `cfg_load_env` function
Synopsis

      #include <mba/cfg.h>
      int cfg_load_env(struct cfg *cfg);

Description
The `cfg_load_env` function loads the process environment as properties.
Returns
The `cfg_load_env` function returns -1 and sets `errno` to an appropriate value if the operation failed or 0 if the process environment was successfully loaded.

The `cfg_load_cgi_query_string` function
Synopsis

      #include <mba/cfg.h>
      int cfg_load_cgi_query_string(struct cfg *cfg, const tchar *qs);

Description
The `cfg_load_cgi_query_string` function parses a `QUERY_STRING` style string like the one below which would result in loading properties 'hl', 'lr', 'ie', 'oe' and 'group' with their respective values. Parameters with no values such as 'lr' will be loaded with an empty string.

      hl=en&lr=&ie=UTF-8&oe=UTF-8&group=comp.unix.programmer

Returns
The `cfg_load_cgi_query_string` function returns 0 if the query string parameters were valid and loaded successfully. Otherwise -1 is returned and `errno` is set appropriately.

The `cfg_store` function
Synopsis

      #include <mba/cfg.h>
      int cfg_store(struct cfg *cfg, const char *filename);

Description
The `cfg_store` function serializes the properties of the object `cfg` and stores them in `filename`.
Returns
The `cfg_store` function returns -1 and sets `errno` to an appropriate value if the operation failed or 0 if the properties were successfully stored.

The `cfg_fwrite` function
Synopsis

      #include <mba/cfg.h>
      int cfg_fwrite(struct cfg *cfg, FILE *stream);

Description
The `cfg_fwrite` function serializes the properties of the object `cfg` and stores them in `filename`.
Returns
The `cfg_fwrite` function returns -1 and sets `errno` to an appropriate value if the operation failed or 0 if the properties were successfully written.

### 3.3. Property manipulation functions

The `cfg_iterate` function
Synopsis

      #include <mba/cfg.h>
      void cfg_iterate(void *cfg, iter_t *iter);

Description
Enumerate each key in this `cfg` object. The `cfg_iterate` function initializes `iter` with the position of the first property in this `cfg`. With each subsequent call to `cfg_next` the key of each property is returned or `NULL` if all keys have been enumerated.

The `cfg_next` function
Synopsis

      #include <mba/cfg.h>
      const tchar *cfg_next(void *cfg, iter_t *iter);

Returns
The `cfg_next` function returns the next property in this `cfg` object or `NULL` if all keys have been enumerated.

The `cfg_get_str` function
Synopsis

      #include <mba/cfg.h>
      int cfg_get_str(struct cfg *cfg,
               tchar *dst,
               int dn,
               const tchar *def,
               const tchar *name);

Description
The `cfg_get_str` function retrieves a property identified by `name` into the memory spcecified by `dst` as a string. No more than `dn` bytes of `dst` will be written to. If the value is truncated a trailing '\0' will be included. If the named property is not in the list and the string `def` is not `NULL`, `def` will be copied into `dst`.
Returns
If the named property is not found and `def` is `NULL` or the operation fails for another reason the `cfg_get_str` function will return -1 and set `errno` to an appropriate value. Otherwise 0 is returned to indicate the string was successfully copied.

The `cfg_vget_str` function
Synopsis

      #include <mba/cfg.h>
      int cfg_vget_str(struct cfg *cfg,
               tchar *dst,
               int dn,
               const tchar *def,
               const tchar *name,
               ...);

Description
The `cfg_vget_str` function retrieves a property identified by `name` into the memory spcecified by `dst` as a string. The `name` parameter is a format specifier that is parsed by vsprintf(3) before being passed to `cfg_get_str`. This permits complex keys to be constructed in-situ. To iterate over each element in a list of at most 10 properties named user.0, user.1, user.2, ... the following might be used:

      for (i = 0; i < 10; i++)
      	if (cfg_vget_str(cfg, buf, BUFSIZ, NULL, "user.%d", idx)) == 0)
      		break;   /* end of list */

Returns
The `cfg_vget_str` function returns -1 and sets `errno` to an appropriate value if the operation failed or 0 if the string was successfully copied.

The `cfg_get_short` function
Synopsis

      #include <mba/cfg.h>
      int cfg_get_short(struct cfg *cfg, short *dst, short def, const tchar *name);

Description
The `cfg_get_short` function is a convienence function that retrieves the property identified by `name` from `cfg` `cfg` object, converts it to a short integer with strtol(3), and stores the value in `dst`. If the named property does not exist, `def` will be copied to `dst`.
Returns
The `cfg_get_short` function returns -1 and sets `errno` to an appropriate value if the operation failed or 0 if the integer was successfully retrieved.

The `cfg_get_int` function
Synopsis

      #include <mba/cfg.h>
      int cfg_get_int(struct cfg *cfg, int *dst, int def, const tchar *name);

Description
The `cfg_get_int` function is a convienence function that retrieves the property identified by `name` from `cfg` `cfg` object, converts it to an integer with strtol(3), and stores the value in `dst`. If the named property does not exist, `def` will be copied to `dst`.
Returns
The `cfg_get_int` function returns -1 and sets `errno` to an appropriate value if the operation failed or 0 if the integer was successfully retrieved.

The `cfg_get_long` function
Synopsis

      #include <mba/cfg.h>
      int cfg_get_long(struct cfg *cfg, long *dst, long def, const tchar *name);

Description
The `cfg_get_long` function is a convienence function that retrieves the property identified by `name` from `cfg` `cfg` object, converts it to a long integer with strtol(3), and stores the value in `dst`. If the named property does not exist, `def` will be copied to `dst`.
Returns
The `cfg_get_long` function returns -1 and sets `errno` to an appropriate value if the operation failed or 0 if the integer was successfully retrieved.

The `cfg_vget_short` function
Synopsis

      #include <mba/cfg.h>
      int cfg_vget_short(struct cfg *cfg, short *dst, short def, const tchar *name, ...);

Description
The `cfg_vget_short` function is a convienence function that retrieves the property identified by `name` from `cfg` `cfg` object, converts it to a short integer with strtol(3), and stores the value in `dst`. The `name` parameter and variable arguments are first reduced using vsprintf(3) permitting complex keys to be constructed. If the named property does not exist, `def` will be copied to `dst`.
Returns
The `cfg_vget_short` function returns -1 and sets `errno` to an appropriate value if the operation failed or 0 if the integer was successfully retrieved.

The `cfg_vget_int` function
Synopsis

      #include <mba/cfg.h>
      int cfg_vget_int(struct cfg *cfg, int *dst, int def, const tchar *name, ...);

Description
The `cfg_vget_int` function is a convienence function that retrieves the property identified by `name` from `cfg` `cfg` object, converts it to an integer with strtol(3), and stores the value in `dst`. The `name` parameter and variable arguments are first reduced using vsprintf(3) permitting complex keys to be constructed. If the named property does not exist, `def` will be copied to `dst`.
Returns
The `cfg_vget_int` function returns -1 and sets `errno` to an appropriate value if the operation failed or 0 if the integer was successfully retrieved.

The `cfg_vget_long` function
Synopsis

      #include <mba/cfg.h>
      int cfg_vget_long(struct cfg *cfg, long *dst, long def, const tchar *name, ...);

Description
The `cfg_vget_long` function is a convienence function that retrieves the property identified by `name` from `cfg` `cfg` object, converts it to a long integer with strtol(3), and stores the value in `dst`. The `name` parameter and variable arguments are first reduced using vsprintf(3) permitting complex keys to be constructed. If the named property does not exist, `def` will be copied to `dst`.
Returns
The `cfg_vget_long` function returns -1 and sets `errno` to an appropriate value if the operation failed or 0 if the integer was successfully retrieved.

Copyright 2002 Michael B. Allen <mba2000 ioplex.com>