$Id: ini_file.txt,v 1.2 2005/10/13 10:16:07 rswindell Exp $

Synchronet/xpdev ini_file module
--------------------------------
The basic format of the files supported by the xpdev ini_file module is that
of the Windows .ini file, with some additional features.

The basic Windows .ini file format is as follows:

1. The file contains ASCII text only with LF or CR/LF-terminated lines.

2. The file is separated into logical "sections". Each section may have its
   own list of keys with associated values, one per line.

3. A section begins with a line consisting only of "[" <section name> "]".

4. White space before or after the section name is ignored.

5. A section ends when the end of file is reached or a new section begins.
 
6. Keys and associated values within a section are specified, each on their
   line, in the format: <key_name> "=" <value>

7. White space before and after the key/value separator ("=") is ignored.

8. Comments are lines with a semicolon (";") as the first non-whitespace
   character.

9. Blank lines between or within sections are ignored.

Example basic Windows .ini file content:

; for 16-bit app support
[fonts]
[extensions]
[Mail]
MAPI=1
CMCDLLNAME32=mapi32.dll
CMCDLLNAME=mapi.dll
CMC=1
MAPIX=1
MAPIXVER=1.0.0.1
OLEMessaging=1
[SciCalc]
layout=0
[MSUCE]
Advanced=1
CodePage=Unicode
Font=Terminal


Synchronet/xpdev extended-ini_file format
=========================================
The Synchronet/xpdev ini_file module supports a somewhat "extended" .ini file
format with the following additions:

Filenames
---------
INI filenames typically end in a ".ini" suffix, but that is not a requirement.

If the application uses the ini_file module's iniFileName() function to
determine the correct ini filename for the current system, different ini files
may be used for different systems on the same network, reading from the same
directory.

The different ini filename permutations supported (assuming "file.ini" is the
base filename) are:

    path/file.<host>.<domain>.ini
    path/file.<host>.ini
    path/file.<platform>.ini
    path/file.ini

Root section
------------
Key/value pairs in the file *before* the first section definition are
considered part of the "root" section. This section is often used to define
key/value pairs that apply globally to all the following sections. The root
section may have other uses as well.

Section Prefixes
----------------
Section names may be include a section "prefix", a fixed portion of the
section name that may be used be the application to logically group
related sections. Section pre-fixes typically end in a colon, but that is
not a requirement.   

Literal string values
---------------------
String values separated by the key name with a colon (':') instead of an
equals sign ('='), are parsed as "literal" strings, which means the string
will retain any trailing white-space on the line. This may be enhanced in
the future to support C escape sequences, multiple/broken lines, etc.

Section name list
-----------------
If one wishes to specify a list of sections for all values to be applied to
they may specify a list of section names, separated by '|', where a single
section name would normally be specified. Example:
"[telnet|rlogin]"

Boolean values
--------------
Values with an either true or false (1 or 0) state can have their value
specified as a number (0, or non-zero), or the following strings (yes,
English only): "true", "yes", or "on" (interpretted as 1), or "false",
"no", or "off" (interpretted as 0). Any otherwise unrecognized text strings
will be interpretted as 0 (false).

Integer values
--------------
Integer values may be negative or positive whole numbers of up to 
(at least) 32-bits in size.

Integer values may be specified in octal (base 8), decimal (base 10),
hexadecimal (base 16), or base 36 formats based on the following
interpretation of the specified value text:

If the first character is 0 and the second character is not 'x' or 'X', the
string is interpreted as an octal integer; otherwise, it is interpreted as
a decimal number. If the first character is '0' and the second character is
'x' or 'X', the string is interpreted as a hexadecimal integer. If the
first character is '1' through '9', the string is interpreted as a decimal
integer. The letters 'a' through 'z' (or 'A' through 'Z') are assigned the
values 10 through 35.

The exception to this rule are the values of "true", "yes", or "on",
always interpretted as the value of 1 (one).

Long integer values
-------------------
Long integer values may be positive whole numbers of up to (at least)
32-bits in size. Otherwise, long integer values are interpretted the same as
normal integer values.

Log levels
----------
The ini_file module includes built-in support for the standard Unix syslog
levels: Emergency (0), Alert (1), Critical (2), Error (3), Warning (4), 
Notice (5), Informational (6), and Debugging (7).

The higher the log level, the more log output will be generated.

Partial or complete log level names may be specified for the log level
value, or the numeric equivalent.

Byte counts
-----------
Byte count values (e.g. file sizes) may be specified as positive numbers
(fractional numbers are supported), optionally with a 'T', 'G', 'M', or 'K'
suffix to specify terabytes, gigabytes, megabytes, or kilobytes, respectively.

Date/Time stamps
----------------
Date and time values may be specified in any of the following formats:

ISO-8601 date and time format:                  "CCYYMMDDThhmmss" 
Euro/Canadian numeric date format:              "DD.MM.[CC]YY [time] [p]"
American numeric date format:                   "MM/DD/[CC]YY [time] [p]"
Perversion of RFC822 date format:               "DD[-]Mon [CC]YY [time] [p]"
IETF standard (RFC2822) date format:            "Wday, DD Mon [CC]YY [time]"
Preferred date format:                          "Mon DD[,] [CC]YY [time] [p]"
JavaScript Date.toString() format:              "Wday Mon DD [CC]YY [time]"
ctime() format:                                 "Wday Mon DD [time] [CC]YY"
time_t format:                                  seconds since Jan 1, 1970 UTC

where:
            CC      = Century (i.e. "19" or "20")
            YY      = Year number (e.g. "05")
            MM      = Month number (1-12)
            DD      = Day of month (1-31)
            hh      = Hour of day (0-23)
            mm      = Minute of hour (0-59)
            ss      = Second of minute (0-59)
            p       = AM/PM designation
            time    = Time of day specified as "hh[:mm[:ss]]"
            Mon     = Month name (e.g. "Jan", "Feb", etc.)
            Wday    = Weekday name (e.g. "Mon", "Tue", etc.)
            []      = Optional parameter

Bit-fields
----------
Bit-field values may be specified as a positive number (same rules of
interpretation as integer values), a bit-name, or a list of numbers or
bit-names separated by the '|' character.

Bit-fields are often used to specify multiple boolean-type values in
a single key/value pair.

Include directive
-----------------
An ini file may be include/imported/inserted into a another with the 
"!include" directive. The line must begin with "!include", followed by 
white space, and then a filename to include (optionally with a path). 
Sections may span files.

file1.ini:
[section_one]
    key1 = value1
!include file2.ini

file2.ini:
    key2 = value2

In the above example, both key1 and key2 are part of section_one.

End-of-file directive
---------------------
An ini file may be prematurely terminated with the "!eof" directive. This
stops the ini_file module functions from processing any lines following this
directive.


