diff options
author | 2019-03-25 22:44:58 +0100 | |
---|---|---|
committer | 2019-03-25 22:44:58 +0100 | |
commit | c24473ddff715ecec2e258a6eb38960cf8c8e98e (patch) | |
tree | 8ea44b6396a6129913c0aac13859b5de9965e972 /src/lib/netlist/plib/poptions.cpp | |
parent | 009cba4fb8102102168ef32870892438327f3705 (diff) | |
parent | 598cd5227223c3b04ca31f0dbc1981256d9ea3ff (diff) |
conflict resolution (nw)
Diffstat (limited to 'src/lib/netlist/plib/poptions.cpp')
-rw-r--r-- | src/lib/netlist/plib/poptions.cpp | 154 |
1 files changed, 80 insertions, 74 deletions
diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index 910660acb3d..4a3d32c4723 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -6,77 +6,39 @@ */ #include "poptions.h" +#include "pexception.h" +#include "ptypes.h" namespace plib { /*************************************************************************** Options ***************************************************************************/ - option_base::option_base(options &parent, pstring help) + option_base::option_base(options &parent, const 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::option(options &parent, const pstring &ashort, const pstring &along, const 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) { + unused_var(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; @@ -85,53 +47,88 @@ namespace plib { } options::options() + : m_other_args(nullptr) { } - options::options(option *o[]) + options::options(option **o) + : m_other_args(nullptr) { int i=0; while (o[i] != nullptr) { - m_opts.push_back(o[i]); + register_option(o[i]); i++; } } - options::~options() + void options::register_option(option_base *opt) { - m_opts.clear(); + m_opts.push_back(opt); } - void options::register_option(option_base *opt) + void options::check_consistency() { - m_opts.push_back(opt); + for (auto &opt : m_opts) + { + auto *o = dynamic_cast<option *>(opt); + if (o != nullptr) + { + if (o->short_opt() == "" && o->long_opt() == "") + { + auto *ov = dynamic_cast<option_args *>(o); + if (ov != nullptr) + { + if (m_other_args != nullptr) + { + throw pexception("other args can only be specified once!"); + } + else + { + m_other_args = ov; + } + } + else + throw pexception("found option with neither short or long tag!" ); + } + } + } } - int options::parse(int argc, char *argv[]) + int options::parse(int argc, char **argv) { - m_app = pstring(argv[0], pstring::UTF8); + check_consistency(); + m_app = pstring(argv[0]); + bool seen_other_args = false; for (int i=1; i<argc; ) { - pstring arg(argv[i], pstring::UTF8); + pstring arg(argv[i]); option *opt = nullptr; pstring opt_arg; bool has_equal_arg = false; - if (arg.startsWith("--")) + if (!seen_other_args && plib::startsWith(arg, "--")) { auto v = psplit(arg.substr(2),"="); - opt = getopt_long(v[0]); - has_equal_arg = (v.size() > 1); - if (has_equal_arg) + if (v.size() && v[0] != pstring("")) { - for (unsigned j = 1; j < v.size() - 1; j++) - opt_arg = opt_arg + v[j] + "="; - opt_arg += v[v.size()-1]; + opt = getopt_long(v[0]); + has_equal_arg = (v.size() > 1); + if (has_equal_arg) + { + for (std::size_t j = 1; j < v.size() - 1; j++) + opt_arg = opt_arg + v[j] + "="; + opt_arg += v[v.size()-1]; + } + } + else + { + opt = m_other_args; + seen_other_args = true; } } - else if (arg.startsWith("-")) + else if (!seen_other_args && plib::startsWith(arg, "-")) { std::size_t p = 1; opt = getopt_short(arg.substr(p, 1)); @@ -144,7 +141,11 @@ namespace plib { } else { - return i; + seen_other_args = true; + if (m_other_args == nullptr) + return i; + opt = m_other_args; + i--; // we haven't had an option specifier; } if (opt == nullptr) return i; @@ -158,7 +159,7 @@ namespace plib { else { i++; // FIXME: are there more arguments? - if (opt->do_parse(pstring(argv[i], pstring::UTF8)) != 0) + if (opt->do_parse(pstring(argv[i])) != 0) return i - 1; } } @@ -173,7 +174,7 @@ namespace plib { return argc; } - pstring options::split_paragraphs(pstring text, unsigned width, unsigned indent, + pstring options::split_paragraphs(const pstring &text, unsigned width, unsigned indent, unsigned firstline_indent) { auto paragraphs = psplit(text,"\n"); @@ -181,13 +182,13 @@ namespace plib { for (auto &p : paragraphs) { - pstring line = pstring("").rpad(" ", firstline_indent); + pstring line = plib::rpad(pstring(""), pstring(" "), firstline_indent); for (auto &s : psplit(p, " ")) { if (line.length() + s.length() > width) { ret += line + "\n"; - line = pstring("").rpad(" ", indent); + line = plib::rpad(pstring(""), pstring(" "), indent); } line += s + " "; } @@ -196,8 +197,8 @@ namespace plib { return ret; } - pstring options::help(pstring description, pstring usage, - unsigned width, unsigned indent) + pstring options::help(const pstring &description, const pstring &usage, + unsigned width, unsigned indent) const { pstring ret; @@ -206,6 +207,10 @@ namespace plib { for (auto & optbase : m_opts ) { + // Skip anonymous inputs which are collected in option_args + if (dynamic_cast<option_args *>(optbase) != nullptr) + continue; + if (auto opt = dynamic_cast<option *>(optbase)) { pstring line = ""; @@ -221,20 +226,20 @@ namespace plib { if (opt->has_argument()) { line += "="; - option_str_limit *ol = dynamic_cast<option_str_limit *>(opt); + auto *ol = dynamic_cast<option_str_limit_base *>(opt); if (ol) { for (auto &v : ol->limit()) { line += v + "|"; } - line = line.left(line.length() - 1); + line = plib::left(line, line.length() - 1); } else line += "Value"; } } - line = line.rpad(" ", indent - 2) + " "; + line = plib::rpad(line, pstring(" "), indent - 2) + " "; if (line.length() > indent) { //ret += "TestGroup abc\n def gef\nxyz\n\n" ; @@ -250,6 +255,7 @@ namespace plib { if (grp->help() != "") ret += split_paragraphs(grp->help(), width, 4, 4) + "\n"; } } + // FIXME: other help ... pstring ex(""); for (auto & optbase : m_opts ) { @@ -266,22 +272,22 @@ namespace plib { return ret; } - option *options::getopt_short(pstring arg) + option *options::getopt_short(const pstring &arg) const { for (auto & optbase : m_opts) { auto opt = dynamic_cast<option *>(optbase); - if (opt && opt->short_opt() == arg) + if (opt && arg != "" && opt->short_opt() == arg) return opt; } return nullptr; } - option *options::getopt_long(pstring arg) + option *options::getopt_long(const pstring &arg) const { for (auto & optbase : m_opts) { auto opt = dynamic_cast<option *>(optbase); - if (opt && opt->long_opt() == arg) + if (opt && arg !="" && opt->long_opt() == arg) return opt; } return nullptr; |