| 521 | } |
| 522 | |
| 523 | inline Option Option::parse(std::string const& option_description) |
| 524 | { |
| 525 | std::string shortOption, longOption; |
| 526 | int argcount = 0; |
| 527 | value val { false }; |
| 528 | |
| 529 | auto double_space = option_description.find(" "); |
| 530 | auto options_end = option_description.end(); |
| 531 | if (double_space != std::string::npos) { |
| 532 | options_end = option_description.begin() + static_cast<std::ptrdiff_t>(double_space); |
| 533 | } |
| 534 | |
| 535 | static const std::regex pattern {"(-{1,2})?(.*?)([,= ]|$)"}; |
| 536 | for(std::sregex_iterator i {option_description.begin(), options_end, pattern, std::regex_constants::match_not_null}, |
| 537 | e{}; |
| 538 | i != e; |
| 539 | ++i) |
| 540 | { |
| 541 | std::smatch const& match = *i; |
| 542 | if (match[1].matched) { // [1] is optional. |
| 543 | if (match[1].length()==1) { |
| 544 | shortOption = "-" + match[2].str(); |
| 545 | } else { |
| 546 | longOption = "--" + match[2].str(); |
| 547 | } |
| 548 | } else if (match[2].length() > 0) { // [2] always matches. |
| 549 | std::string m = match[2]; |
| 550 | argcount = 1; |
| 551 | } else { |
| 552 | // delimeter |
| 553 | } |
| 554 | |
| 555 | if (match[3].length() == 0) { // [3] always matches. |
| 556 | // Hit end of string. For some reason 'match_not_null' will let us match empty |
| 557 | // at the end, and then we'll spin in an infinite loop. So, if we hit an empty |
| 558 | // match, we know we must be at the end. |
| 559 | break; |
| 560 | } |
| 561 | } |
| 562 | |
| 563 | if (argcount) { |
| 564 | std::smatch match; |
| 565 | if (std::regex_search(options_end, option_description.end(), |
| 566 | match, |
| 567 | std::regex{"\\[default: (.*)\\]", std::regex::icase})) |
| 568 | { |
| 569 | val = match[1].str(); |
| 570 | } |
| 571 | } |
| 572 | |
| 573 | return {std::move(shortOption), |
| 574 | std::move(longOption), |
| 575 | argcount, |
| 576 | std::move(val)}; |
| 577 | } |
| 578 | |
| 579 | inline std::pair<size_t, std::shared_ptr<LeafPattern>> Option::single_match(PatternList const& left) const |
| 580 | { |
nothing calls this directly
no outgoing calls
no test coverage detected