summaryrefslogtreecommitdiff
path: root/src/main/options_template.cpp
diff options
context:
space:
mode:
authorGereon Kremer <nafur42@gmail.com>2021-09-13 17:54:55 +0200
committerGitHub <noreply@github.com>2021-09-13 08:54:55 -0700
commit02088737d2845ea00714b6ba6fed8c20485a9645 (patch)
tree6b1b6cd483bdaf718172dbabc652f73e43de6364 /src/main/options_template.cpp
parent2384a8d85517e00bc94e7fcf759a75dc6ea9b009 (diff)
Refactor options parsing (#7143)
This PR refactors the code for options parsing.
Diffstat (limited to 'src/main/options_template.cpp')
-rw-r--r--src/main/options_template.cpp126
1 files changed, 72 insertions, 54 deletions
diff --git a/src/main/options_template.cpp b/src/main/options_template.cpp
index dfd93843e..a7a4429e3 100644
--- a/src/main/options_template.cpp
+++ b/src/main/options_template.cpp
@@ -82,19 +82,25 @@ Languages currently supported as arguments to the --output-lang option:\n\
";
// clang-format on
-void printUsage(const std::string& msg, std::ostream& os) {
- os << msg << "\n" << commonOptionsDescription << "\n\n" << additionalOptionsDescription << std::endl
- << optionsFootnote << std::endl << std::flush;
+void printUsage(const std::string& msg, std::ostream& os)
+{
+ os << msg << "\n"
+ << commonOptionsDescription << "\n\n"
+ << additionalOptionsDescription << std::endl
+ << optionsFootnote << std::endl;
}
-void printShortUsage(const std::string& msg, std::ostream& os) {
- os << msg << "\n" << commonOptionsDescription << std::endl
- << optionsFootnote << std::endl
- << "For full usage, please use --help."
- << std::endl << std::endl << std::flush;
+void printShortUsage(const std::string& msg, std::ostream& os)
+{
+ os << msg << "\n"
+ << commonOptionsDescription << std::endl
+ << optionsFootnote << std::endl
+ << "For full usage, please use --help." << std::endl
+ << std::endl;
}
-void printLanguageHelp(std::ostream& os) {
+void printLanguageHelp(std::ostream& os)
+{
os << languageDescription << std::flush;
}
@@ -111,40 +117,45 @@ void printLanguageHelp(std::ostream& os) {
* required_argument - an argument is expected
* optional_argument - an argument is permitted but not required
* 3. this is a pointer to an int which is set to the 4th entry of the
- * array if the option is present; or NULL, in which case
+ * array if the option is present; or nullptr, in which case
* getopt_long() returns the 4th entry
* 4. the return value for getopt_long() when this long option (or the
* value to set the 3rd entry to; see #3)
*/
-// clang-format off
static struct option cmdlineOptions[] = {
- ${cmdline_options}$
+// clang-format off
+ ${cmdoptions_long}$
+// clang-format on
{nullptr, no_argument, nullptr, '\0'}
};
-// clang-format on
std::string suggestCommandLineOptions(const std::string& optionName)
{
DidYouMean didYouMean;
const char* opt;
- for(size_t i = 0; (opt = cmdlineOptions[i].name) != nullptr; ++i) {
+ for (size_t i = 0; (opt = cmdlineOptions[i].name) != nullptr; ++i)
+ {
didYouMean.addWord(std::string("--") + cmdlineOptions[i].name);
}
- return didYouMean.getMatchAsString(optionName.substr(0, optionName.find('=')));
+ return didYouMean.getMatchAsString(
+ optionName.substr(0, optionName.find('=')));
}
-void parseInternal(api::Solver& solver, int argc,
- char* argv[],
- std::vector<std::string>& nonoptions)
+void parseInternal(api::Solver& solver,
+ int argc,
+ char* argv[],
+ std::vector<std::string>& nonoptions)
{
Assert(argv != nullptr);
- if(Debug.isOn("options")) {
- Debug("options") << "starting a new parseInternal with "
- << argc << " arguments" << std::endl;
- for( int i = 0; i < argc ; i++ ){
- Assert(argv[i] != NULL);
+ if (Debug.isOn("options"))
+ {
+ Debug("options") << "starting a new parseInternal with " << argc
+ << " arguments" << std::endl;
+ for (int i = 0; i < argc; ++i)
+ {
+ Assert(argv[i] != nullptr);
Debug("options") << " argv[" << i << "] = " << argv[i] << std::endl;
}
}
@@ -161,8 +172,8 @@ void parseInternal(api::Solver& solver, int argc,
int main_optind = 0;
int old_optind;
-
- while(true) { // Repeat Forever
+ while (true)
+ { // Repeat Forever
optopt = 0;
@@ -172,8 +183,8 @@ void parseInternal(api::Solver& solver, int argc,
// If we encounter an element that is not at zero and does not start
// with a "-", this is a non-option. We consume this element as a
// non-option.
- if (main_optind > 0 && main_optind < argc &&
- argv[main_optind][0] != '-') {
+ if (main_optind > 0 && main_optind < argc && argv[main_optind][0] != '-')
+ {
Debug("options") << "enqueueing " << argv[main_optind]
<< " as a non-option." << std::endl;
nonoptions.push_back(argv[main_optind]);
@@ -181,7 +192,6 @@ void parseInternal(api::Solver& solver, int argc,
continue;
}
-
Debug("options") << "[ before, main_optind == " << main_optind << " ]"
<< std::endl;
Debug("options") << "[ before, optind == " << optind << " ]" << std::endl;
@@ -189,8 +199,8 @@ void parseInternal(api::Solver& solver, int argc,
<< std::endl;
// clang-format off
int c = getopt_long(argc, argv,
- "+:${options_short}$",
- cmdlineOptions, NULL);
+ "+:${cmdoptions_short}$",
+ cmdlineOptions, nullptr);
// clang-format on
main_optind = optind;
@@ -202,15 +212,19 @@ void parseInternal(api::Solver& solver, int argc,
// The initial getopt_long call should always determine that argv[0]
// is not an option and returns -1. We always manually advance beyond
// this element.
- if ( old_optind == 0 && c == -1 ) {
+ if (old_optind == 0 && c == -1)
+ {
Assert(main_optind > 0);
continue;
}
- if ( c == -1 ) {
- if(Debug.isOn("options")) {
+ if (c == -1)
+ {
+ if (Debug.isOn("options"))
+ {
Debug("options") << "done with option parsing" << std::endl;
- for(int index = optind; index < argc; ++index) {
+ for (int index = optind; index < argc; ++index)
+ {
Debug("options") << "remaining " << argv[index] << std::endl;
}
}
@@ -220,30 +234,29 @@ void parseInternal(api::Solver& solver, int argc,
std::string option = argv[old_optind == 0 ? 1 : old_optind];
std::string optionarg = (optarg == nullptr) ? "" : optarg;
- Debug("preemptGetopt") << "processing option " << c
- << " (`" << char(c) << "'), " << option << std::endl;
+ Debug("preemptGetopt") << "processing option " << c << " (`" << char(c)
+ << "'), " << option << std::endl;
- // clang-format off
- switch(c)
+ switch (c)
{
- ${options_handler}$
+// clang-format off
+ ${parseinternal_impl}$
+// clang-format on
- case ':' :
+ case ':' :
// This can be a long or short option, and the way to get at the
// name of it is different.
throw OptionException(std::string("option `") + option
+ "' missing its required argument");
-
- case '?':
- default:
+ case '?':
+ default:
throw OptionException(std::string("can't understand option `") + option
+ "'" + suggestCommandLineOptions(option));
}
}
- // clang-format on
- Debug("options") << "got " << nonoptions.size()
- << " non-option arguments." << std::endl;
+ Debug("options") << "got " << nonoptions.size() << " non-option arguments."
+ << std::endl;
}
/**
@@ -253,31 +266,36 @@ void parseInternal(api::Solver& solver, int argc,
*
* Throws OptionException on failures.
*/
-std::vector<std::string> parse(
- api::Solver& solver, int argc, char* argv[], std::string& binaryName)
+std::vector<std::string> parse(api::Solver& solver,
+ int argc,
+ char* argv[],
+ std::string& binaryName)
{
Assert(argv != nullptr);
- const char *progName = argv[0];
+ const char* progName = argv[0];
// To debug options parsing, you may prefer to simply uncomment this
// and recompile. Debug flags have not been parsed yet so these have
// not been set.
- //DebugChannel.on("options");
+ // DebugChannel.on("options");
Debug("options") << "argv == " << argv << std::endl;
// Find the base name of the program.
- const char *x = strrchr(progName, '/');
- if(x != nullptr) {
+ const char* x = strrchr(progName, '/');
+ if (x != nullptr)
+ {
progName = x + 1;
}
binaryName = std::string(progName);
std::vector<std::string> nonoptions;
parseInternal(solver, argc, argv, nonoptions);
- if (Debug.isOn("options")){
- for (const auto& no: nonoptions){
+ if (Debug.isOn("options"))
+ {
+ for (const auto& no : nonoptions)
+ {
Debug("options") << "nonoptions " << no << std::endl;
}
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback