From b9906180e8104bc2cf62fa65675d51294ebc1c36 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 25 Oct 2025 17:54:26 +0200 Subject: [PATCH] Implementing request from issue #2183 For strmxor, --drop-empty-cells now is default. To explicitly turn it OFF, use strmxor --drop-empty-cells=false ... --- src/buddies/src/bd/bdWriterOptions.cc | 18 +++++++- src/buddies/src/bd/bdWriterOptions.h | 8 ++++ src/buddies/src/bd/strmxor.cc | 6 ++- src/buddies/unit_tests/bdStrmxorTests.cc | 50 +++++++++++++++++++++-- testdata/bd/strmxor_au1d2.oas | Bin 0 -> 714 bytes 5 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 testdata/bd/strmxor_au1d2.oas diff --git a/src/buddies/src/bd/bdWriterOptions.cc b/src/buddies/src/bd/bdWriterOptions.cc index 87d519ff6..2886aef92 100644 --- a/src/buddies/src/bd/bdWriterOptions.cc +++ b/src/buddies/src/bd/bdWriterOptions.cc @@ -30,9 +30,23 @@ namespace bd { GenericWriterOptions::GenericWriterOptions () - : m_scale_factor (1.0) { - db::SaveLayoutOptions save_options; + db::SaveLayoutOptions options; + init_from_options (options); +} + +GenericWriterOptions::GenericWriterOptions (const db::SaveLayoutOptions &options) +{ + init_from_options (options); +} + +void +GenericWriterOptions::init_from_options (const db::SaveLayoutOptions &save_options_nc) +{ + // const_cast needed because "get_option_by_name" is not const as it should be + db::SaveLayoutOptions &save_options = const_cast (save_options_nc); + + m_scale_factor = 1.0; m_dbu = save_options.get_option_by_name ("dbu").to_double (); m_libname = save_options.get_option_by_name ("libname").to_string (); diff --git a/src/buddies/src/bd/bdWriterOptions.h b/src/buddies/src/bd/bdWriterOptions.h index a5811bdb5..6ebf61f99 100644 --- a/src/buddies/src/bd/bdWriterOptions.h +++ b/src/buddies/src/bd/bdWriterOptions.h @@ -53,6 +53,13 @@ public: */ GenericWriterOptions (); + /** + * @brief Constructor + * + * The "options" object specifies the defaults to be used. + */ + GenericWriterOptions (const db::SaveLayoutOptions &options); + /** * @brief Adds the generic options to the command line parser object * The format string gives a hint about the target format. Certain options will be @@ -142,6 +149,7 @@ private: int m_dxf_polygon_mode; void set_oasis_substitution_char (const std::string &text); + void init_from_options (const db::SaveLayoutOptions &options); }; } diff --git a/src/buddies/src/bd/strmxor.cc b/src/buddies/src/bd/strmxor.cc index 1a5965e83..7df5be64b 100644 --- a/src/buddies/src/bd/strmxor.cc +++ b/src/buddies/src/bd/strmxor.cc @@ -380,7 +380,9 @@ BD_PUBLIC int strmxor (int argc, char *argv[]) generic_reader_options_a.add_options (cmd); generic_reader_options_b.add_options (cmd); - bd::GenericWriterOptions writer_options; + db::SaveLayoutOptions def_writer_options; + def_writer_options.set_dont_write_empty_cells (true); + bd::GenericWriterOptions writer_options (def_writer_options); writer_options.add_options (cmd); cmd << tl::arg ("input_a", &infile_a, "The first input file (any format, may be gzip compressed)") @@ -447,7 +449,7 @@ BD_PUBLIC int strmxor (int argc, char *argv[]) cmd.parse (argc, argv); if (top_a.empty () != top_b.empty ()) { - throw tl::Exception ("Both -ta|--top-a and -tb|--top-b top cells must be given"); + throw tl::Exception ("Both -ta|--top-a and -tb|--top-b top cells must be given, not just one of them"); } if (tolerances.empty ()) { diff --git a/src/buddies/unit_tests/bdStrmxorTests.cc b/src/buddies/unit_tests/bdStrmxorTests.cc index c065bbb43..bb06a9428 100644 --- a/src/buddies/unit_tests/bdStrmxorTests.cc +++ b/src/buddies/unit_tests/bdStrmxorTests.cc @@ -129,6 +129,48 @@ TEST(1A_Deep) std::string output = this->tmp_file ("tmp.oas"); + const char *argv[] = { "x", "--deep", "--drop-empty-cells=false", input_a.c_str (), input_b.c_str (), output.c_str () }; + + EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); + + db::Layout layout; + + { + tl::InputStream stream (output); + db::Reader reader (stream); + reader.read (layout); + } + + db::compare_layouts (this, layout, au, db::NormalizationMode (db::NoNormalization | db::AsPolygons)); + EXPECT_EQ (cap.captured_text (), + "Layer 10/0 is not present in first layout, but in second\n" + "Result summary (layers without differences are not shown):\n" + "\n" + " Layer Output Differences (hierarchical shape count)\n" + " ----------------------------------------------------------------\n" + " 3/0 3/0 3\n" + " 6/0 6/0 314\n" + " 8/1 8/1 1\n" + " 10/0 - (no such layer in first layout)\n" + "\n" + ); +} + +TEST(1A_DeepNoEmptyCells) +{ + tl::CaptureChannel cap; + + std::string input_a = tl::testdata (); + input_a += "/bd/strmxor_in1.gds"; + + std::string input_b = tl::testdata (); + input_b += "/bd/strmxor_in2.gds"; + + std::string au = tl::testdata (); + au += "/bd/strmxor_au1d2.oas"; + + std::string output = this->tmp_file ("tmp.oas"); + const char *argv[] = { "x", "--deep", input_a.c_str (), input_b.c_str (), output.c_str () }; EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); @@ -342,7 +384,7 @@ TEST(2_Deep) std::string output = this->tmp_file ("tmp.oas"); - const char *argv[] = { "x", "-u", "--no-summary", "-l", input_a.c_str (), input_b.c_str (), output.c_str () }; + const char *argv[] = { "x", "-u", "--no-summary", "--drop-empty-cells=false", "-l", input_a.c_str (), input_b.c_str (), output.c_str () }; EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); @@ -508,7 +550,7 @@ TEST(3_Deep) std::string output = this->tmp_file ("tmp.oas"); // NOTE: -p is ignored in deep mode - const char *argv[] = { "x", "-u", "--no-summary", "-p=1.0", "-n=4", input_a.c_str (), input_b.c_str (), output.c_str () }; + const char *argv[] = { "x", "-u", "--drop-empty-cells=false", "--no-summary", "-p=1.0", "-n=4", input_a.c_str (), input_b.c_str (), output.c_str () }; EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); @@ -607,7 +649,7 @@ TEST(4_Deep) std::string output = this->tmp_file ("tmp.oas"); - const char *argv[] = { "x", "-u", "--no-summary", "-p=1.0", "-n=4", "-t=0.0,0.005,0.01,0.02,0.09,0.1", input_a.c_str (), input_b.c_str (), output.c_str () }; + const char *argv[] = { "x", "-u", "--drop-empty-cells=false", "--no-summary", "-p=1.0", "-n=4", "-t=0.0,0.005,0.01,0.02,0.09,0.1", input_a.c_str (), input_b.c_str (), output.c_str () }; EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); @@ -673,7 +715,7 @@ TEST(5_Deep) std::string output = this->tmp_file ("tmp.oas"); - const char *argv[] = { "x", "-u", "--no-summary", "-b=1000", "-t=0.0,0.005,0.01,0.02,0.09,0.1", input_a.c_str (), input_b.c_str (), output.c_str () }; + const char *argv[] = { "x", "-u", "--drop-empty-cells=false", "--no-summary", "-b=1000", "-t=0.0,0.005,0.01,0.02,0.09,0.1", input_a.c_str (), input_b.c_str (), output.c_str () }; EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); diff --git a/testdata/bd/strmxor_au1d2.oas b/testdata/bd/strmxor_au1d2.oas new file mode 100644 index 0000000000000000000000000000000000000000..e4802b448e2755b0f0c5de7b8c542b3f0075eaff GIT binary patch literal 714 zcmY!lcJ=kt^>+;R4CduxWH!_@V0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F; z;|1o9>4KX(8~>b$4qRRSKbqrK6n{_8gJqf4>PjZKWjDxlFOecr#8*H*VHd*(k7XJ+yA3p0`tXW*z}hJ+-D ZJ&TcvaT7Bm1EVryF_2_v7-4{c0RWxDG#dZ_ literal 0 HcmV?d00001