@@ -24,6 +24,7 @@ gen_class:
24
24
Pattern = ref object of RootObj
25
25
m_name: string
26
26
value: Value
27
+ has_children: bool
27
28
children: seq [Pattern]
28
29
29
30
ChildPattern = ref object of Pattern
@@ -57,7 +58,7 @@ proc argument(name: string, value = val()): Argument =
57
58
proc command(name: string , value = val(false )): Command =
58
59
Command(m_name: name, value: value)
59
60
60
- proc option(short, long: string = nil , argcount = 0 ,
61
+ proc option(short, long: string = " " , argcount = 0 ,
61
62
value = val(false )): Option =
62
63
assert argcount in [0 , 1 ]
63
64
result = Option(short: short, long: long,
@@ -66,19 +67,19 @@ proc option(short, long: string = nil, argcount = 0,
66
67
result .value = val()
67
68
68
69
proc required(children: varargs [Pattern]) : Required =
69
- Required(children: @ children)
70
+ Required(has_children: true , children: @ children, value: val() )
70
71
71
72
proc optional(children: varargs [Pattern]) : Optional =
72
- Optional(children: @ children)
73
+ Optional(has_children: true , children: @ children, value: val() )
73
74
74
75
proc any_options(children: varargs [Pattern]) : AnyOptions =
75
- AnyOptions(children: @ children)
76
+ AnyOptions(has_children: true , children: @ children, value: val() )
76
77
77
78
proc one_or_more(children: varargs [Pattern]) : OneOrMore =
78
- OneOrMore(children: @ children)
79
+ OneOrMore(has_children: true , children: @ children, value: val() )
79
80
80
81
proc either(children: varargs [Pattern]) : Either =
81
- Either(children: @ children)
82
+ Either(has_children: true , children: @ children, value: val() )
82
83
83
84
84
85
type
@@ -115,10 +116,8 @@ method match(self: Pattern, left: seq[Pattern],
115
116
116
117
method fix_identities(self: Pattern, uniq: seq [Pattern]) {.base, gcsafe.} =
117
118
# # Make pattern-tree tips point to same object if they are equal.
118
- if self.children.is_nil:
119
- return
120
119
for i, child in self.children:
121
- if child.children.is_nil :
120
+ if not child.has_children :
122
121
assert child in uniq
123
122
self.children[i] = uniq[uniq.find(child)]
124
123
else :
@@ -251,7 +250,7 @@ method single_match(self: Command, left: seq[Pattern]): SingleMatchResult =
251
250
proc option_parse[T](
252
251
constructor: proc(short, long: string ; argcount: int ; value: Value): T,
253
252
option_description: string ): T =
254
- var short, long: string = nil
253
+ var short, long: string = ""
255
254
var argcount = 0
256
255
var value = val(false)
257
256
var (options, p, description) = option_description.strip().partition(" ")
@@ -279,7 +278,7 @@ method single_match(self: Option, left: seq[Pattern]): SingleMatchResult =
279
278
raise new_exception(ValueError, " Not found" )
280
279
281
280
method name(self: Option): string =
282
- if self.long != nil : self.long else : self.short
281
+ if self.long != " " : self.long else : self.short
283
282
284
283
method str(self: Option): string =
285
284
" Option($#, $#, $#, $#)" .format(self.short.str, self.long.str,
@@ -347,8 +346,7 @@ proc token_stream(source: string, error: ref Exception): TokenStream =
347
346
token_stream(source.split_whitespace(), error)
348
347
349
348
proc current(self: TokenStream): string =
350
- if @ self.len > 0 :
351
- result = @ self[0 ]
349
+ if @ self.len > 0 : @ self[0 ] else : " "
352
350
353
351
proc move(self: TokenStream): string =
354
352
result = self.current
@@ -363,18 +361,18 @@ proc parse_long(tokens: TokenStream, options: var seq[Option]): seq[Pattern] =
363
361
var similar = options.filter_it(it.long == long)
364
362
var o: Option
365
363
if tokens.error of DocoptExit and similar.len == 0 : # if no exact match
366
- similar = options.filter_it(it.long != nil and
364
+ similar = options.filter_it(it.long != " " and
367
365
it.long.starts_with long)
368
366
if similar.len > 1 : # might be simply specified ambiguously 2+ times?
369
367
tokens.error.msg = " $# is not a unique prefix: $#?" .format(
370
368
long, similar.map_it(string , it.long).join(" , " ))
371
369
raise tokens.error
372
370
elif similar.len < 1 :
373
371
let argcount = (if eq == " =" : 1 else : 0 )
374
- o = option(nil , long, argcount)
372
+ o = option(" " , long, argcount)
375
373
options.add o
376
374
if tokens.error of DocoptExit:
377
- o = option(nil , long, argcount,
375
+ o = option(" " , long, argcount,
378
376
if argcount > 0 : value else : val(true ))
379
377
else :
380
378
o = option(similar[0 ].short, similar[0 ].long,
@@ -385,7 +383,7 @@ proc parse_long(tokens: TokenStream, options: var seq[Option]): seq[Pattern] =
385
383
raise tokens.error
386
384
else :
387
385
if value.kind == vkNone:
388
- if tokens.current == nil :
386
+ if tokens.current == " " :
389
387
tokens.error.msg = " $# requires argument" .format(o.long)
390
388
raise tokens.error
391
389
value = val(tokens.move())
@@ -410,17 +408,17 @@ proc parse_shorts(tokens: TokenStream, options: var seq[Option]): seq[Pattern] =
410
408
short, similar.len)
411
409
raise tokens.error
412
410
elif similar.len < 1 :
413
- o = option(short, nil , 0 )
411
+ o = option(short, " " , 0 )
414
412
options.add o
415
413
if tokens.error of DocoptExit:
416
- o = option(short, nil , 0 , val(true ))
414
+ o = option(short, " " , 0 , val(true ))
417
415
else : # why copying is necessary here?
418
416
o = option(short, similar[0 ].long,
419
417
similar[0 ].argcount, similar[0 ].value)
420
418
var value = val()
421
419
if o.argcount != 0 :
422
420
if left == " " :
423
- if tokens.current == nil :
421
+ if tokens.current == " " :
424
422
tokens.error.msg = " $# requires argument" .format(short)
425
423
raise tokens.error
426
424
value = val(tokens.move())
@@ -440,7 +438,7 @@ proc parse_pattern(source: string, options: var seq[Option]): Required =
440
438
new_exception(DocoptLanguageError, " " )
441
439
)
442
440
let ret = parse_expr(tokens, options)
443
- if tokens.current != nil :
441
+ if tokens.current != " " :
444
442
tokens.error.msg = " unexpected ending: '$#'" .format(@ tokens.join(" " ))
445
443
raise tokens.error
446
444
required(ret)
@@ -467,7 +465,7 @@ proc parse_atom(tokens: TokenStream, options: var seq[Option]): seq[Pattern] {.g
467
465
proc parse_seq(tokens: TokenStream, options: var seq [Option]) : seq [Pattern] =
468
466
# # seq ::= ( atom [ '...' ] )* ;
469
467
result = @ []
470
- while tokens.current notin [nil , " ]" , " )" , " |" ]:
468
+ while tokens.current notin [" " , " ]" , " )" , " |" ]:
471
469
var atom = parse_atom(tokens, options)
472
470
if tokens.current == " ..." :
473
471
let oom = one_or_more(atom)
@@ -520,17 +518,17 @@ proc parse_argv(tokens: TokenStream, options: var seq[Option],
520
518
# # else:
521
519
# # argv ::= [ long | shorts | argument ]* [ '--' [ argument ]* ] ;
522
520
result = @ []
523
- while tokens.current != nil :
521
+ while tokens.current != " " :
524
522
if tokens.current == " --" :
525
- return result & @ tokens.map_it(Pattern, argument(nil , val(it)))
523
+ return result & @ tokens.map_it(Pattern, argument(" " , val(it)))
526
524
elif tokens.current.starts_with " --" :
527
525
result .add parse_long(tokens, options)
528
526
elif (tokens.current.starts_with " -" ) and tokens.current != " -" :
529
527
result .add parse_shorts(tokens, options)
530
528
elif options_first:
531
- return result & @ tokens.map_it(Pattern, argument(nil , val(it)))
529
+ return result & @ tokens.map_it(Pattern, argument(" " , val(it)))
532
530
else :
533
- result .add argument(nil , val(tokens.move()))
531
+ result .add argument(" " , val(tokens.move()))
534
532
535
533
536
534
proc parse_defaults(doc: string ): seq [Option] =
@@ -566,7 +564,7 @@ proc extras(help: bool, version: string, options: seq[Pattern], doc: string) =
566
564
if help and options.any_it((it.name in [" -h" , " --help" ]) and it.value):
567
565
echo(doc.strip())
568
566
quit()
569
- elif version != nil and
567
+ elif version != " " and
570
568
options.any_it(it.name == " --version" and it.value):
571
569
echo(version)
572
570
quit()
@@ -576,8 +574,6 @@ proc docopt_exc(doc: string, argv: seq[string], help: bool, version: string,
576
574
options_first = false ): Table[string , Value] =
577
575
var doc = doc.replace(" \r\l " , " \l " )
578
576
579
- var argv = (if argv.is_nil: command_line_params() else : argv)
580
-
581
577
var docopt_exit = new_exception(DocoptExit, " " )
582
578
docopt_exit.usage = printable_usage(doc)
583
579
@@ -605,8 +601,8 @@ proc docopt_exc(doc: string, argv: seq[string], help: bool, version: string,
605
601
raise docopt_exit
606
602
607
603
608
- proc docopt*(doc: string , argv: seq [string ] = nil , help = true,
609
- version: string = nil , options_first = false, quit = true
604
+ proc docopt*(doc: string , argv: seq [string ] = command_line_params() , help = true,
605
+ version: string = "" , options_first = false, quit = true
610
606
): Table[string , Value] {.gcsafe.} =
611
607
## Parse `argv` based on command-line interface described in `doc`.
612
608
##
0 commit comments