From 9e272e4b551d14e7032913f0aa972e2dd45fb4bd Mon Sep 17 00:00:00 2001 From: couriersud Date: Mon, 20 Jan 2020 21:15:22 +0100 Subject: [PATCH] netlist: code maintenance. (nw) - remove pthrow trampline as proposed by Vas. - identify throwing code by adding noexcept(false) - move "connected term" information to setup code. - srcclean --- src/lib/netlist/analog/nld_opamps.cpp | 2 +- src/lib/netlist/analog/nlid_twoterm.h | 2 +- src/lib/netlist/devices/nld_log.cpp | 2 +- src/lib/netlist/devices/nlid_proxy.cpp | 4 +- src/lib/netlist/devices/nlid_truthtable.cpp | 6 +- src/lib/netlist/macro/nlm_opamp.cpp | 2 +- src/lib/netlist/nl_base.cpp | 15 ++-- src/lib/netlist/nl_base.h | 26 +++--- src/lib/netlist/nl_config.h | 12 +-- src/lib/netlist/nl_factory.cpp | 4 +- src/lib/netlist/nl_factory.h | 4 +- src/lib/netlist/nl_parser.cpp | 2 +- src/lib/netlist/nl_setup.cpp | 88 +++++++++++--------- src/lib/netlist/nl_setup.h | 11 +++ src/lib/netlist/plib/mat_cr.h | 8 +- src/lib/netlist/plib/parray.h | 8 +- src/lib/netlist/plib/pexception.h | 13 --- src/lib/netlist/plib/pfunction.cpp | 16 ++-- src/lib/netlist/plib/pfunction.h | 6 +- src/lib/netlist/plib/poptions.cpp | 4 +- src/lib/netlist/plib/poptions.h | 2 +- src/lib/netlist/plib/ppreprocessor.cpp | 2 +- src/lib/netlist/plib/ppreprocessor.h | 2 +- src/lib/netlist/plib/pstonum.h | 6 +- src/lib/netlist/plib/pstring.h | 2 +- src/lib/netlist/plib/ptime.h | 2 +- src/lib/netlist/prg/nltool.cpp | 26 +++--- src/lib/netlist/prg/nlwav.cpp | 2 +- src/lib/netlist/solver/nld_matrix_solver.cpp | 54 ++++++++++-- src/lib/netlist/solver/nld_matrix_solver.h | 34 ++------ src/lib/netlist/solver/nld_solver.cpp | 10 ++- 31 files changed, 195 insertions(+), 182 deletions(-) diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp index 6a1502dab00..8af6ab28170 100644 --- a/src/lib/netlist/analog/nld_opamps.cpp +++ b/src/lib/netlist/analog/nld_opamps.cpp @@ -112,7 +112,7 @@ namespace netlist if (m_type < 1 || m_type > 3) { log().fatal(MF_OPAMP_UNKNOWN_TYPE(m_type)); - plib::pthrow(MF_OPAMP_UNKNOWN_TYPE(m_type)); + throw nl_exception(MF_OPAMP_UNKNOWN_TYPE(m_type)); } if (m_type == 1) diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h index 396b4e938c9..cdf55c4ce18 100644 --- a/src/lib/netlist/analog/nlid_twoterm.h +++ b/src/lib/netlist/analog/nlid_twoterm.h @@ -64,7 +64,7 @@ namespace analog { plib::unused_var(d1); if (b) - plib::pthrow("bselect with netlist and b==true"); + throw nl_exception("bselect with netlist and b==true"); return d2; } diff --git a/src/lib/netlist/devices/nld_log.cpp b/src/lib/netlist/devices/nld_log.cpp index 5dd06c9beca..03165a573ef 100644 --- a/src/lib/netlist/devices/nld_log.cpp +++ b/src/lib/netlist/devices/nld_log.cpp @@ -23,7 +23,7 @@ namespace netlist , m_writer(&m_strm) { if (m_strm.fail()) - plib::pthrow(plib::pfmt("{1}.log")(this->name())); + throw plib::file_open_e(plib::pfmt("{1}.log")(this->name())); m_strm.imbue(std::locale::classic()); } diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp index 92db2af4d9b..68af102232b 100644 --- a/src/lib/netlist/devices/nlid_proxy.cpp +++ b/src/lib/netlist/devices/nlid_proxy.cpp @@ -39,9 +39,9 @@ namespace netlist if (tp_ct && tp_cn) { if (tp_ct && !tp_ct->is_analog()) - plib::pthrow(plib::pfmt("Not an analog terminal: {1}")(tp_ct->name())); + throw nl_exception(plib::pfmt("Not an analog terminal: {1}")(tp_ct->name())); if (tp_cn && !tp_cn->is_analog()) - plib::pthrow(plib::pfmt("Not an analog terminal: {1}")(tp_cn->name())); + throw nl_exception(plib::pfmt("Not an analog terminal: {1}")(tp_cn->name())); auto tp_t = static_cast(tp_ct); auto tn_t = static_cast(tp_cn); diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp index 362784aec87..26bac038251 100644 --- a/src/lib/netlist/devices/nlid_truthtable.cpp +++ b/src/lib/netlist/devices/nlid_truthtable.cpp @@ -264,7 +264,7 @@ namespace devices m_family_desc = anetlist.setup().family_from_model(m_family_name); if (m_family_desc == nullptr) - plib::pthrow("family description not found for {1}", m_family_name); + throw nl_exception("family description not found for {1}", m_family_name); return pool.make_unique(anetlist, name, *m_family_desc, *m_ttbl, m_desc); } @@ -372,7 +372,7 @@ void truthtable_parser::parseline(unsigned cur, std::vector list, { // cutoff previous inputs and outputs for ignore if (m_out_state[nstate] != m_out_state.mask() && m_out_state[nstate] != val) - plib::pthrow(plib::pfmt("Error in truthtable: State {1:04} already set, {2} != {3}\n") + throw nl_exception(plib::pfmt("Error in truthtable: State {1:04} already set, {2} != {3}\n") .x(nstate.as_uint())(m_out_state[nstate])(val) ); m_out_state.set(nstate, val); for (std::size_t j=0; j &truthtable) for (size_t i=0; i(plib::pfmt("truthtable: found element not set {1}\n").x(i) ); + throw nl_exception(plib::pfmt("truthtable: found element not set {1}\n").x(i) ); m_out_state.set(i, m_out_state[i] | (ign[i] << m_NO)); } } diff --git a/src/lib/netlist/macro/nlm_opamp.cpp b/src/lib/netlist/macro/nlm_opamp.cpp index ae6b4762703..8925c0efdeb 100644 --- a/src/lib/netlist/macro/nlm_opamp.cpp +++ b/src/lib/netlist/macro/nlm_opamp.cpp @@ -78,7 +78,7 @@ static NETLIST_START(opamp_layout_1_7_4) A.MINUS, /* |2 7| */ A.VCC, A.PLUS, /* |3 6| */ A.OUT, A.GND, /* |4 5| */ NC /* OFFSET */ - /* +--------------+ */ + /* +--------------+ */ ) NETLIST_END() diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index ca4a8600cd2..ca1979333c4 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -170,7 +170,7 @@ namespace netlist else { state().log().fatal(MF_UNKNOWN_TYPE_FOR_OBJECT(name())); - plib::pthrow(MF_UNKNOWN_TYPE_FOR_OBJECT(name())); + throw nl_exception(MF_UNKNOWN_TYPE_FOR_OBJECT(name())); //return terminal_type::TERMINAL; // please compiler } } @@ -518,7 +518,7 @@ namespace netlist if (ret != nullptr) { m_log.fatal(MF_MORE_THAN_ONE_1_DEVICE_FOUND(classname)); - plib::pthrow(MF_MORE_THAN_ONE_1_DEVICE_FOUND(classname)); + throw nl_exception(MF_MORE_THAN_ONE_1_DEVICE_FOUND(classname)); } else ret = d.second.get(); @@ -619,7 +619,7 @@ namespace netlist if (!state().setup().connect(t1, t2)) { log().fatal(MF_ERROR_CONNECTING_1_TO_2(t1.name(), t2.name())); - plib::pthrow(MF_ERROR_CONNECTING_1_TO_2(t1.name(), t2.name())); + throw nl_exception(MF_ERROR_CONNECTING_1_TO_2(t1.name(), t2.name())); } } @@ -703,7 +703,7 @@ namespace netlist if (t == &terminal) { state().log().fatal(MF_NET_1_DUPLICATE_TERMINAL_2(name(), t->name())); - plib::pthrow(MF_NET_1_DUPLICATE_TERMINAL_2(name(), t->name())); + throw nl_exception(MF_NET_1_DUPLICATE_TERMINAL_2(name(), t->name())); } terminal.set_net(this); @@ -721,7 +721,7 @@ namespace netlist else { state().log().fatal(MF_REMOVE_TERMINAL_1_FROM_NET_2(terminal.name(), this->name())); - plib::pthrow(MF_REMOVE_TERMINAL_1_FROM_NET_2(terminal.name(), this->name())); + throw nl_exception(MF_REMOVE_TERMINAL_1_FROM_NET_2(terminal.name(), this->name())); } } @@ -791,9 +791,8 @@ namespace netlist , m_Idr1(nullptr) , m_go1(nullptr) , m_gt1(nullptr) - , m_connected_terminal(otherterm) { - state().setup().register_term(*this); + state().setup().register_term(*this, *otherterm); } void terminal_t::solve_now() @@ -908,7 +907,7 @@ namespace netlist else { state().log().fatal(MF_UNKNOWN_PARAM_TYPE(name())); - plib::pthrow(MF_UNKNOWN_PARAM_TYPE(name())); + throw nl_exception(MF_UNKNOWN_PARAM_TYPE(name())); } } diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index d2ec68800bf..2647ac679b2 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -819,7 +819,7 @@ namespace netlist void set_go_gt_I(nl_fptype GO, nl_fptype GT, nl_fptype I) const noexcept { - // FIXME: is this check still needed? + // Check for rail nets ... if (m_go1 != nullptr) { *m_Idr1 = I; @@ -832,16 +832,12 @@ namespace netlist void schedule_solve_after(netlist_time after) noexcept; void set_ptrs(nl_fptype *gt, nl_fptype *go, nl_fptype *Idr) noexcept(false); - - terminal_t *connected_terminal() const noexcept { return m_connected_terminal; } private: nl_fptype *m_Idr1; // drive current nl_fptype *m_go1; // conductance for Voltage from other term nl_fptype *m_gt1; // conductance for total conductance - terminal_t *m_connected_terminal; // FIXME: only used during setup - }; @@ -1091,7 +1087,7 @@ namespace netlist void connect(const pstring &t1, const pstring &t2); void connect(const detail::core_terminal_t &t1, const detail::core_terminal_t &t2); - void connect_post_start(detail::core_terminal_t &t1, detail::core_terminal_t &t2); + void connect_post_start(detail::core_terminal_t &t1, detail::core_terminal_t &t2) noexcept(false); protected: NETLIB_UPDATEI() { } @@ -1152,7 +1148,7 @@ namespace netlist class param_num_t final: public param_t { public: - param_num_t(device_t &device, const pstring &name, const T val); + param_num_t(device_t &device, const pstring &name, const T val) noexcept(false); T operator()() const noexcept { return m_param; } operator T() const noexcept { return m_param; } @@ -1166,7 +1162,7 @@ namespace netlist class param_enum_t final: public param_t { public: - param_enum_t(device_t &device, const pstring &name, const T val); + param_enum_t(device_t &device, const pstring &name, const T val) noexcept(false); T operator()() const noexcept { return T(m_param); } operator T() const noexcept { return T(m_param); } @@ -1255,7 +1251,7 @@ namespace netlist protected: void changed() noexcept override; private: -}; + }; // ----------------------------------------------------------------------------- // data parameter @@ -1388,7 +1384,7 @@ namespace netlist return dynamic_cast(p) != nullptr; } - core_device_t *get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const; + core_device_t *get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const noexcept(false); /// \brief Get single device filtered by class and name /// @@ -1485,7 +1481,7 @@ namespace netlist { dev.release(); log().fatal(MF_DUPLICATE_NAME_DEVICE_LIST(name)); - plib::pthrow(MF_DUPLICATE_NAME_DEVICE_LIST(name)); + throw nl_exception(MF_DUPLICATE_NAME_DEVICE_LIST(name)); } //m_devices.push_back(std::move(dev)); m_devices.insert(m_devices.end(), { name, std::move(dev) }); @@ -1587,7 +1583,7 @@ namespace netlist bool m_extended_validation; // dummy version - int m_dummy_version; + int m_dummy_version; }; namespace devices @@ -1778,7 +1774,7 @@ namespace netlist auto valx = func.evaluate(); if (std::is_integral::value) if (plib::abs(valx - plib::trunc(valx)) > nlconst::magic(1e-6)) - plib::pthrow(MF_INVALID_NUMBER_CONVERSION_1_2(device.name() + "." + name, p)); + throw nl_exception(MF_INVALID_NUMBER_CONVERSION_1_2(device.name() + "." + name, p)); m_param = static_cast(valx); } else @@ -1800,7 +1796,7 @@ namespace netlist if (!ok) { device.state().log().fatal(MF_INVALID_ENUM_CONVERSION_1_2(name, p)); - plib::pthrow(MF_INVALID_ENUM_CONVERSION_1_2(name, p)); + throw nl_exception(MF_INVALID_ENUM_CONVERSION_1_2(name, p)); } m_param = temp; } @@ -1934,7 +1930,7 @@ namespace netlist if (!(gt && go && Idr) && (gt || go || Idr)) { state().log().fatal("Inconsistent nullptrs for terminal {}", name()); - plib::pthrow("Inconsistent nullptrs for terminal {}", name()); + throw nl_exception("Inconsistent nullptrs for terminal {}", name()); } else { diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index 3ce69e9595f..7c7dd582e1e 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -17,11 +17,11 @@ /// /// \brief Version - Minor. /// -#define NL_VERSION_MINOR 7 +#define NL_VERSION_MINOR 8 /// /// \brief Version - Patch level. /// -#define NL_VERSION_PATCHLEVEL 1 +#define NL_VERSION_PATCHLEVEL 0 /// /// \addtogroup compiledefine @@ -143,10 +143,10 @@ /// /// | Bits | Res | Seconds | Days | Years | /// | ====-| ===-| =======-| ====-| =====-| -/// | 63 | 1,000,000,000 | 9,223,372,037 | 106,752| 292.3 | -/// | 63 | 10,000,000,000 | 922,337,204 | 10,675| 29.2 | -/// | 63 | 100,000,000,000 | 92,233,720 | 1,068| 2.9 | -/// | 63 | 1,000,000,000,000 | 9,223,372 | 107| 0.3 | +/// | 63 | 1,000,000,000 | 9,223,372,037 | 106,752| 292.3 | +/// | 63 | 10,000,000,000 | 922,337,204 | 10,675| 29.2 | +/// | 63 | 100,000,000,000 | 92,233,720 | 1,068| 2.9 | +/// | 63 | 1,000,000,000,000 | 9,223,372 | 107| 0.3 | /// static constexpr const auto NETLIST_INTERNAL_RES = 10'000'000'000LL; diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp index 4e53903971d..7577a9e7dc8 100644 --- a/src/lib/netlist/nl_factory.cpp +++ b/src/lib/netlist/nl_factory.cpp @@ -55,7 +55,7 @@ namespace factory { if (e->name() == factory->name()) { m_log.fatal(MF_FACTORY_ALREADY_CONTAINS_1(factory->name())); - plib::pthrow(MF_FACTORY_ALREADY_CONTAINS_1(factory->name())); + throw nl_exception(MF_FACTORY_ALREADY_CONTAINS_1(factory->name())); } push_back(std::move(factory)); } @@ -69,7 +69,7 @@ namespace factory { } m_log.fatal(MF_CLASS_1_NOT_FOUND(devname)); - plib::pthrow(MF_CLASS_1_NOT_FOUND(devname)); + throw nl_exception(MF_CLASS_1_NOT_FOUND(devname)); } // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h index b9d00b4bcd6..3abe7b49958 100644 --- a/src/lib/netlist/nl_factory.h +++ b/src/lib/netlist/nl_factory.h @@ -110,9 +110,9 @@ namespace factory { register_device(plib::make_unique>(name, classname, def_param)); } - void register_device(plib::unique_ptr &&factory); + void register_device(plib::unique_ptr &&factory) noexcept(false); - element_t * factory_by_name(const pstring &devname); + element_t * factory_by_name(const pstring &devname) noexcept(false); template bool is_class(element_t *f) noexcept diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp index e4d68c20c40..a2eea5494ca 100644 --- a/src/lib/netlist/nl_parser.cpp +++ b/src/lib/netlist/nl_parser.cpp @@ -15,7 +15,7 @@ namespace netlist void parser_t::verror(const pstring &msg) { m_setup.log().fatal("{1}", msg); - plib::pthrow(plib::pfmt("{1}")(msg)); + throw nl_exception(plib::pfmt("{1}")(msg)); } bool parser_t::parse(const pstring &nlname) diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 21b2c0e8999..b1fac785ff6 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -39,7 +39,7 @@ namespace netlist if (list.size() == 0 || (list.size() % 2) == 1) { log().fatal(MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1(build_fqn(""))); - plib::pthrow(MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1(build_fqn(""))); + throw nl_exception(MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1(build_fqn(""))); } std::size_t n = list.size(); for (std::size_t i = 0; i < n / 2; i++) @@ -94,7 +94,7 @@ namespace netlist { auto err(MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size())); log().fatal(err); - plib::pthrow(err); + throw nl_exception(err); //break; } pstring output_name = *ptok; @@ -116,7 +116,7 @@ namespace netlist { auto err(MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size())); log().fatal(err); - plib::pthrow(err); + throw nl_exception(err); } pstring paramfq = name + "." + tp; @@ -133,7 +133,7 @@ namespace netlist { auto err(MF_PARAM_COUNT_EXCEEDED_2(name, params_and_connections.size())); log().fatal(err); - plib::pthrow(err); + throw nl_exception(err); } } } @@ -144,7 +144,7 @@ namespace netlist if (f == nullptr) { log().fatal(MF_CLASS_1_NOT_FOUND(classname)); - plib::pthrow(MF_CLASS_1_NOT_FOUND(classname)); + throw nl_exception(MF_CLASS_1_NOT_FOUND(classname)); } else { @@ -154,7 +154,7 @@ namespace netlist if (device_exists(key)) { log().fatal(MF_DEVICE_ALREADY_EXISTS_1(name)); - plib::pthrow(MF_DEVICE_ALREADY_EXISTS_1(name)); + throw nl_exception(MF_DEVICE_ALREADY_EXISTS_1(name)); } else m_device_factory.insert(m_device_factory.end(), {key, f}); @@ -172,7 +172,7 @@ namespace netlist if (list.size() < 2) { log().fatal(MF_NET_C_NEEDS_AT_LEAST_2_TERMINAL()); - plib::pthrow(MF_NET_C_NEEDS_AT_LEAST_2_TERMINAL()); + throw nl_exception(MF_NET_C_NEEDS_AT_LEAST_2_TERMINAL()); } for (std::size_t i = 1; i < list.size(); i++) { @@ -188,7 +188,7 @@ namespace netlist })) return; log().fatal(MF_NOT_FOUND_IN_SOURCE_COLLECTION(netlist_name)); - plib::pthrow(MF_NOT_FOUND_IN_SOURCE_COLLECTION(netlist_name)); + throw nl_exception(MF_NOT_FOUND_IN_SOURCE_COLLECTION(netlist_name)); } @@ -225,7 +225,7 @@ namespace netlist if (!m_param_values.insert({fqn, value}).second) { log().fatal(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param)); - plib::pthrow(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param)); + throw nl_exception(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param)); } } else @@ -268,7 +268,7 @@ namespace netlist if (!found) { log().fatal(MF_FOUND_NO_OCCURRENCE_OF_1(attach)); - plib::pthrow(MF_FOUND_NO_OCCURRENCE_OF_1(attach)); + throw nl_exception(MF_FOUND_NO_OCCURRENCE_OF_1(attach)); } register_link(attach, frontier_name + ".Q"); } @@ -293,7 +293,7 @@ namespace netlist if (!m_alias.insert({alias, out}).second) { log().fatal(MF_ADDING_ALI1_TO_ALIAS_LIST(alias)); - plib::pthrow(MF_ADDING_ALI1_TO_ALIAS_LIST(alias)); + throw nl_exception(MF_ADDING_ALI1_TO_ALIAS_LIST(alias)); } } @@ -374,10 +374,16 @@ void setup_t::register_term(detail::core_terminal_t &term) if (!m_terminals.insert({term.name(), &term}).second) { log().fatal(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), term.name())); - plib::pthrow(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), term.name())); + throw nl_exception(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), term.name())); } } +void setup_t::register_term(terminal_t &term, terminal_t &other_term) +{ + this->register_term(term); + m_connected_terminals.insert({&term, &other_term}); +} + void setup_t::remove_connections(const pstring &pin) { pstring pinfn = build_fqn(pin); @@ -397,7 +403,7 @@ void setup_t::remove_connections(const pstring &pin) if (!found) { log().fatal(MF_FOUND_NO_OCCURRENCE_OF_1(pin)); - plib::pthrow(MF_FOUND_NO_OCCURRENCE_OF_1(pin)); + throw nl_exception(MF_FOUND_NO_OCCURRENCE_OF_1(pin)); } } @@ -406,7 +412,7 @@ void setup_t::register_param_t(const pstring &name, param_t ¶m) if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second) { log().fatal(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(name)); - plib::pthrow(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(name)); + throw nl_exception(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(name)); } } @@ -502,7 +508,7 @@ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool if (term == nullptr && required) { log().fatal(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname)); - plib::pthrow(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname)); + throw nl_exception(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname)); } if (term != nullptr) { @@ -527,7 +533,7 @@ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, if (ret == m_terminals.end() && required) { log().fatal(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname)); - plib::pthrow(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname)); + throw nl_exception(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname)); } detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second); @@ -536,7 +542,7 @@ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, if (required) { log().fatal(MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname)); - plib::pthrow(MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname)); + throw nl_exception(MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname)); } else term = nullptr; @@ -556,7 +562,7 @@ param_t *setup_t::find_param(const pstring ¶m_in, bool required) const if (ret == m_params.end() && required) { log().fatal(MF_PARAMETER_1_2_NOT_FOUND(param_in_fqn, outname)); - plib::pthrow(MF_PARAMETER_1_2_NOT_FOUND(param_in_fqn, outname)); + throw nl_exception(MF_PARAMETER_1_2_NOT_FOUND(param_in_fqn, outname)); } if (ret != m_params.end()) log().debug("Found parameter {1}\n", outname); @@ -586,7 +592,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out) { log().fatal(MF_CONNECTING_1_TO_2( new_proxy->proxy_term().name(), (*p).name())); - plib::pthrow(MF_CONNECTING_1_TO_2( + throw nl_exception(MF_CONNECTING_1_TO_2( new_proxy->proxy_term().name(), (*p).name())); } } @@ -596,7 +602,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out) auto proxy(new_proxy.get()); if (!m_proxies.insert({&out, proxy}).second) - plib::pthrow(MF_DUPLICATE_PROXY_1(out.name())); + throw nl_exception(MF_DUPLICATE_PROXY_1(out.name())); m_nlstate.register_device(new_proxy->name(), std::move(new_proxy)); return proxy; @@ -625,7 +631,7 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) auto ret(new_proxy.get()); if (!m_proxies.insert({&inp, ret}).second) - plib::pthrow(MF_DUPLICATE_PROXY_1(inp.name())); + throw nl_exception(MF_DUPLICATE_PROXY_1(inp.name())); m_proxy_cnt++; @@ -640,7 +646,7 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) { log().fatal(MF_CONNECTING_1_TO_2( ret->proxy_term().name(), (*p).name())); - plib::pthrow(MF_CONNECTING_1_TO_2( + throw nl_exception(MF_CONNECTING_1_TO_2( ret->proxy_term().name(), (*p).name())); } @@ -677,7 +683,7 @@ void setup_t::merge_nets(detail::net_t &thisnet, detail::net_t &othernet) if (thisnet.isRailNet() && othernet.isRailNet()) { log().fatal(MF_MERGE_RAIL_NETS_1_AND_2(thisnet.name(), othernet.name())); - plib::pthrow(MF_MERGE_RAIL_NETS_1_AND_2(thisnet.name(), othernet.name())); + throw nl_exception(MF_MERGE_RAIL_NETS_1_AND_2(thisnet.name(), othernet.name())); } if (othernet.isRailNet()) @@ -737,7 +743,7 @@ void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t & else { log().fatal(MF_OBJECT_INPUT_TYPE_1(inp.name())); - plib::pthrow(MF_OBJECT_INPUT_TYPE_1(inp.name())); + throw nl_exception(MF_OBJECT_INPUT_TYPE_1(inp.name())); } } @@ -762,7 +768,7 @@ void setup_t::connect_terminal_output(terminal_t &in, detail::core_terminal_t &o else { log().fatal(MF_OBJECT_OUTPUT_TYPE_1(out.name())); - plib::pthrow(MF_OBJECT_OUTPUT_TYPE_1(out.name())); + throw nl_exception(MF_OBJECT_OUTPUT_TYPE_1(out.name())); } } @@ -844,7 +850,7 @@ bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t if (t2.has_net() && t2.net().isRailNet()) { log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t2.name())); - plib::pthrow(MF_INPUT_1_ALREADY_CONNECTED(t2.name())); + throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(t2.name())); } connect_input_output(t2, t1); } @@ -853,7 +859,7 @@ bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t if (t1.has_net() && t1.net().isRailNet()) { log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t1.name())); - plib::pthrow(MF_INPUT_1_ALREADY_CONNECTED(t1.name())); + throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(t1.name())); } connect_input_output(t1, t2); } @@ -919,7 +925,7 @@ void setup_t::resolve_inputs() log().warning(MF_CONNECTING_1_TO_2(setup().de_alias(link.first), setup().de_alias(link.second))); log().fatal(MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops())); - plib::pthrow(MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops())); + throw nl_exception(MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops())); } log().verbose("deleting empty nets ..."); @@ -964,7 +970,7 @@ void setup_t::resolve_inputs() if (err) { log().fatal(MF_TERMINALS_WITHOUT_NET()); - plib::pthrow(MF_TERMINALS_WITHOUT_NET()); + throw nl_exception(MF_TERMINALS_WITHOUT_NET()); } } @@ -1006,11 +1012,11 @@ void models_t::register_model(const pstring &model_in) { auto pos = model_in.find(' '); if (pos == pstring::npos) - plib::pthrow(MF_UNABLE_TO_PARSE_MODEL_1(model_in)); + throw nl_exception(MF_UNABLE_TO_PARSE_MODEL_1(model_in)); pstring model = plib::ucase(plib::trim(plib::left(model_in, pos))); pstring def = plib::trim(model_in.substr(pos + 1)); if (!m_models.insert({model, def}).second) - plib::pthrow(MF_MODEL_ALREADY_EXISTS_1(model_in)); + throw nl_exception(MF_MODEL_ALREADY_EXISTS_1(model_in)); } void models_t::model_parse(const pstring &model_in, model_map_t &map) @@ -1027,7 +1033,7 @@ void models_t::model_parse(const pstring &model_in, model_map_t &map) key = plib::ucase(model); auto i = m_models.find(key); if (i == m_models.end()) - plib::pthrow(MF_MODEL_NOT_FOUND(model)); + throw nl_exception(MF_MODEL_NOT_FOUND(model)); model = i->second; } pstring xmodel = plib::left(model, pos); @@ -1040,12 +1046,12 @@ void models_t::model_parse(const pstring &model_in, model_map_t &map) if (i != m_models.end()) model_parse(xmodel, map); else - plib::pthrow(MF_MODEL_NOT_FOUND(model_in)); + throw nl_exception(MF_MODEL_NOT_FOUND(model_in)); } pstring remainder = plib::trim(model.substr(pos + 1)); if (!plib::endsWith(remainder, ")")) - plib::pthrow(MF_MODEL_ERROR_1(model)); + throw nl_exception(MF_MODEL_ERROR_1(model)); // FIMXE: Not optimal remainder = plib::left(remainder, remainder.size() - 1); @@ -1054,7 +1060,7 @@ void models_t::model_parse(const pstring &model_in, model_map_t &map) { auto pose = pe.find('='); if (pose == pstring::npos) - plib::pthrow(MF_MODEL_ERROR_ON_PAIR_1(model)); + throw nl_exception(MF_MODEL_ERROR_ON_PAIR_1(model)); map[plib::ucase(plib::left(pe, pose))] = pe.substr(pose + 1); } } @@ -1079,9 +1085,9 @@ pstring models_t::value_str(const pstring &model, const pstring &entity) pstring ret; if (entity != plib::ucase(entity)) - plib::pthrow(MF_MODEL_PARAMETERS_NOT_UPPERCASE_1_2(entity, model_string(map))); + throw nl_exception(MF_MODEL_PARAMETERS_NOT_UPPERCASE_1_2(entity, model_string(map))); if (map.find(entity) == map.end()) - plib::pthrow(MF_ENTITY_1_NOT_FOUND_IN_MODEL_2(entity, model_string(map))); + throw nl_exception(MF_ENTITY_1_NOT_FOUND_IN_MODEL_2(entity, model_string(map))); else ret = map[entity]; @@ -1112,7 +1118,7 @@ nl_fptype models_t::value(const pstring &model, const pstring &entity) case 'a': factor = nlconst::magic(1e-18); break; default: if (*p < '0' || *p > '9') - plib::pthrow(MF_UNKNOWN_NUMBER_FACTOR_IN_1(entity)); + throw nl_exception(MF_UNKNOWN_NUMBER_FACTOR_IN_1(entity)); } if (factor != nlconst::one()) tmp = plib::left(tmp, tmp.size() - 1); @@ -1121,7 +1127,7 @@ nl_fptype models_t::value(const pstring &model, const pstring &entity) bool err(false); auto val = plib::pstonum_ne(tmp, err); if (err) - plib::pthrow(MF_MODEL_NUMBER_CONVERSION_ERROR(entity, tmp, "double", model)); + throw nl_exception(MF_MODEL_NUMBER_CONVERSION_ERROR(entity, tmp, "double", model)); return val * factor; } @@ -1284,7 +1290,7 @@ void setup_t::prepare_to_run() if (err || plib::abs(v - plib::floor(v)) > nlconst::magic(1e-6) ) { log().fatal(MF_HND_VAL_NOT_SUPPORTED(p->second)); - plib::pthrow(MF_HND_VAL_NOT_SUPPORTED(p->second)); + throw nl_exception(MF_HND_VAL_NOT_SUPPORTED(p->second)); } // FIXME comparison with zero d.second->set_hint_deactivate(v == nlconst::zero()); @@ -1318,7 +1324,7 @@ void setup_t::prepare_to_run() if (p->is_analog()) { log().fatal(MF_NO_SOLVER()); - plib::pthrow(MF_NO_SOLVER()); + throw nl_exception(MF_NO_SOLVER()); } } else diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index c8f1b4b2250..356eef71999 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -385,6 +385,16 @@ namespace netlist pstring get_initial_param_val(const pstring &name, const pstring &def) const; void register_term(detail::core_terminal_t &term); + void register_term(terminal_t &term, terminal_t &other_term); + + terminal_t *get_connected_terminal(const terminal_t &term) const noexcept + { + auto ret(m_connected_terminals.find(&term)); + if (ret != m_connected_terminals.end()) + return ret->second; + else + return nullptr; + } void remove_connections(const pstring &pin); @@ -443,6 +453,7 @@ namespace netlist detail::core_terminal_t &resolve_proxy(detail::core_terminal_t &term); std::unordered_map m_terminals; + std::unordered_map m_connected_terminals; netlist_state_t &m_nlstate; devices::nld_netlistparams *m_netlist_params; diff --git a/src/lib/netlist/plib/mat_cr.h b/src/lib/netlist/plib/mat_cr.h index 3208ceeed3f..90d4e0aca40 100644 --- a/src/lib/netlist/plib/mat_cr.h +++ b/src/lib/netlist/plib/mat_cr.h @@ -110,11 +110,11 @@ namespace plib template void build_from_fill_mat(const M &f, std::size_t max_fill = FILL_INFINITY - 1, - std::size_t band_width = FILL_INFINITY) + std::size_t band_width = FILL_INFINITY) noexcept(false) { C nz = 0; if (nz_num != 0) - pthrow("build_from_mat only allowed on empty CR matrix"); + throw pexception("build_from_mat only allowed on empty CR matrix"); for (std::size_t k=0; k < size(); k++) { row_idx[k] = nz; @@ -177,7 +177,7 @@ namespace plib // throws error if P(source)>P(destination) template - void slim_copy_from(LUMAT & src) + void slim_copy_from(LUMAT & src) noexcept(false) { for (std::size_t r=0; r("slim_copy_from error"); + throw pexception("slim_copy_from error"); A[dp++] = src.A[sp]; } // fill remaining elements in row diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h index c60698d10e1..e2454f5691b 100644 --- a/src/lib/netlist/plib/parray.h +++ b/src/lib/netlist/plib/parray.h @@ -76,21 +76,21 @@ namespace plib { } template - parray(size_type size, typename std::enable_if<(X != 0), int>::type = 0) + parray(size_type size, typename std::enable_if<(X != 0), int>::type = 0) noexcept(false) : m_size(size) { if ((SIZE < 0 && size > SIZEABS()) || (SIZE > 0 && size != SIZEABS())) - pthrow("parray: size error " + plib::to_string(size) + ">" + plib::to_string(SIZE)); + throw pexception("parray: size error " + plib::to_string(size) + ">" + plib::to_string(SIZE)); } template - parray(size_type size, FT val, typename std::enable_if<(X != 0), int>::type = 0) + parray(size_type size, FT val, typename std::enable_if<(X != 0), int>::type = 0) noexcept(false) : m_size(size) { if ((SIZE < 0 && size > SIZEABS()) || (SIZE > 0 && size != SIZEABS())) - pthrow("parray: size error " + plib::to_string(size) + ">" + plib::to_string(SIZE)); + throw pexception("parray: size error " + plib::to_string(size) + ">" + plib::to_string(SIZE)); m_a.fill(val); } diff --git a/src/lib/netlist/plib/pexception.h b/src/lib/netlist/plib/pexception.h index 22b67925b7e..703e407eae7 100644 --- a/src/lib/netlist/plib/pexception.h +++ b/src/lib/netlist/plib/pexception.h @@ -30,19 +30,6 @@ namespace plib { [[noreturn]] void passert_fail(const char *assertion, const char *file, int lineno, const char *msg) noexcept; - /// \brief throw an exception. - /// - /// throws an exception E. The purpose is to clearly identify exception - /// throwing in the code - /// - /// \tparam E Type of exception to be thrown - /// - template - [[noreturn]] static inline void pthrow(Args&&... args) noexcept(false) - { - throw E(std::forward(args)...); - } - //============================================================ // exception base //============================================================ diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp index dee38f86416..87313c30008 100644 --- a/src/lib/netlist/plib/pfunction.cpp +++ b/src/lib/netlist/plib/pfunction.cpp @@ -15,7 +15,7 @@ namespace plib { template - void pfunction::compile(const pstring &expr, const std::vector &inputs) + void pfunction::compile(const pstring &expr, const std::vector &inputs) noexcept(false) { if (plib::startsWith(expr, "rpn:")) compile_postfix(expr.substr(4), inputs); @@ -24,7 +24,7 @@ namespace plib { } template - void pfunction::compile_postfix(const pstring &expr, const std::vector &inputs) + void pfunction::compile_postfix(const pstring &expr, const std::vector &inputs) noexcept(false) { std::vector cmds(plib::psplit(expr, " ")); compile_postfix(inputs, cmds, expr); @@ -32,7 +32,7 @@ namespace plib { template void pfunction::compile_postfix(const std::vector &inputs, - const std::vector &cmds, const pstring &expr) + const std::vector &cmds, const pstring &expr) noexcept(false) { m_precompiled.clear(); int stk = 0; @@ -76,16 +76,16 @@ namespace plib { bool err(false); rc.m_param = plib::pstonum_ne(cmd, err); if (err) - pthrow(plib::pfmt("pfunction: unknown/misformatted token <{1}> in <{2}>")(cmd)(expr)); + throw pexception(plib::pfmt("pfunction: unknown/misformatted token <{1}> in <{2}>")(cmd)(expr)); stk += 1; } } if (stk < 1) - pthrow(plib::pfmt("pfunction: stack underflow on token <{1}> in <{2}>")(cmd)(expr)); + throw pexception(plib::pfmt("pfunction: stack underflow on token <{1}> in <{2}>")(cmd)(expr)); m_precompiled.push_back(rc); } if (stk != 1) - pthrow(plib::pfmt("pfunction: stack count different to one on <{2}>")(expr)); + throw pexception(plib::pfmt("pfunction: stack count different to one on <{2}>")(expr)); } static int get_prio(const pstring &v) @@ -104,10 +104,10 @@ namespace plib { return -1; } - static pstring pop_check(std::stack &stk, const pstring &expr) + static pstring pop_check(std::stack &stk, const pstring &expr) noexcept(false) { if (stk.size() == 0) - pthrow(plib::pfmt("pfunction: stack underflow during infix parsing of: <{1}>")(expr)); + throw pexception(plib::pfmt("pfunction: stack underflow during infix parsing of: <{1}>")(expr)); pstring res = stk.top(); stk.pop(); return res; diff --git a/src/lib/netlist/plib/pfunction.h b/src/lib/netlist/plib/pfunction.h index c6e94614856..6d556ba2351 100644 --- a/src/lib/netlist/plib/pfunction.h +++ b/src/lib/netlist/plib/pfunction.h @@ -76,21 +76,21 @@ namespace plib { /// to be prefixed with rpn, e.g. "rpn:A B + 1.3 /" /// \param inputs Vector of input variables, e.g. {"A","B"} /// - void compile(const pstring &expr, const std::vector &inputs); + void compile(const pstring &expr, const std::vector &inputs) noexcept(false); /// \brief Compile a rpn expression /// /// \param expr Reverse polish notation expression, e.g. "A B + 1.3 /" /// \param inputs Vector of input variables, e.g. {"A","B"} /// - void compile_postfix(const pstring &expr, const std::vector &inputs); + void compile_postfix(const pstring &expr, const std::vector &inputs) noexcept(false); /// \brief Compile an infix expression /// /// \param expr Infix expression, e.g. "(A+B)/1.3" /// \param inputs Vector of input variables, e.g. {"A","B"} /// - void compile_infix(const pstring &expr, const std::vector &inputs); + void compile_infix(const pstring &expr, const std::vector &inputs) noexcept(false); /// \brief Evaluate the expression /// diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index 6f6ace0599c..6746e453fae 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -75,7 +75,7 @@ namespace plib { { if (m_other_args != nullptr) { - pthrow("other args can only be specified once!"); + throw pexception("other args can only be specified once!"); } else { @@ -83,7 +83,7 @@ namespace plib { } } else - pthrow("found option with neither short or long tag!" ); + throw pexception("found option with neither short or long tag!" ); } } } diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h index 15f43e0330e..53b87812609 100644 --- a/src/lib/netlist/plib/poptions.h +++ b/src/lib/netlist/plib/poptions.h @@ -236,7 +236,7 @@ namespace plib { static pstring split_paragraphs(const pstring &text, unsigned width, unsigned indent, unsigned firstline_indent); - void check_consistency(); + void check_consistency() noexcept(false); template T *getopt_type() const diff --git a/src/lib/netlist/plib/ppreprocessor.cpp b/src/lib/netlist/plib/ppreprocessor.cpp index 377c37d9fca..f98a57cb921 100644 --- a/src/lib/netlist/plib/ppreprocessor.cpp +++ b/src/lib/netlist/plib/ppreprocessor.cpp @@ -63,7 +63,7 @@ namespace plib { s = trail + plib::pfmt("{1}:{2}:0\n")(m_stack.back().m_name, m_stack.back().m_lineno) + s; m_stack.pop_back(); } - pthrow("\n" + s + e + " " + m_line + "\n"); + throw pexception("\n" + s + e + " " + m_line + "\n"); } template diff --git a/src/lib/netlist/plib/ppreprocessor.h b/src/lib/netlist/plib/ppreprocessor.h index 892015b7f5a..fe498fc1148 100644 --- a/src/lib/netlist/plib/ppreprocessor.h +++ b/src/lib/netlist/plib/ppreprocessor.h @@ -77,7 +77,7 @@ namespace plib { return *this; } - [[noreturn]] void error(const pstring &err); + [[noreturn]] void error(const pstring &err) noexcept(false); protected: diff --git a/src/lib/netlist/plib/pstonum.h b/src/lib/netlist/plib/pstonum.h index eed69e85883..737dca9f471 100644 --- a/src/lib/netlist/plib/pstonum.h +++ b/src/lib/netlist/plib/pstonum.h @@ -95,7 +95,7 @@ namespace plib #endif template - T pstonum(const S &arg, const std::locale &loc = std::locale::classic()) + T pstonum(const S &arg, const std::locale &loc = std::locale::classic()) noexcept(false) { decltype(arg.c_str()) cstr = arg.c_str(); std::size_t idx(0); @@ -106,11 +106,11 @@ namespace plib //&& (ret == T(0) || plib::abs(ret) >= std::numeric_limits::min() )) { if (cstr[idx] != 0) - pthrow(pstring("Continuation after numeric value ends: ") + pstring(cstr)); + throw pexception(pstring("Continuation after numeric value ends: ") + pstring(cstr)); } else { - pthrow(pstring("Out of range: ") + pstring(cstr)); + throw pexception(pstring("Out of range: ") + pstring(cstr)); } return static_cast(ret); } diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h index 4a9d99300bb..43cdf5f7e32 100644 --- a/src/lib/netlist/plib/pstring.h +++ b/src/lib/netlist/plib/pstring.h @@ -111,7 +111,7 @@ public: template::value>::type> - pstring_t(C (&string)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) + pstring_t(C (&string)[N]) noexcept(false) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays) { static_assert(N > 0,"pstring from array of length 0"); // need std::exception since pexception depends on pstring diff --git a/src/lib/netlist/plib/ptime.h b/src/lib/netlist/plib/ptime.h index 82ee2213015..72687c44527 100644 --- a/src/lib/netlist/plib/ptime.h +++ b/src/lib/netlist/plib/ptime.h @@ -30,7 +30,7 @@ namespace plib #if 0 template struct ptime_res { - using type = typename std::conditional= sizeof(U), T, U>::type; + using type = typename std::conditional= sizeof(U), T, U>::type; }; #endif diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index dd4a82acea7..b79ff88251e 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -275,7 +275,7 @@ public: size += s->dt().size() * s->count(); if (buf.size() != size) - plib::pthrow("Size different during load state."); + throw netlist::nl_exception("Size different during load state."); char *p = buf.data(); @@ -321,7 +321,7 @@ struct input_t // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) int e = std::sscanf(line.c_str(), "%lf,%[^,],%lf", &t, buf.data(), &val); if (e != 3) - plib::pthrow(plib::pfmt("error {1} scanning line {2}\n")(e)(line)); + throw netlist::nl_exception(plib::pfmt("error {1} scanning line {2}\n")(e)(line)); m_value = static_cast(val); m_time = netlist::netlist_time_ext::from_fp(t); m_param = setup.find_param(pstring(buf.data()), true); @@ -333,7 +333,7 @@ struct input_t { case netlist::param_t::STRING: case netlist::param_t::POINTER: - plib::pthrow(plib::pfmt("param {1} is not numeric\n")(m_param->name())); + throw netlist::nl_exception(plib::pfmt("param {1} is not numeric\n")(m_param->name())); case netlist::param_t::DOUBLE: static_cast(m_param)->setTo(m_value); break; @@ -358,7 +358,7 @@ static std::vector read_input(const netlist::setup_t &setup, const pstr { plib::putf8_reader r = plib::putf8_reader(std::ifstream(plib::filesystem::u8path(fname))); if (r.stream().fail()) - plib::pthrow(netlist::MF_FILE_OPEN_ERROR(fname)); + throw netlist::nl_exception(netlist::MF_FILE_OPEN_ERROR(fname)); r.stream().imbue(std::locale::classic()); pstring l; while (r.readline(l)) @@ -415,7 +415,7 @@ void tool_app_t::run() { std::ifstream strm(plib::filesystem::u8path(opt_loadstate())); if (strm.fail()) - plib::pthrow(netlist::MF_FILE_OPEN_ERROR(opt_loadstate())); + throw netlist::nl_exception(netlist::MF_FILE_OPEN_ERROR(opt_loadstate())); strm.imbue(std::locale::classic()); plib::pbinary_reader reader(strm); std::vector loadstate; @@ -453,7 +453,7 @@ void tool_app_t::run() auto savestate = nt.save_state(); std::ofstream strm(plib::filesystem::u8path(opt_savestate()), std::ios_base::binary); if (strm.fail()) - plib::pthrow(opt_savestate()); + throw plib::file_open_e(opt_savestate()); strm.imbue(std::locale::classic()); plib::pbinary_writer writer(strm); @@ -501,14 +501,14 @@ void tool_app_t::validate() //pout("Validation errors: {}\n", m_errors); if (m_warnings + m_errors > 0) - plib::pthrow("validation: {1} errors {2} warnings", m_errors, m_warnings); + throw netlist::nl_exception("validation: {1} errors {2} warnings", m_errors, m_warnings); } void tool_app_t::static_compile() { if (!opt_dir.was_specified()) - plib::pthrow("--dir option needs to be specified"); + throw netlist::nl_exception("--dir option needs to be specified"); netlist_tool_t nt(*this, "netlist"); @@ -568,7 +568,7 @@ static doc_ext read_docsrc(const pstring &fname, const pstring &id) //printf("file %s\n", fname.c_str()); plib::putf8_reader r = plib::putf8_reader(std::ifstream(plib::filesystem::u8path(fname))); if (r.stream().fail()) - plib::pthrow(netlist::MF_FILE_OPEN_ERROR(fname)); + throw netlist::nl_exception(netlist::MF_FILE_OPEN_ERROR(fname)); r.stream().imbue(std::locale::classic()); doc_ext ret; @@ -585,7 +585,7 @@ static doc_ext read_docsrc(const pstring &fname, const pstring &id) { auto a(plib::psplit(l, ":", true)); if ((a.size() < 1) || (a.size() > 2)) - plib::pthrow(l+" size mismatch"); + throw netlist::nl_exception(l+" size mismatch"); pstring n(plib::trim(a[0])); pstring v(a.size() < 2 ? "" : plib::trim(a[1])); if (n == "Identifier") @@ -622,10 +622,10 @@ static doc_ext read_docsrc(const pstring &fname, const pstring &id) { ret.example = plib::psplit(plib::trim(v),",",true); if (ret.example.size() != 2 && ret.example.size() != 0) - plib::pthrow("Example requires 2 parameters, but found {1}", ret.example.size()); + throw netlist::nl_exception("Example requires 2 parameters, but found {1}", ret.example.size()); } else - plib::pthrow(n); + throw netlist::nl_exception(n); } } } @@ -939,7 +939,7 @@ void tool_app_t::convert() { std::ifstream strm(plib::filesystem::u8path(opt_file())); if (strm.fail()) - plib::pthrow(netlist::MF_FILE_OPEN_ERROR(opt_file())); + throw netlist::nl_exception(netlist::MF_FILE_OPEN_ERROR(opt_file())); strm.imbue(std::locale::classic()); plib::copystream(ostrm, strm); } diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index e3c53bb7c4e..fb59dbdc667 100644 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -534,7 +534,7 @@ int nlwav_app::execute() { auto outstrm(std::ofstream(plib::filesystem::u8path(opt_out()))); if (outstrm.fail()) - plib::pthrow(opt_out()); + throw plib::file_open_e(opt_out()); outstrm.imbue(std::locale::classic()); convert(outstrm); } diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp index 493973d6dc2..951ae526999 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.cpp +++ b/src/lib/netlist/solver/nld_matrix_solver.cpp @@ -2,6 +2,7 @@ // copyright-holders:Couriersud #include "nld_matrix_solver.h" +#include "nl_setup.h" #include "plib/putil.h" namespace netlist @@ -57,6 +58,11 @@ namespace solver setup_matrix(); } + analog_net_t *matrix_solver_t::get_connected_net(terminal_t *term) + { + return &state().setup().get_connected_terminal(*term)->net(); + } + void matrix_solver_t::setup_base(const analog_net_t::list_t &nets) { log().debug("New solver setup\n"); @@ -121,7 +127,7 @@ namespace solver break; case detail::terminal_type::OUTPUT: log().fatal(MF_UNHANDLED_ELEMENT_1_FOUND(p->name())); - plib::pthrow(MF_UNHANDLED_ELEMENT_1_FOUND(p->name())); + throw nl_exception(MF_UNHANDLED_ELEMENT_1_FOUND(p->name())); } } } @@ -211,7 +217,7 @@ namespace solver for (std::size_t i = 0; i < term.count(); i++) //FIXME: this is weird if (other[i] != -1) - other[i] = get_net_idx(&term.terms()[i]->connected_terminal()->net()); + other[i] = get_net_idx(get_connected_net(term.terms()[i])); } } @@ -342,6 +348,36 @@ namespace solver } } + void matrix_solver_t::set_pointers() + { + const std::size_t iN = this->m_terms.size(); + + std::size_t max_count = 0; + std::size_t max_rail = 0; + for (std::size_t k = 0; k < iN; k++) + { + max_count = std::max(max_count, m_terms[k].count()); + max_rail = std::max(max_rail, m_terms[k].railstart()); + } + + m_gtn.resize(iN, max_count); + m_gonn.resize(iN, max_count); + m_Idrn.resize(iN, max_count); + m_connected_net_Vn.resize(iN, max_count); + + for (std::size_t k = 0; k < iN; k++) + { + auto count = m_terms[k].count(); + + for (std::size_t i = 0; i < count; i++) + { + m_terms[k].terms()[i]->set_ptrs(&m_gtn[k][i], &m_gonn[k][i], &m_Idrn[k][i]); + //m_connected_net_Vn[k][i] = m_terms[k].terms()[i]->connected_terminal()->net().Q_Analog_state_ptr(); + m_connected_net_Vn[k][i] = get_connected_net(m_terms[k].terms()[i])->Q_Analog_state_ptr(); + } + } + } + void matrix_solver_t::update_inputs() { // avoid recursive calls. Inputs are updated outside this call @@ -466,7 +502,7 @@ namespace solver for (std::size_t i = 0; i < term.count(); i++) { - auto col = get_net_idx(&term.terms()[i]->connected_terminal()->net()); + auto col = get_net_idx(get_connected_net(term.terms()[i])); if (col != -1) { if (col==row) col = diag; @@ -494,7 +530,7 @@ namespace solver auto &term = m_terms[row]; for (std::size_t i = 0; i < term.count(); i++) { - auto col = get_net_idx(&term.terms()[i]->connected_terminal()->net()); + auto col = get_net_idx(get_connected_net(term.terms()[i])); if (col >= 0) { auto colu = static_cast(col); @@ -508,29 +544,29 @@ namespace solver } } } - return weight; // / static_cast(term.railstart()); + return weight; } } void matrix_solver_t::add_term(std::size_t net_idx, terminal_t *term) { - if (term->connected_terminal()->net().isRailNet()) + if (get_connected_net(term)->isRailNet()) { m_rails_temp[net_idx].add_terminal(term, -1, false); } else { - int ot = get_net_idx(&term->connected_terminal()->net()); + int ot = get_net_idx(get_connected_net(term)); if (ot>=0) { m_terms[net_idx].add_terminal(term, ot, true); } // Should this be allowed ? - else // if (ot<0) + else { m_rails_temp[net_idx].add_terminal(term, ot, true); log().fatal(MF_FOUND_TERM_WITH_MISSING_OTHERNET(term->name())); - plib::pthrow(MF_FOUND_TERM_WITH_MISSING_OTHERNET(term->name())); + throw nl_exception(MF_FOUND_TERM_WITH_MISSING_OTHERNET(term->name())); } } } diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index 2c7bc4fff7b..0c3f416aec2 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -245,7 +245,7 @@ namespace solver std::size_t m_ops; // base setup - called from constructor - void setup_base(const analog_net_t::list_t &nets); + void setup_base(const analog_net_t::list_t &nets) noexcept(false); void sort_terms(matrix_sort_type_e sort); @@ -256,39 +256,15 @@ namespace solver std::pair get_left_right_of_diag(std::size_t irow, std::size_t idiag); nl_fptype get_weight_around_diag(std::size_t row, std::size_t diag); - void add_term(std::size_t net_idx, terminal_t *term); + void add_term(std::size_t net_idx, terminal_t *term) noexcept(false); // calculate matrix void setup_matrix(); - void set_pointers() - { - const std::size_t iN = this->m_terms.size(); + void set_pointers(); - std::size_t max_count = 0; - std::size_t max_rail = 0; - for (std::size_t k = 0; k < iN; k++) - { - max_count = std::max(max_count, m_terms[k].count()); - max_rail = std::max(max_rail, m_terms[k].railstart()); - } - - m_gtn.resize(iN, max_count); - m_gonn.resize(iN, max_count); - m_Idrn.resize(iN, max_count); - m_connected_net_Vn.resize(iN, max_count); - - for (std::size_t k = 0; k < iN; k++) - { - auto count = m_terms[k].count(); - - for (std::size_t i = 0; i < count; i++) - { - m_terms[k].terms()[i]->set_ptrs(&m_gtn[k][i], &m_gonn[k][i], &m_Idrn[k][i]); - m_connected_net_Vn[k][i] = m_terms[k].terms()[i]->connected_terminal()->net().Q_Analog_state_ptr(); - } - } - } + private: + analog_net_t *get_connected_net(terminal_t *term); }; diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 920e3a82452..09920dfd73c 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -27,6 +27,7 @@ #endif #include "netlist/nl_factory.h" +#include "netlist/nl_setup.h" // FIXME: only needed for splitter code #include "nld_matrix_solver.h" #include "nld_ms_direct.h" #include "nld_ms_direct1.h" @@ -264,7 +265,7 @@ namespace devices return false; } - void process_net(analog_net_t &n) + void process_net(netlist_state_t &netlist, analog_net_t &n) { // ignore empty nets. FIXME: print a warning message if (n.num_cons() == 0) @@ -279,9 +280,10 @@ namespace devices { auto *pt = static_cast(term); // check the connected terminal - analog_net_t &connected_net = pt->connected_terminal()->net(); + // analog_net_t &connected_net = pt->connected_terminal()->net(); + analog_net_t &connected_net = netlist.setup().get_connected_terminal(*pt)->net(); if (!already_processed(connected_net)) - process_net(connected_net); + process_net(netlist, connected_net); } } } @@ -299,7 +301,7 @@ namespace devices if (!already_processed(n)) { groups.emplace_back(analog_net_t::list_t()); - process_net(n); + process_net(netlist, n); } } }