diff options
author | 2019-10-18 17:57:55 +0200 | |
---|---|---|
committer | 2019-10-18 17:57:55 +0200 | |
commit | b09fa00cca1a9baa0327a33d865fc970f77d4db0 (patch) | |
tree | 47dd943368aa43a0c0cf4256f88e590960c1e99f | |
parent | ad27643c07d54fc2cc3e56327fe07335e7763d52 (diff) |
Netlist: code maintenance and improvements. [Couriersud]
- Added support for line markers to the preprocessor and parser.
- Added support for include processing to the preprocessor.
- Moved sources base type to plib to be used for preprocessor includes.
This enables to include e.g. from rom memory regions.
- Renamed some defines
27 files changed, 502 insertions, 204 deletions
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index a78b4b5f2fc..2d0ba8244b4 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -286,13 +286,13 @@ public: : netlist::nl_exception(plib::pfmt(fmt)(std::forward<Args>(args)...)) { } }; -class netlist_source_memregion_t : public netlist::source_t +class netlist_source_memregion_t : public netlist::source_netlist_t { public: netlist_source_memregion_t(device_t &dev, pstring name) - : netlist::source_t(), m_dev(dev), m_name(name) + : netlist::source_netlist_t(), m_dev(dev), m_name(name) { } @@ -302,7 +302,7 @@ private: pstring m_name; }; -class netlist_data_memregions_t : public netlist::source_t +class netlist_data_memregions_t : public netlist::source_data_t { public: netlist_data_memregions_t(const device_t &dev); @@ -333,7 +333,7 @@ plib::unique_ptr<std::istream> netlist_source_memregion_t::stream(const pstring } netlist_data_memregions_t::netlist_data_memregions_t(const device_t &dev) - : netlist::source_t(netlist::source_t::DATA), m_dev(dev) + : netlist::source_data_t(), m_dev(dev) { } diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp index d13f3271135..a1c9eb36bbf 100644 --- a/src/lib/netlist/devices/net_lib.cpp +++ b/src/lib/netlist/devices/net_lib.cpp @@ -66,7 +66,7 @@ namespace devices LIB_ENTRY(2102A_dip) LIB_ENTRY(2716) LIB_ENTRY(2716_dip) -#if !(USE_TRUTHTABLE_7448) +#if !(NL_USE_TRUTHTABLE_7448) LIB_ENTRY(7448) LIB_ENTRY(7448_dip) #endif @@ -92,7 +92,7 @@ namespace devices LIB_ENTRY(7493_dip) LIB_ENTRY(7497) LIB_ENTRY(7497_dip) -#if (!USE_TRUTHTABLE_74107) +#if (!NL_USE_TRUTHTABLE_74107) LIB_ENTRY(74107) LIB_ENTRY(74107_dip) #endif diff --git a/src/lib/netlist/devices/nld_74107.cpp b/src/lib/netlist/devices/nld_74107.cpp index c0978cb0128..53279f7df3a 100644 --- a/src/lib/netlist/devices/nld_74107.cpp +++ b/src/lib/netlist/devices/nld_74107.cpp @@ -145,7 +145,7 @@ namespace netlist m_clk.activate_hl(); } -#if (!USE_TRUTHTABLE_74107) +#if (!NL_USE_TRUTHTABLE_74107) NETLIB_DEVICE_IMPL(74107, "TTL_74107", "+CLK,+J,+K,+CLRQ,@VCC,@GND") NETLIB_DEVICE_IMPL(74107_dip, "TTL_74107_DIP", "") #endif diff --git a/src/lib/netlist/devices/nld_74107.h b/src/lib/netlist/devices/nld_74107.h index ae1adf33546..306ae8b1174 100644 --- a/src/lib/netlist/devices/nld_74107.h +++ b/src/lib/netlist/devices/nld_74107.h @@ -75,7 +75,7 @@ NET_CONNECT(name, K, cK) \ NET_CONNECT(name, CLRQ, cCLRQ) -#if (!USE_TRUTHTABLE_74107) +#if (!NL_USE_TRUTHTABLE_74107) #define TTL_74107(name, cCLK, cJ, cK, cCLRQ) \ TTL_74107A(name, cCLK, cJ, cK, cCLRQ) diff --git a/src/lib/netlist/devices/nld_7448.cpp b/src/lib/netlist/devices/nld_7448.cpp index 34826a068f9..cc24e402cfa 100644 --- a/src/lib/netlist/devices/nld_7448.cpp +++ b/src/lib/netlist/devices/nld_7448.cpp @@ -15,7 +15,7 @@ namespace netlist { namespace devices { - #if !(USE_TRUTHTABLE_7448) + #if !(NL_USE_TRUTHTABLE_7448) NETLIB_OBJECT(7448) { NETLIB_CONSTRUCTOR(7448) @@ -79,7 +79,7 @@ namespace netlist #endif - #if !(USE_TRUTHTABLE_7448) + #if !(NL_USE_TRUTHTABLE_7448) #define BITS7(b6,b5,b4,b3,b2,b1,b0) ((b6)<<6) | ((b5)<<5) | ((b4)<<4) | ((b3)<<3) | ((b2)<<2) | ((b1)<<1) | ((b0)<<0) diff --git a/src/lib/netlist/devices/nld_7448.h b/src/lib/netlist/devices/nld_7448.h index 55ebfd8d6e4..8fd4e13c734 100644 --- a/src/lib/netlist/devices/nld_7448.h +++ b/src/lib/netlist/devices/nld_7448.h @@ -27,7 +27,7 @@ #include "netlist/nl_setup.h" #ifndef NL_AUTO_DEVICES -#if !(USE_TRUTHTABLE_7448) +#if !(NL_USE_TRUTHTABLE_7448) #define TTL_7448(name, cA0, cA1, cA2, cA3, cLTQ, cBIQ, cRBIQ) \ NET_REGISTER_DEV(TTL_7448, name) \ NET_CONNECT(name, VCC, VCC) \ diff --git a/src/lib/netlist/macro/nlm_ttl74xx.cpp b/src/lib/netlist/macro/nlm_ttl74xx.cpp index 37c010607c9..e30800abdf2 100644 --- a/src/lib/netlist/macro/nlm_ttl74xx.cpp +++ b/src/lib/netlist/macro/nlm_ttl74xx.cpp @@ -604,7 +604,7 @@ static NETLIST_START(TTL_7486_DIP) ) NETLIST_END() -#if (USE_TRUTHTABLE_74107) +#if (NL_USE_TRUTHTABLE_74107) #ifndef __PLIB_PREPROCESSOR__ #define TTL_74107_TT(name) \ NET_REGISTER_DEV(TTL_74107, name) @@ -846,7 +846,7 @@ static NETLIST_START(DM9312_DIP) ) NETLIST_END() -#if (USE_TRUTHTABLE_7448) +#if (NL_USE_TRUTHTABLE_7448) /* * DM7448: BCD to 7-Segment decoders/drivers @@ -1115,7 +1115,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() -#if (USE_TRUTHTABLE_7448) +#if (NL_USE_TRUTHTABLE_7448) TRUTHTABLE_START(TTL_7448, 7, 7, "+A,+B,+C,+D,+LTQ,+BIQ,+RBIQ,@VCC,@GND") TT_HEAD(" LTQ,BIQ,RBIQ, A , B , C , D | a, b, c, d, e, f, g") @@ -1207,7 +1207,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() -#if (USE_TRUTHTABLE_74107) +#if (NL_USE_TRUTHTABLE_74107) /* * +-----+-----+-----+---++---+-----+ * | CLRQ| CLK | J | K || Q | QQ | @@ -1379,11 +1379,11 @@ NETLIST_START(TTL74XX_lib) LOCAL_LIB_ENTRY(TTL_7430_DIP) LOCAL_LIB_ENTRY(TTL_7432_DIP) LOCAL_LIB_ENTRY(TTL_7437_DIP) -#if (USE_TRUTHTABLE_7448) +#if (NL_USE_TRUTHTABLE_7448) LOCAL_LIB_ENTRY(TTL_7448_DIP) #endif LOCAL_LIB_ENTRY(TTL_7486_DIP) -#if (USE_TRUTHTABLE_74107) +#if (NL_USE_TRUTHTABLE_74107) LOCAL_LIB_ENTRY(TTL_74107_DIP) #endif LOCAL_LIB_ENTRY(TTL_74155_DIP) diff --git a/src/lib/netlist/macro/nlm_ttl74xx.h b/src/lib/netlist/macro/nlm_ttl74xx.h index 4c9e8c4d553..e612ac2b601 100644 --- a/src/lib/netlist/macro/nlm_ttl74xx.h +++ b/src/lib/netlist/macro/nlm_ttl74xx.h @@ -209,7 +209,7 @@ NET_REGISTER_DEV(TTL_7437_DIP, name) -#if (USE_TRUTHTABLE_7448) +#if (NL_USE_TRUTHTABLE_7448) #define TTL_7448(name, cA0, cA1, cA2, cA3, cLTQ, cBIQ, cRBIQ) \ NET_REGISTER_DEV(TTL_7448, name) \ NET_CONNECT(name, VCC, VCC) \ @@ -240,7 +240,7 @@ #define TTL_7486_DIP(name) \ NET_REGISTER_DEV(TTL_7486_DIP, name) -#if (USE_TRUTHTABLE_74107) +#if (NL_USE_TRUTHTABLE_74107) #define TTL_74107(name, cCLK, cJ, cK, cCLRQ) \ NET_REGISTER_DEV(TTL_74107, name) \ NET_CONNECT(name, GND, GND) \ diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 39cdd685608..d69f61df2db 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -254,23 +254,46 @@ namespace netlist void netlist_state_t::compile_defines(std::vector<std::pair<pstring, pstring>> &defs) { - //#define ENTRY(x) { #x, PSTRINGIFY(x) } - #define ENTRY(x) std::pair<pstring, pstring>(#x, PSTRINGIFY(x)) - defs.emplace_back(ENTRY(PHAS_RDTSCP)); - defs.emplace_back(ENTRY(PUSE_ACCURATE_STATS)); - defs.emplace_back(ENTRY(PHAS_INT128)); - defs.emplace_back(ENTRY(USE_ALIGNED_OPTIMIZATIONS)); - defs.emplace_back(ENTRY(NVCCBUILD)); - defs.emplace_back(ENTRY(USE_MEMPOOL)); - defs.emplace_back(ENTRY(USE_QUEUE_STATS)); - defs.emplace_back(ENTRY(USE_COPY_INSTEAD_OF_REFERENCE)); - defs.emplace_back(ENTRY(USE_TRUTHTABLE_7448)); - defs.emplace_back(ENTRY(NL_DEBUG)); - defs.emplace_back(ENTRY(HAS_OPENMP)); - defs.emplace_back(ENTRY(USE_OPENMP)); - - defs.emplace_back(ENTRY(PPMF_TYPE)); - defs.emplace_back(ENTRY(PHAS_PMF_INTERNAL)); + #define ENTRY(x) if (pstring(#x) != PSTRINGIFY(x)) defs.emplace_back(std::pair<pstring, pstring>(#x, PSTRINGIFY(x))); + ENTRY(PHAS_RDTSCP) + ENTRY(PUSE_ACCURATE_STATS) + ENTRY(PHAS_INT128) + ENTRY(PUSE_ALIGNED_OPTIMIZATIONS) + ENTRY(PHAS_OPENMP) + ENTRY(PUSE_OPENMP) + ENTRY(PPMF_TYPE) + ENTRY(PHAS_PMF_INTERNAL) + ENTRY(NL_USE_MEMPOOL) + ENTRY(NL_USE_QUEUE_STATS) + ENTRY(NL_USE_COPY_INSTEAD_OF_REFERENCE) + ENTRY(NL_USE_TRUTHTABLE_7448) + ENTRY(NL_AUTO_DEVICES) + ENTRY(NL_DEBUG) + ENTRY(NVCCBUILD) + + ENTRY(__cplusplus) + ENTRY(__VERSION__) + + ENTRY(__GNUC__) + ENTRY(__GNUC_MINOR__) + ENTRY(__GNUC_PATCHLEVEL__) + + ENTRY(__clang__) + ENTRY(__clang_major__) + ENTRY(__clang_minor__) + ENTRY(__clang_patchlevel__) + ENTRY(__clang_version__) + + ENTRY(OPENMP ) + ENTRY(_OPENMP ) + + ENTRY(__x86_64__ ) + ENTRY(__i386__) + ENTRY(_WIN32) + ENTRY(_MSC_VER) + ENTRY(__APPLE__) + ENTRY(__unix__) + ENTRY(__linux__) #undef ENTRY } @@ -417,7 +440,7 @@ namespace netlist log().verbose("Total time {1:15}", total_time); // FIXME: clang complains about unreachable code without - const auto clang_workaround_unreachable_code = USE_QUEUE_STATS; + const auto clang_workaround_unreachable_code = NL_USE_QUEUE_STATS; if (clang_workaround_unreachable_code) { /* Only one serialization should be counted in total time */ @@ -717,7 +740,7 @@ namespace netlist : device_object_t(dev, dev.name() + "." + aname) , plib::linkedlist_t<core_terminal_t>::element_t() , m_delegate(delegate) - #if USE_COPY_INSTEAD_OF_REFERENCE + #if NL_USE_COPY_INSTEAD_OF_REFERENCE , m_Q(*this, "m_Q", 0) #endif , m_net(nullptr) diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 9518705c2c6..f732c7cd1e2 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -589,7 +589,7 @@ namespace netlist void reset() noexcept { set_state(is_type(OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); } nldelegate m_delegate; - #if USE_COPY_INSTEAD_OF_REFERENCE + #if NL_USE_COPY_INSTEAD_OF_REFERENCE void set_copied_input(netlist_sig_t val) noexcept { m_Q = val; @@ -667,7 +667,7 @@ namespace netlist void move_connections(net_t &dest_net); std::vector<core_terminal_t *> &core_terms() { return m_core_terms; } - #if USE_COPY_INSTEAD_OF_REFERENCE + #if NL_USE_COPY_INSTEAD_OF_REFERENCE void update_inputs() noexcept { for (auto & term : m_core_terms) @@ -1553,7 +1553,7 @@ namespace netlist void process_queue(netlist_time delta) NL_NOEXCEPT; void abort_current_queue_slice() NL_NOEXCEPT { - if (!USE_QUEUE_STATS || !m_use_stats) + if (!NL_USE_QUEUE_STATS || !m_use_stats) m_queue.retime<false>(detail::queue_t::entry_t(m_time, nullptr)); else m_queue.retime<true>(detail::queue_t::entry_t(m_time, nullptr)); @@ -1564,7 +1564,7 @@ namespace netlist template <typename E> void qpush(E && e) noexcept { - if (!USE_QUEUE_STATS || !m_use_stats) + if (!NL_USE_QUEUE_STATS || !m_use_stats) m_queue.push<false>(std::forward<E>(e)); // NOLINT(performance-move-const-arg) else m_queue.push<true>(std::forward<E>(e)); // NOLINT(performance-move-const-arg) @@ -1573,7 +1573,7 @@ namespace netlist template <class R> void qremove(const R &elem) noexcept { - if (!USE_QUEUE_STATS || !m_use_stats) + if (!NL_USE_QUEUE_STATS || !m_use_stats) m_queue.remove<false>(elem); else m_queue.remove<true>(elem); @@ -1860,7 +1860,7 @@ namespace netlist nl_assert(terminal_state() != STATE_INP_PASSIVE); //if (net().Q() != m_Q) // printf("term: %s, %d %d TS %d\n", this->name().c_str(), net().Q(), m_Q, terminal_state()); -#if USE_COPY_INSTEAD_OF_REFERENCE +#if NL_USE_COPY_INSTEAD_OF_REFERENCE return m_Q; #else return net().Q(); diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index 71a0e6c028c..ae3d73a08b7 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -28,8 +28,8 @@ * Your mileage may vary. * */ -#ifndef USE_MEMPOOL -#define USE_MEMPOOL (1) +#ifndef NL_USE_MEMPOOL +#define NL_USE_MEMPOOL (1) #endif /*! Enable queue statistics. @@ -39,8 +39,8 @@ * only needed during development. * */ -#ifndef USE_QUEUE_STATS -#define USE_QUEUE_STATS (0) +#ifndef NL_USE_QUEUE_STATS +#define NL_USE_QUEUE_STATS (0) #endif /*! Store input values in logic_terminal_t. @@ -53,8 +53,8 @@ * the default approach. It is up to 10% slower. * */ -#ifndef USE_COPY_INSTEAD_OF_REFERENCE -#define USE_COPY_INSTEAD_OF_REFERENCE (0) +#ifndef NL_USE_COPY_INSTEAD_OF_REFERENCE +#define NL_USE_COPY_INSTEAD_OF_REFERENCE (0) #endif /* @@ -63,7 +63,9 @@ * setting param USE_DEACTIVATE for the device. */ -#define USE_TRUTHTABLE_7448 (0) +#ifndef NL_USE_TRUTHTABLE_7448 +#define NL_USE_TRUTHTABLE_7448 (0) +#endif /* * FIXME: The truthtable implementation of 74107 (JK-Flipflop) @@ -72,7 +74,9 @@ * It will completely nuke performance for pong. */ -#define USE_TRUTHTABLE_74107 (0) +#ifndef NL_USE_TRUTHTABLE_74107 +#define NL_USE_TRUTHTABLE_74107 (0) +#endif //============================================================ // DEBUGGING diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index e0a696c226a..597962bea3b 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -87,12 +87,21 @@ namespace netlist void nlparse_t::include(const pstring &netlist_name) { - for (auto &source : m_sources) +#if 0 + for (auto &base : m_sources) { - if (source->parse(*this, netlist_name)) + auto source(dynamic_cast<source_netlist_t *>(base.get())); + if (source && source->parse(*this, netlist_name)) return; } log().fatal(MF_NOT_FOUND_IN_SOURCE_COLLECTION(netlist_name)); +#endif + if (m_sources.for_all<source_netlist_t>(netlist_name, [this, &netlist_name] (auto &src) + { + return src->parse(*this, netlist_name); + })) + return; + log().fatal(MF_NOT_FOUND_IN_SOURCE_COLLECTION(netlist_name)); } @@ -206,9 +215,9 @@ namespace netlist return false; } - bool nlparse_t::parse_stream(plib::unique_ptr<std::istream> &&istrm, const pstring &name) + bool nlparse_t::parse_stream(plib::psource_t::stream_ptr &&istrm, const pstring &name) { - plib::ppreprocessor y(&m_defines); + plib::ppreprocessor y(m_includes, &m_defines); plib::ppreprocessor &x(y.process(std::move(istrm))); return parser_t(std::move(x), *this).parse(name); //return parser_t(std::move(plib::ppreprocessor(&m_defines).process(std::move(istrm))), *this).parse(name); @@ -239,12 +248,6 @@ setup_t::setup_t(netlist_state_t &nlstate) setup_t::~setup_t() noexcept { - // FIXME: can't see a need any longer - m_links.clear(); - m_params.clear(); - m_terminals.clear(); - m_param_values.clear(); - m_sources.clear(); } pstring setup_t::termtype_as_str(detail::core_terminal_t &in) const @@ -1019,19 +1022,13 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model) // Sources // ---------------------------------------------------------------------------------------- -plib::unique_ptr<std::istream> setup_t::get_data_stream(const pstring &name) +plib::psource_t::stream_ptr setup_t::get_data_stream(const pstring &name) { - for (auto &source : m_sources) - { - if (source->type() == source_t::DATA) - { - auto strm = source->stream(name); - if (strm) - return strm; - } - } + auto strm = m_sources.get_stream<source_data_t>(name); + if (strm) + return strm; log().warning(MW_DATA_1_NOT_FOUND(name)); - return plib::unique_ptr<std::istream>(nullptr); + return plib::psource_t::stream_ptr(nullptr); } @@ -1185,21 +1182,16 @@ void setup_t::prepare_to_run() // base sources // ---------------------------------------------------------------------------------------- -bool source_t::parse(nlparse_t &setup, const pstring &name) +bool source_netlist_t::parse(nlparse_t &setup, const pstring &name) { - if (m_type != SOURCE) - return false; + auto strm(stream(name)); + if (strm) + return setup.parse_stream(std::move(strm), name); else - { - auto strm(stream(name)); - if (strm) - return setup.parse_stream(std::move(strm), name); - else - return false; - } + return false; } -plib::unique_ptr<std::istream> source_string_t::stream(const pstring &name) +source_string_t::stream_ptr source_string_t::stream(const pstring &name) { plib::unused_var(name); auto ret(plib::make_unique<std::istringstream>(m_str)); @@ -1207,7 +1199,7 @@ plib::unique_ptr<std::istream> source_string_t::stream(const pstring &name) return std::move(ret); } -plib::unique_ptr<std::istream> source_mem_t::stream(const pstring &name) +source_mem_t::stream_ptr source_mem_t::stream(const pstring &name) { plib::unused_var(name); auto ret(plib::make_unique<std::istringstream>(m_str, std::ios_base::binary)); @@ -1215,14 +1207,14 @@ plib::unique_ptr<std::istream> source_mem_t::stream(const pstring &name) return std::move(ret); } -plib::unique_ptr<std::istream> source_file_t::stream(const pstring &name) +source_file_t::stream_ptr source_file_t::stream(const pstring &name) { plib::unused_var(name); auto ret(plib::make_unique<std::ifstream>(plib::filesystem::u8path(m_filename))); if (ret->is_open()) return std::move(ret); else - return plib::unique_ptr<std::istream>(nullptr); + return stream_ptr(nullptr); } bool source_proc_t::parse(nlparse_t &setup, const pstring &name) @@ -1236,10 +1228,10 @@ bool source_proc_t::parse(nlparse_t &setup, const pstring &name) return false; } -plib::unique_ptr<std::istream> source_proc_t::stream(const pstring &name) +source_proc_t::stream_ptr source_proc_t::stream(const pstring &name) { plib::unused_var(name); - plib::unique_ptr<std::istream> p(nullptr); + stream_ptr p(nullptr); return p; } diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 977732623b9..81779d86b85 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -79,7 +79,7 @@ void NETLIST_NAME(name)(netlist::nlparse_t &setup) \ #define SUBMODEL(model, name) \ setup.namespace_push(# name); \ - setup.include(# model); \ + setup.include(# model); \ /*NETLIST_NAME(model)(setup);*/ \ setup.namespace_pop(); @@ -167,42 +167,38 @@ namespace netlist }; // ---------------------------------------------------------------------------------------- - // A Generic netlist sources implementation + // Specific netlist psource_t implementations // ---------------------------------------------------------------------------------------- - class source_t + class source_netlist_t : public plib::psource_t { public: friend class setup_t; - enum type_t - { - SOURCE, - DATA - }; - - using list_t = std::vector<plib::unique_ptr<source_t>>; - - source_t(const type_t type = SOURCE) - : m_type(type) + source_netlist_t() + : plib::psource_t() {} - COPYASSIGNMOVE(source_t, delete) - - virtual ~source_t() noexcept = default; + COPYASSIGNMOVE(source_netlist_t, delete) + virtual ~source_netlist_t() noexcept = default; virtual bool parse(nlparse_t &setup, const pstring &name); + }; - type_t type() const { return m_type; } + class source_data_t : public plib::psource_t + { + public: - protected: - virtual plib::unique_ptr<std::istream> stream(const pstring &name) = 0; + friend class setup_t; - private: - const type_t m_type; - }; + source_data_t() + : plib::psource_t() + {} + COPYASSIGNMOVE(source_data_t, delete) + virtual ~source_data_t() noexcept = default; + }; // ---------------------------------------------------------------------------------------- // Collection of models @@ -253,9 +249,9 @@ namespace netlist void register_frontier(const pstring &attach, const double r_IN, const double r_OUT); /* register a source */ - void register_source(plib::unique_ptr<source_t> &&src) + void register_source(plib::unique_ptr<plib::psource_t> &&src) { - m_sources.push_back(std::move(src)); + m_sources.add_source(std::move(src)); } void tt_factory_create(tt_desc &desc, const pstring &sourcefile); @@ -279,7 +275,12 @@ namespace netlist bool device_exists(const pstring &name) const; /* FIXME: used by source_t - need a different approach at some time */ - bool parse_stream(plib::unique_ptr<std::istream> &&istrm, const pstring &name); + bool parse_stream(plib::psource_t::stream_ptr &&istrm, const pstring &name); + + void add_include(plib::unique_ptr<plib::psource_t> &&inc) + { + m_includes.add_source(std::move(inc)); + } void add_define(const pstring &def, const pstring &val) { @@ -314,7 +315,7 @@ namespace netlist std::vector<link_t> m_links; std::unordered_map<pstring, pstring> m_param_values; - source_t::list_t m_sources; + plib::psource_collection_t<> m_sources; factory::list_t m_factory; @@ -324,6 +325,7 @@ namespace netlist private: plib::ppreprocessor::defines_map_type m_defines; + plib::psource_collection_t<> m_includes; setup_t &m_setup; log_type &m_log; @@ -364,7 +366,7 @@ namespace netlist void register_dynamic_log_devices(); void resolve_inputs(); - plib::unique_ptr<std::istream> get_data_stream(const pstring &name); + plib::psource_t::stream_ptr get_data_stream(const pstring &name); factory::list_t &factory() { return m_factory; } const factory::list_t &factory() const { return m_factory; } @@ -432,58 +434,58 @@ namespace netlist // base sources // ---------------------------------------------------------------------------------------- - class source_string_t : public source_t + class source_string_t : public source_netlist_t { public: source_string_t(const pstring &source) - : source_t(), m_str(source) + : source_netlist_t(), m_str(source) { } protected: - plib::unique_ptr<std::istream> stream(const pstring &name) override; + stream_ptr stream(const pstring &name) override; private: pstring m_str; }; - class source_file_t : public source_t + class source_file_t : public source_netlist_t { public: source_file_t(const pstring &filename) - : source_t(), m_filename(filename) + : source_netlist_t(), m_filename(filename) { } protected: - plib::unique_ptr<std::istream> stream(const pstring &name) override; + stream_ptr stream(const pstring &name) override; private: pstring m_filename; }; - class source_mem_t : public source_t + class source_mem_t : public source_netlist_t { public: source_mem_t(const char *mem) - : source_t(), m_str(mem) + : source_netlist_t(), m_str(mem) { } protected: - plib::unique_ptr<std::istream> stream(const pstring &name) override; + stream_ptr stream(const pstring &name) override; private: pstring m_str; }; - class source_proc_t : public source_t + class source_proc_t : public source_netlist_t { public: source_proc_t(const pstring &name, void (*setup_func)(nlparse_t &)) - : source_t(), + : source_netlist_t(), m_setup_func(setup_func), m_setup_func_name(name) { @@ -492,7 +494,7 @@ namespace netlist bool parse(nlparse_t &setup, const pstring &name) override; protected: - plib::unique_ptr<std::istream> stream(const pstring &name) override; + stream_ptr stream(const pstring &name) override; private: void (*m_setup_func)(nlparse_t &); diff --git a/src/lib/netlist/nltypes.h b/src/lib/netlist/nltypes.h index 453b0bb4adf..75470ca2ebf 100644 --- a/src/lib/netlist/nltypes.h +++ b/src/lib/netlist/nltypes.h @@ -78,7 +78,7 @@ namespace netlist * */ -#if (USE_MEMPOOL) +#if (NL_USE_MEMPOOL) using nlmempool = plib::mempool; #else using nlmempool = plib::aligned_arena; diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index 5b7d2f59c2d..aa1aac5544d 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -276,7 +276,7 @@ namespace plib { static inline void *allocate( size_t alignment, size_t size ) { - #if (USE_ALIGNED_ALLOCATION) + #if (PUSE_ALIGNED_ALLOCATION) #if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER) return _aligned_malloc(size, alignment); #elif defined(__APPLE__) @@ -296,7 +296,7 @@ namespace plib { static inline void deallocate( void *ptr ) { - #if (USE_ALIGNED_ALLOCATION) + #if (PUSE_ALIGNED_ALLOCATION) // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) free(ptr); #else @@ -352,7 +352,7 @@ namespace plib { //auto t = reinterpret_cast<std::uintptr_t>(p); //if (t & (ALIGN-1)) // printf("alignment error!"); -#if (USE_ALIGNED_HINTS) +#if (PUSE_ALIGNED_HINTS) return reinterpret_cast<T *>(__builtin_assume_aligned(p, ALIGN)); #else return p; @@ -364,7 +364,7 @@ namespace plib { { static_assert(ALIGN >= alignof(T), "Alignment must be greater or equal to alignof(T)"); static_assert(is_pow2(ALIGN), "Alignment must be a power of 2"); -#if (USE_ALIGNED_HINTS) +#if (PUSE_ALIGNED_HINTS) return reinterpret_cast<const T *>(__builtin_assume_aligned(p, ALIGN)); #else return p; diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index 3e20170a752..102a991e613 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -38,20 +38,20 @@ * netlists like kidniki. */ -#ifndef USE_OPENMP -#define USE_OPENMP (0) +#ifndef PUSE_OPENMP +#define PUSE_OPENMP (0) #endif /* * Set this to one if you want to use aligned storage optimizations. */ -#ifndef USE_ALIGNED_OPTIMIZATIONS -#define USE_ALIGNED_OPTIMIZATIONS (0) +#ifndef PUSE_ALIGNED_OPTIMIZATIONS +#define PUSE_ALIGNED_OPTIMIZATIONS (0) #endif -#define USE_ALIGNED_ALLOCATION (USE_ALIGNED_OPTIMIZATIONS) -#define USE_ALIGNED_HINTS (USE_ALIGNED_OPTIMIZATIONS) +#define PUSE_ALIGNED_ALLOCATION (PUSE_ALIGNED_OPTIMIZATIONS) +#define PUSE_ALIGNED_HINTS (PUSE_ALIGNED_OPTIMIZATIONS) /* * Standard alignment macros */ @@ -114,11 +114,19 @@ typedef __int128_t INT128; //============================================================ #if defined(OPENMP) -#define HAS_OPENMP ( OPENMP >= 200805 ) +#if ( OPENMP >= 200805 ) +#define PHAS_OPENMP (1) +#else +#define PHAS_OPENMP (0) +#endif #elif defined(_OPENMP) -#define HAS_OPENMP ( _OPENMP >= 200805 ) +#if ( _OPENMP >= 200805 ) +#define PHAS_OPENMP (1) +#else +#define PHAS_OPENMP (0) +#endif #else -#define HAS_OPENMP (0) +#define PHAS_OPENMP (0) #endif @@ -126,8 +134,8 @@ typedef __int128_t INT128; // WARNINGS //============================================================ -#if (USE_OPENMP) -#if (!(HAS_OPENMP)) +#if (PUSE_OPENMP) +#if (!(PHAS_OPENMP)) #error To use openmp compile and link with "-fopenmp" #endif #endif diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp index ca7ec88e2e3..250ead34cb3 100644 --- a/src/lib/netlist/plib/pfmtlog.cpp +++ b/src/lib/netlist/plib/pfmtlog.cpp @@ -112,10 +112,10 @@ pfmt::rtype pfmt::setfmt(std::stringstream &strm, char32_t cfmt_spec) else if (pdot != pstring::npos) { strm << std::setprecision(pstonum<int>(fmt.substr(pdot + 1))); - r.width = pstonum<pstring::size_type>(left(fmt,pdot)); + r.width = pstonum<int>(left(fmt,pdot)); } else if (fmt != "") - r.width = pstonum<pstring::size_type>(fmt); + r.width = pstonum<int>(fmt); switch (r.pend) { diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h index 531b76fafe7..7bf10173857 100644 --- a/src/lib/netlist/plib/pfmtlog.h +++ b/src/lib/netlist/plib/pfmtlog.h @@ -227,7 +227,7 @@ protected: pstring::size_type p; pstring::size_type sl; char32_t pend; - pstring::size_type width; + int width; }; rtype setfmt(std::stringstream &strm, char32_t cfmt_spec); @@ -248,10 +248,14 @@ protected: strm << std::forward<T>(val); const pstring ps(strm.str()); pstring pad(""); - if (ret.width > ps.length()) - pad = pstring(ret.width - ps.length(), ' '); - - m_str = m_str.substr(0, ret.p) + pad + ps + m_str.substr(ret.p + ret.sl); + std::size_t aw(std::abs(ret.width)); + if (aw > ps.length()) + pad = pstring(aw - ps.length(), ' '); + + if (ret.width > 0) + m_str = m_str.substr(0, ret.p) + pad + ps + m_str.substr(ret.p + ret.sl); + else + m_str = m_str.substr(0, ret.p) + ps + pad + m_str.substr(ret.p + ret.sl); } } while (ret.ret == 1); diff --git a/src/lib/netlist/plib/pomp.h b/src/lib/netlist/plib/pomp.h index 400fbee9e64..79fa0f4bf9b 100644 --- a/src/lib/netlist/plib/pomp.h +++ b/src/lib/netlist/plib/pomp.h @@ -14,7 +14,7 @@ #include <cstdint> -#if HAS_OPENMP +#if PHAS_OPENMP #include "omp.h" #endif @@ -26,7 +26,7 @@ void for_static(std::size_t numops, const I start, const I end, const T &what) { if (numops>1000) { - #if HAS_OPENMP && USE_OPENMP + #if PHAS_OPENMP && PUSE_OPENMP #pragma omp parallel for schedule(static) #endif for (I i = start; i < end; i++) @@ -40,7 +40,7 @@ void for_static(std::size_t numops, const I start, const I end, const T &what) template <typename I, class T> void for_static(const I start, const I end, const T &what) { -#if HAS_OPENMP && USE_OPENMP +#if PHAS_OPENMP && PUSE_OPENMP #pragma omp parallel for schedule(static) #endif for (I i = start; i < end; i++) @@ -57,7 +57,7 @@ void for_static_np(const I start, const I end, const T &what) inline void set_num_threads(const std::size_t threads) { -#if HAS_OPENMP && USE_OPENMP +#if PHAS_OPENMP && PUSE_OPENMP omp_set_num_threads(threads); #else plib::unused_var(threads); @@ -66,7 +66,7 @@ inline void set_num_threads(const std::size_t threads) inline std::size_t get_max_threads() { -#if HAS_OPENMP && USE_OPENMP +#if PHAS_OPENMP && PUSE_OPENMP return omp_get_max_threads(); #else return 1; diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp index 74d0b137829..11da93486a4 100644 --- a/src/lib/netlist/plib/pparser.cpp +++ b/src/lib/netlist/plib/pparser.cpp @@ -149,6 +149,23 @@ ptokenizer::token_t ptokenizer::get_token() if (ret.is_type(ENDOFFILE)) return ret; + if (m_support_line_markers && ret.is_type(LINEMARKER)) + { + // FIXME: do something with information gathered + ret = get_token_internal(); + if (!ret.is_type(NUMBER)) + error(pfmt("Expected line number after line marker but got <{1}>")(ret.str()) ); + ret = get_token_internal(); + if (!ret.is_type(STRING)) + error(pfmt("Expected file name after line marker but got <{1}>")(ret.str()) ); + ret = get_token_internal(); + while (ret.is_type(NUMBER)) + { + // FIXME: process flags; actually only 1 (file enter) and 2 (after file exit) + ret = get_token_internal(); + } + } + if (ret.is(m_tok_comment_start)) { do { @@ -184,7 +201,9 @@ ptokenizer::token_t ptokenizer::get_token_internal() return token_t(ENDOFFILE); } } - if (m_number_chars_start.find(c) != pstring::npos) + if (m_support_line_markers && c == '#') + return token_t(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 @@ -259,11 +278,11 @@ ptokenizer::token_t ptokenizer::get_token_internal() // A simple preprocessor // ---------------------------------------------------------------------------------------- -ppreprocessor::ppreprocessor(defines_map_type *defines) +ppreprocessor::ppreprocessor(psource_collection_t<> &sources, defines_map_type *defines) : std::istream(new readbuffer(this)) +, m_sources(sources) , m_if_flag(0) , m_if_level(0) -, m_lineno(0) , m_pos(0) , m_state(PROCESS) , m_comment(false) @@ -289,7 +308,20 @@ ppreprocessor::ppreprocessor(defines_map_type *defines) void ppreprocessor::error(const pstring &err) { - throw pexception("PREPRO ERROR: " + err); + pstring s(""); + pstring trail (" from "); + pstring trail_first("In file included from "); + pstring e = plib::pfmt("PREPRO ERROR: {1}:{2}:0: error: {3}\n") + (m_stack.top().m_name, m_stack.top().m_lineno, err); + m_stack.pop(); + while (m_stack.size() > 0) + { + if (m_stack.size() == 1) + trail = trail_first; + s = trail + plib::pfmt("{1}:{2}:0\n")(m_stack.top().m_name, m_stack.top().m_lineno) + s; + m_stack.pop(); + } + throw pexception("\n" + s + e); } #define CHECKTOK2(p_op, p_prio) \ @@ -504,7 +536,38 @@ pstring ppreprocessor::process_line(pstring line) } else if (lti[0] == "#include") { - // ignore + if (m_if_flag == 0) + { + pstring arg(""); + for (std::size_t i=1; i<lti.size(); i++) + arg += (lti[i] + " "); + + arg = plib::trim(arg); + + if (startsWith(arg, "\"") && endsWith(arg, "\"")) + { + arg = arg.substr(1, arg.length() - 2); + /* first try local context */ + auto l(plib::util::buildpath({m_stack.top().m_local_path, arg})); + auto lstrm(m_sources.get_stream<>(l)); + if (lstrm) + { + m_stack.emplace(input_context(std::move(lstrm), plib::util::path(l), l)); + } + else + { + auto strm(m_sources.get_stream<>(arg)); + if (strm) + { + m_stack.emplace(input_context(std::move(strm), plib::util::path(arg), arg)); + } + else + error("include not found:" + arg); + } + } + else + error("include misspelled:" + arg); + } } else if (lti[0] == "#pragma") { @@ -519,7 +582,7 @@ pstring ppreprocessor::process_line(pstring line) if (m_if_flag == 0) { if (lti.size() < 2) - error("PREPRO: define needs at least one argument: " + line); + error("define needs at least one argument: " + line); else if (lti.size() == 2) m_defines.insert({lti[1], define_t(lti[1], "")}); else @@ -535,7 +598,7 @@ pstring ppreprocessor::process_line(pstring line) else { if (m_if_flag == 0) - error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(replace_macros(line))); + error(pfmt("unknown directive on line {1}: {2}")(m_stack.top().m_lineno)(replace_macros(line))); } } else @@ -547,6 +610,28 @@ pstring ppreprocessor::process_line(pstring line) return ret; } +void ppreprocessor::process_stack() +{ + while (m_stack.size() > 0) + { + pstring line; + pstring linemarker = pfmt("# {1} \"{2}\" 1\n")(m_stack.top().m_lineno, m_stack.top().m_name); + m_outbuf += decltype(m_outbuf)(linemarker.c_str()); + while (m_stack.top().m_reader.readline(line)) + { + m_stack.top().m_lineno++; + line = process_line(line); + m_outbuf += decltype(m_outbuf)(line.c_str()) + static_cast<char>(10); + } + m_stack.pop(); + if (m_stack.size() > 0) + { + linemarker = pfmt("# {1} \"{2}\" 2\n")(m_stack.top().m_lineno, m_stack.top().m_name); + m_outbuf += decltype(m_outbuf)(linemarker.c_str()); + } + } +} + } // namespace plib diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h index 5332ee2518c..ced7e500cad 100644 --- a/src/lib/netlist/plib/pparser.h +++ b/src/lib/netlist/plib/pparser.h @@ -12,9 +12,11 @@ #include "pstream.h" #include "pstring.h" +#include "putil.h" // psource_t + //#include <cstdint> #include <unordered_map> - +#include <stack> namespace plib { class ptokenizer @@ -28,6 +30,7 @@ public: , m_px(m_cur_line.begin()) , m_unget(0) , m_string('"') + , m_support_line_markers(true) // FIXME { } @@ -42,6 +45,7 @@ public: TOKEN, STRING, COMMENT, + LINEMARKER, UNKNOWN, ENDOFFILE }; @@ -156,6 +160,7 @@ private: token_id_t m_tok_comment_start; token_id_t m_tok_comment_end; token_id_t m_tok_line_comment; + bool m_support_line_markers; }; @@ -174,26 +179,7 @@ public: using defines_map_type = std::unordered_map<pstring, define_t>; - explicit ppreprocessor(defines_map_type *defines = nullptr); - - ~ppreprocessor() override - { - delete rdbuf(); - } - - template <typename T> - ppreprocessor & process(T &&istrm) - { - putf8_reader reader(std::forward<T>(istrm)); - pstring line; - while (reader.readline(line)) - { - m_lineno++; - line = process_line(line); - m_outbuf += decltype(m_outbuf)(line.c_str()) + static_cast<char>(10); - } - return *this; - } + explicit ppreprocessor(psource_collection_t<> &sources, defines_map_type *defines = nullptr); COPYASSIGN(ppreprocessor, delete) ppreprocessor &operator=(ppreprocessor &&src) = delete; @@ -201,10 +187,10 @@ public: ppreprocessor(ppreprocessor &&s) noexcept : std::istream(new readbuffer(this)) , m_defines(std::move(s.m_defines)) + , m_sources(s.m_sources) , m_expr_sep(std::move(s.m_expr_sep)) , m_if_flag(s.m_if_flag) , m_if_level(s.m_if_level) - , m_lineno(s.m_lineno) , m_outbuf(std::move(s.m_outbuf)) , m_pos(s.m_pos) , m_state(s.m_state) @@ -212,6 +198,19 @@ public: { } + ~ppreprocessor() override + { + delete rdbuf(); + } + + template <typename T> + ppreprocessor & process(T &&istrm) + { + m_stack.emplace(input_context(std::forward<T>(istrm),"","<stream>")); + process_stack(); + return *this; + } + protected: class readbuffer : public std::streambuf @@ -242,6 +241,7 @@ protected: ? std::char_traits<char>::eof() : std::char_traits<char>::to_int_type(*this->gptr()); } + private: ppreprocessor *m_strm; std::array<char_type, 1024> m_buf; @@ -261,20 +261,41 @@ private: LINE_CONTINUATION }; + void process_stack(); + pstring process_line(pstring line); pstring process_comments(pstring line); defines_map_type m_defines; + psource_collection_t<> &m_sources; std::vector<pstring> m_expr_sep; std::uint_least64_t m_if_flag; // 31 if levels int m_if_level; - int m_lineno; + + struct input_context + { + template <typename T> + input_context(T &&istrm, const pstring &local_path, const pstring &name) + : m_reader(std::forward<T>(istrm)) + , m_lineno(0) + , m_local_path(local_path) + , m_name(name) + {} + + putf8_reader m_reader; + int m_lineno; + pstring m_local_path; + pstring m_name; + }; + + std::stack<input_context> m_stack; pstring_t<pu8_traits> m_outbuf; std::istream::pos_type m_pos; state_e m_state; pstring m_line; bool m_comment; + }; } // namespace plib diff --git a/src/lib/netlist/plib/pstrutil.h b/src/lib/netlist/plib/pstrutil.h index 94ecccca09e..d3e62d06af7 100644 --- a/src/lib/netlist/plib/pstrutil.h +++ b/src/lib/netlist/plib/pstrutil.h @@ -88,6 +88,28 @@ namespace plib } template<typename T> + typename T::size_type find_last_of(const T &str, const T &no) + { + typename T::size_type last_found = T::npos; + typename T::size_type pos = 0; + for (auto it = str.begin(); it != str.end(); ++it, ++pos) + { + bool f = false; + for (typename T::value_type const jt : no) + { + if (*it == jt) + { + f = true; + break; + } + } + if (f) + last_found = pos; + } + return last_found; + } + + template<typename T> T ltrim(const T &str, const T &ws = T(" \t\n\r")) { auto f = find_first_not_of(str, ws); diff --git a/src/lib/netlist/plib/putil.cpp b/src/lib/netlist/plib/putil.cpp index b4824d62738..f6eed734a3e 100644 --- a/src/lib/netlist/plib/putil.cpp +++ b/src/lib/netlist/plib/putil.cpp @@ -13,6 +13,32 @@ namespace plib { namespace util { + #ifdef _WIN32 + static constexpr const char PATH_SEP = '\\'; + #else + static constexpr const char PATH_SEP = '/'; + #endif + + pstring basename(pstring filename) + { + auto p=find_last_of(filename, pstring(1, PATH_SEP)); + if (p == pstring::npos) + return filename; + else + return filename.substr(p+1); + } + + pstring path(pstring filename) + { + auto p=find_last_of(filename, pstring(1, PATH_SEP)); + if (p == pstring::npos) + return ""; + else if (p == 0) // root case + return filename.substr(0, 1); + else + return filename.substr(0, p); + } + pstring buildpath(std::initializer_list<pstring> list ) { pstring ret = ""; @@ -21,11 +47,7 @@ namespace plib if (ret == "") ret = elem; else - #ifdef _WIN32 - ret = ret + '\\' + elem; - #else - ret += ('/' + elem); - #endif + ret += (PATH_SEP + elem); } return ret; } diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h index 5ff70d941a2..227648b172b 100644 --- a/src/lib/netlist/plib/putil.h +++ b/src/lib/netlist/plib/putil.h @@ -10,6 +10,8 @@ #include "pexception.h" #include "pstring.h" +#include "palloc.h" + #include <algorithm> #include <initializer_list> #include <iostream> @@ -24,8 +26,118 @@ namespace plib { + // ---------------------------------------------------------------------------------------- + // A Generic netlist sources implementation + // ---------------------------------------------------------------------------------------- + + class psource_t + { + public: + + using stream_ptr = plib::unique_ptr<std::istream>; + + psource_t() + {} + + COPYASSIGNMOVE(psource_t, delete) + + virtual ~psource_t() noexcept = default; + + virtual stream_ptr stream(const pstring &name) = 0; + private: + }; + + /**! Generic string source + * + * Will return the given string when name matches. + * Is used in preprocessor code to eliminate inclusion of certain files. + * + * @tparam TS base stream class. Default is psource_t + */ + template <typename TS = psource_t> + class psource_str_t : public TS + { + public: + psource_str_t(pstring name, pstring str) + : m_name(name), m_str(str) + {} + + COPYASSIGNMOVE(psource_str_t, delete) + virtual ~psource_str_t() noexcept = default; + + typename TS::stream_ptr stream(const pstring &name) override + { + if (name == m_name) + return plib::make_unique<std::stringstream>(m_str); + else + return typename TS::stream_ptr(nullptr); + } + private: + pstring m_name; + pstring m_str; + }; + + /**! Generic sources collection + * + * @tparam TS base stream class. Default is psource_t + */ + template <typename TS = psource_t> + class psource_collection_t + { + public: + using source_type = plib::unique_ptr<TS>; + using list_t = std::vector<source_type>; + + psource_collection_t() + {} + + COPYASSIGNMOVE(psource_collection_t, delete) + virtual ~psource_collection_t() noexcept = default; + + void add_source(source_type &&src) + { + m_collection.push_back(std::move(src)); + } + + template <typename S = TS> + typename S::stream_ptr get_stream(pstring name) + { + for (auto &s : m_collection) + { + auto source(dynamic_cast<S *>(s.get())); + if (source) + { + auto strm = source->stream(name); + if (strm) + return strm; + } + } + return typename S::stream_ptr(nullptr); + } + + template <typename S, typename F> + bool for_all(pstring name, F lambda) + { + for (auto &s : m_collection) + { + auto source(dynamic_cast<S *>(s.get())); + if (source) + { + if (lambda(source)) + return true; + } + } + return false; + } + + private: + list_t m_collection; + }; + namespace util { + pstring basename(pstring filename); + pstring path(pstring filename); pstring buildpath(std::initializer_list<pstring> list ); pstring environment(const pstring &var, const pstring &default_val); } // namespace util diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index 11ca83c9aa5..f34c83d5382 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -31,6 +31,7 @@ public: opt_grp1(*this, "General options", "The following options apply to all commands."), opt_cmd (*this, "c", "cmd", 0, std::vector<pstring>({"run","validate","convert","listdevices","static","header","docheader"}), "run|validate|convert|listdevices|static|header|docheader"), opt_file(*this, "f", "file", "-", "file to process (default is stdin)"), + opt_includes(*this, "I", "include", "Add the directory to the list of directories to be searched for header files. This option may be specified repeatedly."), opt_defines(*this, "D", "define", "predefine value as macro, e.g. -Dname=value. If '=value' is omitted predefine it as 1. This option may be specified repeatedly."), opt_rfolders(*this, "r", "rom", "where to look for data files"), opt_verb(*this, "v", "verbose", "be verbose - this produces lots of output"), @@ -76,6 +77,7 @@ public: plib::option_group opt_grp1; plib::option_str_limit<unsigned> opt_cmd; plib::option_str opt_file; + plib::option_vec opt_includes; plib::option_vec opt_defines; plib::option_vec opt_rfolders; plib::option_bool opt_verb; @@ -140,21 +142,21 @@ NETLIST_END() CORE IMPLEMENTATION ***************************************************************************/ -class netlist_data_folder_t : public netlist::source_t +class netlist_data_folder_t : public netlist::source_data_t { public: netlist_data_folder_t(const pstring &folder) - : netlist::source_t(netlist::source_t::DATA) + : netlist::source_data_t() , m_folder(folder) { } - plib::unique_ptr<std::istream> stream(const pstring &file) override + stream_ptr stream(const pstring &file) override { pstring name = m_folder + "/" + file; auto strm(plib::make_unique<std::ifstream>(plib::filesystem::u8path(name))); if (strm->fail()) - return plib::unique_ptr<std::istream>(nullptr); + return stream_ptr(nullptr); else { strm->imbue(std::locale::classic()); @@ -198,7 +200,8 @@ public: void read_netlist(const pstring &filename, const pstring &name, const std::vector<pstring> &logs, const std::vector<pstring> &defines, - const std::vector<pstring> &roms) + const std::vector<pstring> &roms, + const std::vector<pstring> &includes) { // read the netlist ... @@ -208,6 +211,11 @@ public: for (auto & r : roms) setup().register_source(plib::make_unique<netlist_data_folder_t>(r)); + using a = plib::psource_str_t<plib::psource_t>; + setup().add_include(plib::make_unique<a>("netlist/devices/net_lib.h","")); + for (auto & i : includes) + setup().add_include(plib::make_unique<netlist_data_folder_t>(i)); + setup().register_source(plib::make_unique<netlist::source_file_t>(filename)); setup().include(name); create_dynamic_logs(logs); @@ -377,7 +385,7 @@ void tool_app_t::run() nt.read_netlist(opt_file(), opt_name(), opt_logs(), - m_options, opt_rfolders()); + m_options, opt_rfolders(), opt_includes()); nt.reset(); @@ -473,7 +481,7 @@ void tool_app_t::validate() nt.read_netlist(opt_file(), opt_name(), opt_logs(), - m_options, opt_rfolders()); + m_options, opt_rfolders(), opt_includes()); } catch (netlist::nl_exception &e) { @@ -507,7 +515,7 @@ void tool_app_t::static_compile() nt.read_netlist(opt_file(), opt_name(), opt_logs(), - m_options, opt_rfolders()); + m_options, opt_rfolders(), opt_includes()); // need to reset ... @@ -824,8 +832,6 @@ int tool_app_t::execute() if (opt_help()) { - pout(plib::pfmt("{:10.3}\n").f(20.0)); - //pout(plib::pfmt("{10.3}\n").f(20)); pout(usage()); return 0; } diff --git a/src/mame/audio/nl_cheekyms.cpp b/src/mame/audio/nl_cheekyms.cpp index 5abc5104778..1e41bedba05 100644 --- a/src/mame/audio/nl_cheekyms.cpp +++ b/src/mame/audio/nl_cheekyms.cpp @@ -1,7 +1,6 @@ // license:BSD-3-Clause // copyright-holders:Vas Crabb -#include "audio/nl_cheekyms.h" #include "netlist/devices/net_lib.h" diff --git a/src/mame/audio/nl_zac1b11142.cpp b/src/mame/audio/nl_zac1b11142.cpp index df97e21da05..631bc2d233a 100644 --- a/src/mame/audio/nl_zac1b11142.cpp +++ b/src/mame/audio/nl_zac1b11142.cpp @@ -1,10 +1,8 @@ // license:BSD-3-Clause // copyright-holders:Vas Crabb, Couriersud -#include "audio/nl_zac1b11142.h" #include "netlist/devices/net_lib.h" - #ifndef __PLIB_PREPROCESSOR__ #endif |