mirror of https://github.com/KLayout/klayout.git
Merge pull request #1554 from KLayout/issue-1549
Fixing issue #1549 (error layer handling in RecursiveShapeIterator)
This commit is contained in:
commit
3533adf8ab
|
|
@ -812,7 +812,7 @@ Layout::delete_cells (const std::set<cell_index_type> &cells_to_delete)
|
|||
// will disable us saving undo data with reference to them.
|
||||
if (manager () && manager ()->transacting ()) {
|
||||
for (unsigned int i = 0; i < layers (); ++i) {
|
||||
if (is_valid_layer (i)) {
|
||||
if (is_valid_layer (i) || is_special_layer (i)) {
|
||||
cref.clear (i);
|
||||
}
|
||||
}
|
||||
|
|
@ -880,7 +880,7 @@ Layout::delete_cell (cell_index_type id)
|
|||
// will disable us saving undo data with reference to them.
|
||||
if (manager () && manager ()->transacting ()) {
|
||||
for (unsigned int i = 0; i < layers (); ++i) {
|
||||
if (is_valid_layer (i)) {
|
||||
if (is_valid_layer (i) || is_special_layer (i)) {
|
||||
cref.clear (i);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1369,6 +1369,13 @@ flatten1 (db::Cell *cell, bool prune)
|
|||
flatten (cell, -1, prune);
|
||||
}
|
||||
|
||||
static void check_layer (const db::Layout *layout, unsigned int layer)
|
||||
{
|
||||
if (! layout->is_valid_layer (layer) && ! layout->is_special_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
}
|
||||
|
||||
static db::RecursiveShapeIterator
|
||||
begin_shapes_rec (const db::Cell *cell, unsigned int layer)
|
||||
{
|
||||
|
|
@ -1376,9 +1383,7 @@ begin_shapes_rec (const db::Cell *cell, unsigned int layer)
|
|||
if (! layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell is not inside layout")));
|
||||
}
|
||||
if (! layout->is_valid_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
check_layer (layout, layer);
|
||||
return db::RecursiveShapeIterator (*layout, *cell, layer);
|
||||
}
|
||||
|
||||
|
|
@ -1389,9 +1394,7 @@ begin_shapes_rec_touching (const db::Cell *cell, unsigned int layer, db::Box reg
|
|||
if (! layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell is not inside layout")));
|
||||
}
|
||||
if (! layout->is_valid_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
check_layer (layout, layer);
|
||||
return db::RecursiveShapeIterator (*layout, *cell, layer, region, false);
|
||||
}
|
||||
|
||||
|
|
@ -1402,9 +1405,7 @@ begin_shapes_rec_touching_um (const db::Cell *cell, unsigned int layer, db::DBox
|
|||
if (! layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell is not inside layout")));
|
||||
}
|
||||
if (! layout->is_valid_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
check_layer (layout, layer);
|
||||
return db::RecursiveShapeIterator (*layout, *cell, layer, db::CplxTrans (layout->dbu ()).inverted () * region, false);
|
||||
}
|
||||
|
||||
|
|
@ -1415,9 +1416,7 @@ begin_shapes_rec_overlapping (const db::Cell *cell, unsigned int layer, db::Box
|
|||
if (! layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell is not inside layout")));
|
||||
}
|
||||
if (! layout->is_valid_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
check_layer (layout, layer);
|
||||
return db::RecursiveShapeIterator (*layout, *cell, layer, region, true);
|
||||
}
|
||||
|
||||
|
|
@ -1428,9 +1427,7 @@ begin_shapes_rec_overlapping_um (const db::Cell *cell, unsigned int layer, db::D
|
|||
if (! layout) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cell is not inside layout")));
|
||||
}
|
||||
if (! layout->is_valid_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
check_layer (layout, layer);
|
||||
return db::RecursiveShapeIterator (*layout, *cell, layer, db::CplxTrans (layout->dbu ()).inverted () * region, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -681,15 +681,20 @@ write_options2 (db::Layout *layout, const std::string &filename, bool /*gzip*/,
|
|||
write_options1 (layout, filename, options);
|
||||
}
|
||||
|
||||
static db::RecursiveShapeIterator
|
||||
static void check_layer (const db::Layout *layout, unsigned int layer)
|
||||
{
|
||||
if (! layout->is_valid_layer (layer) && ! layout->is_special_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
}
|
||||
|
||||
static db::RecursiveShapeIterator
|
||||
begin_shapes (const db::Layout *layout, db::cell_index_type starting_cell, unsigned int layer)
|
||||
{
|
||||
if (! layout->is_valid_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
if (! layout->is_valid_cell_index (starting_cell)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid cell index")));
|
||||
}
|
||||
check_layer (layout, layer);
|
||||
return db::RecursiveShapeIterator (*layout, layout->cell (starting_cell), layer);
|
||||
}
|
||||
|
||||
|
|
@ -702,9 +707,7 @@ begin_shapes2 (const db::Layout *layout, const db::Cell *cell, unsigned int laye
|
|||
static db::RecursiveShapeIterator
|
||||
begin_shapes_touching (const db::Layout *layout, db::cell_index_type starting_cell, unsigned int layer, db::Box region)
|
||||
{
|
||||
if (! layout->is_valid_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
check_layer (layout, layer);
|
||||
if (! layout->is_valid_cell_index (starting_cell)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid cell index")));
|
||||
}
|
||||
|
|
@ -720,9 +723,7 @@ begin_shapes_touching2 (const db::Layout *layout, const db::Cell *cell, unsigned
|
|||
static db::RecursiveShapeIterator
|
||||
begin_shapes_overlapping (const db::Layout *layout, db::cell_index_type starting_cell, unsigned int layer, db::Box region)
|
||||
{
|
||||
if (! layout->is_valid_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
check_layer (layout, layer);
|
||||
if (! layout->is_valid_cell_index (starting_cell)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid cell index")));
|
||||
}
|
||||
|
|
@ -738,9 +739,7 @@ begin_shapes_overlapping2 (const db::Layout *layout, const db::Cell *cell, unsig
|
|||
static db::RecursiveShapeIterator
|
||||
begin_shapes_touching_um (const db::Layout *layout, db::cell_index_type starting_cell, unsigned int layer, db::DBox region)
|
||||
{
|
||||
if (! layout->is_valid_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
check_layer (layout, layer);
|
||||
if (! layout->is_valid_cell_index (starting_cell)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid cell index")));
|
||||
}
|
||||
|
|
@ -756,9 +755,7 @@ begin_shapes_touching2_um (const db::Layout *layout, const db::Cell *cell, unsig
|
|||
static db::RecursiveShapeIterator
|
||||
begin_shapes_overlapping_um (const db::Layout *layout, db::cell_index_type starting_cell, unsigned int layer, db::DBox region)
|
||||
{
|
||||
if (! layout->is_valid_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index")));
|
||||
}
|
||||
check_layer (layout, layer);
|
||||
if (! layout->is_valid_cell_index (starting_cell)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid cell index")));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,33 +60,52 @@ private:
|
|||
|
||||
}
|
||||
|
||||
static void check_layer (const db::Layout &layout, unsigned int layer)
|
||||
{
|
||||
if (! layout.is_valid_layer (layer) && ! layout.is_special_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid layer index %d")), int (layer));
|
||||
}
|
||||
}
|
||||
|
||||
static db::RecursiveShapeIterator *new_si1 (const db::Layout &layout, const db::Cell &cell, unsigned int layer)
|
||||
{
|
||||
check_layer (layout, layer);
|
||||
return new db::RecursiveShapeIterator (layout, cell, layer);
|
||||
}
|
||||
|
||||
static db::RecursiveShapeIterator *new_si2 (const db::Layout &layout, const db::Cell &cell, const std::vector<unsigned int> &layers)
|
||||
{
|
||||
for (auto l = layers.begin (); l != layers.end (); ++l) {
|
||||
check_layer (layout, *l);
|
||||
}
|
||||
return new db::RecursiveShapeIterator (layout, cell, layers);
|
||||
}
|
||||
|
||||
static db::RecursiveShapeIterator *new_si3 (const db::Layout &layout, const db::Cell &cell, unsigned int layer, const db::Box &box, bool overlapping)
|
||||
{
|
||||
check_layer (layout, layer);
|
||||
return new db::RecursiveShapeIterator (layout, cell, layer, box, overlapping);
|
||||
}
|
||||
|
||||
static db::RecursiveShapeIterator *new_si3a (const db::Layout &layout, const db::Cell &cell, unsigned int layer, const db::Region ®ion, bool overlapping)
|
||||
{
|
||||
check_layer (layout, layer);
|
||||
return new db::RecursiveShapeIterator (layout, cell, layer, region, overlapping);
|
||||
}
|
||||
|
||||
static db::RecursiveShapeIterator *new_si4 (const db::Layout &layout, const db::Cell &cell, const std::vector<unsigned int> &layers, const db::Box &box, bool overlapping)
|
||||
{
|
||||
for (auto l = layers.begin (); l != layers.end (); ++l) {
|
||||
check_layer (layout, *l);
|
||||
}
|
||||
return new db::RecursiveShapeIterator (layout, cell, layers, box, overlapping);
|
||||
}
|
||||
|
||||
static db::RecursiveShapeIterator *new_si4a (const db::Layout &layout, const db::Cell &cell, const std::vector<unsigned int> &layers, const db::Region ®ion, bool overlapping)
|
||||
{
|
||||
for (auto l = layers.begin (); l != layers.end (); ++l) {
|
||||
check_layer (layout, *l);
|
||||
}
|
||||
return new db::RecursiveShapeIterator (layout, cell, layers, region, overlapping);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -803,7 +803,7 @@ static void set_shape_layer_index (db::Shape *s, unsigned int layer)
|
|||
throw tl::Exception (tl::to_string (tr ("Shape does not belong to a layout")));
|
||||
}
|
||||
|
||||
if (! layout->is_valid_layer (layer)) {
|
||||
if (! layout->is_valid_layer (layer) && ! layout->is_special_layer (layer)) {
|
||||
throw tl::Exception (tl::to_string (tr ("Layer index does not point to a valid layer")));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2139,6 +2139,107 @@ class DBLayoutTests1_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
# Error layer
|
||||
def test_issue1549
|
||||
|
||||
ly = RBA::Layout::new
|
||||
top = ly.create_cell("TOP")
|
||||
|
||||
ll = ly.layer(1, 0)
|
||||
el = ly.error_layer
|
||||
gs = ly.guiding_shape_layer
|
||||
il = 100
|
||||
|
||||
assert_equal(true, ly.is_special_layer?(el))
|
||||
assert_equal(false, ly.is_valid_layer?(el))
|
||||
assert_equal(true, ly.is_special_layer?(gs))
|
||||
assert_equal(false, ly.is_valid_layer?(gs))
|
||||
assert_equal(false, ly.is_special_layer?(ll))
|
||||
assert_equal(true, ly.is_valid_layer?(ll))
|
||||
assert_equal(false, ly.is_special_layer?(il))
|
||||
assert_equal(false, ly.is_valid_layer?(il))
|
||||
|
||||
top.shapes(gs).insert(RBA::Box::new(0, 0, 100, 200))
|
||||
top.shapes(el).insert(RBA::Box::new(1, 2, 101, 202))
|
||||
top.shapes(ll).insert(RBA::Box::new(10, 20, 110, 220))
|
||||
|
||||
s = RBA::RecursiveShapeIterator::new(ly, top, gs).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (0,0;100,200)", s)
|
||||
|
||||
s = RBA::RecursiveShapeIterator::new(ly, top, [gs]).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (0,0;100,200)", s)
|
||||
|
||||
s = top.begin_shapes_rec(gs).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (0,0;100,200)", s)
|
||||
|
||||
s = top.begin_shapes_rec_touching(gs, RBA::Box::world).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (0,0;100,200)", s)
|
||||
|
||||
s = top.begin_shapes_rec_overlapping(gs, RBA::Box::world).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (0,0;100,200)", s)
|
||||
|
||||
s = RBA::RecursiveShapeIterator::new(ly, top, el).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (1,2;101,202)", s)
|
||||
|
||||
s = RBA::RecursiveShapeIterator::new(ly, top, [el]).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (1,2;101,202)", s)
|
||||
|
||||
s = top.begin_shapes_rec(el).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (1,2;101,202)", s)
|
||||
|
||||
s = top.begin_shapes_rec_touching(el, RBA::Box::world).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (1,2;101,202)", s)
|
||||
|
||||
s = top.begin_shapes_rec_overlapping(el, RBA::Box::world).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (1,2;101,202)", s)
|
||||
|
||||
s = RBA::RecursiveShapeIterator::new(ly, top, ll).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (10,20;110,220)", s)
|
||||
|
||||
s = RBA::RecursiveShapeIterator::new(ly, top, [ll]).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (10,20;110,220)", s)
|
||||
|
||||
s = top.begin_shapes_rec(ll).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (10,20;110,220)", s)
|
||||
|
||||
s = top.begin_shapes_rec_touching(ll, RBA::Box::world).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (10,20;110,220)", s)
|
||||
|
||||
s = top.begin_shapes_rec_overlapping(ll, RBA::Box::world).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal("box (10,20;110,220)", s)
|
||||
|
||||
begin
|
||||
s = RBA::RecursiveShapeIterator::new(ly, top, il).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
end
|
||||
|
||||
begin
|
||||
s = RBA::RecursiveShapeIterator::new(ly, top, [il]).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
end
|
||||
|
||||
begin
|
||||
s = top.begin_shapes_rec(il).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
end
|
||||
|
||||
begin
|
||||
s = top.begin_shapes_rec_touching(il, RBA::Box::world).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
end
|
||||
|
||||
begin
|
||||
s = top.begin_shapes_rec_overlapping(il, RBA::Box::world).each.collect { |it| it.shape.to_s }.join("/")
|
||||
assert_equal(true, false)
|
||||
rescue => ex
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
|
|
|
|||
Loading…
Reference in New Issue