parseopt stdlib module: dont rely on the zero terminator
This commit is contained in:
parent
39b81c836c
commit
203d833688
1 changed files with 25 additions and 23 deletions
|
|
@ -57,26 +57,26 @@ type
|
||||||
{.deprecated: [TCmdLineKind: CmdLineKind, TOptParser: OptParser].}
|
{.deprecated: [TCmdLineKind: CmdLineKind, TOptParser: OptParser].}
|
||||||
|
|
||||||
proc parseWord(s: string, i: int, w: var string,
|
proc parseWord(s: string, i: int, w: var string,
|
||||||
delim: set[char] = {'\x09', ' ', '\0'}): int =
|
delim: set[char] = {'\x09', ' '}): int =
|
||||||
result = i
|
result = i
|
||||||
if s[result] == '\"':
|
if result < s.len and s[result] == '\"':
|
||||||
inc(result)
|
inc(result)
|
||||||
while not (s[result] in {'\0', '\"'}):
|
while result < s.len and s[result] != '\"':
|
||||||
add(w, s[result])
|
add(w, s[result])
|
||||||
inc(result)
|
inc(result)
|
||||||
if s[result] == '\"': inc(result)
|
if result < s.len and s[result] == '\"': inc(result)
|
||||||
else:
|
else:
|
||||||
while not (s[result] in delim):
|
while result < s.len and s[result] notin delim:
|
||||||
add(w, s[result])
|
add(w, s[result])
|
||||||
inc(result)
|
inc(result)
|
||||||
|
|
||||||
when declared(os.paramCount):
|
when declared(os.paramCount):
|
||||||
proc quote(s: string): string =
|
proc quote(s: string): string =
|
||||||
if find(s, {' ', '\t'}) >= 0 and s[0] != '"':
|
if find(s, {' ', '\t'}) >= 0 and s.len > 0 and s[0] != '"':
|
||||||
if s[0] == '-':
|
if s[0] == '-':
|
||||||
result = newStringOfCap(s.len)
|
result = newStringOfCap(s.len)
|
||||||
var i = parseWord(s, 0, result, {'\0', ' ', '\x09', ':', '='})
|
var i = parseWord(s, 0, result, {' ', '\x09', ':', '='})
|
||||||
if s[i] in {':','='}:
|
if i < s.len and s[i] in {':','='}:
|
||||||
result.add s[i]
|
result.add s[i]
|
||||||
inc i
|
inc i
|
||||||
result.add '"'
|
result.add '"'
|
||||||
|
|
@ -144,43 +144,45 @@ proc handleShortOption(p: var OptParser) =
|
||||||
add(p.key.string, p.cmd[i])
|
add(p.key.string, p.cmd[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
p.inShortState = true
|
p.inShortState = true
|
||||||
while p.cmd[i] in {'\x09', ' '}:
|
while i < p.cmd.len and p.cmd[i] in {'\x09', ' '}:
|
||||||
inc(i)
|
inc(i)
|
||||||
p.inShortState = false
|
p.inShortState = false
|
||||||
if p.cmd[i] in {':', '='} or card(p.shortNoVal) > 0 and p.key.string[0] notin p.shortNoVal:
|
if i < p.cmd.len and p.cmd[i] in {':', '='} or
|
||||||
if p.cmd[i] in {':', '='}:
|
card(p.shortNoVal) > 0 and p.key.string[0] notin p.shortNoVal:
|
||||||
|
if i < p.cmd.len and p.cmd[i] in {':', '='}:
|
||||||
inc(i)
|
inc(i)
|
||||||
p.inShortState = false
|
p.inShortState = false
|
||||||
while p.cmd[i] in {'\x09', ' '}: inc(i)
|
while i < p.cmd.len and p.cmd[i] in {'\x09', ' '}: inc(i)
|
||||||
i = parseWord(p.cmd, i, p.val.string)
|
i = parseWord(p.cmd, i, p.val.string)
|
||||||
if p.cmd[i] == '\0': p.inShortState = false
|
if i >= p.cmd.len: p.inShortState = false
|
||||||
p.pos = i
|
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
|
## parses the first or next option; ``p.kind`` describes what token has been
|
||||||
## parsed. ``p.key`` and ``p.val`` are set accordingly.
|
## parsed. ``p.key`` and ``p.val`` are set accordingly.
|
||||||
var i = p.pos
|
var i = p.pos
|
||||||
while p.cmd[i] in {'\x09', ' '}: inc(i)
|
while i < p.cmd.len and p.cmd[i] in {'\x09', ' '}: inc(i)
|
||||||
p.pos = i
|
p.pos = i
|
||||||
setLen(p.key.string, 0)
|
setLen(p.key.string, 0)
|
||||||
setLen(p.val.string, 0)
|
setLen(p.val.string, 0)
|
||||||
if p.inShortState:
|
if p.inShortState:
|
||||||
handleShortOption(p)
|
handleShortOption(p)
|
||||||
return
|
return
|
||||||
case p.cmd[i]
|
if i >= p.cmd.len:
|
||||||
of '\0':
|
|
||||||
p.kind = cmdEnd
|
p.kind = cmdEnd
|
||||||
of '-':
|
return
|
||||||
|
if p.cmd[i] == '-':
|
||||||
inc(i)
|
inc(i)
|
||||||
if p.cmd[i] == '-':
|
if i < p.cmd.len and p.cmd[i] == '-':
|
||||||
p.kind = cmdLongOption
|
p.kind = cmdLongOption
|
||||||
inc(i)
|
inc(i)
|
||||||
i = parseWord(p.cmd, i, p.key.string, {'\0', ' ', '\x09', ':', '='})
|
i = parseWord(p.cmd, i, p.key.string, {' ', '\x09', ':', '='})
|
||||||
while p.cmd[i] in {'\x09', ' '}: inc(i)
|
while i < p.cmd.len and p.cmd[i] in {'\x09', ' '}: inc(i)
|
||||||
if p.cmd[i] in {':', '='} or len(p.longNoVal) > 0 and p.key.string notin p.longNoVal:
|
if i < p.cmd.len and p.cmd[i] in {':', '='} or
|
||||||
if p.cmd[i] in {':', '='}:
|
len(p.longNoVal) > 0 and p.key.string notin p.longNoVal:
|
||||||
|
if i < p.cmd.len and p.cmd[i] in {':', '='}:
|
||||||
inc(i)
|
inc(i)
|
||||||
while p.cmd[i] in {'\x09', ' '}: inc(i)
|
while i < p.cmd.len and p.cmd[i] in {'\x09', ' '}: inc(i)
|
||||||
p.pos = parseWord(p.cmd, i, p.val.string)
|
p.pos = parseWord(p.cmd, i, p.val.string)
|
||||||
else:
|
else:
|
||||||
p.pos = i
|
p.pos = i
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue