summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/parseopt.nim93
1 files changed, 56 insertions, 37 deletions
diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim
index e9d10b51a..218f5ab81 100644
--- a/lib/pure/parseopt.nim
+++ b/lib/pure/parseopt.nim
@@ -21,17 +21,17 @@
 
 include "system/inclrtl"
 
-import 
+import
   os, strutils
 
-type 
+type
   CmdLineKind* = enum         ## the detected command line token
     cmdEnd,                   ## end of command line reached
     cmdArgument,              ## argument detected
     cmdLongOption,            ## a long option ``--option`` detected
     cmdShortOption            ## a short option ``-c`` detected
-  OptParser* = 
-      object of RootObj ## this object implements the command line parser  
+  OptParser* =
+      object of RootObj ## this object implements the command line parser
     cmd: string
     pos: int
     inShortState: bool
@@ -42,8 +42,40 @@ type
 
 {.deprecated: [TCmdLineKind: CmdLineKind, TOptParser: OptParser].}
 
+proc parseWord(s: string, i: int, w: var string,
+               delim: set[char] = {'\x09', ' ', '\0'}): int =
+  result = i
+  if s[result] == '\"':
+    inc(result)
+    while not (s[result] in {'\0', '\"'}):
+      add(w, s[result])
+      inc(result)
+    if s[result] == '\"': inc(result)
+  else:
+    while not (s[result] in delim):
+      add(w, s[result])
+      inc(result)
+
 when declared(os.paramCount):
-  # we cannot provide this for NimRtl creation on Posix, because we can't 
+  proc quote(s: string): string =
+    if find(s, {' ', '\t'}) >= 0 and s[0] != '"':
+      if s[0] == '-':
+        result = newStringOfCap(s.len)
+        var i = parseWord(s, 0, result, {'\0', ' ', '\x09', ':', '='})
+        if 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!
 
   proc initOptParser*(cmdline = ""): OptParser =
@@ -51,40 +83,27 @@ when declared(os.paramCount):
     ## (as provided by the ``OS`` module) is taken.
     result.pos = 0
     result.inShortState = false
-    if cmdline != "": 
+    if cmdline != "":
       result.cmd = cmdline
-    else: 
+    else:
       result.cmd = ""
-      for i in countup(1, paramCount()): 
-        result.cmd = result.cmd & quoteIfContainsWhite(paramStr(i).string) & ' '
+      for i in countup(1, paramCount()):
+        result.cmd.add quote(paramStr(i).string)
+        result.cmd.add ' '
     result.kind = cmdEnd
     result.key = TaintedString""
     result.val = TaintedString""
 
-proc parseWord(s: string, i: int, w: var string, 
-               delim: set[char] = {'\x09', ' ', '\0'}): int = 
-  result = i
-  if s[result] == '\"': 
-    inc(result)
-    while not (s[result] in {'\0', '\"'}): 
-      add(w, s[result])
-      inc(result)
-    if s[result] == '\"': inc(result)
-  else: 
-    while not (s[result] in delim): 
-      add(w, s[result])
-      inc(result)
-
-proc handleShortOption(p: var OptParser) = 
+proc handleShortOption(p: var OptParser) =
   var i = p.pos
   p.kind = cmdShortOption
   add(p.key.string, p.cmd[i])
   inc(i)
   p.inShortState = true
-  while p.cmd[i] in {'\x09', ' '}: 
+  while p.cmd[i] in {'\x09', ' '}:
     inc(i)
     p.inShortState = false
-  if p.cmd[i] in {':', '='}: 
+  if p.cmd[i] in {':', '='}:
     inc(i)
     p.inShortState = false
     while p.cmd[i] in {'\x09', ' '}: inc(i)
@@ -92,7 +111,7 @@ proc handleShortOption(p: var OptParser) =
   if p.cmd[i] == '\0': p.inShortState = false
   p.pos = i
 
-proc next*(p: var OptParser) {.rtl, extern: "npo$1".} = 
+proc next*(p: var OptParser) {.rtl, extern: "npo$1".} =
   ## parses the first or next option; ``p.kind`` describes what token has been
   ## parsed. ``p.key`` and ``p.val`` are set accordingly.
   var i = p.pos
@@ -100,33 +119,33 @@ proc next*(p: var OptParser) {.rtl, extern: "npo$1".} =
   p.pos = i
   setLen(p.key.string, 0)
   setLen(p.val.string, 0)
-  if p.inShortState: 
+  if p.inShortState:
     handleShortOption(p)
-    return 
+    return
   case p.cmd[i]
-  of '\0': 
+  of '\0':
     p.kind = cmdEnd
-  of '-': 
+  of '-':
     inc(i)
-    if p.cmd[i] == '-': 
+    if p.cmd[i] == '-':
       p.kind = cmdLongoption
       inc(i)
       i = parseWord(p.cmd, i, p.key.string, {'\0', ' ', '\x09', ':', '='})
       while p.cmd[i] in {'\x09', ' '}: inc(i)
-      if p.cmd[i] in {':', '='}: 
+      if p.cmd[i] in {':', '='}:
         inc(i)
         while p.cmd[i] in {'\x09', ' '}: inc(i)
         p.pos = parseWord(p.cmd, i, p.val.string)
-      else: 
+      else:
         p.pos = i
-    else: 
+    else:
       p.pos = i
       handleShortOption(p)
   else:
     p.kind = cmdArgument
     p.pos = parseWord(p.cmd, i, p.key.string)
 
-proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo$1".} = 
+proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo$1".} =
   ## retrieves the rest of the command line that has not been parsed yet.
   result = strip(substr(p.cmd, p.pos, len(p.cmd) - 1)).TaintedString
 
@@ -140,7 +159,7 @@ when declared(initOptParser):
     ##     filename = ""
     ##   for kind, key, val in getopt():
     ##     case kind
-    ##     of cmdArgument: 
+    ##     of cmdArgument:
     ##       filename = key
     ##     of cmdLongOption, cmdShortOption:
     ##       case key