From 4213a396d8652e7ea26c07c133932bd9f5a87faa Mon Sep 17 00:00:00 2001 From: couriersud Date: Thu, 10 Jan 2019 00:30:51 +0100 Subject: Improve type safety on string->numeric conversions. (nw) Also fixed an issue with 7497. ./nltool -t 5 -f src/mame/machine/nl_tp1983.cpp -v now runs again. --- src/lib/netlist/plib/poptions.h | 91 +++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 27 deletions(-) (limited to 'src/lib/netlist/plib/poptions.h') diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h index 491ac0b4d91..f3be4b061dd 100644 --- a/src/lib/netlist/plib/poptions.h +++ b/src/lib/netlist/plib/poptions.h @@ -102,72 +102,98 @@ private: pstring m_val; }; -class option_str_limit : public option +class option_str_limit_base : public option { public: - option_str_limit(options &parent, pstring ashort, pstring along, pstring defval, pstring limit, pstring help) - : option(parent, ashort, along, help, true), m_val(defval) - , m_limit(plib::psplit(limit, ":")) + option_str_limit_base(options &parent, pstring ashort, pstring along, std::vector &&limit, pstring help) + : option(parent, ashort, along, help, true) + , m_limit(limit) { } - - pstring operator ()() { return m_val; } - const std::vector &limit() { return m_limit; } + const std::vector &limit() const { return m_limit; } protected: - virtual int parse(const pstring &argument) override; private: - pstring m_val; std::vector m_limit; }; -class option_bool : public option + +template +class option_str_limit : public option_str_limit_base { public: - option_bool(options &parent, pstring ashort, pstring along, pstring help) - : option(parent, ashort, along, help, false), m_val(false) - {} + option_str_limit(options &parent, pstring ashort, pstring along, const T &defval, std::vector &&limit, pstring help) + : option_str_limit_base(parent, ashort, along, std::move(limit), help), m_val(defval) + { + } - bool operator ()() { return m_val; } + T operator ()() { return m_val; } + + pstring as_string() const { return limit()[m_val]; } protected: - virtual int parse(const pstring &argument) override; + virtual int parse(const pstring &argument) override + { + auto raw = plib::container::indexof(limit(), argument); + + if (raw != plib::container::npos) + { + m_val = static_cast(raw); + return 0; + } + else + return 1; + } private: - bool m_val; + T m_val; }; -class option_double : public option +class option_bool : public option { public: - option_double(options &parent, pstring ashort, pstring along, double defval, pstring help) - : option(parent, ashort, along, help, true), m_val(defval) + option_bool(options &parent, pstring ashort, pstring along, pstring help) + : option(parent, ashort, along, help, false), m_val(false) {} - double operator ()() { return m_val; } + bool operator ()() { return m_val; } protected: virtual int parse(const pstring &argument) override; private: - double m_val; + bool m_val; }; -class option_long : public option +template +class option_num : public option { public: - option_long(options &parent, pstring ashort, pstring along, long defval, pstring help) - : option(parent, ashort, along, help, true), m_val(defval) + option_num(options &parent, pstring ashort, pstring along, T defval, + pstring help, + T minval = std::numeric_limits::min(), + T maxval = std::numeric_limits::max() ) + : option(parent, ashort, along, help, true) + , m_val(defval) + , m_min(minval) + , m_max(maxval) {} - long operator ()() { return m_val; } + T operator ()() { return m_val; } protected: - virtual int parse(const pstring &argument) override; + virtual int parse(const pstring &argument) override + { + bool err; + m_val = pstonum_ne(argument, err); + return (err ? 1 : (m_val < m_min || m_val > m_max)); + } private: - long m_val; + T m_val; + T m_min; + T m_max; }; class option_vec : public option @@ -207,6 +233,17 @@ private: static pstring split_paragraphs(pstring text, unsigned width, unsigned indent, unsigned firstline_indent); + template + T *getopt_type() + { + for (auto & optbase : m_opts ) + { + if (auto opt = dynamic_cast(optbase)) + return opt; + } + return nullptr; + } + option *getopt_short(pstring arg); option *getopt_long(pstring arg); -- cgit v1.2.3-70-g09d2 From 83d558d0962efbb20cfa8e3589b9377e10818e1c Mon Sep 17 00:00:00 2001 From: couriersud Date: Sat, 19 Jan 2019 23:37:01 +0100 Subject: netlist: nlwav now also converts log files to VCD format. [couriersud] Please refer to nlwav --help for examples. There is also an example how to create multi-channel wav files. --- src/lib/netlist/nl_base.h | 4 +- src/lib/netlist/plib/poptions.cpp | 74 +++++- src/lib/netlist/plib/poptions.h | 11 + src/lib/netlist/plib/pstream.h | 4 +- src/lib/netlist/prg/nlwav.cpp | 501 ++++++++++++++++++++++++-------------- src/mame/audio/nl_kidniki.cpp | 10 +- 6 files changed, 398 insertions(+), 206 deletions(-) (limited to 'src/lib/netlist/plib/poptions.h') diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index f09715bbbc4..97f83735028 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -1064,7 +1064,7 @@ namespace netlist protected: virtual void changed() override { - stream()->read(&m_data[0],1<read(reinterpret_cast(&m_data[0]),1<read(&m_data[0],1<read(reinterpret_cast(&m_data[0]),1<(opt); + if (o != nullptr) + { + if (o->short_opt() == "" && o->long_opt() == "") + { + option_args *ov = dynamic_cast(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[]) { + check_consistency(); m_app = pstring(argv[0]); + bool seen_other_args = false; for (int i=1; i 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 (unsigned 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 (plib::startsWith(arg, "-")) + else if (!seen_other_args && plib::startsWith(arg, "-")) { std::size_t p = 1; opt = getopt_short(arg.substr(p, 1)); @@ -121,7 +162,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; @@ -183,6 +228,10 @@ namespace plib { for (auto & optbase : m_opts ) { + // Skip anonymous inputs which are collected in option_args + if (dynamic_cast(optbase) != nullptr) + continue; + if (auto opt = dynamic_cast