minor improve the docs of parsecfg (#16208)

This commit is contained in:
flywind 2020-12-02 04:06:37 +08:00 • committed by GitHub
commit 62eb1312a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -7,8 +7,8 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
## The ``parsecfg`` module implements a high performance configuration file ## The `parsecfg` module implements a high performance configuration file
## parser. The configuration file's syntax is similar to the Windows ``.ini`` ## 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 ## 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 ## literals, raw string literals and triple quoted string literals are supported
## as in the Nim programming language. ## as in the Nim programming language.
@ -116,9 +116,9 @@ include "system/inclrtl"
type type
CfgEventKind* = enum ## enumeration of all events that may occur when parsing CfgEventKind* = enum ## enumeration of all events that may occur when parsing
cfgEof, ## end of file reached cfgEof, ## end of file reached
cfgSectionStart, ## a ``[section]`` has been parsed cfgSectionStart, ## a `[section]` has been parsed
cfgKeyValuePair, ## a ``key=value`` pair has been detected cfgKeyValuePair, ## a `key=value` pair has been detected
cfgOption, ## a ``--key=value`` command line option cfgOption, ## a `--key=value` command line option
cfgError ## an error occurred during parsing cfgError ## an error occurred during parsing
CfgEvent* = object of RootObj ## describes a parsing event CfgEvent* = object of RootObj ## describes a parsing event
@ -126,12 +126,12 @@ type
of cfgEof: nil of cfgEof: nil
of cfgSectionStart: of cfgSectionStart:
section*: string ## `section` contains the name of the section*: string ## `section` contains the name of the
## parsed section start (syntax: ``[section]``) ## parsed section start (syntax: `[section]`)
of cfgKeyValuePair, cfgOption: of cfgKeyValuePair, cfgOption:
key*, value*: string ## contains the (key, value) pair if an option key*, value*: string ## contains the (key, value) pair if an option
## of the form ``--key: value`` or an ordinary ## of the form `--key: value` or an ordinary
## ``key= value`` pair has been parsed. ## `key= value` pair has been parsed.
## ``value==""`` if it was not specified in the ## `value==""` if it was not specified in the
## configuration file. ## configuration file.
of cfgError: ## the parser encountered an error: `msg` of cfgError: ## the parser encountered an error: `msg`
msg*: string ## contains the error message. No exceptions msg*: string ## contains the error message. No exceptions
@ -157,7 +157,7 @@ proc rawGetTok(c: var CfgParser, tok: var Token) {.gcsafe.}
proc open*(c: var CfgParser, input: Stream, filename: string, proc open*(c: var CfgParser, input: Stream, filename: string,
lineOffset = 0) {.rtl, extern: "npc$1".} = lineOffset = 0) {.rtl, extern: "npc$1".} =
## initializes the parser with an input stream. `Filename` is only used ## Initializes the parser with an input stream. `Filename` is only used
## for nice error messages. `lineOffset` can be used to influence the line ## for nice error messages. `lineOffset` can be used to influence the line
## number information in the generated error messages. ## number information in the generated error messages.
lexbase.open(c, input) lexbase.open(c, input)
@ -168,19 +168,19 @@ proc open*(c: var CfgParser, input: Stream, filename: string,
rawGetTok(c, c.tok) rawGetTok(c, c.tok)
proc close*(c: var CfgParser) {.rtl, extern: "npc$1".} = proc close*(c: var CfgParser) {.rtl, extern: "npc$1".} =
## closes the parser `c` and its associated input stream. ## Closes the parser `c` and its associated input stream.
lexbase.close(c) lexbase.close(c)
proc getColumn*(c: CfgParser): int {.rtl, extern: "npc$1".} = proc getColumn*(c: CfgParser): int {.rtl, extern: "npc$1".} =
## get the current column the parser has arrived at. ## Gets the current column the parser has arrived at.
result = getColNumber(c, c.bufpos) result = getColNumber(c, c.bufpos)
proc getLine*(c: CfgParser): int {.rtl, extern: "npc$1".} = proc getLine*(c: CfgParser): int {.rtl, extern: "npc$1".} =
## get the current line the parser has arrived at. ## Gets the current line the parser has arrived at.
result = c.lineNumber result = c.lineNumber
proc getFilename*(c: CfgParser): string {.rtl, extern: "npc$1".} = proc getFilename*(c: CfgParser): string {.rtl, extern: "npc$1".} =
## get the filename of the file that the parser processes. ## Gets the filename of the file that the parser processes.
result = c.filename result = c.filename
proc handleHexChar(c: var CfgParser, xi: var int) = proc handleHexChar(c: var CfgParser, xi: var int) =
@ -367,19 +367,19 @@ proc rawGetTok(c: var CfgParser, tok: var Token) =
else: getSymbol(c, tok) else: getSymbol(c, tok)
proc errorStr*(c: CfgParser, msg: string): string {.rtl, extern: "npc$1".} = proc errorStr*(c: CfgParser, msg: string): string {.rtl, extern: "npc$1".} =
## returns a properly formatted error message containing current line and ## Returns a properly formatted error message containing current line and
## column information. ## column information.
result = `%`("$1($2, $3) Error: $4", result = `%`("$1($2, $3) Error: $4",
[c.filename, $getLine(c), $getColumn(c), msg]) [c.filename, $getLine(c), $getColumn(c), msg])
proc warningStr*(c: CfgParser, msg: string): string {.rtl, extern: "npc$1".} = proc warningStr*(c: CfgParser, msg: string): string {.rtl, extern: "npc$1".} =
## returns a properly formatted warning message containing current line and ## Returns a properly formatted warning message containing current line and
## column information. ## column information.
result = `%`("$1($2, $3) Warning: $4", result = `%`("$1($2, $3) Warning: $4",
[c.filename, $getLine(c), $getColumn(c), msg]) [c.filename, $getLine(c), $getColumn(c), msg])
proc ignoreMsg*(c: CfgParser, e: CfgEvent): string {.rtl, extern: "npc$1".} = proc ignoreMsg*(c: CfgParser, e: CfgEvent): string {.rtl, extern: "npc$1".} =
## returns a properly formatted warning message containing that ## Returns a properly formatted warning message containing that
## an entry is ignored. ## an entry is ignored.
case e.kind case e.kind
of cfgSectionStart: result = c.warningStr("section ignored: " & e.section) of cfgSectionStart: result = c.warningStr("section ignored: " & e.section)
@ -410,7 +410,7 @@ proc getKeyValPair(c: var CfgParser, kind: CfgEventKind): CfgEvent =
rawGetTok(c, c.tok) rawGetTok(c, c.tok)
proc next*(c: var CfgParser): CfgEvent {.rtl, extern: "npc$1".} = proc next*(c: var CfgParser): CfgEvent {.rtl, extern: "npc$1".} =
## retrieves the first/next event. This controls the parser. ## Retrieves the first/next event. This controls the parser.
case c.tok.kind case c.tok.kind
of tkEof: of tkEof:
result = CfgEvent(kind: cfgEof) result = CfgEvent(kind: cfgEof)
@ -442,12 +442,12 @@ type
Config* = OrderedTableRef[string, <//>OrderedTableRef[string, string]] Config* = OrderedTableRef[string, <//>OrderedTableRef[string, string]]
proc newConfig*(): Config = proc newConfig*(): Config =
## Create a new configuration table. ## Creates a new configuration table.
## Useful when wanting to create a configuration file. ## Useful when wanting to create a configuration file.
result = newOrderedTable[string, <//>OrderedTableRef[string, string]]() result = newOrderedTable[string, <//>OrderedTableRef[string, string]]()
proc loadConfig*(stream: Stream, filename: string = "[stream]"): <//>Config = proc loadConfig*(stream: Stream, filename: string = "[stream]"): <//>Config =
## Load the specified configuration from stream into a new Config instance. ## Loadw the specified configuration from stream into a new Config instance.
## `filename` parameter is only used for nicer error messages. ## `filename` parameter is only used for nicer error messages.
var dict = newOrderedTable[string, <//>OrderedTableRef[string, string]]() var dict = newOrderedTable[string, <//>OrderedTableRef[string, string]]()
var curSection = "" ## Current section, var curSection = "" ## Current section,
@ -480,7 +480,7 @@ proc loadConfig*(stream: Stream, filename: string = "[stream]"): <//>Config =
result = dict result = dict
proc loadConfig*(filename: string): <//>Config = proc loadConfig*(filename: string): <//>Config =
## Load the specified configuration file into a new Config instance. ## Loads the specified configuration file into a new Config instance.
let file = open(filename, fmRead) let file = open(filename, fmRead)
let fileStream = newFileStream(file) let fileStream = newFileStream(file)
defer: fileStream.close() defer: fileStream.close()
@ -505,7 +505,7 @@ proc replace(s: string): string =
result = d result = d
proc writeConfig*(dict: Config, stream: Stream) = proc writeConfig*(dict: Config, stream: Stream) =
## Writes the contents of the table to the specified stream ## Writes the contents of the table to the specified stream.
## ##
## **Note:** Comment statement will be ignored. ## **Note:** Comment statement will be ignored.
for section, sectionData in dict.pairs(): for section, sectionData in dict.pairs():
@ -546,7 +546,8 @@ proc writeConfig*(dict: Config, stream: Stream) =
proc `$`*(dict: Config): string = proc `$`*(dict: Config): string =
## Writes the contents of the table to string. ## Writes the contents of the table to string.
## Note: Comment statement will be ignored. ##
## **Note:** Comment statement will be ignored.
let stream = newStringStream() let stream = newStringStream()
defer: stream.close() defer: stream.close()
dict.writeConfig(stream) dict.writeConfig(stream)
@ -554,7 +555,8 @@ proc `$`*(dict: Config): string =
proc writeConfig*(dict: Config, filename: string) = proc writeConfig*(dict: Config, filename: string) =
## Writes the contents of the table to the specified configuration file. ## Writes the contents of the table to the specified configuration file.
## Note: Comment statement will be ignored. ##
## **Note:** Comment statement will be ignored.
let file = open(filename, fmWrite) let file = open(filename, fmWrite)
defer: file.close() defer: file.close()
let fileStream = newFileStream(file) let fileStream = newFileStream(file)
@ -584,7 +586,7 @@ proc delSection*(dict: var Config, section: string) =
dict.del(section) dict.del(section)
proc delSectionKey*(dict: var Config, section, key: string) = proc delSectionKey*(dict: var Config, section, key: string) =
## Delete the key of the specified section. ## Deletes the key of the specified section.
if dict.hasKey(section): if dict.hasKey(section):
if dict[section].hasKey(key): if dict[section].hasKey(key):
if dict[section].len == 1: if dict[section].len == 1: