The parsecfg module implements a high performance configuration file parser. The configuration file's syntax is similar to the Windows .ini format, but much more powerful, as it is not a line based parser. String literals, raw string literals and triple quoted string literals are supported as in the Nim programming language.This is an example of how a configuration file may look like:
# This is a comment. ; this too. [Common] cc=gcc # '=' and ':' are the same --foo="bar" # '--cc' and 'cc' are the same, 'bar' and '"bar"' are the same --verbose [Windows] isConsoleApplication=False ; another comment [Posix] isConsoleApplication=True key1: "in this string backslash escapes are interpreted\n" key2: r"in this string not" key3: """triple quotes strings are also supported. They may span multiple lines.""" --"long option with spaces": r"c:\myfiles\test.txt"Here is an example of how to use the configuration file parser:
import
os, parsecfg, strutils, streams
var f = newFileStream(paramStr(1), fmRead)
if f != nil:
var p: CfgParser
open(p, f, paramStr(1))
while true:
var e = next(p)
case e.kind
of cfgEof: break
of cfgSectionStart: ## a ``[section]`` has been parsed
echo("new section: " & e.section)
of cfgKeyValuePair:
echo("key-value-pair: " & e.key & ": " & e.value)
of cfgOption:
echo("command: " & e.key & ": " & e.value)
of cfgError:
echo(e.msg)
close(p)
else:
echo("cannot open: " & paramStr(1)) This is an example of a configuration file.
charset = "utf-8" [Package] name = "hello" --threads:on [Author] name = "lihf8515" qq = "10214028" email = "[email protected]"
import parsecfg
var dict=newConfig()
dict.setSectionKey("","charset","utf-8")
dict.setSectionKey("Package","name","hello")
dict.setSectionKey("Package","--threads","on")
dict.setSectionKey("Author","name","lihf8515")
dict.setSectionKey("Author","qq","10214028")
dict.setSectionKey("Author","email","[email protected]")
dict.writeConfig("config.ini") import parsecfg
var dict = loadConfig("config.ini")
var charset = dict.getSectionValue("","charset")
var threads = dict.getSectionValue("Package","--threads")
var pname = dict.getSectionValue("Package","name")
var name = dict.getSectionValue("Author","name")
var qq = dict.getSectionValue("Author","qq")
var email = dict.getSectionValue("Author","email")
echo pname & "\n" & name & "\n" & qq & "\n" & email import parsecfg
var dict = loadConfig("config.ini")
dict.setSectionKey("Author","name","lhf")
dict.writeConfig("config.ini") import parsecfg
var dict = loadConfig("config.ini")
dict.delSectionKey("Author","email")
dict.writeConfig("config.ini") CfgEventKind = enum cfgEof, ## end of file reached cfgSectionStart, ## a ``[section]`` has been parsed cfgKeyValuePair, ## a ``key=value`` pair has been detected cfgOption, ## a ``--key=value`` command line option cfgError ## an error occurred during parsing
CfgEvent = object of RootObj
case kind*: CfgEventKind ## the kind of the event
of cfgEof:
nil
of cfgSectionStart:
section*: string ## `section` contains the name of the
## parsed section start (syntax: ``[section]``)
of cfgKeyValuePair, cfgOption:
key*, value*: string ## contains the (key, value) pair if an option
## of the form ``--key: value`` or an ordinary
## ``key= value`` pair has been parsed.
## ``value==""`` if it was not specified in the
## configuration file.
of cfgError: ## the parser encountered an error: `msg`
msg*: string ## contains the error message. No exceptions
## are thrown if a parse error occurs.CfgParser = object of BaseLexer tok: Token filename: string
Config = OrderedTableRef[string, OrderedTableRef[string, string]]
proc open(c: var CfgParser; input: Stream; filename: string; lineOffset = 0) {...}{.gcsafe,
extern: "npc$1", raises: [Exception], tags: [ReadIOEffect, RootEffect].}proc close(c: var CfgParser) {...}{.gcsafe, extern: "npc$1", raises: [Exception], tags: [].}proc getColumn(c: CfgParser): int {...}{.gcsafe, extern: "npc$1", raises: [], tags: [].}proc getLine(c: CfgParser): int {...}{.gcsafe, extern: "npc$1", raises: [], tags: [].}proc getFilename(c: CfgParser): string {...}{.gcsafe, extern: "npc$1", raises: [], tags: [].}proc errorStr(c: CfgParser; msg: string): string {...}{.gcsafe, extern: "npc$1",
raises: [ValueError], tags: [].}proc warningStr(c: CfgParser; msg: string): string {...}{.gcsafe, extern: "npc$1",
raises: [ValueError], tags: [].}proc ignoreMsg(c: CfgParser; e: CfgEvent): string {...}{.gcsafe, extern: "npc$1",
raises: [ValueError], tags: [].}proc next(c: var CfgParser): CfgEvent {...}{.gcsafe, extern: "npc$1",
raises: [Exception, ValueError],
tags: [ReadIOEffect].}proc newConfig(): Config {...}{.raises: [], tags: [].}proc loadConfig(stream: Stream; filename: string = "[stream]"): Config {...}{.
raises: [Exception, ValueError, KeyError], tags: [ReadIOEffect, RootEffect].}proc loadConfig(filename: string): Config {...}{.raises: [Exception, IOError, Exception,
ValueError, KeyError], tags: [ReadIOEffect, RootEffect].}proc writeConfig(dict: Config; stream: Stream) {...}{.raises: [Exception],
tags: [WriteIOEffect].}Writes the contents of the table to the specified stream
Note: Comment statement will be ignored.
proc `$`(dict: Config): string {...}{.raises: [Exception], tags: [WriteIOEffect].}proc writeConfig(dict: Config; filename: string) {...}{.
raises: [Exception, IOError, Exception], tags: [WriteIOEffect].}proc getSectionValue(dict: Config; section, key: string): string {...}{.raises: [KeyError],
tags: [].}proc setSectionKey(dict: var Config; section, key, value: string) {...}{.raises: [KeyError],
tags: [].}proc delSection(dict: var Config; section: string) {...}{.raises: [], tags: [].}proc delSectionKey(dict: var Config; section, key: string) {...}{.raises: [KeyError], tags: [].}
© 2006–2018 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/parsecfg.html