Implemented #586 (issues with duplicate cell names) (#605)

As discussed in the ticket, the implementation will
check for unique cell names upon *writing* of a layout
file.
This commit is contained in:
Matthias Köfferlein 2020-07-05 09:41:44 -07:00 committed by Matthias Koefferlein
parent c6798c090b
commit 1d5275d22f
3 changed files with 58 additions and 2 deletions

View File

@ -26,6 +26,7 @@
#include "tlClassRegistry.h"
#include "tlStream.h"
#include "tlExpression.h"
#include "tlInternational.h"
namespace db
{
@ -327,7 +328,7 @@ SaveLayoutOptions::get_valid_layers (const db::Layout &layout, std::vector <std:
}
void
SaveLayoutOptions::get_cells (const db::Layout &layout, std::set <db::cell_index_type> &cells, const std::vector <std::pair <unsigned int, db::LayerProperties> > &valid_layers) const
SaveLayoutOptions::get_cells (const db::Layout &layout, std::set <db::cell_index_type> &cells, const std::vector <std::pair <unsigned int, db::LayerProperties> > &valid_layers, bool require_unique_names) const
{
if (m_all_cells) {
@ -408,6 +409,26 @@ SaveLayoutOptions::get_cells (const db::Layout &layout, std::set <db::cell_index
}
}
if (require_unique_names) {
std::map<std::string, unsigned int> use_count;
for (std::set <db::cell_index_type>::const_iterator c = cells.begin (); c != cells.end (); ++c) {
use_count.insert (std::make_pair (std::string (layout.cell_name (*c)), 0)).first->second += 1;
}
std::vector<std::string> multi;
for (std::map<std::string, unsigned int>::const_iterator u = use_count.begin (); u != use_count.end (); ++u) {
if (u->second > 1) {
multi.push_back (u->first);
}
}
if (! multi.empty ()) {
throw tl::Exception (tl::to_string (tr ("The following cell name(s) are used for more than one cell - can't write this layout:\n ")) + tl::join (multi, "\n "));
}
}
}
bool

View File

@ -413,7 +413,7 @@ public:
*
* It must be given a list of valid layers which is used to determine empty cells if dont_save_empty_cells is true.
*/
void get_cells (const db::Layout &layout, std::set <db::cell_index_type> &cells, const std::vector <std::pair <unsigned int, db::LayerProperties> > &valid_layers) const;
void get_cells (const db::Layout &layout, std::set <db::cell_index_type> &cells, const std::vector <std::pair <unsigned int, db::LayerProperties> > &valid_layers, bool require_unique_names = true) const;
/**
* @brief Sets a layout reader option by name

View File

@ -1129,6 +1129,40 @@ TEST(117)
EXPECT_EQ (pp == poly, true);
}
// error on duplicate cell name
TEST(118)
{
db::Manager m (false);
db::Layout layout_org (&m);
db::cell_index_type cid1 = layout_org.add_cell ("A");
db::cell_index_type cid2 = layout_org.add_cell ("B");
layout_org.rename_cell (cid2, "A"); // creates a duplicate cell
db::LayerProperties lp;
lp.layer = 1;
lp.datatype = 0;
unsigned int lid = layout_org.insert_layer (lp);
layout_org.cell (cid1).shapes (lid).insert (db::Box (0, 0, 1000, 2000));
layout_org.cell (cid2).shapes (lid).insert (db::Box (0, 0, 1000, 2000));
std::string tmp_file = tl::TestBase::tmp_file ("tmp_GDS2Writer_117.gds");
bool error = false;
try {
tl::OutputStream stream (tmp_file);
db::SaveLayoutOptions options;
db::Writer writer (options);
writer.write (layout_org, stream);
} catch (tl::Exception &ex) {
tl::warn << ex.msg ();
error = true;
}
EXPECT_EQ (error, true);
}
// Extreme fracturing by max. points
TEST(120)
{
@ -1153,3 +1187,4 @@ TEST(166)
opt.max_vertex_count = 4;
run_test (_this, "t166.oas.gz", "t166_au.gds.gz", false, opt);
}