mirror of https://github.com/KLayout/klayout.git
Implemented .lib for Spice reader - issue #1320
This commit is contained in:
parent
a39441cdbd
commit
02e9f605d9
|
|
@ -75,6 +75,7 @@ class SpiceReaderStream
|
|||
{
|
||||
public:
|
||||
SpiceReaderStream ();
|
||||
SpiceReaderStream (const std::string &lib);
|
||||
~SpiceReaderStream ();
|
||||
|
||||
void set_stream (tl::InputStream &stream);
|
||||
|
|
@ -85,9 +86,11 @@ public:
|
|||
int line_number () const;
|
||||
std::string source () const;
|
||||
bool at_end () const;
|
||||
const std::string &lib () const { return m_lib; }
|
||||
|
||||
void swap (SpiceReaderStream &other)
|
||||
{
|
||||
std::swap (m_lib, other.m_lib);
|
||||
std::swap (mp_stream, other.mp_stream);
|
||||
std::swap (m_owns_stream, other.m_owns_stream);
|
||||
std::swap (mp_text_stream, other.mp_text_stream);
|
||||
|
|
@ -103,6 +106,7 @@ private:
|
|||
int m_line_number;
|
||||
std::string m_stored_line;
|
||||
bool m_has_stored_line;
|
||||
std::string m_lib;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -112,6 +116,12 @@ SpiceReaderStream::SpiceReaderStream ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
SpiceReaderStream::SpiceReaderStream (const std::string &lib)
|
||||
: mp_stream (0), m_owns_stream (false), mp_text_stream (0), m_line_number (0), m_stored_line (), m_has_stored_line (false), m_lib (lib)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
SpiceReaderStream::~SpiceReaderStream ()
|
||||
{
|
||||
close ();
|
||||
|
|
@ -372,6 +382,7 @@ private:
|
|||
std::vector<std::string> m_paths;
|
||||
std::map<std::string, int> m_file_id_per_path;
|
||||
std::list<SpiceReaderStream> m_streams;
|
||||
std::list<std::string> m_in_lib;
|
||||
SpiceReaderStream m_stream;
|
||||
int m_file_id;
|
||||
std::map<std::string, SpiceCachedCircuit *> m_cached_circuits;
|
||||
|
|
@ -382,7 +393,7 @@ private:
|
|||
std::set<std::string> m_global_net_names;
|
||||
std::vector<std::string> m_global_nets;
|
||||
|
||||
void push_stream (const std::string &path);
|
||||
void push_stream (const std::string &path, const std::string &lib = std::string ());
|
||||
void pop_stream ();
|
||||
bool at_end ();
|
||||
void read_subcircuit (const std::string &sc_name, const std::string &nc_name, const std::vector<db::Net *> &nets);
|
||||
|
|
@ -489,7 +500,7 @@ SpiceCircuitDict::read (tl::InputStream &stream)
|
|||
}
|
||||
|
||||
void
|
||||
SpiceCircuitDict::push_stream (const std::string &path)
|
||||
SpiceCircuitDict::push_stream (const std::string &path, const std::string &lib)
|
||||
{
|
||||
tl::URI current_uri (m_stream.source ());
|
||||
tl::URI new_uri (path);
|
||||
|
|
@ -505,7 +516,7 @@ SpiceCircuitDict::push_stream (const std::string &path)
|
|||
istream = new tl::InputStream (current_uri.resolved (new_uri).to_abstract_path ());
|
||||
}
|
||||
|
||||
m_streams.push_back (SpiceReaderStream ());
|
||||
m_streams.push_back (SpiceReaderStream (lib));
|
||||
m_streams.back ().swap (m_stream);
|
||||
m_stream.set_stream (istream);
|
||||
|
||||
|
|
@ -557,24 +568,73 @@ SpiceCircuitDict::get_line ()
|
|||
if (m_streams.empty ()) {
|
||||
break;
|
||||
} else {
|
||||
if (! m_stream.lib ().empty ()) {
|
||||
m_in_lib.pop_back ();
|
||||
}
|
||||
pop_stream ();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
bool consider_line = m_in_lib.empty () || (! m_stream.lib ().empty () && m_stream.lib () == m_in_lib.back ());
|
||||
|
||||
tl::Extractor ex (lp.first.c_str ());
|
||||
if (ex.test_without_case (".include") || ex.test_without_case (".inc")) {
|
||||
|
||||
std::string path;
|
||||
ex.read_word_or_quoted (path, allowed_name_chars);
|
||||
|
||||
push_stream (path);
|
||||
if (consider_line) {
|
||||
std::string libname = m_stream.lib ();
|
||||
push_stream (path, libname);
|
||||
if (! libname.empty ()) {
|
||||
m_in_lib.push_back (libname);
|
||||
}
|
||||
}
|
||||
|
||||
ex.expect_end ();
|
||||
|
||||
} else if (ex.test_without_case (".lib")) {
|
||||
|
||||
std::string path_or_libname;
|
||||
|
||||
ex.read_word_or_quoted (path_or_libname, allowed_name_chars);
|
||||
if (! ex.at_end ()) {
|
||||
|
||||
std::string libname;
|
||||
ex.read_word_or_quoted (libname, allowed_name_chars);
|
||||
|
||||
if (consider_line) {
|
||||
libname = mp_netlist->normalize_name (libname);
|
||||
push_stream (path_or_libname, libname);
|
||||
if (! libname.empty ()) {
|
||||
m_in_lib.push_back (std::string ());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
std::string libname = mp_netlist->normalize_name (path_or_libname);
|
||||
m_in_lib.push_back (libname);
|
||||
ex.expect_end ();
|
||||
|
||||
}
|
||||
|
||||
} else if (ex.test_without_case (".endl")) {
|
||||
|
||||
if (! m_in_lib.empty ()) {
|
||||
m_in_lib.pop_back ();
|
||||
} else {
|
||||
warn (tl::to_string (tr ("Ignoring .endl without .lib")));
|
||||
}
|
||||
|
||||
ex.expect_end ();
|
||||
|
||||
} else if (ex.at_end () || ex.test ("*")) {
|
||||
|
||||
// skip empty and comment lines
|
||||
|
||||
} else {
|
||||
} else if (consider_line) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -814,6 +814,28 @@ TEST(20_precendence)
|
|||
);
|
||||
}
|
||||
|
||||
// issue #1320, .lib support
|
||||
TEST(21_lib)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
std::string path = tl::combine_path (tl::combine_path (tl::testdata (), "algo"), "nreader21.cir");
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"circuit .TOP ();\n"
|
||||
" device CAP '10' (A='1',B='2') (C=1e-12,A=0,P=0);\n"
|
||||
" device CAP '1' (A='1',B='2') (C=1e-10,A=0,P=0);\n"
|
||||
" device CAP '2A' (A='1',B='2') (C=1.01e-10,A=0,P=0);\n"
|
||||
" device CAP '2B' (A='1',B='2') (C=1.02e-10,A=0,P=0);\n"
|
||||
" device CAP '100' (A='1',B='2') (C=1.5e-11,A=0,P=0);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
||||
TEST(100_ExpressionParser)
|
||||
{
|
||||
std::map<std::string, tl::Variant> vars;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
.lib nreader21_lib1.cir lib1
|
||||
.lib nreader21_lib1.cir lib2
|
||||
|
||||
C100 1 2 15p
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
C2a 1 2 101p
|
||||
C2b 1 2 102p
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
.lib lib1
|
||||
.lib nreader21_lib2.cir lib3
|
||||
C1 1 2 100p
|
||||
.endl
|
||||
|
||||
.lib lib2
|
||||
.include nreader21_inc.cir
|
||||
.endl
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
.lib lib3
|
||||
C10 1 2 1p
|
||||
.endl
|
||||
|
||||
C11 1 2 1.5p
|
||||
|
||||
.lib lib4
|
||||
C12 1 2 42p
|
||||
.endl
|
||||
|
||||
Loading…
Reference in New Issue