8000 Moving more files into the _private.h file. This is because I notice… · docopt/docopt.cpp@cbc85d6 · GitHub
[go: up one dir, main page]

Skip to content

Commit cbc85d6

Browse files
committed
Moving more files into the _private.h file. This is because I noticed that functions were showing up in the public symboltable. To remove that, I would mark them as inline, but then I figured I would put the functions closer to the class name.
1 parent b45b9b6 commit cbc85d6

File tree

3 files changed

+372
-381
lines changed

3 files changed

+372
-381
lines changed

docopt.cpp

Lines changed: 1 addition & 379 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,7 @@
2424

2525
using namespace docopt;
2626

27-
const char* value::kindAsString(Kind kind)
28-
{
29-
switch (kind) {
30-
case Kind::Empty: return "empty";
31-
case Kind::Bool: return "bool";
32-
case Kind::Long: return "long";
33-
case Kind::String: return "string";
34-
case Kind::StringList: return "string-list";
35-
}
36-
return "unknown";
37-
}
38-
39-
void value::throwIfNotKind(Kind expected) const
40-
{
41-
if (kind == expected)
42-
return;
43-
44-
std::string error = "Illegal cast to ";
45-
error += kindAsString(expected);
46-
error += "; type is actually ";
47-
error += kindAsString(kind);
48-
throw std::runtime_error(std::move(error));
49-
}
50-
27+
DOCOPT_INLINE
5128
std::ostream& docopt::operator<<(std::ostream& os, value const& val)
5229
{
5330
if (val.isBool()) {
@@ -78,364 +55,9 @@ std::ostream& docopt::operator<<(std::ostream& os, value const& val)
7855
return os;
7956
}
8057

81-
#pragma mark -
82-
#pragma mark Pattern types
83-
84-
std::vector<LeafPattern*> Pattern::leaves() {
85-
std::vector<LeafPattern*> ret;
86-
collect_leaves(ret);
87-
return ret;
88-
}
89-
90-
bool Required::match(PatternList& left, std::vector<std::shared_ptr<LeafPattern>>& collected) const
91-
{
92-
auto l = left;
93-
auto c = collected;
94-
95-
for(auto const& pattern : fChildren) {
96-
bool ret = pattern->match(l, c);
97-
if (!ret) {
98-
// leave (left, collected) untouched
99-
return false;
100-
}
101-
}
102-
103-
left = std::move(l);
104-
collected = std::move(c);
105-
return true;
106-
}
107-
108-
bool LeafPattern::match(PatternList& left, std::vector<std::shared_ptr<LeafPattern>>& collected) const
109-
{
110-
auto match = single_match(left);
111-
if (!match.second) {
112-
return false;
113-
}
114-
115-
left.erase(left.begin()+static_cast<std::ptrdiff_t>(match.first));
116-
117-
auto same_name = std::find_if(collected.begin(), collected.end(), [&](std::shared_ptr<LeafPattern> const& p) {
118-
return p->name()==name();
119-
});
120-
if (getValue().isLong()) {
121-
long val = 1;
122-
if (same_name == collected.end()) {
123-
collected.push_back(match.second);
124-
match.second->setValue(value{val});
125-
} else if ((**same_name).getValue().isLong()) {
126-
val += (**same_name).getValue().asLong();
127-
(**same_name).setValue(value{val});
128-
} else {
129-
(**same_name).setValue(value{val});
130-
}
131-
} else if (getValue().isS F438 tringList()) {
132-
std::vector<std::string> val;
133-
if (match.second->getValue().isString()) {
134-
val.push_back(match.second->getValue().asString());
135-
} else if (match.second->getValue().isStringList()) {
136-
val = match.second->getValue().asStringList();
137-
} else {
138-
/// cant be!?
139-
}
140-
141-
if (same_name == collected.end()) {
142-
collected.push_back(match.second);
143-
match.second->setValue(value{val});
144-
} else if ((**same_name).getValue().isStringList()) {
145-
std::vector<std::string> const& list = (**same_name).getValue().asStringList();
146-
val.insert(val.begin(), list.begin(), list.end());
147-
(**same_name).setValue(value{val});
148-
} else {
149-
(**same_name).setValue(value{val});
150-
}
151-
} else {
152-
collected.push_back(match.second);
153-
}
154-
return true;
155-
}
156-
157-
Option Option::parse(std::string const& option_description)
158-
{
159-
std::string shortOption, longOption;
160-
int argcount = 0;
161-
value val { false };
162-
163-
auto double_space = option_description.find(" ");
164-
auto options_end = option_description.end();
165-
if (double_space != std::string::npos) {
166-
options_end = option_description.begin() + static_cast<std::ptrdiff_t>(double_space);
167-
}
168-
169-
static const std::regex pattern {"(-{1,2})?(.*?)([,= ]|$)"};
170-
for(std::sregex_iterator i {option_description.begin(), options_end, pattern, std::regex_constants::match_not_null},
171-
e{};
172-
i != e;
173-
++i)
174-
{
175-
std::smatch const& match = *i;
176-
if (match[1].matched) { // [1] is optional.
177-
if (match[1].length()==1) {
178-
shortOption = "-" + match[2].str();
179-
} else {
180-
longOption = "--" + match[2].str();
181-
}
182-
} else if (match[2].length() > 0) { // [2] always matches.
183-
std::string m = match[2];
184-
argcount = 1;
185-
} else {
186-
// delimeter
187-
}
188-
189-
if (match[3].length() == 0) { // [3] always matches.
190-
// Hit end of string. For some reason 'match_not_null' will let us match empty
191-
// at the end, and then we'll spin in an infinite loop. So, if we hit an empty
192-
// match, we know we must be at the end.
193-
break;
194-
}
195-
}
196-
197-
if (argcount) {
198-
std::smatch match;
199-
if (std::regex_search(options_end, option_description.end(),
200-
match,
201-
std::regex{"\\[default: (.*)\\]", std::regex::icase}))
202-
{
203-
val = match[1].str();
204-
}
205-
}
206-
207-
return {std::move(shortOption),
208-
std::move(longOption),
209-
argcount,
210-
std::move(val)};
211-
}
212-
213-
bool OneOrMore::match(PatternList& left, std::vector<std::shared_ptr<LeafPattern>>& collected) const
214-
{
215-
assert(fChildren.size() == 1);
216-
217-
auto l = left;
218-
auto c = collected;
219-
220-
bool matched = true;
221-
size_t times = 0;
222-
223-
decltype(l) l_;
224-
bool firstLoop = true;
225-
226-
while (matched) {
227-
// could it be that something didn't match but changed l or c?
228-
matched = fChildren[0]->match(l, c);
229-
230-
if (matched)
231-
++times;
232-
233-
if (firstLoop) {
234-
firstLoop = false;
235-
} else if (l == l_) {
236-
break;
237-
}
238-
239-
l_ = l;
240-
}
241-
242-
if (times == 0) {
243-
return false;
244-
}
245-
246-
left = std::move(l);
247-
collected = std::move(c);
248-
return true;
249-
}
250-
251-
bool Either::match(PatternList& left, std::vector<std::shared_ptr<LeafPattern>>& collected) const
252-
{
253-
using Outcome = std::pair<PatternList, std::vector<std::shared_ptr<LeafPattern>>>;
254-
255-
std::vector<Outcome> outcomes;
256-
257-
for(auto const& pattern : fChildren) {
258-
// need a copy so we apply the same one for every iteration
259-
auto l = left;
260-
auto c = collected;
261-
bool matched = pattern->match(l, c);
262-
if (matched) {
263-
outcomes.emplace_back(std::move(l), std::move(c));
264-
}
265-
}
266-
267-
auto min = std::min_element(outcomes.begin(), outcomes.end(), [](Outcome const& o1, Outcome const& o2) {
268-
return o1.first.size() < o2.first.size();
269-
});
270-
271-
if (min == outcomes.end()) {
272-
// (left, collected) unchanged
273-
return false;
274-
}
275-
276-
std::tie(left, collected) = std::move(*min);
277-
return true;
278-
}
279-
280-
std::pair<size_t, std::shared_ptr<LeafPattern>> Argument::single_match(PatternList const& left) const
281-
{
282-
std::pair<size_t, std::shared_ptr<LeafPattern>> ret {};
283-
284-
for(size_t i = 0, size = left.size(); i < size; ++i)
285-
{
286-
auto arg = dynamic_cast<Argument const*>(left[i].get());
287-
if (arg) {
288-
ret.first = i;
289-
ret.second = std::make_shared<Argument>(name(), arg->getValue());
290-
break;
291-
}
292-
}
293-
294-
return ret;
295-
}
296-
297-
std::pair<size_t, std::shared_ptr<LeafPattern>> Command::single_match(PatternList const& left) const
298-
{
299-
std::pair<size_t, std::shared_ptr<LeafPattern>> ret {};
300-
301-
for(size_t i = 0, size = left.size(); i < size; ++i)
302-
{
303-
auto arg = dynamic_cast<Argument const*>(left[i].get());
304-
if (arg) {
305-
if (name() == arg->getValue()) {
306-
ret.first = i;
307-
ret.second = std::make_shared<Command>(name(), value{true});
308-
}
309-
break;
310-
}
311-
}
312-
313-
return ret;
314-
}
315-
316-
std::pair<size_t, std::shared_ptr<LeafPattern>> Option::single_match(PatternList const& left) const
317-
{
318-
std::pair<size_t, std::shared_ptr<LeafPattern>> ret {};
319-
320-
for(size_t i = 0, size = left.size(); i < size; ++i)
321-
{
322-
auto leaf = std::dynamic_pointer_cast<LeafPattern>(left[i]);
323-
if (leaf && name() == leaf->name()) {
324-
ret.first = i;
325-
ret.second = leaf;
326-
break;
327-
}
328-
}
329-
330-
return ret;
331-
}
332-
33358
#pragma mark -
33459
#pragma mark Parsing stuff
33560

336-
static std::vector<PatternList> transform(PatternList pattern);
337-
338-
void BranchPattern::fix_repeating_arguments()
339-
{
340-
std::vector<PatternList> either = transform(children());
341-
for(auto const& group : either) {
342-
// use multiset to help identify duplicate entries
343-
std::unordered_multiset<std::shared_ptr<Pattern>, PatternHasher> group_set {group.begin(), group.end()};
344-
for(auto const& e : group_set) {
345-
if (group_set.count(e) == 1)
346-
continue;
347-
348-
LeafPattern* leaf = dynamic_cast<LeafPattern*>(e.get());
349-
if (!leaf) continue;
350-
351-
bool ensureList = false;
352-
bool ensureInt = false;
353-
354-
if (dynamic_cast<Command*>(leaf)) {
355-
ensureInt = true;
356-
} else if (dynamic_cast<Argument*>(leaf)) {
357-
ensureList = true;
358-
} else if (Option* o = dynamic_cast<Option*>(leaf)) {
359-
if (o->argCount()) {
360-
ensureList = true;
361-
} else {
362-
ensureInt = true;
363-
}
364-
}
365-
366-
if (ensureList) {
367-
std::vector<std::string> newValue;
368-
if (leaf->getValue().isString()) {
369-
newValue = split(leaf->getValue().asString());
370-
}
371-
if (!leaf->getValue().isStringList()) {
372-
leaf->setValue(value{newValue});
373-
}
374-
} else if (ensureInt) {
375-
leaf->setValue(value{0});
376-
}
377-
}
378-
}
379-
}
380-
381-
static std::vector<PatternList> transform(PatternList pattern)
382-
{
383-
std::vector<PatternList> result;
384-
385-
std::vector<PatternList> groups;
386-
groups.emplace_back(std::move(pattern));
387-
388-
while(!groups.empty()) {
389-
// pop off the first element
390-
auto children = std::move(groups[0]);
391-
groups.erase(groups.begin());
392-
393-
// find the first branch node in the list
394-
auto child_iter = std::find_if(children.begin(), children.end(), [](std::shared_ptr<Pattern> const& p) {
395-
return dynamic_cast<BranchPattern const*>(p.get());
396-
});
397-
398-
// no branch nodes left : expansion is complete for this grouping
399-
if (child_iter == children.end()) {
400-
result.emplace_back(std::move(children));
401-
continue;
402-
}
403-
404-
// pop the child from the list
405-
auto child = std::move(*child_iter);
406-
children.erase(child_iter);
407-
408-
// expand the branch in the appropriate way
409-
if (Either* either = dynamic_cast<Either*>(child.get())) {
410-
// "[e] + children" for each child 'e' in Either
411-
for(auto const& eitherChild : either->children()) {
412-
PatternList group = { eitherChild };
413-
group.insert(group.end(), children.begin(), children.end());
414-
415-
groups.emplace_back(std::move(group));
416-
}
417-
} else if (OneOrMore* oneOrMore = dynamic_cast<OneOrMore*>(child.get())) {
418-
// child.children * 2 + children
419-
auto const& subchildren = oneOrMore->children();
420-
PatternList group = subchildren;
421-
group.insert(group.end(), subchildren.begin(), subchildren.end());
422-
group.insert(group.end(), children.begin(), children.end());
423-
424-
groups.emplace_back(std::move(group));
425-
} else { // Required, Optional, OptionsShortcut
426-
BranchPattern* branch = dynamic_cast<BranchPattern*>(child.get());
427-
428-
// child.children + children
429-
PatternList group = branch->children();
430-
group.insert(group.end(), children.begin(), children.end());
431-
432-
groups.emplace_back(std::move(group));
433-
}
434-
}
435-
436-
return result;
437-
}
438-
43961
class Tokens {
44062
public:
44163
Tokens(std::vector<std::string> tokens, bool isParsingArgv = true)

0 commit comments

Comments
 (0)
0