From 67dc264e22edad3f2b67bcc3573587ca3b2eb2a0 Mon Sep 17 00:00:00 2001 From: couriersud Date: Sat, 16 Nov 2019 16:08:48 +0100 Subject: netlist: more code maintenance. (nw) - refactor error messages. - Fix some drivers to cope with outputted added my the mame driver for video and sound. - Fix validation. --- src/lib/netlist/devices/nlid_proxy.cpp | 2 +- src/lib/netlist/devices/nlid_proxy.h | 8 +- src/lib/netlist/nl_base.cpp | 1 + src/lib/netlist/nl_base.h | 23 ++ src/lib/netlist/nl_errstr.h | 24 +- src/lib/netlist/nl_parser.cpp | 123 +++--- src/lib/netlist/nl_parser.h | 5 +- src/lib/netlist/nl_setup.cpp | 1 - src/lib/netlist/nl_setup.h | 18 - src/lib/netlist/plib/pfmtlog.h | 661 +++++++++++++++++---------------- src/lib/netlist/plib/ptokenizer.cpp | 73 ++-- src/lib/netlist/plib/ptokenizer.h | 9 +- src/lib/netlist/prg/nltool.cpp | 2 +- src/lib/netlist/solver/nld_ms_gcr.h | 18 +- src/lib/netlist/tools/nl_convert.cpp | 8 +- 15 files changed, 502 insertions(+), 474 deletions(-) (limited to 'src/lib') diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp index d59e7416e12..92db2af4d9b 100644 --- a/src/lib/netlist/devices/nlid_proxy.cpp +++ b/src/lib/netlist/devices/nlid_proxy.cpp @@ -122,7 +122,7 @@ namespace netlist register_subalias("Q", m_RN.m_P); log().verbose("D/A Proxy: Found power terminals on device {1}", out_proxied->device().name()); - if (anetlist.setup().is_extended_validation()) + if (anetlist.is_extended_validation()) { // During validation, don't connect to terminals found // This will cause terminals not connected to a rail net to diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h index 0e1b51c9ca7..936d03f8fb6 100644 --- a/src/lib/netlist/devices/nlid_proxy.h +++ b/src/lib/netlist/devices/nlid_proxy.h @@ -61,9 +61,9 @@ namespace devices nld_a_to_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *in_proxied); - virtual logic_output_t &out() noexcept override { return m_Q; } + logic_output_t &out() noexcept override { return m_Q; } - virtual detail::core_terminal_t &proxy_term() noexcept override + detail::core_terminal_t &proxy_term() noexcept override { return m_I; } @@ -99,9 +99,9 @@ namespace devices nld_d_to_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *out_proxied); - virtual logic_input_t &in() noexcept override { return m_I; } + logic_input_t &in() noexcept override { return m_I; } - virtual detail::core_terminal_t &proxy_term() noexcept override + detail::core_terminal_t &proxy_term() noexcept override { return m_RN.m_P; } diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index c161c9ea80b..84762b39901 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -201,6 +201,7 @@ namespace netlist , m_state() , m_callbacks(std::move(callbacks)) // Order is important here , m_log(*m_callbacks) + , m_extended_validation(false) { pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"})); m_lib = plib::make_unique(libpath); diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index bcff0162fa6..2c53aab7a9c 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -1539,6 +1539,25 @@ namespace netlist // memory pool - still needed in some places nlmempool &pool() noexcept { return m_pool; } const nlmempool &pool() const noexcept { return m_pool; } + + /// \brief set extended validation mode. + /// + /// The extended validation mode is not intended for running. + /// The intention is to identify power pins which are not properly + /// connected. The downside is that this mode creates a netlist which + /// is different (and not able to run). + /// + /// Extended validation is supported by nltool validate option. + /// + /// \param val Boolean value enabling/disabling extended validation mode + void set_extended_validation(bool val) { m_extended_validation = val; } + + /// \brief State of extended validation mode. + /// + /// \returns boolean value indicating if extended validation mode is + /// turned on. + bool is_extended_validation() const { return m_extended_validation; } + private: void reset(); @@ -1555,6 +1574,7 @@ namespace netlist nets_collection_type m_nets; // sole use is to manage lifetime of net objects devices_collection_type m_devices; + bool m_extended_validation; }; namespace devices @@ -1781,7 +1801,10 @@ namespace netlist { auto f = stream(); if (f != nullptr) + { f->read(reinterpret_cast(&m_data[0]),1< explicit name(Args&&... args) \ - : m_m(plib::pfmt(str)(std::forward(args)...)) \ - { static_assert(narg == sizeof...(args), "Argument count mismatch"); } \ - operator pstring() const { return m_m; } \ - pstring m_m; \ - }; - namespace netlist { @@ -53,12 +37,18 @@ namespace netlist // nl_base.cpp PERRMSGV(MF_MODEL_1_CAN_NOT_BE_CHANGED_AT_RUNTIME, 1, "Model {1} can not be changed at runtime") - PERRMSGV(MF_MORE_THAN_ONE_1_DEVICE_FOUND, 1, "more than one {1} device found") + PERRMSGV(MF_MORE_THAN_ONE_1_DEVICE_FOUND, 1, "More than one {1} device found") // nl_parser.cpp PERRMSGV(MF_UNEXPECTED_NETLIST_END, 0, "Unexpected NETLIST_END") + PERRMSGV(MF_UNEXPECTED_END_OF_FILE, 0, "Unexpected end of file, missing NETLIST_END") PERRMSGV(MF_UNEXPECTED_NETLIST_START, 0, "Unexpected NETLIST_START") + PERRMSGV(MF_EXPECTED_IDENTIFIER_GOT_1, 1, "Expected an identifier, but got {1}") + PERRMSGV(MF_EXPECTED_COMMA_OR_RP_1, 1, "Expected comma or right parenthesis but found <{1}>") + PERRMSGV(MF_DIPPINS_EQUAL_NUMBER_1, 1, "DIPPINS requires equal number of pins to DIPPINS, first pin is {}") + PERRMSGV(MF_PARAM_NOT_FP_1, 1, "Parameter value <{1}> not floating point") + PERRMSGV(MF_TT_LINE_WITHOUT_HEAD, 0, "TT_LINE found without TT_HEAD") // nl_setup.cpp diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp index 77d174bc038..e4d68c20c40 100644 --- a/src/lib/netlist/nl_parser.cpp +++ b/src/lib/netlist/nl_parser.cpp @@ -24,8 +24,8 @@ bool parser_t::parse(const pstring &nlname) .number_chars(".0123456789", "0123456789eE-.") //FIXME: processing of numbers .whitespace(pstring("") + ' ' + static_cast(9) + static_cast(10) + static_cast(13)) .comment("/*", "*/", "//"); - m_tok_param_left = register_token("("); - m_tok_param_right = register_token(")"); + m_tok_paren_left = register_token("("); + m_tok_paren_right = register_token(")"); m_tok_comma = register_token(","); m_tok_ALIAS = register_token("ALIAS"); @@ -59,29 +59,29 @@ bool parser_t::parse(const pstring &nlname) while (true) { token_t token = get_token(); - if (token.is_type(ENDOFFILE)) + if (token.is_type(token_type::ENDOFFILE)) { return false; } if (token.is(m_tok_NETLIST_END)) { - require_token(m_tok_param_left); + require_token(m_tok_paren_left); if (!in_nl) error (MF_UNEXPECTED_NETLIST_END()); else { in_nl = false; } - require_token(m_tok_param_right); + require_token(m_tok_paren_right); } else if (token.is(m_tok_NETLIST_START)) { if (in_nl) error (MF_UNEXPECTED_NETLIST_START()); - require_token(m_tok_param_left); + require_token(m_tok_paren_left); token_t name = get_token(); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); if (name.str() == nlname || nlname == "") { parse_netlist(name.str()); @@ -98,10 +98,9 @@ void parser_t::parse_netlist(const pstring &nlname) { token_t token = get_token(); - if (token.is_type(ENDOFFILE)) - return; + if (token.is_type(token_type::ENDOFFILE)) + error (MF_UNEXPECTED_END_OF_FILE()); - require_token(m_tok_param_left); m_setup.log().debug("Parser: Device: {1}\n", token.str()); if (token.is(m_tok_ALIAS)) @@ -128,14 +127,17 @@ void parser_t::parse_netlist(const pstring &nlname) net_truthtable_start(nlname); else if (token.is(m_tok_LOCAL_LIB_ENTRY)) { + require_token(m_tok_paren_left); m_setup.register_lib_entry(get_identifier(), "parser: " + nlname); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); } else if (token.is(m_tok_NETLIST_END)) { netdev_netlist_end(); return; } + else if (!token.is_type(token_type::IDENTIFIER)) + error(MF_EXPECTED_IDENTIFIER_GOT_1(token.str())); else device(token.str()); } @@ -143,7 +145,8 @@ void parser_t::parse_netlist(const pstring &nlname) void parser_t::net_truthtable_start(const pstring &nlname) { - pstring name = get_identifier(); + require_token(m_tok_paren_left); + pstring name(get_identifier()); bool head_found(false); require_token(m_tok_comma); @@ -152,7 +155,7 @@ void parser_t::net_truthtable_start(const pstring &nlname) long no = get_number_long(); require_token(m_tok_comma); pstring def_param = get_string(); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); netlist::tt_desc desc; desc.classname = name; @@ -168,65 +171,58 @@ void parser_t::net_truthtable_start(const pstring &nlname) if (token.is(m_tok_TT_HEAD)) { - require_token(m_tok_param_left); + require_token(m_tok_paren_left); desc.desc.push_back(get_string()); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); head_found = true; } else if (token.is(m_tok_TT_LINE)) { if (!head_found) - m_setup.log().error("TT_LINE found without TT_HEAD"); - require_token(m_tok_param_left); + error(MF_TT_LINE_WITHOUT_HEAD()); + require_token(m_tok_paren_left); desc.desc.push_back(get_string()); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); } else if (token.is(m_tok_TT_FAMILY)) { - require_token(m_tok_param_left); + require_token(m_tok_paren_left); desc.family = get_string(); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); } else { require_token(token, m_tok_TRUTHTABLE_END); - require_token(m_tok_param_left); - require_token(m_tok_param_right); + require_token(m_tok_paren_left); + require_token(m_tok_paren_right); m_setup.truthtable_create(desc, nlname); return; } } } - -void parser_t::netdev_netlist_start() -{ - // don't do much - token_t name = get_token(); - require_token(m_tok_param_right); -} - void parser_t::netdev_netlist_end() { // don't do much - require_token(m_tok_param_right); + require_token(m_tok_paren_left); + require_token(m_tok_paren_right); } void parser_t::net_model() { - // don't do much + require_token(m_tok_paren_left); pstring model = get_string(); m_setup.register_model(model); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); } void parser_t::net_submodel() { - // don't do much - pstring model = get_identifier(); + require_token(m_tok_paren_left); + pstring model(get_identifier()); require_token(m_tok_comma); pstring name = get_identifier(); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); m_setup.namespace_push(name); m_setup.include(model); @@ -235,22 +231,23 @@ void parser_t::net_submodel() void parser_t::frontier() { + require_token(m_tok_paren_left); // don't do much pstring attachat = get_identifier(); require_token(m_tok_comma); nl_fptype r_IN = eval_param(get_token()); require_token(m_tok_comma); nl_fptype r_OUT = eval_param(get_token()); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); m_setup.register_frontier(attachat, r_IN, r_OUT); } void parser_t::net_include() { - // don't do much - pstring name = get_identifier(); - require_token(m_tok_param_right); + require_token(m_tok_paren_left); + pstring name(get_identifier()); + require_token(m_tok_paren_right); m_setup.include(name); } @@ -258,20 +255,22 @@ void parser_t::net_include() void parser_t::net_local_source() { // This directive is only for hardcoded netlists. Ignore it here. - pstring name = get_identifier(); - require_token(m_tok_param_right); + require_token(m_tok_paren_left); + pstring name(get_identifier()); + require_token(m_tok_paren_right); } void parser_t::net_alias() { + require_token(m_tok_paren_left); pstring alias = get_identifier_or_number(); require_token(m_tok_comma); pstring out = get_identifier(); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); m_setup.log().debug("Parser: Alias: {1} {2}\n", alias, out); m_setup.register_alias(alias, out); @@ -279,6 +278,7 @@ void parser_t::net_alias() void parser_t::net_c() { + require_token(m_tok_paren_left); pstring first = get_identifier(); require_token(m_tok_comma); @@ -288,10 +288,10 @@ void parser_t::net_c() m_setup.register_link(first , t1); m_setup.log().debug("Parser: Connect: {1} {2}\n", first, t1); token_t n = get_token(); - if (n.is(m_tok_param_right)) + if (n.is(m_tok_paren_right)) break; if (!n.is(m_tok_comma)) - error(plib::pfmt("expected a comma, found <{1}>")(n.str()) ); + error(MF_EXPECTED_COMMA_OR_RP_1(n.str())); } } @@ -300,6 +300,7 @@ void parser_t::dippins() { std::vector pins; + require_token(m_tok_paren_left); pins.push_back(get_identifier()); require_token(m_tok_comma); @@ -308,13 +309,13 @@ void parser_t::dippins() pstring t1 = get_identifier(); pins.push_back(t1); token_t n = get_token(); - if (n.is(m_tok_param_right)) + if (n.is(m_tok_paren_right)) break; if (!n.is(m_tok_comma)) - error(plib::pfmt("expected a comma, found <{1}>")(n.str()) ); + error(MF_EXPECTED_COMMA_OR_RP_1(n.str())); } if ((pins.size() % 2) == 1) - error(plib::pfmt("You must pass an equal number of pins to DIPPINS, first pin is {}")(pins[0])); + error(MF_DIPPINS_EQUAL_NUMBER_1(pins[0])); std::size_t n = pins.size(); for (std::size_t i = 0; i < n / 2; i++) { @@ -325,11 +326,11 @@ void parser_t::dippins() void parser_t::netdev_param() { - pstring param; - param = get_identifier(); + require_token(m_tok_paren_left); + pstring param(get_identifier()); require_token(m_tok_comma); token_t tok = get_token(); - if (tok.is_type(STRING)) + if (tok.is_type(token_type::STRING)) { m_setup.log().debug("Parser: Param: {1} {2}\n", param, tok.str()); m_setup.register_param(param, tok.str()); @@ -340,34 +341,34 @@ void parser_t::netdev_param() m_setup.log().debug("Parser: Param: {1} {2}\n", param, val); m_setup.register_param(param, val); } - require_token(m_tok_param_right); + require_token(m_tok_paren_right); } void parser_t::netdev_hint() { + require_token(m_tok_paren_left); pstring dev(get_identifier()); require_token(m_tok_comma); pstring hint(get_identifier()); m_setup.register_param(dev + ".HINT_" + hint, 1); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); } void parser_t::device(const pstring &dev_type) { std::vector params; - pstring devname = get_identifier(); + require_token(m_tok_paren_left); + pstring devname(get_identifier()); m_setup.log().debug("Parser: IC: {1}\n", devname); auto tok(get_token()); - //printf("enter\n"); while (tok.is(m_tok_comma)) { tok = get_token(); - //printf("%d %s\n", tok.type(), tok.str().c_str()); - if (tok.is_type(IDENTIFIER) || tok.is_type(STRING)) + if (tok.is_type(token_type::IDENTIFIER) || tok.is_type(token_type::STRING)) params.push_back(tok.str()); else { @@ -382,7 +383,7 @@ void parser_t::device(const pstring &dev_type) tok = get_token(); } - require_token(tok, m_tok_param_right); + require_token(tok, m_tok_paren_right); m_setup.register_dev(dev_type, devname, params); } @@ -411,16 +412,16 @@ nl_fptype parser_t::eval_param(const token_t &tok) f = i; if (f>0) { - require_token(m_tok_param_left); + require_token(m_tok_paren_left); ret = static_cast(get_number_double()); - require_token(m_tok_param_right); + require_token(m_tok_paren_right); } else { bool err(false); ret = plib::pstonum_ne(tok.str(), err); if (err) - error(plib::pfmt("Parameter value <{1}> not floating point \n")(tok.str())); + error(MF_PARAM_NOT_FP_1(tok.str())); } return ret * facs[f]; diff --git a/src/lib/netlist/nl_parser.h b/src/lib/netlist/nl_parser.h index 7f29c69b03b..e747f2dac28 100644 --- a/src/lib/netlist/nl_parser.h +++ b/src/lib/netlist/nl_parser.h @@ -34,7 +34,6 @@ namespace netlist void net_c(); void frontier(); void device(const pstring &dev_type); - void netdev_netlist_start(); void netdev_netlist_end(); void net_model(); void net_submodel(); @@ -47,8 +46,8 @@ namespace netlist nl_fptype eval_param(const token_t &tok); - token_id_t m_tok_param_left; - token_id_t m_tok_param_right; + token_id_t m_tok_paren_left; + token_id_t m_tok_paren_right; token_id_t m_tok_comma; token_id_t m_tok_ALIAS; token_id_t m_tok_NET_C; diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 1bd5a4aeffb..21b2c0e8999 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -340,7 +340,6 @@ setup_t::setup_t(netlist_state_t &nlstate) , m_nlstate(nlstate) , m_netlist_params(nullptr) , m_proxy_cnt(0) - , m_validation(false) { } diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 77bb68d8803..00974f93fd0 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -425,23 +425,6 @@ namespace netlist void prepare_to_run(); - /// \brief set extended validation mode. - /// - /// The extended validation mode is not intended for running. - /// The intention is to identify power pins which are not properly - /// connected. The downside is that this mode creates a netlist which - /// is different (and not able to run). - /// - /// Extended validation is supported by nltool validate option. - /// - /// \param val Boolean value enabling/disabling extended validation mode - void set_extended_validation(bool val) { m_validation = val; } - - /// \brief State of extended validation mode. - /// - /// \returns boolean value indicating if extended validation mode is - /// turned on. - bool is_extended_validation() const { return m_validation; } private: void merge_nets(detail::net_t &thisnet, detail::net_t &othernet); @@ -468,7 +451,6 @@ namespace netlist devices::nld_base_proxy *> m_proxies; unsigned m_proxy_cnt; - bool m_validation; }; // ---------------------------------------------------------------------------------------- diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h index aaa43505293..86761096caf 100644 --- a/src/lib/netlist/plib/pfmtlog.h +++ b/src/lib/netlist/plib/pfmtlog.h @@ -16,390 +16,411 @@ #include #include +#define PERRMSGV(name, narg, str) \ + struct name : public plib::perrmsg \ + { \ + template explicit name(Args&&... args) \ + : plib::perrmsg(str, std::forward(args)...) \ + { static_assert(narg == sizeof...(args), "Argument count mismatch"); } \ + }; + namespace plib { -P_ENUM(plog_level, - DEBUG, - VERBOSE, - INFO, - WARNING, - ERROR, - FATAL) - -template -struct ptype_traits_base -{ - static constexpr const bool is_signed = std::numeric_limits::is_signed; - static char32_t fmt_spec() { return 'u'; } - static inline void streamify(std::ostream &s, const T &v) + P_ENUM(plog_level, + DEBUG, + VERBOSE, + INFO, + WARNING, + ERROR, + FATAL) + + template + struct ptype_traits_base { - s << v; - } -}; - -#if (PUSE_FLOAT128) -template <> -struct ptype_traits_base<__float128> -{ - // FIXME: need native support at some time - static constexpr const bool is_signed = true; - static char32_t fmt_spec() { return 'f'; } - static inline void streamify(std::ostream &s, const __float128 &v) + static constexpr const bool is_signed = std::numeric_limits::is_signed; + static char32_t fmt_spec() { return 'u'; } + static inline void streamify(std::ostream &s, const T &v) + { + s << v; + } + }; + + #if (PUSE_FLOAT128) + template <> + struct ptype_traits_base<__float128> { - s << static_cast(v); - } -}; -#endif - -template -struct ptype_traits; - -template<> -struct ptype_traits : ptype_traits_base -{ -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return is_signed ? 'd' : 'u'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'd'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'd'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'd'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'd'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'd'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'u'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'u'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'u'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'u'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'u'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'f'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'f'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'f'; } -}; - -#if (PUSE_FLOAT128) -template<> -struct ptype_traits<__float128> : ptype_traits_base<__float128> -{ - static char32_t fmt_spec() { return 'f'; } -}; -#endif - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 's'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 's'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 's'; } -}; - -template<> -struct ptype_traits : ptype_traits_base -{ - static char32_t fmt_spec() { return 'p'; } -}; - -class pfmt -{ -public: - explicit pfmt(const pstring &fmt) - : m_str(fmt), m_locale(std::locale::classic()), m_arg(0) + // FIXME: need native support at some time + static constexpr const bool is_signed = true; + static char32_t fmt_spec() { return 'f'; } + static inline void streamify(std::ostream &s, const __float128 &v) + { + s << static_cast(v); + } + }; + #endif + + template + struct ptype_traits; + + template<> + struct ptype_traits : ptype_traits_base { - } - explicit pfmt(const std::locale &loc, const pstring &fmt) - : m_str(fmt), m_locale(loc), m_arg(0) + }; + + template<> + struct ptype_traits : ptype_traits_base { - } + static char32_t fmt_spec() { return is_signed ? 'd' : 'u'; } + }; - COPYASSIGNMOVE(pfmt, default) + template<> + struct ptype_traits : ptype_traits_base + { + static char32_t fmt_spec() { return 'd'; } + }; - ~pfmt() noexcept = default; + template<> + struct ptype_traits : ptype_traits_base + { + static char32_t fmt_spec() { return 'd'; } + }; - operator pstring() const { return m_str; } + template<> + struct ptype_traits : ptype_traits_base + { + static char32_t fmt_spec() { return 'd'; } + }; - template - typename std::enable_if::value, pfmt &>::type - f(const T &x) {return format_element('f', x); } + template<> + struct ptype_traits : ptype_traits_base + { + static char32_t fmt_spec() { return 'd'; } + }; - template - typename std::enable_if::value, pfmt &>::type - e(const T &x) {return format_element('e', x); } + template<> + struct ptype_traits : ptype_traits_base + { + static char32_t fmt_spec() { return 'd'; } + }; -#if PUSE_FLOAT128 - // FIXME: should use quadmath_snprintf - pfmt & e(const __float128 &x) {return format_element('e', static_cast(x)); } -#endif + template<> + struct ptype_traits : ptype_traits_base + { + static char32_t fmt_spec() { return 'u'; } + }; - template - typename std::enable_if::value, pfmt &>::type - g(const T &x) {return format_element('g', x); } + template<> + struct ptype_traits : ptype_traits_base + { + static char32_t fmt_spec() { return 'u'; } + }; - pfmt &operator ()(const void *x) {return format_element('p', x); } - pfmt &operator ()(const pstring &x) {return format_element('s', x.c_str() ); } + template<> + struct ptype_traits : ptype_traits_base + { + static char32_t fmt_spec() { return 'u'; } + }; - template - pfmt &operator ()(const T &x) + template<> + struct ptype_traits : ptype_traits_base { - return format_element(x); - } + static char32_t fmt_spec() { return 'u'; } + }; - template - pfmt &operator ()(const T *x) + template<> + struct ptype_traits : ptype_traits_base { - return format_element(x); - } + static char32_t fmt_spec() { return 'u'; } + }; - pfmt &operator ()() + template<> + struct ptype_traits : ptype_traits_base { - return *this; - } + static char32_t fmt_spec() { return 'f'; } + }; - template - pfmt &operator()(X&& x, Y && y, Args&&... args) + template<> + struct ptype_traits : ptype_traits_base { - return ((*this)(std::forward(x)))(std::forward(y), std::forward(args)...); - } + static char32_t fmt_spec() { return 'f'; } + }; - template - typename std::enable_if::value, pfmt &>::type - x(const T &x) + template<> + struct ptype_traits : ptype_traits_base { - return format_element('x', x); - } + static char32_t fmt_spec() { return 'f'; } + }; - template - typename std::enable_if::value, pfmt &>::type - o(const T &x) + #if (PUSE_FLOAT128) + template<> + struct ptype_traits<__float128> : ptype_traits_base<__float128> { - return format_element('o', x); - } + static char32_t fmt_spec() { return 'f'; } + }; + #endif - friend std::ostream& operator<<(std::ostream &ostrm, const pfmt &fmt) + template<> + struct ptype_traits : ptype_traits_base { - ostrm << fmt.m_str; - return ostrm; - } + static char32_t fmt_spec() { return 's'; } + }; -protected: + template<> + struct ptype_traits : ptype_traits_base + { + static char32_t fmt_spec() { return 's'; } + }; - struct rtype + template<> + struct ptype_traits : ptype_traits_base { - rtype() : ret(0), p(0), sl(0) {} - int ret; - pstring::size_type p; - pstring::size_type sl; + static char32_t fmt_spec() { return 's'; } }; - rtype setfmt(std::stringstream &strm, char32_t cfmt_spec); - template - pfmt &format_element(T &&v) + template<> + struct ptype_traits : ptype_traits_base { - return format_element(ptype_traits::type>::fmt_spec(), std::forward(v)); - } + static char32_t fmt_spec() { return 'p'; } + }; - template - pfmt &format_element(const char32_t cfmt_spec, T &&v) + class pfmt { - rtype ret; + public: + explicit pfmt(const pstring &fmt) + : m_str(fmt), m_locale(std::locale::classic()), m_arg(0) + { + } + explicit pfmt(const std::locale &loc, const pstring &fmt) + : m_str(fmt), m_locale(loc), m_arg(0) + { + } - m_arg++; + COPYASSIGNMOVE(pfmt, default) - do { - std::stringstream strm; - strm.imbue(m_locale); - ret = setfmt(strm, cfmt_spec); - if (ret.ret>=0) - { - ptype_traits::type>::streamify(strm, std::forward(v)); - const pstring ps(strm.str()); - m_str = m_str.substr(0, ret.p) + ps + m_str.substr(ret.p + ret.sl); - } - } while (ret.ret == 1); + ~pfmt() noexcept = default; - return *this; - } + operator pstring() const { return m_str; } + template + typename std::enable_if::value, pfmt &>::type + f(const T &x) {return format_element('f', x); } -private: + template + typename std::enable_if::value, pfmt &>::type + e(const T &x) {return format_element('e', x); } - pstring m_str; - std::locale m_locale; - unsigned m_arg; -}; + #if PUSE_FLOAT128 + // FIXME: should use quadmath_snprintf + pfmt & e(const __float128 &x) {return format_element('e', static_cast(x)); } + #endif -template -class pfmt_writer_t -{ -public: - explicit pfmt_writer_t() : m_enabled(true) { } + template + typename std::enable_if::value, pfmt &>::type + g(const T &x) {return format_element('g', x); } - COPYASSIGNMOVE(pfmt_writer_t, delete) + pfmt &operator ()(const void *x) {return format_element('p', x); } + pfmt &operator ()(const pstring &x) {return format_element('s', x.c_str() ); } - // runtime enable - template - void log(const pstring & fmt, Args&&... args) const noexcept - { - if (build_enabled && enabled && m_enabled) + template + pfmt &operator ()(const T &x) { - pfmt pf(fmt); - static_cast(this)->vdowrite(xlog(pf, std::forward(args)...)); + return format_element(x); } - } - template - void operator ()(const pstring &fmt, Args&&... args) const noexcept - { - if (build_enabled && m_enabled) + template + pfmt &operator ()(const T *x) + { + return format_element(x); + } + + pfmt &operator ()() + { + return *this; + } + + template + pfmt &operator()(X&& x, Y && y, Args&&... args) + { + return ((*this)(std::forward(x)))(std::forward(y), std::forward(args)...); + } + + template + typename std::enable_if::value, pfmt &>::type + x(const T &x) + { + return format_element('x', x); + } + + template + typename std::enable_if::value, pfmt &>::type + o(const T &x) + { + return format_element('o', x); + } + + friend std::ostream& operator<<(std::ostream &ostrm, const pfmt &fmt) + { + ostrm << fmt.m_str; + return ostrm; + } + + protected: + + struct rtype + { + rtype() : ret(0), p(0), sl(0) {} + int ret; + pstring::size_type p; + pstring::size_type sl; + }; + rtype setfmt(std::stringstream &strm, char32_t cfmt_spec); + + template + pfmt &format_element(T &&v) { - pfmt pf(fmt); - static_cast(this)->vdowrite(xlog(pf, std::forward(args)...)); + return format_element(ptype_traits::type>::fmt_spec(), std::forward(v)); } - } - void set_enabled(const bool v) + template + pfmt &format_element(const char32_t cfmt_spec, T &&v) + { + rtype ret; + + m_arg++; + + do { + std::stringstream strm; + strm.imbue(m_locale); + ret = setfmt(strm, cfmt_spec); + if (ret.ret>=0) + { + ptype_traits::type>::streamify(strm, std::forward(v)); + const pstring ps(strm.str()); + m_str = m_str.substr(0, ret.p) + ps + m_str.substr(ret.p + ret.sl); + } + } while (ret.ret == 1); + + return *this; + } + + + private: + + pstring m_str; + std::locale m_locale; + unsigned m_arg; + }; + + template + class pfmt_writer_t { - m_enabled = v; - } + public: + explicit pfmt_writer_t() : m_enabled(true) { } - bool is_enabled() const { return m_enabled; } + COPYASSIGNMOVE(pfmt_writer_t, delete) -protected: - ~pfmt_writer_t() noexcept = default; + // runtime enable + template + void log(const pstring & fmt, Args&&... args) const noexcept + { + if (build_enabled && enabled && m_enabled) + { + pfmt pf(fmt); + static_cast(this)->vdowrite(xlog(pf, std::forward(args)...)); + } + } + + template + void operator ()(const pstring &fmt, Args&&... args) const noexcept + { + if (build_enabled && m_enabled) + { + pfmt pf(fmt); + static_cast(this)->vdowrite(xlog(pf, std::forward(args)...)); + } + } + + void set_enabled(const bool v) + { + m_enabled = v; + } + + bool is_enabled() const { return m_enabled; } + + protected: + ~pfmt_writer_t() noexcept = default; -private: - pfmt &xlog(pfmt &fmt) const { return fmt; } + private: + pfmt &xlog(pfmt &fmt) const { return fmt; } - template - pfmt &xlog(pfmt &fmt, X&& x, Args&&... args) const + template + pfmt &xlog(pfmt &fmt, X&& x, Args&&... args) const + { + return xlog(fmt(std::forward(x)), std::forward(args)...); + } + + bool m_enabled; + + }; + + template + class plog_channel : public pfmt_writer_t, build_enabled> { - return xlog(fmt(std::forward(x)), std::forward(args)...); - } + friend class pfmt_writer_t, build_enabled>; + public: + explicit plog_channel(T &b) : pfmt_writer_t(), m_base(b) { } - bool m_enabled; + COPYASSIGNMOVE(plog_channel, delete) -}; + ~plog_channel() noexcept = default; -template -class plog_channel : public pfmt_writer_t, build_enabled> -{ - friend class pfmt_writer_t, build_enabled>; -public: - explicit plog_channel(T &b) : pfmt_writer_t(), m_base(b) { } + protected: + void vdowrite(const pstring &ls) const noexcept + { + m_base.vlog(L, ls); + } - COPYASSIGNMOVE(plog_channel, delete) + private: + T &m_base; + }; - ~plog_channel() noexcept = default; + template + class plog_base + { + public: + + explicit plog_base(T &proxy) + : debug(proxy), + info(proxy), + verbose(proxy), + warning(proxy), + error(proxy), + fatal(proxy) + {} + + COPYASSIGNMOVE(plog_base, default) + virtual ~plog_base() noexcept = default; + + plog_channel debug; + plog_channel info; + plog_channel verbose; + plog_channel warning; + plog_channel error; + plog_channel fatal; + }; -protected: - void vdowrite(const pstring &ls) const noexcept + struct perrmsg { - m_base.vlog(L, ls); - } - -private: - T &m_base; -}; - -template -class plog_base -{ -public: - - explicit plog_base(T &proxy) - : debug(proxy), - info(proxy), - verbose(proxy), - warning(proxy), - error(proxy), - fatal(proxy) - {} - - COPYASSIGNMOVE(plog_base, default) - virtual ~plog_base() noexcept = default; - - plog_channel debug; - plog_channel info; - plog_channel verbose; - plog_channel warning; - plog_channel error; - plog_channel fatal; -}; + template + explicit perrmsg(const char (&fmt)[N], Args&&... args) + : m_msg(plib::pfmt(fmt)(std::forward(args)...)) + { } + operator pstring const & () const noexcept { return m_msg; } + const pstring & operator ()() const noexcept { return m_msg; } + private: + pstring m_msg; + }; + } // namespace plib diff --git a/src/lib/netlist/plib/ptokenizer.cpp b/src/lib/netlist/plib/ptokenizer.cpp index 95b63f7f161..a29b3342333 100644 --- a/src/lib/netlist/plib/ptokenizer.cpp +++ b/src/lib/netlist/plib/ptokenizer.cpp @@ -8,6 +8,15 @@ namespace plib { + PERRMSGV(MF_EXPECTED_TOKEN_1_GOT_2, 2, "Expected token <{1}>, got <{2}>") + PERRMSGV(MF_EXPECTED_STRING_GOT_1, 1, "Expected a string, got <{1}>") + PERRMSGV(MF_EXPECTED_IDENTIFIER_GOT_1, 1, "Expected an identifier, got <{1}>") + PERRMSGV(MF_EXPECTED_ID_OR_NUM_GOT_1, 1, "Expected an identifier or number, got <{1}>") + PERRMSGV(MF_EXPECTED_NUMBER_GOT_1, 1, "Expected a number, got <{1}>") + PERRMSGV(MF_EXPECTED_LONGINT_GOT_1, 1, "Expected a logn int, got <{1}>") + PERRMSGV(MF_EXPECTED_LINENUM_GOT_1, 1, "Expected line number after line marker but got <{1}>") + PERRMSGV(MF_EXPECTED_FILENAME_GOT_1, 1, "Expected file name after line marker but got <{1}>") + // ---------------------------------------------------------------------------------------- // A simple tokenizer // ---------------------------------------------------------------------------------------- @@ -63,7 +72,6 @@ namespace plib { { require_token(get_token(), token_num); } - void ptokenizer::require_token(const token_t &tok, const token_id_t &token_num) { if (!tok.is(token_num)) @@ -72,26 +80,27 @@ namespace plib { for (auto &i : m_tokens) if (i.second.id() == token_num.id()) val = i.first; - error(pfmt("Expected token <{1}> got <{2}>")(val)(tok.str()) ); + error(MF_EXPECTED_TOKEN_1_GOT_2(val, tok.str())); } } pstring ptokenizer::get_string() { token_t tok = get_token(); - if (!tok.is_type(STRING)) + if (!tok.is_type(token_type::STRING)) { - error(pfmt("Expected a string, got <{1}>")(tok.str()) ); + error(MF_EXPECTED_STRING_GOT_1(tok.str())); } return tok.str(); } + pstring ptokenizer::get_identifier() { token_t tok = get_token(); - if (!tok.is_type(IDENTIFIER)) + if (!tok.is_type(token_type::IDENTIFIER)) { - error(pfmt("Expected an identifier, got <{1}>")(tok.str()) ); + error(MF_EXPECTED_IDENTIFIER_GOT_1(tok.str())); } return tok.str(); } @@ -99,9 +108,9 @@ namespace plib { pstring ptokenizer::get_identifier_or_number() { token_t tok = get_token(); - if (!(tok.is_type(IDENTIFIER) || tok.is_type(NUMBER))) + if (!(tok.is_type(token_type::IDENTIFIER) || tok.is_type(token_type::NUMBER))) { - error(pfmt("Expected an identifier or number, got <{1}>")(tok.str()) ); + error(MF_EXPECTED_ID_OR_NUM_GOT_1(tok.str())); } return tok.str(); } @@ -110,28 +119,28 @@ namespace plib { double ptokenizer::get_number_double() { token_t tok = get_token(); - if (!tok.is_type(NUMBER)) + if (!tok.is_type(token_type::NUMBER)) { - error(pfmt("Expected a number, got <{1}>")(tok.str()) ); + error(MF_EXPECTED_NUMBER_GOT_1(tok.str())); } bool err(false); auto ret = plib::pstonum_ne(tok.str(), err); if (err) - error(pfmt("Expected a number, got <{1}>")(tok.str()) ); + error(MF_EXPECTED_NUMBER_GOT_1(tok.str())); return ret; } long ptokenizer::get_number_long() { token_t tok = get_token(); - if (!tok.is_type(NUMBER)) + if (!tok.is_type(token_type::NUMBER)) { - error(pfmt("Expected a long int, got <{1}>")(tok.str()) ); + error(MF_EXPECTED_LONGINT_GOT_1(tok.str()) ); } bool err(false); auto ret = plib::pstonum_ne(tok.str(), err); if (err) - error(pfmt("Expected a long int, got <{1}>")(tok.str()) ); + error(MF_EXPECTED_LONGINT_GOT_1(tok.str()) ); return ret; } @@ -140,9 +149,9 @@ namespace plib { token_t ret = get_token_internal(); while (true) { - if (ret.is_type(ENDOFFILE)) + if (ret.is_type(token_type::token_type::ENDOFFILE)) return ret; - else if (m_support_line_markers && ret.is_type(LINEMARKER)) + else if (m_support_line_markers && ret.is_type(token_type::LINEMARKER)) { bool benter(false); bool bexit(false); @@ -150,15 +159,15 @@ namespace plib { unsigned lineno; ret = get_token_internal(); - if (!ret.is_type(NUMBER)) - error(pfmt("Expected line number after line marker but got <{1}>")(ret.str()) ); + if (!ret.is_type(token_type::NUMBER)) + error(MF_EXPECTED_LINENUM_GOT_1(ret.str())); lineno = pstonum(ret.str()); ret = get_token_internal(); - if (!ret.is_type(STRING)) - error(pfmt("Expected file name after line marker but got <{1}>")(ret.str()) ); + if (!ret.is_type(token_type::STRING)) + error(MF_EXPECTED_FILENAME_GOT_1(ret.str())); file = ret.str(); ret = get_token_internal(); - while (ret.is_type(NUMBER)) + while (ret.is_type(token_type::NUMBER)) { if (ret.str() == "1") benter = true; @@ -201,20 +210,20 @@ namespace plib { c = getc(); if (eof()) { - return token_t(ENDOFFILE); + return token_t(token_type::ENDOFFILE); } } if (m_support_line_markers && c == '#') - return token_t(LINEMARKER, "#"); + return token_t(token_type::LINEMARKER, "#"); else if (m_number_chars_start.find(c) != pstring::npos) { // read number while we receive number or identifier chars // treat it as an identifier when there are identifier chars in it - token_type ret = NUMBER; + token_type ret = token_type::NUMBER; pstring tokstr = ""; while (true) { if (m_identifier_chars.find(c) != pstring::npos && m_number_chars.find(c) == pstring::npos) - ret = IDENTIFIER; + ret = token_type::IDENTIFIER; else if (m_number_chars.find(c) == pstring::npos) break; tokstr += c; @@ -237,7 +246,7 @@ namespace plib { if (id != m_tokens.end()) return token_t(id->second, tokstr); else - return token_t(IDENTIFIER, tokstr); + return token_t(token_type::IDENTIFIER, tokstr); } else if (c == m_string) { @@ -248,7 +257,7 @@ namespace plib { tokstr += c; c = getc(); } - return token_t(STRING, tokstr); + return token_t(token_type::STRING, tokstr); } else { @@ -271,17 +280,17 @@ namespace plib { if (id != m_tokens.end()) return token_t(id->second, tokstr); else - return token_t(UNKNOWN, tokstr); + return token_t(token_type::UNKNOWN, tokstr); } } - void ptokenizer::error(const pstring &errs) + void ptokenizer::error(const perrmsg &errs) { pstring s(""); pstring trail (" from "); pstring trail_first("In file included from "); pstring e = plib::pfmt("{1}:{2}:0: error: {3}\n") - (m_source_location.back().file_name(), m_source_location.back().line(), errs); + (m_source_location.back().file_name(), m_source_location.back().line(), errs()); m_source_location.pop_back(); while (m_source_location.size() > 0) { @@ -290,7 +299,7 @@ namespace plib { s = trail + plib::pfmt("{1}:{2}:0\n")(m_source_location.back().file_name(), m_source_location.back().line()) + s; m_source_location.pop_back(); } - verror("\n" + s + e + " " + currentline_str() + "\n"); -} + verror("\n" + s + e + " " + currentline_str() + "\n"); + } } // namespace plib diff --git a/src/lib/netlist/plib/ptokenizer.h b/src/lib/netlist/plib/ptokenizer.h index d0c05b4b75a..773df365bed 100644 --- a/src/lib/netlist/plib/ptokenizer.h +++ b/src/lib/netlist/plib/ptokenizer.h @@ -39,8 +39,7 @@ namespace plib { virtual ~ptokenizer() = default; - enum token_type - { + P_ENUM(token_type, IDENTIFIER, NUMBER, TOKEN, @@ -49,7 +48,7 @@ namespace plib { LINEMARKER, UNKNOWN, ENDOFFILE - }; + ) struct token_id_t { @@ -75,7 +74,7 @@ namespace plib { { } token_t(const token_id_t &id, const pstring &str) - : m_type(TOKEN), m_id(id), m_token(str) + : m_type(token_type::TOKEN), m_id(id), m_token(str) { } @@ -129,7 +128,7 @@ namespace plib { } token_t get_token_internal(); - void error(const pstring &errs); + void error(const perrmsg &errs); putf8_reader &stream() { return m_strm; } protected: diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index fadf1af2d03..440c958711d 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -482,7 +482,7 @@ void tool_app_t::validate() m_errors = 0; m_warnings = 0; - nt.setup().set_extended_validation(opt_extended_validation()); + nt.set_extended_validation(opt_extended_validation()); try { diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h index b6625bc576f..c3fdf9a4328 100644 --- a/src/lib/netlist/solver/nld_ms_gcr.h +++ b/src/lib/netlist/solver/nld_ms_gcr.h @@ -83,25 +83,29 @@ namespace solver this->m_mat_ptr[k][this->m_terms[k].railstart()] = &mat.A[mat.diag[k]]; } - this->log().verbose("maximum fill: {1}", gr.first); - this->log().verbose("Post elimination occupancy ratio: {2} Ops: {1}", gr.second, + anetlist.log().verbose("maximum fill: {1}", gr.first); + anetlist.log().verbose("Post elimination occupancy ratio: {2} Ops: {1}", gr.second, static_cast(mat.nz_num) / static_cast(iN * iN)); - this->log().verbose(" Pre elimination occupancy ratio: {2}", + anetlist.log().verbose(" Pre elimination occupancy ratio: {2}", static_cast(raw_elements) / static_cast(iN * iN)); // FIXME: Move me + // - if (this->state().lib().isLoaded()) + // During extended validation there is no reason to check for + // differences in the generated code since during + // extended validation this will be different (and non-functional) + if (!anetlist.is_extended_validation() && anetlist.lib().isLoaded()) { pstring symname = static_compile_name(); - m_proc.load(this->state().lib(), symname); + m_proc.load(anetlist.lib(), symname); if (m_proc.resolved()) { - this->log().info("External static solver {1} found ...", symname); + anetlist.log().info("External static solver {1} found ...", symname); } else { - this->log().warning("External static solver {1} not found ...", symname); + anetlist.log().warning("External static solver {1} not found ...", symname); } } } diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp index 8bcabe5a56a..28cf290d97c 100644 --- a/src/lib/netlist/tools/nl_convert.cpp +++ b/src/lib/netlist/tools/nl_convert.cpp @@ -492,7 +492,7 @@ void nl_convert_eagle_t::convert(const pstring &contents) tokenizer::token_t token = tok.get_token(); while (true) { - if (token.is_type(tokenizer::ENDOFFILE)) + if (token.is_type(tokenizer::token_type::ENDOFFILE)) { dump_nl(); // FIXME: Parameter @@ -563,7 +563,7 @@ void nl_convert_eagle_t::convert(const pstring &contents) break; } default: - tok.error("// IGNORED " + name); + tok.error(plib::perrmsg("// IGNORED {1}", name)); } } @@ -639,7 +639,7 @@ void nl_convert_rinf_t::convert(const pstring &contents) tokenizer::token_t token = tok.get_token(); while (true) { - if (token.is_type(tokenizer::ENDOFFILE) || token.is(tok.m_tok_END)) + if (token.is_type(tokenizer::token_type::ENDOFFILE) || token.is(tok.m_tok_END)) { dump_nl(); // FIXME: Parameter @@ -731,7 +731,7 @@ void nl_convert_rinf_t::convert(const pstring &contents) if (token.is(tok.m_tok_TER)) { token = tok.get_token(); - while (token.is_type(plib::ptokenizer::IDENTIFIER)) + while (token.is_type(plib::ptokenizer::token_type::IDENTIFIER)) { pin = tok.get_identifier_or_number(); add_term(net, token.str() + "." + pin); -- cgit v1.2.3