22Arguments::Arguments (
void)
24 , nonopt_max(
std::numeric_limits<
std::size_t>::max())
28 , cur_result(
std::numeric_limits<
std::size_t>::max())
38 ss <<
"Usage: " << argv0 <<
" " << usage;
39 this->usage_str = ss.str();
46 bool has_argument, std::string
const& description)
48 if (shortname ==
'\0' && longname.empty())
49 throw std::invalid_argument(
"Neither short nor long name given");
52 for (std::size_t i = 0; i < this->options.size(); ++i)
53 if ((shortname !=
'\0' && this->options[i].sopt == shortname)
54 || (!longname.empty() && this->options[i].lopt == longname))
55 throw std::runtime_error(
"Option already exists");
61 opt.
desc = description;
62 this->options.push_back(opt);
70 std::vector<std::string> args;
71 for (
int i = 0; i < argc; ++i)
72 args.push_back(argv[i]);
83 this->parse_intern(args);
90 std::cerr << std::endl;
92 std::cerr << std::endl <<
"Error: " << e.
what() << std::endl;
100Arguments::parse_long_opt (std::string
const& tok)
102 std::size_t pos = tok.find_first_of(
'=');
103 std::string opt = tok.substr(2, pos - 2);
105 if (pos != std::string::npos)
106 arg = tok.substr(pos + 1);
111 ArgOption const* option = this->find_opt(opt);
112 if (option ==
nullptr)
115 if (option->
argument && arg.empty())
118 if (!option->
argument && !arg.empty())
124 this->results.push_back(result);
130Arguments::parse_short_opt (std::string
const& tok1, std::string
const& tok2)
133 throw std::runtime_error(
"Short option with too few chars");
138 ArgOption
const* option = this->find_opt(opt);
140 if (option ==
nullptr)
144 if (!option->argument && tok1.size() > 2)
146 for (std::size_t i = 1; i < tok1.size(); ++i)
148 std::string sopt =
"-";
149 sopt.append(1, tok1[i]);
150 this->parse_short_opt(sopt,
"");
155 if (option->argument && tok1.size() == 2)
157 if (tok2.empty() || tok2[0] ==
'-')
162 else if (option->argument)
164 arg = tok1.substr(2);
167 if (!option->argument && tok1.size() != 2)
173 this->results.push_back(result);
181Arguments::find_opt (
char sopt)
183 for (std::size_t i = 0; i < this->options.size(); ++i)
184 if (this->options[i].sopt == sopt)
185 return &this->options[i];
193Arguments::find_opt (std::string
const& lopt)
195 for (std::size_t i = 0; i < this->options.size(); ++i)
196 if (this->options[i].lopt == lopt)
197 return &this->options[i];
205Arguments::parse_intern (std::vector<std::string>
const& args)
207 this->results.clear();
208 this->command_name.clear();
209 this->cur_result = std::numeric_limits<std::size_t>::max();
212 bool parseopt =
true;
213 for (std::size_t i = 0; i < args.size(); ++i)
217 this->command_name = args[i];
221 std::string tok = args[i];
229 if (parseopt && tok.size() == 2 && tok ==
"--")
235 else if (parseopt && tok.size() >= 3 && tok[0] ==
'-' && tok[1] ==
'-')
238 this->parse_long_opt(tok);
240 else if (parseopt && tok.size() >= 2 && tok[0] ==
'-')
243 std::string next_tok;
244 if (i + 1 < args.size())
246 next_tok = args[i + 1];
250 bool used_next = this->parse_short_opt(tok, next_tok);
260 this->results.push_back(res);
265 std::size_t num_nonopt = 0;
266 for (std::size_t i = 0; i < this->results.size(); ++i)
268 if (this->results[i].opt ==
nullptr)
272 if (num_nonopt > this->nonopt_max)
274 if (num_nonopt < this->nonopt_min)
283 this->cur_result += 1;
284 if (this->cur_result >= this->results.size())
286 this->cur_result = (std::size_t)(-1);
290 return &this->results[this->cur_result];
300 this->cur_result += 1;
301 if (this->cur_result >= this->results.size())
303 ArgResult const* ret = &this->results[this->cur_result];
304 if (ret->
opt ==
nullptr)
308 this->cur_result = (std::size_t)(-1);
318 for (std::size_t i = 0; i < this->results.size(); ++i)
320 if (this->results[i].opt)
323 return this->results[i].arg;
327 return std::string();
341 for (std::size_t i = 0; i < t.size(); ++i)
343 std::size_t pos = t[i].find_first_of(
'-');
344 if (pos != std::string::npos)
346 int const first = util::string::convert<int>(t[i].substr(0, pos));
347 int const last = util::string::convert<int>(t[i].substr(pos + 1));
348 int const inc = (
first > last ? -1 : 1);
349 for (
int j =
first; j != last + inc; j += inc)
354 ids->push_back(util::string::convert<int>(t[i]));
365 (this->descr_str.c_str(), this->descrtext_width);
368 stream << descr << std::endl << std::endl;
370 if (!this->usage_str.empty())
371 stream << this->usage_str << std::endl;
373 if (!this->options.empty() && (!this->usage_str.empty() || !descr.empty()))
374 stream <<
"Available options: " << std::endl;
376 for (std::size_t i = 0; i < this->options.size(); ++i)
379 std::stringstream optstr;
380 if (opt.
sopt !=
'\0')
382 optstr <<
'-' << opt.
sopt;
385 if (!opt.
lopt.empty())
389 if (!opt.
lopt.empty())
391 optstr <<
"--" << opt.
lopt;
397 stream <<
" " << std::setiosflags(std::ios::left)
398 << std::setw(this->helptext_indent) << optstr.str()
399 << opt.
desc << std::endl;
void add_option(char shortname, std::string const &longname, bool has_argument, std::string const &description="")
Adds an option to the list of possible arguments.
void get_ids_from_string(std::string const &str, std::vector< int > *ids)
Returns a numeric list of IDs by parsing the given string.
void parse(std::vector< std::string > const &args)
Parses arguments from a vector.
void generate_helptext(std::ostream &stream) const
Generates a help text that lists all arguments.
ArgResult const * next_option(void)
Iterator for the options.
std::string get_nth_nonopt(std::size_t index)
Returns the Nth non-option argument, or an empty string.
ArgResult const * next_result(void)
Iterator for the results.
void set_usage(std::string const &str)
Sets the usage string for printing the help text.
Universal, simple exception class.
virtual const char * what(void) const
void split(std::string const &str, char delim=' ', bool keep_empty=false)
Very simple tokenziation at a given delimiter characater.
std::string wordwrap(char const *str, int width)
Inserts line breaks on word boundaries to limit lines to 'width' chars.
void clip_newlines(std::string *str)
Clips newlines from the end of the string, in-place.
void clip_whitespaces(std::string *str)
Clips whitespaces from the front and end of the string, in-place.
std::string lowercase(std::string const &str)
Returns a lower-case version of the string.
A single argument option.
std::string lopt
Long option name.
std::string desc
Description.
bool argument
Requires argument?
char sopt
Short option name.
An argument which can either be an option or a non-option.
ArgOption const * opt
Null for non-options.
std::string arg
Empty for options without arguments.
#define UTIL_NAMESPACE_BEGIN
#define UTIL_NAMESPACE_END