NAME¶
ggLoadConfig,
ggFreeConfig,
ggConfigIterTarget,
ggConfigIterLocation - Configuration helpers
SYNOPSIS¶
int ggLoadConfig(const char *file, gg_config *config);
void ggFreeConfig(gg_config config);
struct gg_location_iter {
struct gg_iter iter;
const void * config;
const char * name;
char * location;
const char * symbol;
void * _state;
};
int ggConfigIterLocation(struct gg_location_iter * iter);
struct gg_target_iter {
struct gg_iter iter;
void * config;
const char * input;
char * target;
char * options;
void * nested;
};
int ggConfigIterTarget(struct gg_target_iter *iter);
DESCRIPTION¶
These functions provides a simple way of handling configuration files.
ggLoadConfig tries to load the configuration file given as parameter. It
adds the content to the config handle found at
*config. If the handle
is NULL, a new one is created.
ggFreeConfig deletes the internal structure for the configuration handle
config. This handle becomes invalid and should not be used anymore.
ggConfigIterLocation allows to retreive the location and symbol
associated to canonical names. This function is mainly used together with the
scope abstraction to query application modules at runtime. This function will
prepare the
iter structure to be used as an iterator that will generate
correct matches.
iter is a pointer to a gg_location_iter structure
owned by the caller. This user part of the structure must be set by the caller
before calling
ggConfigIterLocation. The
config field must be
filled with the config handle which contains target information; the
name field must be filled with the canonical name that is being looked
for.
location and
symbol are placeholders in which the results
will be found along the iteration. The resulting strings
*do* belong to
libgg and
*must not* be freed or altered, and they may be invalidated
if not used during the iteration process. They must be copied if needed later.
_state is an internal opaque pointer that keeps track of the iterator
state. Its value must never be touched by the caller.
ggConfigIterTarget allows to iterate over canonical target names and
options strings found in a target spec string. This function also work as a
generator.
iter is a pointer to a gg_target_iter structure owned by the
caller. This user part of the structure must be set by the caller before
calling
ggConfigIterTarget. The
config field must be filled with
the config handle which contains target information; the
input field
must be filled with the initial input spec string.
target and
options are placeholders in which the results will be found along the
iteration. Here again, the resulting strings
*do* belong to libgg and
*must not* be freed or altered, and they may be invalidated if
not used during the iteration process. They must be copied if needed later.
nested is an internal opaque pointer that keeps track of the iterator
state. Its value must never be touched by the caller.
RETURN VALUE¶
ggLoadConfig returns
GGI_OK on success, or:
- •
- GGI_ENOMEM if it can not allocate a new
configuration handle. Note that if subsequent memory allocations fail
(when feeding the handle), those will not be reported as an error. The
handle will be incomplete with regard to the config file contents;
- •
- GGI_ENOTFOUND if the file does not exists. Note that
missing files in include directives will not be reported an error. Also,
other parse error in the file will simply cause the incriminated lines to
be ignored.
ggConfigIterLocation returns
GGI_OK on success or
GGI_ENOMEM.
ggConfigIterTarget always return
GGI_OK and will never fail.
The configuration file is line oriented. Each line may define a mapping between
a canonical name and a location. The generic format is:
<pattern> <location>[:<symbol>]
alias <name> <expansion>
On the first line pattern is a canonical name that may contain one * as a
wildcard, location is a string that corresponds to a scope location, and
symbol is an optional string that gives the name of the symbol to retreive
from the scope. If not given, NULL will be reported. The second line defines
an alias. When a target called name is found while iterating over target spec
strings, the iterator parse expansion as a sub-input spec, and aggregate all
option strings that where found on upstream aliases.
In addition, the configuration file loader knowns the following directives:
.root <path>
.include <file>
When locations following the .root directive are given as relative path, path
will be prepended. .include will parse the given file recursively, before
continuing with the current one.
EXAMPLE¶
This code demonstrates how to get the first module init function accessible from
a scope for a given name. It also shows how to use the libgg iterator scheme:
int openModule(gg_config cfg, const char * moduleName,
const char * defaultSymbol) {
struct gg_location_iter match;
gg_scope scope;
module_init_func *init;
/* prepare the iterator */
match.name = name;
match.config = cfg;
ggConfigMatchIter(&match);
/* iterate over the matches */
GG_ITER_FOREACH(&match) {
/* try to retreive the collection at suggested location */
if((scope = ggGetScope(match.location)) == NULL)
continue;
/* use default symbol if none suggested */
if (match.symbol == NULL) match.symbol = defaultSymbol;
/* try to retreive the symbol from that scope */
if((init = ggFromScope(scope, match.symbol)) == NULL) {
ggDelScope(scope);
continue;
}
/* try to initialize the module */
if(init() != GGI_OK) {
ggDelScope(scope);
continue;
}
/* the module is up, abort iteration and return */
GG_ITER_DONE(&match);
return GGI_OK;
}
/* module not found */
GG_ITER_DONE(&match);
return GGI_ENOTFOUND;
Note that this code is not completely correct, because the scope cannot be
deleted later if it is not remembered somewhere. This next example shows how
to list all targets and options specified by a string:
static void showAllTargets(void * cfg, const char * input)
{
struct gg_target_iter match;
match.config = cfg;
match.input = input;
ggConfigIterTarget(&match);
GG_ITER_FOREACH(&match) {
printf("Target \"%s\" with options \"%s\".\n",
match.target, match.options);
}
GG_ITER_DONE(&match);
}
SEE ALSO¶
ggGetScope(3)