| 125 | } |
| 126 | |
| 127 | void Options::parse(int argc, const char* argv[]) { |
| 128 | assert(argc > 0 && "expect at least program name as an argument"); |
| 129 | size_t positionalsSeen = 0; |
| 130 | auto dashes = [](const std::string& s) { |
| 131 | for (size_t i = 0; i < s.size(); ++i) { |
| 132 | if (s[i] != '-') { |
| 133 | return i; |
| 134 | } |
| 135 | } |
| 136 | return s.size(); |
| 137 | }; |
| 138 | for (size_t i = 1, e = argc; i != e; ++i) { |
| 139 | std::string currentOption = argv[i]; |
| 140 | |
| 141 | // "-" alone is a positional option |
| 142 | if (dashes(currentOption) == 0 || currentOption == "-") { |
| 143 | // Positional. |
| 144 | switch (positional) { |
| 145 | case Arguments::Zero: |
| 146 | // Optional arguments must use --flag=A format, and not separated by |
| 147 | // spaces (which would be ambiguous). |
| 148 | case Arguments::Optional: |
| 149 | std::cerr << "Unexpected positional argument '" << currentOption |
| 150 | << "'\n"; |
| 151 | exit(EXIT_FAILURE); |
| 152 | case Arguments::One: |
| 153 | if (positionalsSeen) { |
| 154 | std::cerr << "Unexpected second positional argument '" |
| 155 | << currentOption << "' for " << positionalName << '\n'; |
| 156 | exit(EXIT_FAILURE); |
| 157 | } |
| 158 | [[fallthrough]]; |
| 159 | case Arguments::N: |
| 160 | positionalAction(this, currentOption); |
| 161 | ++positionalsSeen; |
| 162 | break; |
| 163 | } |
| 164 | continue; |
| 165 | } |
| 166 | |
| 167 | // Non-positional. |
| 168 | std::string argument; |
| 169 | auto equal = currentOption.find_first_of('='); |
| 170 | if (equal != std::string::npos) { |
| 171 | argument = currentOption.substr(equal + 1); |
| 172 | currentOption = currentOption.substr(0, equal); |
| 173 | } |
| 174 | Option* option = nullptr; |
| 175 | for (auto& o : options) { |
| 176 | if (o.longName == currentOption || o.shortName == currentOption) { |
| 177 | option = &o; |
| 178 | } |
| 179 | } |
| 180 | if (!option) { |
| 181 | std::cerr << "Unknown option '" << currentOption << "'\n"; |
| 182 | exit(EXIT_FAILURE); |
| 183 | } |
| 184 | switch (option->arguments) { |
no test coverage detected