Skip to content
Permalink
Browse files

fix nim-lang#9842 nim-lang#9951: `nim -r` and parseopt.cmdLineRest ar…

…e now correct
  • Loading branch information...
timotheecour committed Jan 12, 2019
1 parent 7510603 commit cd45f34e4b39c1d99cf831869841b2fbaabdba2e
Showing with 94 additions and 68 deletions.
  1. +1 −1 compiler/lineinfos.nim
  2. +1 −23 lib/pure/parseopt.nim
  3. +92 −44 tests/misc/tparseopt.nim
@@ -171,7 +171,7 @@ proc computeNotesVerbosity(): array[0..3, TNoteKinds] =
warnGcUnsafe, hintPath, hintDependency, hintCodeBegin, hintCodeEnd,
hintSource, hintGlobalVar, hintGCStats}
result[0] = result[1] - {hintSuccessX, hintSuccess, hintConf,
hintProcessing, hintPattern, hintExecuting, hintLinking}
hintProcessing, hintPattern, hintExecuting, hintLinking, hintCC}

const
NotesVerbosity* = computeNotesVerbosity()
@@ -73,24 +73,6 @@ proc parseWord(s: string, i: int, w: var string,
inc(result)

when declared(os.paramCount):
proc quote(s: string): string =
if find(s, {' ', '\t'}) >= 0 and s.len > 0 and s[0] != '"':
if s[0] == '-':
result = newStringOfCap(s.len)
var i = parseWord(s, 0, result, {' ', '\t', ':', '='})
if i < s.len and s[i] in {':','='}:
result.add s[i]
inc i
result.add '"'
while i < s.len:
result.add s[i]
inc i
result.add '"'
else:
result = '"' & s & '"'
else:
result = s

# we cannot provide this for NimRtl creation on Posix, because we can't
# access the command line arguments then!

@@ -228,11 +210,7 @@ proc next*(p: var OptParser) {.rtl, extern: "npo$1".} =
when declared(os.paramCount):
proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo$1".} =
## retrieves the rest of the command line that has not been parsed yet.
var res = ""
for i in p.idx..<p.cmds.len:
if i > p.idx: res.add ' '
res.add quote(p.cmds[i])
result = res.TaintedString
result = p.cmds[p.idx .. ^1].quoteShellCommand.TaintedString

proc remainingArgs*(p: OptParser): seq[TaintedString] {.rtl, extern: "npo$1".} =
## retrieves the rest of the command line that has not been parsed yet.
@@ -30,54 +30,102 @@ kind: cmdLongOption key:val -- debug:3
kind: cmdShortOption key:val -- l:4
kind: cmdShortOption key:val -- r:2'''
"""
from parseopt import nil
from parseopt2 import nil

when defined(testament_tparseopt):
import os
proc main() =
let args = commandLineParams()
echo args
for i, ai in args:
echo "arg ", i, " ai.len:", ai.len, " :{", ai, "}"
main()
else:
from parseopt import nil
from parseopt2 import nil

block:
echo "parseopt"
for kind, key, val in parseopt.getopt():
echo "kind: ", kind, "\tkey:val -- ", key, ":", val
block:
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
# 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
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

block:
echo "parseopt2"
for kind, key, val in parseopt2.getopt():
echo "kind: ", kind, "\tkey:val -- ", key, ":", val
block:
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

import osproc, os, strutils
from stdtest/specialpaths import buildDir
import "../.." / compiler/unittest_light

block: # fix #9951
var p = parseopt.initOptParser(@["echo \"quoted\""])
assertEquals parseopt.cmdLineRest(p), """'echo "quoted"'"""
let args = @["a1b", "a2 b", "", "a4\"b", "a5'b", r"a6\b", "a7\'b"]
var p2 = parseopt.initOptParser(args)
assertEquals parseopt.cmdLineRest(p2),
"""a1b 'a2 b' '' 'a4"b' 'a5'"'"'b' 'a6\b' 'a7'"'"'b'"""
doAssert "a5'b" == "a5\'b"

block: # fix #9842
let exe = buildDir / "D20190112T145450".addFileExt(ExeExt)
defer: removeFile exe
let args = @["a1b", "a2 b", "", "a4\"b", "a5'b", r"a6\b", "a7\'b"]
let cmd = "$# c -r --verbosity:0 -o:$# -d:testament_tparseopt $# $#" %
[getCurrentCompilerExe(), exe, currentSourcePath(),
args.quoteShellCommand]
var ret = execCmdEx(cmd, options = {})
if ret.exitCode != 0:
# before bug fix, running cmd would show:
# sh: -c: line 0: unexpected EOF while looking for matching `"'\n
echo "exitCode: ", ret.exitCode, " cmd:", cmd
doAssert false
stripLineEnd(ret.output)
assertEquals ret.output,
"""
@["a1b", "a2 b", "", "a4\"b", "a5\'b", "a6\\b", "a7\'b"]
arg 0 ai.len:3 :{a1b}
arg 1 ai.len:4 :{a2 b}
arg 2 ai.len:0 :{}
arg 3 ai.len:4 :{a4"b}
arg 4 ai.len:4 :{a5'b}
arg 5 ai.len:4 :{a6\b}
arg 6 ai.len:4 :{a7'b}"""

0 comments on commit cd45f34

Please sign in to comment.
You can’t perform that action at this time.