Better .include for Spice reader

* .inc is allowed as synonym
* Paths can be URL's (with HTTP)
* Relative resolution of paths/URL's vs. parent of .include
This commit is contained in:
Matthias Koefferlein 2019-08-19 21:45:40 +02:00
parent 9fecc4b674
commit 24b985f32e
7 changed files with 91 additions and 2 deletions

View File

@ -27,6 +27,8 @@
#include "tlStream.h"
#include "tlLog.h"
#include "tlString.h"
#include "tlFileUtils.h"
#include "tlUri.h"
#include <sstream>
#include <cctype>
@ -243,7 +245,20 @@ void NetlistSpiceReader::finish ()
void NetlistSpiceReader::push_stream (const std::string &path)
{
tl::InputStream *istream = new tl::InputStream (path);
tl::URI current_uri (mp_stream->source ());
tl::URI new_uri (path);
tl::InputStream *istream;
if (current_uri.scheme ().empty () && new_uri.scheme ().empty ()) {
if (tl::is_absolute (path)) {
istream = new tl::InputStream (path);
} else {
istream = new tl::InputStream (tl::combine_path (tl::dirname (mp_stream->source ()), path));
}
} else {
istream = new tl::InputStream (current_uri.resolved (new_uri).to_string ());
}
m_streams.push_back (std::make_pair (istream, mp_stream.release ()));
mp_stream.reset (new tl::TextInputStream (*istream));
}
@ -291,7 +306,7 @@ std::string NetlistSpiceReader::get_line ()
}
tl::Extractor ex (l.c_str ());
if (ex.test_without_case (".include")) {
if (ex.test_without_case (".include") || ex.test_without_case (".inc")) {
std::string path = read_name_with_case (ex);

View File

@ -294,3 +294,42 @@ TEST(7_GlobalNets)
"end;\n"
);
}
TEST(8_Include)
{
db::Netlist nl;
std::string path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "nreader8.cir");
db::NetlistSpiceReader reader;
tl::InputStream is (path);
reader.read (is, nl);
EXPECT_EQ (nl.to_string (),
"circuit INVX1 ('1'='1','2'='2','3'='3','4'='4','5'='5','6'='6');\n"
" device MLVPMOS $1 (S='1',G='5',D='2',B='4') (L=0.25,W=1.5,AS=0,AD=0,PS=0,PD=0);\n"
" device MLVNMOS $2 (S='3',G='5',D='2',B='6') (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
"end;\n"
"circuit ND2X1 ('1'='1','2'='2','3'='3','4'='4','5'='5','6'='6','7'='7');\n"
" device MLVPMOS $1 (S='2',G='6',D='1',B='4') (L=0.25,W=1.5,AS=0,AD=0,PS=0,PD=0);\n"
" device MLVPMOS $2 (S='1',G='5',D='2',B='4') (L=0.25,W=1.5,AS=0,AD=0,PS=0,PD=0);\n"
" device MLVNMOS $3 (S='3',G='6',D='8',B='7') (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
" device MLVNMOS $4 (S='8',G='5',D='2',B='7') (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0);\n"
"end;\n"
"circuit RINGO ('11'='11','12'='12','13'='13','14'='14','15'='15');\n"
" subcircuit ND2X1 $1 ('1'='12','2'='1','3'='15','4'='12','5'='11','6'='14','7'='15');\n"
" subcircuit INVX1 $2 ('1'='12','2'='2','3'='15','4'='12','5'='1','6'='15');\n"
" subcircuit INVX1 $3 ('1'='12','2'='3','3'='15','4'='12','5'='2','6'='15');\n"
" subcircuit INVX1 $4 ('1'='12','2'='4','3'='15','4'='12','5'='3','6'='15');\n"
" subcircuit INVX1 $5 ('1'='12','2'='5','3'='15','4'='12','5'='4','6'='15');\n"
" subcircuit INVX1 $6 ('1'='12','2'='6','3'='15','4'='12','5'='5','6'='15');\n"
" subcircuit INVX1 $7 ('1'='12','2'='7','3'='15','4'='12','5'='6','6'='15');\n"
" subcircuit INVX1 $8 ('1'='12','2'='8','3'='15','4'='12','5'='7','6'='15');\n"
" subcircuit INVX1 $9 ('1'='12','2'='9','3'='15','4'='12','5'='8','6'='15');\n"
" subcircuit INVX1 $10 ('1'='12','2'='10','3'='15','4'='12','5'='9','6'='15');\n"
" subcircuit INVX1 $11 ('1'='12','2'='11','3'='15','4'='12','5'='10','6'='15');\n"
" subcircuit INVX1 $12 ('1'='12','2'='13','3'='15','4'='12','5'='11','6'='15');\n"
"end;\n"
);
}

5
testdata/algo/nreader8.cir vendored Normal file
View File

@ -0,0 +1,5 @@
.include "nreader8a.cir"
.include ../algo/nreader8b.cir
.inc nreader8c.cir

4
testdata/algo/nreader8a.cir vendored Normal file
View File

@ -0,0 +1,4 @@
.subckt INVX1 1 2 3 4 5 6
.include nreader8x.cir
.ends

8
testdata/algo/nreader8b.cir vendored Normal file
View File

@ -0,0 +1,8 @@
.subckt ND2X1 1 2 3 4 5 6 7
m$1 2 6 1 4 MLVPMOS L=0.25um W=1.5um
m$2 1 5 2 4 MLVPMOS L=0.25um W=1.5um
m$3 3 6 8 7 MLVNMOS L=0.25um W=0.95um
m$4 8 5 2 7 MLVNMOS L=0.25um W=0.95um
.ends ND2X1

15
testdata/algo/nreader8c.cir vendored Normal file
View File

@ -0,0 +1,15 @@
.subckt RINGO 11 12 13 14 15
x$1 12 1 15 12 11 14 15 ND2X1
x$2 12 2 15 12 1 15 INVX1
x$3 12 3 15 12 2 15 INVX1
x$4 12 4 15 12 3 15 INVX1
x$5 12 5 15 12 4 15 INVX1
x$6 12 6 15 12 5 15 INVX1
x$7 12 7 15 12 6 15 INVX1
x$8 12 8 15 12 7 15 INVX1
x$9 12 9 15 12 8 15 INVX1
x$10 12 10 15 12 9 15 INVX1
x$11 12 11 15 12 10 15 INVX1
x$12 12 13 15 12 11 15 INVX1
.ends RINGO

3
testdata/algo/nreader8x.cir vendored Normal file
View File

@ -0,0 +1,3 @@
m$1 1 5 2 4 mlvpmos w=1.5um l=0.25um
m$2 3 5 2 6 mlvnmos w=0.95um l=0.25um