-
Notifications
You must be signed in to change notification settings - Fork 0
Parser Options
IniParserOptions is a configuration class that controls how IniFileParser
interprets INI file content. All options default to the most common / lenient
behaviour so that existing code continues to work unchanged.
Use the fluent IniConfigBuilder methods to apply options when loading via the
registry, or pass an IniParserOptions instance directly to IniFileParser.Parse
when using the low-level API.
using var config = IniConfigRegistry.ForFile("app.ini")
.AddSearchPath(AppContext.BaseDirectory)
.EnableEscapeSequences() // decode \n, \t, \\, \xHH, …
.EnableQuotedValues() // strip surrounding "…" / '…'
.EnableLineContinuation() // join lines ending with \
.AssignmentDelimiters("=:") // accept '=' and ':'
.CaseSensitiveKeys() // AppName ≠ appname
.WithDuplicateKeyHandling(DuplicateKeyHandling.FirstWins)
.RegisterSection<IAppSettings>(new AppSettingsImpl())
.Build();Or supply a pre-built IniParserOptions object:
var opts = new IniParserOptions
{
AssignmentDelimiters = "=:",
EscapeSequences = true,
QuotedValues = true,
};
using var config = IniConfigRegistry.ForFile("app.ini")
.AddSearchPath(AppContext.BaseDirectory)
.WithParserOptions(opts)
.RegisterSection<IAppSettings>(new AppSettingsImpl())
.Build();Controls which characters are treated as key/value assignment delimiters.
Default is =: (both equals and colon are accepted).
[Database]
Host = server
Port: 5432var opts = new IniParserOptions { AssignmentDelimiters = "=:" };
var file = IniFileParser.Parse(content, opts);Builder shorthand:
.AssignmentDelimiters("=:")Controls what happens when the same key appears more than once inside one section.
| Value | Behaviour |
|---|---|
LastWins (default)
|
Each occurrence overwrites the previous one; the last value wins |
FirstWins |
The first occurrence is kept; later duplicates are silently ignored |
ThrowError |
An InvalidOperationException is thrown on the first duplicate |
[Database]
Host = server1
Host = server2 ; duplicate!// LastWins (default) → Host = "server2"
var file = IniFileParser.Parse(content);
// FirstWins → Host = "server1"
var file = IniFileParser.Parse(content,
new IniParserOptions { DuplicateKeyHandling = DuplicateKeyHandling.FirstWins });
// ThrowError → throws InvalidOperationException
var file = IniFileParser.Parse(content,
new IniParserOptions { DuplicateKeyHandling = DuplicateKeyHandling.ThrowError });Builder shorthand:
.WithDuplicateKeyHandling(DuplicateKeyHandling.FirstWins)When true, values enclosed in matching double-quotes "…" or single-quotes '…'
have their surrounding quote characters stripped. Interior whitespace is preserved.
QuotedValues |
INI line | Parsed value |
|---|---|---|
false (default)
|
key = "hello world" |
"hello world" |
true |
key = "hello world" |
hello world |
true |
key = ' spaces ' |
spaces |
true |
key = plain value |
plain value (unchanged — no quotes)
|
var opts = new IniParserOptions { QuotedValues = true };
var file = IniFileParser.Parse(content, opts);Builder shorthand:
.EnableQuotedValues()When true, a backslash (\) at the very end of a value line causes the parser to
append the trimmed content of the following line, forming a single value.
The chain continues as long as each continuation line also ends with \.
[Message]
Text = Hello, \
World!LineContinuation |
Parsed value |
|---|---|
false (default)
|
Hello, \ |
true |
Hello, World! |
Multi-line example:
[Script]
Command = first \
second \
thirdParsed value with LineContinuation = true: first second third
var opts = new IniParserOptions { LineContinuation = true };
var file = IniFileParser.Parse(content, opts);Builder shorthand:
.EnableLineContinuation()When true, standard C-style escape sequences in values are decoded.
| Sequence | Decoded character |
|---|---|
\\ |
Literal backslash \
|
\n |
Newline (LF, U+000A) |
\r |
Carriage return (CR, U+000D) |
\t |
Horizontal tab (U+0009) |
\0 |
Null character (U+0000) |
\" |
Double quote "
|
\' |
Single quote '
|
\a |
Bell / alert (U+0007) |
\b |
Backspace (U+0008) |
\xHH |
Character with hex code HH (two hex digits) |
Unrecognised sequences (e.g. \q) are left unchanged — the backslash is preserved.
[Paths]
DataDir = C:\\ProgramData\\MyApp
Greeting = Hello\nWorld
Tab = col1\tcol2
Bullet = \x2022 itemWith EscapeSequences = true:
| Key | Value |
|---|---|
DataDir |
C:\ProgramData\MyApp |
Greeting |
Hello + newline + World
|
Tab |
col1 + tab + col2
|
Bullet |
• item |
var opts = new IniParserOptions { EscapeSequences = true };
var file = IniFileParser.Parse(content, opts);Builder shorthand:
.EnableEscapeSequences()By default (false) key names within a section are compared
case-insensitively — AppName, appname, and APPNAME all refer to the
same entry.
When set to true, key comparisons use ordinal case-sensitive equality, so
AppName and appname are treated as different keys.
[S]
AppName = Pascal
appname = lowerCaseSensitiveKeys |
GetValue("AppName") |
GetValue("appname") |
Entry count |
|---|---|---|---|
false (default)
|
lower (LastWins)
|
lower |
1 |
true |
Pascal |
lower |
2 |
var opts = new IniParserOptions { CaseSensitiveKeys = true };
var file = IniFileParser.Parse(content, opts);Builder shorthand:
.CaseSensitiveKeys()By default (false) section names are compared case-insensitively —
[General], [GENERAL], and [general] all refer to the same section.
When set to true, section-name comparisons use ordinal case-sensitive
equality, so [General] and [GENERAL] are independent sections.
[General]
key = v1
[GENERAL]
key = v2CaseSensitiveSections |
GetSection("General") |
GetSection("GENERAL") |
Section count |
|---|---|---|---|
false (default)
|
v2 (LastWins)
|
v2 |
1 |
true |
v1 |
v2 |
2 |
var opts = new IniParserOptions { CaseSensitiveSections = true };
var file = IniFileParser.Parse(content, opts);Builder shorthand:
.CaseSensitiveSections()All options can be combined freely. Use the fluent builder methods to compose the exact set you need:
using var config = IniConfigRegistry.ForFile("app.ini")
.AddSearchPath(AppContext.BaseDirectory)
.EnableEscapeSequences()
.EnableQuotedValues()
.EnableLineContinuation()
.CaseSensitiveKeys()
.CaseSensitiveSections()
.WithDuplicateKeyHandling(DuplicateKeyHandling.ThrowError)
.RegisterSection<IAppSettings>(new AppSettingsImpl())
.Build();Or build the options object once and reuse it across multiple configs:
var strictOpts = new IniParserOptions
{
EscapeSequences = true,
QuotedValues = true,
CaseSensitiveKeys = true,
DuplicateKeyHandling = DuplicateKeyHandling.ThrowError,
};
using var configA = IniConfigRegistry.ForFile("a.ini")
.WithParserOptions(strictOpts)
.RegisterSection<IA>(new AImpl())
.Build();
using var configB = IniConfigRegistry.ForFile("b.ini")
.WithParserOptions(strictOpts)
.RegisterSection<IB>(new BImpl())
.Build();If you use IniFileParser directly (without IniConfig / IniConfigBuilder),
pass IniParserOptions as the second argument:
var opts = new IniParserOptions
{
EscapeSequences = true,
QuotedValues = true,
};
// From a string
var iniFile = IniFileParser.Parse(rawText, opts);
// From disk (sync)
var iniFile = IniFileParser.ParseFile("/path/to/file.ini", Encoding.UTF8, opts);
// From disk (async)
var iniFile = await IniFileParser.ParseFileAsync("/path/to/file.ini",
Encoding.UTF8, opts, cancellationToken);- Ini-File-Format — INI syntax overview, value formats, comments
-
Loading-Configuration —
IniConfigBuilderfluent API reference -
Registry-API — complete
IniConfigBuildermethod table