Parse the doc string and generate the Pattern tree
| 567 | |
| 568 | // Parse the doc string and generate the Pattern tree |
| 569 | static std::pair<Required, std::vector<Option>> create_pattern_tree(std::string const& doc) |
| 570 | { |
| 571 | auto usage_sections = parse_section("usage:", doc); |
| 572 | if (usage_sections.empty()) { |
| 573 | throw DocoptLanguageError("'usage:' (case-insensitive) not found."); |
| 574 | } |
| 575 | if (usage_sections.size() > 1) { |
| 576 | throw DocoptLanguageError("More than one 'usage:' (case-insensitive)."); |
| 577 | } |
| 578 | |
| 579 | std::vector<Option> options = parse_defaults(doc); |
| 580 | Required pattern = parse_pattern(formal_usage(usage_sections[0]), options); |
| 581 | |
| 582 | std::vector<Option const*> pattern_options = flat_filter<Option const>(pattern); |
| 583 | |
| 584 | using UniqueOptions = std::unordered_set<Option const*, PatternHasher, PatternPointerEquality>; |
| 585 | UniqueOptions const uniq_pattern_options { pattern_options.begin(), pattern_options.end() }; |
| 586 | |
| 587 | // Fix up any "[options]" shortcuts with the actual option tree |
| 588 | for(auto& options_shortcut : flat_filter<OptionsShortcut>(pattern)) { |
| 589 | std::vector<Option> doc_options = parse_defaults(doc); |
| 590 | |
| 591 | // set(doc_options) - set(pattern_options) |
| 592 | UniqueOptions uniq_doc_options; |
| 593 | for(auto const& opt : doc_options) { |
| 594 | if (uniq_pattern_options.count(&opt)) |
| 595 | continue; |
| 596 | uniq_doc_options.insert(&opt); |
| 597 | } |
| 598 | |
| 599 | // turn into shared_ptr's and set as children |
| 600 | PatternList children; |
| 601 | std::transform(uniq_doc_options.begin(), uniq_doc_options.end(), |
| 602 | std::back_inserter(children), [](Option const* opt) { |
| 603 | return std::make_shared<Option>(*opt); |
| 604 | }); |
| 605 | options_shortcut->setChildren(std::move(children)); |
| 606 | } |
| 607 | |
| 608 | return { std::move(pattern), std::move(options) }; |
| 609 | } |
| 610 | |
| 611 | DOCOPT_INLINE |
| 612 | docopt::Options |
no test coverage detected