feat(command_line): Properly handle positional args

This commit is contained in:
Michael Carlberg 2017-01-13 04:47:25 +01:00
parent 761b224f7c
commit b48a275235
3 changed files with 32 additions and 5 deletions

View File

@ -15,6 +15,7 @@ namespace command_line {
using choices = vector<string>; using choices = vector<string>;
using options = vector<option>; using options = vector<option>;
using values = std::map<string, string>; using values = std::map<string, string>;
using posargs = vector<string>;
// class definition : option {{{ // class definition : option {{{
@ -49,8 +50,11 @@ namespace command_line {
void process_input(const vector<string>& values); void process_input(const vector<string>& values);
bool has(const string& option) const; bool has(const string& option) const;
bool has(size_t index) const;
string get(string opt) const; string get(string opt) const;
string get(size_t index) const;
bool compare(string opt, const string& val) const; bool compare(string opt, const string& val) const;
bool compare(size_t index, const string& val) const;
protected: protected:
auto is_short(const string& option, const string& opt_short) const; auto is_short(const string& option, const string& opt_short) const;
@ -64,6 +68,7 @@ namespace command_line {
string m_synopsis{}; string m_synopsis{};
const options m_opts; const options m_opts;
values m_optvalues{}; values m_optvalues{};
posargs m_posargs{};
bool m_skipnext{false}; bool m_skipnext{false};
}; };

View File

@ -83,7 +83,14 @@ namespace command_line {
} }
/** /**
* Gets the value defined for given option * Test if a positional argument is defined at given index
*/
bool parser::has(size_t index) const {
return m_posargs.size() > index;
}
/**
* Get the value defined for given option
*/ */
string parser::get(string opt) const { string parser::get(string opt) const {
if (has(forward<string>(opt))) { if (has(forward<string>(opt))) {
@ -92,6 +99,13 @@ namespace command_line {
return ""; return "";
} }
/**
* Get the positional argument at given index
*/
string parser::get(size_t index) const {
return index < m_posargs.size() ? m_posargs[index] : "";
}
/** /**
* Compare option value with given string * Compare option value with given string
*/ */
@ -99,6 +113,13 @@ namespace command_line {
return get(move(opt)) == val; return get(move(opt)) == val;
} }
/**
* Compare positional argument at given index with given string
*/
bool parser::compare(size_t index, const string& val) const {
return get(index) == val;
}
/** /**
* Compare option with its short version * Compare option with its short version
*/ */
@ -166,12 +187,13 @@ namespace command_line {
m_skipnext = (value == input_next); m_skipnext = (value == input_next);
m_optvalues.insert(make_pair(opt.flag_long.substr(2), value)); m_optvalues.insert(make_pair(opt.flag_long.substr(2), value));
} }
return; return;
} }
} }
if (input.compare(0, 1, "-") == 0) { if (input[0] != '-') {
m_posargs.emplace_back(input);
} else {
throw argument_error("Unrecognized option " + input); throw argument_error("Unrecognized option " + input);
} }
} }

View File

@ -61,7 +61,7 @@ int main(int argc, char** argv) {
} else if (cli->has("version")) { } else if (cli->has("version")) {
print_build_info(version_details(args)); print_build_info(version_details(args));
return EXIT_SUCCESS; return EXIT_SUCCESS;
} else if (args.empty() || args[0][0] == '-') { } else if (!cli->has(0)) {
cli->usage(); cli->usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -95,7 +95,7 @@ int main(int argc, char** argv) {
throw application_error("Define configuration using --config=PATH"); throw application_error("Define configuration using --config=PATH");
} }
config::make_type conf{config::make(move(confpath), args[0])}; config::make_type conf{config::make(move(confpath), cli->get(0))};
//================================================== //==================================================
// Dump requested data // Dump requested data