diff options
Diffstat (limited to 'rod/parseopt.nim')
-rwxr-xr-x | rod/parseopt.nim | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/rod/parseopt.nim b/rod/parseopt.nim new file mode 100755 index 000000000..35f7d5b2c --- /dev/null +++ b/rod/parseopt.nim @@ -0,0 +1,115 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2008 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +# A command line parser; the Nimrod version of this file +# will become part of the standard library. + +import + os, strutils + +type + TCmdLineKind* = enum + cmdEnd, # end of command line reached + cmdArgument, # argument detected + cmdLongoption, # a long option ``--option`` detected + cmdShortOption # a short option ``-c`` detected + TOptParser* = object of TObject + cmd*: string + pos*: int + inShortState*: bool + kind*: TCmdLineKind + key*, val*: string + + +proc init*(cmdline: string = ""): TOptParser +proc next*(p: var TOptParser) +proc getRestOfCommandLine*(p: TOptParser): string +# implementation + +proc init(cmdline: string = ""): TOptParser = + result.pos = 0 + result.inShortState = false + if cmdline != "": + result.cmd = cmdline + else: + result.cmd = "" + for i in countup(1, ParamCount()): + result.cmd = result.cmd & quoteIfContainsWhite(paramStr(i)) & ' ' + result.kind = cmdEnd + result.key = "" + result.val = "" + +proc parseWord(s: string, i: int, w: var string, + delim: TCharSet = {'\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 TOptParser) = + var i: int + i = p.pos + p.kind = cmdShortOption + add(p.key, p.cmd[i]) + inc(i) + p.inShortState = true + while p.cmd[i] in {'\x09', ' '}: + inc(i) + p.inShortState = false + if p.cmd[i] in {':', '='}: + inc(i) + p.inShortState = false + while p.cmd[i] in {'\x09', ' '}: inc(i) + i = parseWord(p.cmd, i, p.val) + if p.cmd[i] == '\0': p.inShortState = false + p.pos = i + +proc next(p: var TOptParser) = + var i: int + i = p.pos + while p.cmd[i] in {'\x09', ' '}: inc(i) + p.pos = i + setlen(p.key, 0) + setlen(p.val, 0) + if p.inShortState: + handleShortOption(p) + return + case p.cmd[i] + of '\0': + p.kind = cmdEnd + of '-': + inc(i) + if p.cmd[i] == '-': + p.kind = cmdLongOption + inc(i) + i = parseWord(p.cmd, i, p.key, {'\0', ' ', '\x09', ':', '='}) + while p.cmd[i] in {'\x09', ' '}: inc(i) + if p.cmd[i] in {':', '='}: + inc(i) + while p.cmd[i] in {'\x09', ' '}: inc(i) + p.pos = parseWord(p.cmd, i, p.val) + else: + p.pos = i + else: + p.pos = i + handleShortOption(p) + else: + p.kind = cmdArgument + p.pos = parseWord(p.cmd, i, p.key) + +proc getRestOfCommandLine(p: TOptParser): string = + result = strip(copy(p.cmd, p.pos + 0, len(p.cmd) - 1)) # always -1, because Pascal version uses a trailing zero here + \ No newline at end of file |