diff --git a/src/db/db/dbReader.cc b/src/db/db/dbReader.cc index 6561c6d9a..aa5a096f8 100644 --- a/src/db/db/dbReader.cc +++ b/src/db/db/dbReader.cc @@ -61,7 +61,7 @@ join_layer_names (std::string &s, const std::string &n) // ReaderBase implementation ReaderBase::ReaderBase () - : m_warnings_as_errors (false), m_warn_level (1), m_warn_count_for_same_message (0), m_first_warning (true) + : m_warnings_as_errors (false), m_warn_level (1), m_warn_count_for_same_message (0), m_first_warning (true), m_expected_dbu (0.0) { } @@ -82,6 +82,7 @@ ReaderBase::init (const db::LoadLayoutOptions &options) m_last_warning.clear (); m_warn_count_for_same_message = 0; m_first_warning = true; + m_expected_dbu = 0.0; } bool @@ -114,6 +115,20 @@ ReaderBase::compress_warning (const std::string &msg) } } +void +ReaderBase::set_expected_dbu (double dbu) +{ + m_expected_dbu = dbu; +} + +void +ReaderBase::check_dbu (double dbu) const +{ + if (m_expected_dbu > db::epsilon && fabs (dbu - m_expected_dbu) > db::epsilon) { + throw ReaderException (tl::sprintf (tl::to_string (tr ("Former and present database units are not compatible: %.12g (former) vs. %.12g (present)")), m_expected_dbu, dbu)); + } +} + // --------------------------------------------------------------- // Reader implementation diff --git a/src/db/db/dbReader.h b/src/db/db/dbReader.h index b13025a56..76b92cc17 100644 --- a/src/db/db/dbReader.h +++ b/src/db/db/dbReader.h @@ -138,6 +138,33 @@ public: */ int compress_warning (const std::string &msg); + /** + * @brief Sets the expected database unit + * + * With this value set, the reader can check if the present database unit is + * compatible with the expected one and either take actions to scale the layouts + * or to reject the file. + * + * Setting the value to 0 resets the expected DBU and will disable all checks + * or scaling. + */ + void set_expected_dbu (double dbu); + + /** + * @brief Gets the expected database unit + */ + double expected_dbu () const + { + return m_expected_dbu; + } + + /** + * @brief Checks the given DBU against the expected one + * + * This method will raise an exception if the database units do not match. + */ + void check_dbu (double dbu) const; + protected: virtual void init (const db::LoadLayoutOptions &options); @@ -147,6 +174,7 @@ private: std::string m_last_warning; int m_warn_count_for_same_message; bool m_first_warning; + double m_expected_dbu; }; /** diff --git a/src/plugins/streamers/cif/db_plugin/dbCIFReader.cc b/src/plugins/streamers/cif/db_plugin/dbCIFReader.cc index 1d101f041..9b338c833 100644 --- a/src/plugins/streamers/cif/db_plugin/dbCIFReader.cc +++ b/src/plugins/streamers/cif/db_plugin/dbCIFReader.cc @@ -836,6 +836,7 @@ CIFReader::do_read (db::Layout &layout) db::LayoutLocker locker (&layout); double sf = 0.01 / m_dbu; + check_dbu (m_dbu); layout.dbu (m_dbu); m_cellname = "{CIF top level}"; diff --git a/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc b/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc index 3abe3501f..cf7a00912 100644 --- a/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc +++ b/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc @@ -350,6 +350,7 @@ DXFReader::read (db::Layout &layout, const db::LoadLayoutOptions &options) db::cell_index_type top = layout.add_cell("TOP"); // TODO: make variable .. + check_dbu (m_dbu); layout.dbu (m_dbu); do_read (layout, top); cleanup (layout, top); diff --git a/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc b/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc index dad91a563..f6a9f8889 100644 --- a/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc +++ b/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc @@ -236,6 +236,7 @@ GDS2ReaderBase::do_read (db::Layout &layout) m_dbuu = dbuu; m_dbu = dbum * 1e6; /*in micron*/ + check_dbu (m_dbu); layout.dbu (m_dbu); } else { diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc index e4e7dfb80..253b7b6db 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFPlugin.cc @@ -119,6 +119,7 @@ LEFDEFReader::read_lefdef (db::Layout &layout, const db::LoadLayoutOptions &opti effective_options = *lefdef_options; } + check_dbu (effective_options.dbu ()); layout.dbu (effective_options.dbu ()); std::string base_path; diff --git a/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc b/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc index 78e6420c4..56abcf8d3 100644 --- a/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc +++ b/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc @@ -98,6 +98,7 @@ MAGReader::read (db::Layout &layout, const db::LoadLayoutOptions &options) top_cell = layout.add_cell (top_cellname.c_str ()); } + check_dbu (m_dbu); layout.dbu (m_dbu); m_cells_to_read.clear (); diff --git a/src/plugins/streamers/maly/db_plugin/dbMALYReader.cc b/src/plugins/streamers/maly/db_plugin/dbMALYReader.cc index a474874a7..07c0e1de4 100644 --- a/src/plugins/streamers/maly/db_plugin/dbMALYReader.cc +++ b/src/plugins/streamers/maly/db_plugin/dbMALYReader.cc @@ -51,7 +51,6 @@ namespace db MALYReader::MALYReader (tl::InputStream &s) : m_stream (s), m_progress (tl::to_string (tr ("Reading MALY file")), 1000), - m_dbu (0.001), m_last_record_line (0) { m_progress.set_format (tl::to_string (tr ("%.0fk lines"))); @@ -89,7 +88,10 @@ MALYReader::read (db::Layout &layout, const db::LoadLayoutOptions &options) init (options); const db::MALYReaderOptions &specific_options = options.get_options (); - m_dbu = specific_options.dbu; + double dbu = specific_options.dbu; + + check_dbu (dbu); + layout.dbu (dbu); set_layer_map (specific_options.layer_map); set_create_layers (specific_options.create_other_layers); diff --git a/src/plugins/streamers/maly/db_plugin/dbMALYReader.h b/src/plugins/streamers/maly/db_plugin/dbMALYReader.h index ea4feabbb..be63c9ccd 100644 --- a/src/plugins/streamers/maly/db_plugin/dbMALYReader.h +++ b/src/plugins/streamers/maly/db_plugin/dbMALYReader.h @@ -223,7 +223,6 @@ private: tl::TextInputStream m_stream; tl::AbsoluteProgress m_progress; - double m_dbu; unsigned int m_last_record_line; std::string m_record; std::string m_record_returned; diff --git a/src/plugins/streamers/maly/unit_tests/dbMALYReaderTests.cc b/src/plugins/streamers/maly/unit_tests/dbMALYReaderTests.cc index 95a6ff447..6068c082f 100644 --- a/src/plugins/streamers/maly/unit_tests/dbMALYReaderTests.cc +++ b/src/plugins/streamers/maly/unit_tests/dbMALYReaderTests.cc @@ -135,6 +135,7 @@ TEST(10_BasicLayout) { run_test (_this, tl::testdata (), "MALY_test10.maly", "maly_test10_au.oas"); run_test (_this, tl::testdata (), "MALY_test10.maly", "maly_test10_lm_au.oas", "A: 10, B: 11, C: 12, D: 13"); + run_test (_this, tl::testdata (), "MALY_test10.maly", "maly_test10_dbu10nm_au.oas", 0, 0.01); } TEST(11_Titles) diff --git a/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc b/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc index 74fc56034..865110228 100644 --- a/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc +++ b/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc @@ -659,7 +659,9 @@ OASISReader::do_read (db::Layout &layout) } // compute database unit in pixel per meter - layout.dbu (1.0 / res); + double dbu = 1.0 / res; + check_dbu (dbu); + layout.dbu (dbu); // read over table offsets if required bool table_offsets_at_end = get_uint (); diff --git a/testdata/maly/maly_test10_dbu10nm_au.oas b/testdata/maly/maly_test10_dbu10nm_au.oas new file mode 100644 index 000000000..f8193382b Binary files /dev/null and b/testdata/maly/maly_test10_dbu10nm_au.oas differ