Commit 1b2c46b87b58271f61bc813e17af41cb670fa6f7
1 parent
c577e6e6
Added groups support using divider and exported some procs.
Showing
1 changed file
with
28 additions
and
12 deletions
lapp.nim
... | ... | @@ -17,6 +17,8 @@ type |
17 | 17 | trange |
18 | 18 | telipsis |
19 | 19 | tchar |
20 | + toption | |
21 | + tdivider | |
20 | 22 | |
21 | 23 | proc thisChar(L: PLexer):char = L.str[L.idx] |
22 | 24 | proc next(L: PLexer) = L.idx += 1 |
... | ... | @@ -35,9 +37,15 @@ proc get(L: PLexer; t: var TLexType): string = |
35 | 37 | t = tchar |
36 | 38 | case c |
37 | 39 | of '-': # '-", "--" |
40 | + t = toption | |
38 | 41 | if thisChar(L) == '-': |
39 | 42 | result.add('-') |
40 | 43 | next(L) |
44 | + if thisChar(L) == '-': # "---..." | |
45 | + t = tdivider | |
46 | + result.add('-') | |
47 | + while thisChar(L) == '-': | |
48 | + next(L) | |
41 | 49 | of Letters: # word |
42 | 50 | t = tword |
43 | 51 | while thisChar(L) in Letters: |
... | ... | @@ -112,14 +120,13 @@ proc intValue(v: int): PValue = PValue(kind: vInt, asInt: v) |
112 | 120 | proc floatValue(v: float): PValue = PValue(kind: vFloat, asFloat: v) |
113 | 121 | |
114 | 122 | proc seqValue(v: seq[PValue]): PValue = PValue(kind: vSeq, asSeq: v) |
115 | - | |
116 | -const MAX_FILES = 30 | |
117 | 123 | |
118 | 124 | type |
119 | 125 | PSpec = ref TSpec |
120 | 126 | TSpec = object |
121 | 127 | defVal: string |
122 | 128 | ptype: string |
129 | + group: int | |
123 | 130 | needsValue, multiple, used: bool |
124 | 131 | var |
125 | 132 | progname, usage: string |
... | ... | @@ -134,6 +141,7 @@ proc parseSpec(u: string) = |
134 | 141 | var |
135 | 142 | L: PLexer |
136 | 143 | tok: string |
144 | + groupCounter: int | |
137 | 145 | k = 1 |
138 | 146 | |
139 | 147 | let lines = u.splitLines |
... | ... | @@ -173,7 +181,8 @@ proc parseSpec(u: string) = |
173 | 181 | k += 1 |
174 | 182 | tok = L.get |
175 | 183 | if tok != ">": fail("argument must be enclosed in <...>") |
176 | - | |
184 | + elif tok == "---": # divider | |
185 | + inc(groupCounter) | |
177 | 186 | if getnext: tok = L.get |
178 | 187 | if tok == ":": # allowed to have colon after flags |
179 | 188 | tok = L.get |
... | ... | @@ -205,8 +214,8 @@ proc parseSpec(u: string) = |
205 | 214 | defValue = "false" |
206 | 215 | |
207 | 216 | if name != nil: |
208 | - # echo("Param: " & name & " type: " & $ftype & " needsvalue: " & $(ftype != "bool") & " default: " & $defValue & " multiple: " & $multiple) | |
209 | - let spec = PSpec(defVal:defValue, ptype: ftype, needsValue: ftype != "bool",multiple:multiple) | |
217 | + #echo("Param: " & name & " type: " & $ftype & " group: " & $groupCounter & " needsvalue: " & $(ftype != "bool") & " default: " & $defValue & " multiple: " & $multiple) | |
218 | + let spec = PSpec(defVal:defValue, ptype: ftype, group: groupCounter, needsValue: ftype != "bool",multiple:multiple) | |
210 | 219 | aliases[alias] = name |
211 | 220 | parm_spec[name] = spec |
212 | 221 | |
... | ... | @@ -297,12 +306,19 @@ proc parseArguments*(usage: string, args: seq[string]): Table[string,PValue] = |
297 | 306 | if info.used: |
298 | 307 | if flag == "help" or flag == "version": |
299 | 308 | enableChecks = false |
300 | - | |
301 | - | |
309 | + | |
310 | + # Check maximum group used | |
311 | + var maxGroup = 0 | |
312 | + for item in flagvalues: | |
313 | + info = get_spec(item[0]) | |
314 | + if maxGroup < info.group: | |
315 | + maxGroup = info.group | |
316 | + | |
302 | 317 | # any flags not mentioned? |
303 | 318 | for flag,info in parm_spec: |
304 | 319 | if not info.used: |
305 | - if info.defVal == "": # no default! | |
320 | + # Is there no default and we have used options in this group? | |
321 | + if info.defVal == "" and info.group <= maxGroup: | |
306 | 322 | failures.add("required option or argument missing: " & flag) |
307 | 323 | else: |
308 | 324 | flagvalues.add(@[flag,info.defVal]) |
... | ... | @@ -310,7 +326,7 @@ proc parseArguments*(usage: string, args: seq[string]): Table[string,PValue] = |
310 | 326 | if enableChecks: |
311 | 327 | # any failures up until now - then we fail |
312 | 328 | if failures.len > 0: |
313 | - fail(failures.join(", ")) | |
329 | + fail(failures.join("\n") & "\n") | |
314 | 330 | |
315 | 331 | # cool, we have the info, can convert known flags |
316 | 332 | for item in flagvalues: |
... | ... | @@ -381,7 +397,7 @@ proc parse*(usage: string): Table[string,PValue] = |
381 | 397 | return parseArguments(usage,args) |
382 | 398 | |
383 | 399 | # Helper proc for verbosity level. |
384 | -proc verbosityLevel(args: Table[string,PValue]): int = | |
400 | +proc verbosityLevel*(args: Table[string,PValue]): int = | |
385 | 401 | if args.hasKey("verbose"): |
386 | 402 | let verbosity = args["verbose"].asSeq |
387 | 403 | result = verbosity.len |
... | ... | @@ -391,11 +407,11 @@ proc verbosityLevel(args: Table[string,PValue]): int = |
391 | 407 | result = 0 |
392 | 408 | |
393 | 409 | # Helper to check if we should show version |
394 | -proc showVersion(args: Table[string,PValue]): bool = | |
410 | +proc showVersion*(args: Table[string,PValue]): bool = | |
395 | 411 | args["version"].asBool |
396 | 412 | |
397 | 413 | # Helper to check if we should show help |
398 | -proc showHelp(args: Table[string,PValue]): bool = | |
414 | +proc showHelp*(args: Table[string,PValue]): bool = | |
399 | 415 | args["help"].asBool |
400 | 416 | |
401 | 417 | ... | ... |