summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/tools')
-rw-r--r--src/lib/netlist/tools/nl_convert.cpp694
-rw-r--r--src/lib/netlist/tools/nl_convert.h168
2 files changed, 609 insertions, 253 deletions
diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp
index 3e705910bf4..2859034c166 100644
--- a/src/lib/netlist/tools/nl_convert.cpp
+++ b/src/lib/netlist/tools/nl_convert.cpp
@@ -1,24 +1,29 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
-/*
- * nl_convert.c
- *
- */
#include "plib/palloc.h"
-#include "nl_convert.h"
+#include "plib/pstonum.h"
+#include "plib/pstrutil.h"
#include "plib/putil.h"
+#include "nl_convert.h"
+
+#include <cstdio>
#include <algorithm>
-#include <cmath>
#include <unordered_map>
+#include <vector>
+
+namespace netlist::convert
+{
-/* FIXME: temporarily defined here - should be in a file */
-/* FIXME: family logic in netlist is convoluted, create
- * define a model param on core device
- */
-/* Format: external name,netlist device,model */
-static const char * s_lib_map =
+// FIXME: temporarily defined here - should be in a file
+// FIXME: family logic in netlist is convoluted, create
+// define a model param on core device
+
+// Format: external name,netlist device,model
+
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)
+static constexpr const char s_lib_map[] =
"SN74LS00D, TTL_7400_DIP, 74LSXX\n"
"SN74LS04D, TTL_7404_DIP, 74LSXX\n"
"SN74ALS08D, TTL_7408_DIP, 74ALSXX\n"
@@ -43,47 +48,57 @@ using lib_map_t = std::unordered_map<pstring, lib_map_entry>;
static lib_map_t read_lib_map(const pstring &lm)
{
- auto reader = plib::putf8_reader(std::istringstream(lm));
+ auto reader = plib::putf8_reader(std::make_unique<std::istringstream>(putf8string(lm)));
reader.stream().imbue(std::locale::classic());
lib_map_t m;
- pstring line;
- while (reader.readline(line))
+ putf8string line;
+ while (reader.read_line(line))
{
- std::vector<pstring> split(plib::psplit(line, ","));
+ std::vector<pstring> split(plib::psplit(pstring(line), ','));
m[plib::trim(split[0])] = { plib::trim(split[1]), plib::trim(split[2]) };
}
return m;
}
-/*-------------------------------------------------
- convert - convert a spice netlist
--------------------------------------------------*/
+// -------------------------------------------------
+// convert - convert a spice netlist
+// -------------------------------------------------
nl_convert_base_t::nl_convert_base_t()
: out(&m_buf)
- , m_numberchars("0123456789-+e.")
+ , m_number_chars("0123456789-+Ee.")
{
m_buf.imbue(std::locale::classic());
m_units = {
- {"T", "", 1.0e12 },
- {"G", "", 1.0e9 },
- {"MEG", "RES_M({1})", 1.0e6 },
- {"k", "RES_K({1})", 1.0e3 }, /* eagle */
- {"K", "RES_K({1})", 1.0e3 },
- {"", "{1}", 1.0e0 },
- {"M", "CAP_M({1})", 1.0e-3 },
- {"u", "CAP_U({1})", 1.0e-6 }, /* eagle */
- {"U", "CAP_U({1})", 1.0e-6 },
- {"μ", "CAP_U({1})", 1.0e-6 },
- {"µ", "CAP_U({1})", 1.0e-6 },
- {"N", "CAP_N({1})", 1.0e-9 },
- {"pF", "CAP_P({1})", 1.0e-12},
- {"P", "CAP_P({1})", 1.0e-12},
- {"F", "{1}e-15", 1.0e-15},
-
- {"MIL", "{1}", 25.4e-6}
+ {"T", "{1}e12", 1.0e12 }, // NOLINT
+ {"G", "{1}e9", 1.0e9 }, // NOLINT
+ {"MEG", "RES_M({1})", 1.0e6 }, // NOLINT
+ {"k", "RES_K({1})", 1.0e3 }, // NOLINT: eagle
+ {"K", "RES_K({1})", 1.0e3 }, // NOLINT
+ {"", "{1}", 1.0e0 }, // NOLINT
+ {"M", "{1}e-3", 1.0e-3 }, // NOLINT
+ {"u", "CAP_U({1})", 1.0e-6 }, // NOLINT: eagle
+ {"U", "CAP_U({1})", 1.0e-6 }, // NOLINT
+ {"μ", "CAP_U({1})", 1.0e-6 }, // NOLINT
+ {"N", "CAP_N({1})", 1.0e-9 }, // NOLINT
+ {"pF", "CAP_P({1})", 1.0e-12}, // NOLINT
+ {"P", "CAP_P({1})", 1.0e-12}, // NOLINT
+ {"F", "{1}e-15", 1.0e-15}, // NOLINT
+
+ {"MIL", "{1}", 25.4e-6} // NOLINT
};
+ dev_map =
+ {
+ { "VCCS", {"OP", "ON", "IP", "IN"} },
+ { "VCVS", {"OP", "ON", "IP", "IN"} },
+ { "CCCS", {"OP", "ON", "IP", "IN"} },
+ { "CCVS", {"OP", "ON", "IP", "IN"} },
+ { "VS", {"1", "2"} },
+ { "TTL_INPUT", {"Q", "VCC", "GND"} },
+ { "DIODE", {"A", "K"} },
+ { "POT", {"1", "2", "3"} },
+ };
}
nl_convert_base_t::~nl_convert_base_t()
@@ -96,15 +111,20 @@ nl_convert_base_t::~nl_convert_base_t()
void nl_convert_base_t::add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias)
{
pstring pname = devname + "." + name;
- m_pins.emplace(pname, plib::make_unique<pin_alias_t>(pname, devname + "." + alias));
+ m_pins.emplace(pname, plib::make_unique<pin_alias_t, arena>(pname, devname + "." + alias));
}
void nl_convert_base_t::add_ext_alias(const pstring &alias)
{
- m_ext_alias.push_back(alias);
+ m_ext_alias.emplace_back(alias, alias);
}
-void nl_convert_base_t::add_device(plib::unique_ptr<dev_t> dev)
+void nl_convert_base_t::add_ext_alias(const pstring &alias, const pstring &net)
+{
+ m_ext_alias.emplace_back(alias, net);
+}
+
+void nl_convert_base_t::add_device(arena::unique_ptr<dev_t> dev)
{
for (auto & d : m_devs)
if (d->name() == dev->name())
@@ -117,31 +137,35 @@ void nl_convert_base_t::add_device(plib::unique_ptr<dev_t> dev)
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, const pstring &amodel)
{
- add_device(plib::make_unique<dev_t>(atype, aname, amodel));
+ add_device(plib::make_unique<dev_t, arena>(atype, aname, amodel));
}
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, double aval)
{
- add_device(plib::make_unique<dev_t>(atype, aname, aval));
+ add_device(plib::make_unique<dev_t, arena>(atype, aname, aval));
}
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname)
{
- add_device(plib::make_unique<dev_t>(atype, aname));
+ add_device(plib::make_unique<dev_t, arena>(atype, aname));
}
void nl_convert_base_t::add_term(const pstring &netname, const pstring &termname)
{
+ // Ignore NC nets!
+ if (plib::startsWith(netname,"NC_"))
+ return;
+
net_t * net = nullptr;
auto idx = m_nets.find(netname);
if (idx != m_nets.end())
net = m_nets[netname].get();
else
{
- auto nets = plib::make_unique<net_t>(netname);
+ auto nets = plib::make_unique<net_t, arena>(netname);
net = nets.get();
m_nets.emplace(netname, std::move(nets));
}
- /* if there is a pin alias, translate ... */
+ // if there is a pin alias, translate ...
pin_alias_t *alias = m_pins[termname].get();
if (alias != nullptr)
@@ -150,19 +174,77 @@ void nl_convert_base_t::add_term(const pstring &netname, const pstring &termname
net->terminals().push_back(termname);
}
+void nl_convert_base_t::add_term(const pstring &netname, const pstring &devname, unsigned term)
+{
+ auto e = dev_map.find(get_device(devname)->type());
+ if (e == dev_map.end())
+ out("// ERROR: No terminals found for device {}\n", devname);
+ else
+ {
+ if (term >= e->second.size())
+ out("// ERROR: {} : Term {} exceeds number of terminals {}\n", netname, devname, term);
+ else
+ add_term(netname, devname + "." + e->second[term]);
+ }
+}
+
+void nl_convert_base_t::add_device_extra_s(const pstring &devname, const pstring &extra)
+{
+ auto *dev = get_device(devname);
+ if (dev == nullptr)
+ out("// ERROR: Device {} not found\n", devname);
+ else
+ {
+ dev->add_extra(extra);
+ }
+}
+
+
+
void nl_convert_base_t::dump_nl()
{
+ // do replacements
+ for (auto &r : m_replace)
+ {
+ // Get the device entry
+ auto *d = get_device(r.m_ce);
+ if (d == nullptr)
+ {
+ out("ERROR: Can not find <{}>\n", r.m_ce);
+ continue;
+ }
+
+ auto e = dev_map.find(d->type());
+ if (e == dev_map.end())
+ {
+ out("ERROR: Can not find type {}\n", d->type());
+ continue;
+ }
+ pstring term1 = r.m_ce + "." + e->second[0];
+ // scan all nets
+ for (auto &n : m_nets)
+ {
+ for (auto &t : n.second->terminals())
+ {
+ if (t == term1)
+ t = r.m_repterm;
+ }
+ }
+ add_term(r.m_net, term1);
+ }
+
for (auto & alias : m_ext_alias)
{
- net_t *net = m_nets[alias].get();
+ net_t *net = m_nets[alias.second].get();
// use the first terminal ...
- out("ALIAS({}, {})\n", alias.c_str(), net->terminals()[0].c_str());
+ out("ALIAS({}, {})\n", alias.first, net->terminals()[0]);
// if the aliased net only has this one terminal connected ==> don't dump
if (net->terminals().size() == 1)
net->set_no_export();
}
std::vector<size_t> sorted;
+ sorted.reserve(m_devs.size());
for (size_t i=0; i < m_devs.size(); i++)
sorted.push_back(i);
std::sort(sorted.begin(), sorted.end(),
@@ -173,48 +255,63 @@ void nl_convert_base_t::dump_nl()
std::size_t j = sorted[i];
if (m_devs[j]->has_value())
- out("{}({}, {})\n", m_devs[j]->type().c_str(),
- m_devs[j]->name().c_str(), get_nl_val(m_devs[j]->value()).c_str());
+ {
+ pstring t = m_devs[j]->type();
+ pstring vals = (t == "RES" || t == "CAP") ? get_nl_val(m_devs[j]->value()) : plib::pfmt("{1:g}")(m_devs[j]->value());
+ out("{}({}, {})\n", t, m_devs[j]->name(), vals);
+ }
else if (m_devs[j]->has_model())
- out("{}({}, \"{}\")\n", m_devs[j]->type().c_str(),
- m_devs[j]->name().c_str(), m_devs[j]->model().c_str());
+ out("{}({}, \"{}\")\n", m_devs[j]->type(),
+ m_devs[j]->name(), m_devs[j]->model());
else
- out("{}({})\n", m_devs[j]->type().c_str(),
- m_devs[j]->name().c_str());
+ out("{}({})\n", m_devs[j]->type(),
+ m_devs[j]->name());
+ for (const auto &e : m_devs[j]->extra())
+ out("{}\n", e);
+
}
// print nets
for (auto & i : m_nets)
{
net_t * net = i.second.get();
- if (!net->is_no_export())
+ if (!net->is_no_export() && !(net->terminals().size() == 1 && net->terminals()[0] == "GND" ))
{
- out("NET_C({}", net->terminals()[0].c_str() );
+ out("NET_C({}", net->terminals()[0] );
for (std::size_t j=1; j<net->terminals().size(); j++)
{
- out(", {}", net->terminals()[j].c_str() );
+ out(", {}", net->terminals()[j] );
}
out(")\n");
}
}
+ m_replace.clear();
m_devs.clear();
m_nets.clear();
m_pins.clear();
m_ext_alias.clear();
}
-const pstring nl_convert_base_t::get_nl_val(const double val)
+pstring nl_convert_base_t::get_nl_val(double val) const
{
- for (auto &e : m_units)
+ for (const auto &e : m_units)
{
- if (e.m_mult <= std::abs(val))
- return plib::pfmt(e.m_func)(val / e.m_mult);
+ if (e.m_mult <= plib::abs(val))
+ {
+ double v = val / e.m_mult;
+ if (plib::abs(v - std::round(v)) <= 1e-6)
+ return plib::pfmt(e.m_func)(static_cast<int>(std::round(v)));
+ return plib::pfmt(e.m_func)(v);
+ }
}
+
+ if (plib::abs(val - std::round(val)) <= 1e-6)
+ return plib::pfmt("{1}")(static_cast<int>(std::round(val)));
return plib::pfmt("{1}")(val);
}
-double nl_convert_base_t::get_sp_unit(const pstring &unit)
+double nl_convert_base_t::get_sp_unit(const pstring &unit) const
{
- for (auto &e : m_units)
+ for (const auto &e : m_units)
{
if (e.m_unit == unit)
return e.m_mult;
@@ -223,10 +320,10 @@ double nl_convert_base_t::get_sp_unit(const pstring &unit)
return 0.0;
}
-double nl_convert_base_t::get_sp_val(const pstring &sin)
+double nl_convert_base_t::get_sp_val(const pstring &sin) const
{
std::size_t p = 0;
- while (p < sin.length() && (m_numberchars.find(sin.substr(p, 1)) != pstring::npos))
+ while (p < sin.length() && (m_number_chars.find(sin.substr(p, 1)) != pstring::npos))
++p;
pstring val = plib::left(sin, p);
pstring unit = sin.substr(p);
@@ -234,40 +331,38 @@ double nl_convert_base_t::get_sp_val(const pstring &sin)
return ret;
}
-#if 0
-std::vector<nl_convert_base_t::unit_t> nl_convert_base_t::m_units = {
- {"T", "", 1.0e12 },
- {"G", "", 1.0e9 },
- {"MEG", "RES_M({1})", 1.0e6 },
- {"k", "RES_K({1})", 1.0e3 }, /* eagle */
- {"K", "RES_K({1})", 1.0e3 },
- {"", "{1}", 1.0e0 },
- {"M", "CAP_M({1})", 1.0e-3 },
- {"u", "CAP_U({1})", 1.0e-6 }, /* eagle */
- {"U", "CAP_U({1})", 1.0e-6 },
- {"μ", "CAP_U({1})", 1.0e-6 },
- {"µ", "CAP_U({1})", 1.0e-6 },
- {"N", "CAP_N({1})", 1.0e-9 },
- {"pF", "CAP_P({1})", 1.0e-12},
- {"P", "CAP_P({1})", 1.0e-12},
- {"F", "{1}e-15", 1.0e-15},
-
- {"MIL", "{1}", 25.4e-6}
-};
-#endif
+void nl_convert_spice_t::convert_block(const str_list &contents)
+{
+ int linenumber = 1;
+ for (const auto &line : contents)
+ {
+ try
+ {
+ process_line(line);
+ }
+ catch ([[maybe_unused]] const plib::pexception &e)
+ {
+ fprintf(stderr, "Error on line: <%d>\n", linenumber);
+ throw;
+ }
+ linenumber++;
+ }
+}
+
void nl_convert_spice_t::convert(const pstring &contents)
{
- std::vector<pstring> spnl(plib::psplit(contents, "\n"));
+ std::vector<pstring> spnl(plib::psplit(contents, '\n'));
+ std::vector<pstring> after_line_continuation;
// Add gnd net
// FIXME: Parameter
- out("NETLIST_START(dummy)\n");
- add_term("0", "GND");
pstring line = "";
+ // process line continuation
+
for (const auto &i : spnl)
{
// Basic preprocessing
@@ -276,14 +371,56 @@ void nl_convert_spice_t::convert(const pstring &contents)
line += inl.substr(1);
else
{
- process_line(line);
+ after_line_continuation.push_back(line);
line = inl;
}
}
- process_line(line);
+ after_line_continuation.push_back(line);
+ spnl.clear(); // no longer needed
+
+ // Process sub circuits
+
+ std::vector<std::vector<pstring>> subckts;
+ std::vector<pstring> nl;
+ auto inp = after_line_continuation.begin();
+ while (inp != after_line_continuation.end())
+ {
+ if (plib::startsWith(*inp, ".SUBCKT"))
+ {
+ std::vector<pstring> sub;
+ while (inp != after_line_continuation.end())
+ {
+ auto s(*inp);
+ sub.push_back(s);
+ inp++;
+ if (plib::startsWith(s, ".ENDS"))
+ break;
+ }
+ subckts.push_back(sub);
+ }
+ else
+ {
+ nl.push_back(*inp);
+ inp++;
+ }
+ }
+
+ for (const auto &sub : subckts)
+ {
+ add_term("0", "GND");
+ add_term("GND", "GND"); // For Kicad
+ convert_block(sub);
+ }
+
+ out("NETLIST_START(dummy)\n");
+ out("{\n");
+ add_term("0", "GND");
+ add_term("GND", "GND"); // For Kicad
+
+ convert_block(nl);
dump_nl();
// FIXME: Parameter
- out("NETLIST_END()\n");
+ out("}\n");
}
static pstring rem(const std::vector<pstring> &vps, std::size_t start)
@@ -294,58 +431,79 @@ static pstring rem(const std::vector<pstring> &vps, std::size_t start)
return r;
}
+static int get_poly_count(const pstring &s)
+{
+ // Brute force
+ if (s=="POLY(1)")
+ return 1;
+ if (s=="POLY(2)")
+ return 2;
+ if (s=="POLY(3)")
+ return 3;
+ if (s=="POLY(4)")
+ return 4;
+ if (s=="POLY(5)")
+ return 5;
+ return -1;
+}
+
void nl_convert_spice_t::process_line(const pstring &line)
{
- if (line != "")
+ if (!line.empty())
{
//printf("// %s\n", line.c_str());
- std::vector<pstring> tt(plib::psplit(line, " ", true));
+ std::vector<pstring> tt(plib::psplit(line, ' ', true));
double val = 0.0;
switch (tt[0].at(0))
{
case ';':
- out("// {}\n", line.substr(1));
- break;
case '*':
- out("// {}\n", line.substr(1).c_str());
+ out("// {}\n", line.substr(1));
break;
case '.':
if (tt[0] == ".SUBCKT")
{
m_subckt = tt[1] + "_";
out("NETLIST_START({})\n", tt[1]);
+ out("{\n");
for (std::size_t i=2; i<tt.size(); i++)
add_ext_alias(tt[i]);
}
else if (tt[0] == ".ENDS")
{
dump_nl();
- out("NETLIST_END()\n");
+ out("}\n");
m_subckt = "";
}
else if (tt[0] == ".MODEL")
{
- out("NET_MODEL(\"{} {}\")\n", m_subckt + tt[1], rem(tt,2));
+ pstring mod(rem(tt,2));
+ // Filter out `ngspice` X=X model declarations
+ if (tt[1] != mod)
+ out("NET_MODEL(\"{} {}\")\n", m_subckt + tt[1], mod);
+ }
+ else if (tt[0] == ".TITLE" && tt[1] == "KICAD")
+ {
+ m_is_kicad = true;
}
else
- out("// {}\n", line.c_str());
+ out("// {}\n", line);
break;
case 'Q':
{
- /* check for fourth terminal ... should be numeric net
- * including "0" or start with "N" (ltspice)
- */
+ // check for fourth terminal ... should be numeric net
+ // including "0" or start with "N" (`ltspice`)
+
pstring model;
pstring pins ="CBE";
- bool err;
- auto nval = plib::pstonum_ne<long, true>(tt[4], err);
- plib::unused_var(nval);
+ bool err(false);
+ [[maybe_unused]] auto nval = plib::pstonum_ne<long>(tt[4], err);
if ((!err || plib::startsWith(tt[4], "N")) && tt.size() > 5)
model = tt[5];
else
model = tt[4];
- std::vector<pstring> m(plib::psplit(model,"{"));
+ std::vector<pstring> m(plib::psplit(model, '{'));
if (m.size() == 2)
{
if (m[1].length() != 4)
@@ -367,6 +525,17 @@ void nl_convert_spice_t::process_line(const pstring &line)
add_term(tt[2], tt[0] + ".2");
add_term(tt[3], tt[0] + ".3");
}
+ else if (plib::startsWith(tt[0], "RA"))
+ {
+ val = get_sp_val(tt.back());
+ for (unsigned int res = 2; res < tt.size(); res++)
+ {
+ pstring devname = plib::pfmt("{}.{}")(tt[0], res);
+ add_device("RES", devname, val);
+ add_term(tt[1], devname);
+ add_term(tt[res], devname);
+ }
+ }
else
{
val = get_sp_val(tt[3]);
@@ -381,55 +550,117 @@ void nl_convert_spice_t::process_line(const pstring &line)
add_term(tt[1], tt[0] + ".1");
add_term(tt[2], tt[0] + ".2");
break;
- case 'B': // arbitrary behavioural current source - needs manual work afterwords
+ case 'B': // arbitrary behavioural current source - needs manual work afterwards
add_device("CS", tt[0], "/*" + rem(tt, 3) + "*/");
add_term(tt[1], tt[0] + ".P");
add_term(tt[2], tt[0] + ".N");
break;
case 'E':
- add_device("VCVS", tt[0]);
- add_term(tt[1], tt[0] + ".OP");
- add_term(tt[2], tt[0] + ".ON");
- add_term(tt[3], tt[0] + ".IP");
- add_term(tt[4], tt[0] + ".IN");
- out("PARAM({}, {})\n", tt[0] + ".G", tt[5]);
- break;
- case 'V':
- // just simple Voltage sources ....
- if (tt[2] == "0")
+ {
+ auto n=get_poly_count(tt[3]);
+ if (n<0)
{
- val = get_sp_val(tt[3]);
- add_device("ANALOG_INPUT", tt[0], val);
- add_term(tt[1], tt[0] + ".Q");
- //add_term(tt[2], tt[0] + ".2");
+ add_device("VCVS", tt[0], get_sp_val(tt[5]));
+ add_term(tt[1], tt[0], 0);
+ add_term(tt[2], tt[0], 1);
+ add_term(tt[3], tt[0], 2);
+ add_term(tt[4], tt[0], 3);
+ //add_device_extra(tt[0], "PARAM({}, {})", tt[0] + ".G", tt[5]);
}
else
- plib::perrlogger("Voltage Source {} not connected to GND\n", tt[0]);
+ {
+ unsigned sce(4);
+ auto scoeff(static_cast<unsigned>(5 + n));
+ if ((tt.size() != 5 + 2 * static_cast<unsigned>(n)) || (tt[scoeff-1] != "0"))
+ {
+ out("// IGNORED {}: {}\n", tt[0], line);
+ break;
+ }
+ pstring last_net = tt[1];
+ for (std::size_t i=0; i < static_cast<std::size_t>(n); i++)
+ {
+ pstring devname = plib::pfmt("{}{}")(tt[0], i);
+ pstring next_net = (i<static_cast<std::size_t>(n)-1) ? plib::pfmt("{}a{}")(tt[1], i) : tt[2];
+ auto net2 = plib::psplit(plib::replace_all(plib::replace_all(tt[sce+i],")",""),"(",""),',');
+ add_device("VCVS", devname, get_sp_val(tt[scoeff+i]));
+ add_term(last_net, devname, 0);
+ add_term(next_net, devname, 1);
+ add_term(net2[0], devname, 2);
+ add_term(net2[1], devname, 3);
+ //# add_device_extra(devname, "PARAM({}, {})", devname + ".G", tt[scoeff+i]);
+ last_net = next_net;
+ }
+ }
+ }
break;
-#if 0
- // This is wrong ... Need to use something else for inputs!
- case 'I': // Input pin special notation
+ case 'F':
{
- val = get_sp_val(tt[2]);
- add_device("ANALOG_INPUT", tt[0], val);
- add_term(tt[1], tt[0] + ".Q");
+ auto n=get_poly_count(tt[3]);
+ unsigned sce(4);
+ unsigned scoeff(5 + static_cast<unsigned>(n));
+ if (n<0)
+ {
+ sce = 3;
+ scoeff = 4;
+ n = 1;
+ }
+ else
+ {
+ if ((tt.size() != 5 + 2 * static_cast<unsigned>(n)) || (tt[scoeff-1] != "0"))
+ {
+ out("// IGNORED {}: {}\n", tt[0], line);
+ break;
+ }
+ }
+ for (std::size_t i=0; i < static_cast<std::size_t>(n); i++)
+ {
+ pstring devname = plib::pfmt("{}{}")(tt[0], i);
+ add_device("CCCS", devname, get_sp_val(tt[scoeff+i]));
+ add_term(tt[1], devname, 0);
+ add_term(tt[2], devname, 1);
+
+ pstring extra_net_name = devname + "net";
+ m_replace.push_back({tt[sce+i], devname + ".IP", extra_net_name });
+ add_term(extra_net_name, devname + ".IN");
+ //# add_device_extra(devname, "PARAM({}, {})", devname + ".G", tt[scoeff+i]);
+ }
}
break;
-#else
+ case 'H':
+ add_device("CCVS", tt[0], get_sp_val(tt[4]));
+ add_term(tt[1], tt[0] + ".OP");
+ add_term(tt[2], tt[0] + ".ON");
+ m_replace.push_back({tt[3], tt[0] + ".IP", tt[2] + "a" });
+ add_term(tt[2] + "a", tt[0] + ".IN");
+ //add_device_extra(tt[0], "PARAM({}, {})", tt[0] + ".G", tt[4]);
+ break;
+ case 'G':
+ add_device("VCCS", tt[0], get_sp_val(tt[5]));
+ add_term(tt[1], tt[0], 0);
+ add_term(tt[2], tt[0], 1);
+ add_term(tt[3], tt[0], 2);
+ add_term(tt[4], tt[0], 3);
+ //add_device_extra(tt[0], "PARAM({}, {})", tt[0] + ".G", tt[5]);
+ break;
+ case 'V':
+ // only DC Voltage sources ....
+ val = get_sp_val(tt[3] == "DC" ? tt[4] : tt[3]);
+ add_device("VS", tt[0], val);
+ add_term(tt[1], tt[0] + ".1");
+ add_term(tt[2], tt[0] + ".2");
+ break;
case 'I':
{
- val = get_sp_val(tt[3]);
+ val = get_sp_val(tt[3] == "DC" ? tt[4] : tt[3]);
add_device("CS", tt[0], val);
add_term(tt[1], tt[0] + ".1");
add_term(tt[2], tt[0] + ".2");
}
break;
-#endif
case 'D':
- add_device("DIODE", tt[0], tt[3]);
- /* FIXME ==> does Kicad use different notation from LTSPICE */
- add_term(tt[1], tt[0] + ".K");
- add_term(tt[2], tt[0] + ".A");
+ add_device("DIODE", tt[0], m_subckt + tt[3]);
+ add_term(tt[1], tt[0], 0);
+ add_term(tt[2], tt[0], 1);
break;
case 'U':
case 'X':
@@ -439,78 +670,149 @@ void nl_convert_spice_t::process_line(const pstring &line)
// FIXME: Parameter
pstring xname = plib::replace_all(tt[0], pstring("."), pstring("_"));
- pstring tname = "TTL_" + tt[tt.size()-1] + "_DIP";
+ // Extract parameters of form X=Y
+ std::vector<pstring> nets;
+ std::unordered_map<pstring, pstring> params;
+ for (std::size_t i=1; i < tt.size(); i++)
+ {
+ auto p = tt[i].find('=');
+ if (p != pstring::npos)
+ params.emplace(tt[i].substr(0,p), tt[i].substr(p+1));
+ else
+ {
+ nets.push_back(tt[i]);
+ }
+ }
+ pstring modname = nets[nets.size()-1];
+ pstring tname = modname;
+ if (plib::startsWith(modname, "7"))
+ tname = "TTL_" + modname + "_DIP";
+ else if (plib::startsWith(modname, "4"))
+ tname = "CD" + modname + "_DIP";
+ else if (modname == "ANALOG_INPUT" && params.size()== 1 && params.begin()->first == "V")
+ {
+ auto yname=pstring("I_") + tt[0].substr(1);
+ val = get_sp_val(params["V"]);
+ add_device(modname, yname, val);
+ add_term(nets[0], yname + ".Q");
+ break;
+ }
+ else if (modname == "TTL_INPUT" && params.size()== 1 && params.begin()->first == "L")
+ {
+ auto yname=pstring("I_") + tt[0].substr(1);
+ val = get_sp_val(params["L"]);
+ add_device(modname, yname, val);
+ add_term(nets[0], yname, 0);
+ add_term(nets[1], yname, 1);
+ add_term(nets[2], yname, 2);
+ break;
+ }
+ else if (modname == "ALIAS" && nets.size() == 2 && params.empty())
+ {
+ auto yname=tt[0].substr(1);
+ add_ext_alias(yname, nets[0]);
+ break;
+ }
+ else if (modname == "RPOT" && nets.size() == 4 && !params.empty())
+ {
+ auto yname=tt[0];
+ auto R = params.find("R");
+ auto V = params.find("V");
+ if (R != params.end())
+ {
+ add_device("POT", yname, get_sp_val(R->second));
+ add_term(nets[0], yname, 0);
+ add_term(nets[1], yname, 1);
+ add_term(nets[2], yname, 2);
+ if (V != params.end())
+ add_device_extra(yname, "PARAM({}, {})", yname + ".DIAL", get_sp_val(V->second));
+ }
+ else
+ out("// IGNORED {}: {}\n", tt[0], line);
+ break;
+ }
+ else
+ tname = modname + "_DIP";
+
add_device(tname, xname);
- for (std::size_t i=1; i < tt.size() - 1; i++)
+ for (std::size_t i=0; i < nets.size() - 1; i++)
{
- pstring term = plib::pfmt("{1}.{2}")(xname)(i);
- add_term(tt[i], term);
+ // FIXME:
+ pstring term = plib::pfmt("{1}.{2}")(xname)(i+1);
+ add_term(nets[i], term);
}
break;
}
default:
- out("// IGNORED {}: {}\n", tt[0].c_str(), line.c_str());
+ out("// IGNORED {}: {}\n", tt[0], line);
}
}
}
-/*-------------------------------------------------
- Eagle converter
--------------------------------------------------*/
+//-------------------------------------------------
+// Eagle converter
+// -------------------------------------------------
-nl_convert_eagle_t::tokenizer::tokenizer(nl_convert_eagle_t &convert, plib::putf8_reader &&strm)
- : plib::ptokenizer(std::move(strm))
+nl_convert_eagle_t::tokenizer::tokenizer(nl_convert_eagle_t &convert)
+ : plib::tokenizer_t()
, m_convert(convert)
{
this->identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-")
.number_chars(".0123456789", "0123456789eE-.") //FIXME: processing of numbers
.whitespace(pstring("") + ' ' + static_cast<char>(9) + static_cast<char>(10) + static_cast<char>(13))
- /* FIXME: gnetlist doesn't print comments */
+ // FIXME: netlist doesn't print comments
.comment("/*", "*/", "//")
.string_char('\'');
m_tok_ADD = register_token("ADD");
m_tok_VALUE = register_token("VALUE");
m_tok_SIGNAL = register_token("SIGNAL");
m_tok_SEMICOLON = register_token(";");
- /* currently not used, but required for parsing */
+ // currently not used, but required for parsing
register_token(")");
register_token("(");
}
-void nl_convert_eagle_t::tokenizer::verror(const pstring &msg, int line_num, const pstring &line)
+void nl_convert_eagle_t::tokenizer::verror(const pstring &msg)
{
- m_convert.out("{} (line {}): {}\n", msg.c_str(), line_num, line.c_str());
+ m_convert.out("{}\n", msg);
}
//FIXME: should accept a stream as well
void nl_convert_eagle_t::convert(const pstring &contents)
{
- tokenizer tok(*this, plib::putf8_reader(std::istringstream(contents)));
- tok.stream().stream().imbue(std::locale::classic());
+ tokenizer tok(*this);
+
+ tokenizer::token_store tokstor;
+ plib::putf8_reader u8reader(std::make_unique<std::istringstream>(putf8string(contents)));
+
+ tok.append_to_store(&u8reader, tokstor);
+ tok.set_token_source(&tokstor);
out("NETLIST_START(dummy)\n");
+ out("{\n");
add_term("GND", "GND");
add_term("VCC", "VCC");
tokenizer::token_t token = tok.get_token();
while (true)
{
- if (token.is_type(tokenizer::ENDOFFILE))
+ if (token.is_type(tokenizer::token_type::ENDOFFILE))
{
dump_nl();
// FIXME: Parameter
- out("NETLIST_END()\n");
+ out("}\n");
return;
}
- else if (token.is(tok.m_tok_SEMICOLON))
+
+ if (token.is(tok.m_tok_SEMICOLON))
{
- /* ignore empty statements */
+ // ignore empty statements
token = tok.get_token();
}
else if (token.is(tok.m_tok_ADD))
{
pstring name = tok.get_string();
- /* skip to semicolon */
+ // skip to semicolon
do
{
token = tok.get_token();
@@ -553,7 +855,7 @@ void nl_convert_eagle_t::convert(const pstring &contents)
add_pin_alias(name, "1", "Q");
break;
case 'D':
- /* Pin 1 = Anode, Pin 2 = Cathode */
+ // Pin 1 = Anode, Pin 2 = Cathode
add_device("DIODE", name, sval);
add_pin_alias(name, "1", "A");
add_pin_alias(name, "2", "K");
@@ -566,7 +868,7 @@ void nl_convert_eagle_t::convert(const pstring &contents)
break;
}
default:
- tok.error("// IGNORED " + name);
+ tok.error(plib::perrmsg("// IGNORED {1}", name));
}
}
@@ -576,7 +878,7 @@ void nl_convert_eagle_t::convert(const pstring &contents)
token = tok.get_token();
while (!token.is(tok.m_tok_SEMICOLON))
{
- /* fixme: should check for string */
+ // fixme: should check for string
pstring devname = token.str();
pstring pin = tok.get_string();
add_term(netname, devname + "." + pin);
@@ -584,25 +886,25 @@ void nl_convert_eagle_t::convert(const pstring &contents)
}
else
{
- out("Unexpected {}\n", token.str().c_str());
+ out("Unexpected {}\n", token.str());
return;
}
}
}
-/*-------------------------------------------------
- RINF converter
--------------------------------------------------*/
+// -------------------------------------------------
+// RINF converter
+// -------------------------------------------------
-nl_convert_rinf_t::tokenizer::tokenizer(nl_convert_rinf_t &convert, plib::putf8_reader &&strm)
- : plib::ptokenizer(std::move(strm))
+nl_convert_rinf_t::tokenizer::tokenizer(nl_convert_rinf_t &convert)
+ : plib::tokenizer_t()
, m_convert(convert)
{
this->identifier_chars(".abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_-")
.number_chars("0123456789", "0123456789eE-.") //FIXME: processing of numbers
.whitespace(pstring("") + ' ' + static_cast<char>(9) + static_cast<char>(10) + static_cast<char>(13))
- /* FIXME: gnetlist doesn't print comments */
+ // FIXME: netlist doesn't print comments
.comment("","","//") // FIXME:needs to be confirmed
.string_char('"');
m_tok_HEA = register_token(".HEA");
@@ -616,56 +918,62 @@ nl_convert_rinf_t::tokenizer::tokenizer(nl_convert_rinf_t &convert, plib::putf8_
m_tok_END = register_token(".END");
}
-void nl_convert_rinf_t::tokenizer::verror(const pstring &msg, int line_num, const pstring &line)
+void nl_convert_rinf_t::tokenizer::verror(const pstring &msg)
{
- m_convert.out("{} (line {}): {}\n", msg.c_str(), line_num, line.c_str());
+ m_convert.out("{}\n", msg);
}
-/* token_id_t m_tok_HFA;
- token_id_t m_tok_APP;
- token_id_t m_tok_TIM;
- token_id_t m_tok_TYP;
- token_id_t m_tok_ADDC;
- token_id_t m_tok_ATTC;
- token_id_t m_tok_NET;
- token_id_t m_tok_TER;
- *
- */
+// token_id_t m_tok_HFA;
+// token_id_t m_tok_APP;
+// token_id_t m_tok_TIM;
+// token_id_t m_tok_TYP;
+// token_id_t m_tok_ADDC;
+// token_id_t m_tok_ATTC;
+// token_id_t m_tok_NET;
+// token_id_t m_tok_TER;
void nl_convert_rinf_t::convert(const pstring &contents)
{
- tokenizer tok(*this, plib::putf8_reader(std::istringstream(contents)));
- tok.stream().stream().imbue(std::locale::classic());
+ tokenizer tok(*this);
+
+ tokenizer::token_store tokstor;
+ plib::putf8_reader u8reader(std::make_unique<std::istringstream>(putf8string(contents)));
+
+ tok.append_to_store(&u8reader, tokstor);
+ tok.set_token_source(&tokstor);
+
auto lm = read_lib_map(s_lib_map);
out("NETLIST_START(dummy)\n");
+ out("{\n");
add_term("GND", "GND");
add_term("VCC", "VCC");
tokenizer::token_t token = tok.get_token();
while (true)
{
- if (token.is_type(tokenizer::ENDOFFILE) || token.is(tok.m_tok_END))
+ if (token.is_type(tokenizer::token_type::ENDOFFILE) || token.is(tok.m_tok_END))
{
dump_nl();
// FIXME: Parameter
- out("NETLIST_END()\n");
+ out("}\n");
return;
}
- else if (token.is(tok.m_tok_HEA))
+
+ if (token.is(tok.m_tok_HEA))
{
- /* seems to be start token - ignore */
+ // seems to be start token - ignore
token = tok.get_token();
}
else if (token.is(tok.m_tok_APP))
{
- /* version string */
+ // version string
pstring app = tok.get_string();
out("// APP: {}\n", app);
token = tok.get_token();
}
else if (token.is(tok.m_tok_TIM))
{
- /* time */
+ // time
out("// TIM:");
for (int i=0; i<6; i++)
{
@@ -705,7 +1013,7 @@ void nl_convert_rinf_t::convert(const pstring &contents)
pstring sim = attr["Simulation"];
pstring val = attr["Value"];
pstring com = attr["Comment"];
- if (val == "")
+ if (val.empty())
val = com;
if (sim == "CAP")
@@ -736,7 +1044,7 @@ void nl_convert_rinf_t::convert(const pstring &contents)
if (token.is(tok.m_tok_TER))
{
token = tok.get_token();
- while (token.is_type(plib::ptokenizer::IDENTIFIER))
+ while (token.is_type(plib::token_reader_t::token_type::IDENTIFIER))
{
pin = tok.get_identifier_or_number();
add_term(net, token.str() + "." + pin);
@@ -746,7 +1054,7 @@ void nl_convert_rinf_t::convert(const pstring &contents)
}
#if 0
token = tok.get_token();
- /* skip to semicolon */
+ // skip to semicolon
do
{
token = tok.get_token();
@@ -789,7 +1097,7 @@ void nl_convert_rinf_t::convert(const pstring &contents)
add_pin_alias(name, "1", "Q");
break;
case 'D':
- /* Pin 1 = Anode, Pin 2 = Cathode */
+ // Pin 1 = Anode, Pin 2 = Cathode
add_device("DIODE", name, sval);
add_pin_alias(name, "1", "A");
add_pin_alias(name, "2", "K");
@@ -812,7 +1120,7 @@ void nl_convert_rinf_t::convert(const pstring &contents)
token = tok.get_token();
while (!token.is(tok.m_tok_SEMICOLON))
{
- /* fixme: should check for string */
+ // fixme: should check for string
pstring devname = token.str();
pstring pin = tok.get_string();
add_term(netname, devname + "." + pin);
@@ -827,3 +1135,5 @@ void nl_convert_rinf_t::convert(const pstring &contents)
}
}
+
+} // namespace netlist::convert
diff --git a/src/lib/netlist/tools/nl_convert.h b/src/lib/netlist/tools/nl_convert.h
index e070514d5ed..0e36e85a253 100644
--- a/src/lib/netlist/tools/nl_convert.h
+++ b/src/lib/netlist/tools/nl_convert.h
@@ -1,35 +1,40 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
-/*
- * nl_convert.h
- *
- */
-
-#pragma once
#ifndef NL_CONVERT_H_
#define NL_CONVERT_H_
-#include "plib/plists.h"
-#include "plib/pparser.h"
+///
+/// \file nl_convert.h
+///
+
+#include "plib/palloc.h"
#include "plib/pstring.h"
#include "plib/ptypes.h"
#include <memory>
-/*-------------------------------------------------
- convert - convert a spice netlist
--------------------------------------------------*/
+#include "../plib/ptokenizer.h"
+
+// -------------------------------------------------
+// convert - convert a spice netlist
+// -------------------------------------------------
+
+namespace netlist::convert
+{
+
+using arena = plib::aligned_arena<>;
class nl_convert_base_t
{
public:
+ using str_list = std::vector<pstring>;
- COPYASSIGNMOVE(nl_convert_base_t, delete)
+ PCOPYASSIGNMOVE(nl_convert_base_t, delete)
virtual ~nl_convert_base_t();
- pstring result() { return pstring(m_buf.str()); }
+ pstring result() { return pstring(putf8string(m_buf.str())); }
virtual void convert(const pstring &contents) = 0;
@@ -39,21 +44,40 @@ protected:
void add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias);
void add_ext_alias(const pstring &alias);
+ void add_ext_alias(const pstring &alias, const pstring &net);
void add_device(const pstring &atype, const pstring &aname, const pstring &amodel);
void add_device(const pstring &atype, const pstring &aname, double aval);
void add_device(const pstring &atype, const pstring &aname);
+ void add_device_extra_s(const pstring &devname, const pstring &extra);
+
+ template<typename... Args>
+ void add_device_extra(const pstring &devname, const pstring &fmt, Args&&... args)
+ {
+ add_device_extra_s(devname, plib::pfmt(fmt)(std::forward<Args>(args)...));
+ }
+
void add_term(const pstring &netname, const pstring &termname);
+ void add_term(const pstring &netname, const pstring &devname, unsigned term);
void dump_nl();
- const pstring get_nl_val(const double val);
- double get_sp_unit(const pstring &unit);
+ pstring get_nl_val(double val) const;
+ double get_sp_unit(const pstring &unit) const;
- double get_sp_val(const pstring &sin);
+ double get_sp_val(const pstring &sin) const;
plib::putf8_fmt_writer out;
+
+ struct replace_t
+ {
+ pstring m_ce; // controlling element - must be a two terminal element
+ pstring m_repterm; // replace with terminal
+ pstring m_net; // connect to net
+ };
+ std::vector<replace_t> m_replace;
+
private:
struct net_t
@@ -62,10 +86,10 @@ private:
explicit net_t(pstring aname)
: m_name(std::move(aname)), m_no_export(false) {}
- const pstring &name() { return m_name;}
- std::vector<pstring> &terminals() { return m_terminals; }
+ const pstring &name() const { return m_name;}
+ std::vector<pstring> &terminals(){ return m_terminals; }
void set_no_export() { m_no_export = true; }
- bool is_no_export() { return m_no_export; }
+ bool is_no_export() const { return m_no_export; }
private:
pstring m_name;
@@ -100,20 +124,23 @@ private:
, m_has_val(false)
{}
- const pstring &name() { return m_name;}
- const pstring &type() { return m_type;}
- const pstring &model() { return m_model;}
- const double &value() { return m_val;}
+ const pstring &name() const { return m_name;}
+ const pstring &type() const { return m_type;}
+ const pstring &model() const { return m_model;}
+ double value() const { return m_val;}
+ const str_list &extra() const { return m_extra;}
- bool has_model() { return m_model != ""; }
- bool has_value() { return m_has_val; }
+ bool has_model() const { return !m_model.empty(); }
+ bool has_value() const { return m_has_val; }
+ void add_extra(const pstring &s) { m_extra.push_back(s); }
private:
pstring m_type;
pstring m_name;
pstring m_model;
double m_val;
bool m_has_val;
+ str_list m_extra;
};
struct unit_t {
@@ -128,26 +155,33 @@ private:
pin_alias_t(pstring name, pstring alias)
: m_name(std::move(name)), m_alias(std::move(alias))
{}
- const pstring &name() { return m_name; }
- const pstring &alias() { return m_alias; }
+ const pstring &name() const { return m_name; }
+ const pstring &alias() const { return m_alias; }
private:
pstring m_name;
pstring m_alias;
};
-private:
-
- void add_device(plib::unique_ptr<dev_t> dev);
+ void add_device(arena::unique_ptr<dev_t> dev);
+ dev_t *get_device(const pstring &name)
+ {
+ for (auto &e : m_devs)
+ if (e->name() == name)
+ return e.get();
+ return nullptr;
+ }
std::stringstream m_buf;
- std::vector<plib::unique_ptr<dev_t>> m_devs;
- std::unordered_map<pstring, plib::unique_ptr<net_t> > m_nets;
- std::vector<pstring> m_ext_alias;
- std::unordered_map<pstring, plib::unique_ptr<pin_alias_t>> m_pins;
+ std::vector<arena::unique_ptr<dev_t>> m_devs;
+ std::unordered_map<pstring, arena::unique_ptr<net_t> > m_nets;
+ std::vector<std::pair<pstring, pstring>> m_ext_alias;
+ std::unordered_map<pstring, arena::unique_ptr<pin_alias_t>> m_pins;
std::vector<unit_t> m_units;
- pstring m_numberchars;
+ pstring m_number_chars;
+
+ std::unordered_map<pstring, str_list> dev_map;
};
@@ -155,37 +189,44 @@ class nl_convert_spice_t : public nl_convert_base_t
{
public:
- nl_convert_spice_t() : nl_convert_base_t() {}
+ nl_convert_spice_t() : m_is_kicad(false) { }
void convert(const pstring &contents) override;
protected:
+ bool is_kicad() const { return m_is_kicad; }
+ void convert_block(const str_list &contents);
void process_line(const pstring &line);
private:
pstring m_subckt;
+ bool m_is_kicad;
};
class nl_convert_eagle_t : public nl_convert_base_t
{
public:
- nl_convert_eagle_t() : nl_convert_base_t() {}
+ nl_convert_eagle_t() = default;
- class tokenizer : public plib::ptokenizer
+ class tokenizer : public plib::tokenizer_t, public plib::token_reader_t
{
public:
- tokenizer(nl_convert_eagle_t &convert, plib::putf8_reader &&strm);
+ using token_t = tokenizer_t::token_t;
+ using token_type = tokenizer_t::token_type;
+ using token_id_t = tokenizer_t::token_id_t;
+ using token_store = tokenizer_t::token_store_t;
- token_id_t m_tok_ADD;
- token_id_t m_tok_VALUE;
- token_id_t m_tok_SIGNAL;
- token_id_t m_tok_SEMICOLON;
+ tokenizer(nl_convert_eagle_t &convert);
+ token_id_t m_tok_ADD; // NOLINT
+ token_id_t m_tok_VALUE; // NOLINT
+ token_id_t m_tok_SIGNAL; // NOLINT
+ token_id_t m_tok_SEMICOLON; // NOLINT
protected:
- void verror(const pstring &msg, int line_num, const pstring &line) override;
+ void verror(const pstring &msg) override;
private:
nl_convert_eagle_t &m_convert;
@@ -204,26 +245,29 @@ class nl_convert_rinf_t : public nl_convert_base_t
{
public:
- nl_convert_rinf_t() : nl_convert_base_t() {}
+ nl_convert_rinf_t() = default;
- class tokenizer : public plib::ptokenizer
+ class tokenizer : public plib::tokenizer_t, public plib::token_reader_t
{
public:
- tokenizer(nl_convert_rinf_t &convert, plib::putf8_reader &&strm);
-
- token_id_t m_tok_HEA;
- token_id_t m_tok_APP;
- token_id_t m_tok_TIM;
- token_id_t m_tok_TYP;
- token_id_t m_tok_ADDC;
- token_id_t m_tok_ATTC;
- token_id_t m_tok_NET;
- token_id_t m_tok_TER;
- token_id_t m_tok_END;
-
+ using token_t = tokenizer_t::token_t;
+ using token_type = tokenizer_t::token_type;
+ using token_id_t = tokenizer_t::token_id_t;
+ using token_store = tokenizer_t::token_store_t;
+ tokenizer(nl_convert_rinf_t &convert);
+
+ token_id_t m_tok_HEA; // NOLINT
+ token_id_t m_tok_APP; // NOLINT
+ token_id_t m_tok_TIM; // NOLINT
+ token_id_t m_tok_TYP; // NOLINT
+ token_id_t m_tok_ADDC; // NOLINT
+ token_id_t m_tok_ATTC; // NOLINT
+ token_id_t m_tok_NET; // NOLINT
+ token_id_t m_tok_TER; // NOLINT
+ token_id_t m_tok_END; // NOLINT
protected:
- void verror(const pstring &msg, int line_num, const pstring &line) override;
+ void verror(const pstring &msg) override;
private:
nl_convert_rinf_t &m_convert;
@@ -238,4 +282,6 @@ private:
};
-#endif /* NL_CONVERT_H_ */
+} // namespace netlist::convert
+
+#endif // NL_CONVERT_H_