summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2019-10-18 17:57:55 +0200
committer couriersud <couriersud@gmx.org>2019-10-18 17:57:55 +0200
commitb09fa00cca1a9baa0327a33d865fc970f77d4db0 (patch)
tree47dd943368aa43a0c0cf4256f88e590960c1e99f /src/lib
parentad27643c07d54fc2cc3e56327fe07335e7763d52 (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
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/netlist/devices/net_lib.cpp4
-rw-r--r--src/lib/netlist/devices/nld_74107.cpp2
-rw-r--r--src/lib/netlist/devices/nld_74107.h2
-rw-r--r--src/lib/netlist/devices/nld_7448.cpp4
-rw-r--r--src/lib/netlist/devices/nld_7448.h2
-rw-r--r--src/lib/netlist/macro/nlm_ttl74xx.cpp12
-rw-r--r--src/lib/netlist/macro/nlm_ttl74xx.h4
-rw-r--r--src/lib/netlist/nl_base.cpp61
-rw-r--r--src/lib/netlist/nl_base.h12
-rw-r--r--src/lib/netlist/nl_config.h20
-rw-r--r--src/lib/netlist/nl_setup.cpp66
-rw-r--r--src/lib/netlist/nl_setup.h80
-rw-r--r--src/lib/netlist/nltypes.h2
-rw-r--r--src/lib/netlist/plib/palloc.h8
-rw-r--r--src/lib/netlist/plib/pconfig.h30
-rw-r--r--src/lib/netlist/plib/pfmtlog.cpp4
-rw-r--r--src/lib/netlist/plib/pfmtlog.h14
-rw-r--r--src/lib/netlist/plib/pomp.h10
-rw-r--r--src/lib/netlist/plib/pparser.cpp99
-rw-r--r--src/lib/netlist/plib/pparser.h67
-rw-r--r--src/lib/netlist/plib/pstrutil.h22
-rw-r--r--src/lib/netlist/plib/putil.cpp32
-rw-r--r--src/lib/netlist/plib/putil.h112
-rw-r--r--src/lib/netlist/prg/nltool.cpp26
24 files changed, 498 insertions, 197 deletions
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;
}