Commit 7be5e09db10b63f84cbf307a4b4de0f14b2c9181
1 parent
19ec8d35
Fixed float parsing, exported PValue, added example.nim.
Showing
4 changed files
with
82 additions
and
15 deletions
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 | 50 | next(L) |
51 | 51 | if thisChar(L) == '.': |
52 | 52 | t = tfloat |
53 | - result.add(c) | |
53 | + result.add(thisChar(L)) | |
54 | 54 | next(L) |
55 | 55 | while thisChar(L) in Digits: |
56 | - result.add(c) | |
56 | + result.add(thisChar(L)) | |
57 | 57 | next(L) |
58 | 58 | of '.': # ".", "..", "..." |
59 | 59 | if thisChar(L) == '.': |
... | ... | @@ -89,17 +89,17 @@ type |
89 | 89 | vFile, |
90 | 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 | 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 | 104 | proc boolValue(c: bool): PValue = PValue(kind: vBool, asBool: c) |
105 | 105 | |
... | ... | @@ -205,6 +205,7 @@ proc parseSpec(u: string) = |
205 | 205 | defValue = "false" |
206 | 206 | |
207 | 207 | if name != nil: |
208 | + # echo("Param: " & name & " type: " & $ftype & " needsvalue: " & $(ftype != "bool") & " default: " & $defValue & " multiple: " & $multiple) | |
208 | 209 | let spec = PSpec(defVal:defValue, ptype: ftype, needsValue: ftype != "bool",multiple:multiple) |
209 | 210 | aliases[alias] = name |
210 | 211 | parm_spec[name] = spec |
... | ... | @@ -314,7 +315,7 @@ proc parseArguments(usage: string, args: seq[string]): Table[string,PValue] = |
314 | 315 | try: |
315 | 316 | v = value.parseFloat |
316 | 317 | except: |
317 | - fail("bad integer") | |
318 | + fail("bad float") | |
318 | 319 | pval = floatValue(v) |
319 | 320 | of "bool": |
320 | 321 | pval = boolValue(value.parseBool) |
... | ... | @@ -359,12 +360,12 @@ proc parse*(usage: string): Table[string,PValue] = |
359 | 360 | |
360 | 361 | when isMainModule: |
361 | 362 | var args = parse""" |
362 | - head [flags] filename | |
363 | + head [flags] [file1, file2 ...] [outfile] | |
363 | 364 | -n: (default 10) number of lines |
364 | 365 | -v,--verbose: (bool...) verbosity level |
365 | 366 | -a,--alpha useless parm |
366 | 367 | <file>: (default stdin...) |
367 | - |<out>: (default stdout) | |
368 | + <out>: (default stdout) | |
368 | 369 | """ |
369 | 370 | |
370 | 371 | echo args["n"].asInt | ... | ... |