parse_conf library 1.0pre

Table of Contents


Next: , Up: (dir)

parse_conf library

This manual is for parse_conf library (version 1.0pre, 16 September 2008), the library to parse standard configuration files with string references resolution.


Next: , Previous: Top, Up: Top

1 Introduction

parse_conf is a library for parsing standard configuration or initialization files and supports some extensions over the standard syntax. It supports the separation of config files into different groups and reading strings and numbers. The library is written in ANSI~C and designed to be fine with C++. Originally (in 2002, 2004) it was designed for reading initial values for scientific applications of special type. It was rewritten and extended to be a flexible general purpose library. Since version 1.0, a very extensive reference substitution system is included into the library. The library is designed to be thread-safety and you can read/write as many configuration files simultaneously as you would like.

The configuration file consists of sections, led by a [section] header and followed by name: value entries, name=value is also accepted. You also can concatenate a string to the previous value using name += value or name +: value commands. Note that leading and ending whitespaces are removed from string values and ignored from numeric values. To add a whitespace to a string, the string should be quoted by quote " sign or you may use \s and \t values for spaces and tabulations. The rest of lines from # or ; are ignored and may be used to provide comments.

Any variable definition can contain references to other values. See documentation for the details. For example, to substitute the value from variable a of the same group or from the global variables, one may use $a reference or Pythonish %(a)s.


Next: , Previous: Introduction, Up: Top

2 Installation

To install the library and pcnfdump utility to a standard location, use

     ./configure
     make
     su -c "make install"

In the case you installing it locally, use

     ./configure --prefix=/desired/location
     make
     make install

instead. Do not forget to change LIBRARY_PATH and C_INCLUDE_PATH accordingly to be able to reach the library. You can also generate tests if you wish by using --enable-tests option for configure.


Next: , Previous: Installation, Up: Top

3 Configuration File Format


Next: , Up: Configuration File Format

3.1 Format Description

parse_conf library reads a very common format for configuration or initialization files that is widely used. However, many important extensions are also supported. One of such an extension is a reference substitutions feature. The configuration file consists of sections or groups with variable string definitions (fields) that belong to these sections. You can make references to other fields and the library will substitute the values. You can reference to the variables defined anywhere else in the configuration file.


Next: , Up: Format Description

3.1.1 Sections

Sections start with a section declaration like [section name] on a separate line. Such a line must contain only this declaration and possibly comments after it. All spaces around the declaration are ignored. All spaces around the name of the section are also ignored. Thus, [ section name ] is a valid declaration equivalent to that does not have spaces around the name. Section names can contain spaces between words and they are meaningful. Section names are also case sensitive. Every section declaration ends the previous section. More formally, the section name must start with an alpha-numeric symbol and must end with an alpha-numeric symbol. Other symbols can contain everything except a new line, (, ), [, ], :, and =.

The global section is the only section that does not have a section declaration. Every variable defined before the first section declaration belongs to that global section (known also as a NULL section). Every configuration file contains at least one global section which may have no field in it. Thus, no section declaration are necessary in the configuration file. In such a file without section declarations, all variables belong to the global section.


Next: , Previous: Sections, Up: Format Description

3.1.2 Fields

All other lines can be used to read information from the configuration file. These lines contain either signs : or = as a separator of the variable (field name) and its definition line. It is possible to have more : or = in the line which are considered as a part of the definition line. The field also can use an increment sign (either +: or +=). If used, the increment sign will add the string to its previous value (concatenation) or will be treated as a simple initialization if there were no such field was defined before. Spaces around the definition line are ignored.

There are in the line that are treated differently that usual signs. First of all, the backslash \ is a control sign that changes the meaning of the succeeding character. To type a \ itself one need to use \\. \s represents a space and \t represents tabulation. These signs are useful if definition line must contain spaces at the beginning or the end due to spaces around the definition line are ignored. Any appearance of \" are replaced by " in the definition lines. This may be useful if your definition line starts with ". You cannot use just this double quote "q at the beginning of the line due to it will switch the input mode to quoted definition lines. See Quoted Format. \ at the end of the line (with possible spaces or comments followed) indicates that the definition will continue at the next line. It is used to split long lines. \# stays for #, and \; stays for ;.


Previous: Fields, Up: Format Description

3.1.3 Comments

Comments are any lines started with # or ;, or the rest of any line from this sign unless (1) these signs appear inside the quoted strings See Quoted Format, or (2) these signs appear in a regular string and preceded by backslash \. See special sequences. Comments can appear in any part of your configuration file. Any lines besides the comments, section names, and fields are considered to be a syntax error. These lines will cause your program to exit with an error message.

Field name or variable name is the part of a string before first =, :, +=, or +: without leading and trailing spaces. That is all leading and finishing spaces are deleted from the line. The name convention for field names is the same as for section names. See Sections.


Next: , Previous: Format Description, Up: Configuration File Format

3.2 References

Definition lines of the fields can contains references to other fields. In this case the library will substitute the value of referenced field instead of the reference.


Next: , Up: References

3.2.1 Local References

To make a reference to a field x defined in the same section one needs to use one of the following format: $x, $(x), or %(x)s. All these references will first search for x definition in the same section. If not found, the search will be made in the global section. The last format is provided to make the library capable to read configuration files provided for ConfigParser Python module. The important difference from most of other libraries is that the references can reference to the fields defined later in the file.

You cannot use simple reference like $x if the name of the field in the reference contains spaces or any characters besides alpha-numeric, -, or _. For example to make a reference to the field Three Words Field one can use $(Three Words Field) or %(Three Words Field)s references only.


Next: , Previous: Local References, Up: References

3.2.2 Global References

You can make a reference from one section to another. The form of such a reference to a variable x in a section y can be $x@y, $(x)@y, $x@[y], or in most general case $(x)@[y]. The last form is suitable when both a field name and a group name contain spaces in them. To make a reference to the global section, one may use $x@ or $(x)@ form. In this case x will not be searched in the local section first.


Next: , Previous: Global References, Up: References

3.2.3 Characters $, %, and @

One need to use a special sequences to be able to use $, %, and @ in their configuration files. They are \\$, \\%, and \\@ correspondingly. Please notice two backslashes, not one. It is because of the References Substitution Rule. The first parsing replaces two backslashes by one.


Previous: Characters Used in References, Up: References

3.2.4 References Substitution Rule

One may ask what would happen if the field has been changed a few times in the file. To understand what happens in this case, one should understand how substitutions work. The parsing of the configuration file contains two independent stages. First, the configuration file is read without any substitutions and all references are treated as a plain text. This may be the last stage if you wish and use special flags for your library. See Interface. However, there may be the second stage of substitutions.

After the file initially parsed, every definition line is parsed for references. However, it may be not the same definition line as it was in the file. Thus, if you have a few definitions or increments of the same field, then the combined results will be parsed for references. Suppose you have in you ini-file:

  field1 =  Hello $x,
  field1 += \sBye $x.

Then the definition line to be parsed will be “Hello $x, Bye $x”.

At the second stage the resolution does not care when the variable was defined. It parses and makes substitutions for the resulted definitions. The referenced fields can contain other references as well. The only evident exception is that no recursive references are allowed. If they occur, the library will notify about the error and will not resolve that references.


Next: , Previous: References, Up: Configuration File Format

3.3 Quoted Format

Quotes can be used in the field definition lines as below:

  a = "This is a quoted definition line"
If such a form is used, other special characters are defined. #, ; can be used without \. In addition \" for a quote is necessary. It is defined in a standard format as well but need to be used there only if the string starts from a quote.


Next: , Previous: Quoted Format, Up: Configuration File Format

3.4 Continuing Long Lines

Continuing long lines is easy, just put a backslash \ at the end of the definition line. You can put comments and spaces after this backslash but nothing else. The following long definition is all considered on one line:

    SRC_FILES = application.cc \    # files to compile
filelister.cc menu\ #               # a word split!
item.cc \
usepix.cc
Thus the field SRC_FILES will be defined as “application.cc filelister.cc menuitem.cc usepix.cc”.


Previous: Continuing Long Lines, Up: Configuration File Format

3.5 Configuration Examples

There is an example of simple initialization file:


  default group string: "just a string"

  [ INITIAL CONDITIONS ]

    # velocity
    v = 100.5  # km/s
    n = 5.1    # 1/m^3

  [ DATE ]   # the date of the event

    # What month is to be output (just a number, f.e. 4 is April)
    Month = 3 #this value will be read

  [ FILENAMES ]
  
    # Kp and Ap index: 
    Kp, Ap data file: "2001KpAp.txt"

    # Solar Activity
    Solar wind data file: "ace_merge_25944.lst"

There are four sections in this file: global (or NULL) section, INITIAL CONDITIONS, DATE, and FILENAMES.

Another example with references:


  usr dir: /home/bubukin/usr

  [programs]
    bin = $(usr dir)/bin
    include = $(usr dir)/include

The value of bin field will be /home/bubukin/usr/bin etc.


Next: , Previous: Configuration File Format, Up: Top

4 Interface


Next: , Up: Interface

4.1 Include Instruction

When you work with parse_conf library you should include a description file first.

#include <parse_conf.h> /* C/C++ code */


Next: , Previous: Include Instruction, Up: Interface

4.2 Handler Allocation

The library is designed to be thread-safety and you can read/write as many configuration files simultaneously as you would like. The special handler type pcnf_t is defined in parse_conf.h. You should declare a pointer to this type in your code to work with.

pcnf_t* pcnf;

Before working with the library you need to get a pcnf instance using pcnf_alloc function:

        pcnf_t *pcnf = pcnf_alloc();

As usual, the function would return NULL if memory allocation would fail by any reason. When the work with the handler is finished, it need to be freed with pcnf_free:

        pcnf_free( pcnf );
— Function: pcnf_t* pcnf_alloc ()

Allocates a pointer to the instance of pcnf_t type. Returns NULL pointer on error.

— Function: void pcnf_free ( pcnf_t* pcnf )

Frees the memory allocated by instance of pcnf_t type.


Next: , Previous: Handler Allocation, Up: Interface

4.3 Flags

Flags change the behavior of the library. There are following flags are defined:

— Flag: PCNF_F_DUMP_QUOTED

If set (unset by default), pcnf_dump prints the configuration in quoted format. See Quoted Format.

— Flag: PCNF_F_DUMP_EQUAL

If set (default), pcnf_dump uses = for fields definitions instead of :.

— Flag: PCNF_F_RESOLVE_REFS

If set (default), functions pcnf_read and pcnf_append will resolve references in the field definition lines. You can use pcnf_resolve function later for references resolution, if this flag is not set.

To set or drop flags the following functions are used:

— Function: void pcnf_flags_set ( pcnf_t* pcnf, int flags )

Sets the flags for pcnf to value flags. For example, to set quoted dump with = as a field separator, use

            pcnf_flags_set( pcnf, PCNF_F_DUMP_QUOTED | PCNF_F_DUMP_EQUAL );
       
— Function: void pcnf_flags_drop ( pcnf_t* pcnf, int flags )

Drops the flags flags for pcnf. For example, to set unquoted dump, use

            pcnf_flags_drop( pcnf, PCNF_F_DUMP_QUOTED );
       


Next: , Previous: Flags, Up: Interface

4.4 Configuration Reading

To read/parse your configuration file you need to use pcnf_read or pcnf_append functions. They are not different when called first. However, the later one would append an additional information from the second file read to your pcnf structure while pcnf_read would clean the content before reading the next file. Any of the function will fail if your configuration file contains a syntax error. There is no reading from streams supported at the moment due to the way error messages are reported.

— Function: int pcnf_read ( pcnf_t* pcnf, char* filename)

Reads and parses the file filename. All previous values from the pcnf are removed. Function returns PCNF_OK on success.

— Function: int pcnf_append ( pcnf_t* pcnf, char* filename)

Reads and parses the file filename. All previous values from the pcnf are saved unless they are replaced by same names from filename. As usual, += or := in the fields definitions from filename will increment values in pcnf, not replace them. Function returns PCNF_OK on success.


Next: , Previous: Configuration Reading, Up: Interface

4.5 Getting Field Values

After you get your file into the pcnf structure, you can get field values. All values are stored as stings in the pcnf structure. Integers and floats are produced using atoi and atof functions.

— Function: char* pcnf_sget ( pcnf_t* pcnf, char* gname, char* fname )

Returns the pointer to the field value from section gname with filed name fname. You are not supposed to change it. Consider this as a constant string. To change the meaning of the field, use pcnf_set or pcnf_inc functions.

— Function: int pcnf_iget ( pcnf_t* pcnf, char* gname, char* fname )

Returns the integer value from section gname with filed name fname.

— Function: double pcnf_fget ( pcnf_t* pcnf, char* gname, char* fname )

Returns the double value of the field from section gname with filed name fname.


Next: , Previous: Getting Field Values, Up: Interface

4.6 Setting Field Values

You can set different values if desired. It can be useful for generation configuration files. It also can be useful to replace some values in other configuration files or to resolve some undefined variables if you use your configuration files as templates.

— Function: int pcnf_set ( pcnf_t* pcnf, char* gname, char* fname, char* value )

Sets the string value of field fname in section gname to value. Function actually duplicates the string value.

— Function: int pcnf_inc ( pcnf_t* pcnf, char* gname, char* fname, char* value )

Appends the string value to the value of the field fname in section gname.


Next: , Previous: Setting Field Values, Up: Interface

4.7 Printing Configuration

— Function: void pcnf_dump ( pcnf_t* pcnf, FILE* fp )

Dumps the configuration into the stream fp. To print the configuration in a standard parse_conf format to the screen, use pcnf_dump( pcnf, stdout );

which can be useful even for test what variables were read.


Next: , Previous: Printing Configuration, Up: Interface

4.8 Cleaning Configuration

— Function: void pcnf_clean ( pcnf_t* pcnf )

Removes all content from PCNF. It does not free the memory though.


Previous: Cleaning Configuration, Up: Interface

4.9 Resolving References

— Function: int pcnf_resolve ( pcnf_t* pcnf )

Resolves all references. This function is useful when flag PCNF_F_RESOLVE_REFS is not set. You can combine a few configuration files together and resolve cross references in them. Another application would be to provide a reference to the file with undefined references in it. For example, you can decide to use this if reference values can be known only during an execution time of your program.


Next: , Previous: Interface, Up: Top

5 Compiling and Linking

After you properly installed the library, you can include the header in your program by

     #include <parse_conf.h>

and compile it. To link your code against the library, you need -lparse_conf flag for your linker. For example,

       gcc <you_program_files> -lparse_conf -o program_name


Next: , Previous: Compiling and Linking, Up: Top

6 pcnfdump Utility

pcnfdump is a utility to read the configuration file and dump its content resolving references if necessary. It reads a configuration file specified with -c option and outputs what it have read in some of the standard format that parse_conf library can read. It is useful to check the substitutions of references made. It also can be used to generate simpler configuration files without references from more general parse_conf library format.

Usage: pcnfdump -c input_file [-o output_file] [-xQnhV]
        -x      variable definitions with : instead of =
        -Q      variable definitions should be quoted
        -n      do not resolve references in definition lines

        -V      version and other information about the program
        -h      this usage message


Previous: pcnfdump Utility, Up: Top

Appendix A Index