Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/db/db/dbCommonReader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,6 @@ CommonReaderBase::name_for_id (size_t id) const
void
CommonReaderBase::rename_cell (db::Layout &layout, size_t id, const std::string &cn)
{
m_name_for_id.insert (std::make_pair (id, cn));

std::map<size_t, std::pair<std::string, db::cell_index_type> >::iterator iid = m_id_map.find (id);
std::map<std::string, std::pair<size_t, db::cell_index_type> >::iterator iname = m_name_map.find (cn);

Expand All @@ -156,9 +154,22 @@ CommonReaderBase::rename_cell (db::Layout &layout, size_t id, const std::string
}

if (iname != m_name_map.end () && iname->second.first != null_id && iname->second.first != id) {
common_reader_error (tl::sprintf (tl::to_string (tr ("Same cell name %s, but different IDs: %ld and %ld")), cn, id, iname->second.first));

// picking a different name on name clash (issue #2088)
std::string cn_new = cn + "_id$" + tl::to_string (id);
for (size_t i = 0; m_name_map.find (cn_new) != m_name_map.end (); ++i) {
cn_new = cn + "_id$" + tl::to_string (id) + "$" + tl::to_string (i);
}

common_reader_warn (tl::sprintf (tl::to_string (tr ("Same cell name %s, but different IDs: %ld and %ld, renaming first to %s")), cn, id, iname->second.first, cn_new));
rename_cell (layout, id, cn_new);

return;

}

m_name_for_id.insert (std::make_pair (id, cn));

if (iid != m_id_map.end () && iname != m_name_map.end ()) {

if (iname->second.second != iid->second.second) {
Expand Down
32 changes: 30 additions & 2 deletions src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "tlDeflate.h"
#include "tlMath.h"
#include "tlUniqueName.h"

#include <math.h>

Expand Down Expand Up @@ -1334,7 +1335,7 @@ OASISWriter::write_cellname_table (size_t &cellnames_table_pos, const std::vecto
begin_table (cellnames_table_pos);

write_record_id (sequential ? 3 : 4);
write_nstring (layout.cell_name (*cell));
write_nstring (cell_nstring (*cell));
if (! sequential) {
write ((unsigned long) *cell);
}
Expand Down Expand Up @@ -1476,6 +1477,31 @@ static bool skip_cell_body (const db::Cell &cref)
return cref.is_ghost_cell () && cref.empty ();
}

void
OASISWriter::create_cell_nstrings (const db::Layout &layout, const std::set <db::cell_index_type> &cell_set)
{
m_cell_nstrings.clear ();

std::set<std::string> names;

for (auto c = cell_set.begin (); c != cell_set.end (); ++c) {

std::string cn = make_nstring (layout.cell_name (*c));
cn = tl::unique_name (cn, names);

m_cell_nstrings.insert (std::make_pair (*c, cn));
names.insert (cn);

}
}

const char *
OASISWriter::cell_nstring (db::cell_index_type cell_index)
{
auto n = m_cell_nstrings.find (cell_index);
tl_assert (n != m_cell_nstrings.end ());
return n->second.c_str ();
}

void
OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLayoutOptions &options)
Expand Down Expand Up @@ -1510,6 +1536,8 @@ OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::Save
std::set <db::cell_index_type> cell_set;
options.get_cells (layout, cell_set, layers);

create_cell_nstrings (layout, cell_set);

// create a cell index vector sorted bottom-up
std::vector <db::cell_index_type> cells, cells_by_index;

Expand Down Expand Up @@ -1602,7 +1630,7 @@ OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::Save
is_top = (cell_set.find (*p) == cell_set.end ());
}
if (is_top) {
write_property_def (s_top_cell_name, tl::Variant (make_nstring (layout.cell_name (*cell))), true);
write_property_def (s_top_cell_name, tl::Variant (cell_nstring (*cell)), true);
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/plugins/streamers/oasis/db_plugin/dbOASISWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ class DB_PLUGIN_PUBLIC OASISWriter
std::map <std::string, unsigned long> m_textstrings;
std::map <std::string, unsigned long> m_propnames;
std::map <std::string, unsigned long> m_propstrings;
std::map <db::cell_index_type, std::string> m_cell_nstrings;

typedef std::vector<tl::Variant> property_value_list;

Expand Down Expand Up @@ -248,6 +249,9 @@ class DB_PLUGIN_PUBLIC OASISWriter
OASISWriterOptions m_options;
tl::AbsoluteProgress m_progress;

void create_cell_nstrings (const db::Layout &layout, const std::set <db::cell_index_type> &cell_set);
const char *cell_nstring(db::cell_index_type cell_index);

void write_record_id (char b);
void write_byte (char b);
void write_bytes (const char *b, size_t n);
Expand Down
18 changes: 7 additions & 11 deletions src/plugins/streamers/oasis/unit_tests/dbOASISReaderTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -662,20 +662,16 @@ TEST(Bug_1799)
EXPECT_EQ (ps2.value (pn).to_string (), "hello, world!");
}

// Modified in #2088 to give a warning
TEST(DuplicateCellname)
{
db::Manager m (false);
db::Layout layout (&m);

try {
tl::InputStream file (tl::testdata () + "/oasis/duplicate_cellname.oas");
db::OASISReader reader (file);
reader.read (layout);
EXPECT_EQ (false, true);
} catch (tl::CancelException &ex) {
// Seen when private test data is not installed
throw;
} catch (tl::Exception &ex) {
EXPECT_EQ (ex.msg ().find ("Same cell name TOP, but different IDs: 3 and 0 (position=1070, cell=)"), size_t (0));
}
tl::InputStream file (tl::testdata () + "/oasis/duplicate_cellname.oas");
db::OASISReader reader (file);
reader.read (layout);

std::string fn_au (tl::testdata () + "/oasis/duplicate_cellname_au.oas");
db::compare_layouts (_this, layout, fn_au, db::NoNormalization, 1);
}
28 changes: 28 additions & 0 deletions src/plugins/streamers/oasis/unit_tests/dbOASISWriterTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2072,3 +2072,31 @@ TEST(130d)
run_test130 (_this, true, true);
}

// Issue #2088 (name duplication)
TEST(140)
{
db::Layout layout_org;

layout_org.add_cell ("X X");
layout_org.add_cell ("X*X");

std::string tmp_file = tl::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter140.oas"));

{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
db::Writer writer (options);
writer.write (layout_org, out);
}

{
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);

db::compare_layouts (_this, gg, tl::testdata () + "/oasis/dbOASISWriter40_au.gds", db::NoNormalization);
}
}
Binary file added testdata/oasis/dbOASISWriter40_au.gds
Binary file not shown.
Binary file added testdata/oasis/duplicate_cellname_au.oas
Binary file not shown.
Loading