From 1415421fd707ad02e0cfddf20bf70bbd045a9203 Mon Sep 17 00:00:00 2001 From: couriersud Date: Sun, 6 Jan 2019 13:17:20 +0100 Subject: More c++ alignment. pstring now behaves like std::string. (nw) This change removes all string extensions like trim, rpad, left, right, ... from pstring and replaces them by function templates. This aligns a lot better with the intentions of the standard library. --- src/lib/netlist/plib/poptions.cpp | 42 +++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'src/lib/netlist/plib/poptions.cpp') diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index 910660acb3d..d576eff0bb2 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -65,16 +65,28 @@ namespace plib { int option_double::parse(const pstring &argument) { - bool err = false; - m_val = argument.as_double(&err); - return (err ? 1 : 0); + try + { + m_val = plib::pstod(argument); + return 0; + } + catch (...) + { + return 1; + } } int option_long::parse(const pstring &argument) { - bool err = false; - m_val = argument.as_long(&err); - return (err ? 1 : 0); + try + { + m_val = plib::pstol(argument); + return 0; + } + catch (...) + { + return 1; + } } int option_vec::parse(const pstring &argument) @@ -110,16 +122,16 @@ namespace plib { int options::parse(int argc, char *argv[]) { - m_app = pstring(argv[0], pstring::UTF8); + m_app = pstring(argv[0]); for (int i=1; ido_parse(pstring(argv[i], pstring::UTF8)) != 0) + if (opt->do_parse(pstring(argv[i])) != 0) return i - 1; } } @@ -181,13 +193,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 + " "; } @@ -228,13 +240,13 @@ namespace plib { { 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" ; -- cgit v1.2.3-70-g09d2 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/devices/net_lib.cpp | 2 +- src/lib/netlist/devices/nlid_system.h | 4 +- src/lib/netlist/devices/nlid_truthtable.cpp | 3 +- src/lib/netlist/nl_base.cpp | 4 +- src/lib/netlist/nl_config.h | 1 - src/lib/netlist/nl_parser.cpp | 8 +-- src/lib/netlist/nl_setup.cpp | 13 +++-- src/lib/netlist/plib/pfunction.cpp | 4 +- src/lib/netlist/plib/poptions.cpp | 40 +------------ src/lib/netlist/plib/poptions.h | 91 ++++++++++++++++++++--------- src/lib/netlist/plib/pparser.cpp | 15 +++-- src/lib/netlist/plib/pstring.h | 77 ++++++++++++++---------- src/lib/netlist/plib/putil.cpp | 30 ++++++++++ src/lib/netlist/plib/putil.h | 5 ++ src/lib/netlist/prg/nltool.cpp | 18 +++--- src/lib/netlist/prg/nlwav.cpp | 4 +- src/lib/netlist/solver/nld_solver.cpp | 2 +- src/lib/netlist/tools/nl_convert.cpp | 9 +-- 18 files changed, 197 insertions(+), 133 deletions(-) (limited to 'src/lib/netlist/plib/poptions.cpp') diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp index 30ddf3af84c..dd77be5a9a2 100644 --- a/src/lib/netlist/devices/net_lib.cpp +++ b/src/lib/netlist/devices/net_lib.cpp @@ -74,7 +74,7 @@ namespace netlist ENTRYX(7485, TTL_7485, "+A0,+A1,+A2,+A3,+B0,+B1,+B2,+B3,+LTIN,+EQIN,+GTIN") ENTRYX(7490, TTL_7490, "+A,+B,+R1,+R2,+R91,+R92") ENTRYX(7493, TTL_7493, "+CLKA,+CLKB,+R1,+R2") - ENTRYX(7497, TTL_7497, "+CLK,+STRB,+EN,+UNITY,+CLR,+B0,+B1,+B2,+B3,+B4,+B5") + ENTRYX(7497, TTL_7497, "+CLK,+STRBQ,+ENQ,+UNITYQ,+CLR,+B0,+B1,+B2,+B3,+B4,+B5") ENTRYX(74107, TTL_74107, "+CLK,+J,+K,+CLRQ") ENTRYX(74107A, TTL_74107A, "+CLK,+J,+K,+CLRQ") ENTRYX(74123, TTL_74123, "") diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 881cce03592..5a874aef3df 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -136,7 +136,9 @@ namespace netlist unsigned long total = 0; for (unsigned i=0; i(plib::pstol(pat[i])); + // FIXME: use pstonum_ne + //pati[i] = plib::pstonum(pat[i]); + pati[i] = plib::pstonum(pat[i]); total += pati[i]; } netlist_time ttotal = netlist_time::zero(); diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp index c3449d5b604..dbb9401425d 100644 --- a/src/lib/netlist/devices/nlid_truthtable.cpp +++ b/src/lib/netlist/devices/nlid_truthtable.cpp @@ -407,7 +407,8 @@ void truthtable_parser::parse(const std::vector &truthtable) val.set(j); else nl_assert_always(outs == "0", "Unknown value (not 0 or 1"); - netlist_time t = netlist_time::from_nsec(static_cast(plib::pstol(plib::trim(times[j])))); + // FIXME: error handling + netlist_time t = netlist_time::from_nsec(plib::pstonum(plib::trim(times[j]))); uint_least8_t k=0; while (m_timing_nt[k] != netlist_time::zero() && m_timing_nt[k] != t) k++; diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 5b132ebd554..a0eabcc7fbe 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -343,8 +343,8 @@ void netlist_t::start() auto p = setup().m_param_values.find(d->name() + ".HINT_NO_DEACTIVATE"); if (p != setup().m_param_values.end()) { - //FIXME: turn this into a proper function - auto v = plib::pstod(p->second);; + //FIXME: check for errors ... + double v = plib::pstonum(p->second);; if (std::abs(v - std::floor(v)) > 1e-6 ) log().fatal(MF_1_HND_VAL_NOT_SUPPORTED, p->second); d->set_hint_deactivate(v == 0.0); diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index d2f4dc75511..20ddf5c71a3 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -26,7 +26,6 @@ * linear memory pool. This is based of the assumption that * due to enhanced locality there will be less cache misses. * Your mileage may vary. - * This will cause crashes on OSX and thus is ignored on OSX. * */ #define USE_MEMPOOL (0) diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp index a6a805826ce..1ff6ef6c6b7 100644 --- a/src/lib/netlist/nl_parser.cpp +++ b/src/lib/netlist/nl_parser.cpp @@ -403,7 +403,6 @@ nl_double parser_t::eval_param(const token_t tok) int i; int f=0; nl_double ret; - pstring val; for (i=1; i<6;i++) if (tok.str() == macs[i]) @@ -416,9 +415,10 @@ nl_double parser_t::eval_param(const token_t tok) } else { - val = tok.str(); - if (!plib::pstod_ne(val, ret)) - error(plib::pfmt("Parameter value <{1}> not double \n")(val)); + bool err; + ret = plib::pstonum_ne(tok.str(), err); + if (err) + error(plib::pfmt("Parameter value <{1}> not double \n")(tok.str())); } return ret * facs[f]; diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index cf89e4a8fae..28385d984cf 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -159,8 +159,9 @@ double setup_t::get_initial_param_val(const pstring &name, const double def) auto i = m_param_values.find(name); if (i != m_param_values.end()) { - double vald = 0; - if (!plib::pstod_ne(i->second, vald)) + bool err = false; + double vald = plib::pstonum_ne(i->second, err); + if (err) log().fatal(MF_2_INVALID_NUMBER_CONVERSION_1_2, name, i->second); return vald; } @@ -173,8 +174,9 @@ int setup_t::get_initial_param_val(const pstring &name, const int def) auto i = m_param_values.find(name); if (i != m_param_values.end()) { - long vald = 0; - if (!plib::pstod_ne(i->second, vald)) + bool err; + double vald = plib::pstonum_ne(i->second, err); + if (err) log().fatal(MF_2_INVALID_NUMBER_CONVERSION_1_2, name, i->second); if (vald - std::floor(vald) != 0.0) log().fatal(MF_2_INVALID_NUMBER_CONVERSION_1_2, name, i->second); @@ -872,7 +874,8 @@ nl_double setup_t::model_value(detail::model_map_t &map, const pstring &entity) } if (factor != NL_FCONST(1.0)) tmp = plib::left(tmp, tmp.size() - 1); - return plib::pstod(tmp) * factor; + // FIXME: check for errors + return plib::pstonum(tmp) * factor; } class logic_family_std_proxy_t : public logic_family_desc_t diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp index e9e2de009c8..f2ef3522813 100644 --- a/src/lib/netlist/plib/pfunction.cpp +++ b/src/lib/netlist/plib/pfunction.cpp @@ -69,7 +69,9 @@ void pfunction::compile_postfix(const std::vector &inputs, if (rc.m_cmd != PUSH_INPUT) { rc.m_cmd = PUSH_CONST; - if (!plib::pstod_ne(cmd, rc.m_param)) + bool err; + rc.m_param = plib::pstonum_ne(cmd, err); + if (err) throw plib::pexception(plib::pfmt("nld_function: unknown/misformatted token <{1}> in <{2}>")(cmd)(expr)); stk += 1; } diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index d576eff0bb2..c790d1f55af 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -46,49 +46,13 @@ namespace plib { 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) - { - try - { - m_val = plib::pstod(argument); - return 0; - } - catch (...) - { - return 1; - } - } - - int option_long::parse(const pstring &argument) - { - try - { - m_val = plib::pstol(argument); - return 0; - } - catch (...) - { - return 1; - } - } - int option_vec::parse(const pstring &argument) { bool err = false; @@ -233,7 +197,7 @@ namespace plib { if (opt->has_argument()) { line += "="; - option_str_limit *ol = dynamic_cast(opt); + option_str_limit_base *ol = dynamic_cast(opt); if (ol) { for (auto &v : ol->limit()) 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); diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp index 298fa589fba..b18b3265440 100644 --- a/src/lib/netlist/plib/pparser.cpp +++ b/src/lib/netlist/plib/pparser.cpp @@ -122,6 +122,7 @@ pstring ptokenizer::get_identifier_or_number() return tok.str(); } +// FIXME: combine into template double ptokenizer::get_number_double() { token_t tok = get_token(); @@ -129,9 +130,9 @@ double ptokenizer::get_number_double() { error(pfmt("Expected a number, got <{1}>")(tok.str()) ); } - double ret = 0.0; - - if (!plib::pstod_ne(tok.str(), ret)) + bool err; + double ret = plib::pstonum_ne(tok.str(), err); + if (err) error(pfmt("Expected a number, got <{1}>")(tok.str()) ); return ret; } @@ -143,8 +144,9 @@ long ptokenizer::get_number_long() { error(pfmt("Expected a long int, got <{1}>")(tok.str()) ); } - long ret = 0; - if (!plib::pstol_ne(tok.str(), ret)) + bool err; + long ret = plib::pstonum_ne(tok.str(), err); + if (err) error(pfmt("Expected a long int, got <{1}>")(tok.str()) ); return ret; } @@ -326,7 +328,8 @@ double ppreprocessor::expr(const std::vector &sexpr, std::size_t &start else { tok=sexpr[start]; - val = plib::pstod(tok); + // FIXME: error handling + val = plib::pstonum(tok); start++; } while (start < sexpr.size()) diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h index 67104a54213..677ce9e43b8 100644 --- a/src/lib/netlist/plib/pstring.h +++ b/src/lib/netlist/plib/pstring.h @@ -9,8 +9,10 @@ #include #include +#include #include #include +#include #include // ---------------------------------------------------------------------------------------- @@ -518,57 +520,72 @@ namespace plib return pwstring(std::to_wstring(v)); } -#if (PSTRING_USE_STD_STRING) - inline double pstod(const std::string &str, std::size_t *e = nullptr) - { - return std::stod(str, e); - } + template + struct pstonum_helper; - inline long pstol(const std::string &str, std::size_t *e = nullptr, int base = 10) + template + struct pstonum_helper::value + && std::is_signed::value>::type> { - return std::stol(str, e, base); - } -#else + template + long long operator()(const S &arg, std::size_t *idx) + { + return std::stoll(arg, idx); + } + }; + template - double pstod(const T &str, std::size_t *e = nullptr) + struct pstonum_helper::value + && !std::is_signed::value>::type> { - return std::stod(str.cpp_string(), e); - } + template + unsigned long long operator()(const S &arg, std::size_t *idx) + { + return std::stoull(arg, idx); + } + }; template - long pstol(const T &str, std::size_t *e = nullptr, int base = 10) + struct pstonum_helper::value>::type> { - return std::stol(str.cpp_string(), e, base); - } -#endif + template + long double operator()(const S &arg, std::size_t *idx) + { + return std::stold(arg, idx); + } + }; - template - bool pstol_ne(const T &str, R &ret) + template + T pstonum(const S &arg) { - try + decltype(arg.c_str()) cstr = arg.c_str(); + std::size_t idx(0); + auto ret = pstonum_helper()(cstr, &idx); + if (ret >= std::numeric_limits::lowest() && ret <= std::numeric_limits::max()) + //&& (ret == T(0) || std::abs(ret) >= std::numeric_limits::min() )) { - std::size_t e = 0; - ret = pstol(str, &e); - return str.c_str()[e] == 0; + if (cstr[idx] != 0) + throw std::invalid_argument(std::string("Continuation after numeric value ends: ") + cstr); } - catch (...) + else { - return false; + throw std::out_of_range(std::string("Out of range: ") + cstr); } + return static_cast(ret); } - template - bool pstod_ne(const T &str, R &ret) + template + R pstonum_ne(const T &str, bool &err) noexcept { try { - std::size_t e = 0; - ret = pstod(str, &e); - return str.c_str()[e] == 0; + err = false; + return pstonum(str); } catch (...) { - return false; + err = true; + return R(0); } } diff --git a/src/lib/netlist/plib/putil.cpp b/src/lib/netlist/plib/putil.cpp index 0d3a0ebca3f..92e0e6b3ab1 100644 --- a/src/lib/netlist/plib/putil.cpp +++ b/src/lib/netlist/plib/putil.cpp @@ -64,6 +64,36 @@ namespace plib return ret; } + std::vector psplit_r(const std::string &stri, + const std::string &token, + const std::size_t maxsplit) + { + std::string str(stri); + std::vector result; + std::size_t splits = 0; + + while(str.size()) + { + std::size_t index = str.rfind(token); + bool found = index!=std::string::npos; + if (found) + splits++; + if ((splits <= maxsplit || maxsplit == 0) && found) + { + result.push_back(str.substr(index+token.size())); + str = str.substr(0, index); + if (str.size()==0) + result.push_back(str); + } + else + { + result.push_back(str); + str = ""; + } + } + return result; + } + std::vector psplit(const pstring &str, const std::vector &onstrl) { pstring col = ""; diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h index 8d59c0357e2..914d9820560 100644 --- a/src/lib/netlist/plib/putil.h +++ b/src/lib/netlist/plib/putil.h @@ -16,6 +16,11 @@ namespace plib { + + // Avoid unused variable warnings + template + inline void unused_var(Ts&&...) {} + namespace util { const pstring buildpath(std::initializer_list list ); diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 4fcb4ebdc30..4395bd3bd17 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -23,7 +23,7 @@ public: tool_app_t() : plib::app(), opt_grp1(*this, "General options", "The following options apply to all commands."), - opt_cmd (*this, "c", "cmd", "run", "run:convert:listdevices:static:header:docheader", "run|convert|listdevices|static|header"), + opt_cmd (*this, "c", "cmd", 0, std::vector({"run","convert","listdevices","static","header","docheader"}), "run|convert|listdevices|static|header|docheader"), opt_file(*this, "f", "file", "-", "file to process (default is stdin)"), opt_defines(*this, "D", "define", "predefine value as macro, e.g. -Dname=value. If '=value' is omitted predefine it as 1. This option may be specified repeatedly."), opt_rfolders(*this, "r", "rom", "where to look for data files"), @@ -40,7 +40,7 @@ public: opt_loadstate(*this,"", "loadstate", "", "load state from file and continue from there"), opt_savestate(*this,"", "savestate", "", "save state to file at end of run"), opt_grp4(*this, "Options for convert command", "These options are only used by the convert command."), - opt_type(*this, "y", "type", "spice", "spice:eagle:rinf", "type of file to be converted: spice,eagle,rinf"), + opt_type(*this, "y", "type", 0, std::vector({"spice","eagle","rinf"}), "type of file to be converted: spice,eagle,rinf"), opt_ex1(*this, "nltool -c run -t 3.5 -f nl_examples/cdelay.c -n cap_delay", "Run netlist \"cap_delay\" from file nl_examples/cdelay.c for 3.5 seconds"), @@ -49,7 +49,7 @@ public: {} plib::option_group opt_grp1; - plib::option_str_limit opt_cmd; + plib::option_str_limit opt_cmd; plib::option_str opt_file; plib::option_vec opt_defines; plib::option_vec opt_rfolders; @@ -60,13 +60,13 @@ public: plib::option_group opt_grp2; plib::option_str opt_name; plib::option_group opt_grp3; - plib::option_double opt_ttr; + plib::option_num opt_ttr; plib::option_vec opt_logs; plib::option_str opt_inp; plib::option_str opt_loadstate; plib::option_str opt_savestate; plib::option_group opt_grp4; - plib::option_str_limit opt_type; + plib::option_str_limit opt_type; plib::option_example opt_ex1; plib::option_example opt_ex2; @@ -706,7 +706,7 @@ int tool_app_t::execute() try { - pstring cmd = opt_cmd(); + pstring cmd = opt_cmd.as_string(); if (cmd == "listdevices") listdevices(); else if (cmd == "run") @@ -734,19 +734,19 @@ int tool_app_t::execute() contents = ostrm.str(); pstring result; - if (opt_type() == "spice") + if (opt_type.as_string() == "spice") { nl_convert_spice_t c; c.convert(contents); result = c.result(); } - else if (opt_type() == "eagle") + else if (opt_type.as_string() == "eagle") { nl_convert_eagle_t c; c.convert(contents); result = c.result(); } - else if (opt_type() == "rinf") + else if (opt_type.as_string() == "rinf") { nl_convert_rinf_t c; c.convert(contents); diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index 23491e88349..a1f14692364 100644 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -24,8 +24,8 @@ public: {} plib::option_str opt_inp; plib::option_str opt_out; - plib::option_double opt_amp; - plib::option_long opt_rate; + plib::option_num opt_amp; + plib::option_num opt_rate; plib::option_bool opt_verb; plib::option_bool opt_quiet; plib::option_bool opt_version; diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 2158d725694..ad62ba17c28 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -268,7 +268,7 @@ void NETLIB_NAME(solver)::post_start() // Override log statistics pstring p = plib::util::environment("NL_STATS", ""); if (p != "") - m_params.m_log_stats = plib::pstol(p); + m_params.m_log_stats = plib::pstonum(p); else m_params.m_log_stats = m_log_stats(); diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp index aff7d0da81b..4488396a131 100644 --- a/src/lib/netlist/tools/nl_convert.cpp +++ b/src/lib/netlist/tools/nl_convert.cpp @@ -214,7 +214,7 @@ double nl_convert_base_t::get_sp_val(const pstring &sin) ++p; pstring val = plib::left(sin, p); pstring unit = sin.substr(p); - double ret = get_sp_unit(unit) * plib::pstod(val); + double ret = get_sp_unit(unit) * plib::pstonum(val); return ret; } @@ -304,11 +304,12 @@ void nl_convert_spice_t::process_line(const pstring &line) /* check for fourth terminal ... should be numeric net * including "0" or start with "N" (ltspice) */ - long nval = 0; pstring model; pstring pins ="CBE"; + bool err; + ATTR_UNUSED long nval = plib::pstonum_ne(tt[4], err); - if ((!plib::pstol_ne(tt[4], nval) || plib::startsWith(tt[4], "N")) && tt.size() > 5) + if ((err || plib::startsWith(tt[4], "N")) && tt.size() > 5) model = tt[5]; else model = tt[4]; @@ -492,7 +493,7 @@ void nl_convert_eagle_t::convert(const pstring &contents) else if (plib::ucase(sval) == "LOW") add_device("TTL_INPUT", name, 0); else - add_device("ANALOG_INPUT", name, plib::pstod(sval)); + add_device("ANALOG_INPUT", name, plib::pstonum(sval)); add_pin_alias(name, "1", "Q"); break; case 'D': -- cgit v1.2.3-70-g09d2 From 9c7037d6c64f2e6f6b0aa221900944530b9f985f Mon Sep 17 00:00:00 2001 From: couriersud Date: Sun, 13 Jan 2019 01:01:43 +0100 Subject: Replace ATTR_UNUSED by c++ template. (nw) --- src/lib/netlist/nl_base.h | 12 ++++++------ src/lib/netlist/plib/pconfig.h | 2 -- src/lib/netlist/plib/poptions.cpp | 1 + src/lib/netlist/plib/ptypes.h | 8 ++++++++ src/lib/netlist/plib/putil.h | 4 ---- src/lib/netlist/solver/nld_matrix_solver.cpp | 4 +++- src/lib/netlist/solver/nld_solver.cpp | 10 ++++++++-- src/lib/netlist/tools/nl_convert.cpp | 3 ++- 8 files changed, 28 insertions(+), 16 deletions(-) (limited to 'src/lib/netlist/plib/poptions.cpp') diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 27291a85f39..24129821b4b 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -181,6 +181,11 @@ class NETLIB_NAME(name) : public device_t namespace netlist { + /*! Delegate type for device notification. + * + */ + typedef plib::pmfp nldelegate; + // ----------------------------------------------------------------------------- // forward definitions // ----------------------------------------------------------------------------- @@ -474,11 +479,6 @@ namespace netlist core_device_t & m_device; }; - /*! Delegate type for device notification. - * - */ - typedef plib::pmfp nldelegate; - // ----------------------------------------------------------------------------- // core_terminal_t // ----------------------------------------------------------------------------- @@ -1118,7 +1118,7 @@ namespace netlist plib::plog_base &log(); public: - virtual void timestep(ATTR_UNUSED const nl_double st) { } + virtual void timestep(const nl_double st) { plib::unused_var(st); } virtual void update_terminals() { } virtual void update_param() {} diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index 0200c305ecd..dddaf0de86a 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -73,10 +73,8 @@ typedef __int128_t INT128; #undef RESTRICT #endif #define RESTRICT __restrict__ -#define ATTR_UNUSED __attribute__((__unused__)) #else #define RESTRICT -#define ATTR_UNUSED #endif //============================================================ diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index c790d1f55af..de00f9efa4a 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -6,6 +6,7 @@ */ #include "poptions.h" +#include "ptypes.h" namespace plib { /*************************************************************************** diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h index d09575fed56..8b6b7ff7914 100644 --- a/src/lib/netlist/plib/ptypes.h +++ b/src/lib/netlist/plib/ptypes.h @@ -65,6 +65,14 @@ namespace plib nocopyassign &operator=(const nocopyassign &) = delete; }; + //============================================================ + // Avoid unused variable warnings + //============================================================ + template + inline void unused_var(Ts&&...) {} + + + //============================================================ // penum - strongly typed enumeration //============================================================ diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h index 05cc44f5f68..ed27867af6b 100644 --- a/src/lib/netlist/plib/putil.h +++ b/src/lib/netlist/plib/putil.h @@ -17,10 +17,6 @@ namespace plib { - // Avoid unused variable warnings - template - inline void unused_var(Ts&&...) {} - namespace util { const pstring buildpath(std::initializer_list list ); diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp index 87c9b46ba21..0b2e89df08f 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.cpp +++ b/src/lib/netlist/solver/nld_matrix_solver.cpp @@ -390,7 +390,9 @@ void matrix_solver_t::update() NL_NOEXCEPT void matrix_solver_t::update_forced() { - ATTR_UNUSED const netlist_time new_timestep = solve(); + const netlist_time new_timestep = solve(); + plib::unused_var(new_timestep); + update_inputs(); if (m_params.m_dynamic_ts && has_timestep_devices()) diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 09f0173b339..ad75bcaf6ca 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -104,12 +104,18 @@ NETLIB_UPDATE(solver) { plib::omp::set_num_threads(nthreads); plib::omp::for_static(static_cast(0), t_cnt, [this, &solv](std::size_t i) - { ATTR_UNUSED const netlist_time ts = this->m_mat_solvers[solv[i]]->solve(); }); + { + const netlist_time ts = this->m_mat_solvers[solv[i]]->solve(); + plib::unused_var(ts); + }); } else for (auto & solver : m_mat_solvers) if (solver->has_timestep_devices() || force_solve) - ATTR_UNUSED const netlist_time ts = solver->solve(); + { + const netlist_time ts = solver->solve(); + plib::unused_var(ts); + }; for (auto & solver : m_mat_solvers) if (solver->has_timestep_devices() || force_solve) diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp index 6b6f3925a5a..52665ce1f78 100644 --- a/src/lib/netlist/tools/nl_convert.cpp +++ b/src/lib/netlist/tools/nl_convert.cpp @@ -306,7 +306,8 @@ void nl_convert_spice_t::process_line(const pstring &line) pstring model; pstring pins ="CBE"; bool err; - ATTR_UNUSED long nval = plib::pstonum_ne(tt[4], err); + long nval = plib::pstonum_ne(tt[4], err); + plib::unused_var(nval); if ((err || plib::startsWith(tt[4], "N")) && tt.size() > 5) model = tt[5]; -- 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.cpp') 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