From 6d0fe8542526d529f7ff893f8b529e2b60c722a0 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 11 Feb 2018 00:34:28 +0100 Subject: [PATCH 1/9] Fixed #75 (Python PCell issue when parameters are called 'layer') This commit - Ignores exceptions when checking for PCells that accept shapes. Hence a single rogue one does not break the feature. - Prevents errors when parameters named "layer" are present by making the implementation safe against this case. - In addition, guiding shape parameters of type "Path", "Box" etc. (i.e. integer types) are supported too although they are not recommended for portability. --- .../pcell_declaration_helper.lym | 15 ++++++-- src/db/db/dbPCellVariant.cc | 23 +++++++++++++ src/edt/edt/edtMainService.cc | 34 +++++++++++-------- 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/db/db/built-in-pymacros/pcell_declaration_helper.lym b/src/db/db/built-in-pymacros/pcell_declaration_helper.lym index 13abeb6c5..c69cbc74a 100644 --- a/src/db/db/built-in-pymacros/pcell_declaration_helper.lym +++ b/src/db/db/built-in-pymacros/pcell_declaration_helper.lym @@ -226,16 +226,27 @@ class _PCellDeclarationHelperLayerDescriptor(object): class _PCellDeclarationHelperParameterDescriptor(object): """ A descriptor object which translates the PCell parameters into class attributes + + In some cases (i.e. can_convert_from_shape), these placeholders are not + connected to real parameters (obj._param_values is None). In this case, + the descriptor acts as a value holder (self.value) """ def __init__(self, param_index): self.param_index = param_index + self.value = None def __get__(self, obj, type = None): - return obj._param_values[self.param_index] + if obj._param_values: + return obj._param_values[self.param_index] + else: + return self.value def __set__(self, obj, value): - obj._param_values[self.param_index] = value + if obj._param_values: + obj._param_values[self.param_index] = value + else: + self.value = value class _PCellDeclarationHelper(pya.PCellDeclaration): """ diff --git a/src/db/db/dbPCellVariant.cc b/src/db/db/dbPCellVariant.cc index 0430996f0..55f67a840 100644 --- a/src/db/db/dbPCellVariant.cc +++ b/src/db/db/dbPCellVariant.cc @@ -186,15 +186,28 @@ PCellVariant::update (ImportLayerMapping *layer_mapping) shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(db::Box (m_parameters[i].to_user () * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props))); + } else if (m_parameters[i].is_user ()) { + + shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(m_parameters[i].to_user (), layout ()->properties_repository ().properties_id (props))); + } else if (m_parameters[i].is_user ()) { shapes (layout ()->guiding_shape_layer ()).insert (db::EdgeWithProperties(db::Edge (m_parameters[i].to_user () * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props))); + } else if (m_parameters[i].is_user ()) { + + shapes (layout ()->guiding_shape_layer ()).insert (db::EdgeWithProperties(m_parameters[i].to_user (), layout ()->properties_repository ().properties_id (props))); + } else if (m_parameters[i].is_user ()) { db::DPoint p = m_parameters[i].to_user (); shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(db::Box (db::DBox (p, p) * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props))); + } else if (m_parameters[i].is_user ()) { + + db::Point p = m_parameters[i].to_user (); + shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(db::Box (p, p), layout ()->properties_repository ().properties_id (props))); + } else if (m_parameters[i].is_user ()) { db::complex_trans dbu_trans (1.0 / layout ()->dbu ()); @@ -202,11 +215,21 @@ PCellVariant::update (ImportLayerMapping *layer_mapping) // Hint: we don't compress the polygon since we don't want to loose information shapes (layout ()->guiding_shape_layer ()).insert (db::PolygonWithProperties(poly, layout ()->properties_repository ().properties_id (props))); + } else if (m_parameters[i].is_user ()) { + + db::Polygon poly = m_parameters[i].to_user (); + // Hint: we don't compress the polygon since we don't want to loose information + shapes (layout ()->guiding_shape_layer ()).insert (db::PolygonWithProperties(poly, layout ()->properties_repository ().properties_id (props))); + } else if (m_parameters[i].is_user ()) { db::complex_trans dbu_trans (1.0 / layout ()->dbu ()); shapes (layout ()->guiding_shape_layer ()).insert (db::PathWithProperties(dbu_trans * m_parameters[i].to_user (), layout ()->properties_repository ().properties_id (props))); + } else if (m_parameters[i].is_user ()) { + + shapes (layout ()->guiding_shape_layer ()).insert (db::PathWithProperties(m_parameters[i].to_user (), layout ()->properties_repository ().properties_id (props))); + } } diff --git a/src/edt/edt/edtMainService.cc b/src/edt/edt/edtMainService.cc index 59bf0a572..0d98f3872 100644 --- a/src/edt/edt/edtMainService.cc +++ b/src/edt/edt/edtMainService.cc @@ -1084,23 +1084,29 @@ MainService::cm_convert_to_pcell () db::Library *lib = db::LibraryManager::instance ().lib (l->second); for (db::Layout::pcell_iterator pc = lib->layout ().begin_pcells (); pc != lib->layout ().end_pcells (); ++pc) { - const db::PCellDeclaration *pc_decl = lib->layout ().pcell_declaration (pc->second); - size_t n = 1000; // 1000 tries max. - for (std::vector::const_iterator es = edt_services.begin (); n > 0 && pc_decl && es != edt_services.end (); ++es) { - for (edt::Service::obj_iterator s = (*es)->selection ().begin (); n > 0 && pc_decl && s != (*es)->selection ().end (); ++s) { - const lay::CellView &cv = view ()->cellview (s->cv_index ()); - if (pc_decl->can_create_from_shape (cv->layout (), s->shape (), s->layer ())) { - --n; - } else { - pc_decl = 0; // stop + try { + + const db::PCellDeclaration *pc_decl = lib->layout ().pcell_declaration (pc->second); + size_t n = 1000; // 1000 tries max. + for (std::vector::const_iterator es = edt_services.begin (); n > 0 && pc_decl && es != edt_services.end (); ++es) { + for (edt::Service::obj_iterator s = (*es)->selection ().begin (); n > 0 && pc_decl && s != (*es)->selection ().end (); ++s) { + const lay::CellView &cv = view ()->cellview (s->cv_index ()); + if (pc_decl->can_create_from_shape (cv->layout (), s->shape (), s->layer ())) { + --n; + } else { + pc_decl = 0; // stop + } } } - } - // We have positive hit - if (pc_decl) { - pcells.push_back (std::make_pair (lib, pc->second)); - items.push_back (tl::to_qstring (lib->get_name () + "." + pc_decl->name ())); + // We have positive hit + if (pc_decl) { + pcells.push_back (std::make_pair (lib, pc->second)); + items.push_back (tl::to_qstring (lib->get_name () + "." + pc_decl->name ())); + } + + } catch (...) { + // ignore errors in can_create_from_shape } } From 5d59b890d33fccebf891218cc033e51c450a6c7c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 12 Feb 2018 22:04:03 +0100 Subject: [PATCH 2/9] Small bugfix: DRC error message on wrong '@' input/output was wrong. --- src/drc/drc/built-in-macros/drc.lym | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/drc/drc/built-in-macros/drc.lym b/src/drc/drc/built-in-macros/drc.lym index 3f103f38c..a86fb5121 100644 --- a/src/drc/drc/built-in-macros/drc.lym +++ b/src/drc/drc/built-in-macros/drc.lym @@ -3922,9 +3922,9 @@ CODE n = $1.to_i - 1 view = RBA::LayoutView::current view || raise("No view open") - (n >= 0 && view.cellviews > n) || raise("Invalid layout index @#{n}") + (n >= 0 && view.cellviews > n) || raise("Invalid layout index @#{n + 1}") cv = view.cellview(n) - cv.is_valid? || raise("Invalid layout @#{n}") + cv.is_valid? || raise("Invalid layout @#{n + 1}") @def_source = make_source(cv.layout, cv.cell) else layout = RBA::Layout::new @@ -4016,9 +4016,9 @@ CODE n = $1.to_i - 1 view = RBA::LayoutView::current view || raise("No view open") - (n >= 0 && view.cellviews > n) || raise("Invalid layout index @#{n}") + (n >= 0 && view.cellviews > n) || raise("Invalid layout index @#{n + 1}") cv = view.cellview(n) - cv.is_valid? || raise("Invalid layout @#{n}") + cv.is_valid? || raise("Invalid layout @#{n + 1}") return make_source(cv.layout, cv.cell) else layout = RBA::Layout::new @@ -4173,9 +4173,9 @@ CODE n = $1.to_i - 1 view = RBA::LayoutView::current view || raise("No view open") - (n >= 0 && view.cellviews > n) || raise("Invalid layout index @#{n}") + (n >= 0 && view.cellviews > n) || raise("Invalid layout index @#{n + 1}") cv = view.cellview(n) - cv.is_valid? || raise("Invalid layout @#{n}") + cv.is_valid? || raise("Invalid layout @#{n + 1}") @output_layout = cv.layout @output_cell = cellname ? (@output_layout.cell(cellname.to_s) || @output_layout.create_cell(cellname.to_s)) : cv.cell @output_layout_file = nil From 4f3b205d93e8f9163b293600170c9099a357ec7a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 12 Feb 2018 22:46:47 +0100 Subject: [PATCH 3/9] Fixed #71 (target cell argument is required) --- src/drc/drc/built-in-macros/drc.lym | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/drc/drc/built-in-macros/drc.lym b/src/drc/drc/built-in-macros/drc.lym index a86fb5121..514b59a4d 100644 --- a/src/drc/drc/built-in-macros/drc.lym +++ b/src/drc/drc/built-in-macros/drc.lym @@ -4694,11 +4694,20 @@ CODE else - output = @output_layout || @def_layout - output || raise("No output layout specified") - - output_cell = @output_cell || @def_cell - output_cell || raise("No output cell specified") + if @output_layout + output = @output_layout + if @output_cell + output_cell = @output_cell + elsif @def_cell + output_cell = @output_layout.cell(@def_cell.name) || @output_layout.create_cell(@def_cell.name) + end + output_cell || raise("No output cell specified (see 'target' instruction)") + else + output = @def_layout + output || raise("No output layout specified") + output_cell = @output_cell || @def_cell + output_cell || raise("No output cell specified") + end info = nil if args.size == 1 From 12bb664a80e50d154b5a50ec636efb0f0a36c400 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 13 Feb 2018 00:09:54 +0100 Subject: [PATCH 4/9] Fixed the default implementation of transformation_from_shape in Python --- src/db/db/built-in-pymacros/pcell_declaration_helper.lym | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/db/built-in-pymacros/pcell_declaration_helper.lym b/src/db/db/built-in-pymacros/pcell_declaration_helper.lym index c69cbc74a..22a175075 100644 --- a/src/db/db/built-in-pymacros/pcell_declaration_helper.lym +++ b/src/db/db/built-in-pymacros/pcell_declaration_helper.lym @@ -443,7 +443,7 @@ class _PCellDeclarationHelper(pya.PCellDeclaration): """ default implementation """ - return pya.Trans.new + return pya.Trans() # import the Type... constants from PCellParameterDeclaration for k in dir(pya.PCellParameterDeclaration): From f6f75cd7912526cf06031e6bbb47641164d23540 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 13 Feb 2018 00:59:11 +0100 Subject: [PATCH 5/9] A small rework of the Python PCell helpers The aim of this rework was to enable PCell implementations that use the basic methods rather than the "_impl" variants. For the latter, potential variable name clashes happen when parameters are called "cell", "layout", "layer" or similar. New methods enable implementation on the level of the non-"impl" methods. For example: def produce(self, layout, layers, parameters, cell): self.init_values(parameters, layers) ... self.finish() --- .../pcell_declaration_helper.lym | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/src/db/db/built-in-pymacros/pcell_declaration_helper.lym b/src/db/db/built-in-pymacros/pcell_declaration_helper.lym index 22a175075..f0b6c0003 100644 --- a/src/db/db/built-in-pymacros/pcell_declaration_helper.lym +++ b/src/db/db/built-in-pymacros/pcell_declaration_helper.lym @@ -332,7 +332,38 @@ class _PCellDeclarationHelper(pya.PCellDeclaration): gets the parameters """ return self._param_decls + + def get_values(self): + """ + gets the temporary parameter values + """ + v = self._param_values + self._param_values = None + return v + def init_values(self, values = None, layers = None): + """ + initializes the temporary parameter values + "values" are the original values. If "None" is given, the + default values will be used. + "layers" are the layer indexes corresponding to the layer + parameters. + """ + if not values: + self._param_values = [] + for pd in self._param_decls: + self._param_values.append(pd.default) + else: + self._param_values = values + self._layers = layers + + def finish(self): + """ + Needs to be called at the end of produce() after init_values was used + """ + self._param_values = None + self._layers = None + def get_layers(self, parameters): """ get the layer definitions @@ -346,25 +377,23 @@ class _PCellDeclarationHelper(pya.PCellDeclaration): """ coerce parameters (make consistent) """ - self._param_values = parameters + self.init_values(parameters) self.layout = layout self.coerce_parameters_impl() self.layout = None - return self._param_values + return self.get_values() def produce(self, layout, layers, parameters, cell): """ coerce parameters (make consistent) """ - self._layers = layers + self.init_values(parameters, layers) self.cell = cell - self._param_values = parameters self.layout = layout self.produce_impl() - self._layers = None self.cell = None - self._param_values = None self.layout = None + self.finish() def can_create_from_shape(self, layout, shape, layer): """ @@ -397,9 +426,7 @@ class _PCellDeclarationHelper(pya.PCellDeclaration): produce a helper for parameters_from_shape with this helper, the implementation can use the parameter setters """ - self._param_values = [] - for pd in self._param_decls: - self._param_values.append(pd.default) + self.init_values() self.layout = layout self.shape = shape self.layer = layer @@ -407,7 +434,7 @@ class _PCellDeclarationHelper(pya.PCellDeclaration): self.layout = None self.shape = None self.layer = None - return self._param_values + return self.get_values() def display_text_impl(self): """ From 6052a0442995680d28a528cefdee927483e92f89 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 17 Feb 2018 01:26:25 +0100 Subject: [PATCH 6/9] A few enhancements and unit tests for PCells This commit adds unit tests for implementation helper-based PCells in Python and Ruby. --- .../pcell_declaration_helper.lym | 20 +++ .../pcell_declaration_helper.lym | 5 +- testdata/python/dbPCells.py | 138 ++++++++++++++- testdata/ruby/dbPCells.rb | 159 +++++++++++++++++- 4 files changed, 311 insertions(+), 11 deletions(-) diff --git a/src/db/db/built-in-macros/pcell_declaration_helper.lym b/src/db/db/built-in-macros/pcell_declaration_helper.lym index 0c8497f0b..b0674e5b2 100644 --- a/src/db/db/built-in-macros/pcell_declaration_helper.lym +++ b/src/db/db/built-in-macros/pcell_declaration_helper.lym @@ -183,6 +183,13 @@ to create the \\LayerInfo object, i.e. like this: The default implementation does nothing. All parameters not set in this method will receive their default value. +If you use a parameter called "layer" for example, the parameter getter will hide the +"layer" argument. Use "_layer" for the argument in this case (same for "layout", "shape" or "cell): + +@code + set_layer layout.get_info(_layer) +@/code + @method transformation_from_shape_impl @brief Gets the initial PCell instance transformation when creating from a shape @@ -230,6 +237,13 @@ module RBA # provide accessors for the current layout and cell (for prod) attr_reader :layout, :cell, :shape, :layer + + # provide fallback accessors in case of a name clash with a + # parameter + def _layer; @layer; end + def _layout; @layout; end + def _cell; @cell; end + def _shape; @shape; end # define a parameter # name -> the short name of the parameter @@ -246,6 +260,12 @@ module RBA # set_{name} -> write accessor ({name}= does not work because the # Ruby confuses that method with variables) # {name}_layer -> read accessor for the layer index for TypeLayer parameters + # in addition, fallback accessors are defined which can be used if + # the parameter's name clashes with another name: + # param_{name} + # set_param_{name} + # param_{name}_layer + def param(name, type, description, args = {}) # create accessor methods for the parameters diff --git a/src/db/db/built-in-pymacros/pcell_declaration_helper.lym b/src/db/db/built-in-pymacros/pcell_declaration_helper.lym index f0b6c0003..f867865dc 100644 --- a/src/db/db/built-in-pymacros/pcell_declaration_helper.lym +++ b/src/db/db/built-in-pymacros/pcell_declaration_helper.lym @@ -26,7 +26,7 @@ class MyPCell(pya.PCellDeclarationHelper): def __init__(self): # Important: initialize the super class - super(Circle, self).__init__() + super(MyPCell, self).__init__() # your initialization: add parameters with name, type, description and # optional other values @@ -431,10 +431,11 @@ class _PCellDeclarationHelper(pya.PCellDeclaration): self.shape = shape self.layer = layer self.parameters_from_shape_impl() + param = self.get_values() self.layout = None self.shape = None self.layer = None - return self.get_values() + return param def display_text_impl(self): """ diff --git a/testdata/python/dbPCells.py b/testdata/python/dbPCells.py index 686df2e88..27a80057b 100644 --- a/testdata/python/dbPCells.py +++ b/testdata/python/dbPCells.py @@ -52,20 +52,25 @@ class BoxPCell(pya.PCellDeclaration): # create the shape cell.shapes(layers[0]).insert(pya.Box(-w / 2, -h / 2, w / 2, h / 2)) + + def can_create_from_shape(self, layout, shape, layer): + return shape.is_box() + + def transformation_from_shape(self, layout, shape, layer): + return pya.Trans(shape.box.center() - pya.Point()) + + def parameters_from_shape(self, layout, shape, layer): + return [ layout.get_info(layer), shape.box.width() * layout.dbu, shape.box.height() * layout.dbu ] - class PCellTestLib(pya.Library): - boxpcell = None - def __init__(self): # set the description self.description = "PCell test lib" # create the PCell declarations - boxpcell = BoxPCell() - self.layout().register_pcell("Box", boxpcell) + self.layout().register_pcell("Box", BoxPCell()) sb_index = self.layout().add_cell("StaticBox") l10 = self.layout().insert_layer(pya.LayerInfo(10, 0)) @@ -75,6 +80,60 @@ class PCellTestLib(pya.Library): # register us with the name "MyLib" self.register("PCellTestLib") + +# A PCell based on the declaration helper + +class BoxPCell2(pya.PCellDeclarationHelper): + + def __init__(self): + + super(BoxPCell2, self).__init__() + + self.param("layer", self.TypeLayer, "Layer", default = pya.LayerInfo(0, 0)) + self.param("width", self.TypeDouble, "Width", default = 1.0) + self.param("height", self.TypeDouble, "Height", default = 1.0) + + def display_text_impl(self): + # provide a descriptive text for the cell + return "Box2(L=" + str(self.layer) + ",W=" + ('%.3f' % self.width) + ",H=" + ('%.3f' % self.height) + ")" + + def produce_impl(self): + + dbu = self.layout.dbu + + # fetch the parameters + l = self.layer_layer + w = self.width / self.layout.dbu + h = self.height / self.layout.dbu + + # create the shape + self.cell.shapes(l).insert(pya.Box(-w / 2, -h / 2, w / 2, h / 2)) + + def can_create_from_shape_impl(self): + return self.shape.is_box() + + def transformation_from_shape_impl(self): + return pya.Trans(self.shape.box.center() - pya.Point()) + + def parameters_from_shape_impl(self): + self.layer = self.layout.get_info(self.layer) + self.width = self.shape.box.width() * self.layout.dbu + self.height = self.shape.box.height() * self.layout.dbu + +class PCellTestLib2(pya.Library): + + def __init__(self): + + # set the description + self.description = "PCell test lib2" + + # create the PCell declarations + self.layout().register_pcell("Box2", BoxPCell2()) + + # register us with the name "MyLib" + self.register("PCellTestLib2") + + def inspect_LayerInfo(self): return "<" + str(self) + ">" @@ -233,6 +292,75 @@ class DBPCellTests(unittest.TestCase): pcell_inst.cell_index = new_id self.assertEqual(ly.begin_shapes(c1.cell_index(), li1).shape().__str__(), "box (-500,-100;500,100)") + l10 = ly.layer(10, 0) + c1.shapes(l10).insert(pya.Box(0, 10, 100, 210)) + l11 = ly.layer(11, 0) + c1.shapes(l11).insert(pya.Text("hello", pya.Trans())) + self.assertEqual(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l11).shape(), l10), False) + self.assertEqual(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10), True) + self.assertEqual(repr(pcell_decl.parameters_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10)), "[<10/0>, 1.0, 2.0]") + self.assertEqual(str(pcell_decl.transformation_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10)), "r0 50,110") + + + def test_1a(self): + + # instantiate and register the library + tl = PCellTestLib2() + + ly = pya.Layout(True) + ly.dbu = 0.01 + + li1 = find_layer(ly, "1/0") + self.assertEqual(li1 == None, True) + + ci1 = ly.add_cell("c1") + c1 = ly.cell(ci1) + + lib = pya.Library.library_by_name("PCellTestLib2") + self.assertEqual(lib != None, True) + pcell_decl = lib.layout().pcell_declaration("Box2") + + param = [ pya.LayerInfo(1, 0) ] # rest is filled with defaults + pcell_var_id = ly.add_pcell_variant(lib, pcell_decl.id(), param) + pcell_var = ly.cell(pcell_var_id) + pcell_inst = c1.insert(pya.CellInstArray(pcell_var_id, pya.Trans())) + self.assertEqual(pcell_var.basic_name(), "Box2") + self.assertEqual(pcell_var.pcell_parameters().__repr__(), "[<1/0>, 1.0, 1.0]") + self.assertEqual(pcell_var.display_title(), "PCellTestLib2.Box2(L=1/0,W=1.000,H=1.000)") + self.assertEqual(nh(pcell_var.pcell_parameters_by_name()), "{'height': 1.0, 'layer': <1/0>, 'width': 1.0}") + self.assertEqual(pcell_var.pcell_parameter("height").__repr__(), "1.0") + self.assertEqual(c1.pcell_parameters(pcell_inst).__repr__(), "[<1/0>, 1.0, 1.0]") + self.assertEqual(nh(c1.pcell_parameters_by_name(pcell_inst)), "{'height': 1.0, 'layer': <1/0>, 'width': 1.0}") + self.assertEqual(c1.pcell_parameter(pcell_inst, "height").__repr__(), "1.0") + self.assertEqual(nh(pcell_inst.pcell_parameters_by_name()), "{'height': 1.0, 'layer': <1/0>, 'width': 1.0}") + self.assertEqual(pcell_inst["height"].__repr__(), "1.0") + self.assertEqual(pcell_inst.pcell_parameter("height").__repr__(), "1.0") + self.assertEqual(pcell_var.pcell_declaration().__repr__(), pcell_decl.__repr__()) + self.assertEqual(c1.pcell_declaration(pcell_inst).__repr__(), pcell_decl.__repr__()) + self.assertEqual(pcell_inst.pcell_declaration().__repr__(), pcell_decl.__repr__()) + + li1 = find_layer(ly, "1/0") + self.assertEqual(li1 == None, False) + pcell_inst.change_pcell_parameter("height", 2.0) + self.assertEqual(nh(pcell_inst.pcell_parameters_by_name()), "{'height': 2.0, 'layer': <1/0>, 'width': 1.0}") + + self.assertEqual(ly.begin_shapes(c1.cell_index(), li1).shape().__str__(), "box (-50,-100;50,100)") + + param = { "layer": pya.LayerInfo(2, 0), "width": 2, "height": 1 } + li2 = ly.layer(2, 0) + c1.change_pcell_parameters(pcell_inst, param) + self.assertEqual(ly.begin_shapes(c1.cell_index(), li2).shape().__str__(), "box (-100,-50;100,50)") + + l10 = ly.layer(10, 0) + c1.shapes(l10).insert(pya.Box(0, 10, 100, 210)) + l11 = ly.layer(11, 0) + c1.shapes(l11).insert(pya.Text("hello", pya.Trans())) + self.assertEqual(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l11).shape(), l10), False) + self.assertEqual(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10), True) + self.assertEqual(repr(pcell_decl.parameters_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10)), "[<10/0>, 1.0, 2.0]") + self.assertEqual(str(pcell_decl.transformation_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10)), "r0 50,110") + + def test_2(self): # instantiate and register the library diff --git a/testdata/ruby/dbPCells.rb b/testdata/ruby/dbPCells.rb index 938c0d1f6..1f3e30950 100644 --- a/testdata/ruby/dbPCells.rb +++ b/testdata/ruby/dbPCells.rb @@ -61,6 +61,18 @@ class BoxPCell < RBA::PCellDeclaration end + def can_create_from_shape(layout, shape, layer) + return shape.is_box? + end + + def transformation_from_shape(layout, shape, layer) + return RBA::Trans::new(shape.box.center - RBA::Point::new) + end + + def parameters_from_shape(layout, shape, layer) + return [ layout.get_info(layer), shape.box.width * layout.dbu, shape.box.height * layout.dbu ] + end + end class PCellTestLib < RBA::Library @@ -85,6 +97,72 @@ class PCellTestLib < RBA::Library end +# A PCell based on the declaration helper + +class BoxPCell2 < RBA::PCellDeclarationHelper + + def initialize + + super() + + param("layer", BoxPCell2::TypeLayer, "Layer", :default => RBA::LayerInfo::new(0, 0)) + param("width", BoxPCell2::TypeDouble, "Width", :default => 1.0) + param("height", BoxPCell2::TypeDouble, "Height", :default => 1.0) + + end + + def display_text_impl + # provide a descriptive text for the cell + return "Box2(L=" + layer.to_s + ",W=" + ('%.3f' % width) + ",H=" + ('%.3f' % height) + ")" + end + + def produce_impl + + # fetch the parameters + l = layer_layer + w = width / layout.dbu + h = height / layout.dbu + + # create the shape + cell.shapes(l).insert(RBA::Box::new(-w / 2, -h / 2, w / 2, h / 2)) + + end + + def can_create_from_shape_impl + return self.shape.is_box? + end + + def transformation_from_shape_impl + return RBA::Trans::new(shape.box.center - RBA::Point::new) + end + + def parameters_from_shape_impl + # NOTE: because there is one parameter called "layer" already, we need to use + # the "_layer" fallback to access the argument to this method + set_layer(_layout.get_info(_layer)) + set_width(shape.box.width * _layout.dbu) + set_height(shape.box.height * _layout.dbu) + end + +end + +class PCellTestLib2 < RBA::Library + + def initialize + + # set the description + description = "PCell test lib2" + + # create the PCell declarations + layout.register_pcell("Box2", BoxPCell2::new) + + # register us with the name "MyLib" + self.register("PCellTestLib2") + + end + +end + # A helper for testing: provide an inspect method class RBA::LayerInfo def inspect @@ -115,8 +193,7 @@ class DBPCell_TestClass < TestBase ly = RBA::Layout::new(true) ly.dbu = 0.01 - li1 = ly.layer_indices.find { |li| ly.get_info(li).to_s == "1/0" } - assert_equal(li1 == nil, true) + li1 = ly.layer(1, 0) ci1 = ly.add_cell("c1") c1 = ly.cell(ci1) @@ -241,10 +318,84 @@ class DBPCell_TestClass < TestBase pcell_inst.cell_index = new_id assert_equal(ly.begin_shapes(c1.cell_index, li1).shape.to_s, "box (-500,-100;500,100)") -#ly.destroy + l10 = ly.layer(10, 0) + c1.shapes(l10).insert(RBA::Box::new(0, 10, 100, 210)) + l11 = ly.layer(11, 0) + c1.shapes(l11).insert(RBA::Text::new("hello", RBA::Trans::new)) + assert_equal(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l11).shape(), l10), false) + assert_equal(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10), true) + assert_equal(pcell_decl.parameters_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10).inspect, "[<10/0>, 1.0, 2.0]") + assert_equal(pcell_decl.transformation_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10).to_s, "r0 50,110") + + ly.destroy ensure -#tl.delete + tl.delete + end + + end + + def test_1a + + # instantiate and register the library + tl = PCellTestLib2::new + + begin + + ly = RBA::Layout::new(true) + ly.dbu = 0.01 + + ci1 = ly.add_cell("c1") + c1 = ly.cell(ci1) + + lib = RBA::Library.library_by_name("PCellTestLib2") + assert_equal(lib != nil, true) + pcell_decl = lib.layout().pcell_declaration("Box2") + + param = [ RBA::LayerInfo::new(1, 0) ] # rest is filled with defaults + pcell_var_id = ly.add_pcell_variant(lib, pcell_decl.id(), param) + pcell_var = ly.cell(pcell_var_id) + pcell_inst = c1.insert(RBA::CellInstArray::new(pcell_var_id, RBA::Trans::new)) + assert_equal(pcell_var.basic_name, "Box2") + assert_equal(pcell_var.pcell_parameters().inspect, "[<1/0>, 1.0, 1.0]") + assert_equal(pcell_var.display_title(), "PCellTestLib2.Box2(L=1/0,W=1.000,H=1.000)") + assert_equal(norm_hash(pcell_var.pcell_parameters_by_name()), "{\"height\"=>1.0, \"layer\"=><1/0>, \"width\"=>1.0}") + assert_equal(pcell_var.pcell_parameter("height").inspect(), "1.0") + assert_equal(c1.pcell_parameters(pcell_inst).inspect(), "[<1/0>, 1.0, 1.0]") + assert_equal(norm_hash(c1.pcell_parameters_by_name(pcell_inst)), "{\"height\"=>1.0, \"layer\"=><1/0>, \"width\"=>1.0}") + assert_equal(c1.pcell_parameter(pcell_inst, "height").inspect(), "1.0") + assert_equal(norm_hash(pcell_inst.pcell_parameters_by_name()), "{\"height\"=>1.0, \"layer\"=><1/0>, \"width\"=>1.0}") + assert_equal(pcell_inst["height"].inspect(), "1.0") + assert_equal(pcell_inst.pcell_parameter("height").inspect(), "1.0") + assert_equal(pcell_var.pcell_declaration().inspect(), pcell_decl.inspect) + assert_equal(c1.pcell_declaration(pcell_inst).inspect(), pcell_decl.inspect) + assert_equal(pcell_inst.pcell_declaration().inspect(), pcell_decl.inspect) + + li1 = ly.layer(1, 0) + assert_equal(li1 == nil, false) + pcell_inst.change_pcell_parameter("height", 2.0) + assert_equal(norm_hash(pcell_inst.pcell_parameters_by_name()), "{\"height\"=>2.0, \"layer\"=><1/0>, \"width\"=>1.0}") + + assert_equal(ly.begin_shapes(c1.cell_index(), li1).shape().to_s, "box (-50,-100;50,100)") + + param = { "layer" => RBA::LayerInfo::new(2, 0), "width" => 2, "height" => 1 } + li2 = ly.layer(2, 0) + c1.change_pcell_parameters(pcell_inst, param) + assert_equal(ly.begin_shapes(c1.cell_index(), li2).shape().to_s, "box (-100,-50;100,50)") + + l10 = ly.layer(10, 0) + c1.shapes(l10).insert(RBA::Box::new(0, 10, 100, 210)) + l11 = ly.layer(11, 0) + c1.shapes(l11).insert(RBA::Text::new("hello", RBA::Trans::new)) + assert_equal(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l11).shape(), l10), false) + assert_equal(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10), true) + assert_equal(pcell_decl.parameters_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10).inspect, "[<10/0>, 1.0, 2.0]") + assert_equal(pcell_decl.transformation_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10).to_s, "r0 50,110") + + ly.destroy + + ensure + tl.delete end end From 2f46f0d1c629b4e2de92321019019400f4510add Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 21 Feb 2018 00:21:19 +0100 Subject: [PATCH 7/9] Fixed some issues found with Coverity. --- src/ant/ant/gsiDeclAnt.cc | 2 +- src/db/db/dbOASISReader.cc | 30 ++++++- src/db/db/dbOASISReader.h | 1 + src/db/db/dbRecursiveShapeIterator.cc | 2 + src/db/unit_tests/dbObject.cc | 2 + src/ext/ext/extNetTracerIO.cc | 2 +- src/ext/ext/extRS274XApertures.cc | 84 ++++++------------- src/ext/ext/extRS274XApertures.h | 1 + src/gsi/gsi/gsiMethods.h | 1 - src/img/img/imgObject.cc | 2 + src/lay/lay/layProgress.cc | 10 ++- src/lay/lay/laySaltGrainPropertiesDialog.cc | 2 +- .../laybasic/gsiDeclLayTechnologies.cc | 2 +- src/laybasic/laybasic/layQtTools.cc | 12 +-- src/laybasic/laybasic/layTechnology.cc | 32 +++++-- src/laybasic/laybasic/layTechnology.h | 19 ++++- src/lym/lym/lymMacro.cc | 34 ++++---- src/pya/pya/pya.cc | 6 +- src/rdb/rdb/rdb.h | 2 +- src/tl/tl/tlIntervalMap.h | 2 +- src/tl/tl/tlThreadedWorkers.cc | 19 +++-- src/tl/tl/tlVariant.cc | 2 +- 22 files changed, 153 insertions(+), 116 deletions(-) diff --git a/src/ant/ant/gsiDeclAnt.cc b/src/ant/ant/gsiDeclAnt.cc index 61e407f06..65298eceb 100644 --- a/src/ant/ant/gsiDeclAnt.cc +++ b/src/ant/ant/gsiDeclAnt.cc @@ -1035,7 +1035,7 @@ public: value_type operator* () const { - return value_type (*(dynamic_cast (m_iter->first->ptr ())), m_services[m_service]->view ()); + return value_type (*(static_cast (m_iter->first->ptr ())), m_services[m_service]->view ()); } private: diff --git a/src/db/db/dbOASISReader.cc b/src/db/db/dbOASISReader.cc index 1edcec995..844a0024b 100644 --- a/src/db/db/dbOASISReader.cc +++ b/src/db/db/dbOASISReader.cc @@ -110,6 +110,18 @@ OASISReader::OASISReader (tl::InputStream &s) { m_progress.set_format (tl::to_string (QObject::tr ("%.0f MB"))); m_progress.set_unit (1024 * 1024); + m_first_cellname = 0; + m_first_propname = 0; + m_first_propstring = 0; + m_first_textstring = 0; + m_first_layername = 0; + m_in_table = NotInTable; + m_table_cellname = 0; + m_table_propname = 0; + m_table_propstring = 0; + m_table_textstring = 0; + m_table_layername = 0; + m_table_start = 0; } OASISReader::~OASISReader () @@ -197,6 +209,16 @@ OASISReader::get_long () } } +inline unsigned long +OASISReader::get_ulong_for_divider () +{ + unsigned long l = get_ulong (); + if (l == 0) { + error (tl::to_string (QObject::tr ("Divider must not be zero"))); + } + return l; +} + inline unsigned long OASISReader::get_ulong () { @@ -295,21 +317,21 @@ OASISReader::get_real () } else if (t == 2) { - return 1.0 / double (get_ulong ()); + return 1.0 / double (get_ulong_for_divider ()); } else if (t == 3) { - return -1.0 / double (get_ulong ()); + return -1.0 / double (get_ulong_for_divider ()); } else if (t == 4) { double d = double (get_ulong ()); - return d / double (get_ulong ()); + return d / double (get_ulong_for_divider ()); } else if (t == 5) { double d = double (get_ulong ()); - return -d / double (get_ulong ()); + return -d / double (get_ulong_for_divider ()); } else if (t == 6) { diff --git a/src/db/db/dbOASISReader.h b/src/db/db/dbOASISReader.h index 60f04aeda..26487ef68 100644 --- a/src/db/db/dbOASISReader.h +++ b/src/db/db/dbOASISReader.h @@ -318,6 +318,7 @@ private: unsigned long long get_ulong_long (); long get_long (); unsigned long get_ulong (); + unsigned long get_ulong_for_divider (); int get_int (); unsigned int get_uint (); diff --git a/src/db/db/dbRecursiveShapeIterator.cc b/src/db/db/dbRecursiveShapeIterator.cc index bd6718522..7281b9861 100644 --- a/src/db/db/dbRecursiveShapeIterator.cc +++ b/src/db/db/dbRecursiveShapeIterator.cc @@ -276,6 +276,8 @@ RecursiveShapeIterator::init () m_shape_inv_prop_sel = false; m_inst_quad_id = 0; m_shape_quad_id = 0; + mp_cell = 0; + m_current_layer = 0; } void diff --git a/src/db/unit_tests/dbObject.cc b/src/db/unit_tests/dbObject.cc index 0ecf9195b..a8d03d968 100644 --- a/src/db/unit_tests/dbObject.cc +++ b/src/db/unit_tests/dbObject.cc @@ -58,6 +58,7 @@ struct A : public db::Object void redo (db::Op *op) throw () { AO *aop = dynamic_cast (op); + tl_assert (aop != 0); x += aop->d; } @@ -162,6 +163,7 @@ struct B : public db::Object void redo (db::Op *op) throw () { BO *bop = dynamic_cast (op); + tl_assert (bop != 0); x += bop->d; } diff --git a/src/ext/ext/extNetTracerIO.cc b/src/ext/ext/extNetTracerIO.cc index 761271dd2..22d9ef3fb 100644 --- a/src/ext/ext/extNetTracerIO.cc +++ b/src/ext/ext/extNetTracerIO.cc @@ -1092,7 +1092,7 @@ Net::Net () } Net::Net (const NetTracer &tracer, const db::ICplxTrans &trans, const db::Layout &layout, db::cell_index_type cell_index, const std::string &layout_filename, const std::string &layout_name, const NetTracerData &data) - : m_name (tracer.name ()), m_incomplete (tracer.incomplete ()) + : m_name (tracer.name ()), m_incomplete (tracer.incomplete ()), m_trace_path (false) { m_dbu = layout.dbu (); m_top_cell_name = layout.cell_name (cell_index); diff --git a/src/ext/ext/extRS274XApertures.cc b/src/ext/ext/extRS274XApertures.cc index 0a42d40ea..d232293c9 100644 --- a/src/ext/ext/extRS274XApertures.cc +++ b/src/ext/ext/extRS274XApertures.cc @@ -607,11 +607,30 @@ RS274XMacroAperture::do_produce_flash () } } +void +RS274XMacroAperture::read_exposure (tl::Extractor &ex, bool &clear, bool &clear_set) +{ + int pol = int (floor (read_expr (ex) + 0.5)); + + if (pol == 0) { + clear = true; + } else if (pol == 1) { + clear = false; + } else if (pol == 2) { + clear = !clear_set || !clear; + } else { + throw tl::Exception (tl::to_string (QObject::tr ("Invalid exposure code '%d'")), pol); + } + + clear_set = true; +} + void RS274XMacroAperture::do_produce_flash_internal () { tl::Extractor ex (m_def.c_str ()); bool clear = false; + bool clear_set = false; while (! ex.at_end ()) { @@ -640,18 +659,7 @@ RS274XMacroAperture::do_produce_flash_internal () if (code == 1) { ex.expect (","); - int pol = (read_expr (ex) > 0.5); - - if (pol == 0) { - clear = true; - } else if (pol == 1) { - clear = false; - } else if (pol == 2) { - clear = !clear; - } else { - throw tl::Exception (tl::to_string (QObject::tr ("Invalid exposure code '%d'")), pol); - } - + read_exposure (ex, clear, clear_set); ex.expect (","); double d = read_expr (ex, true); ex.expect (","); @@ -670,18 +678,7 @@ RS274XMacroAperture::do_produce_flash_internal () } else if (code == 2 || code == 20) { ex.expect (","); - int pol = (read_expr (ex) > 0.5); - - if (pol == 0) { - clear = true; - } else if (pol == 1) { - clear = false; - } else if (pol == 2) { - clear = !clear; - } else { - throw tl::Exception (tl::to_string (QObject::tr ("Invalid exposure code '%d'")), pol); - } - + read_exposure (ex, clear, clear_set); ex.expect (","); double w = read_expr (ex, true); ex.expect (","); @@ -723,18 +720,7 @@ RS274XMacroAperture::do_produce_flash_internal () } else if (code == 21 || code == 22) { ex.expect (","); - int pol = (read_expr (ex) > 0.5); - - if (pol == 0) { - clear = true; - } else if (pol == 1) { - clear = false; - } else if (pol == 2) { - clear = !clear; - } else { - throw tl::Exception (tl::to_string (QObject::tr ("Invalid exposure code '%d'")), pol); - } - + read_exposure (ex, clear, clear_set); ex.expect (","); double w = read_expr (ex, true); ex.expect (","); @@ -766,18 +752,7 @@ RS274XMacroAperture::do_produce_flash_internal () } else if (code == 4) { ex.expect (","); - int pol = (read_expr (ex) > 0.5); - - if (pol == 0) { - clear = true; - } else if (pol == 1) { - clear = false; - } else if (pol == 2) { - clear = !clear; - } else { - throw tl::Exception (tl::to_string (QObject::tr ("Invalid exposure code '%d'")), pol); - } - + read_exposure (ex, clear, clear_set); ex.expect (","); int n = int (read_expr (ex) + 0.5); if (n < 1) { @@ -854,18 +829,7 @@ RS274XMacroAperture::do_produce_flash_internal () } else if (code == 5) { ex.expect (","); - int pol = (read_expr (ex) > 0.5); - - if (pol == 0) { - clear = true; - } else if (pol == 1) { - clear = false; - } else if (pol == 2) { - clear = !clear; - } else { - throw tl::Exception (tl::to_string (QObject::tr ("Invalid exposure code '%d'")), pol); - } - + read_exposure (ex, clear, clear_set); ex.expect (","); int n = int (read_expr (ex) + 0.5); if (n < 3) { diff --git a/src/ext/ext/extRS274XApertures.h b/src/ext/ext/extRS274XApertures.h index 969a1d710..78fa02ac6 100644 --- a/src/ext/ext/extRS274XApertures.h +++ b/src/ext/ext/extRS274XApertures.h @@ -168,6 +168,7 @@ private: double read_atom (tl::Extractor &ex); double read_dot_expr (tl::Extractor &ex); double read_expr (tl::Extractor &ex, bool length = false); + void read_exposure (tl::Extractor &ex, bool &clear, bool &clear_set); void do_produce_flash_internal (); }; diff --git a/src/gsi/gsi/gsiMethods.h b/src/gsi/gsi/gsiMethods.h index c0deceef9..d4bb408bd 100644 --- a/src/gsi/gsi/gsiMethods.h +++ b/src/gsi/gsi/gsiMethods.h @@ -524,7 +524,6 @@ private: ArgType m_ret_type; bool m_const : 1; bool m_static : 1; - bool m_is_predicate : 1; bool m_protected : 1; unsigned int m_argsize; std::vector m_method_synonyms; diff --git a/src/img/img/imgObject.cc b/src/img/img/imgObject.cc index c4c1e9b2f..eb45a1668 100644 --- a/src/img/img/imgObject.cc +++ b/src/img/img/imgObject.cc @@ -697,12 +697,14 @@ static size_t make_id () Object::Object () : m_trans (1.0), mp_data (0), m_id (make_id ()), m_min_value (0.0), m_max_value (1.0), m_min_value_set (false), m_max_value_set (false), m_visible (true), m_z_position (0) { + m_updates_enabled = false; mp_pixel_data = 0; } Object::Object (size_t w, size_t h, const db::DCplxTrans &trans, bool color) : m_trans (trans), m_id (make_id ()), m_min_value (0.0), m_max_value (1.0), m_min_value_set (false), m_max_value_set (false), m_visible (true), m_z_position (0) { + m_updates_enabled = false; mp_pixel_data = 0; mp_data = new DataHeader (w, h, color, false); diff --git a/src/lay/lay/layProgress.cc b/src/lay/lay/layProgress.cc index 219473fa5..daefbaff1 100644 --- a/src/lay/lay/layProgress.cc +++ b/src/lay/lay/layProgress.cc @@ -211,10 +211,12 @@ ProgressReporter::set_visible (bool vis) // actual operation tl::DeferredMethodScheduler::enable (!vis); - if (!vis) { - mp_pb->progress_remove_widget (); - } else if (mp_pb->progress_wants_widget () && mp_objects.front ()) { - mp_pb->progress_add_widget (mp_objects.front ()->progress_widget ()); + if (mp_pb) { + if (!vis) { + mp_pb->progress_remove_widget (); + } else if (mp_pb->progress_wants_widget () && mp_objects.front ()) { + mp_pb->progress_add_widget (mp_objects.front ()->progress_widget ()); + } } m_pw_visible = vis; diff --git a/src/lay/lay/laySaltGrainPropertiesDialog.cc b/src/lay/lay/laySaltGrainPropertiesDialog.cc index 809d953e4..336f041c4 100644 --- a/src/lay/lay/laySaltGrainPropertiesDialog.cc +++ b/src/lay/lay/laySaltGrainPropertiesDialog.cc @@ -259,7 +259,7 @@ SaltGrainPropertiesDialog::dependency_changed (QTreeWidgetItem *item, int column m_update_enabled = false; std::string name = tl::to_string (item->data (0, Qt::UserRole).toString ().simplified ()); - SaltGrain *g = mp_salt->grain_by_name (name); + SaltGrain *g = mp_salt ? mp_salt->grain_by_name (name) : 0; if (column == 0 && mp_salt) { diff --git a/src/laybasic/laybasic/gsiDeclLayTechnologies.cc b/src/laybasic/laybasic/gsiDeclLayTechnologies.cc index acd9b6964..9ed316979 100644 --- a/src/laybasic/laybasic/gsiDeclLayTechnologies.cc +++ b/src/laybasic/laybasic/gsiDeclLayTechnologies.cc @@ -45,7 +45,7 @@ static lay::Technology *create_technology (const std::string &name) { lay::Technology *tech = new lay::Technology (); tech->set_name (name); - lay::Technologies::instance ()->add (tech); + lay::Technologies::instance ()->add_new (tech); return tech; } diff --git a/src/laybasic/laybasic/layQtTools.cc b/src/laybasic/laybasic/layQtTools.cc index d9d0751a9..f7642e8d7 100644 --- a/src/laybasic/laybasic/layQtTools.cc +++ b/src/laybasic/laybasic/layQtTools.cc @@ -88,11 +88,13 @@ save_dialog_state (QWidget *w) } - for (QList::const_iterator c = w->children ().begin (); c != w->children ().end (); ++c) { - if (dynamic_cast (*c)) { - std::string cs = save_dialog_state (dynamic_cast (*c)); - if (! cs.empty ()) { - s += cs; + if (w) { + for (QList::const_iterator c = w->children ().begin (); c != w->children ().end (); ++c) { + if (dynamic_cast (*c)) { + std::string cs = save_dialog_state (dynamic_cast (*c)); + if (! cs.empty ()) { + s += cs; + } } } } diff --git a/src/laybasic/laybasic/layTechnology.cc b/src/laybasic/laybasic/layTechnology.cc index 0ff8b044d..8934cb547 100644 --- a/src/laybasic/laybasic/layTechnology.cc +++ b/src/laybasic/laybasic/layTechnology.cc @@ -45,6 +45,8 @@ Technologies::Technologies () Technologies::Technologies (const Technologies &other) : tl::Object () { + m_changed = false; + m_in_update = false; operator= (other); } @@ -115,19 +117,30 @@ Technologies::load_from_xml (const std::string &s) } void -Technologies::add (Technology *technology) +Technologies::add_tech (Technology *tech, bool replace_same) { - for (tl::stable_vector::iterator t = m_technologies.begin (); technology && t != m_technologies.end (); ++t) { - if (t->name () == technology->name ()) { - *t = *technology; - delete technology; - technology = 0; + if (! tech) { + return; + } + + std::auto_ptr tech_ptr (tech); + + Technology *t = 0; + for (tl::stable_vector::iterator i = m_technologies.begin (); !t && i != m_technologies.end (); ++i) { + if (i->name () == tech->name ()) { + t = i.operator-> (); } } - if (technology) { - m_technologies.push_back (technology); - technology->technology_changed_with_sender_event.add (this, &Technologies::technology_changed); + if (t) { + if (replace_same) { + *t = *tech; + } else { + throw tl::Exception (tl::to_string (QObject::tr ("A technology with this name already exists: %1").arg (tl::to_qstring (tech->name ())))); + } + } else { + m_technologies.push_back (tech_ptr.release ()); + tech->technology_changed_with_sender_event.add (this, &Technologies::technology_changed); } technologies_changed (); @@ -218,6 +231,7 @@ Technologies::technology_by_name (const std::string &name) } } + tl_assert (! m_technologies.empty ()); return &*m_technologies.begin (); } diff --git a/src/laybasic/laybasic/layTechnology.h b/src/laybasic/laybasic/layTechnology.h index 03f2ddc55..a7d130c7d 100644 --- a/src/laybasic/laybasic/layTechnology.h +++ b/src/laybasic/laybasic/layTechnology.h @@ -126,7 +126,22 @@ public: * The container becomes owner of the technology object. * Replaces a technology with the name of the given technology. */ - void add (Technology *technology); + void add (Technology *technology) + { + add_tech (technology, true /*replace*/); + } + + /** + * @brief Adds a technology with a new name + * + * Like \add, but throws an exception if a technology with this name + * already exists. Takes over ownership over the technology object. + * The technology object is discarded if an exception is thrown. + */ + void add_new (Technology *technology) + { + add_tech (technology, false /*throws exception on same name*/); + } /** * @brief Remove a technology with the given name from the setup @@ -233,6 +248,8 @@ private: tl::stable_vector m_technologies; bool m_changed; bool m_in_update; + + void add_tech (Technology *technology, bool replace_same); }; /** diff --git a/src/lym/lym/lymMacro.cc b/src/lym/lym/lymMacro.cc index 4f76d32e2..e6c64c658 100644 --- a/src/lym/lym/lymMacro.cc +++ b/src/lym/lym/lymMacro.cc @@ -915,26 +915,28 @@ void Macro::install_doc () const if (cls == 0) { tl::error << tl::to_string (QObject::tr ("Reading class doc from ")) << path () << ": " << tl::to_string (QObject::tr ("@method without preceeding @class")); - } + } else { - std::string n; - ex.read_word_or_quoted (n); + std::string n; + ex.read_word_or_quoted (n); - std::string doc; - while (++i < lines.size ()) { - std::string l = tl::trim (lines [i]); - if (l.find ("@method") == 0 || l.find ("@static_method") == 0) { - break; + std::string doc; + while (++i < lines.size ()) { + std::string l = tl::trim (lines [i]); + if (l.find ("@method") == 0 || l.find ("@static_method") == 0) { + break; + } + if (! doc.empty ()) { + doc += "\n"; + } + doc += lines [i]; } - if (! doc.empty ()) { - doc += "\n"; - } - doc += lines [i]; - } - --i; + --i; - ExternalMethod *meth = new ExternalMethod (n, doc, false, st); - cls->add_method (meth); + ExternalMethod *meth = new ExternalMethod (n, doc, false, st); + cls->add_method (meth); + + } } diff --git a/src/pya/pya/pya.cc b/src/pya/pya/pya.cc index c2d3ebac4..4bcce316e 100644 --- a/src/pya/pya/pya.cc +++ b/src/pya/pya/pya.cc @@ -1945,7 +1945,11 @@ property_setter_impl (int mid, PyObject *self, PyObject *value) if (meth->is_signal ()) { - if (PyObject_IsInstance (value, (PyObject *) PYASignal::cls)) { + if (!p) { + + // TODO: Static signals? + + } else if (PyObject_IsInstance (value, (PyObject *) PYASignal::cls)) { // assigning a signal to a signal works if it applies to the same handler - // this simplifies the implementation of += and -=. diff --git a/src/rdb/rdb/rdb.h b/src/rdb/rdb/rdb.h index 44029f3f0..ae401399f 100644 --- a/src/rdb/rdb/rdb.h +++ b/src/rdb/rdb/rdb.h @@ -495,7 +495,7 @@ public: bool compare (const ValueBase *other) const { - return m_value < dynamic_cast *> (other)->m_value; + return m_value < static_cast *> (other)->m_value; } std::string to_string () const; diff --git a/src/tl/tl/tlIntervalMap.h b/src/tl/tl/tlIntervalMap.h index ed477748a..194d0e5ce 100644 --- a/src/tl/tl/tlIntervalMap.h +++ b/src/tl/tl/tlIntervalMap.h @@ -213,7 +213,7 @@ public: ++lb0; } --lb; - if (lb != m_index_map.end () && i2 < lb->first.second) { + if (i2 < lb->first.second) { // the last one is overlapping above i2: cut it lb->first.first = i2; } else { diff --git a/src/tl/tl/tlThreadedWorkers.cc b/src/tl/tl/tlThreadedWorkers.cc index 648afcfb6..16a3e7c5a 100644 --- a/src/tl/tl/tlThreadedWorkers.cc +++ b/src/tl/tl/tlThreadedWorkers.cc @@ -424,17 +424,20 @@ JobBase::schedule (Task *task) { m_lock.lock (); - // Don't allow tasks to be scheduled while stopping or exiting (waiting for m_queue_empty_condition) if (m_stopping) { - m_lock.unlock (); - throw TaskTerminatedException (); - } - // Add the task to the task queue - m_task_list.put (task); + // Don't allow tasks to be scheduled while stopping or exiting (waiting for m_queue_empty_condition) + delete task; + + } else { + + // Add the task to the task queue + m_task_list.put (task); + + if (m_running) { + m_task_available_condition.wakeAll (); + } - if (m_running) { - m_task_available_condition.wakeAll (); } m_lock.unlock (); diff --git a/src/tl/tl/tlVariant.cc b/src/tl/tl/tlVariant.cc index b1b73dff0..d223ab537 100644 --- a/src/tl/tl/tlVariant.cc +++ b/src/tl/tl/tlVariant.cc @@ -1298,7 +1298,7 @@ Variant::can_convert_to_long () const case t_double: return m_var.m_double <= std::numeric_limits::max () && m_var.m_double >= std::numeric_limits::min (); case t_float: - return m_var.m_float <= std::numeric_limits::max () && m_var.m_float >= std::numeric_limits::min (); + return m_var.m_float <= float (std::numeric_limits::max ()) && m_var.m_float >= float (std::numeric_limits::min ()); #if defined(HAVE_64BIT_COORD) case t_int128: return m_var.m_int128 <= __int128 (std::numeric_limits::max ()) && m_var.m_int128 >= __int128 (std::numeric_limits::min ()); From a272ba39a7ff4850c088e96c1eb55c195882117c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 21 Feb 2018 07:47:02 +0100 Subject: [PATCH 8/9] Remove a debug output. --- src/ant/ant/antObject.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ant/ant/antObject.cc b/src/ant/ant/antObject.cc index a67b54a14..686224fc9 100644 --- a/src/ant/ant/antObject.cc +++ b/src/ant/ant/antObject.cc @@ -343,7 +343,6 @@ Object::class_name () const void Object::from_string (const char *s) { -printf("@@@ %s\n", s); fflush(stdout); tl::Extractor ex (s); while (! ex.at_end ()) { From 5f4e715dcf27ad3ea8ac8e95f93f6565fbc854c4 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 21 Feb 2018 07:47:41 +0100 Subject: [PATCH 9/9] Fixed #77 (copy_tree should work in non-editable mode too) --- src/db/db/gsiDeclDbCell.cc | 39 - testdata/ruby/dbLayout.rb | 1623 +++++++++++++++++------------------- 2 files changed, 778 insertions(+), 884 deletions(-) diff --git a/src/db/db/gsiDeclDbCell.cc b/src/db/db/gsiDeclDbCell.cc index 31433cfb0..bdc97c797 100644 --- a/src/db/db/gsiDeclDbCell.cc +++ b/src/db/db/gsiDeclDbCell.cc @@ -883,8 +883,6 @@ static bool cell_has_prop_id (const db::Cell *c) static void delete_cell_property (db::Cell *c, const tl::Variant &key) { - check_is_editable (c); - db::properties_id_type id = c->prop_id (); if (id == 0) { return; @@ -911,8 +909,6 @@ static void delete_cell_property (db::Cell *c, const tl::Variant &key) static void set_cell_property (db::Cell *c, const tl::Variant &key, const tl::Variant &value) { - check_is_editable (c); - db::properties_id_type id = c->prop_id (); db::Layout *layout = c->layout (); @@ -1110,13 +1106,11 @@ static void move_or_copy_from_other_cell (db::Cell *cell, db::Cell *src_cell, un static void move_from_other_cell (db::Cell *cell, db::Cell *src_cell, unsigned int src_layer, unsigned int dest_layer) { - check_is_editable (cell); move_or_copy_from_other_cell (cell, src_cell, src_layer, dest_layer, true); } static void copy_from_other_cell (db::Cell *cell, db::Cell *src_cell, unsigned int src_layer, unsigned int dest_layer) { - check_is_editable (cell); move_or_copy_from_other_cell (cell, src_cell, src_layer, dest_layer, false); } @@ -1158,7 +1152,6 @@ write_options (const db::Cell *cell, const std::string &filename, const db::Save static void clear_all (db::Cell *cell) { - check_is_editable (cell); cell->clear_shapes (); cell->clear_insts (); } @@ -1166,7 +1159,6 @@ clear_all (db::Cell *cell) static void delete_cell (db::Cell *cell) { - check_is_editable (cell); db::Layout *layout = cell->layout (); if (layout) { layout->delete_cell (cell->cell_index ()); @@ -1176,7 +1168,6 @@ delete_cell (db::Cell *cell) static void prune_subcells (db::Cell *cell, int levels) { - check_is_editable (cell); db::Layout *layout = cell->layout (); if (layout) { layout->prune_subcells (cell->cell_index (), levels); @@ -1192,7 +1183,6 @@ prune_subcells0 (db::Cell *cell) static void prune_cell (db::Cell *cell, int levels) { - check_is_editable (cell); db::Layout *layout = cell->layout (); if (layout) { layout->prune_cell (cell->cell_index (), levels); @@ -1208,7 +1198,6 @@ prune_cell0 (db::Cell *cell) static void flatten (db::Cell *cell, int levels, bool prune) { - check_is_editable (cell); db::Layout *layout = cell->layout (); if (layout) { layout->flatten (*cell, levels, prune); @@ -1288,8 +1277,6 @@ begin_shapes_rec_overlapping_um (const db::Cell *cell, unsigned int layer, db::D static void copy_shapes2 (db::Cell *cell, const db::Cell &source_cell, const db::LayerMapping &layer_mapping) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot copy shapes within the same cell"))); } @@ -1318,8 +1305,6 @@ static void copy_shapes2 (db::Cell *cell, const db::Cell &source_cell, const db: static void copy_shapes1 (db::Cell *cell, const db::Cell &source_cell) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot copy shapes within the same cell"))); } @@ -1344,8 +1329,6 @@ static void copy_shapes1 (db::Cell *cell, const db::Cell &source_cell) static void copy_instances (db::Cell *cell, const db::Cell &source_cell) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot copy instances within the same cell"))); } @@ -1360,8 +1343,6 @@ static void copy_instances (db::Cell *cell, const db::Cell &source_cell) static std::vector copy_tree (db::Cell *cell, const db::Cell &source_cell) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot copy shapes within the same cell"))); } @@ -1393,8 +1374,6 @@ static std::vector copy_tree (db::Cell *cell, const db::Cel static void copy_tree_shapes2 (db::Cell *cell, const db::Cell &source_cell, const db::CellMapping &cm) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot copy shapes within the same cell"))); } @@ -1421,8 +1400,6 @@ static void copy_tree_shapes2 (db::Cell *cell, const db::Cell &source_cell, cons static void copy_tree_shapes3 (db::Cell *cell, const db::Cell &source_cell, const db::CellMapping &cm, const db::LayerMapping &lm) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot copy shapes within the same cell"))); } @@ -1446,8 +1423,6 @@ static void copy_tree_shapes3 (db::Cell *cell, const db::Cell &source_cell, cons static void move_shapes2 (db::Cell *cell, db::Cell &source_cell, const db::LayerMapping &layer_mapping) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot move shapes within the same cell"))); } @@ -1478,8 +1453,6 @@ static void move_shapes2 (db::Cell *cell, db::Cell &source_cell, const db::Layer static void move_shapes1 (db::Cell *cell, db::Cell &source_cell) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot move shapes within the same cell"))); } @@ -1505,8 +1478,6 @@ static void move_shapes1 (db::Cell *cell, db::Cell &source_cell) static void move_instances (db::Cell *cell, db::Cell &source_cell) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot move instances within the same cell"))); } @@ -1523,8 +1494,6 @@ static void move_instances (db::Cell *cell, db::Cell &source_cell) static std::vector move_tree (db::Cell *cell, db::Cell &source_cell) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot move shapes within the same cell"))); } @@ -1558,8 +1527,6 @@ static std::vector move_tree (db::Cell *cell, db::Cell &sou static void move_tree_shapes2 (db::Cell *cell, db::Cell &source_cell, const db::CellMapping &cm) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot move shapes within the same cell"))); } @@ -1586,8 +1553,6 @@ static void move_tree_shapes2 (db::Cell *cell, db::Cell &source_cell, const db:: static void move_tree_shapes3 (db::Cell *cell, db::Cell &source_cell, const db::CellMapping &cm, const db::LayerMapping &lm) { - check_is_editable (cell); - if (cell == &source_cell) { throw tl::Exception (tl::to_string (QObject::tr ("Cannot move shapes within the same cell"))); } @@ -1612,8 +1577,6 @@ static void move_tree_shapes3 (db::Cell *cell, db::Cell &source_cell, const db:: static void fill_region1 (db::Cell *cell, const db::Region &fr, db::cell_index_type fill_cell_index, const db::Box &fc_box, const db::Point *origin) { - check_is_editable (cell); - if (fc_box.empty () || fc_box.width () == 0 || fc_box.height () == 0) { throw tl::Exception (tl::to_string (QObject::tr ("Invalid fill cell footprint (empty or zero width/height)"))); } @@ -1624,8 +1587,6 @@ static void fill_region2 (db::Cell *cell, const db::Region &fr, db::cell_index_type fill_cell_index, const db::Box &fc_box, const db::Point *origin, db::Region *remaining_parts, const db::Vector &fill_margin, db::Region *remaining_polygons) { - check_is_editable (cell); - if (fc_box.empty () || fc_box.width () == 0 || fc_box.height () == 0) { throw tl::Exception (tl::to_string (QObject::tr ("Invalid fill cell footprint (empty or zero width/height)"))); } diff --git a/testdata/ruby/dbLayout.rb b/testdata/ruby/dbLayout.rb index 3bd511982..7a49fe621 100644 --- a/testdata/ruby/dbLayout.rb +++ b/testdata/ruby/dbLayout.rb @@ -488,443 +488,415 @@ END def test_5a - if RBA::Application::instance.is_editable? + # delete_cell + + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) + assert_equal(c0.is_empty?, true) - # delete_cell - - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) - assert_equal(c0.is_empty?, true) + tt = RBA::Trans.new + c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(c0.is_empty?, false) - tt = RBA::Trans.new - c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - assert_equal(c0.is_empty?, false) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); + c0_index = c0.cell_index + assert_equal(l.is_valid_cell_index?(c0_index), true) + l.delete_cell(c0.cell_index) + assert_equal(l.is_valid_cell_index?(c0_index), false) - c0_index = c0.cell_index - assert_equal(l.is_valid_cell_index?(c0_index), true) - l.delete_cell(c0.cell_index) - assert_equal(l.is_valid_cell_index?(c0_index), false) + assert_equal(collect_hier(l), "[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c2)(C=)"); + assert_equal(c3.is_empty?, true) - assert_equal(collect_hier(l), "[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c2)(C=)"); - assert_equal(c3.is_empty?, true) + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) + assert_equal(c0.is_empty?, true) - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) - assert_equal(c0.is_empty?, true) + tt = RBA::Trans.new + c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(c0.is_empty?, false) - tt = RBA::Trans.new - c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - assert_equal(c0.is_empty?, false) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); + c0_index = c0.cell_index + assert_equal(l.is_valid_cell_index?(c0_index), true) + l.cell(c0_index).delete + assert_equal(l.is_valid_cell_index?(c0_index), false) - c0_index = c0.cell_index - assert_equal(l.is_valid_cell_index?(c0_index), true) - l.cell(c0_index).delete - assert_equal(l.is_valid_cell_index?(c0_index), false) - - assert_equal(collect_hier(l), "[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c2)(C=)"); - assert_equal(c3.is_empty?, true) - - end + assert_equal(collect_hier(l), "[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c2)(C=)"); + assert_equal(c3.is_empty?, true) end def test_5b - if RBA::Application::instance.is_editable? + # delete_cells + + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - # delete_cells - - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) + assert_equal(c0.is_empty?, false) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) - assert_equal(c0.is_empty?, false) + tt = RBA::Trans.new + c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); + c0_index = c0.cell_index + c2_index = c2.cell_index - c0_index = c0.cell_index - c2_index = c2.cell_index + ll = l.dup - ll = l.dup + l.delete_cells([c0_index, c2_index]) + assert_equal(collect_hier(l), "[c1](P=)(C=)/[c3](P=)(C=)"); - l.delete_cells([c0_index, c2_index]) - assert_equal(collect_hier(l), "[c1](P=)(C=)/[c3](P=)(C=)"); - - l = ll - # Hint: even though we deleted c0 and c2, their indices are still valid - l.delete_cells([c2_index, c0_index]) - assert_equal(collect_hier(l), "[c1](P=)(C=)/[c3](P=)(C=)"); - - end + l = ll + # Hint: even though we deleted c0 and c2, their indices are still valid + l.delete_cells([c2_index, c0_index]) + assert_equal(collect_hier(l), "[c1](P=)(C=)/[c3](P=)(C=)"); end def test_5d - # TODO: undo tests crashes in non-editable mode! Should be checked properly. - if RBA::Application::instance.is_editable? + # prune_cell + + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - # prune_cell - - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) + tt = RBA::Trans.new + c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); + c0_index = c0.cell_index + c2_index = c2.cell_index - c0_index = c0.cell_index - c2_index = c2.cell_index + ll = l.dup - ll = l.dup + l.prune_cell(c0_index, -1) + assert_equal(collect_hier(l), ""); - l.prune_cell(c0_index, -1) - assert_equal(collect_hier(l), ""); + l = ll + ll = l.dup + # Hint: even though we deleted c0 and c2, their indices are still valid + l.prune_cell(c2_index, -1) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c3)/[c1](P=c0)(C=)/[c3](P=c0)(C=)"); - l = ll - ll = l.dup - # Hint: even though we deleted c0 and c2, their indices are still valid - l.prune_cell(c2_index, -1) - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c3)/[c1](P=c0)(C=)/[c3](P=c0)(C=)"); + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) + tt = RBA::Trans.new + c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); + c0_index = c0.cell_index + c2_index = c2.cell_index - c0_index = c0.cell_index - c2_index = c2.cell_index + ll = l.dup - ll = l.dup + l.cell(c0_index).prune_cell + assert_equal(collect_hier(l), ""); - l.cell(c0_index).prune_cell - assert_equal(collect_hier(l), ""); - - l = ll - ll = l.dup - # Hint: even though we deleted c0 and c2, their indices are still valid - l.cell(c2_index).prune_cell(-1) - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c3)/[c1](P=c0)(C=)/[c3](P=c0)(C=)"); - - end + l = ll + ll = l.dup + # Hint: even though we deleted c0 and c2, their indices are still valid + l.cell(c2_index).prune_cell(-1) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c3)/[c1](P=c0)(C=)/[c3](P=c0)(C=)"); end def test_5e - # TODO: undo tests crashes in non-editable mode! Should be checked properly. - if RBA::Application::instance.is_editable? + # delete_cell_rec + + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - # delete_cell_rec - - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) + tt = RBA::Trans.new + c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); + c0_index = c0.cell_index + c2_index = c2.cell_index - c0_index = c0.cell_index - c2_index = c2.cell_index + ll = l.dup - ll = l.dup + l.delete_cell_rec(c0_index) + assert_equal(collect_hier(l), ""); - l.delete_cell_rec(c0_index) - assert_equal(collect_hier(l), ""); - - l = ll - ll = l.dup - # Hint: even though we deleted c0 and c2, their indices are still valid - l.delete_cell_rec(c2_index) - assert_equal(collect_hier(l), "[c0](P=)(C=c1)/[c1](P=c0)(C=)"); - - end + l = ll + ll = l.dup + # Hint: even though we deleted c0 and c2, their indices are still valid + l.delete_cell_rec(c2_index) + assert_equal(collect_hier(l), "[c0](P=)(C=c1)/[c1](P=c0)(C=)"); end def test_5f - # TODO: undo tests crashes in non-editable mode! Should be checked properly. - if RBA::Application::instance.is_editable? + # delete_cell_rec + + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - # delete_cell_rec - - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) + tt = RBA::Trans.new + c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + c0_index = c0.cell_index + c2_index = c2.cell_index - c0_index = c0.cell_index - c2_index = c2.cell_index + ii = l.begin_shapes(c0_index, 0); + assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)"); - ii = l.begin_shapes(c0_index, 0); - assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)"); + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); + ll = l.dup - ll = l.dup + l.flatten(c0_index, -1, false) + assert_equal(collect_hier(l), "[c0](P=)(C=)/[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c2)(C=)"); - l.flatten(c0_index, -1, false) - assert_equal(collect_hier(l), "[c0](P=)(C=)/[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c2)(C=)"); + ii = l.begin_shapes(c0_index, 0); + assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](1200,0;2200,1100)/[c0](-1200,0;-100,1000)"); - ii = l.begin_shapes(c0_index, 0); - assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](1200,0;2200,1100)/[c0](-1200,0;-100,1000)"); + l = ll + ll = l.dup + l.flatten(c0_index, -1, true) + assert_equal(collect_hier(l), "[c0](P=)(C=)"); - l = ll - ll = l.dup - l.flatten(c0_index, -1, true) - assert_equal(collect_hier(l), "[c0](P=)(C=)"); + ii = l.begin_shapes(c0_index, 0); + assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](1200,0;2200,1100)/[c0](-1200,0;-100,1000)"); - ii = l.begin_shapes(c0_index, 0); - assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](1200,0;2200,1100)/[c0](-1200,0;-100,1000)"); + l = ll + ll = l.dup + l.flatten(c0_index, 0, false) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); - l = ll - ll = l.dup - l.flatten(c0_index, 0, false) - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); + ii = l.begin_shapes(c0_index, 0); + assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)"); - ii = l.begin_shapes(c0_index, 0); - assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)"); + l = ll + ll = l.dup + l.flatten(c0_index, 1, false) + assert_equal(collect_hier(l), "[c0](P=)(C=c3)/[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c0,c2)(C=)"); - l = ll - ll = l.dup - l.flatten(c0_index, 1, false) - assert_equal(collect_hier(l), "[c0](P=)(C=c3)/[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c0,c2)(C=)"); + ii = l.begin_shapes(c0_index, 0); + assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](-1200,0;-100,1000)/[c3](1200,0;2200,1100)"); - ii = l.begin_shapes(c0_index, 0); - assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](-1200,0;-100,1000)/[c3](1200,0;2200,1100)"); + l = ll + ll = l.dup + l.flatten(c0_index, 1, true) + assert_equal(collect_hier(l), "[c0](P=)(C=c3)/[c3](P=c0)(C=)"); - l = ll - ll = l.dup - l.flatten(c0_index, 1, true) - assert_equal(collect_hier(l), "[c0](P=)(C=c3)/[c3](P=c0)(C=)"); + l = ll + ll = l.dup - l = ll - ll = l.dup + l.cell(c0_index).flatten(false) + assert_equal(collect_hier(l), "[c0](P=)(C=)/[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c2)(C=)"); - l.cell(c0_index).flatten(false) - assert_equal(collect_hier(l), "[c0](P=)(C=)/[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c2)(C=)"); + ii = l.begin_shapes(c0_index, 0); + assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](1200,0;2200,1100)/[c0](-1200,0;-100,1000)"); - ii = l.begin_shapes(c0_index, 0); - assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](1200,0;2200,1100)/[c0](-1200,0;-100,1000)"); + l = ll + ll = l.dup + l.cell(c0_index).flatten(true) + assert_equal(collect_hier(l), "[c0](P=)(C=)"); - l = ll - ll = l.dup - l.cell(c0_index).flatten(true) - assert_equal(collect_hier(l), "[c0](P=)(C=)"); + ii = l.begin_shapes(c0_index, 0); + assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](1200,0;2200,1100)/[c0](-1200,0;-100,1000)"); - ii = l.begin_shapes(c0_index, 0); - assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](1200,0;2200,1100)/[c0](-1200,0;-100,1000)"); + l = ll + ll = l.dup + l.cell(c0_index).flatten(0, false) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); - l = ll - ll = l.dup - l.cell(c0_index).flatten(0, false) - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); + ii = l.begin_shapes(c0_index, 0); + assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)"); - ii = l.begin_shapes(c0_index, 0); - assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)"); + l = ll + ll = l.dup + l.cell(c0_index).flatten(1, false) + assert_equal(collect_hier(l), "[c0](P=)(C=c3)/[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c0,c2)(C=)"); - l = ll - ll = l.dup - l.cell(c0_index).flatten(1, false) - assert_equal(collect_hier(l), "[c0](P=)(C=c3)/[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c0,c2)(C=)"); + ii = l.begin_shapes(c0_index, 0); + assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](-1200,0;-100,1000)/[c3](1200,0;2200,1100)"); - ii = l.begin_shapes(c0_index, 0); - assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](-1200,0;-100,1000)/[c3](1200,0;2200,1100)"); + l = ll + ll = l.dup + l.cell(c0_index).flatten(1, true) + assert_equal(collect_hier(l), "[c0](P=)(C=c3)/[c3](P=c0)(C=)"); - l = ll - ll = l.dup - l.cell(c0_index).flatten(1, true) - assert_equal(collect_hier(l), "[c0](P=)(C=c3)/[c3](P=c0)(C=)"); + ii = l.cell(c0_index).begin_shapes_rec(0); + assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](-1200,0;-100,1000)/[c3](1200,0;2200,1100)"); - ii = l.cell(c0_index).begin_shapes_rec(0); - assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](-1200,0;-100,1000)/[c3](1200,0;2200,1100)"); - - ii = l.cell(c0_index).begin_shapes_rec(0); - assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](-1200,0;-100,1000)/[c3](1200,0;2200,1100)"); - - end + ii = l.cell(c0_index).begin_shapes_rec(0); + assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](-1200,0;-100,1000)/[c3](1200,0;2200,1100)"); end def test_5g - # TODO: undo tests crashes in non-editable mode! Should be checked properly. - if RBA::Application::instance.is_editable? + # prune_subcells + + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - # prune_subcells - - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) + tt = RBA::Trans.new + c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); + c0_index = c0.cell_index + c2_index = c2.cell_index - c0_index = c0.cell_index - c2_index = c2.cell_index + ll = l.dup - ll = l.dup + l.prune_subcells(c0_index, -1) + assert_equal(collect_hier(l), "[c0](P=)(C=)"); - l.prune_subcells(c0_index, -1) - assert_equal(collect_hier(l), "[c0](P=)(C=)"); + l = ll + ll = l.dup + # Hint: even though we deleted c0 and c2, their indices are still valid + l.prune_subcells(c2_index, -1) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=)/[c3](P=c0)(C=)"); - l = ll - ll = l.dup - # Hint: even though we deleted c0 and c2, their indices are still valid - l.prune_subcells(c2_index, -1) - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=)/[c3](P=c0)(C=)"); + l = ll + # Hint: even though we deleted c0 and c2, their indices are still valid + l.prune_subcells(c0_index, 1) + assert_equal(collect_hier(l), "[c0](P=)(C=)"); - l = ll - # Hint: even though we deleted c0 and c2, their indices are still valid - l.prune_subcells(c0_index, 1) - assert_equal(collect_hier(l), "[c0](P=)(C=)"); + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) + tt = RBA::Trans.new + c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)"); + c0_index = c0.cell_index + c2_index = c2.cell_index - c0_index = c0.cell_index - c2_index = c2.cell_index + ll = l.dup - ll = l.dup + l.cell(c0_index).prune_subcells + assert_equal(collect_hier(l), "[c0](P=)(C=)"); - l.cell(c0_index).prune_subcells - assert_equal(collect_hier(l), "[c0](P=)(C=)"); + l = ll + ll = l.dup + # Hint: even though we deleted c0 and c2, their indices are still valid + l.cell(c2_index).prune_subcells + assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=)/[c3](P=c0)(C=)"); - l = ll - ll = l.dup - # Hint: even though we deleted c0 and c2, their indices are still valid - l.cell(c2_index).prune_subcells - assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=)/[c3](P=c0)(C=)"); - - l = ll - # Hint: even though we deleted c0 and c2, their indices are still valid - l.cell(c0_index).prune_subcells(1) - assert_equal(collect_hier(l), "[c0](P=)(C=)"); - - end + l = ll + # Hint: even though we deleted c0 and c2, their indices are still valid + l.cell(c0_index).prune_subcells(1) + assert_equal(collect_hier(l), "[c0](P=)(C=)"); end @@ -1218,84 +1190,80 @@ END # copy shapes between cells - if RBA::Application::instance.is_editable? + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) + b = RBA::Box.new(1, 101, 1001, 1201) + s = c0.shapes(1).insert(b) + s.set_property("p", 17) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) - b = RBA::Box.new(1, 101, 1001, 1201) - s = c0.shapes(1).insert(b) - s.set_property("p", 17) + tt = RBA::Trans.new + c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") + c0c = l.cell(l.add_cell("c0")) + c0c.copy_shapes(c0) + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)") + assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") + assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) + + c0c.clear + lm = RBA::LayerMapping::new + lm.map(1, 0) + c0c.copy_shapes(c0, lm) + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](1,101;1001,1201)") + assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), 17) + assert_equal(collect(c0c.begin_shapes_rec(1), l), "") + assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), nil) - c0c = l.cell(l.add_cell("c0")) - c0c.copy_shapes(c0) - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)") - assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") - assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) - - c0c.clear - lm = RBA::LayerMapping::new - lm.map(1, 0) - c0c.copy_shapes(c0, lm) - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](1,101;1001,1201)") - assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), 17) - assert_equal(collect(c0c.begin_shapes_rec(1), l), "") - assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), nil) + l2 = RBA::Layout::new + l2.dbu = 0.0005 + c0c = l2.cell(l2.add_cell("c0")) - l2 = RBA::Layout::new - l2.dbu = 0.0005 - c0c = l2.cell(l2.add_cell("c0")) + c0c.copy_shapes(c0) + layer1 = l2.find_layer(1, 0) + layer2 = l2.find_layer(2, 0) + assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)") + assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") + assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) - c0c.copy_shapes(c0) - layer1 = l2.find_layer(1, 0) - layer2 = l2.find_layer(2, 0) - assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)") - assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") - assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) + l2 = RBA::Layout::new + l2.dbu = 0.0005 + c0c = l2.cell(l2.add_cell("c0")) - l2 = RBA::Layout::new - l2.dbu = 0.0005 - c0c = l2.cell(l2.add_cell("c0")) + lm = RBA::LayerMapping::new + lm.create(l2, l) + layer1 = l2.find_layer(1, 0) + assert_equal(layer1, nil) + layer2 = l2.find_layer(2, 0) + assert_equal(layer2, nil) - lm = RBA::LayerMapping::new - lm.create(l2, l) - layer1 = l2.find_layer(1, 0) - assert_equal(layer1, nil) - layer2 = l2.find_layer(2, 0) - assert_equal(layer2, nil) + lm.create_full(l2, l) - lm.create_full(l2, l) - - c0c.copy_shapes(c0, lm) - layer1 = l2.find_layer(1, 0) - layer2 = l2.find_layer(2, 0) - assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)") - assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") - assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) - - end + c0c.copy_shapes(c0, lm) + layer1 = l2.find_layer(1, 0) + layer2 = l2.find_layer(2, 0) + assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)") + assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") + assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) end @@ -1303,104 +1271,100 @@ END # move shapes between cells - if RBA::Application::instance.is_editable? + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) + b = RBA::Box.new(1, 101, 1001, 1201) + s = c0.shapes(1).insert(b) + s.set_property("p", 17) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) - b = RBA::Box.new(1, 101, 1001, 1201) - s = c0.shapes(1).insert(b) - s.set_property("p", 17) + tt = RBA::Trans.new + c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + ll = l.dup - ll = l.dup + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") + c0c = l.cell(l.add_cell("c0")) + c0c.move_shapes(c0) + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "") + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)") + assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") + assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) + c0.move_shapes(c0c) + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") + assert_equal(collect(c0c.begin_shapes_rec(0), l), "") + assert_equal(collect(c0c.begin_shapes_rec(1), l), "") + + lm = RBA::LayerMapping::new + lm.map(1, 0) + c0c.move_shapes(c0, lm) + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "") + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](1,101;1001,1201)") + assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), 17) + assert_equal(collect(c0c.begin_shapes_rec(1), l), "") + assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), nil) - c0c = l.cell(l.add_cell("c0")) - c0c.move_shapes(c0) - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "") - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)") - assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") - assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) - c0.move_shapes(c0c) - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") - assert_equal(collect(c0c.begin_shapes_rec(0), l), "") - assert_equal(collect(c0c.begin_shapes_rec(1), l), "") - - lm = RBA::LayerMapping::new - lm.map(1, 0) - c0c.move_shapes(c0, lm) - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "") - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](1,101;1001,1201)") - assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), 17) - assert_equal(collect(c0c.begin_shapes_rec(1), l), "") - assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), nil) + l = ll.dup + c0 = l.cell("c0") - l = ll.dup - c0 = l.cell("c0") + l2 = RBA::Layout::new + l2.dbu = 0.0005 + c0c = l2.cell(l2.add_cell("c0")) - l2 = RBA::Layout::new - l2.dbu = 0.0005 - c0c = l2.cell(l2.add_cell("c0")) + c0c.move_shapes(c0) + layer1 = l2.find_layer(1, 0) + layer2 = l2.find_layer(2, 0) + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "") + assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)") + assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") + assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) - c0c.move_shapes(c0) - layer1 = l2.find_layer(1, 0) - layer2 = l2.find_layer(2, 0) - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "") - assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)") - assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") - assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) + l = ll.dup + c0 = l.cell("c0") - l = ll.dup - c0 = l.cell("c0") + l2 = RBA::Layout::new + l2.dbu = 0.0005 + c0c = l2.cell(l2.add_cell("c0")) - l2 = RBA::Layout::new - l2.dbu = 0.0005 - c0c = l2.cell(l2.add_cell("c0")) + lm = RBA::LayerMapping::new + lm.create(l2, l) + layer1 = l2.find_layer(1, 0) + assert_equal(layer1, nil) + layer2 = l2.find_layer(2, 0) + assert_equal(layer2, nil) - lm = RBA::LayerMapping::new - lm.create(l2, l) - layer1 = l2.find_layer(1, 0) - assert_equal(layer1, nil) - layer2 = l2.find_layer(2, 0) - assert_equal(layer2, nil) + lm.create_full(l2, l) - lm.create_full(l2, l) - - c0c.move_shapes(c0, lm) - layer1 = l2.find_layer(1, 0) - layer2 = l2.find_layer(2, 0) - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "") - assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)") - assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") - assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) - - end + c0c.move_shapes(c0, lm) + layer1 = l2.find_layer(1, 0) + layer2 = l2.find_layer(2, 0) + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c1](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "") + assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)") + assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") + assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) end @@ -1408,55 +1372,51 @@ END # copy instances between cells - if RBA::Application::instance.is_editable? + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) + b = RBA::Box.new(1, 101, 1001, 1201) + s = c0.shapes(1).insert(b) + s.set_property("p", 17) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) - b = RBA::Box.new(1, 101, 1001, 1201) - s = c0.shapes(1).insert(b) - s.set_property("p", 17) + tt = RBA::Trans.new + i0 = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + i0.set_property("p", 17) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - i0 = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - i0.set_property("p", 17) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") + c0c = l.cell(l.add_cell("c0")) + c0c.copy_instances(c0) + i0 = nil + c0c.each_inst { |i| i.cell_index == c1.cell_index && i0 = i } + assert_equal(i0.property("p"), 17) + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") + assert_equal(collect(c0c.begin_shapes_rec(1), l), "") - c0c = l.cell(l.add_cell("c0")) + l2 = RBA::Layout::new + l2.dbu = 0.0005 + c0c = l2.cell(l2.add_cell("c0")) + err = false + begin c0c.copy_instances(c0) - i0 = nil - c0c.each_inst { |i| i.cell_index == c1.cell_index && i0 = i } - assert_equal(i0.property("p"), 17) - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") - assert_equal(collect(c0c.begin_shapes_rec(1), l), "") - - l2 = RBA::Layout::new - l2.dbu = 0.0005 - c0c = l2.cell(l2.add_cell("c0")) - err = false - begin - c0c.copy_instances(c0) - rescue => ex - err = true - end - assert_equal(err, true) - - end + rescue => ex + err = true + end + assert_equal(err, true) end @@ -1464,57 +1424,53 @@ END # move instances between cells - if RBA::Application::instance.is_editable? + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) + b = RBA::Box.new(1, 101, 1001, 1201) + s = c0.shapes(1).insert(b) + s.set_property("p", 17) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) - b = RBA::Box.new(1, 101, 1001, 1201) - s = c0.shapes(1).insert(b) - s.set_property("p", 17) + tt = RBA::Trans.new + i0 = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + i0.set_property("p", 17) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - i0 = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - i0.set_property("p", 17) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") + c0c = l.cell(l.add_cell("c0")) + c0c.move_instances(c0) + i0 = nil + c0c.each_inst { |i| i.cell_index == c1.cell_index && i0 = i } + assert_equal(i0.property("p"), 17) + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") + assert_equal(collect(c0c.begin_shapes_rec(1), l), "") + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") - c0c = l.cell(l.add_cell("c0")) - c0c.move_instances(c0) - i0 = nil - c0c.each_inst { |i| i.cell_index == c1.cell_index && i0 = i } - assert_equal(i0.property("p"), 17) - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") - assert_equal(collect(c0c.begin_shapes_rec(1), l), "") - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") - - l2 = RBA::Layout::new - l2.dbu = 0.0005 - c0c = l2.cell(l2.add_cell("c0")) - err = false - begin - c0c.copy_instances(c0) - rescue => ex - err = true - end - assert_equal(err, true) - - end + l2 = RBA::Layout::new + l2.dbu = 0.0005 + c0c = l2.cell(l2.add_cell("c0")) + err = false + begin + c0c.copy_instances(c0) + rescue => ex + err = true + end + assert_equal(err, true) end @@ -1522,62 +1478,58 @@ END # copy cell tree - if RBA::Application::instance.is_editable? + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + s = c1.shapes(0).insert(b) + s.set_property("p", 17) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) + b = RBA::Box.new(1, 101, 1001, 1201) + c0.shapes(1).insert(b) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - s = c1.shapes(0).insert(b) - s.set_property("p", 17) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) - b = RBA::Box.new(1, 101, 1001, 1201) - c0.shapes(1).insert(b) + tt = RBA::Trans.new + i0 = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + i0.set_property("p", 18) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - i0 = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - i0.set_property("p", 18) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") + c0c = l.cell(l.add_cell("c0")) + c0c.copy_tree(c0) - c0c = l.cell(l.add_cell("c0")) - c0c.copy_tree(c0) + i0 = nil + c0c.each_inst { |i| i.cell_index == l.cell("c1$1").cell_index && i0 = i } + assert_equal(i0.property("p"), 18) + assert_equal(l.cell("c1$1").begin_shapes_rec(0).shape.property("p"), 17) - i0 = nil - c0c.each_inst { |i| i.cell_index == l.cell("c1$1").cell_index && i0 = i } - assert_equal(i0.property("p"), 18) - assert_equal(l.cell("c1$1").begin_shapes_rec(0).shape.property("p"), 17) + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c2$1](100,0;1100,1100)/[c3$1](1200,0;2200,1100)/[c3$1](-1200,0;-100,1000)/[c1$1](0,100;1000,1200)") + assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c2$1](100,0;1100,1100)/[c3$1](1200,0;2200,1100)/[c3$1](-1200,0;-100,1000)/[c1$1](0,100;1000,1200)") - assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") + l2 = RBA::Layout::new + l2.dbu = 0.0005 + c0c = l2.cell(l2.add_cell("c0")) + c0c.copy_tree(c0) - l2 = RBA::Layout::new - l2.dbu = 0.0005 - c0c = l2.cell(l2.add_cell("c0")) - c0c.copy_tree(c0) + i0 = nil + c0c.each_inst { |i| i.cell_index == l2.cell("c1").cell_index && i0 = i } + assert_equal(i0.property("p"), 18) - i0 = nil - c0c.each_inst { |i| i.cell_index == l2.cell("c1").cell_index && i0 = i } - assert_equal(i0.property("p"), 18) - - layer1 = l2.find_layer(1, 0) - layer2 = l2.find_layer(2, 0) - assert_equal(l2.cell("c1").begin_shapes_rec(layer1).shape.property("p"), 17) - assert_equal(collect(c0c.begin_shapes_rec(layer1), l2), "[c0](0,200;2000,2400)/[c2](200,0;2200,2200)/[c3](2400,0;4400,2200)/[c3](-2400,0;-200,2000)/[c1](0,200;2000,2400)") - assert_equal(collect(c0c.begin_shapes_rec(layer2), l2), "[c0](2,202;2002,2402)") - - end + layer1 = l2.find_layer(1, 0) + layer2 = l2.find_layer(2, 0) + assert_equal(l2.cell("c1").begin_shapes_rec(layer1).shape.property("p"), 17) + assert_equal(collect(c0c.begin_shapes_rec(layer1), l2), "[c0](0,200;2000,2400)/[c2](200,0;2200,2200)/[c3](2400,0;4400,2200)/[c3](-2400,0;-200,2000)/[c1](0,200;2000,2400)") + assert_equal(collect(c0c.begin_shapes_rec(layer2), l2), "[c0](2,202;2002,2402)") end @@ -1585,80 +1537,76 @@ END # move cell tree - if RBA::Application::instance.is_editable? + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + s = c1.shapes(0).insert(b) + s.set_property("p", 17) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) + b = RBA::Box.new(1, 101, 1001, 1201) + c0.shapes(1).insert(b) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - s = c1.shapes(0).insert(b) - s.set_property("p", 17) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) - b = RBA::Box.new(1, 101, 1001, 1201) - c0.shapes(1).insert(b) + tt = RBA::Trans.new + i0 = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + i0.set_property("p", 18) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - i0 = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - i0.set_property("p", 18) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + ll = l.dup - ll = l.dup + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") + c0c = l.cell(l.add_cell("c0")) + c0c.move_tree(c0) + assert_equal(l.has_cell?("c0"), true) + assert_equal(l.has_cell?("c1"), false) + assert_equal(l.has_cell?("c2"), false) + assert_equal(l.has_cell?("c3"), false) - c0c = l.cell(l.add_cell("c0")) - c0c.move_tree(c0) - assert_equal(l.has_cell?("c0"), true) - assert_equal(l.has_cell?("c1"), false) - assert_equal(l.has_cell?("c2"), false) - assert_equal(l.has_cell?("c3"), false) + i0 = nil + c0c.each_inst { |i| i.cell_index == l.cell("c1$1").cell_index && i0 = i } + assert_equal(i0.property("p"), 18) + assert_equal(l.cell("c1$1").begin_shapes_rec(0).shape.property("p"), 17) - i0 = nil - c0c.each_inst { |i| i.cell_index == l.cell("c1$1").cell_index && i0 = i } - assert_equal(i0.property("p"), 18) - assert_equal(l.cell("c1$1").begin_shapes_rec(0).shape.property("p"), 17) + assert_equal(collect(c0.begin_shapes_rec(0), l), "") + assert_equal(collect(c0.begin_shapes_rec(1), l), "") + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c2$1](100,0;1100,1100)/[c3$1](1200,0;2200,1100)/[c3$1](-1200,0;-100,1000)/[c1$1](0,100;1000,1200)") + assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") - assert_equal(collect(c0.begin_shapes_rec(0), l), "") - assert_equal(collect(c0.begin_shapes_rec(1), l), "") - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c2$1](100,0;1100,1100)/[c3$1](1200,0;2200,1100)/[c3$1](-1200,0;-100,1000)/[c1$1](0,100;1000,1200)") - assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") + l = ll.dup + c0 = l.cell("c0") - l = ll.dup - c0 = l.cell("c0") + l2 = RBA::Layout::new + l2.dbu = 0.0005 + c0c = l2.cell(l2.add_cell("c0")) + c0c.move_tree(c0) - l2 = RBA::Layout::new - l2.dbu = 0.0005 - c0c = l2.cell(l2.add_cell("c0")) - c0c.move_tree(c0) + assert_equal(collect(c0.begin_shapes_rec(0), l), "") + assert_equal(collect(c0.begin_shapes_rec(1), l), "") + assert_equal(l.has_cell?("c0"), true) + assert_equal(l.has_cell?("c1"), false) + assert_equal(l.has_cell?("c2"), false) + assert_equal(l.has_cell?("c3"), false) - assert_equal(collect(c0.begin_shapes_rec(0), l), "") - assert_equal(collect(c0.begin_shapes_rec(1), l), "") - assert_equal(l.has_cell?("c0"), true) - assert_equal(l.has_cell?("c1"), false) - assert_equal(l.has_cell?("c2"), false) - assert_equal(l.has_cell?("c3"), false) + i0 = nil + c0c.each_inst { |i| i.cell_index == l2.cell("c1").cell_index && i0 = i } + assert_equal(i0.property("p"), 18) - i0 = nil - c0c.each_inst { |i| i.cell_index == l2.cell("c1").cell_index && i0 = i } - assert_equal(i0.property("p"), 18) - - layer1 = l2.find_layer(1, 0) - layer2 = l2.find_layer(2, 0) - assert_equal(l2.cell("c1").begin_shapes_rec(layer1).shape.property("p"), 17) - assert_equal(collect(c0c.begin_shapes_rec(layer1), l2), "[c0](0,200;2000,2400)/[c2](200,0;2200,2200)/[c3](2400,0;4400,2200)/[c3](-2400,0;-200,2000)/[c1](0,200;2000,2400)") - assert_equal(collect(c0c.begin_shapes_rec(layer2), l2), "[c0](2,202;2002,2402)") - - end + layer1 = l2.find_layer(1, 0) + layer2 = l2.find_layer(2, 0) + assert_equal(l2.cell("c1").begin_shapes_rec(layer1).shape.property("p"), 17) + assert_equal(collect(c0c.begin_shapes_rec(layer1), l2), "[c0](0,200;2000,2400)/[c2](200,0;2200,2200)/[c3](2400,0;4400,2200)/[c3](-2400,0;-200,2000)/[c1](0,200;2000,2400)") + assert_equal(collect(c0c.begin_shapes_rec(layer2), l2), "[c0](2,202;2002,2402)") end @@ -1666,83 +1614,79 @@ END # copy shapes between cell trees - if RBA::Application::instance.is_editable? + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) + b = RBA::Box.new(1, 101, 1001, 1201) + s = c0.shapes(1).insert(b) + s.set_property("p", 17) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) - b = RBA::Box.new(1, 101, 1001, 1201) - s = c0.shapes(1).insert(b) - s.set_property("p", 17) + tt = RBA::Trans.new + s = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + s.set_property("p", 18) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - s = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - s.set_property("p", 18) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") + c0c = l.cell(l.add_cell("c0")) + cm = RBA::CellMapping::new + cm.for_single_cell(l, c0c.cell_index, l, c0.cell_index) + c0c.copy_tree_shapes(c0, cm) + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c0$1](0,100;1000,1200)/[c0$1](100,0;1100,1100)/[c0$1](-1200,0;-100,1000)/[c0$1](1200,0;2200,1100)") + assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") + assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) + + c0c.clear + lm = RBA::LayerMapping::new + lm.map(1, 0) + c0c.copy_tree_shapes(c0, cm, lm) + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](1,101;1001,1201)") + assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), 17) + assert_equal(collect(c0c.begin_shapes_rec(1), l), "") + assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), nil) - c0c = l.cell(l.add_cell("c0")) - cm = RBA::CellMapping::new - cm.for_single_cell(l, c0c.cell_index, l, c0.cell_index) - c0c.copy_tree_shapes(c0, cm) - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c0$1](0,100;1000,1200)/[c0$1](100,0;1100,1100)/[c0$1](-1200,0;-100,1000)/[c0$1](1200,0;2200,1100)") - assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") - assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) - - c0c.clear - lm = RBA::LayerMapping::new - lm.map(1, 0) - c0c.copy_tree_shapes(c0, cm, lm) - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](1,101;1001,1201)") - assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), 17) - assert_equal(collect(c0c.begin_shapes_rec(1), l), "") - assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), nil) + c0c.clear + cm.for_single_cell_full(l, c0c.cell_index, l, c0.cell_index) + c0c.copy_tree_shapes(c0, cm) + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c2$1](100,0;1100,1100)/[c3$1](1200,0;2200,1100)/[c3$1](-1200,0;-100,1000)/[c1$1](0,100;1000,1200)") + assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") + assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) - c0c.clear - cm.for_single_cell_full(l, c0c.cell_index, l, c0.cell_index) - c0c.copy_tree_shapes(c0, cm) - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c2$1](100,0;1100,1100)/[c3$1](1200,0;2200,1100)/[c3$1](-1200,0;-100,1000)/[c1$1](0,100;1000,1200)") - assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") - assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) + i0 = nil + c0c.each_inst { |i| i.cell_index == l.cell("c1$1").cell_index && i0 = i } + assert_equal(i0.property("p"), 18) - i0 = nil - c0c.each_inst { |i| i.cell_index == l.cell("c1$1").cell_index && i0 = i } - assert_equal(i0.property("p"), 18) + l2 = RBA::Layout::new + l2.dbu = 0.0005 + c0c = l2.cell(l2.add_cell("c0")) - l2 = RBA::Layout::new - l2.dbu = 0.0005 - c0c = l2.cell(l2.add_cell("c0")) + cm.for_single_cell_full(l2, c0c.cell_index, l, c0.cell_index) + c0c.copy_tree_shapes(c0, cm) + layer1 = l2.find_layer(1, 0) + layer2 = l2.find_layer(2, 0) + assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)/[c2](200,0;2200,2200)/[c3](2400,0;4400,2200)/[c3](-2400,0;-200,2000)/[c1](0,200;2000,2400)") + assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") + assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) - cm.for_single_cell_full(l2, c0c.cell_index, l, c0.cell_index) - c0c.copy_tree_shapes(c0, cm) - layer1 = l2.find_layer(1, 0) - layer2 = l2.find_layer(2, 0) - assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)/[c2](200,0;2200,2200)/[c3](2400,0;4400,2200)/[c3](-2400,0;-200,2000)/[c1](0,200;2000,2400)") - assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") - assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) - - i0 = nil - c0c.each_inst { |i| i.cell_index == l2.cell("c1").cell_index && i0 = i } - assert_equal(i0.property("p"), 18) - - end + i0 = nil + c0c.each_inst { |i| i.cell_index == l2.cell("c1").cell_index && i0 = i } + assert_equal(i0.property("p"), 18) end @@ -1750,115 +1694,107 @@ END # move shapes between cell trees - if RBA::Application::instance.is_editable? + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + c2 = l.cell(l.add_cell("c2")) + c3 = l.cell(l.add_cell("c3")) - l = RBA::Layout.new - l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) - l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) - c0 = l.cell(l.add_cell("c0")) - c1 = l.cell(l.add_cell("c1")) - c2 = l.cell(l.add_cell("c2")) - c3 = l.cell(l.add_cell("c3")) + b = RBA::Box.new(0, 100, 1000, 1200) + c0.shapes(0).insert(b) + c1.shapes(0).insert(b) + c2.shapes(0).insert(b) + c3.shapes(0).insert(b) + b = RBA::Box.new(1, 101, 1001, 1201) + s = c0.shapes(1).insert(b) + s.set_property("p", 17) - b = RBA::Box.new(0, 100, 1000, 1200) - c0.shapes(0).insert(b) - c1.shapes(0).insert(b) - c2.shapes(0).insert(b) - c3.shapes(0).insert(b) - b = RBA::Box.new(1, 101, 1001, 1201) - s = c0.shapes(1).insert(b) - s.set_property("p", 17) + tt = RBA::Trans.new + s = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) + assert_equal(s.is_pcell?, false) + assert_equal(s.pcell_declaration, nil) + assert_equal(s.pcell_parameters, []) + assert_equal(s.pcell_parameters_by_name, {}) + s.set_property("p", 18) + c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) + c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) + c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - tt = RBA::Trans.new - s = c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) - assert_equal(s.is_pcell?, false) - assert_equal(s.pcell_declaration, nil) - assert_equal(s.pcell_parameters, []) - assert_equal(s.pcell_parameters_by_name, {}) - s.set_property("p", 18) - c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) - c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) - c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + ll = l.dup - ll = l.dup + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "[c0](1,101;1001,1201)") + c0c = l.cell(l.add_cell("c0")) + cm = RBA::CellMapping::new + cm.for_single_cell(l, c0c.cell_index, l, c0.cell_index) + c0c.move_tree_shapes(c0, cm) + assert_equal(collect(c0.begin_shapes_rec(0), l), "") + assert_equal(collect(c0.begin_shapes_rec(1), l), "") + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c0$1](0,100;1000,1200)/[c0$1](100,0;1100,1100)/[c0$1](-1200,0;-100,1000)/[c0$1](1200,0;2200,1100)") + assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") + assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) - c0c = l.cell(l.add_cell("c0")) - cm = RBA::CellMapping::new - cm.for_single_cell(l, c0c.cell_index, l, c0.cell_index) - c0c.move_tree_shapes(c0, cm) - assert_equal(collect(c0.begin_shapes_rec(0), l), "") - assert_equal(collect(c0.begin_shapes_rec(1), l), "") - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c0$1](0,100;1000,1200)/[c0$1](100,0;1100,1100)/[c0$1](-1200,0;-100,1000)/[c0$1](1200,0;2200,1100)") - assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") - assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) + l = ll.dup + c0 = l.cell("c0") + c0c = l.cell(l.add_cell("c0")) + + lm = RBA::LayerMapping::new + lm.map(1, 0) + c0c.move_tree_shapes(c0, cm, lm) + assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") + assert_equal(collect(c0.begin_shapes_rec(1), l), "") + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](1,101;1001,1201)") + assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), 17) + assert_equal(collect(c0c.begin_shapes_rec(1), l), "") + assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), nil) - l = ll.dup - c0 = l.cell("c0") - c0c = l.cell(l.add_cell("c0")) - - lm = RBA::LayerMapping::new - lm.map(1, 0) - c0c.move_tree_shapes(c0, cm, lm) - assert_equal(collect(c0.begin_shapes_rec(0), l), "[c0](0,100;1000,1200)/[c2](100,0;1100,1100)/[c3](1200,0;2200,1100)/[c3](-1200,0;-100,1000)/[c1](0,100;1000,1200)") - assert_equal(collect(c0.begin_shapes_rec(1), l), "") - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](1,101;1001,1201)") - assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), 17) - assert_equal(collect(c0c.begin_shapes_rec(1), l), "") - assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), nil) + l = ll.dup + c0 = l.cell("c0") + c0c = l.cell(l.add_cell("c0")) + + cm.for_single_cell_full(l, c0c.cell_index, l, c0.cell_index) + c0c.move_tree_shapes(c0, cm) + assert_equal(collect(c0.begin_shapes_rec(0), l), "") + assert_equal(collect(c0.begin_shapes_rec(1), l), "") + assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c2$1](100,0;1100,1100)/[c3$1](1200,0;2200,1100)/[c3$1](-1200,0;-100,1000)/[c1$1](0,100;1000,1200)") + assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") + assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) - l = ll.dup - c0 = l.cell("c0") - c0c = l.cell(l.add_cell("c0")) - - cm.for_single_cell_full(l, c0c.cell_index, l, c0.cell_index) - c0c.move_tree_shapes(c0, cm) - assert_equal(collect(c0.begin_shapes_rec(0), l), "") - assert_equal(collect(c0.begin_shapes_rec(1), l), "") - assert_equal(collect(c0c.begin_shapes_rec(0), l), "[c0$1](0,100;1000,1200)/[c2$1](100,0;1100,1100)/[c3$1](1200,0;2200,1100)/[c3$1](-1200,0;-100,1000)/[c1$1](0,100;1000,1200)") - assert_equal(c0c.begin_shapes_rec(0).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(1), l), "[c0$1](1,101;1001,1201)") - assert_equal(c0c.begin_shapes_rec(1).shape.property("p"), 17) + i0 = nil + c0c.each_inst { |i| i.cell_index == l.cell("c1$1").cell_index && i0 = i } + assert_equal(i0.property("p"), 18) - i0 = nil - c0c.each_inst { |i| i.cell_index == l.cell("c1$1").cell_index && i0 = i } - assert_equal(i0.property("p"), 18) + l = ll.dup + c0 = l.cell("c0") + + l2 = RBA::Layout::new + l2.dbu = 0.0005 + c0c = l2.cell(l2.add_cell("c0")) - l = ll.dup - c0 = l.cell("c0") - - l2 = RBA::Layout::new - l2.dbu = 0.0005 - c0c = l2.cell(l2.add_cell("c0")) + cm.for_single_cell_full(l2, c0c.cell_index, l, c0.cell_index) + c0c.move_tree_shapes(c0, cm) + assert_equal(collect(c0.begin_shapes_rec(0), l), "") + assert_equal(collect(c0.begin_shapes_rec(1), l), "") + layer1 = l2.find_layer(1, 0) + layer2 = l2.find_layer(2, 0) + assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)/[c2](200,0;2200,2200)/[c3](2400,0;4400,2200)/[c3](-2400,0;-200,2000)/[c1](0,200;2000,2400)") + assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) + assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") + assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) - cm.for_single_cell_full(l2, c0c.cell_index, l, c0.cell_index) - c0c.move_tree_shapes(c0, cm) - assert_equal(collect(c0.begin_shapes_rec(0), l), "") - assert_equal(collect(c0.begin_shapes_rec(1), l), "") - layer1 = l2.find_layer(1, 0) - layer2 = l2.find_layer(2, 0) - assert_equal(collect(c0c.begin_shapes_rec(layer1), l), "[c0](0,200;2000,2400)/[c2](200,0;2200,2200)/[c3](2400,0;4400,2200)/[c3](-2400,0;-200,2000)/[c1](0,200;2000,2400)") - assert_equal(c0c.begin_shapes_rec(layer1).shape.property("p"), nil) - assert_equal(collect(c0c.begin_shapes_rec(layer2), l), "[c0](2,202;2002,2402)") - assert_equal(c0c.begin_shapes_rec(layer2).shape.property("p"), 17) - - i0 = nil - c0c.each_inst { |i| i.cell_index == l2.cell("c1").cell_index && i0 = i } - assert_equal(i0.property("p"), 18) - - end + i0 = nil + c0c.each_inst { |i| i.cell_index == l2.cell("c1").cell_index && i0 = i } + assert_equal(i0.property("p"), 18) end def test_16 - if !RBA::Application::instance.is_editable? - return - end - # fill tool l = nil @@ -1980,9 +1916,6 @@ END def test_18 ly = RBA::Layout::new - if !ly.is_editable? - return - end cell = ly.create_cell("X")