diff --git a/src/db/db/dbNetlistSpiceReader.cc b/src/db/db/dbNetlistSpiceReader.cc index c54a7e352..dff5050cc 100644 --- a/src/db/db/dbNetlistSpiceReader.cc +++ b/src/db/db/dbNetlistSpiceReader.cc @@ -254,6 +254,7 @@ void NetlistSpiceReader::read (tl::InputStream &stream, db::Netlist &netlist) mp_circuit = 0; mp_nets_by_name.reset (0); m_global_nets.clear (); + m_circuits_read.clear (); try { @@ -891,11 +892,16 @@ void NetlistSpiceReader::read_circuit (tl::Extractor &ex, const std::string &nc) } else { if (cc->pin_count () != nn.size () + m_global_nets.size ()) { - error (tl::sprintf (tl::to_string (tr ("Pin count mismatch between implicit (through call) and explicit circuit definition: %d expected, got %d")), int (cc->pin_count ()), int (nn.size ()))); + error (tl::sprintf (tl::to_string (tr ("Pin count mismatch between implicit (through call) and explicit circuit definition: %d expected, got %d in circuit %s")), int (cc->pin_count ()), int (nn.size ()), nc)); } } + if (m_circuits_read.find (cc) != m_circuits_read.end ()) { + error (tl::sprintf (tl::to_string (tr ("Redefinition of circuit %s")), nc)); + } + m_circuits_read.insert (cc); + std::auto_ptr > n2n (mp_nets_by_name.release ()); mp_nets_by_name.reset (0); diff --git a/src/db/db/dbNetlistSpiceReader.h b/src/db/db/dbNetlistSpiceReader.h index 95eca62e2..ddf5eecea 100644 --- a/src/db/db/dbNetlistSpiceReader.h +++ b/src/db/db/dbNetlistSpiceReader.h @@ -28,6 +28,8 @@ #include "tlStream.h" #include +#include +#include #include namespace db @@ -129,6 +131,7 @@ private: std::string m_stored_line; std::map m_captured; std::vector m_global_nets; + std::set m_circuits_read; void push_stream (const std::string &path); void pop_stream (); diff --git a/src/db/unit_tests/dbNetlistReaderTests.cc b/src/db/unit_tests/dbNetlistReaderTests.cc index 98a6b3491..dc4d40d41 100644 --- a/src/db/unit_tests/dbNetlistReaderTests.cc +++ b/src/db/unit_tests/dbNetlistReaderTests.cc @@ -384,3 +384,21 @@ TEST(10_SubcircuitsNoPins) ); } +TEST(11_ErrorOnCircuitRedefinition) +{ + db::Netlist nl; + + std::string path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "nreader11.cir"); + + std::string msg; + try { + db::NetlistSpiceReader reader; + tl::InputStream is (path); + reader.read (is, nl); + } catch (tl::Exception &ex) { + msg = ex.msg (); + } + + EXPECT_EQ (tl::replaced (msg, path, "?"), "Redefinition of circuit SUBCKT in ?, line 20"); +} + diff --git a/testdata/algo/nreader11.cir b/testdata/algo/nreader11.cir new file mode 100644 index 000000000..2b334a8d2 --- /dev/null +++ b/testdata/algo/nreader11.cir @@ -0,0 +1,22 @@ +* written by unit test + +* cell SUBCKT +* pin +* pin A +* pin V42 +* pin Z +* pin gnd +* pin gnd +.SUBCKT SUBCKT \$1 A[5]<1> V42\x28\x25\x29 Z gnd gnd$1 +XD_$1 V42\x28\x25\x29 \$3 Z \$1 HVPMOS PARAMS: L=0.2 W=1 AS=0.18 AD=0.18 ++ PS=2.16 PD=2.16 +* device instance $2 r0 *1 0,0 HVPMOS +XD_$2 V42\x28\x25\x29 A[5]<1> \$3 \$1 HVPMOS PARAMS: L=0.2 W=1 AS=0.18 AD=0.18 ++ PS=2.16 PD=2.16 +XD_$3 gnd \$3 gnd gnd$1 HVNMOS PARAMS: L=1.13 W=2.12 PS=6 PD=6 AS=0 AD=0 +XD_$4 gnd \$3 Z gnd$1 HVNMOS PARAMS: L=0.4 W=0.4 PS=1.16 PD=1.16 AS=0.19 AD=0.19 +XD_$5 gnd A[5]<1> \$3 gnd$1 HVNMOS PARAMS: L=0.4 W=0.4 PS=1.76 PD=1.76 AS=0.19 AD=0.19 +.ENDS SUBCKT +.SUBCKT SUBCKT \$1 A[5]<1> V42\x28\x25\x29 Z gnd gnd$1 +XD_$13 gnd \$3 gnd gnd$1 HVNMOS PARAMS: L=1.13 W=2.12 PS=6 PD=6 AS=0 AD=0 +.ENDS SUBCKT