diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-11-09 09:00:43 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-11-09 09:03:28 +0100 |
commit | c0fc2f57263058b22d49b4d4d3222b40aa9e5f85 (patch) | |
tree | 5180a55d2142430c8acefb993a0dcd030ec980be | |
parent | fdd09ad0902eb7967d7bffe7777cf2a12ca4d88a (diff) | |
download | Nim-c0fc2f57263058b22d49b4d4d3222b40aa9e5f85.tar.gz |
fixes #9619
-rw-r--r-- | changelog.md | 5 | ||||
-rw-r--r-- | lib/pure/parseopt.nim | 11 | ||||
-rw-r--r-- | tests/misc/tparseopt.nim | 77 |
3 files changed, 55 insertions, 38 deletions
diff --git a/changelog.md b/changelog.md index 1372faa62..54daa7379 100644 --- a/changelog.md +++ b/changelog.md @@ -72,6 +72,11 @@ proc enumToString*(enums: openArray[enum]): string = - Complex type is now generic and not a tuple anymore. +- The `parseopt` module now supports a new flag `allowWhitespaceAfterColon` + (default value: true) that can be set to `false` for better Posix + interoperability. (Bug #9619.) + + ### Language additions - Vm suport for float32<->int32 and float64<->int64 casts was added. diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim index c91134738..c4da88e1d 100644 --- a/lib/pure/parseopt.nim +++ b/lib/pure/parseopt.nim @@ -47,6 +47,7 @@ type cmd*: string # cmd,pos exported so caller can catch "--" as.. pos*: int # ..empty key or subcmd cmdArg & handle specially inShortState: bool + allowWhitespaceAfterColon: bool shortNoVal: set[char] longNoVal: seq[string] cmds: seq[string] @@ -95,7 +96,8 @@ when declared(os.paramCount): # access the command line arguments then! proc initOptParser*(cmdline = "", shortNoVal: set[char]={}, - longNoVal: seq[string] = @[]): OptParser = + longNoVal: seq[string] = @[]; + allowWhitespaceAfterColon = true): OptParser = ## inits the option parser. If ``cmdline == ""``, the real command line ## (as provided by the ``OS`` module) is taken. If ``shortNoVal`` is ## provided command users do not need to delimit short option keys and @@ -108,6 +110,7 @@ when declared(os.paramCount): result.inShortState = false result.shortNoVal = shortNoVal result.longNoVal = longNoVal + result.allowWhitespaceAfterColon = allowWhitespaceAfterColon if cmdline != "": result.cmd = cmdline result.cmds = parseCmdLine(cmdline) @@ -124,7 +127,8 @@ when declared(os.paramCount): result.val = TaintedString"" proc initOptParser*(cmdline: seq[TaintedString], shortNoVal: set[char]={}, - longNoVal: seq[string] = @[]): OptParser = + longNoVal: seq[string] = @[]; + allowWhitespaceAfterColon = true): OptParser = ## inits the option parser. If ``cmdline.len == 0``, the real command line ## (as provided by the ``OS`` module) is taken. ``shortNoVal`` and ## ``longNoVal`` behavior is the same as for ``initOptParser(string,...)``. @@ -133,6 +137,7 @@ when declared(os.paramCount): result.inShortState = false result.shortNoVal = shortNoVal result.longNoVal = longNoVal + result.allowWhitespaceAfterColon = allowWhitespaceAfterColon result.cmd = "" if cmdline.len != 0: result.cmds = newSeq[string](cmdline.len) @@ -210,7 +215,7 @@ proc next*(p: var OptParser) {.rtl, extern: "npo$1".} = inc(i) while i < p.cmds[p.idx].len and p.cmds[p.idx][i] in {'\t', ' '}: inc(i) # if we're at the end, use the next command line option: - if i >= p.cmds[p.idx].len and p.idx < p.cmds.len: + if i >= p.cmds[p.idx].len and p.idx < p.cmds.len and p.allowWhitespaceAfterColon: inc p.idx i = 0 p.val = TaintedString p.cmds[p.idx].substr(i) diff --git a/tests/misc/tparseopt.nim b/tests/misc/tparseopt.nim index badbc59ad..651689398 100644 --- a/tests/misc/tparseopt.nim +++ b/tests/misc/tparseopt.nim @@ -9,6 +9,8 @@ kind: cmdLongOption key:val -- left: kind: cmdLongOption key:val -- debug:3 kind: cmdShortOption key:val -- l:4 kind: cmdShortOption key:val -- r:2 +cmdLongOption foo +cmdLongOption path parseoptNoVal kind: cmdLongOption key:val -- left: kind: cmdLongOption key:val -- debug:3 @@ -34,44 +36,49 @@ from parseopt2 import nil block: - echo "parseopt" - for kind, key, val in parseopt.getopt(): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val + echo "parseopt" + for kind, key, val in parseopt.getopt(): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val - # pass custom cmdline arguments - echo "first round" - var argv = "--left --debug:3 -l=4 -r:2" - var p = parseopt.initOptParser(argv) - for kind, key, val in parseopt.getopt(p): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val - break - # reset getopt iterator and check arguments are returned correctly. - echo "second round" - for kind, key, val in parseopt.getopt(p): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val + # pass custom cmdline arguments + echo "first round" + var argv = "--left --debug:3 -l=4 -r:2" + var p = parseopt.initOptParser(argv) + for kind, key, val in parseopt.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + break + # reset getopt iterator and check arguments are returned correctly. + echo "second round" + for kind, key, val in parseopt.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + + # bug #9619 + var x = parseopt.initOptParser(@["--foo:", "--path"], allowWhitespaceAfterColon = false) + for kind, key, val in parseopt.getopt(x): + echo kind, " ", key block: - echo "parseoptNoVal" - # test NoVal mode with custom cmdline arguments - var argv = "--left --debug:3 -l -r:2 --debug 2 --debug=1 -r1 -r=0 -lr4" - var p = parseopt.initOptParser(argv, - shortNoVal = {'l'}, longNoVal = @["left"]) - for kind, key, val in parseopt.getopt(p): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val + echo "parseoptNoVal" + # test NoVal mode with custom cmdline arguments + var argv = "--left --debug:3 -l -r:2 --debug 2 --debug=1 -r1 -r=0 -lr4" + var p = parseopt.initOptParser(argv, + shortNoVal = {'l'}, longNoVal = @["left"]) + for kind, key, val in parseopt.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val block: - echo "parseopt2" - for kind, key, val in parseopt2.getopt(): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val + echo "parseopt2" + for kind, key, val in parseopt2.getopt(): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val - # pass custom cmdline arguments - echo "first round" - var argv: seq[string] = @["--left", "--debug:3", "-l=4", "-r:2"] - var p = parseopt2.initOptParser(argv) - for kind, key, val in parseopt2.getopt(p): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val - break - # reset getopt iterator and check arguments are returned correctly. - echo "second round" - for kind, key, val in parseopt2.getopt(p): - echo "kind: ", kind, "\tkey:val -- ", key, ":", val + # pass custom cmdline arguments + echo "first round" + var argv: seq[string] = @["--left", "--debug:3", "-l=4", "-r:2"] + var p = parseopt2.initOptParser(argv) + for kind, key, val in parseopt2.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val + break + # reset getopt iterator and check arguments are returned correctly. + echo "second round" + for kind, key, val in parseopt2.getopt(p): + echo "kind: ", kind, "\tkey:val -- ", key, ":", val |