mirror of https://github.com/KLayout/klayout.git
As discussed in the ticket, the implementation will check for unique cell names upon *writing* of a layout file.
This commit is contained in:
parent
c6798c090b
commit
1d5275d22f
|
|
@ -26,6 +26,7 @@
|
||||||
#include "tlClassRegistry.h"
|
#include "tlClassRegistry.h"
|
||||||
#include "tlStream.h"
|
#include "tlStream.h"
|
||||||
#include "tlExpression.h"
|
#include "tlExpression.h"
|
||||||
|
#include "tlInternational.h"
|
||||||
|
|
||||||
namespace db
|
namespace db
|
||||||
{
|
{
|
||||||
|
|
@ -327,7 +328,7 @@ SaveLayoutOptions::get_valid_layers (const db::Layout &layout, std::vector <std:
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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) {
|
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
|
bool
|
||||||
|
|
|
||||||
|
|
@ -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.
|
* 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
|
* @brief Sets a layout reader option by name
|
||||||
|
|
|
||||||
|
|
@ -1129,6 +1129,40 @@ TEST(117)
|
||||||
EXPECT_EQ (pp == poly, true);
|
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
|
// Extreme fracturing by max. points
|
||||||
TEST(120)
|
TEST(120)
|
||||||
{
|
{
|
||||||
|
|
@ -1153,3 +1187,4 @@ TEST(166)
|
||||||
opt.max_vertex_count = 4;
|
opt.max_vertex_count = 4;
|
||||||
run_test (_this, "t166.oas.gz", "t166_au.gds.gz", false, opt);
|
run_test (_this, "t166.oas.gz", "t166_au.gds.gz", false, opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue