diff --git a/src/db/db/dbCircuit.cc b/src/db/db/dbCircuit.cc index a2d5036bb..0c80b380a 100644 --- a/src/db/db/dbCircuit.cc +++ b/src/db/db/dbCircuit.cc @@ -333,20 +333,40 @@ void Circuit::remove_pin (size_t id) void Circuit::add_net (Net *net) { + if (! net) { + return; + } + if (net->circuit ()) { + throw tl::Exception (tl::to_string (tr ("Net already part of a circuit"))); + } + m_nets.push_back (net); net->set_circuit (this); } void Circuit::remove_net (Net *net) { + if (! net) { + return; + } + if (net->circuit () != this) { + throw tl::Exception (tl::to_string (tr ("Net not withing given circuit"))); + } + m_nets.erase (net); } void Circuit::join_nets (Net *net, Net *with) { + if (! net) { + return; + } if (net == with || ! with) { return; } + if (net->circuit () != this || with->circuit () != this) { + throw tl::Exception (tl::to_string (tr ("Nets not withing given circuit"))); + } while (with->begin_terminals () != with->end_terminals ()) { db::Device *device = const_cast (with->begin_terminals ()->device ()); @@ -372,6 +392,13 @@ void Circuit::join_nets (Net *net, Net *with) void Circuit::add_device (Device *device) { + if (! device) { + return; + } + if (device->circuit ()) { + throw tl::Exception (tl::to_string (tr ("Device already in a circuit"))); + } + device->set_circuit (this); size_t id = 0; @@ -386,11 +413,25 @@ void Circuit::add_device (Device *device) void Circuit::remove_device (Device *device) { + if (! device) { + return; + } + if (device->circuit () != this) { + throw tl::Exception (tl::to_string (tr ("Device not withing given circuit"))); + } + m_devices.erase (device); } void Circuit::add_subcircuit (SubCircuit *subcircuit) { + if (! subcircuit) { + return; + } + if (subcircuit->circuit ()) { + throw tl::Exception (tl::to_string (tr ("Subcircuit already in a circuit"))); + } + subcircuit->set_circuit (this); size_t id = 0; @@ -405,6 +446,13 @@ void Circuit::add_subcircuit (SubCircuit *subcircuit) void Circuit::remove_subcircuit (SubCircuit *subcircuit) { + if (! subcircuit) { + return; + } + if (subcircuit->circuit () != this) { + throw tl::Exception (tl::to_string (tr ("Subcircuit not withing given circuit"))); + } + m_subcircuits.erase (subcircuit); } @@ -420,7 +468,12 @@ void Circuit::unregister_ref (SubCircuit *r) void Circuit::flatten_subcircuit (SubCircuit *subcircuit) { - tl_assert (subcircuit != 0); + if (! subcircuit) { + return; + } + if (subcircuit->circuit () != this) { + throw tl::Exception (tl::to_string (tr ("Subcircuit not withing given circuit"))); + } const db::Circuit *c = subcircuit->circuit_ref (); diff --git a/src/db/db/dbNetlist.cc b/src/db/db/dbNetlist.cc index bd33399d5..dd32a00ab 100644 --- a/src/db/db/dbNetlist.cc +++ b/src/db/db/dbNetlist.cc @@ -265,6 +265,10 @@ void Netlist::unlock () const tl::vector &Netlist::child_circuits (Circuit *circuit) { + if (circuit->netlist () != this) { + throw tl::Exception (tl::to_string (tr ("Circuit not within given netlist"))); + } + if (! m_valid_topology) { validate_topology (); } @@ -275,6 +279,10 @@ const tl::vector &Netlist::child_circuits (Circuit *circuit) const tl::vector &Netlist::parent_circuits (Circuit *circuit) { + if (circuit->netlist () != this) { + throw tl::Exception (tl::to_string (tr ("Circuit not within given netlist"))); + } + if (! m_valid_topology) { validate_topology (); } @@ -364,18 +372,39 @@ void Netlist::clear () void Netlist::add_circuit (Circuit *circuit) { + if (! circuit) { + return; + } + if (circuit->netlist ()) { + throw tl::Exception (tl::to_string (tr ("Circuit already contained in a netlist"))); + } + m_circuits.push_back (circuit); circuit->set_netlist (this); } void Netlist::remove_circuit (Circuit *circuit) { + if (! circuit) { + return; + } + if (circuit->netlist () != this) { + throw tl::Exception (tl::to_string (tr ("Circuit not within given netlist"))); + } + circuit->set_netlist (0); m_circuits.erase (circuit); } void Netlist::purge_circuit (Circuit *circuit) { + if (! circuit) { + return; + } + if (circuit->netlist () != this) { + throw tl::Exception (tl::to_string (tr ("Circuit not within given netlist"))); + } + circuit->blank (); remove_circuit (circuit); } @@ -406,7 +435,12 @@ void Netlist::flatten_circuits (const std::vector &circuits) void Netlist::flatten_circuit (Circuit *circuit) { - tl_assert (circuit != 0); + if (! circuit) { + return; + } + if (circuit->netlist () != this) { + throw tl::Exception (tl::to_string (tr ("Circuit not within given netlist"))); + } std::vector refs; for (db::Circuit::refs_iterator sc = circuit->begin_refs (); sc != circuit->end_refs (); ++sc) { @@ -448,24 +482,52 @@ DeviceClass *Netlist::device_class_by_name (const std::string &name) void Netlist::add_device_class (DeviceClass *device_class) { + if (! device_class) { + return; + } + if (device_class->netlist ()) { + throw tl::Exception (tl::to_string (tr ("Device class already contained in a netlist"))); + } + m_device_classes.push_back (device_class); device_class->set_netlist (this); } void Netlist::remove_device_class (DeviceClass *device_class) { + if (! device_class) { + return; + } + if (device_class->netlist () != this) { + throw tl::Exception (tl::to_string (tr ("Device class not within given netlist"))); + } + device_class->set_netlist (0); m_device_classes.erase (device_class); } void Netlist::add_device_abstract (DeviceAbstract *device_abstract) { + if (! device_abstract) { + return; + } + if (device_abstract->netlist ()) { + throw tl::Exception (tl::to_string (tr ("Device abstract already contained in a netlist"))); + } + m_device_abstracts.push_back (device_abstract); device_abstract->set_netlist (this); } void Netlist::remove_device_abstract (DeviceAbstract *device_abstract) { + if (! device_abstract) { + return; + } + if (device_abstract->netlist () != this) { + throw tl::Exception (tl::to_string (tr ("Device abstract not within given netlist"))); + } + device_abstract->set_netlist (0); m_device_abstracts.erase (device_abstract); } diff --git a/testdata/ruby/dbNetlist.rb b/testdata/ruby/dbNetlist.rb index 3fc2e64ce..c927e9dfb 100644 --- a/testdata/ruby/dbNetlist.rb +++ b/testdata/ruby/dbNetlist.rb @@ -68,9 +68,21 @@ class DBNetlist_TestClass < TestBase cc.dont_purge = true assert_equal(cc.dont_purge, true) + begin + nl.remove(cc) # not in netlist yet + assert_equal(false, true) + rescue + end + nl.add(cc) cc.name = "ABC" + begin + nl.add(cc) # already in netlist + assert_equal(false, true) + rescue + end + names = [] nl.each_circuit { |i| names << i.name } assert_equal(names, [ c.name, cc.name ]) @@ -119,9 +131,22 @@ class DBNetlist_TestClass < TestBase assert_equal(c.name, "XYZ") cc = RBA::GenericDeviceClass::new + + begin + nl.remove(cc) # not in netlist yet + assert_equal(false, true) + rescue + end + nl.add(cc) cc.name = "ABC" + begin + nl.add(cc) # already in netlist + assert_equal(false, true) + rescue + end + names = [] nl.each_device_class { |i| names << i.name } assert_equal(names, [ c.name, cc.name ])