Skip to content

INI files format

elfmz edited this page Feb 28, 2021 · 14 revisions

Synopsis:

; comment
[Section]
KeyName=string value
# another comment
[Section/Subsection]
IntKeyName=123
HexIntKeyName=0xabc
HexBytesKeyName=1a2b3c4d
SpacedHexBytesKeyName=1a 2b 3c 4d
"Escaped\EKey\tName"="Escaped\EString\tValue"

When content is parsed all spaces at beginnings and end of lines trimmed

Lines that starts by # or ; just ignored, thus can be used as comments

Escaping applied only in case where it is required:

  • For section names: escaping required in case actual section name starts and ends by double quotes (") or contains characters with {'\n' (line feed), '\r' (carriage return), '\x00' (NUL char)}
  • For key names: escaping required in case actual key name starts and ends by quote (") or starts by any of following characters: {';', '#', '[', ' ', '\t'} or ends by any of characters: {' ', '\t'} or contains any of {'=', '\n', '\r', \x00'}
  • For values data: escaping required in case actual value starts and ends by quote (") or starts by any of following characters: {' ', '\t'} or ends by any of characters: {' ', '\t'} or contains any of {'\n', '\r', \x00'}

Escaping implemented by appliing following string transformations:

  • Adding double quote at beginning and ending of string.
  • Following character codes are replaced by following sequenced (in C-notation):
    '\r' -> "\r"
    '\n' -> "\n"
    '\t' -> "\t"
    '\x00' -> "\0"
    '\' -> "\\"
    '=' -> "\E"
  • When parsing file un-escaping performed only if raw string representation starts and ends by double quotes. Other strings taken as is. In case of meeting unrecognized escape sequence in quote-enclosed raw string parser treats such sequence also as is, but complains about it into stderr.

Data representation and (incomplete) set-data parser API:

  • SetString(section, name, value) - assigns string value to specified key name inside of specified section. This string will appear in file as is, unless its storing will require escaped-encoding as described above.
  • SetInt(section, name, value) - assigns signed integer value to specified key name inside of specified section. This value will be formated in file as signed decimal integer like 123 (and thus will never need escaping)
  • SetUInt(section, name, value) - assigns unsigned integer value to specified key name inside of specified section. This value will be formated in file as hexadecimal integer prefixed by 0x, like 0x123abc (and thus will never need escaping)
  • SetULL(section, name, value) - assigns unsigned long long integer value to specified key name inside of specified section. This value will be formated in file as hexadecimal integer prefixed by 0x, like 0x123abc (and thus will never need escaping)
  • SetBytes(section, name, buf, len, space_interval) - assigns hexadecimal dump of specified buffer to specified key name inside of specified section. If space_interval is not zero then each group of specified count of bytes will be separated by space. So if space_interval = 0 then result in file will look as 1a2b3c4d5e6f, if space_interval = 1 then it will look as 1a 2b 3c 4d 5e 6f, if space_interval = 2 then it will look as 1a2b 3c4d 5e6f.
  • RemoveKey(section, name) removes key with specified name from specified section
  • RemoveSection(section) removes section with specified name
  • RemoveSectionsAt(section) removes all sections which names prefixed by given section name and slash, so all with names that match to pattern "section/*"
  • RenameSection(src_section, dst_section, recursed) renames section with name src_section to section with name dst_section. If recursed set to true - then also renames all sections that matches "src_section/*" to "dst_section/*"

Get-data parser API:

  • GetString(section, name, def) - returns string value of specified key name inside of specified section. If no such section or key found returns def argument.
  • GetInt(section, name, def) - returns integer value of specified key name inside of specified section. If no such section or key found returns def argument. Automatically detects decimal or hexadecimal encoding by 0x prefix.
  • GetUInt(section, name, def) - returns unsigned integer value of specified key name inside of specified section. If no such section or key found returns def argument. Automatically detects decimal or hexadecimal encoding by 0x prefix.
  • GetULL(section, name, def) - returns unsigned long long integer value of specified key name inside of specified section. If no such section or key found returns def argument. Automatically detects decimal or hexadecimal encoding by 0x prefix.
  • GetBytes(out, len, section, name, def) - decodes hexdump values of specified key name inside of specified section. Returns count of decoded bytes. If no such section or key found - copies amount of data from def argument. When decodes spaced hexdump - spaces do not affect result.
  • EnumSections - enumerates all sections loaded from file
  • EnumSectionsAt(parent_section, recursed) - enumerates only sections that have names matched to parent_section/*. If recursed is false - then only one-level depth subsections are returned (so parent_section/*/* will not be reported)
Clone this wiki locally