Commit c577e6e67d222e20662f2fe90d06fe1d013a27a0

Authored by Göran Krampe
1 parent 809a975c

Added failures collection and help/version helpers.

Showing 1 changed file with 68 additions and 18 deletions
lapp.nim
... ... @@ -253,6 +253,9 @@ proc parseArguments*(usage: string, args: seq[string]): Table[string,PValue] =
253 253 parseSpec(usage)
254 254 addQuitProc(closeFiles)
255 255  
  256 + # Collect failures
  257 + var failures = newSeq[string]()
  258 +
256 259 # parse the flags and arguments
257 260 while i <= n:
258 261 arg = next()
... ... @@ -275,7 +278,8 @@ proc parseArguments*(usage: string, args: seq[string]): Table[string,PValue] =
275 278 for c in arg.tail:
276 279 let f = get_alias(c)
277 280 let i = get_spec(f)
278   - if i.needsValue: fail("needs value! " & f)
  281 + if i.needsValue:
  282 + failures.add("option " & f & " needs a value")
279 283 flagvalues.add(@[f,"true"])
280 284 i.used = true
281 285 else: # argument (stored as \001, \002, etc
... ... @@ -286,14 +290,28 @@ proc parseArguments*(usage: string, args: seq[string]): Table[string,PValue] =
286 290 if not info.multiple: k += 1
287 291 flagvalues.add(@[flag,value])
288 292 info.used = true
289   -
  293 +
  294 + # Some options disables checking
  295 + var enableChecks = true
  296 + for flag,info in parm_spec:
  297 + if info.used:
  298 + if flag == "help" or flag == "version":
  299 + enableChecks = false
  300 +
  301 +
290 302 # any flags not mentioned?
291 303 for flag,info in parm_spec:
292 304 if not info.used:
293 305 if info.defVal == "": # no default!
294   - fail("required option or argument missing: " & flag)
295   - flagvalues.add(@[flag,info.defVal])
296   -
  306 + failures.add("required option or argument missing: " & flag)
  307 + else:
  308 + flagvalues.add(@[flag,info.defVal])
  309 +
  310 + if enableChecks:
  311 + # any failures up until now - then we fail
  312 + if failures.len > 0:
  313 + fail(failures.join(", "))
  314 +
297 315 # cool, we have the info, can convert known flags
298 316 for item in flagvalues:
299 317 var pval: PValue;
... ... @@ -362,23 +380,55 @@ proc parse*(usage: string): Table[string,PValue] =
362 380 args[i] = paramStr(i)
363 381 return parseArguments(usage,args)
364 382  
  383 +# Helper proc for verbosity level.
  384 +proc verbosityLevel(args: Table[string,PValue]): int =
  385 + if args.hasKey("verbose"):
  386 + let verbosity = args["verbose"].asSeq
  387 + result = verbosity.len
  388 + if not verbosity[0].asBool:
  389 + result = 0
  390 + else:
  391 + result = 0
  392 +
  393 +# Helper to check if we should show version
  394 +proc showVersion(args: Table[string,PValue]): bool =
  395 + args["version"].asBool
  396 +
  397 +# Helper to check if we should show help
  398 +proc showHelp(args: Table[string,PValue]): bool =
  399 + args["help"].asBool
  400 +
  401 +
  402 +# Typical usage
365 403 when isMainModule:
366   - var args = parse"""
367   - head [flags] file [out]
368   - -n: (default 10) number of lines
369   - -v,--verbose: (bool...) verbosity level
370   - -a,--alpha useless parm
371   - <file>: (default stdin...)
372   - <out>: (default stdout)
  404 + let help = """
  405 + head [flags] files... [out]
  406 + -h,--help Show this help
  407 + --version Show version
  408 + -n: (default 10) Number of lines to show
  409 + -v,--verbose: (bool...) Verbosity level, ignored
  410 + -o,--out: (default stdout) Optional outfile, defaults to stdout
  411 + <files>: (default stdin...) Files to take head of
373 412 """
  413 + # On parsing failure this will show usage automatically
  414 + var args = parse(help)
374 415  
375   - echo args["n"].asInt
376   - echo args["alpha"].asBool
  416 + # These two are special, they short out
  417 + if args.showHelp: quit(help)
  418 + if args.showVersion: quit("Version: 1.99")
377 419  
378   - for v in args["verbose"].asSeq:
379   - echo "got ",v.asBool
  420 + # Ok, so what did we get...
  421 + let n = args["n"].asInt
  422 +
  423 + # This one is a helper
  424 + let v = verbosityLevel(args)
  425 +
  426 + echo "Lines to show: " & $n
  427 + echo "Verbosity level: " & $verbosityLevel(args)
380 428  
381 429 let myfiles = args["files"].asSeq
  430 + var outFile = args["out"].asFile
  431 +
382 432 for f in myfiles:
383   - echo f.asFile.readLine()
384   -
  433 + for i in 1..n:
  434 + writeln(outFile, string(f.asFile.readLine()))
... ...