Config File Loader

By Malcolm McLean Homepage

This file contains functions to load configuration files.

Any enhancements or bug fixes send to regniztar@btinternet.com

Source files

readconfig.c
readconfig.h

A configuration file contains parameters for programs. They are designed to be fairly simple for humans to edit, and to reduce the number of arguments on the command line. It consists essentially of a name in the left-hand column followed by a value or list of values.

Example config file

# comments are allowed, started by # x 0.45 string astring # blank line allowed path "/usr/local/My Files" # quote strings containing spaces point = 0.5, 1.2, 1.1 # vector arguments alowed

Equals signs or colons are allowed in assignments, but not required.
Fields may be separated by either spaces or commas.

The loader is designed to take away all the parsing and error-handling logic from the caller, allowing the file to be read by a simple series of commands.


CONFIG *loadconfig(char *fname);

Load a CONFIG file

The function will return NULL if the file fails to load. Note all functions are NULL-safe.


CONFIG *floadconfig(FILE *fp);

Load a CONFIG file from an already opened file.

As previous function, useful if using pipes.


void killconfig(CONFIG *config);

Destroy the object and free memory used.
int config_hasid(CONFIG *config, char *id)

Tests if a field is present in the config file.
Does not flag any error.

double config_getd(CONFIG *config, char *id);

Read a single double value from the config file.
float config_getf(CONFIG *config, char *id);

Read a single float value from the configuration file.
int config_geti(CONFIG *config, char *id);

Read a single integer form the file. An error is flagged if the number is not an integer.
int config_getdvals(CONFIG *config, char *id, double *ret, int N);

Get a list of doubles from the configuration file. Error flagged if exactly N values are not present. Use config_getNvals() if the number of values is not known at complile time.
Returns 0 on success, -1 on fail.
int config_getfvals(CONFIG *config, char *id, float *ret, int N);

Get a list of floating point values form the configuration file.
int config_getivals(CONFIG *config, char *id, int *ret, int N);

Get a list of integers form the configuration. Flags an error if any values non-integral.
int config_getNvals(CONFIG *config, char *id);

Gets the number of values associated with a field. Flags an error if the field is not present. If you wish to allow valueless fields to represent flags, this function will read them and return 0 to indicate that the field has no values associated with it. Use config_hasid() to test for presence without reading the field.
char *config_getstring(CONFIG *config, char *id, int index);

Gets a string from the config file. A zero-based index is passed in to support fields with more than one string. Call with this parameter zero to read a single string. Return is alloacted with malloc().
int config_readstring(CONFIG *config, char *id, int index, char *ret, int size);

Read a string from the config file into a fixed buffer. index is zeri-based index of string, as before. size gives the buffer size, including terminating NUL. An error will be flagged if the string is too long.
int config_error(CONFIG *config, FILE *out, int reportunread);

Report the error status of the config file. out is the stream which receives the error report, and can be NULL. reportunread is a flag which turns on or suppresses errors for unread fields. The funtion return 0 if there were no errors, -1 if an error occured. Typical Usage We have a configuration file consisting of a file path, an integer called x, a three-dimensional point, an list of integers called varlist, two strings, and an optional flag called optional. path = /usr/local/myfile.txt x = 123 point 0.5, 0.4, 0.3 varlist 11, 12, 13, 14, 15, 15 twostrings "Fred", "Jim" optional We simply call the read functions for most fields. The exception is the optional field and the field taking a variable number of values, in which case thigns are slightly more complicated.

#include <stdlib.h> #include <stdio.h> #include "readconfig.h" struct params { char *path; int x; float point[3]; int *varlist; int Nvars; char string1[32]; char string2[32]; int optional; }; int main(int argc, char **argv) { struct params params; CONFIG *cnf; cnf = config(argv[1]); params.path = config_getstring(cnf, "path", 0); params.x = config_geti(cnf, "x"); config_getfvals(cnf, "point", params.point, 3); params.Nvars = config_getNvals(cnf, "varlist"); params.varlist = malloc(params.Nvars * sizeof(int)); if(!params.varlist) return 0; config_getivals(cnf, "varlist", params.varlist, params.Nvars); config_readstring(cnf, "twostrings", 0, params.string1, 32); config_readstring(cnf, "twostrings", 1, params.string2, 32); if(config_hasid(cnf, "optional")) { params.optional = 1; config_getNvals(cnf, "optional"); } else params.optional = 0; if(config_error(cnf, stderr, 1)) exit(EXIT_FAILURE); killconfig(cnf); return 0; }