Start on include/inn/confparse.h

Russ Allbery rra at
Thu Jun 29 02:31:32 UTC 2000

(Better names are welcome.)  This was the first pass I put together last
night for the interface described in previous mail.  I figured I may as
well send it out to see if anyone has any critiques or can think of data
structures that I'm missing that should be there.

One thing I noticed when designing the interface is that the return of
conf_parse is going to be minorly annoying to deal with for configuration
files with nested groups.  For example, with incoming.conf, all you really
care about is the array of structs corresponding to peer groups; those may
be grouped into other groups, though, and what you'll actually get out of
conf_parse is a tree of conf_data structs, with pointers to the structs
that you care about in the data members.  Basically, the interesting part
will be all the leaves.  The best way of handling this may be to write a
conf_collapse function that takes a conf_data tree and returns a list of
just the leaves, freeing everything at a higher level.

Another interesting problem is that conf_parse doesn't actually know the
data type of the structs that it will be creating, just their size and the
offsets into which to write data.  As such, it will be a bit tricky for
anything at the conf parser level to free those generated structs,
although you could just loop through the parameter group definition and
free anything that has a type of PARAM_STRING and isn't NULL, and then
free the allocated memory....

Anyway, I don't know how coherent this is.  If I'm not giving enough
information to understand my thought process or where I'm heading with
this, questions (the more specific the better, so as to be sure that
you're getting the right information) are *very* welcome.

/*  $Id$
**  Configuration file parsing.



/* The type of a parameter (which determines how it will be parsed when
   encountered in the configuration file and what type of data it will be
   converted into). */
typedef enum conf_parameter {
} conf_parameter_t;

/* This struct defines a configuration file parameter.  offset is the byte
   offset into the struct the configuration results will be placed into. */
struct conf_parameter {
    char *              name;
    size_t              offset;
    conf_parameter_t    type;

/* The type of a callback called at the beginning or end of the parsing of a
   parameter group.  Passed the conf_data struct being filled in and the
   corresponding conf_group struct dictating its structure. */
struct conf_group;
struct conf_data;
typedef bool (*conf_callback_t)(struct conf_data *, struct conf_group *);

/* Parameters are collected into parameter groups, which are defined by the
   following struct.  init and finish are callbacks used to do various
   initialization, cleanup, or programmatic defaults for the result struct
   of a parse of a configuration file. */
struct conf_group {
    char *              name;
    size_t              struct_size;
    void *              defaults;
    conf_callback_t     init;
    conf_callback_t     finish;

    struct conf_group *         parent;
    struct conf_group **        subgroups;
    struct conf_parameter **    parameters;

/* The results of a configuration file parse are a tree of these structs;
   data is a pointer to the struct corresponding with the parameter group at
   that level, and set is an array saying whether the nth member of that
   struct was explicitly set in the configuration file or only set by
   defaults. */
struct conf_data {
    char * name;
    char * tag;
    bool * set;

    void * data;

    struct conf_data *  parent;
    struct conf_data ** subgroups;

/* The public parse function.  Takes the name of a file to parse and a
   pointer to a conf_group tree that specifies the semantic structure of the
   file.  Returns a pointer to a conf_data tree containing the results of
   the parse. */
extern struct conf_data *conf_parse(const char *file,
                                    const struct conf_group *structure);

/* Frees a conf_data tree, including all subgroups.  The data is *not*
   freed; the caller must take those pointers and interpret them as the
   appropriate struct, freeing them if they need to be freed. */
extern void conf_free(struct conf_data *data);


#endif /* !INN_CONFPARSE_H */

Russ Allbery (rra at             <>

More information about the inn-workers mailing list