libt3config
Syntax of configuration files.

Introduction

Configuration files as used by libt3config are structured files. They consist of a set of key/value expressions, where each key is assigned a type based on the assigned value. Each key may only occur once.

Data types

There are six data types available: integers, floating point numbers, strings, booleans, lists and sections. The data type of each item is determined from the input as follows:

Integers

Integers consist of a either an optional sign, followed by a series of digits from 0 through 9, or of 0x followed by a series of hexadecimal digits (i.e. 0 through 9 and a through f in either lower or upper case).

Floating point numbers

Floating point numbers consist of an optional sign, zero or more decimal digits, a point, zero or more optional digits and an optional exponent. The exponent consists of the letter e (or E), an optional exponent and one or more decimal digits. The special words nan, inf and infinity are also accepted as floating point numbers.

Strings

Strings are text enclosed in either " or '. Strings may not include newline characters. To include the delimiting character in the string, repeat the character twice (i.e. 'foo''bar' encodes the string foo'bar). Multiple strings may be concatenated by using a plus sign (+). To split a string accross multiple lines, use string concatenation using the plus sign, where a plus sign must appear before the newline after each substring.

Booleans

Booleans are one of the special words yes, no, true or false.

Lists

Lists are items enclosed by parentheses and separated by commas. A list may contain items of any datatype, including lists. Alternately, a list can be specified by repeatedly using the list name preceeded by a %-sign and assigning a single value to each of them. The list is inserted in the parsed configuration at the first occurence of the name.

Sections

Sections are delimited by curly braces ({}), and contain key/value expressions. Key/value expressions are separated by newlines or semi-colons. For all but the section type, the key/value expressions are of the form key = value. For sections, the key/value expression is of the form key { <key/value expressions> }. Key names may consist of the letters a through z, in both upper- and lowercase, the digits 0 through 9, hyphen and underscore. The first character of a key name may not be a digit or a hyphen. Each key may only occur once.

Example

# integer:
i = 9
# floating point number:
f = 1.0
# strings:
s1 = "A simple string"
s2 = 'Another string, with embedded double quotes: "'
s3 = "Embedded double qoutes "" in a double quoted string"
s4 = "Multi-part string" +
    ' split over multiple lines'
# boolean:
b = true
# lists:
l1 = ( 1, yes, "text", ( 7, 8, 9 ), { key = "value" } )
# The following is equivalent to: l2 = ( 1, yes, "text" )
%l2 = 1
%l2 = yes
%l2 = "text"
# sections:
sect {
  foo = yes
  bar = 9
  sect {
    l1 = ( true, false, yes, no )
  }
}

File Inclusion

Libt3config provides a mechanism to include other files from a configuration file. An included file must be a valid configuration file in itself. By default the include mechanism not used. To enable it, set either the T3_CONFIG_INCLUDE_DFLT or the T3_CONFIG_INCLUDE_USER flag in the t3_config_opts_t struct passed to t3_config_read_file or t3_config_read_buffer (or the equivalent schema loading functions). Depending on the flag passed, different members of the t3_config_opts_t struct must be filled in.

Once the include mechanism has been enabled, files can be included using the percent-style list specification syntax:

%include = "file1.inc"
%include = "file2.inc"

The include mechanism prevents recursive inclusion, by keeping track of the included file names. If the same name is included again from a deeper nested file, it will trigger an error and abort the parsing process. This does not preclude multiple inclusion of the same file at different points in the inclusion hierarchy. For example, the following is perfectly valid (as long as file1.inc does not recursively include itself):

%include = "file1.inc"

nested {
  %include = "file1.inc"
}