File Coverage

blib/lib/Docopt.pm
Criterion Covered Total %
statement 585 609 96.0
branch 203 238 85.2
condition 88 99 88.8
subroutine 95 97 97.9
pod 1 13 7.6
total 972 1056 92.0


line stmt bran cond sub pod time code
1 4     4   93578 use 5.008005;
  4         14  
  4         147  
2 4     4   21 use strict;
  4         7  
  4         160  
3 4     4   21 use warnings FATAL => 'all';
  4         14  
  4         218  
4              
5             package Docopt;
6              
7 4     4   7436 use Docopt::Util qw(string_partition in serialize defined_or);
  4         14  
  4         372  
8              
9             package Docopt::Pattern;
10              
11 4     4   23 use Docopt::Util qw(defined_or);
  4         7  
  4         342  
12              
13             sub new {
14 0     0   0     my $class = shift;
15 0         0     bless [], $class;
16             }
17              
18             sub fix {
19 218     218   291     my $self = shift;
20 218         546     $self->fix_identities();
21 218         684     $self->fix_repeating_arguments();
22 218         1109     return $self;
23             }
24 4     4   19 use Docopt::Util qw(in serialize);
  4         6  
  4         1006  
25              
26             # Make pattern-tree tips point to same object if they are equal.
27             sub fix_identities {
28 801     801   1162     my ($self, $uniq) = @_;
29              
30 801 50       2682     if (!$self->can('children')) {
31 0         0         return $self;
32                 }
33 801         1545     $uniq = defined_or($uniq, $self->flat);
34 801         2743     for (my $i=0; $i<@{$self->children}; $i++) {
  1827         3941  
35 1026         1938         my $child = $self->children->[$i];
36 1026 100       3684         if (not $child->can('children')) {
37 445         663             local $Storable::canonical=1;
38 445 50       1216             in(serialize($child), [map { serialize($_) } @$uniq]) or die;
  1701         99701  
39 445         13033             ($self->children->[$i], ) = grep { serialize($_) eq serialize($child) } @$uniq;
  1701         66237  
40                     } else {
41 581         1284             $child->fix_identities($uniq);
42                     }
43                 }
44              
45             # def fix_identities(self, uniq=None):
46             # """Make pattern-tree tips point to same object if they are equal."""
47             # if not hasattr(self, 'children'):
48             # return self
49             # uniq = list(set(self.flat())) if uniq is None else uniq
50             # for i, child in enumerate(self.children):
51             # if not hasattr(child, 'children'):
52             # assert child in uniq
53             # self.children[i] = uniq[uniq.index(child)]
54             # else:
55             # child.fix_identities(uniq)
56             }
57              
58 4     4   24 use Scalar::Util qw(refaddr);
  4         8  
  4         380  
59 4     4   19 use Docopt::Util qw(repl serialize);
  4         12  
  4         1502  
60              
61             # Fix elements that should accumulate/increment values.
62             sub fix_repeating_arguments {
63 222     222   306     my $self = shift;
64              
65                 my $list_count = sub {
66 517     517   677         my ($list, $stuff) = @_;
67 517         644         my $n = 0;
68 517         992         for (@$list) {
69 1205 100       40341             $n++ if serialize($stuff) eq serialize($_);
70                     }
71 517         27055         return $n;
72 222         1267     };
73              
74             # print repl(Docopt::transform($self));
75 222         352     my @either = map { $_->children } @{Docopt::transform($self)->children};
  291         554  
  222         615  
76 222         834     for my $case (@either) {
77 291         567         for my $e (grep { $list_count->($case, $_) > 1 } @$case) {
  517         1092  
78 167 100 66     1520             if ($e->isa('Docopt::Argument') || ($e->isa('Docopt::Option') && $e->argcount)) {
      66        
79 112 100       377                 if (not defined $e->value) {
    100          
80 83         216                     $e->value([]);
81                             } elsif (ref($e->value) ne 'ARRAY') {
82 12         58                     $e->value([split /\s+/, $e->value]);
83                             }
84                         }
85 167 100 100     1997             if ($e->isa('Docopt::Command') || ($e->isa('Docopt::Option') && $e->argcount==0)) {
      66        
86 67         404                 $e->value(0);
87                         }
88                     }
89                 }
90 222         1326     return $self;
91              
92             # either = [list(child.children) for child in transform(self).children]
93             # for case in either:
94             # for e in [child for child in case if case.count(child) > 1]:
95             # if type(e) is Argument or type(e) is Option and e.argcount:
96             # if e.value is None:
97             # e.value = []
98             # elif type(e.value) is not list:
99             # e.value = e.value.split()
100             # if type(e) is Command or type(e) is Option and e.argcount == 0:
101             # e.value = 0
102             # return self
103             }
104              
105             package Docopt;
106              
107 4     4   24 use parent qw(Exporter);
  4         10  
  4         31  
108              
109             our @EXPORT = qw(docopt);
110              
111 4     4   4185 use List::MoreUtils qw(any);
  4         4905  
  4         442  
112 4     4   28 use Scalar::Util qw(blessed refaddr);
  4         7  
  4         228  
113 4     4   20 use Docopt::Util qw(repl pyprint serialize);
  4         6  
  4         1826  
114              
115             # Expand pattern into an (almost) equivalent one, but with single Either.
116             # Example: ((-a | -b) (-c | -d)) => (-a -c | -a -d | -b -c | -b -d)
117             # Quirks: [-a] => (-a), (-a...) => (-a -a)
118             sub transform {
119 229     229 0 381     my ($pattern) = @_;
120              
121             # pyprint($pattern);
122 229         332     my @results;
123 229         536     my @groups = [$pattern];
124 229         599     while (@groups) {
125 1139         1731         my $children = shift @groups;
126             # pyprint($children);
127 1139         2498         my @parents = qw(Docopt::Required Docopt::Optional Docopt::OptionsShortcut Docopt::Either Docopt::OneOrMore);
128 1139 100   2953   4873         if (any { in($_, [map { blessed $_ } @$children]) } @parents) {
  2953         5883  
  4528         17631  
129             # print " ANY\n";
130 837         1124             my $child = [grep { in(blessed $_, \@parents) } @$children]->[0];
  1008         3800  
131 837         1596             $children = [ grep { refaddr($child) ne refaddr($_) } @$children ];
  1008         3951  
132 837 100       7033             if ($child->isa('Docopt::Either')) {
    100          
133             # print " EITHER\n";
134 60         100                 for (@{$child->children}) {
  60         125  
135 133         416                     push @groups, [$_, @{$children}];
  133         823  
136                             }
137                         } elsif ($child->isa('Docopt::OneOrMore')) {
138             # print " ONEORMORE\n";
139             # I need copying.
140 41         62                 push @groups, [@{$child->children}, @{Storable::dclone($child->children)}, @$children];
  41         97  
  41         86  
141                         } else {
142             # print " OTHER\n";
143 736         846                 push @groups, [@{$child->children}, @$children];
  736         1334  
144                         }
145                     } else {
146             # print " JUST PUSH\n";
147 302         1633             push @results, $children;
148                     }
149                 }
150             # pyprint(\@results);
151 229         442     return Docopt::Either->new([map { Docopt::Required->new($_) } @results]);
  302         783  
152              
153             #ef transform(pattern):
154             # result = []
155             # groups = [[pattern]]
156             # while groups:
157             # children = groups.pop(0)
158             # parents = [Required, Optional, OptionsShortcut, Either, OneOrMore]
159             # if any(t in map(type, children) for t in parents):
160             # child = [c for c in children if type(c) in parents][0]
161             # children.remove(child)
162             # if type(child) is Either:
163             # for c in child.children:
164             # groups.append([c] + children)
165             # elif type(child) is OneOrMore:
166             # groups.append(child.children * 2 + children)
167             # else:
168             # groups.append(child.children + children)
169             # else:
170             # result.append(children)
171             # return Either(*[Required(*e) for e in result])
172             }
173              
174             # Leaf/terminal node of a pattern tree
175             package Docopt::LeafPattern;
176 4     4   22 use parent -norequire, qw(Docopt::Pattern);
  4         14  
  4         31  
177              
178 4     4   210 use Docopt::Util qw(repl class_name True False is_number);
  4         7  
  4         308  
179              
180             use Class::Accessor::Lite (
181 4         33     rw => [qw(name)],
182 4     4   3794 );
  4         5272  
183              
184             sub value {
185 909     909   2975     my $self = shift;
186 909 100       4568     return $self->{value} if @_==0;
187 108 50       253     if (@_==1) {
188             # warn "SET: $_[0]";
189 108         242         $self->{value} = $_[0];
190                 } else {
191 0         0         Carp::confess("Too much arguments");
192                 }
193             }
194              
195             sub new {
196 502     502   34232     my ($class, $name, $value) = @_;
197 502         3593     bless {
198                     name => $name,
199                     value => $value,
200                 }, $class;
201             }
202              
203              
204             sub __repl__ {
205 25     25   37     my $self = shift;
206 25         64     sprintf '%s(%s, %s)',
207                     class_name($self),
208                     repl($self->name),
209                     repl($self->value);
210             }
211             sub flat {
212 2647     2647   3449     my ($self, $types) = @_;
213 2647 100 100     10222     if (!defined($types) || $self->isa($types)) {
214 2097         5395         return [$self];
215                 } else {
216 550         1348         return [];
217                 }
218             }
219             sub match {
220 543     543   778     my $self = shift;
221 543         759     my @left = @{+shift};
  543         1109  
222 543 100       635     my @collected = @{ +shift || +[] };
  543         1427  
223              
224 543         1638     my ($pos, $match) = $self->single_match(\@left);
225 543 100       1514     unless ($match) {
226 212         693         return (False, \@left, \@collected);
227                 }
228 331         1272     my @left_ = (@left[0..$pos-1], @left[$pos+1..@left-1]);
229 331         597     my @same_name = grep { $_->name eq $self->name } @collected;
  151         553  
230 331 100 100     1512     if (is_number($self->value) || ref($self->value) eq 'ARRAY') {
231 118         154         my $increment;
232 118 100       252         if (is_number($self->value)) {
233 60         82             $increment = 1;
234                     } else {
235 58 100       124             $increment = ref($match->value) eq 'ARRAY' ? $match->value : [$match->value];
236                     }
237 118 100       309         unless (@same_name) {
238             # warn "NO SAME: " . ' . ' . repl($self->value) . ' : ' . repl($increment);
239 64         140             $match->value($increment);
240 64         223             return (True, \@left_, [@collected, $match]);
241                     }
242 54 100       158         if (ref $same_name[0]->value eq 'ARRAY') {
243 23 50       39             $same_name[0]->value([@{$same_name[0]->value}, ref($increment) eq 'ARRAY' ? @$increment : $increment]);
  23         47  
244                     } else {
245 31 50       90             ref($increment) ne 'ARRAY' or Carp::confess("Invalid addition");
246 31         78             $same_name[0]->value($same_name[0]->value + $increment);
247                     }
248 54         202         return (True, \@left_, \@collected);
249                 }
250 213         798     return (True, \@left_, [@collected, $match]);
251             }
252              
253             package Docopt::BranchPattern;
254              
255 4     4   2550 use parent -norequire, qw(Docopt::Pattern);
  4         7  
  4         32  
256              
257 4     4   186 use Carp;
  4         15  
  4         471  
258              
259 4     4   22 use Docopt::Util qw(repl class_name);
  4         7  
  4         208  
260 4     4   20 use Scalar::Util qw(blessed);
  4         7  
  4         1858  
261              
262             sub new {
263 1554     1554   2752     my ($class, $children) = @_;
264 1554 50       3259     Carp::croak("Too much arguments") unless @_==2;
265 1554 50       3816     Carp::confess "Children must be arrayref: $class, $children" unless ref $children eq 'ARRAY';
266              
267             # zjzj FIXME ad-hoc hack
268 1554 50       2311     $children = [ map { ref($_) eq 'ARRAY' ? @$_ : $_ } @$children];
  2109         6082  
269              
270 1554         9202     bless {
271                     children => [@$children],
272                 }, $class;
273             }
274              
275             sub children {
276 9843     9843   33220     my $self = shift;
277 9843 100       43309     return $self->{children} if @_==0;
278 43 50       95     if (@_==1) {
279 43 50       113         ref($_[0]) eq 'ARRAY' or Carp::confess("Argument must be ArrayRef but: " . $_[0]);
280 43         174         $self->{children} = $_[0];
281                 } else {
282 0         0         Carp::confess("Too much arguments");
283                 }
284             }
285              
286             sub __repl__ {
287 90     90   760     my $self = shift;
288 112         1800     sprintf '%s(%s)',
289                     class_name($self),
290 90         222         join(', ', map { repl($_) } @{$self->{children}});
  90         226  
291             }
292              
293             sub flat {
294 4179     4179   5065     my $self = shift;
295 4179         4542     my $types = shift;
296 4179 100 100     16341     if (defined($types) && $self->isa($types)) {
297 44         123         return [$self];
298                 }
299 4135 50       4146     my @ret = map { ref($_) eq 'ARRAY' ? @$_ : $_ } map { $_->flat($types) } @{$self->children};
  5420         14131  
  5420         10380  
  4135         7208  
300 4135         11170     return \@ret;
301             # if type(self) in types:
302             # return [self]
303             # return sum([child.flat(*types) for child in self.children], [])
304             }
305              
306             package Docopt::Argument;
307 4     4   25 use parent -norequire, qw(Docopt::LeafPattern);
  4         7  
  4         29  
308              
309             sub single_match {
310 167     167   244     my ($self, $left) = @_;
311 167 50       457     ref $left eq 'ARRAY' or die;
312              
313 167         467     for (my $n=0; $n<@$left; $n++) {
314 127         180         my $pattern = $left->[$n];
315 127 100       703         if ($pattern->isa(Docopt::Argument::)) {
316 108         340             return ($n, Docopt::Argument->new($self->name, $pattern->value));
317                     }
318                 }
319 59         142     return (undef, undef);
320             }
321              
322             sub parse {
323 0     0   0     my ($class, $source) = @_;
324 0         0     $source =~ /(<\S*?>)/;
325 0         0     my $name = $1;
326 0         0     $source =~ /\[default: (.*)\]/i;
327 0         0     my $value = $1;
328 0         0     return $class->new($name, $value);
329             }
330              
331             package Docopt::Command;
332 4     4   1092 use parent -norequire, qw(Docopt::Argument);
  4         13  
  4         95  
333              
334             use Class::Accessor::Lite (
335 4         28     rw => [qw(name value)]
336 4     4   174 );
  4         8  
337 4     4   579 use boolean;
  4         7  
  4         30  
338              
339             sub new {
340 86     86   4408     my ($class, $name, $value) = @_;
341 86         536     bless {
342                     name => $name,
343                     value => $value,
344                 }, $class;
345             }
346              
347             sub single_match {
348 48     48   74     my ($self, $left) = @_;
349 48 50       121     ref $left eq 'ARRAY' or die;
350              
351 48         131     for (my $n=0; $n<@$left; $n++) {
352 42         55         my $pattern = $left->[$n];
353 42 100       172         if ($pattern->isa(Docopt::Argument::)) {
354 39 100       83             if ($pattern->value eq $self->name) {
355 30         209                 return ($n, Docopt::Command->new($self->name, true));
356                         } else {
357 9         58                 last;
358                         }
359                     }
360                 }
361 18         47     return (undef, undef);
362             }
363              
364             package Docopt::Required;
365              
366 4     4   1071 use parent -norequire, qw(Docopt::BranchPattern);
  4         7  
  4         25  
367 4     4   162 use boolean;
  4         13  
  4         25  
368              
369             sub match {
370 512     512   833     my ($self, $left, $collected) = @_;
371 512   100     1700     $collected ||= [];
372              
373 512         618     my $l = $left;
374 512         676     my $c = $collected;
375 512         633     for my $pattern (@{$self->children}) {
  512         978  
376 595         1214         my $matched;
377 595         1503         ($matched, $l, $c) = $pattern->match($l, $c);
378 595 100       3657         unless ($matched) {
379 75 50       584             ref($c) eq 'ARRAY' or Carp::confess("c is not arrayref");
380 75         179             return (false, $left, $collected);
381                     }
382                 }
383 437 50       4144     ref($c) eq 'ARRAY' or Carp::confess("c is not arrayref: " . join(', ', @{$self->children}));
  0         0  
384 437         918     return (true, $l, $c);
385              
386                 
387             # def match(self, left, collected=None):
388             # collected = [] if collected is None else collected
389             # l = left
390             # c = collected
391             # for pattern in self.children:
392             # matched, l, c = pattern.match(l, c)
393             # if not matched:
394             # return False, left, collected
395             # return True, l, c
396             }
397              
398             package Docopt::Optional;
399              
400 4     4   962 use parent -norequire, qw(Docopt::BranchPattern);
  4         8  
  4         18  
401              
402 4     4   162 use boolean;
  4         6  
  4         14  
403              
404             sub match {
405 234     234   369     my ($self, $left, $collected) = @_;
406 234   100     505     $collected ||= [];
407 234 50       631     ref($collected) eq 'ARRAY' or Carp::confess("collected is not arrayref: " . join(', ', @{$self->children}));
  0         0  
408              
409 234         260     my $m;
410 234         309     for my $pattern (@{$self->children}) {
  234         498  
411 295         1193         ($m, $left, $collected) = $pattern->match($left, $collected);
412                 }
413 234 50       1973     ref($collected) eq 'ARRAY' or Carp::confess("collected is not arrayref: " . join(', ', @{$self->children}));
  0         0  
414 234         555     return (true, $left, $collected);
415              
416             # def match(self, left, collected=None):
417             # collected = [] if collected is None else collected
418             # for pattern in self.children:
419             # m, left, collected = pattern.match(left, collected)
420             # return True, left, collected
421             }
422              
423             package Docopt::OptionsShortcut;
424             # Marker/placeholder for [options] shortcut.
425              
426 4     4   992 use parent -norequire, qw(Docopt::Optional);
  4         6  
  4         19  
427              
428             package Docopt::OneOrMore;
429              
430 4     4   232 use parent -norequire, qw(Docopt::BranchPattern);
  4         7  
  4         20  
431 4     4   172 use boolean;
  4         14  
  4         26  
432 4     4   266 use Storable;
  4         11  
  4         233  
433 4     4   20 use Docopt::Util qw(serialize);
  4         7  
  4         3610  
434              
435             sub match {
436 45     45   87     my ($self, $left, $collected) = @_;
437 45 50       60     @{$self->children} == 1 or die;
  45         100  
438 45   100     135     $collected ||= [];
439              
440 45         58     my $l = $left;
441 45         53     my $c = $collected;
442 45         68     my $l_ = undef;
443 45         140     my $matched = true;
444 45         126     my $times = 0;
445              
446 45         132     while ($matched) {
447             # could it be that something didn't match but changed l or c?
448 115         887         ($matched, $l, $c) = $self->children->[0]->match($l, $c);
449 115 100       771         $times++ if $matched;
450 115 100       972         if (serialize(\$l_) eq serialize(\$l)) {
451 36         784             last;
452                     }
453 79         3232         $l_ = $l;
454                 }
455 45 100       173     if ($times >= 1) {
456 36         91         return (true, $l, $c);
457                 }
458 9         25     return (false, $left, $collected);
459              
460             # def match(self, left, collected=None):
461             # assert len(self.children) == 1
462             # collected = [] if collected is None else collected
463             # l = left
464             # c = collected
465             # l_ = None
466             # matched = True
467             # times = 0
468             # while matched:
469             # # could it be that something didn't match but changed l or c?
470             # matched, l, c = self.children[0].match(l, c)
471             # times += 1 if matched else 0
472             # if l_ == l:
473             # break
474             # l_ = l
475             # if times >= 1:
476             # return True, l, c
477             # return False, left, collected
478             }
479              
480             package Docopt::Either;
481              
482 4     4   27 use parent -norequire, qw(Docopt::BranchPattern);
  4         13  
  4         21  
483 4     4   148 use boolean;
  4         7  
  4         17  
484              
485             sub match {
486 55     55   96     my ($self, $left, $collected) = @_;
487 55   100     149     $collected ||= [];
488 55         72     my @outcomes;
489 55         67     for my $pattern (@{$self->children}) {
  55         111  
490 124         507         my @outcome = $pattern->match($left, $collected);
491 124         652         my $matched = $outcome[0];
492 124 100       310         if ($matched) {
493 62         517             push @outcomes, \@outcome;
494                     }
495                 }
496 55 100       406     if (@outcomes) {
497 46         70         my $retval = shift @outcomes;
498 46         102         for (@outcomes) {
499 16 100       20             if (@{$_->[1]} < @{$retval->[1]}) {
  16         32  
  16         51  
500 10         38                 $retval = $_;
501                         }
502                     }
503 46         208         return @$retval;
504                 }
505 9         23     return (false, $left, $collected);
506              
507             # def match(self, left, collected=None):
508             # collected = [] if collected is None else collected
509             # outcomes = []
510             # for pattern in self.children:
511             # matched, _, _ = outcome = pattern.match(left, collected)
512             # if matched:
513             # outcomes.append(outcome)
514             # if outcomes:
515             # return min(outcomes, key=lambda outcome: len(outcome[1]))
516             # return False, left, collected
517             }
518              
519             package Docopt::Tokens;
520              
521 4     4   1014 use Docopt::Util qw(repl);
  4         7  
  4         197  
522             use Class::Accessor::Lite 0.05 (
523 4         28     rw => [qw(error source)],
524 4     4   20 );
  4         133  
525              
526             sub new {
527 480     480   851     my ($class, $source, $error) = @_;
528 480   100     1396     $error ||= 'Docopt::Exceptions::DocoptExit';
529              
530 480 100       1006     unless (ref $source) {
531 49         162         $source = [split /\s+/, $source];
532                 }
533 480         3525     bless {source => [@$source], error => $error}, $class;
534             }
535              
536             sub from_pattern {
537 248     248   2278     my ($class, $source) = @_;
538              
539 248         5865     $source =~ s/([\[\]\(\)\|]|\.\.\.)/ $1 /g;
540 248 100       2832     my @source = grep { defined($_) && length $_ > 0 } split /\s+|(\S*<.*?>)/, $source;
  3565         11754  
541 248         1001     return Docopt::Tokens->new(\@source, 'Docopt::Exceptions::DocoptLanguageError');
542             }
543              
544             sub move {
545 1834     1834   2376     my $self = shift;
546 1834         1887     shift @{$self->{source}};
  1834         5773  
547             }
548              
549             sub current {
550 7397     7397   18748     my $self = shift;
551 7397         16563     $self->source->[0];
552             }
553              
554             sub __repl__ {
555 3     3   4     my $self = shift;
556 3         7     '[' . join(', ', map { repl($_) } @{$self->source}) . ']';
  22         951  
  3         13  
557             }
558              
559              
560             package Docopt;
561              
562             our $VERSION = "0.03";
563              
564             package Docopt::Option;
565              
566 4     4   1757 use parent -norequire, qw(Docopt::LeafPattern);
  4         6  
  4         30  
567              
568 4     4   194 use Docopt::Util qw(repl string_strip string_partition defined_or);
  4         12  
  4         291  
569              
570             use Class::Accessor::Lite 0.05 (
571 4         30     rw => [qw(short long argcount)],
572 4     4   21 );
  4         66  
573              
574             sub new {
575 968     968   65713     my ($class, $short, $long, $argcount, $value) = @_;
576 968 100       2433     if (@_<= 3) { $argcount = 0 }
  203         267  
577              
578 968 100 100     10406     return bless {
579                     short => $short,
580                     long => $long,
581                     argcount => $argcount,
582                     value => !defined($value) && $argcount ? undef : $value,
583                 }, $class;
584             }
585              
586             sub value {
587 1540     1540   6506     my $self = shift;
588 1540 100       7111     return $self->{value} if @_==0;
589 320 50       577     if (@_==1) {
590             # Carp::cluck("SET: $_[0], $self->{long}, $self->{value}") if $_[0] eq 1;
591 320         764         $self->{value} = $_[0];
592                 } else {
593 0         0         Carp::confess("Too much arguments");
594                 }
595             }
596              
597              
598             sub single_match {
599 328     328   440     my ($self, $left) = @_;
600 328 50       830     ref $left eq 'ARRAY' or die;
601              
602 328         938     for (my $n=0; $n<@$left; $n++) {
603 308         498         my $pattern = $left->[$n];
604 308 100       642         if ($self->name eq defined_or($pattern->name, '')) {
605 193         504             return ($n, $pattern);
606                     }
607                 }
608 135         275     return (undef, undef);
609             }
610              
611             sub name {
612 1255     1255   3012     my $self = shift;
613 1255 100 100     3057     if (defined($self->long) && !ref($self->long)) {
614 401         4940         $self->long;
615                 } else {
616 854         5741         $self->short;
617                 }
618             }
619              
620             sub parse {
621 257     257   21938     my ($class, $option_description) = @_;
622 257         430     my ($short, $long, $argcount, $value) = (undef, undef, 0, undef);
623              
624 257         655     my ($options, undef, $description) = string_partition(string_strip($option_description), ' ');
625              
626 257         570     $options =~ s/,/ /g;
627 257         406     $options =~ s/=/ /g;
628 257         650     for my $s (split /\s+/, $options) {
629 347 100       1193         if ($s =~ /^--/) {
    100          
630 99         232             $long = $s;
631                     } elsif ($s =~ /^-/) {
632 179         420             $short = $s;
633                     } else {
634 69         151             $argcount = 1;
635                     }
636                 }
637 257 100       606     if ($argcount) {
638 65 100 66     938         if (defined($description) && $description =~ /\[default: (.*)\]/i) {
639 19         39             $value = $1;
640                     }
641                 }
642 257         809     return $class->new($short, $long, $argcount, $value);
643             }
644              
645             sub __repl__ {
646 27     27   1328     my ($self) = @_;
647 27         99     sprintf 'Option(%s, %s, %s, %s)',
648                     repl($self->{short}),
649                     repl($self->{long}),
650                     repl($self->{argcount}),
651                     repl($self->{value});
652             }
653              
654             package Docopt;
655              
656 4     4   2831 use boolean;
  4         7  
  4         24  
657              
658             # long ::= '--' chars [ ( ' ' | '=' ) chars ] ;
659             sub parse_long {
660 147     147 0 219     my ($tokens, $options) = @_;
661 147 50       365     ref($options) eq 'ARRAY' or Carp::confess "Options must be arrayref";
662              
663 147         324     my ($long, $eq, $value) = string_partition($tokens->move, '=');
664 147 50       703     $long =~ /\A--/ or die;
665 147 100 66     614     $value = $eq eq '' && $value eq '' ? undef : $value;
666 147 100       287     my @similar = grep { $_->long && $_->long eq $long } @$options;
  209         1576  
667 147 100 100     1640     if ($tokens->error eq 'Docopt::Exceptions::DocoptExit' && @similar == 0) { # if no exact match
668 18 100       146         @similar = grep { $_->long && $_->long =~ /$long/ } @$options;
  26         171  
669                 }
670 147         1103     my $o;
671 147 100       447     if (@similar > 1) { # might be simply specified ambiguously 2+ times?
    100          
672 6         57         $tokens->error->throw(sprintf '%s is not a unique prefix: %s?',
673 3         12             $long, join(', ', map { $_->long } @similar));
674                 } elsif (@similar < 1) {
675 48 100       122         my $argcount = $eq eq '=' ? 1 : 0;
676 48         170         $o = Docopt::Option->new(undef, $long, $argcount);
677 48         90         push @$options, $o;
678 48 100       127         if ($tokens->error eq 'Docopt::Exceptions::DocoptExit') {
679 10 100       76             $o = Docopt::Option->new(undef, $long, $argcount, $argcount ? $value : true);
680                     }
681                 } else {
682 96         313         $o = Docopt::Option->new(
683                         $similar[0]->short,
684                         $similar[0]->long,
685                         $similar[0]->argcount,
686                         $similar[0]->value,
687                     );
688 96 100       383         if ($o->argcount == 0) {
689 62 100       387             if (defined $value) {
690 3         12                 $tokens->error->throw(sprintf "%s must not have an argument", $o->long);
691                         }
692                     } else {
693 34 100       243             if (not defined $value) {
694 20 100 100     47                 if (
695                                 (not defined $tokens->current() ) || $tokens->current eq '--') {
696 3         25                     $tokens->error->throw(sprintf "%s requires argument", $o->long);
697                             }
698 17         149                 $value = $tokens->move;
699                         }
700                     }
701 90 100       256         if ($tokens->error eq 'Docopt::Exceptions::DocoptExit') {
702 57 100       406             $o->value(defined($value) ? $value : true);
703                     }
704                 }
705 138         912     return [$o];
706              
707             # long, eq, value = tokens.move().partition('=')
708             # assert long.startswith('--')
709             # value = None if eq == value == '' else value
710             # similar = [o for o in options if o.long == long]
711             # if tokens.error is DocoptExit and similar == []: # if no exact match
712             # similar = [o for o in options if o.long and o.long.startswith(long)]
713             # if len(similar) > 1: # might be simply specified ambiguously 2+ times?
714             # raise tokens.error('%s is not a unique prefix: %s?' %
715             # (long, ', '.join(o.long for o in similar)))
716             # elif len(similar) < 1:
717             # argcount = 1 if eq == '=' else 0
718             # o = Option(None, long, argcount)
719             # options.append(o)
720             # if tokens.error is DocoptExit:
721             # o = Option(None, long, argcount, value if argcount else True)
722             # else:
723             # o = Option(similar[0].short, similar[0].long,
724             # similar[0].argcount, similar[0].value)
725             # if o.argcount == 0:
726             # if value is not None:
727             # raise tokens.error('%s must not have an argument' % o.long)
728             # else:
729             # if value is None:
730             # if tokens.current() in [None, '--']:
731             # raise tokens.error('%s requires argument' % o.long)
732             # value = tokens.move()
733             # if tokens.error is DocoptExit:
734             # o.value = value if value is not None else True
735             # return [o]
736             }
737              
738             # shorts ::= '-' ( chars )* [ [ ' ' ] chars ] ;
739             sub parse_shorts {
740 235     235 0 340     my ($tokens, $options) = @_;
741              
742 235         423     my $token = $tokens->move;
743 235         786     (my $left = $token) =~ s/^-//;
744 235         317     my @parsed;
745 235         512     while ($left ne '') {
746 307         300         my $o;
747 307         955         $left =~ s/\A(.)//;
748 307         682         my $short = '-' . $1;
749 307         637         my @similar = grep { defined_or($_->short, '') eq $short } @$options;
  519         1346  
750 307 100       1009         if (@similar > 1) {
    100          
751 1         5             $tokens->error->throw(sprintf "%s is specified ambiguously %d times",
752                             $short, 0+@similar);
753                     } elsif (@similar < 1) {
754 45         160             $o = Docopt::Option->new($short, undef, 0);
755 45         95             push @$options, $o;
756 45 100       143             if ($tokens->error eq 'Docopt::Exceptions::DocoptExit') {
757 5         45                 $o = Docopt::Option->new($short, undef, 0, undef)
758                         }
759                     } else {
760             # why copying is necessary here?
761 261         732             $o = Docopt::Option->new($short, $similar[0]->long,
762                             $similar[0]->argcount, $similar[0]->value);
763 261         615             my $value = undef;
764 261 100       641             if ($o->argcount != 0) {
765 28 100       164                 if ($left eq '') {
766 20 100 100     42                     if (!defined($tokens->current) || $tokens->current eq '--') {
767 2         19                         $tokens->error->throw("$short requires argument");
768                                 }
769 18         171                     $value = $tokens->move;
770                             } else {
771 8         15                     $value = $left;
772 8         15                     $left = '';
773                             }
774                         }
775 259 100       1643             if ($tokens->error eq 'Docopt::Exceptions::DocoptExit') {
776 127 100       852                 $o->value(defined($value) ? $value : true);
777                         }
778                     }
779 304         2075         push @parsed, $o;
780                 }
781 232         877     return \@parsed;
782              
783             # def parse_shorts(tokens, options):
784             # token = tokens.move()
785             # assert token.startswith('-') and not token.startswith('--')
786             # left = token.lstrip('-')
787             # parsed = []
788             # while left != '':
789             # short, left = '-' + left[0], left[1:]
790             # similar = [o for o in options if o.short == short]
791             # if len(similar) > 1:
792             # raise tokens.error('%s is specified ambiguously %d times' %
793             # (short, len(similar)))
794             # elif len(similar) < 1:
795             # o = Option(short, None, 0)
796             # options.append(o)
797             # if tokens.error is DocoptExit:
798             # o = Option(short, None, 0, True)
799             # else: # why copying is necessary here?
800             # o = Option(short, similar[0].long,
801             # similar[0].argcount, similar[0].value)
802             # value = None
803             # if o.argcount != 0:
804             # if left == '':
805             # if tokens.current() in [None, '--']:
806             # raise tokens.error('%s requires argument' % short)
807             # value = tokens.move()
808             # else:
809             # value = left
810             # left = ''
811             # if tokens.error is DocoptExit:
812             # o.value = value if value is not None else True
813             # parsed.append(o)
814             # return parsed
815             }
816 4     4   3885 use Docopt::Util qw(repl);
  4         9  
  4         7021  
817              
818             sub parse_pattern {
819 245     245 0 527     my ($source, $options) = @_;
820 245         910     my $tokens = Docopt::Tokens->from_pattern($source);
821 245         910     my $result = parse_expr($tokens, $options);
822 240 100       596     if (defined $tokens->current()) {
823 1         10         $tokens->error->throw("unexpected ending: " . repl(join(' ', $tokens)));
824                 }
825 239         1781     return Docopt::Required->new($result);
826              
827             # def parse_pattern(source, options):
828             # tokens = Tokens.from_pattern(source)
829             # result = parse_expr(tokens, options)
830             # if tokens.current() is not None:
831             # raise tokens.error('unexpected ending: %r' % ' '.join(tokens))
832             # return Required(*result)
833             }
834              
835             # $tokens: Docopt::Tokens
836             # $options: ARRAY
837             sub parse_expr {
838             # expr ::= seq ( '|' seq )* ;
839 729     729 0 955     my ($tokens, $options) = @_;
840              
841 729         1352     my $seq = parse_seq($tokens, $options);
842 721 100 100     1723     if (!defined($tokens->current) || $tokens->current ne '|') {
843 662         5286         return $seq;
844                 }
845              
846             # result = [Required(*seq)] if len(seq) > 1 else seq
847 59 100       607     my @result = @$seq > 1 ? Docopt::Required->new($seq) : @$seq;
848 59   100     138     while (defined($tokens->current) && $tokens->current eq '|') {
849 73         575         $tokens->move();
850 73         148         $seq = parse_seq($tokens, $options);
851 73 100       304         push @result, @$seq > 1 ? Docopt::Required->new($seq) : @$seq;
852                 }
853             # zjzj This map() is so bad. But i can't remove this correctly...
854 59 50       526     return @result > 1 ? [Docopt::Either->new([map { ref($_) eq 'ARRAY' ? @$_ : $_ } @result])] : \@result;
  132 50       470  
855              
856             # seq = parse_seq(tokens, options)
857             # if tokens.current() != '|':
858             # return seq
859             # result = [Required(*seq)] if len(seq) > 1 else seq
860             # while tokens.current() == '|':
861             # tokens.move()
862             # seq = parse_seq(tokens, options)
863             # result += [Required(*seq)] if len(seq) > 1 else seq
864             # return [Either(*result)] if len(result) > 1 else result
865             }
866              
867             # seq ::= ( atom [ '...' ] )* ;
868             sub parse_seq {
869 802     802 0 1014     my ($tokens, $options) = @_;
870 802         848     my @result;
871 802         4700     while (not in($tokens->current, [undef, ']', ')', '|'])) {
872 930         2545         my $atom = parse_atom($tokens, $options);
873 922 100 100     1896         if (defined($tokens->current) && $tokens->current eq '...') {
874 39         358             $atom = Docopt::OneOrMore->new($atom);
875 39         104             $tokens->move;
876                     }
877 922         7529         push @result, $atom;
878                 }
879 794 100       2319     return [map { ref($_) eq 'ARRAY' ? @$_ : $_ } @result];
  922         3898  
880             # def parse_seq(tokens, options):
881             # """seq ::= ( atom [ '...' ] )* ;"""
882             # result = []
883             # while tokens.current() not in [None, ']', ')', '|']:
884             # atom = parse_atom(tokens, options)
885             # if tokens.current() == '...':
886             # atom = [OneOrMore(*atom)]
887             # tokens.move()
888             # result += atom
889             # return result
890             }
891              
892             # atom ::= '(' expr ')' | '[' expr ']' | 'options'
893             # | long | shorts | argument | command ;
894             sub parse_atom {
895 930     930 0 1260     my ($tokens, $options) = @_;
896              
897 930         1609     my $token = $tokens->current();
898 930         4600     my @result;
899 930 100 100     7539     if ($token eq '(' || $token eq '[') {
    100 100        
    100 100        
    100 66        
    100 66        
      100        
900 484         1158         $tokens->move;
901 484         653         my ($matching, $pattern) = @{{
  484         2528  
902                         '(' => [')', Docopt::Required::],
903                         '[' => [']', Docopt::Optional::]
904                     }->{$token}};
905 484         9438         my $expr = parse_expr($tokens, $options);
906 481         1470         my $result = $pattern->new($expr);
907 481 100 100     1019         if (($tokens->move ||'') ne $matching) {
908 3         26             Docopt::Exceptions::DocoptLanguageError->throw("unmatched '$token'");
909                     }
910 478         1577         return [$result];
911                 } elsif ($token eq 'options') {
912 49         99         $tokens->move;
913 49         190         return [Docopt::OptionsShortcut->new([])];
914                 } elsif ($token =~ /^--/ && $token ne '--') {
915 72         214         return parse_long($tokens, $options);
916                 } elsif ($token =~ /^-/ && ($token ne '-' && $token ne '--')) {
917 135         397         return parse_shorts($tokens, $options);
918                 } elsif (($token =~ /^</ && $token =~ />$/) or $token =~ /\A[A-Z]+\z/) {
919 142         498         return [Docopt::Argument->new($tokens->move)];
920                 } else {
921 48         113         return [Docopt::Command->new($tokens->move)];
922                 }
923              
924             # token = tokens.current()
925             # result = []
926             # if token in '([':
927             # tokens.move()
928             # matching, pattern = {'(': [')', Required], '[': [']', Optional]}[token]
929             # result = pattern(*parse_expr(tokens, options))
930             # if tokens.move() != matching:
931             # raise tokens.error("unmatched '%s'" % token)
932             # return [result]
933             # elif token == 'options':
934             # tokens.move()
935             # return [OptionsShortcut()]
936             # elif token.startswith('--') and token != '--':
937             # return parse_long(tokens, options)
938             # elif token.startswith('-') and token not in ('-', '--'):
939             # return parse_shorts(tokens, options)
940             # elif token.startswith('<') and token.endswith('>') or token.isupper():
941             # return [Argument(tokens.move())]
942             # else:
943             # return [Command(tokens.move())]
944             }
945              
946             # Parse command-line argument vector.
947             #
948             # If options_first:
949             # argv ::= [ long | shorts ]* [ argument ]* [ '--' [ argument ]* ] ;
950             # else:
951             # argv ::= [ long | shorts | argument ]* [ '--' [ argument ]* ] ;
952             sub parse_argv {
953 232     232 0 367     my ($tokens, $options, $options_first) = @_;
954 232 50       523     ref($options) eq 'ARRAY' or Carp::confess "Options must be arrayref";
955              
956 232         262     my @parsed;
957 232         549     while (defined $tokens->current()) {
958 280 100 100     2067         if ($tokens->current() eq '--') {
    100          
    100          
    100          
959 3         19             return [@parsed, map { Docopt::Argument->new(undef, $_) } @{$tokens->source}];
  6         24  
  3         10  
960                     } elsif ($tokens->current() =~ /\A--/) {
961 75         519             push @parsed, @{parse_long($tokens, $options)};
  75         155  
962                     } elsif ($tokens->current() =~ /\A-/ && $tokens->current ne '-') {
963 100         671             push @parsed, @{parse_shorts($tokens, $options)};
  100         230  
964                     } elsif ($options_first) {
965 1         15             return [@parsed, map { Docopt::Argument->new(undef, $_) } @{$tokens->source}];
  3         11  
  1         4  
966                     } else {
967 101         813             push @parsed, Docopt::Argument->new(undef, $tokens->move);
968                     }
969                 }
970 218         1640     return \@parsed;
971             }
972              
973             sub parse_defaults {
974 275     275 0 1909     my ($doc) = @_;
975              
976 275         310     my @defaults;
977              
978 275         557     for my $s (parse_section('options:', $doc)) {
979             # FIXME corner case "bla: options: --foo"
980 151         538         (undef, undef, $s) = string_partition($s, ':');
981 151         1367         my @split = split /\n *(-\S+?)/, "\n" . $s;
982 151         242         shift @split;
983 151         223         my @split2;
984 151         434         for (my $i=0; $i<@split; $i+=2) {
985 240         768             push @split2, $split[$i].defined_or($split[$i+1], '');
986                     }
987             # options = [Option.parse(s) for s in split if s.startswith('-')]
988 151         676         for my $s (grep /^-/, @split2) {
989 240         708             push @defaults, Docopt::Option->parse($s);
990                     }
991                 }
992 275         901     return @defaults;
993             }
994              
995             sub parse_section {
996 514     514 0 14017     my ($name, $source) = @_;
997 514 50       976     defined($source) or Carp::confess("Missing source");
998 514         582     my @s;
999 514         21755     while ($source =~ /^([^\n]*${name}[^\n]*\n?(?:[ \t].*?(?:\n|$))*)/img) {
1000 396         1460         local $_ = $1;
1001 396         853         s/\A\s+//;
1002 396         1574         s/\s+\z//;
1003 396         2754         push @s, $_;
1004                 }
1005 514         1827     return @s;
1006             }
1007              
1008             sub formal_usage {
1009 235     235 0 6478     my ($section) = @_;
1010             # _, _, section = section.partition(':') # drop "usage:"
1011 235         964     (undef, undef, $section) = string_partition($section, ':');
1012 235         1198     my @pu = grep { /\S/ } split /\s+/, $section;
  985         2745  
1013 235         485     my $cmd = shift @pu;
1014 235 100       463     return '( ' . join(' ', map { $_ eq $cmd ? ') | (' : $_ } @pu) . ' )';
  516         2044  
1015             }
1016              
1017              
1018 4     4   30 use List::MoreUtils qw(any);
  4         8  
  4         3337  
1019             sub extras {
1020 215     215 0 382     my ($help, $version, $options, $doc) = @_;
1021 215 100 66 293   991     if ($help && any { in($_->name, ['-h', '--help']) && $_->value } @$options) {
  293 100       3266  
1022 2         924         print $doc . "\n";
1023 2         12         exit(0);
1024                 }
1025 213 0 33     1966     if ($version && grep { defined($_->name) && $_->name eq '--version' } @$options) {
  0 50       0  
1026 0         0         print "$version\n";
1027 0         0         exit(0);
1028                 }
1029              
1030             #ef extras(help, version, options, doc):
1031             # if help and any((o.name in ('-h', '--help')) and o.value for o in options):
1032             # print(doc.strip("\n"))
1033             # sys.exit()
1034             # if version and any(o.name == '--version' and o.value for o in options):
1035             # print(version)
1036             # sys.exit()
1037             }
1038              
1039             sub docopt {
1040             # def docopt(doc, argv=None, help=True, version=None, options_first=False):
1041 233 50   233 1 93706     @_%2==0 or Carp::confess("You need to pass arguments are hash");
1042              
1043 233         1537     my %args = @_;
1044              
1045 233         631     my $doc = delete $args{doc};
1046 233   100     829     my $argv = delete $args{argv} || \@ARGV;
1047 233 50       1095     my $help = exists($args{help}) ? delete $args{help} : true;
1048 233         823     my $version = delete $args{version};
1049 233         449     my $option_first = delete $args{option_first};
1050              
1051 233 50       713     if (%args) {
1052 0         0         Carp::confess("Unknown argument passed to docopt(): " . join(", ", keys %args));
1053                 }
1054              
1055 233 50       697     if (not defined $doc) {
1056             # Should I selecte 'SYNOPSIS' section?
1057 0         0         require Pod::Usage;
1058             # require Pod::Simple::Text;
1059              
1060 0 0       0         open my $fh, '>', \$doc
1061                         or die $!;
1062 0         0         my $parser = Pod::Usage->new(USAGE_OPTIONS => +{});
1063 0         0         $parser->select('(?:SYNOPSIS|USAGE)\s*');
1064 0         0         $parser->parse_from_file($0, $fh);
1065             # my $parser = Pod::Simple::Text->new();
1066             # $parser->{output_fh} = $fh;
1067             # $parser->parse_file($0);
1068                 }
1069              
1070 233         954     my @usage_sections = parse_section('usage:', $doc);
1071 233 100       738     if (@usage_sections == 0) {
1072 1         6         Docopt::Exceptions::DocoptLanguageError->throw('"usage:" (case-insensitive) not found.');
1073                 }
1074 232 100       673     if (@usage_sections > 1) {
1075 1         5         Docopt::Exceptions::DocoptLanguageError->throw('More than one "usage:" (case-insensitive).');
1076                 }
1077 231         399     $Docopt::Exceptions::DocoptExit::USAGE = $usage_sections[0];
1078              
1079 231         713     my $options = [parse_defaults($doc)];
1080 231         807     my $pattern = parse_pattern(formal_usage($usage_sections[0]), $options);
1081             # pyprint($pattern);
1082             # [default] syntax for argument is disabled
1083             #for a in pattern.flat(Argument):
1084             # same_name = [d for d in arguments if d.name == a.name]
1085             # if same_name:
1086             # a.value = same_name[0].value
1087             # pyprint($argv);
1088 225         753     $argv = parse_argv(Docopt::Tokens->new($argv), $options, $option_first);
1089 215         812     my $parse_options = $pattern->flat(Docopt::Option::);
1090 215         387     for my $options_shortcut (@{$pattern->flat(Docopt::OptionsShortcut::)}) {
  215         429  
1091 43         85         my @doc_options = parse_defaults($doc);
1092 43         92         $options_shortcut->children([grep { !in(serialize($_), [map { serialize($_) } @$parse_options]) } @doc_options]);
  59         162  
  9         548  
1093             # pyprint($options_shortcut);
1094              
1095             #if any_options:
1096             # options_shortcut.children += [Option(o.short, o.long, o.argcount)
1097             # for o in argv if type(o) is Option]
1098                 }
1099 215         638     extras($help, $version, $argv, $doc);
1100             #pyprint($pattern->fix);
1101             # pyprint($argv);
1102 213         582     my ($matched, $left, $collected) = $pattern->fix->match($argv);
1103             #pyprint([$matched, $left, $collected]);
1104 213 100 100     1063     if ($matched && serialize($left) eq serialize([])) { # better error message if left?
1105                     return +{
1106 539         1430             map {
1107 173         466                 $_->name => $_->value
1108 173         3631             } @{$pattern->flat}, @$collected
1109                     };
1110                 }
1111 40         794     Docopt::Exceptions::DocoptExit->throw();
1112              
1113             # argv = parse_argv(Tokens(argv), list(options), options_first)
1114             # pattern_options = set(pattern.flat(Option))
1115             # for options_shortcut in pattern.flat(OptionsShortcut):
1116             # doc_options = parse_defaults(doc)
1117             # options_shortcut.children = list(set(doc_options) - pattern_options)
1118             # #if any_options:
1119             # # options_shortcut.children += [Option(o.short, o.long, o.argcount)
1120             # # for o in argv if type(o) is Option]
1121             # extras(help, version, argv, doc)
1122             # matched, left, collected = pattern.fix().match(argv)
1123             # if matched and left == []: # better error message if left?
1124             # return Dict((a.name, a.value) for a in (pattern.flat() + collected))
1125             # raise DocoptExit()
1126             }
1127              
1128             package Docopt::Exception;
1129              
1130             use overload (
1131 4         47     q{""} => 'stringify',
1132 4     4   30 );
  4         9  
1133              
1134             sub stringify {
1135 8     8   175     my $self = shift;
1136 8   50     97     sprintf "[%s] %s", ref $self, $self->{message} || 'Died';
1137             }
1138              
1139             sub new {
1140 58     58   82     my ($class, $message) = @_;
1141 58         1028     bless {message => $message}, $class;
1142             }
1143             sub throw {
1144 58     58   309     my ($class, $message) = @_;
1145 58         190     die $class->new($message);
1146             }
1147              
1148             package Docopt::Exceptions::DocoptLanguageError;
1149 4     4   724 use parent -norequire, qw(Docopt::Exception);
  4         6  
  4         27  
1150              
1151             package Docopt::Exceptions::DocoptExit;
1152 4     4   296 use parent -norequire, qw(Docopt::Exception);
  4         8  
  4         22  
1153              
1154             our $USAGE;
1155              
1156             sub stringify {
1157 83     83   902     my $self = shift;
1158 83   100     943     sprintf "%s\n%s\n", $self->{message} || '', $USAGE;
1159             }
1160              
1161             1;
1162             __END__
1163            
1164             =for stopwords kn docopt parens docopt-py
1165            
1166             =encoding utf-8
1167            
1168             =head1 NAME
1169            
1170             Docopt - Command-line interface description language
1171            
1172             =head1 SYNOPSIS
1173            
1174             use Docopt;
1175            
1176             my $opts = docopt();
1177             ...
1178            
1179             __END__
1180            
1181             =head1 SYNOPSIS
1182            
1183             log-aggregate [--date=<ymd>]
1184            
1185             =head1 DESCRIPTION
1186            
1187             B<Docopt.pm is still under development. I may change interface without notice.>
1188            
1189             Docopt is command-line interface description language.
1190            
1191             docopt helps you:
1192            
1193             =over 4
1194            
1195             =item define interface for your command-line app, and
1196            
1197             =item automatically generate parser for it.
1198            
1199             =back
1200            
1201             docopt is based on conventions that are used for decades in help messages and man pages for program interface description. Interface description in docopt is such a help message, but formalized. Here is an example:
1202            
1203             Naval Fate.
1204            
1205             Usage:
1206             naval_fate ship new <name>...
1207             naval_fate ship <name> move <x> <y> [--speed=<kn>]
1208             naval_fate ship shoot <x> <y>
1209             naval_fate mine (set|remove) <x> <y> [--moored|--drifting]
1210             naval_fate -h | --help
1211             naval_fate --version
1212            
1213             Options:
1214             -h --help Show this screen.
1215             --version Show version.
1216             --speed=<kn> Speed in knots [default: 10].
1217             --moored Moored (anchored) mine.
1218             --drifting Drifting mine.
1219            
1220             The example describes interface of executable naval_fate, which can be invoked with different combinations of commands (ship, new, move, etc.), options (-h, --help, --speed=<kn>, etc.) and positional arguments (<name>, <x>, <y>).
1221            
1222             Example uses brackets "[ ]", parens "( )", pipes "|" and ellipsis "..." to describe optional, required, mutually exclusive, and repeating elements. Together, these elements form valid usage patterns, each starting with program's name naval_fate.
1223            
1224             Below the usage patterns, there is a list of options with descriptions. They describe whether an option has short/long forms (-h, --help), whether an option has an argument (--speed=<kn>), and whether that argument has a default value ([default: 10]).
1225            
1226             docopt implementation will extract all that information and generate a command-line arguments parser, with text of the example above being the help message, which is shown to a user when the program is invoked with -h or --help options.
1227            
1228             =head1 Usage patterns
1229            
1230             You can read official document: L<http://docopt.org/>
1231            
1232             =head1 FUNCTIONS
1233            
1234             =over 4
1235            
1236             =item C<< my $opts = docopt(%args) >>
1237            
1238             Analyze argv by Docopt!
1239            
1240             Return value is HashRef.
1241            
1242             You can pass following options in C<%args>:
1243            
1244             =over 4
1245            
1246             =item doc
1247            
1248             It's Docopt documentation.
1249            
1250             If you don't provide this argument, Docopt.pm uses pod SYNOPSIS section in $0.
1251            
1252             =item argv
1253            
1254             Argument in arrayref.
1255            
1256             Default: C<\@ARGV>
1257            
1258             =item help
1259            
1260             If it's true value, Docopt.pm enables C< --help > option automatically.
1261            
1262             Default: true.
1263            
1264             =item version
1265            
1266             Version number of the script. If it's not undef, Docopt.pm enables C< --version > option.
1267            
1268             Default: undef
1269            
1270             =item option_first
1271            
1272             if (options_first) {
1273             argv ::= [ long | shorts ]* [ argument ]* [ '--' [ argument ]* ] ;
1274             } else {
1275             argv ::= [ long | shorts | argument ]* [ '--' [ argument ]* ] ;
1276             }
1277            
1278             Default: undef
1279            
1280             =back
1281            
1282             =back
1283            
1284             =head1 BASED ON
1285            
1286             This version is based on docopt-py e495aaaf0b9dcea6bc8bc97d9143a0d7a649fa06.
1287            
1288             =head1 LICENSE
1289            
1290             Copyright (C) tokuhirom.
1291            
1292             This library is free software; you can redistribute it and/or modify
1293             it under the same terms as Perl itself.
1294            
1295             =head1 AUTHOR
1296            
1297             tokuhirom E<lt>tokuhirom@gmail.comE<gt>
1298            
1299             =cut
1300            
1301