Commit 7be5e09db10b63f84cbf307a4b4de0f14b2c9181

Authored by Göran Krampe
1 parent 19ec8d35

Fixed float parsing, exported PValue, added example.nim.

.gitignore
1 nimcache 1 nimcache
2 lapp 2 lapp
  3 +example
README.md 0 → 100644
  1 +Lapp is a command line parser that uses the regular help text for the synopsis as the specification
  2 +for the options and arguments, it was originally written by Steve Donovan in Lua:
  3 +
  4 +http://lua-users.org/wiki/LappFramework
  5 +
  6 +...and ported to Nim by Steve. Then I made it work with current Nim.
  7 +
  8 +See example.nim for how to use it.
example.nim 0 → 100644
  1 +import lapp, tables
  2 +
  3 +# This is a trivial example trying to cover all features of lapp.
  4 +
  5 +let help = """
  6 + example [options] command filenames
  7 +
  8 + -r Just an optional single character flag. Show the args using repr.
  9 + -a,--alpha Or with additional long variant, no whitespace there.
  10 + -n: A colon can be added, but has no meaning, instead () specifies further.
  11 + -N (default 10) And it can take a value, and have a default value.
  12 + -f (default 0.04) And be a float
  13 + -s (default banana) Or a string
  14 + -x (int) And it can be typed with int, string, float, stdin, stdout - without a
  15 + default value. This implies that the option is mandatory!
  16 + -X (int...) And allow multiples.
  17 + -v,--verbose: (bool...) Verbosity level, "..." means can be multiple.
  18 + -o,--out (default stdout) A file to direct to.
  19 + <command> Arguments are string by default.
  20 + <file>: (default stdin...) One or more files or stdin by default
  21 +
  22 +
  23 + The first line in this help text is arbitrary, or rather
  24 + its only the lines (trimmed) beginning with '-' or '<' that constitute
  25 + the speciciation, so this text is also ignored.
  26 +
  27 + Things we know are not working:
  28 + ranges. The lexer in lapp does it, but there is no more support.
  29 + """
  30 +
  31 +# We call `parse` in lapp with our help text as argument.
  32 +# This will both parse the help text above and then, parse the
  33 +# arguments passed to this program. A table is returned
  34 +# with all command line elements in it, keyed by their name
  35 +# and with a PValue as value.
  36 +var args = parse(help)
  37 +
  38 +# Let's examine what we got using repr
  39 +for k,v in args:
  40 + echo "Parameter: " & k & " PValue: " & repr(v)
  41 +
  42 +# Or print out a bit cleaner
  43 +echo "Parameters and their values:"
  44 +echo "r == " & $args["r"].asBool
  45 +echo "alpha == " & $args["alpha"].asBool # Long name is used as key, if its specified
  46 +echo "n == " & $args["n"].asBool
  47 +echo "N == " & $args["N"].asInt
  48 +echo "f == " & $args["f"].asFloat
  49 +echo "s == " & $args["s"].asString
  50 +echo "x == " & $args["x"].asInt
  51 +echo "X == " & $args["X"].asSeq.map(proc(x:PValue):int = x.asInt)
  52 +echo "verbose == " & $args["verbose"].asSeq.len
  53 +echo "out == " & $args["out"].filename
  54 +echo "command == " & $args["command"].asString
  55 +echo "file == " & $args["file"].asSeq.map(proc(x:PValue):string = x.filename)
  56 +
  57 +
lapp.nim
@@ -50,10 +50,10 @@ proc get(L: PLexer; t: var TLexType): string = @@ -50,10 +50,10 @@ proc get(L: PLexer; t: var TLexType): string =
50 next(L) 50 next(L)
51 if thisChar(L) == '.': 51 if thisChar(L) == '.':
52 t = tfloat 52 t = tfloat
53 - result.add(c) 53 + result.add(thisChar(L))
54 next(L) 54 next(L)
55 while thisChar(L) in Digits: 55 while thisChar(L) in Digits:
56 - result.add(c) 56 + result.add(thisChar(L))
57 next(L) 57 next(L)
58 of '.': # ".", "..", "..." 58 of '.': # ".", "..", "..."
59 if thisChar(L) == '.': 59 if thisChar(L) == '.':
@@ -89,17 +89,17 @@ type @@ -89,17 +89,17 @@ type
89 vFile, 89 vFile,
90 vSeq 90 vSeq
91 91
92 - PValue = ref TValue  
93 - TValue = object  
94 - case kind: TValueKind  
95 - of vInt: asInt *: int  
96 - of vFloat: asFloat *: float  
97 - of vString: asString *: string  
98 - of vBool: asBool *: bool 92 + PValue* = ref TValue
  93 + TValue* = object
  94 + case kind*: TValueKind
  95 + of vInt: asInt*: int
  96 + of vFloat: asFloat*: float
  97 + of vString: asString*: string
  98 + of vBool: asBool*: bool
99 of vFile: 99 of vFile:
100 - asFile *: File  
101 - fileName *: string  
102 - of vSeq: asSeq *: seq[PValue] 100 + asFile*: File
  101 + fileName*: string
  102 + of vSeq: asSeq*: seq[PValue]
103 103
104 proc boolValue(c: bool): PValue = PValue(kind: vBool, asBool: c) 104 proc boolValue(c: bool): PValue = PValue(kind: vBool, asBool: c)
105 105
@@ -205,6 +205,7 @@ proc parseSpec(u: string) = @@ -205,6 +205,7 @@ proc parseSpec(u: string) =
205 defValue = "false" 205 defValue = "false"
206 206
207 if name != nil: 207 if name != nil:
  208 + # echo("Param: " & name & " type: " & $ftype & " needsvalue: " & $(ftype != "bool") & " default: " & $defValue & " multiple: " & $multiple)
208 let spec = PSpec(defVal:defValue, ptype: ftype, needsValue: ftype != "bool",multiple:multiple) 209 let spec = PSpec(defVal:defValue, ptype: ftype, needsValue: ftype != "bool",multiple:multiple)
209 aliases[alias] = name 210 aliases[alias] = name
210 parm_spec[name] = spec 211 parm_spec[name] = spec
@@ -314,7 +315,7 @@ proc parseArguments(usage: string, args: seq[string]): Table[string,PValue] = @@ -314,7 +315,7 @@ proc parseArguments(usage: string, args: seq[string]): Table[string,PValue] =
314 try: 315 try:
315 v = value.parseFloat 316 v = value.parseFloat
316 except: 317 except:
317 - fail("bad integer") 318 + fail("bad float")
318 pval = floatValue(v) 319 pval = floatValue(v)
319 of "bool": 320 of "bool":
320 pval = boolValue(value.parseBool) 321 pval = boolValue(value.parseBool)
@@ -359,12 +360,12 @@ proc parse*(usage: string): Table[string,PValue] = @@ -359,12 +360,12 @@ proc parse*(usage: string): Table[string,PValue] =
359 360
360 when isMainModule: 361 when isMainModule:
361 var args = parse""" 362 var args = parse"""
362 - head [flags] filename 363 + head [flags] [file1, file2 ...] [outfile]
363 -n: (default 10) number of lines 364 -n: (default 10) number of lines
364 -v,--verbose: (bool...) verbosity level 365 -v,--verbose: (bool...) verbosity level
365 -a,--alpha useless parm 366 -a,--alpha useless parm
366 <file>: (default stdin...) 367 <file>: (default stdin...)
367 - |<out>: (default stdout) 368 + <out>: (default stdout)
368 """ 369 """
369 370
370 echo args["n"].asInt 371 echo args["n"].asInt