// license:GPL-2.0+ // copyright-holders:Couriersud /* * poptions.cpp * */ #include "poptions.h" namespace plib { /*************************************************************************** Options ***************************************************************************/ option_base::option_base(options &parent, pstring help) : m_help(help) { parent.register_option(this); } option_base::~option_base() { } option_group::~option_group() { } option_example::~option_example() { } option::option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument) : option_base(parent, help), m_short(ashort), m_long(along), m_has_argument(has_argument), m_specified(false) { } option::~option() { } int option_str::parse(const pstring &argument) { m_val = argument; return 0; } int option_str_limit::parse(const pstring &argument) { if (plib::container::contains(m_limit, argument)) { m_val = argument; return 0; } else return 1; } int option_bool::parse(const pstring &argument) { m_val = true; return 0; } int option_double::parse(const pstring &argument) { bool err = false; m_val = argument.as_double(&err); return (err ? 1 : 0); } int option_long::parse(const pstring &argument) { bool err = false; m_val = argument.as_long(&err); return (err ? 1 : 0); } int option_vec::parse(const pstring &argument) { bool err = false; m_val.push_back(argument); return (err ? 1 : 0); } options::options() { } options::options(option *o[]) { int i=0; while (o[i] != nullptr) { m_opts.push_back(o[i]); i++; } } options::~options() { m_opts.clear(); } void options::register_option(option_base *opt) { m_opts.push_back(opt); } int options::parse(int argc, char *argv[]) { m_app = pstring(argv[0], pstring::UTF8); for (int i=1; i 1); if (has_equal_arg) { for (unsigned j = 1; j < v.size() - 1; j++) opt_arg = opt_arg + v[j] + "="; opt_arg += v[v.size()-1]; } } else if (arg.startsWith("-")) { std::size_t p = 1; opt = getopt_short(arg.substr(p, 1)); ++p; if (p < arg.length()) { has_equal_arg = true; opt_arg = arg.substr(p); } } else { return i; } if (opt == nullptr) return i; if (opt->has_argument()) { if (has_equal_arg) { if (opt->do_parse(opt_arg) != 0) return i; } else { i++; // FIXME: are there more arguments? if (opt->do_parse(pstring(argv[i], pstring::UTF8)) != 0) return i - 1; } } else { if (has_equal_arg) return i; opt->do_parse(""); } i++; } return argc; } pstring options::split_paragraphs(pstring text, unsigned width, unsigned indent, unsigned firstline_indent) { auto paragraphs = psplit(text,"\n"); pstring ret(""); for (auto &p : paragraphs) { pstring line = pstring("").rpad(" ", firstline_indent); for (auto &s : psplit(p, " ")) { if (line.length() + s.length() > width) { ret += line + "\n"; line = pstring("").rpad(" ", indent); } line += s + " "; } ret += line + "\n"; } return ret; } pstring options::help(pstring description, pstring usage, unsigned width, unsigned indent) { pstring ret; ret = split_paragraphs(description, width, 0, 0) + "\n"; ret += "Usage:\t" + usage + "\n\nOptions:\n\n"; for (auto & optbase : m_opts ) { if (auto opt = dynamic_cast