diff options
author | flywind <43030857+xflywind@users.noreply.github.com> | 2020-12-06 16:50:46 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-06 09:50:46 +0100 |
commit | 48d7c40553f0769c22b4b47f8079dd96c3e23323 (patch) | |
tree | f31daea6eae62c74e0545aad8b6cafbedd9576de /lib/pure/parsecfg.nim | |
parent | 1aaa67fc18879bd2aa8ae8f5e7dc763f826c73b6 (diff) | |
download | Nim-48d7c40553f0769c22b4b47f8079dd96c3e23323.tar.gz |
fix #16206 (#16207)
* better docs and tests * a bit better only clean trailing whitespace
Diffstat (limited to 'lib/pure/parsecfg.nim')
-rw-r--r-- | lib/pure/parsecfg.nim | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim index 9b140a809..c87010122 100644 --- a/lib/pure/parsecfg.nim +++ b/lib/pure/parsecfg.nim @@ -107,6 +107,70 @@ ## var dict = loadConfig("config.ini") ## dict.delSectionKey("Author","email") ## dict.writeConfig("config.ini") +## +## Supported INI File structure +## ---------------------------- +## The examples below are supported: +## + +# taken from https://docs.python.org/3/library/configparser.html#supported-ini-file-structure +runnableExamples: + import streams + + var dict = loadConfig(newStringStream("""[Simple Values] + key=value + spaces in keys=allowed + spaces in values=allowed as well + spaces around the delimiter = obviously + you can also use : to delimit keys from values + [All Values Are Strings] + values like this: 19990429 + or this: 3.14159265359 + are they treated as numbers : no + integers floats and booleans are held as: strings + can use the API to get converted values directly: true + [No Values] + key_without_value + # empty string value is not allowed = + [ Seletion A ] + space around section name will be ignored + [You can use comments] + # like this + ; or this + # By default only in an empty line. + # Inline comments can be harmful because they prevent users + # from using the delimiting characters as parts of values. + # That being said, this can be customized. + [Sections Can Be Indented] + can_values_be_as_well = True + does_that_mean_anything_special = False + purpose = formatting for readability + # Did I mention we can indent comments, too? + """) + ) + + let section1 = "Simple Values" + doAssert dict.getSectionValue(section1, "key") == "value" + doAssert dict.getSectionValue(section1, "spaces in keys") == "allowed" + doAssert dict.getSectionValue(section1, "spaces in values") == "allowed as well" + doAssert dict.getSectionValue(section1, "spaces around the delimiter") == "obviously" + doAssert dict.getSectionValue(section1, "you can also use") == "to delimit keys from values" + + let section2 = "All Values Are Strings" + doAssert dict.getSectionValue(section2, "values like this") == "19990429" + doAssert dict.getSectionValue(section2, "or this") == "3.14159265359" + doAssert dict.getSectionValue(section2, "are they treated as numbers") == "no" + doAssert dict.getSectionValue(section2, "integers floats and booleans are held as") == "strings" + doAssert dict.getSectionValue(section2, "can use the API to get converted values directly") == "true" + + let section3 = "Seletion A" + doAssert dict.getSectionValue(section3, + "space around section name will be ignored", "not an empty value") == "" + + let section4 = "Sections Can Be Indented" + doAssert dict.getSectionValue(section4, "can_values_be_as_well") == "True" + doAssert dict.getSectionValue(section4, "does_that_mean_anything_special") == "False" + doAssert dict.getSectionValue(section4, "purpose") == "formatting for readability" import strutils, lexbase, streams, tables @@ -151,7 +215,7 @@ type # implementation const - SymChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF', '.', '/', '\\', '-'} + SymChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', ' ', '\x80'..'\xFF', '.', '/', '\\', '-'} proc rawGetTok(c: var CfgParser, tok: var Token) {.gcsafe.} @@ -306,6 +370,10 @@ proc getSymbol(c: var CfgParser, tok: var Token) = add(tok.literal, c.buf[pos]) inc(pos) if not (c.buf[pos] in SymChars): break + + while tok.literal.len > 0 and tok.literal[^1] == ' ': + tok.literal.setLen(tok.literal.len - 1) + c.bufpos = pos tok.kind = tkSymbol |