Created
July 25, 2015 12:49
-
-
Save 02JanDal/1a9c3eb27ea6acab6d98 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
for (int i = 1; i < argc; ++i) | |
{ | |
const std::string arg = argv[i]; | |
if (expectedArgument && arg[0] != '-') | |
{ | |
items.back().hasArgument = true; | |
} | |
else | |
{ | |
if (arg[0] == '-' && !noMoreOptions) | |
{ | |
if (arg.size() == 2 && arg[1] == '-') | |
{ | |
// -- means no more options. only positional arguments from now on | |
noMoreOptions = true; | |
} | |
else if (arg.size() > 1 && arg[1] == '-') | |
{ | |
// --long-argument | |
const size_t pos = arg.find('='); | |
const std::string name = arg.substr(2, pos == std::string::npos ? std::string::npos : pos - 2); | |
const auto option = options.find(name); | |
if (option == options.end()) | |
{ | |
throw CmdParserException(std::string("Unknown option --") + name); | |
} | |
else | |
{ | |
const std::string argument = pos == std::string::npos ? std::string() : arg.substr(pos + 1); | |
items.emplace_back(name, argument, pos != std::string::npos); | |
expectedArgument = pos == std::string::npos && (*option).second.argument.size() != 0; | |
} | |
} | |
else if (arg.size() > 1 && arg[1] != '-') | |
{ | |
// -abc short argument | |
for (auto it = ++arg.begin(); it != arg.end(); ++it) | |
{ | |
const auto option = options.find(std::string({*it})); | |
if (option == options.end()) | |
{ | |
throw CmdParserException(std::string("Unknown option -") + *it); | |
} | |
else | |
{ | |
items.emplace_back(std::string({*it}), std::string(), false); | |
expectedArgument = (*option).second.argument.size() != 0; | |
} | |
} | |
} | |
else // arg.size() == 1 | |
{ | |
// single - is a positional argument. used to mean stdin and similar | |
positional.push_back(arg); | |
noMoreOptions = true; // we do not allow any more options after the first positional argument | |
} | |
} | |
else | |
{ | |
auto cmdIt = std::find_if(currentCommand.commands.begin(), currentCommand.commands.end(), [arg](const CmdSubcommand &cmd) | |
{ | |
return std::find(cmd.names.begin(), cmd.names.end(), arg) != cmd.names.end(); | |
}); | |
if (!noMoreOptions && cmdIt != currentCommand.commands.end()) | |
{ | |
commands.push_back(*cmdIt); | |
currentCommand = *cmdIt; | |
const auto newOptions = currentCommand.mappedOptions(); | |
options.insert(newOptions.begin(), newOptions.end()); | |
} | |
else | |
{ | |
positional.push_back(arg); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment