annotate dep/fmt/support/docopt.py @ 364:99c961c91809

core: refactor out byte stream into its own file easy dubs
author Paper <paper@paper.us.eu.org>
date Tue, 16 Jul 2024 21:15:59 -0400
parents 1faa72660932
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
343
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
1 """Pythonic command-line interface parser that will make you smile.
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
2
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
3 * http://docopt.org
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
4 * Repository and issue-tracker: https://github.com/docopt/docopt
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
5 * Licensed under terms of MIT license (see LICENSE-MIT)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
6 * Copyright (c) 2013 Vladimir Keleshev, vladimir@keleshev.com
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
7
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
8 """
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
9 import sys
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
10 import re
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
11
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
12
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
13 __all__ = ['docopt']
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
14 __version__ = '0.6.1'
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
15
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
16
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
17 class DocoptLanguageError(Exception):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
18
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
19 """Error in construction of usage-message by developer."""
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
20
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
21
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
22 class DocoptExit(SystemExit):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
23
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
24 """Exit in case user invoked program with incorrect arguments."""
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
25
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
26 usage = ''
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
27
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
28 def __init__(self, message=''):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
29 SystemExit.__init__(self, (message + '\n' + self.usage).strip())
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
30
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
31
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
32 class Pattern(object):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
33
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
34 def __eq__(self, other):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
35 return repr(self) == repr(other)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
36
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
37 def __hash__(self):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
38 return hash(repr(self))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
39
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
40 def fix(self):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
41 self.fix_identities()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
42 self.fix_repeating_arguments()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
43 return self
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
44
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
45 def fix_identities(self, uniq=None):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
46 """Make pattern-tree tips point to same object if they are equal."""
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
47 if not hasattr(self, 'children'):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
48 return self
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
49 uniq = list(set(self.flat())) if uniq is None else uniq
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
50 for i, child in enumerate(self.children):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
51 if not hasattr(child, 'children'):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
52 assert child in uniq
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
53 self.children[i] = uniq[uniq.index(child)]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
54 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
55 child.fix_identities(uniq)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
56
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
57 def fix_repeating_arguments(self):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
58 """Fix elements that should accumulate/increment values."""
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
59 either = [list(child.children) for child in transform(self).children]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
60 for case in either:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
61 for e in [child for child in case if case.count(child) > 1]:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
62 if type(e) is Argument or type(e) is Option and e.argcount:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
63 if e.value is None:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
64 e.value = []
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
65 elif type(e.value) is not list:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
66 e.value = e.value.split()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
67 if type(e) is Command or type(e) is Option and e.argcount == 0:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
68 e.value = 0
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
69 return self
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
70
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
71
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
72 def transform(pattern):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
73 """Expand pattern into an (almost) equivalent one, but with single Either.
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
74
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
75 Example: ((-a | -b) (-c | -d)) => (-a -c | -a -d | -b -c | -b -d)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
76 Quirks: [-a] => (-a), (-a...) => (-a -a)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
77
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
78 """
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
79 result = []
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
80 groups = [[pattern]]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
81 while groups:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
82 children = groups.pop(0)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
83 parents = [Required, Optional, OptionsShortcut, Either, OneOrMore]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
84 if any(t in map(type, children) for t in parents):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
85 child = [c for c in children if type(c) in parents][0]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
86 children.remove(child)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
87 if type(child) is Either:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
88 for c in child.children:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
89 groups.append([c] + children)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
90 elif type(child) is OneOrMore:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
91 groups.append(child.children * 2 + children)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
92 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
93 groups.append(child.children + children)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
94 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
95 result.append(children)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
96 return Either(*[Required(*e) for e in result])
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
97
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
98
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
99 class LeafPattern(Pattern):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
100
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
101 """Leaf/terminal node of a pattern tree."""
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
102
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
103 def __init__(self, name, value=None):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
104 self.name, self.value = name, value
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
105
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
106 def __repr__(self):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
107 return '%s(%r, %r)' % (self.__class__.__name__, self.name, self.value)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
108
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
109 def flat(self, *types):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
110 return [self] if not types or type(self) in types else []
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
111
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
112 def match(self, left, collected=None):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
113 collected = [] if collected is None else collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
114 pos, match = self.single_match(left)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
115 if match is None:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
116 return False, left, collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
117 left_ = left[:pos] + left[pos + 1:]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
118 same_name = [a for a in collected if a.name == self.name]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
119 if type(self.value) in (int, list):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
120 if type(self.value) is int:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
121 increment = 1
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
122 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
123 increment = ([match.value] if type(match.value) is str
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
124 else match.value)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
125 if not same_name:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
126 match.value = increment
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
127 return True, left_, collected + [match]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
128 same_name[0].value += increment
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
129 return True, left_, collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
130 return True, left_, collected + [match]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
131
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
132
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
133 class BranchPattern(Pattern):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
134
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
135 """Branch/inner node of a pattern tree."""
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
136
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
137 def __init__(self, *children):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
138 self.children = list(children)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
139
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
140 def __repr__(self):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
141 return '%s(%s)' % (self.__class__.__name__,
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
142 ', '.join(repr(a) for a in self.children))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
143
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
144 def flat(self, *types):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
145 if type(self) in types:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
146 return [self]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
147 return sum([child.flat(*types) for child in self.children], [])
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
148
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
149
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
150 class Argument(LeafPattern):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
151
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
152 def single_match(self, left):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
153 for n, pattern in enumerate(left):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
154 if type(pattern) is Argument:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
155 return n, Argument(self.name, pattern.value)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
156 return None, None
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
157
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
158 @classmethod
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
159 def parse(class_, source):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
160 name = re.findall('(<\S*?>)', source)[0]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
161 value = re.findall('\[default: (.*)\]', source, flags=re.I)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
162 return class_(name, value[0] if value else None)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
163
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
164
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
165 class Command(Argument):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
166
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
167 def __init__(self, name, value=False):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
168 self.name, self.value = name, value
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
169
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
170 def single_match(self, left):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
171 for n, pattern in enumerate(left):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
172 if type(pattern) is Argument:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
173 if pattern.value == self.name:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
174 return n, Command(self.name, True)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
175 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
176 break
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
177 return None, None
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
178
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
179
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
180 class Option(LeafPattern):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
181
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
182 def __init__(self, short=None, long=None, argcount=0, value=False):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
183 assert argcount in (0, 1)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
184 self.short, self.long, self.argcount = short, long, argcount
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
185 self.value = None if value is False and argcount else value
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
186
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
187 @classmethod
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
188 def parse(class_, option_description):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
189 short, long, argcount, value = None, None, 0, False
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
190 options, _, description = option_description.strip().partition(' ')
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
191 options = options.replace(',', ' ').replace('=', ' ')
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
192 for s in options.split():
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
193 if s.startswith('--'):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
194 long = s
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
195 elif s.startswith('-'):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
196 short = s
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
197 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
198 argcount = 1
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
199 if argcount:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
200 matched = re.findall('\[default: (.*)\]', description, flags=re.I)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
201 value = matched[0] if matched else None
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
202 return class_(short, long, argcount, value)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
203
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
204 def single_match(self, left):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
205 for n, pattern in enumerate(left):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
206 if self.name == pattern.name:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
207 return n, pattern
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
208 return None, None
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
209
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
210 @property
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
211 def name(self):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
212 return self.long or self.short
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
213
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
214 def __repr__(self):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
215 return 'Option(%r, %r, %r, %r)' % (self.short, self.long,
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
216 self.argcount, self.value)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
217
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
218
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
219 class Required(BranchPattern):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
220
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
221 def match(self, left, collected=None):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
222 collected = [] if collected is None else collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
223 l = left
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
224 c = collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
225 for pattern in self.children:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
226 matched, l, c = pattern.match(l, c)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
227 if not matched:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
228 return False, left, collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
229 return True, l, c
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
230
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
231
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
232 class Optional(BranchPattern):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
233
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
234 def match(self, left, collected=None):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
235 collected = [] if collected is None else collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
236 for pattern in self.children:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
237 m, left, collected = pattern.match(left, collected)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
238 return True, left, collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
239
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
240
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
241 class OptionsShortcut(Optional):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
242
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
243 """Marker/placeholder for [options] shortcut."""
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
244
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
245
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
246 class OneOrMore(BranchPattern):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
247
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
248 def match(self, left, collected=None):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
249 assert len(self.children) == 1
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
250 collected = [] if collected is None else collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
251 l = left
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
252 c = collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
253 l_ = None
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
254 matched = True
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
255 times = 0
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
256 while matched:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
257 # could it be that something didn't match but changed l or c?
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
258 matched, l, c = self.children[0].match(l, c)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
259 times += 1 if matched else 0
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
260 if l_ == l:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
261 break
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
262 l_ = l
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
263 if times >= 1:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
264 return True, l, c
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
265 return False, left, collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
266
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
267
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
268 class Either(BranchPattern):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
269
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
270 def match(self, left, collected=None):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
271 collected = [] if collected is None else collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
272 outcomes = []
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
273 for pattern in self.children:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
274 matched, _, _ = outcome = pattern.match(left, collected)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
275 if matched:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
276 outcomes.append(outcome)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
277 if outcomes:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
278 return min(outcomes, key=lambda outcome: len(outcome[1]))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
279 return False, left, collected
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
280
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
281
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
282 class Tokens(list):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
283
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
284 def __init__(self, source, error=DocoptExit):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
285 self += source.split() if hasattr(source, 'split') else source
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
286 self.error = error
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
287
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
288 @staticmethod
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
289 def from_pattern(source):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
290 source = re.sub(r'([\[\]\(\)\|]|\.\.\.)', r' \1 ', source)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
291 source = [s for s in re.split('\s+|(\S*<.*?>)', source) if s]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
292 return Tokens(source, error=DocoptLanguageError)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
293
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
294 def move(self):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
295 return self.pop(0) if len(self) else None
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
296
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
297 def current(self):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
298 return self[0] if len(self) else None
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
299
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
300
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
301 def parse_long(tokens, options):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
302 """long ::= '--' chars [ ( ' ' | '=' ) chars ] ;"""
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
303 long, eq, value = tokens.move().partition('=')
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
304 assert long.startswith('--')
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
305 value = None if eq == value == '' else value
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
306 similar = [o for o in options if o.long == long]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
307 if tokens.error is DocoptExit and similar == []: # if no exact match
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
308 similar = [o for o in options if o.long and o.long.startswith(long)]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
309 if len(similar) > 1: # might be simply specified ambiguously 2+ times?
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
310 raise tokens.error('%s is not a unique prefix: %s?' %
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
311 (long, ', '.join(o.long for o in similar)))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
312 elif len(similar) < 1:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
313 argcount = 1 if eq == '=' else 0
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
314 o = Option(None, long, argcount)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
315 options.append(o)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
316 if tokens.error is DocoptExit:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
317 o = Option(None, long, argcount, value if argcount else True)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
318 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
319 o = Option(similar[0].short, similar[0].long,
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
320 similar[0].argcount, similar[0].value)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
321 if o.argcount == 0:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
322 if value is not None:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
323 raise tokens.error('%s must not have an argument' % o.long)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
324 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
325 if value is None:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
326 if tokens.current() in [None, '--']:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
327 raise tokens.error('%s requires argument' % o.long)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
328 value = tokens.move()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
329 if tokens.error is DocoptExit:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
330 o.value = value if value is not None else True
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
331 return [o]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
332
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
333
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
334 def parse_shorts(tokens, options):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
335 """shorts ::= '-' ( chars )* [ [ ' ' ] chars ] ;"""
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
336 token = tokens.move()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
337 assert token.startswith('-') and not token.startswith('--')
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
338 left = token.lstrip('-')
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
339 parsed = []
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
340 while left != '':
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
341 short, left = '-' + left[0], left[1:]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
342 similar = [o for o in options if o.short == short]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
343 if len(similar) > 1:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
344 raise tokens.error('%s is specified ambiguously %d times' %
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
345 (short, len(similar)))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
346 elif len(similar) < 1:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
347 o = Option(short, None, 0)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
348 options.append(o)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
349 if tokens.error is DocoptExit:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
350 o = Option(short, None, 0, True)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
351 else: # why copying is necessary here?
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
352 o = Option(short, similar[0].long,
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
353 similar[0].argcount, similar[0].value)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
354 value = None
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
355 if o.argcount != 0:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
356 if left == '':
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
357 if tokens.current() in [None, '--']:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
358 raise tokens.error('%s requires argument' % short)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
359 value = tokens.move()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
360 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
361 value = left
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
362 left = ''
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
363 if tokens.error is DocoptExit:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
364 o.value = value if value is not None else True
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
365 parsed.append(o)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
366 return parsed
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
367
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
368
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
369 def parse_pattern(source, options):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
370 tokens = Tokens.from_pattern(source)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
371 result = parse_expr(tokens, options)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
372 if tokens.current() is not None:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
373 raise tokens.error('unexpected ending: %r' % ' '.join(tokens))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
374 return Required(*result)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
375
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
376
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
377 def parse_expr(tokens, options):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
378 """expr ::= seq ( '|' seq )* ;"""
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
379 seq = parse_seq(tokens, options)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
380 if tokens.current() != '|':
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
381 return seq
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
382 result = [Required(*seq)] if len(seq) > 1 else seq
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
383 while tokens.current() == '|':
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
384 tokens.move()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
385 seq = parse_seq(tokens, options)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
386 result += [Required(*seq)] if len(seq) > 1 else seq
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
387 return [Either(*result)] if len(result) > 1 else result
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
388
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
389
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
390 def parse_seq(tokens, options):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
391 """seq ::= ( atom [ '...' ] )* ;"""
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
392 result = []
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
393 while tokens.current() not in [None, ']', ')', '|']:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
394 atom = parse_atom(tokens, options)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
395 if tokens.current() == '...':
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
396 atom = [OneOrMore(*atom)]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
397 tokens.move()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
398 result += atom
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
399 return result
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
400
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
401
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
402 def parse_atom(tokens, options):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
403 """atom ::= '(' expr ')' | '[' expr ']' | 'options'
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
404 | long | shorts | argument | command ;
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
405 """
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
406 token = tokens.current()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
407 result = []
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
408 if token in '([':
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
409 tokens.move()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
410 matching, pattern = {'(': [')', Required], '[': [']', Optional]}[token]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
411 result = pattern(*parse_expr(tokens, options))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
412 if tokens.move() != matching:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
413 raise tokens.error("unmatched '%s'" % token)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
414 return [result]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
415 elif token == 'options':
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
416 tokens.move()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
417 return [OptionsShortcut()]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
418 elif token.startswith('--') and token != '--':
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
419 return parse_long(tokens, options)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
420 elif token.startswith('-') and token not in ('-', '--'):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
421 return parse_shorts(tokens, options)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
422 elif token.startswith('<') and token.endswith('>') or token.isupper():
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
423 return [Argument(tokens.move())]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
424 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
425 return [Command(tokens.move())]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
426
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
427
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
428 def parse_argv(tokens, options, options_first=False):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
429 """Parse command-line argument vector.
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
430
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
431 If options_first:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
432 argv ::= [ long | shorts ]* [ argument ]* [ '--' [ argument ]* ] ;
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
433 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
434 argv ::= [ long | shorts | argument ]* [ '--' [ argument ]* ] ;
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
435
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
436 """
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
437 parsed = []
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
438 while tokens.current() is not None:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
439 if tokens.current() == '--':
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
440 return parsed + [Argument(None, v) for v in tokens]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
441 elif tokens.current().startswith('--'):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
442 parsed += parse_long(tokens, options)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
443 elif tokens.current().startswith('-') and tokens.current() != '-':
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
444 parsed += parse_shorts(tokens, options)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
445 elif options_first:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
446 return parsed + [Argument(None, v) for v in tokens]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
447 else:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
448 parsed.append(Argument(None, tokens.move()))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
449 return parsed
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
450
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
451
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
452 def parse_defaults(doc):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
453 defaults = []
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
454 for s in parse_section('options:', doc):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
455 # FIXME corner case "bla: options: --foo"
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
456 _, _, s = s.partition(':') # get rid of "options:"
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
457 split = re.split('\n[ \t]*(-\S+?)', '\n' + s)[1:]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
458 split = [s1 + s2 for s1, s2 in zip(split[::2], split[1::2])]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
459 options = [Option.parse(s) for s in split if s.startswith('-')]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
460 defaults += options
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
461 return defaults
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
462
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
463
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
464 def parse_section(name, source):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
465 pattern = re.compile('^([^\n]*' + name + '[^\n]*\n?(?:[ \t].*?(?:\n|$))*)',
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
466 re.IGNORECASE | re.MULTILINE)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
467 return [s.strip() for s in pattern.findall(source)]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
468
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
469
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
470 def formal_usage(section):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
471 _, _, section = section.partition(':') # drop "usage:"
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
472 pu = section.split()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
473 return '( ' + ' '.join(') | (' if s == pu[0] else s for s in pu[1:]) + ' )'
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
474
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
475
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
476 def extras(help, version, options, doc):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
477 if help and any((o.name in ('-h', '--help')) and o.value for o in options):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
478 print(doc.strip("\n"))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
479 sys.exit()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
480 if version and any(o.name == '--version' and o.value for o in options):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
481 print(version)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
482 sys.exit()
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
483
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
484
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
485 class Dict(dict):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
486 def __repr__(self):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
487 return '{%s}' % ',\n '.join('%r: %r' % i for i in sorted(self.items()))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
488
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
489
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
490 def docopt(doc, argv=None, help=True, version=None, options_first=False):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
491 """Parse `argv` based on command-line interface described in `doc`.
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
492
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
493 `docopt` creates your command-line interface based on its
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
494 description that you pass as `doc`. Such description can contain
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
495 --options, <positional-argument>, commands, which could be
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
496 [optional], (required), (mutually | exclusive) or repeated...
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
497
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
498 Parameters
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
499 ----------
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
500 doc : str
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
501 Description of your command-line interface.
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
502 argv : list of str, optional
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
503 Argument vector to be parsed. sys.argv[1:] is used if not
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
504 provided.
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
505 help : bool (default: True)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
506 Set to False to disable automatic help on -h or --help
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
507 options.
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
508 version : any object
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
509 If passed, the object will be printed if --version is in
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
510 `argv`.
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
511 options_first : bool (default: False)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
512 Set to True to require options precede positional arguments,
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
513 i.e. to forbid options and positional arguments intermix.
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
514
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
515 Returns
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
516 -------
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
517 args : dict
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
518 A dictionary, where keys are names of command-line elements
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
519 such as e.g. "--verbose" and "<path>", and values are the
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
520 parsed values of those elements.
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
521
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
522 Example
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
523 -------
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
524 >>> from docopt import docopt
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
525 >>> doc = '''
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
526 ... Usage:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
527 ... my_program tcp <host> <port> [--timeout=<seconds>]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
528 ... my_program serial <port> [--baud=<n>] [--timeout=<seconds>]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
529 ... my_program (-h | --help | --version)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
530 ...
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
531 ... Options:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
532 ... -h, --help Show this screen and exit.
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
533 ... --baud=<n> Baudrate [default: 9600]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
534 ... '''
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
535 >>> argv = ['tcp', '127.0.0.1', '80', '--timeout', '30']
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
536 >>> docopt(doc, argv)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
537 {'--baud': '9600',
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
538 '--help': False,
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
539 '--timeout': '30',
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
540 '--version': False,
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
541 '<host>': '127.0.0.1',
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
542 '<port>': '80',
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
543 'serial': False,
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
544 'tcp': True}
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
545
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
546 See also
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
547 --------
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
548 * For video introduction see http://docopt.org
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
549 * Full documentation is available in README.rst as well as online
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
550 at https://github.com/docopt/docopt#readme
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
551
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
552 """
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
553 argv = sys.argv[1:] if argv is None else argv
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
554
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
555 usage_sections = parse_section('usage:', doc)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
556 if len(usage_sections) == 0:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
557 raise DocoptLanguageError('"usage:" (case-insensitive) not found.')
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
558 if len(usage_sections) > 1:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
559 raise DocoptLanguageError('More than one "usage:" (case-insensitive).')
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
560 DocoptExit.usage = usage_sections[0]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
561
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
562 options = parse_defaults(doc)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
563 pattern = parse_pattern(formal_usage(DocoptExit.usage), options)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
564 # [default] syntax for argument is disabled
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
565 #for a in pattern.flat(Argument):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
566 # same_name = [d for d in arguments if d.name == a.name]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
567 # if same_name:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
568 # a.value = same_name[0].value
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
569 argv = parse_argv(Tokens(argv), list(options), options_first)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
570 pattern_options = set(pattern.flat(Option))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
571 for options_shortcut in pattern.flat(OptionsShortcut):
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
572 doc_options = parse_defaults(doc)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
573 options_shortcut.children = list(set(doc_options) - pattern_options)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
574 #if any_options:
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
575 # options_shortcut.children += [Option(o.short, o.long, o.argcount)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
576 # for o in argv if type(o) is Option]
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
577 extras(help, version, argv, doc)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
578 matched, left, collected = pattern.fix().match(argv)
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
579 if matched and left == []: # better error message if left?
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
580 return Dict((a.name, a.value) for a in (pattern.flat() + collected))
1faa72660932 *: transfer back to cmake from autotools
Paper <paper@paper.us.eu.org>
parents:
diff changeset
581 raise DocoptExit()