From db981b0f7d2222f3dce8057cb4562b461773c233 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 8 Oct 2018 23:31:22 +0200 Subject: [PATCH 1/6] A huge patch to make Windows build functional again after recent updates The issue was: for MacOS/clang, the virtual format-specific option structs had to be embedded in one compile unit (for RTTI). In Windows this will lead to link errors since the DLL is not reachable at build time for the generic reader/writer configuration in the buddy tools. The solution is to use GSI methods (provided for scripting) to set the reader/writer options in a generic way that does not require linking against the plugin DLLs. --- src/buddies/src/bd/bd.pro | 10 -- src/buddies/src/bd/bdReaderOptions.cc | 101 ++++++++++----- src/buddies/src/bd/bdReaderOptions.h | 41 ++++-- src/buddies/src/bd/bdWriterOptions.cc | 117 ++++++++++++------ src/buddies/src/bd/bdWriterOptions.h | 45 +++++-- src/buddies/src/bd/strmclip.cc | 4 +- src/buddies/src/bd/strmrun.cc | 2 - src/buddies/unit_tests/bdBasicTests.cc | 5 + src/db/db/dbLoadLayoutOptions.cc | 30 +++++ src/db/db/dbLoadLayoutOptions.h | 18 +++ src/db/db/dbSaveLayoutOptions.cc | 30 +++++ src/db/db/dbSaveLayoutOptions.h | 20 +++ src/db/db/gsiDeclDbCommonStreamOptions.cc | 11 ++ src/db/unit_tests/dbLoadLayoutOptionsTests.cc | 104 ++++++++++++++++ src/db/unit_tests/dbSaveLayoutOptionsTests.cc | 104 ++++++++++++++++ src/db/unit_tests/unit_tests.pro | 4 +- .../streamers/cif/db_plugin/gsiDeclDbCIF.cc | 12 ++ .../streamers/dxf/db_plugin/gsiDeclDbDXF.cc | 12 ++ .../oasis/db_plugin/gsiDeclDbOASIS.cc | 63 ++++++++++ src/unit_tests/unit_test_main.cc | 84 ++++++------- 20 files changed, 667 insertions(+), 150 deletions(-) create mode 100644 src/db/unit_tests/dbLoadLayoutOptionsTests.cc create mode 100644 src/db/unit_tests/dbSaveLayoutOptionsTests.cc diff --git a/src/buddies/src/bd/bd.pro b/src/buddies/src/bd/bd.pro index 4a11a6fdf..1b80e94f2 100644 --- a/src/buddies/src/bd/bd.pro +++ b/src/buddies/src/bd/bd.pro @@ -35,16 +35,6 @@ INCLUDEPATH += $$TL_INC $$GSI_INC $$VERSION_INC $$DB_INC $$LIB_INC $$RDB_INC DEPENDPATH += $$TL_INC $$GSI_INC $$VERSION_INC $$DB_INC $$LIB_INC $$RDB_INC LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi -lklayout_lib -lklayout_rdb -PLUGINPATH += \ - $$PWD/../../../plugins/common \ - $$PWD/../../../plugins/streamers/gds2/db_plugin \ - $$PWD/../../../plugins/streamers/cif/db_plugin \ - $$PWD/../../../plugins/streamers/oasis/db_plugin \ - $$PWD/../../../plugins/streamers/dxf/db_plugin \ - -INCLUDEPATH += $$PLUGINPATH -DEPENDPATH += $$PLUGINPATH - INCLUDEPATH += $$RBA_INC DEPENDPATH += $$RBA_INC diff --git a/src/buddies/src/bd/bdReaderOptions.cc b/src/buddies/src/bd/bdReaderOptions.cc index 12dceaab8..f5832d279 100644 --- a/src/buddies/src/bd/bdReaderOptions.cc +++ b/src/buddies/src/bd/bdReaderOptions.cc @@ -28,7 +28,27 @@ namespace bd { GenericReaderOptions::GenericReaderOptions () - : m_prefix ("i"), m_group_prefix ("Input"), m_create_other_layers (true) + : m_prefix ("i"), m_group_prefix ("Input"), m_create_other_layers (true), + m_common_enable_text_objects (true), + m_common_enable_properties (true), + m_gds2_box_mode (1), + m_gds2_allow_big_records (true), + m_gds2_allow_multi_xy_records (true), + m_oasis_read_all_properties (true), + m_oasis_expect_strict_mode (-1), + m_cif_wire_mode (0), + m_cif_dbu (0.001), + m_cif_keep_layer_names (false), + m_dxf_dbu (0.001), + m_dxf_unit (1.0), + m_dxf_text_scaling (100.0), + m_dxf_polyline_mode (0), + m_dxf_circle_points (100), + m_dxf_circle_accuracy (0.0), + m_dxf_contour_accuracy (0.0), + m_dxf_render_texts_as_polygons (false), + m_dxf_keep_layer_names (false), + m_dxf_keep_other_cells (false) { // .. nothing yet .. } @@ -79,11 +99,11 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) std::string group ("[" + m_group_prefix + " options - GDS2 and OASIS specific]"); cmd << tl::arg (group + - "#!--" + m_long_prefix + "no-texts", &m_common_reader_options.enable_text_objects, "Skips text objects", + "#!--" + m_long_prefix + "no-texts", &m_common_enable_text_objects, "Skips text objects", "With this option set, text objects won't be read." ) << tl::arg (group + - "#!--" + m_long_prefix + "no-properties", &m_common_reader_options.enable_properties, "Skips properties", + "#!--" + m_long_prefix + "no-properties", &m_common_enable_properties, "Skips properties", "With this option set, properties won't be read." ) ; @@ -93,20 +113,20 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) std::string group ("[" + m_group_prefix + " options - GDS2 specific]"); cmd << tl::arg (group + - "#!--" + m_long_prefix + "no-multi-xy-records", &m_gds2_reader_options.allow_multi_xy_records, "Gives an error on multi-XY records", + "#!--" + m_long_prefix + "no-multi-xy-records", &m_gds2_allow_multi_xy_records, "Gives an error on multi-XY records", "This option disables an advanced interpretation of GDS2 which allows unlimited polygon and path " "complexity. For compatibility with other readers, this option restores the standard behavior and " "disables this feature." ) << tl::arg (group + - "#!--" + m_long_prefix + "no-big-records", &m_gds2_reader_options.allow_big_records, "Gives an error on big (>32767 bytes) records", + "#!--" + m_long_prefix + "no-big-records", &m_gds2_allow_big_records, "Gives an error on big (>32767 bytes) records", "The GDS2 specification claims the record length to be a signed 16 bit value. So a record " "can be 32767 bytes max. To allow bigger records (i.e. bigger polygons), the usual approach " "is to take the length as a unsigned 16 bit value, so the length is up to 65535 bytes. " "This option restores the original behavior and reports big (>32767 bytes) records are errors." ) << tl::arg (group + - "-" + m_prefix + "b|--" + m_long_prefix + "box-mode=mode", &m_gds2_reader_options.box_mode, "Specifies how BOX records are read", + "-" + m_prefix + "b|--" + m_long_prefix + "box-mode=mode", &m_gds2_box_mode, "Specifies how BOX records are read", "This an option provided for compatibility with other readers. The mode value specifies how " "BOX records are read:\n" "\n" @@ -122,7 +142,7 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) std::string group ("[" + m_group_prefix + " options - OASIS specific]"); cmd << tl::arg (group + - "#--" + m_long_prefix + "expect-strict-mode=mode", &m_oasis_reader_options.expect_strict_mode, "Makes the reader expect strict or non-strict mode", + "#--" + m_long_prefix + "expect-strict-mode=mode", &m_oasis_expect_strict_mode, "Makes the reader expect strict or non-strict mode", "With this option, the OASIS reader will expect strict mode (mode is 1) or expect non-strict mode " "(mode is 0). By default, both modes are allowed. This is a diagnostic feature and does not " "have any other effect than checking the mode." @@ -150,7 +170,7 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) std::string group ("[" + m_group_prefix + " options - CIF specific]"); cmd << tl::arg (group + - "-" + m_prefix + "w|--" + m_long_prefix + "wire-mode=mode", &m_cif_reader_options.wire_mode, "Specifies how wires (W) are read", + "-" + m_prefix + "w|--" + m_long_prefix + "wire-mode=mode", &m_cif_wire_mode, "Specifies how wires (W) are read", "This option specifies how wire objects (W) are read:\n" "\n" "* 0: as square ended paths (the default)\n" @@ -164,19 +184,19 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) std::string group ("[" + m_group_prefix + " options - DXF specific]"); cmd << tl::arg (group + - "-" + m_prefix + "u|--" + m_long_prefix + "dxf-unit=unit", &m_dxf_reader_options.unit, "Specifies the DXF drawing units", + "-" + m_prefix + "u|--" + m_long_prefix + "dxf-unit=unit", &m_dxf_unit, "Specifies the DXF drawing units", "Since DXF is unitless, this value needs to be given to specify the drawing units. " "By default, a drawing unit of micrometers is assumed." ) << tl::arg (group + - "#--" + m_long_prefix + "dxf-text-scaling=factor", &m_dxf_reader_options.text_scaling, "Specifies text scaling", + "#--" + m_long_prefix + "dxf-text-scaling=factor", &m_dxf_text_scaling, "Specifies text scaling", "This value specifies text scaling in percent. A value of 100 roughly means that the letter " "pitch of the font will be 92% of the specified text height. That value applies for ROMANS fonts. " "When generating GDS texts, a value of 100 generates TEXT objects with " "the specified size. Smaller values generate smaller sizes." ) << tl::arg (group + - "#--" + m_long_prefix + "dxf-polyline-mode=mode", &m_dxf_reader_options.polyline_mode, "Specifies how POLYLINE records are handled", + "#--" + m_long_prefix + "dxf-polyline-mode=mode", &m_dxf_polyline_mode, "Specifies how POLYLINE records are handled", "This value specifies how POLYLINE records are handled:\n" "\n" "* 0: automatic mode (default)\n" @@ -186,11 +206,11 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) "* 4: as 3 and auto-close contours" ) << tl::arg (group + - "#--" + m_long_prefix + "dxf-circle-points=points", &m_dxf_reader_options.circle_points, "Specifies the number of points for a full circle for arc interpolation", + "#--" + m_long_prefix + "dxf-circle-points=points", &m_dxf_circle_points, "Specifies the number of points for a full circle for arc interpolation", "See --" + m_long_prefix + "dxf-circle-accuracy for another way of specifying the number of points per circle." ) << tl::arg (group + - "#--" + m_long_prefix + "dxf-circle-accuracy=value", &m_dxf_reader_options.circle_accuracy, "Specifies the accuracy of circle approximation", + "#--" + m_long_prefix + "dxf-circle-accuracy=value", &m_dxf_circle_accuracy, "Specifies the accuracy of circle approximation", "This value specifies the approximation accuracy of the circle and other\n" "\"round\" structures. If this value is a positive number bigger than the\n" "database unit (see dbu), it will control the number of points the\n" @@ -203,16 +223,16 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) "The value is given in the units of the DXF file." ) << tl::arg (group + - "#--" + m_long_prefix + "dxf-contour-accuracy=value", &m_dxf_reader_options.contour_accuracy, "Specifies the point accuracy for contour closing", + "#--" + m_long_prefix + "dxf-contour-accuracy=value", &m_dxf_contour_accuracy, "Specifies the point accuracy for contour closing", "This value specifies the distance (in units of the DXF file) by which points can be separated and still\n" "be considered to be connected. This value is effective in polyline mode 3 and 4.\n" ) << tl::arg (group + - "#--" + m_long_prefix + "dxf-render-texts-as-polygons", &m_dxf_reader_options.render_texts_as_polygons, "Renders texts as polygons", + "#--" + m_long_prefix + "dxf-render-texts-as-polygons", &m_dxf_render_texts_as_polygons, "Renders texts as polygons", "If this option is used, texts are converted to polygons instead of being converted to labels." ) << tl::arg (group + - "#--" + m_long_prefix + "dxf-keep-other-cells", &m_dxf_reader_options.keep_other_cells, "Keeps cells which are not instantiated by the top cell", + "#--" + m_long_prefix + "dxf-keep-other-cells", &m_dxf_keep_other_cells, "Keeps cells which are not instantiated by the top cell", "With this option, all cells not found to be instantiated are kept as additional top cells. " "By default, such cells are removed." ) @@ -234,36 +254,49 @@ void GenericReaderOptions::set_layer_map (const std::string &lm) void GenericReaderOptions::set_read_named_layers (bool f) { - m_dxf_reader_options.keep_layer_names = f; - m_cif_reader_options.keep_layer_names = f; + m_dxf_keep_layer_names = f; + m_cif_keep_layer_names = f; } void GenericReaderOptions::set_dbu (double dbu) { - m_dxf_reader_options.dbu = dbu; - m_cif_reader_options.dbu = dbu; + m_dxf_dbu = dbu; + m_cif_dbu = dbu; } void GenericReaderOptions::configure (db::LoadLayoutOptions &load_options) const { - db::CommonReaderOptions common_reader_options = m_common_reader_options; - common_reader_options.layer_map = m_layer_map; - common_reader_options.create_other_layers = m_create_other_layers; + load_options.set_option_by_name ("layer_map", tl::Variant::make_variant (m_layer_map)); + load_options.set_option_by_name ("create_other_layers", m_create_other_layers); + load_options.set_option_by_name ("text_enabled", m_common_enable_text_objects); + load_options.set_option_by_name ("properties_enabled", m_common_enable_properties); - db::DXFReaderOptions dxf_reader_options = m_dxf_reader_options; - dxf_reader_options.layer_map = m_layer_map; - dxf_reader_options.create_other_layers = m_create_other_layers; + load_options.set_option_by_name ("gds2_box_mode", m_gds2_box_mode); + load_options.set_option_by_name ("gds2_allow_big_records", m_gds2_allow_big_records); + load_options.set_option_by_name ("gds2_allow_multi_xy_records", m_gds2_allow_multi_xy_records); - db::CIFReaderOptions cif_reader_options = m_cif_reader_options; - cif_reader_options.layer_map = m_layer_map; - cif_reader_options.create_other_layers = m_create_other_layers; + load_options.set_option_by_name ("oasis_read_all_properties", m_oasis_read_all_properties); + load_options.set_option_by_name ("oasis_expect_strict_mode", m_oasis_expect_strict_mode); - load_options.set_options (common_reader_options); - load_options.set_options (m_gds2_reader_options); - load_options.set_options (m_oasis_reader_options); - load_options.set_options (cif_reader_options); - load_options.set_options (dxf_reader_options); + load_options.set_option_by_name ("cif_layer_map", tl::Variant::make_variant (m_layer_map)); + load_options.set_option_by_name ("cif_create_other_layers", m_create_other_layers); + load_options.set_option_by_name ("cif_dbu", m_dxf_dbu); + load_options.set_option_by_name ("cif_wire_mode", m_cif_wire_mode); + load_options.set_option_by_name ("cif_keep_layer_names", m_cif_keep_layer_names); + + load_options.set_option_by_name ("dxf_layer_map", tl::Variant::make_variant (m_layer_map)); + load_options.set_option_by_name ("dxf_create_other_layers", m_create_other_layers); + load_options.set_option_by_name ("dxf_dbu", m_dxf_dbu); + load_options.set_option_by_name ("dxf_unit", m_dxf_unit); + load_options.set_option_by_name ("dxf_text_scaling", m_dxf_text_scaling); + load_options.set_option_by_name ("dxf_polyline_mode", m_dxf_polyline_mode); + load_options.set_option_by_name ("dxf_circle_points", m_dxf_circle_points); + load_options.set_option_by_name ("dxf_circle_accuracy", m_dxf_circle_accuracy); + load_options.set_option_by_name ("dxf_contour_accuracy", m_dxf_contour_accuracy); + load_options.set_option_by_name ("dxf_render_texts_as_polygons", m_dxf_render_texts_as_polygons); + load_options.set_option_by_name ("dxf_keep_layer_names", m_dxf_keep_layer_names); + load_options.set_option_by_name ("dxf_keep_other_cells", m_dxf_keep_other_cells); } } diff --git a/src/buddies/src/bd/bdReaderOptions.h b/src/buddies/src/bd/bdReaderOptions.h index e59304e1e..fe71b310f 100644 --- a/src/buddies/src/bd/bdReaderOptions.h +++ b/src/buddies/src/bd/bdReaderOptions.h @@ -25,10 +25,6 @@ #include "bdCommon.h" #include "dbCommonReader.h" -#include "dbGDS2Format.h" -#include "dbOASISFormat.h" -#include "dbDXFFormat.h" -#include "dbCIFFormat.h" #include @@ -99,13 +95,40 @@ public: private: std::string m_prefix, m_long_prefix, m_group_prefix; + + // generic db::LayerMap m_layer_map; bool m_create_other_layers; - db::CommonReaderOptions m_common_reader_options; - db::GDS2ReaderOptions m_gds2_reader_options; - db::OASISReaderOptions m_oasis_reader_options; - db::CIFReaderOptions m_cif_reader_options; - db::DXFReaderOptions m_dxf_reader_options; + + // common GDS2+OASIS + bool m_common_enable_text_objects; + bool m_common_enable_properties; + + // GDS2 + unsigned int m_gds2_box_mode; + bool m_gds2_allow_big_records; + bool m_gds2_allow_multi_xy_records; + + // OASIS + bool m_oasis_read_all_properties; + int m_oasis_expect_strict_mode; + + // CIF + unsigned int m_cif_wire_mode; + double m_cif_dbu; + bool m_cif_keep_layer_names; + + // DXF + double m_dxf_dbu; + double m_dxf_unit; + double m_dxf_text_scaling; + int m_dxf_polyline_mode; + int m_dxf_circle_points; + double m_dxf_circle_accuracy; + double m_dxf_contour_accuracy; + bool m_dxf_render_texts_as_polygons; + bool m_dxf_keep_layer_names; + bool m_dxf_keep_other_cells; void set_layer_map (const std::string &lm); void set_dbu (double dbu); diff --git a/src/buddies/src/bd/bdWriterOptions.cc b/src/buddies/src/bd/bdWriterOptions.cc index 2d557cad6..210d39468 100644 --- a/src/buddies/src/bd/bdWriterOptions.cc +++ b/src/buddies/src/bd/bdWriterOptions.cc @@ -30,21 +30,43 @@ namespace bd { GenericWriterOptions::GenericWriterOptions () - : m_scale_factor (1.0), m_dbu (0.0), - m_dont_write_empty_cells (false), m_keep_instances (false), m_write_context_info (true) + : m_scale_factor (1.0), + m_dbu (0.0), + m_dont_write_empty_cells (false), + m_keep_instances (false), + m_write_context_info (true), + m_gds2_max_vertex_count (8000), + m_gds2_no_zero_length_paths (false), + m_gds2_multi_xy_records (false), + m_gds2_max_cellname_length (32000), + m_gds2_libname ("LIB"), + m_gds2_user_units (1.0), + m_gds2_write_timestamps (true), + m_gds2_write_cell_properties (false), + m_gds2_write_file_properties (false), + m_oasis_compression_level (2), + m_oasis_write_cblocks (false), + m_oasis_strict_mode (false), + m_oasis_recompress (false), + m_oasis_permissive (false), + m_oasis_write_std_properties (1), + m_oasis_subst_char ("*"), + m_cif_dummy_calls (false), + m_cif_blank_separator (false), + m_dxf_polygon_mode (0) { // .. nothing yet .. } +const std::string GenericWriterOptions::m_gds2_format_name = "GDS2"; +const std::string GenericWriterOptions::m_gds2text_format_name = "GDS2Text"; // no special options +const std::string GenericWriterOptions::m_oasis_format_name = "OASIS"; +const std::string GenericWriterOptions::m_dxf_format_name = "DXF"; +const std::string GenericWriterOptions::m_cif_format_name = "CIF"; + void GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::string &format) { - const std::string gds2_format_name = m_gds2_writer_options.format_name (); - const std::string gds2text_format_name = gds2_format_name + "Text"; // no special options - const std::string oasis_format_name = m_oasis_writer_options.format_name (); - const std::string dxf_format_name = m_dxf_writer_options.format_name (); - const std::string cif_format_name = m_cif_writer_options.format_name (); - std::string group ("[Output options - General]"); cmd << tl::arg (group + @@ -53,7 +75,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin "given factor." ); - if (format.empty () || format == gds2_format_name || format == gds2text_format_name || format == oasis_format_name) { + if (format.empty () || format == m_gds2_format_name || format == m_gds2text_format_name || format == m_oasis_format_name) { cmd << tl::arg (group + "-od|--dbu-out=dbu", &m_dbu, "Uses the specified database unit", "Specifies the database unit to save the layout in. The database unit is given " @@ -68,7 +90,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin "If given, empty cells won't be written. See --keep-instances for more options." ); - if (format.empty () || format == gds2_format_name || format == gds2text_format_name) { + if (format.empty () || format == m_gds2_format_name || format == m_gds2text_format_name) { cmd << tl::arg (group + "#--keep-instances", &m_keep_instances, "Keeps instances of dropped cells", "If given, instances of dropped cell's won't be removed. Hence, ghost cells are " @@ -79,7 +101,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin ); } - if (format.empty () || format == gds2_format_name || format == gds2text_format_name || format == oasis_format_name) { + if (format.empty () || format == m_gds2_format_name || format == m_gds2text_format_name || format == m_oasis_format_name) { cmd << tl::arg (group + "!#--no-context-info", &m_write_context_info, "Does not write context information", "Context information is included to maintain PCell parameters and library connections. " @@ -110,53 +132,53 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin "* \"TOP,-A\" - Select cell TOP (plus children), then remove A (with children)" ); - if (format.empty () || format == gds2_format_name || format == gds2text_format_name) { + if (format.empty () || format == m_gds2_format_name || format == m_gds2text_format_name) { // Add GDS2 and GDS2Text format options std::string group = "[Output options - GDS2 specific]"; cmd << tl::arg (group + - "-ov|--max-vertex-count=count", &m_gds2_writer_options.max_vertex_count, "Specifies the maximum number of points per polygon", + "-ov|--max-vertex-count=count", &m_gds2_max_vertex_count, "Specifies the maximum number of points per polygon", "If this number is given, polygons are cut into smaller parts if they have more " "than the specified number of points. If not given, the maximum number of points will be used. " "This is 8190 unless --multi-xy-records is given." ) << tl::arg (group + - "#--multi-xy-records", &m_gds2_writer_options.multi_xy_records, "Allows unlimited number of points", + "#--multi-xy-records", &m_gds2_multi_xy_records, "Allows unlimited number of points", "If this option is given, multiple XY records will be written to accomodate an unlimited number " "of points per polygon or path. However, such files may not be compatible with some consumers." ) << tl::arg (group + - "#--no-zero-length-paths", &m_gds2_writer_options.no_zero_length_paths, "Converts zero-length paths to polygons", + "#--no-zero-length-paths", &m_gds2_no_zero_length_paths, "Converts zero-length paths to polygons", "If this option is given, zero-length paths (such with one point) are not written as paths " "but converted to polygons. This avoids compatibility issues with consumers of this layout file." ) << tl::arg (group + - "-on|--cellname-length=length", &m_gds2_writer_options.max_cellname_length, "Limits cell names to the given length", + "-on|--cellname-length=length", &m_gds2_max_cellname_length, "Limits cell names to the given length", "If this option is given, long cell names will truncated if their length exceeds the given length." ) << tl::arg (group + - "-ol|--libname=libname", &m_gds2_writer_options.libname, "Uses the given library name", + "-ol|--libname=libname", &m_gds2_libname, "Uses the given library name", "This option can specify the GDS2 LIBNAME for the output file. By default, the original LIBNAME is " "written." ) << tl::arg (group + - "#--user-units=unit", &m_gds2_writer_options.user_units, "Specifies the user unit to use", + "#--user-units=unit", &m_gds2_user_units, "Specifies the user unit to use", "Specifies the GDS2 user unit. By default micrometers are used for the user unit." ) << tl::arg (group + - "#!--no-timestamps", &m_gds2_writer_options.write_timestamps, "Don't write timestamps", + "#!--no-timestamps", &m_gds2_write_timestamps, "Don't write timestamps", "Writes a dummy time stamp instead of the actual time. With this option, GDS2 files become " "bytewise indentical even if written at different times. This option is useful if binary " "identity is important (i.e. in regression scenarios)." ) << tl::arg (group + - "#--write-cell-properties", &m_gds2_writer_options.write_cell_properties, "Write cell properties", + "#--write-cell-properties", &m_gds2_write_cell_properties, "Write cell properties", "This option enables a GDS2 extension that allows writing of cell properties to GDS2 files. " "Consumers that don't support this feature, may not be able to read such a GDS2 files." ) << tl::arg (group + - "#--write-file-properties", &m_gds2_writer_options.write_file_properties, "Write file properties", + "#--write-file-properties", &m_gds2_write_file_properties, "Write file properties", "This option enables a GDS2 extension that allows writing of file properties to GDS2 files. " "Consumers that don't support this feature, may not be able to read such a GDS2 files." ) @@ -164,13 +186,13 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin } - if (format.empty () || format == oasis_format_name) { + if (format.empty () || format == m_oasis_format_name) { // Add OASIS format options std::string group = "[Output options - OASIS specific]"; cmd << tl::arg (group + - "-ok|--compression-level=level", &m_oasis_writer_options.compression_level, "Specifies the OASIS compression level", + "-ok|--compression-level=level", &m_oasis_compression_level, "Specifies the OASIS compression level", "This level describes how hard the OASIS writer will try to compress the shapes " "using shape arrays. Building shape arrays may take some time and requires some memory. " "The default compression level is 2.\n" @@ -179,23 +201,23 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin "* 2++ - enhanced shape array search algorithm using 2nd and further neighbor distances as well\n" ) << tl::arg (group + - "-ob|--cblocks", &m_oasis_writer_options.write_cblocks, "Uses CBLOCK compression" + "-ob|--cblocks", &m_oasis_write_cblocks, "Uses CBLOCK compression" ) << tl::arg (group + - "-ot|--strict-mode", &m_oasis_writer_options.strict_mode, "Uses strict mode" + "-ot|--strict-mode", &m_oasis_strict_mode, "Uses strict mode" ) << tl::arg (group + - "#--recompress", &m_oasis_writer_options.recompress, "Compresses shape arrays again", + "#--recompress", &m_oasis_recompress, "Compresses shape arrays again", "With this option, shape arrays will be expanded and recompressed. This may result in a better " "compression ratio, but at the cost of slower execution." ) << tl::arg (group + - "#--permissive", &m_oasis_writer_options.permissive, "Permissive mode", + "#--permissive", &m_oasis_permissive, "Permissive mode", "In permissive mode, certain forbidden objects are reported as warnings, not as errors: " "paths with odd width, polygons with less than three points etc." ) << tl::arg (group + - "#--write-std-properties", &m_oasis_writer_options.write_std_properties, "Writes some global standard properties", + "#--write-std-properties", &m_oasis_write_std_properties, "Writes some global standard properties", "This is an integer describing what standard properties shall be written. 0 is \"none\", " "1 means \"global standard properties such as S_TOP_CELL\" are produced (the default). With 2 also per-cell bounding " "boxes are produced." @@ -209,13 +231,13 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin } - if (format.empty () || format == dxf_format_name) { + if (format.empty () || format == m_dxf_format_name) { // Add DXF format options std::string group = "[Output options - DXF specific]"; cmd << tl::arg (group + - "-op|--polygon-mode=mode", &m_dxf_writer_options.polygon_mode, "Specifies how to write polygons", + "-op|--polygon-mode=mode", &m_dxf_polygon_mode, "Specifies how to write polygons", "This option specifies how to write polygons:\n" "* 0: create POLYLINE (default)\n" "* 1: create LWPOLYLINE\n" @@ -226,17 +248,17 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin } - if (format.empty () || format == cif_format_name) { + if (format.empty () || format == m_cif_format_name) { // Add CIF format options std::string group = "[Output options - CIF specific]"; cmd << tl::arg (group + - "#--dummy-calls", &m_cif_writer_options.dummy_calls, "Produces dummy calls", + "#--dummy-calls", &m_cif_dummy_calls, "Produces dummy calls", "If this option is given, the writer will produce dummy cell calls on global level for all top cells" ) << tl::arg (group + - "#--blank-separator", &m_cif_writer_options.blank_separator, "Uses blanks as x/y separators", + "#--blank-separator", &m_cif_blank_separator, "Uses blanks as x/y separators", "If this option is given, blank characters will be used to separate x and y values. " "Otherwise comma characters will be used.\n" "Use this option if your CIF consumer cannot read comma characters as x/y separators." @@ -249,7 +271,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin void GenericWriterOptions::set_oasis_substitution_char (const std::string &text) { if (! text.empty ()) { - m_oasis_writer_options.subst_char = text[0]; + m_oasis_subst_char = text[0]; } } @@ -306,10 +328,29 @@ GenericWriterOptions::configure (db::SaveLayoutOptions &save_options, const db:: save_options.set_keep_instances (m_keep_instances); save_options.set_write_context_info (m_write_context_info); - save_options.set_options (m_gds2_writer_options); - save_options.set_options (m_oasis_writer_options); - save_options.set_options (m_dxf_writer_options); - save_options.set_options (m_cif_writer_options); + save_options.set_option_by_name ("gds2_max_vertex_count", m_gds2_max_vertex_count); + save_options.set_option_by_name ("gds2_no_zero_length_paths", m_gds2_no_zero_length_paths); + save_options.set_option_by_name ("gds2_multi_xy_records", m_gds2_multi_xy_records); + save_options.set_option_by_name ("gds2_max_cellname_length", m_gds2_max_cellname_length); + save_options.set_option_by_name ("gds2_libname", m_gds2_libname); + save_options.set_option_by_name ("gds2_user_units", m_gds2_user_units); + save_options.set_option_by_name ("gds2_write_timestamps", m_gds2_write_timestamps); + save_options.set_option_by_name ("gds2_write_cell_properties", m_gds2_write_cell_properties); + save_options.set_option_by_name ("gds2_write_file_properties", m_gds2_write_file_properties); + + save_options.set_option_by_name ("oasis_compression_level", m_oasis_compression_level); + save_options.set_option_by_name ("oasis_write_cblocks", m_oasis_write_cblocks); + save_options.set_option_by_name ("oasis_strict_mode", m_oasis_strict_mode); + save_options.set_option_by_name ("oasis_recompress", m_oasis_recompress); + save_options.set_option_by_name ("oasis_permissive", m_oasis_permissive); + // Note: "..._ext" is a version taking the real value (not just a boolean) + save_options.set_option_by_name ("oasis_write_std_properties_ext", m_oasis_write_std_properties); + save_options.set_option_by_name ("oasis_substitution_char", m_oasis_subst_char); + + save_options.set_option_by_name ("cif_dummy_calls", m_cif_dummy_calls); + save_options.set_option_by_name ("cif_blank_separator", m_cif_blank_separator); + + save_options.set_option_by_name ("dxf_polygon_mode", m_dxf_polygon_mode); if (!m_cell_selection.empty ()) { diff --git a/src/buddies/src/bd/bdWriterOptions.h b/src/buddies/src/bd/bdWriterOptions.h index 4bbb218bd..2f42b3f8b 100644 --- a/src/buddies/src/bd/bdWriterOptions.h +++ b/src/buddies/src/bd/bdWriterOptions.h @@ -24,10 +24,6 @@ #define HDR_bdWriterOptions #include "bdCommon.h" -#include "dbGDS2Format.h" -#include "dbOASISFormat.h" -#include "dbDXFFormat.h" -#include "dbCIFFormat.h" #include @@ -69,7 +65,7 @@ public: */ void add_options_for_gds2 (tl::CommandLineOptions &cmd) { - add_options (cmd, m_gds2_writer_options.format_name ()); + add_options (cmd, m_gds2_format_name); } /** @@ -77,7 +73,7 @@ public: */ void add_options_for_oasis (tl::CommandLineOptions &cmd) { - add_options (cmd, m_oasis_writer_options.format_name ()); + add_options (cmd, m_oasis_format_name); } /** @@ -85,7 +81,7 @@ public: */ void add_options_for_cif (tl::CommandLineOptions &cmd) { - add_options (cmd, m_cif_writer_options.format_name ()); + add_options (cmd, m_cif_format_name); } /** @@ -93,7 +89,7 @@ public: */ void add_options_for_dxf (tl::CommandLineOptions &cmd) { - add_options (cmd, m_dxf_writer_options.format_name ()); + add_options (cmd, m_dxf_format_name); } /** @@ -109,10 +105,35 @@ private: bool m_keep_instances; bool m_write_context_info; std::string m_cell_selection; - db::GDS2WriterOptions m_gds2_writer_options; - db::OASISWriterOptions m_oasis_writer_options; - db::CIFWriterOptions m_cif_writer_options; - db::DXFWriterOptions m_dxf_writer_options; + + unsigned int m_gds2_max_vertex_count; + bool m_gds2_no_zero_length_paths; + bool m_gds2_multi_xy_records; + unsigned int m_gds2_max_cellname_length; + std::string m_gds2_libname; + double m_gds2_user_units; + bool m_gds2_write_timestamps; + bool m_gds2_write_cell_properties; + bool m_gds2_write_file_properties; + + int m_oasis_compression_level; + bool m_oasis_write_cblocks; + bool m_oasis_strict_mode; + bool m_oasis_recompress; + bool m_oasis_permissive; + int m_oasis_write_std_properties; + std::string m_oasis_subst_char; + + bool m_cif_dummy_calls; + bool m_cif_blank_separator; + + int m_dxf_polygon_mode; + + static const std::string m_gds2_format_name; + static const std::string m_gds2text_format_name; + static const std::string m_oasis_format_name; + static const std::string m_cif_format_name; + static const std::string m_dxf_format_name; void set_oasis_substitution_char (const std::string &text); }; diff --git a/src/buddies/src/bd/strmclip.cc b/src/buddies/src/bd/strmclip.cc index c08adc750..918b93eac 100644 --- a/src/buddies/src/bd/strmclip.cc +++ b/src/buddies/src/bd/strmclip.cc @@ -24,9 +24,9 @@ #include "bdWriterOptions.h" #include "dbClip.h" #include "dbLayout.h" -#include "dbGDS2Writer.h" -#include "dbOASISWriter.h" #include "dbReader.h" +#include "dbWriter.h" +#include "dbSaveLayoutOptions.h" #include "tlLog.h" #include "tlCommandLineParser.h" diff --git a/src/buddies/src/bd/strmrun.cc b/src/buddies/src/bd/strmrun.cc index 90268871f..3ddbbeb2c 100644 --- a/src/buddies/src/bd/strmrun.cc +++ b/src/buddies/src/bd/strmrun.cc @@ -24,8 +24,6 @@ #include "bdWriterOptions.h" #include "gsiInterpreter.h" #include "dbLayout.h" -#include "dbGDS2Writer.h" -#include "dbOASISWriter.h" #include "dbReader.h" #include "tlLog.h" #include "tlCommandLineParser.h" diff --git a/src/buddies/unit_tests/bdBasicTests.cc b/src/buddies/unit_tests/bdBasicTests.cc index d48438f30..0b5080835 100644 --- a/src/buddies/unit_tests/bdBasicTests.cc +++ b/src/buddies/unit_tests/bdBasicTests.cc @@ -26,6 +26,11 @@ #include "tlUnitTest.h" #include "dbLayout.h" #include "dbCell.h" +#include "dbSaveLayoutOptions.h" +#include "dbCIFFormat.h" +#include "dbDXFFormat.h" +#include "dbOASISFormat.h" +#include "dbGDS2Format.h" // Testing writer options TEST(1) diff --git a/src/db/db/dbLoadLayoutOptions.cc b/src/db/db/dbLoadLayoutOptions.cc index a1e196941..7e8aa8206 100644 --- a/src/db/db/dbLoadLayoutOptions.cc +++ b/src/db/db/dbLoadLayoutOptions.cc @@ -25,6 +25,7 @@ #include "dbStream.h" #include "tlClassRegistry.h" #include "tlStream.h" +#include "tlExpression.h" namespace db { @@ -105,5 +106,34 @@ namespace db return 0; } } + + void + LoadLayoutOptions::set_option_by_name (const std::string &method, const tl::Variant &value) + { + // Utilizes the GSI binding to set the values + tl::Variant options_ref = tl::Variant::make_variant_ref (this); + const tl::EvalClass *eval_cls = options_ref.user_cls ()->eval_cls (); + tl::ExpressionParserContext context; + + tl::Variant out; + std::vector args; + args.push_back (value); + eval_cls->execute (context, out, options_ref, method + "=", args); + } + + tl::Variant + LoadLayoutOptions::get_option_by_name (const std::string &method) + { + // Utilizes the GSI binding to set the values + tl::Variant options_ref = tl::Variant::make_variant_ref (this); + const tl::EvalClass *eval_cls = options_ref.user_cls ()->eval_cls (); + tl::ExpressionParserContext context; + + tl::Variant out; + std::vector args; + eval_cls->execute (context, out, options_ref, method, args); + + return out; + } } diff --git a/src/db/db/dbLoadLayoutOptions.h b/src/db/db/dbLoadLayoutOptions.h index 409e5706b..3a8452951 100644 --- a/src/db/db/dbLoadLayoutOptions.h +++ b/src/db/db/dbLoadLayoutOptions.h @@ -33,6 +33,8 @@ #include "dbStreamLayers.h" #include "gsiObject.h" +#include "gsiClass.h" +#include "tlVariant.h" namespace db { @@ -182,6 +184,22 @@ public: */ FormatSpecificReaderOptions *get_options (const std::string &name); + /** + * @brief Sets a layout reader option by name + * + * The name is taken to be a GSI method which is called to set the + * option. For example, setting "gds2_unit", the method "gds2_unit=" is + * called with the given value. + */ + void set_option_by_name (const std::string &name, const tl::Variant &value); + + /** + * @brief Gets a layout reader option by name + * + * See "set_option_by_name" for details. + */ + tl::Variant get_option_by_name (const std::string &name); + private: std::map m_options; diff --git a/src/db/db/dbSaveLayoutOptions.cc b/src/db/db/dbSaveLayoutOptions.cc index 269211989..19155e2af 100644 --- a/src/db/db/dbSaveLayoutOptions.cc +++ b/src/db/db/dbSaveLayoutOptions.cc @@ -25,6 +25,7 @@ #include "dbStream.h" #include "tlClassRegistry.h" #include "tlStream.h" +#include "tlExpression.h" namespace db { @@ -125,6 +126,35 @@ SaveLayoutOptions::get_options (const std::string &format) } } +void +SaveLayoutOptions::set_option_by_name (const std::string &method, const tl::Variant &value) +{ + // Utilizes the GSI binding to set the values + tl::Variant options_ref = tl::Variant::make_variant_ref (this); + const tl::EvalClass *eval_cls = options_ref.user_cls ()->eval_cls (); + tl::ExpressionParserContext context; + + tl::Variant out; + std::vector args; + args.push_back (value); + eval_cls->execute (context, out, options_ref, method + "=", args); +} + +tl::Variant +SaveLayoutOptions::get_option_by_name (const std::string &method) +{ + // Utilizes the GSI binding to set the values + tl::Variant options_ref = tl::Variant::make_variant_ref (this); + const tl::EvalClass *eval_cls = options_ref.user_cls ()->eval_cls (); + tl::ExpressionParserContext context; + + tl::Variant out; + std::vector args; + eval_cls->execute (context, out, options_ref, method, args); + + return out; +} + void SaveLayoutOptions::set_format (const std::string &format_name) { diff --git a/src/db/db/dbSaveLayoutOptions.h b/src/db/db/dbSaveLayoutOptions.h index b49330365..77f49a808 100644 --- a/src/db/db/dbSaveLayoutOptions.h +++ b/src/db/db/dbSaveLayoutOptions.h @@ -33,6 +33,10 @@ #include "dbLayout.h" #include "dbStreamLayers.h" +#include "gsiObject.h" +#include "gsiClass.h" +#include "tlVariant.h" + namespace db { @@ -409,6 +413,22 @@ public: */ void get_cells (const db::Layout &layout, std::set &cells, const std::vector > &valid_layers) const; + /** + * @brief Sets a layout reader option by name + * + * The name is taken to be a GSI method which is called to set the + * option. For example, setting "gds2_unit", the method "gds2_unit=" is + * called with the given value. + */ + void set_option_by_name (const std::string &name, const tl::Variant &value); + + /** + * @brief Gets a layout reader option by name + * + * See "set_option_by_name" for details. + */ + tl::Variant get_option_by_name (const std::string &name); + private: std::string m_format; std::map m_layers; diff --git a/src/db/db/gsiDeclDbCommonStreamOptions.cc b/src/db/db/gsiDeclDbCommonStreamOptions.cc index ec8f2f4da..0cb974b4c 100644 --- a/src/db/db/gsiDeclDbCommonStreamOptions.cc +++ b/src/db/db/gsiDeclDbCommonStreamOptions.cc @@ -38,6 +38,11 @@ static void set_layer_map (db::LoadLayoutOptions *options, const db::LayerMap &l options->get_options ().create_other_layers = f; } +static void set_layer_map1 (db::LoadLayoutOptions *options, const db::LayerMap &lm) +{ + options->get_options ().layer_map = lm; +} + static db::LayerMap &get_layer_map (db::LoadLayoutOptions *options) { return options->get_options ().layer_map; @@ -91,6 +96,12 @@ gsi::ClassExt common_reader_options ( "\n" "Starting with version 0.25 this option only applies to GDS2 and OASIS format. Other formats provide their own configuration." ) + + gsi::method_ext ("layer_map=", &set_layer_map1, gsi::arg ("map"), + "@brief Sets the layer map, but does not affect the \"create_other_layers\" flag.\n" + "@param map The layer map to set." + "\n" + "This convenience method has been introduced with version 0.26." + ) + gsi::method_ext ("select_all_layers", &select_all_layers, "@brief Selects all layers and disables the layer map\n" "\n" diff --git a/src/db/unit_tests/dbLoadLayoutOptionsTests.cc b/src/db/unit_tests/dbLoadLayoutOptionsTests.cc new file mode 100644 index 000000000..2e59b9f1e --- /dev/null +++ b/src/db/unit_tests/dbLoadLayoutOptionsTests.cc @@ -0,0 +1,104 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#include "tlUnitTest.h" +#include "dbLoadLayoutOptions.h" +#include "gsiDecl.h" + +class MyReaderOptions + : public db::FormatSpecificReaderOptions +{ +public: + MyReaderOptions () + : db::FormatSpecificReaderOptions () + { + } + + virtual FormatSpecificReaderOptions *clone () const + { + return new MyReaderOptions (*this); + } + + virtual const std::string &format_name () const + { + static std::string fmt ("myformat"); + return fmt; + } + + std::string value; + db::LayerMap lm; +}; + +static std::string get_myreader_value (const db::LoadLayoutOptions *options) +{ + return options->get_options ().value; +} + +static void set_myreader_value (db::LoadLayoutOptions *options, const std::string &v) +{ + options->get_options ().value = v; +} + +static db::LayerMap get_myreader_lm (const db::LoadLayoutOptions *options) +{ + return options->get_options ().lm; +} + +static void set_myreader_lm (db::LoadLayoutOptions *options, const db::LayerMap &lm) +{ + options->get_options ().lm = lm; +} + + +static +gsi::ClassExt myreaderoptions_cls ( + gsi::method_ext ("myreader_value", &get_myreader_value) + + gsi::method_ext ("myreader_value=", &set_myreader_value) + + gsi::method_ext ("myreader_lm", &get_myreader_lm) + + gsi::method_ext ("myreader_lm=", &set_myreader_lm), + "@hide"); + + +TEST(1) +{ + db::LoadLayoutOptions opt; + MyReaderOptions myopt; + myopt.value = "42"; + opt.set_options (myopt); + + EXPECT_EQ (opt.get_options ().value, "42"); + EXPECT_EQ (opt.get_option_by_name ("myreader_value").to_string (), "42"); + opt.set_option_by_name ("myreader_value", tl::Variant ("abc")); + EXPECT_EQ (opt.get_option_by_name ("myreader_value").to_string (), "abc"); + + db::LayerMap lm = db::LayerMap::from_string_file_format ("1/0:2\n10/0"); + EXPECT_EQ (lm.to_string (), "layer_map('1/0 : 2/0';'10/0')"); + opt.set_option_by_name ("myreader_lm", tl::Variant::make_variant (lm)); + EXPECT_EQ (opt.get_option_by_name ("myreader_lm").to_user ().to_string (), "layer_map('1/0 : 2/0';'10/0')"); + + myopt.value = "17"; + opt.set_options (myopt); + EXPECT_EQ (opt.get_options ().value, "17"); + EXPECT_EQ (opt.get_option_by_name ("myreader_value").to_string (), "17"); +} + diff --git a/src/db/unit_tests/dbSaveLayoutOptionsTests.cc b/src/db/unit_tests/dbSaveLayoutOptionsTests.cc new file mode 100644 index 000000000..d8ecee18b --- /dev/null +++ b/src/db/unit_tests/dbSaveLayoutOptionsTests.cc @@ -0,0 +1,104 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#include "tlUnitTest.h" +#include "dbSaveLayoutOptions.h" +#include "gsiDecl.h" + +class MyWriterOptions + : public db::FormatSpecificWriterOptions +{ +public: + MyWriterOptions () + : db::FormatSpecificWriterOptions () + { + } + + virtual FormatSpecificWriterOptions *clone () const + { + return new MyWriterOptions (*this); + } + + virtual const std::string &format_name () const + { + static std::string fmt ("myformat"); + return fmt; + } + + std::string value; + db::LayerMap lm; +}; + +static std::string get_mywriter_value (const db::SaveLayoutOptions *options) +{ + return options->get_options ().value; +} + +static void set_mywriter_value (db::SaveLayoutOptions *options, const std::string &v) +{ + options->get_options ().value = v; +} + +static db::LayerMap get_mywriter_lm (const db::SaveLayoutOptions *options) +{ + return options->get_options ().lm; +} + +static void set_mywriter_lm (db::SaveLayoutOptions *options, const db::LayerMap &lm) +{ + options->get_options ().lm = lm; +} + + +static +gsi::ClassExt mywriteroptions_cls ( + gsi::method_ext ("mywriter_value", &get_mywriter_value) + + gsi::method_ext ("mywriter_value=", &set_mywriter_value) + + gsi::method_ext ("mywriter_lm", &get_mywriter_lm) + + gsi::method_ext ("mywriter_lm=", &set_mywriter_lm), + "@hide"); + + +TEST(1) +{ + db::SaveLayoutOptions opt; + MyWriterOptions myopt; + myopt.value = "42"; + opt.set_options (myopt); + + EXPECT_EQ (opt.get_options ().value, "42"); + EXPECT_EQ (opt.get_option_by_name ("mywriter_value").to_string (), "42"); + opt.set_option_by_name ("mywriter_value", tl::Variant ("abc")); + EXPECT_EQ (opt.get_option_by_name ("mywriter_value").to_string (), "abc"); + + db::LayerMap lm = db::LayerMap::from_string_file_format ("1/0:2\n10/0"); + EXPECT_EQ (lm.to_string (), "layer_map('1/0 : 2/0';'10/0')"); + opt.set_option_by_name ("mywriter_lm", tl::Variant::make_variant (lm)); + EXPECT_EQ (opt.get_option_by_name ("mywriter_lm").to_user ().to_string (), "layer_map('1/0 : 2/0';'10/0')"); + + myopt.value = "17"; + opt.set_options (myopt); + EXPECT_EQ (opt.get_options ().value, "17"); + EXPECT_EQ (opt.get_option_by_name ("mywriter_value").to_string (), "17"); +} + diff --git a/src/db/unit_tests/unit_tests.pro b/src/db/unit_tests/unit_tests.pro index 044d18021..c1a034f6a 100644 --- a/src/db/unit_tests/unit_tests.pro +++ b/src/db/unit_tests/unit_tests.pro @@ -51,7 +51,9 @@ SOURCES = \ dbTrans.cc \ dbVector.cc \ dbWriterTools.cc \ - dbVariableWidthPath.cc + dbVariableWidthPath.cc \ + dbLoadLayoutOptionsTests.cc \ + dbSaveLayoutOptionsTests.cc INCLUDEPATH += $$TL_INC $$DB_INC $$GSI_INC DEPENDPATH += $$TL_INC $$DB_INC $$GSI_INC diff --git a/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc b/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc index 6ba48bb54..db25c52c0 100644 --- a/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc +++ b/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc @@ -59,6 +59,11 @@ static void set_layer_map (db::LoadLayoutOptions *options, const db::LayerMap &l options->get_options ().create_other_layers = f; } +static void set_layer_map1 (db::LoadLayoutOptions *options, const db::LayerMap &lm) +{ + options->get_options ().layer_map = lm; +} + static db::LayerMap &get_layer_map (db::LoadLayoutOptions *options) { return options->get_options ().layer_map; @@ -103,6 +108,13 @@ gsi::ClassExt cif_reader_options ( "This method has been added in version 0.25 and replaces the respective global option in \\LoadLayoutOptions " "in a format-specific fashion." ) + + gsi::method_ext ("cif_layer_map=", &set_layer_map1, gsi::arg ("map"), + "@brief Sets the layer map\n" + "This sets a layer mapping for the reader. Unlike \\cif_set_layer_map, the 'create_other_layers' flag is not changed.\n" + "@param map The layer map to set." + "\n" + "This convenience method has been added in version 0.26." + ) + gsi::method_ext ("cif_select_all_layers", &select_all_layers, "@brief Selects all layers and disables the layer map\n" "\n" diff --git a/src/plugins/streamers/dxf/db_plugin/gsiDeclDbDXF.cc b/src/plugins/streamers/dxf/db_plugin/gsiDeclDbDXF.cc index d444e3659..9a00a0d25 100644 --- a/src/plugins/streamers/dxf/db_plugin/gsiDeclDbDXF.cc +++ b/src/plugins/streamers/dxf/db_plugin/gsiDeclDbDXF.cc @@ -133,6 +133,11 @@ static void set_layer_map (db::LoadLayoutOptions *options, const db::LayerMap &l options->get_options ().create_other_layers = f; } +static void set_layer_map1 (db::LoadLayoutOptions *options, const db::LayerMap &lm) +{ + options->get_options ().layer_map = lm; +} + static db::LayerMap &get_layer_map (db::LoadLayoutOptions *options) { return options->get_options ().layer_map; @@ -177,6 +182,13 @@ gsi::ClassExt dxf_reader_options ( "This method has been added in version 0.25 and replaces the respective global option in \\LoadLayoutOptions " "in a format-specific fashion." ) + + gsi::method_ext ("dxf_layer_map=", &set_layer_map1, gsi::arg ("map"), + "@brief Sets the layer map\n" + "This sets a layer mapping for the reader. Unlike \\dxf_set_layer_map, the 'create_other_layers' flag is not changed.\n" + "@param map The layer map to set." + "\n" + "This convenience method has been added in version 0.26." + ) + gsi::method_ext ("dxf_select_all_layers", &select_all_layers, "@brief Selects all layers and disables the layer map\n" "\n" diff --git a/src/plugins/streamers/oasis/db_plugin/gsiDeclDbOASIS.cc b/src/plugins/streamers/oasis/db_plugin/gsiDeclDbOASIS.cc index fc7734ba8..5d6a78010 100644 --- a/src/plugins/streamers/oasis/db_plugin/gsiDeclDbOASIS.cc +++ b/src/plugins/streamers/oasis/db_plugin/gsiDeclDbOASIS.cc @@ -30,6 +30,51 @@ namespace gsi { +// --------------------------------------------------------------- +// gsi Implementation of specific methods of LoadLayoutOptions + +static void set_oasis_read_all_properties (db::LoadLayoutOptions *options, bool f) +{ + options->get_options ().read_all_properties = f; +} + +static int get_oasis_read_all_properties (const db::LoadLayoutOptions *options) +{ + return options->get_options ().read_all_properties; +} + +static void set_oasis_expect_strict_mode (db::LoadLayoutOptions *options, int f) +{ + options->get_options ().expect_strict_mode = f; +} + +static int get_oasis_expect_strict_mode (const db::LoadLayoutOptions *options) +{ + return options->get_options ().expect_strict_mode; +} + +// extend lay::LoadLayoutOptions with the OASIS options +static +gsi::ClassExt oasis_reader_options ( + gsi::method_ext ("oasis_read_all_properties=", &set_oasis_read_all_properties, + // this method is mainly provided as access point for the generic interface + "@hide" + ) + + gsi::method_ext ("oasis_read_all_properties?", &get_oasis_read_all_properties, + // this method is mainly provided as access point for the generic interface + "@hide" + ) + + gsi::method_ext ("oasis_expect_strict_mode=", &set_oasis_expect_strict_mode, + // this method is mainly provided as access point for the generic interface + "@hide" + ) + + gsi::method_ext ("oasis_expect_strict_mode?", &get_oasis_expect_strict_mode, + // this method is mainly provided as access point for the generic interface + "@hide" + ), + "" +); + // --------------------------------------------------------------- // gsi Implementation of specific methods @@ -78,6 +123,16 @@ static bool get_oasis_write_std_properties (const db::SaveLayoutOptions *options return options->get_options ().write_std_properties != 0; } +static void set_oasis_write_std_properties_ext (db::SaveLayoutOptions *options, int f) +{ + options->get_options ().write_std_properties = f; +} + +static int get_oasis_write_std_properties_ext (const db::SaveLayoutOptions *options) +{ + return options->get_options ().write_std_properties; +} + static void set_oasis_write_cell_bounding_boxes (db::SaveLayoutOptions *options, bool f) { db::OASISWriterOptions &oasis_options = options->get_options (); @@ -222,6 +277,14 @@ gsi::ClassExt oasis_writer_options ( "\n" "This method has been introduced in version 0.24." ) + + gsi::method_ext ("oasis_write_std_properties_ext=", &set_oasis_write_std_properties_ext, + // this method is mainly provided as access point for the generic interface + "@hide" + ) + + gsi::method_ext ("oasis_write_std_properties_ext", &get_oasis_write_std_properties_ext, + // this method is mainly provided as access point for the generic interface + "@hide" + ) + gsi::method_ext ("oasis_compression_level=", &set_oasis_compression, "@brief Set the OASIS compression level\n" "@args level\n" diff --git a/src/unit_tests/unit_test_main.cc b/src/unit_tests/unit_test_main.cc index 5aa76f074..da260797c 100644 --- a/src/unit_tests/unit_test_main.cc +++ b/src/unit_tests/unit_test_main.cc @@ -380,48 +380,6 @@ main_cont (int &argc, char **argv) pya::PythonInterpreter::initialize (); gsi::initialize_external (); -#if defined(HAVE_QT) - - // NOTE: we need an application object, but we don't call parse_cmd. This makes the object - // behave neutral as far as possible. - lay::GuiApplication app (argc, argv); - app.init_app (); - - app.ruby_interpreter ().push_console (&console); - app.python_interpreter ().push_console (&console); - - app.autorun (); - -#if QT_VERSION < 0x050000 - QTextCodec::setCodecForTr (QTextCodec::codecForName ("utf8")); -#endif - -#else - - // select the system locale - setlocale (LC_ALL, ""); - - // initialize the modules (load their plugins from the paths) - db::init (); - - // initialize the GSI class system (Variant binding, Expression support) - // We have to do this now since plugins may register GSI classes and before the - // ruby interpreter, because it depends on a proper class system. - gsi::initialize (); - - // initialize the tl::Expression subsystem with GSI-bound classes - gsi::initialize_expressions (); - - // instantiate the interpreters - - ruby_interpreter.reset (new rba::RubyInterpreter ()); - ruby_interpreter->push_console (&console); - - python_interpreter.reset (new pya::PythonInterpreter ()); - python_interpreter->push_console (&console); - -#endif - // Search and initialize plugin unit tests std::string inst_dir = tl::get_inst_path (); @@ -464,6 +422,48 @@ main_cont (int &argc, char **argv) throw tl::Exception ("No test libraries found - make sure, the *.ut files are next to the ut_runner executable."); } +#if defined(HAVE_QT) + + // NOTE: we need an application object, but we don't call parse_cmd. This makes the object + // behave neutral as far as possible. + lay::GuiApplication app (argc, argv); + app.init_app (); + + app.ruby_interpreter ().push_console (&console); + app.python_interpreter ().push_console (&console); + + app.autorun (); + +#if QT_VERSION < 0x050000 + QTextCodec::setCodecForTr (QTextCodec::codecForName ("utf8")); +#endif + +#else + + // select the system locale + setlocale (LC_ALL, ""); + + // initialize the modules (load their plugins from the paths) + db::init (); + + // initialize the GSI class system (Variant binding, Expression support) + // We have to do this now since plugins may register GSI classes and before the + // ruby interpreter, because it depends on a proper class system. + gsi::initialize (); + + // initialize the tl::Expression subsystem with GSI-bound classes + gsi::initialize_expressions (); + + // instantiate the interpreters + + ruby_interpreter.reset (new rba::RubyInterpreter ()); + ruby_interpreter->push_console (&console); + + python_interpreter.reset (new pya::PythonInterpreter ()); + python_interpreter->push_console (&console); + +#endif + bool editable = false, non_editable = false; bool gsi_coverage = false; std::vector class_names; From a7846ead9f13b3c1956ab341da283fbd9f2b9f54 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 9 Oct 2018 00:18:45 +0200 Subject: [PATCH 2/6] Add-on to previous commit: fixes some Python issues The comments for LoadLayoutOptions#layer_map, #cif_layer_map and #dxf_layer_map have been updated to reflect the new status of these properties (which have been methods). The tests are updated accordingly (layer_map() -> layer_map). --- src/db/db/gsiDeclDbCommonStreamOptions.cc | 2 ++ src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc | 4 +++- src/plugins/streamers/dxf/db_plugin/gsiDeclDbDXF.cc | 2 ++ testdata/python/dbReaders.py | 12 ++++++------ 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/db/db/gsiDeclDbCommonStreamOptions.cc b/src/db/db/gsiDeclDbCommonStreamOptions.cc index 0cb974b4c..53ab34891 100644 --- a/src/db/db/gsiDeclDbCommonStreamOptions.cc +++ b/src/db/db/gsiDeclDbCommonStreamOptions.cc @@ -115,6 +115,8 @@ gsi::ClassExt common_reader_options ( "@return A reference to the layer map\n" "\n" "Starting with version 0.25 this option only applies to GDS2 and OASIS format. Other formats provide their own configuration." + "\n" + "Python note: this method has been turned into a property in version 0.26." ) + gsi::method_ext ("create_other_layers?", &create_other_layers, "@brief Gets a value indicating whether other layers shall be created\n" diff --git a/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc b/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc index db25c52c0..fd3414092 100644 --- a/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc +++ b/src/plugins/streamers/cif/db_plugin/gsiDeclDbCIF.cc @@ -129,7 +129,9 @@ gsi::ClassExt cif_reader_options ( "@return A reference to the layer map\n" "\n" "This method has been added in version 0.25 and replaces the respective global option in \\LoadLayoutOptions " - "in a format-specific fashion." + "in a format-specific fashion.\n" + "\n" + "Python note: this method has been turned into a property in version 0.26." ) + gsi::method_ext ("cif_create_other_layers?", &create_other_layers, "@brief Gets a value indicating whether other layers shall be created\n" diff --git a/src/plugins/streamers/dxf/db_plugin/gsiDeclDbDXF.cc b/src/plugins/streamers/dxf/db_plugin/gsiDeclDbDXF.cc index 9a00a0d25..4a6a9f774 100644 --- a/src/plugins/streamers/dxf/db_plugin/gsiDeclDbDXF.cc +++ b/src/plugins/streamers/dxf/db_plugin/gsiDeclDbDXF.cc @@ -204,6 +204,8 @@ gsi::ClassExt dxf_reader_options ( "\n" "This method has been added in version 0.25 and replaces the respective global option in \\LoadLayoutOptions " "in a format-specific fashion." + "\n" + "Python note: this method has been turned into a property in version 0.26." ) + gsi::method_ext ("dxf_create_other_layers?", &create_other_layers, "@brief Gets a value indicating whether other layers shall be created\n" diff --git a/testdata/python/dbReaders.py b/testdata/python/dbReaders.py index 51253c33b..9f8119d1a 100644 --- a/testdata/python/dbReaders.py +++ b/testdata/python/dbReaders.py @@ -31,14 +31,14 @@ class DBReadersTests(unittest.TestCase): lm.map(pya.LayerInfo(1, 0), 2, pya.LayerInfo(42, 17)) opt.set_layer_map(lm, True) - self.assertEqual(opt.layer_map().to_string(), "1/0 : 42/17\n") + self.assertEqual(opt.layer_map.to_string(), "1/0 : 42/17\n") self.assertEqual(opt.create_other_layers, True) opt.create_other_layers = False self.assertEqual(opt.create_other_layers, False) opt.select_all_layers() - self.assertEqual(opt.layer_map().to_string(), "") + self.assertEqual(opt.layer_map.to_string(), "") self.assertEqual(opt.create_other_layers, True) opt.text_enabled = True @@ -88,14 +88,14 @@ class DBReadersTests(unittest.TestCase): lm.map(pya.LayerInfo(1, 0), 2, pya.LayerInfo(42, 17)) opt.dxf_set_layer_map(lm, True) - self.assertEqual(opt.dxf_layer_map().to_string(), "1/0 : 42/17\n") + self.assertEqual(opt.dxf_layer_map.to_string(), "1/0 : 42/17\n") self.assertEqual(opt.dxf_create_other_layers, True) opt.dxf_create_other_layers = False self.assertEqual(opt.dxf_create_other_layers, False) opt.dxf_select_all_layers() - self.assertEqual(opt.dxf_layer_map().to_string(), "") + self.assertEqual(opt.dxf_layer_map.to_string(), "") self.assertEqual(opt.dxf_create_other_layers, True) opt.dxf_dbu = 0.5 @@ -144,14 +144,14 @@ class DBReadersTests(unittest.TestCase): lm.map(pya.LayerInfo(1, 0), 2, pya.LayerInfo(42, 17)) opt.cif_set_layer_map(lm, True) - self.assertEqual(opt.cif_layer_map().to_string(), "1/0 : 42/17\n") + self.assertEqual(opt.cif_layer_map.to_string(), "1/0 : 42/17\n") self.assertEqual(opt.cif_create_other_layers, True) opt.cif_create_other_layers = False self.assertEqual(opt.cif_create_other_layers, False) opt.cif_select_all_layers() - self.assertEqual(opt.cif_layer_map().to_string(), "") + self.assertEqual(opt.cif_layer_map.to_string(), "") self.assertEqual(opt.cif_create_other_layers, True) opt.cif_keep_layer_names = True From f0661ba0b364a609aa410f812f7461a2597df5aa Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 9 Oct 2018 00:35:03 +0200 Subject: [PATCH 3/6] Some wrong header includes fixed. --- src/buddies/src/bd/bdWriterOptions.cc | 24 ++++++++++++------------ src/buddies/src/bd/bdWriterOptions.h | 20 ++++++++++---------- src/buddies/src/bd/strm2cif.cc | 4 ++-- src/buddies/src/bd/strm2dxf.cc | 4 ++-- src/buddies/src/bd/strm2gds.cc | 4 ++-- src/buddies/src/bd/strm2gdstxt.cc | 4 ++-- src/buddies/src/bd/strm2oas.cc | 4 ++-- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/buddies/src/bd/bdWriterOptions.cc b/src/buddies/src/bd/bdWriterOptions.cc index 210d39468..e7ecfd08c 100644 --- a/src/buddies/src/bd/bdWriterOptions.cc +++ b/src/buddies/src/bd/bdWriterOptions.cc @@ -58,11 +58,11 @@ GenericWriterOptions::GenericWriterOptions () // .. nothing yet .. } -const std::string GenericWriterOptions::m_gds2_format_name = "GDS2"; -const std::string GenericWriterOptions::m_gds2text_format_name = "GDS2Text"; // no special options -const std::string GenericWriterOptions::m_oasis_format_name = "OASIS"; -const std::string GenericWriterOptions::m_dxf_format_name = "DXF"; -const std::string GenericWriterOptions::m_cif_format_name = "CIF"; +const std::string GenericWriterOptions::gds2_format_name = "GDS2"; +const std::string GenericWriterOptions::gds2text_format_name = "GDS2Text"; // no special options +const std::string GenericWriterOptions::oasis_format_name = "OASIS"; +const std::string GenericWriterOptions::dxf_format_name = "DXF"; +const std::string GenericWriterOptions::cif_format_name = "CIF"; void GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::string &format) @@ -75,7 +75,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin "given factor." ); - if (format.empty () || format == m_gds2_format_name || format == m_gds2text_format_name || format == m_oasis_format_name) { + if (format.empty () || format == gds2_format_name || format == gds2text_format_name || format == oasis_format_name) { cmd << tl::arg (group + "-od|--dbu-out=dbu", &m_dbu, "Uses the specified database unit", "Specifies the database unit to save the layout in. The database unit is given " @@ -90,7 +90,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin "If given, empty cells won't be written. See --keep-instances for more options." ); - if (format.empty () || format == m_gds2_format_name || format == m_gds2text_format_name) { + if (format.empty () || format == gds2_format_name || format == gds2text_format_name) { cmd << tl::arg (group + "#--keep-instances", &m_keep_instances, "Keeps instances of dropped cells", "If given, instances of dropped cell's won't be removed. Hence, ghost cells are " @@ -101,7 +101,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin ); } - if (format.empty () || format == m_gds2_format_name || format == m_gds2text_format_name || format == m_oasis_format_name) { + if (format.empty () || format == gds2_format_name || format == gds2text_format_name || format == oasis_format_name) { cmd << tl::arg (group + "!#--no-context-info", &m_write_context_info, "Does not write context information", "Context information is included to maintain PCell parameters and library connections. " @@ -132,7 +132,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin "* \"TOP,-A\" - Select cell TOP (plus children), then remove A (with children)" ); - if (format.empty () || format == m_gds2_format_name || format == m_gds2text_format_name) { + if (format.empty () || format == gds2_format_name || format == gds2text_format_name) { // Add GDS2 and GDS2Text format options std::string group = "[Output options - GDS2 specific]"; @@ -186,7 +186,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin } - if (format.empty () || format == m_oasis_format_name) { + if (format.empty () || format == oasis_format_name) { // Add OASIS format options std::string group = "[Output options - OASIS specific]"; @@ -231,7 +231,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin } - if (format.empty () || format == m_dxf_format_name) { + if (format.empty () || format == dxf_format_name) { // Add DXF format options std::string group = "[Output options - DXF specific]"; @@ -248,7 +248,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin } - if (format.empty () || format == m_cif_format_name) { + if (format.empty () || format == cif_format_name) { // Add CIF format options std::string group = "[Output options - CIF specific]"; diff --git a/src/buddies/src/bd/bdWriterOptions.h b/src/buddies/src/bd/bdWriterOptions.h index 2f42b3f8b..87104c612 100644 --- a/src/buddies/src/bd/bdWriterOptions.h +++ b/src/buddies/src/bd/bdWriterOptions.h @@ -65,7 +65,7 @@ public: */ void add_options_for_gds2 (tl::CommandLineOptions &cmd) { - add_options (cmd, m_gds2_format_name); + add_options (cmd, gds2_format_name); } /** @@ -73,7 +73,7 @@ public: */ void add_options_for_oasis (tl::CommandLineOptions &cmd) { - add_options (cmd, m_oasis_format_name); + add_options (cmd, oasis_format_name); } /** @@ -81,7 +81,7 @@ public: */ void add_options_for_cif (tl::CommandLineOptions &cmd) { - add_options (cmd, m_cif_format_name); + add_options (cmd, cif_format_name); } /** @@ -89,7 +89,7 @@ public: */ void add_options_for_dxf (tl::CommandLineOptions &cmd) { - add_options (cmd, m_dxf_format_name); + add_options (cmd, dxf_format_name); } /** @@ -98,6 +98,12 @@ public: */ void configure (db::SaveLayoutOptions &save_options, const db::Layout &layout) const; + static const std::string gds2_format_name; + static const std::string gds2text_format_name; + static const std::string oasis_format_name; + static const std::string cif_format_name; + static const std::string dxf_format_name; + private: double m_scale_factor; double m_dbu; @@ -129,12 +135,6 @@ private: int m_dxf_polygon_mode; - static const std::string m_gds2_format_name; - static const std::string m_gds2text_format_name; - static const std::string m_oasis_format_name; - static const std::string m_cif_format_name; - static const std::string m_dxf_format_name; - void set_oasis_substitution_char (const std::string &text); }; diff --git a/src/buddies/src/bd/strm2cif.cc b/src/buddies/src/bd/strm2cif.cc index 3502dd240..77f3e43ce 100644 --- a/src/buddies/src/bd/strm2cif.cc +++ b/src/buddies/src/bd/strm2cif.cc @@ -21,9 +21,9 @@ */ #include "bdConverterMain.h" -#include "dbCIFFormat.h" +#include "bdWriterOptions.h" BD_PUBLIC int strm2cif (int argc, char *argv[]) { - return bd::converter_main (argc, argv, db::CIFWriterOptions ().format_name ()); + return bd::converter_main (argc, argv, bd::GenericWriterOptions::cif_format_name); } diff --git a/src/buddies/src/bd/strm2dxf.cc b/src/buddies/src/bd/strm2dxf.cc index bfdb480f2..4ddc26cda 100644 --- a/src/buddies/src/bd/strm2dxf.cc +++ b/src/buddies/src/bd/strm2dxf.cc @@ -21,9 +21,9 @@ */ #include "bdConverterMain.h" -#include "dbDXFFormat.h" +#include "bdWriterOptions.h" BD_PUBLIC int strm2dxf (int argc, char *argv[]) { - return bd::converter_main (argc, argv, db::DXFWriterOptions ().format_name ()); + return bd::converter_main (argc, argv, bd::GenericWriterOptions::dxf_format_name); } diff --git a/src/buddies/src/bd/strm2gds.cc b/src/buddies/src/bd/strm2gds.cc index 55f5198cf..b9d8ebdc1 100644 --- a/src/buddies/src/bd/strm2gds.cc +++ b/src/buddies/src/bd/strm2gds.cc @@ -21,9 +21,9 @@ */ #include "bdConverterMain.h" -#include "dbGDS2Format.h" +#include "bdWriterOptions.h" BD_PUBLIC int strm2gds (int argc, char *argv[]) { - return bd::converter_main (argc, argv, db::GDS2WriterOptions ().format_name ()); + return bd::converter_main (argc, argv, bd::GenericWriterOptions::gds2_format_name); } diff --git a/src/buddies/src/bd/strm2gdstxt.cc b/src/buddies/src/bd/strm2gdstxt.cc index 403beacea..590e49a33 100644 --- a/src/buddies/src/bd/strm2gdstxt.cc +++ b/src/buddies/src/bd/strm2gdstxt.cc @@ -21,9 +21,9 @@ */ #include "bdConverterMain.h" -#include "dbGDS2Format.h" +#include "bdWriterOptions.h" BD_PUBLIC int strm2gdstxt (int argc, char *argv[]) { - return bd::converter_main (argc, argv, db::GDS2WriterOptions ().format_name () + "Text"); + return bd::converter_main (argc, argv, bd::GenericWriterOptions::gds2text_format_name); } diff --git a/src/buddies/src/bd/strm2oas.cc b/src/buddies/src/bd/strm2oas.cc index 51df95a69..f70ba59c9 100644 --- a/src/buddies/src/bd/strm2oas.cc +++ b/src/buddies/src/bd/strm2oas.cc @@ -21,9 +21,9 @@ */ #include "bdConverterMain.h" -#include "dbOASISFormat.h" +#include "bdWriterOptions.h" BD_PUBLIC int strm2oas (int argc, char *argv[]) { - return bd::converter_main (argc, argv, db::OASISWriterOptions ().format_name ()); + return bd::converter_main (argc, argv, bd::GenericWriterOptions::gds2_format_name); } From 70778e941451d8645f42c8647cabc9d6326e190b Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 9 Oct 2018 01:12:58 +0200 Subject: [PATCH 4/6] Now also fixed the bd unit tests - there are also independent from the streamer plugins now. --- src/buddies/unit_tests/bdBasicTests.cc | 160 ++++++++++----------- src/buddies/unit_tests/bdConverterTests.cc | 22 +-- src/buddies/unit_tests/unit_tests.pro | 10 -- 3 files changed, 85 insertions(+), 107 deletions(-) diff --git a/src/buddies/unit_tests/bdBasicTests.cc b/src/buddies/unit_tests/bdBasicTests.cc index 0b5080835..f79edb7f1 100644 --- a/src/buddies/unit_tests/bdBasicTests.cc +++ b/src/buddies/unit_tests/bdBasicTests.cc @@ -27,10 +27,6 @@ #include "dbLayout.h" #include "dbCell.h" #include "dbSaveLayoutOptions.h" -#include "dbCIFFormat.h" -#include "dbDXFFormat.h" -#include "dbOASISFormat.h" -#include "dbGDS2Format.h" // Testing writer options TEST(1) @@ -78,23 +74,23 @@ TEST(1) EXPECT_EQ (stream_opt.dont_write_empty_cells (), false); EXPECT_EQ (stream_opt.keep_instances (), false); EXPECT_EQ (stream_opt.write_context_info (), true); - EXPECT_EQ (stream_opt.get_options ().blank_separator, false); - EXPECT_EQ (stream_opt.get_options ().dummy_calls, false); - EXPECT_EQ (stream_opt.get_options ().polygon_mode, 0); - EXPECT_EQ (stream_opt.get_options ().libname, "LIB"); - EXPECT_EQ (stream_opt.get_options ().max_vertex_count, (unsigned int) 8000); - EXPECT_EQ (stream_opt.get_options ().multi_xy_records, false); - EXPECT_EQ (stream_opt.get_options ().write_timestamps, true); - EXPECT_EQ (stream_opt.get_options ().no_zero_length_paths, false); - EXPECT_EQ (tl::to_string (stream_opt.get_options ().user_units), "1"); - EXPECT_EQ (stream_opt.get_options ().write_cell_properties, false); - EXPECT_EQ (stream_opt.get_options ().write_file_properties, false); - EXPECT_EQ (stream_opt.get_options ().write_cblocks, false); - EXPECT_EQ (stream_opt.get_options ().compression_level, 2); - EXPECT_EQ (stream_opt.get_options ().strict_mode, false); - EXPECT_EQ (stream_opt.get_options ().recompress, false); - EXPECT_EQ (stream_opt.get_options ().subst_char, "*"); - EXPECT_EQ (stream_opt.get_options ().write_std_properties, 1); + EXPECT_EQ (stream_opt.get_option_by_name ("cif_blank_separator").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("cif_dummy_calls").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_polygon_mode").to_int (), 0); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_libname").to_string (), "LIB"); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_max_vertex_count").to_uint (), (unsigned int) 8000); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_multi_xy_records").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_timestamps").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_no_zero_length_paths").to_bool (), false); + EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("gds2_user_units").to_double ()), "1"); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_cell_properties").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_file_properties").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_cblocks").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_compression_level").to_int (), 2); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_strict_mode").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_recompress").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_substitution_char").to_string (), "*"); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_std_properties_ext").to_int (), 1); opt.configure (stream_opt, layout); @@ -103,23 +99,23 @@ TEST(1) EXPECT_EQ (stream_opt.dont_write_empty_cells (), true); EXPECT_EQ (stream_opt.keep_instances (), true); EXPECT_EQ (stream_opt.write_context_info (), false); - EXPECT_EQ (stream_opt.get_options ().blank_separator, true); - EXPECT_EQ (stream_opt.get_options ().dummy_calls, true); - EXPECT_EQ (stream_opt.get_options ().polygon_mode, 2); - EXPECT_EQ (stream_opt.get_options ().libname, "MYLIBNAME"); - EXPECT_EQ (stream_opt.get_options ().max_vertex_count, (unsigned int) 250); - EXPECT_EQ (stream_opt.get_options ().multi_xy_records, true); - EXPECT_EQ (stream_opt.get_options ().write_timestamps, false); - EXPECT_EQ (stream_opt.get_options ().no_zero_length_paths, true); - EXPECT_EQ (tl::to_string (stream_opt.get_options ().user_units), "2.5"); - EXPECT_EQ (stream_opt.get_options ().write_cell_properties, true); - EXPECT_EQ (stream_opt.get_options ().write_file_properties, true); - EXPECT_EQ (stream_opt.get_options ().write_cblocks, true); - EXPECT_EQ (stream_opt.get_options ().compression_level, 9); - EXPECT_EQ (stream_opt.get_options ().strict_mode, true); - EXPECT_EQ (stream_opt.get_options ().recompress, true); - EXPECT_EQ (stream_opt.get_options ().subst_char, "X"); - EXPECT_EQ (stream_opt.get_options ().write_std_properties, 2); + EXPECT_EQ (stream_opt.get_option_by_name ("cif_blank_separator").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("cif_dummy_calls").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_polygon_mode").to_int (), 2); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_libname").to_string (), "MYLIBNAME"); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_max_vertex_count").to_uint (), (unsigned int) 250); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_multi_xy_records").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_timestamps").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_no_zero_length_paths").to_bool (), true); + EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("gds2_user_units").to_double ()), "2.5"); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_cell_properties").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_file_properties").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_cblocks").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_compression_level").to_int (), 9); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_strict_mode").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_recompress").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_substitution_char").to_string (), "X"); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_std_properties_ext").to_int (), 2); } static std::string cells2string (const db::Layout &layout, const std::set &cells) @@ -246,52 +242,52 @@ TEST(10) cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); db::LoadLayoutOptions stream_opt; - EXPECT_EQ (tl::to_string (stream_opt.get_options ().dbu), "0.001"); - EXPECT_EQ (stream_opt.get_options ().wire_mode, (unsigned int) 0); - EXPECT_EQ (stream_opt.get_options ().layer_map.to_string (), "layer_map()"); - EXPECT_EQ (stream_opt.get_options ().create_other_layers, true); - EXPECT_EQ (tl::to_string (stream_opt.get_options ().dbu), "0.001"); - EXPECT_EQ (stream_opt.get_options ().layer_map.to_string (), "layer_map()"); - EXPECT_EQ (stream_opt.get_options ().create_other_layers, true); - EXPECT_EQ (stream_opt.get_options ().unit, 1.0); - EXPECT_EQ (tl::to_string (stream_opt.get_options ().circle_accuracy), "0"); - EXPECT_EQ (stream_opt.get_options ().circle_points, 100); - EXPECT_EQ (stream_opt.get_options ().keep_other_cells, false); - EXPECT_EQ (stream_opt.get_options ().polyline_mode, 0); - EXPECT_EQ (stream_opt.get_options ().render_texts_as_polygons, false); - EXPECT_EQ (stream_opt.get_options ().text_scaling, 100); - EXPECT_EQ (stream_opt.get_options ().layer_map.to_string (), "layer_map()"); - EXPECT_EQ (stream_opt.get_options ().create_other_layers, true); - EXPECT_EQ (stream_opt.get_options ().enable_properties, true); - EXPECT_EQ (stream_opt.get_options ().enable_text_objects, true); - EXPECT_EQ (stream_opt.get_options ().box_mode, (unsigned int) 1); - EXPECT_EQ (stream_opt.get_options ().allow_big_records, true); - EXPECT_EQ (stream_opt.get_options ().allow_multi_xy_records, true); - EXPECT_EQ (stream_opt.get_options ().expect_strict_mode, -1); + EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("cif_dbu").to_double ()), "0.001"); + EXPECT_EQ (stream_opt.get_option_by_name ("cif_wire_mode").to_uint (), (unsigned int) 0); + EXPECT_EQ (stream_opt.get_option_by_name ("cif_layer_map").to_user ().to_string (), "layer_map()"); + EXPECT_EQ (stream_opt.get_option_by_name ("cif_create_other_layers").to_bool (), true); + EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("dxf_dbu").to_double ()), "0.001"); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_layer_map").to_user ().to_string (), "layer_map()"); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_create_other_layers").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_unit").to_double (), 1.0); + EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("dxf_circle_accuracy").to_double ()), "0"); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_circle_points").to_int (), 100); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_keep_other_cells").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_polyline_mode").to_int (), 0); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_render_texts_as_polygons").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_text_scaling").to_int (), 100); + EXPECT_EQ (stream_opt.get_option_by_name ("layer_map").to_user ().to_string (), "layer_map()"); + EXPECT_EQ (stream_opt.get_option_by_name ("create_other_layers").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("properties_enabled").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("text_enabled").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_box_mode").to_uint (), (unsigned int) 1); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_allow_big_records").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_allow_multi_xy_records").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_expect_strict_mode").to_int (), -1); opt.configure (stream_opt); - EXPECT_EQ (tl::to_string (stream_opt.get_options ().dbu), "0.125"); - EXPECT_EQ (stream_opt.get_options ().wire_mode, (unsigned int) 1); - EXPECT_EQ (stream_opt.get_options ().layer_map.to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')"); - EXPECT_EQ (stream_opt.get_options ().create_other_layers, false); - EXPECT_EQ (tl::to_string (stream_opt.get_options ().dbu), "0.125"); - EXPECT_EQ (stream_opt.get_options ().layer_map.to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')"); - EXPECT_EQ (stream_opt.get_options ().create_other_layers, false); - EXPECT_EQ (stream_opt.get_options ().unit, 2.5); - EXPECT_EQ (tl::to_string (stream_opt.get_options ().circle_accuracy), "0.5"); - EXPECT_EQ (stream_opt.get_options ().circle_points, 1000); - EXPECT_EQ (stream_opt.get_options ().keep_other_cells, true); - EXPECT_EQ (stream_opt.get_options ().polyline_mode, 3); - EXPECT_EQ (stream_opt.get_options ().render_texts_as_polygons, true); - EXPECT_EQ (stream_opt.get_options ().text_scaling, 75); - EXPECT_EQ (stream_opt.get_options ().layer_map.to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')"); - EXPECT_EQ (stream_opt.get_options ().create_other_layers, false); - EXPECT_EQ (stream_opt.get_options ().enable_properties, false); - EXPECT_EQ (stream_opt.get_options ().enable_text_objects, false); - EXPECT_EQ (stream_opt.get_options ().box_mode, (unsigned int) 3); - EXPECT_EQ (stream_opt.get_options ().allow_big_records, false); - EXPECT_EQ (stream_opt.get_options ().allow_multi_xy_records, false); - EXPECT_EQ (stream_opt.get_options ().expect_strict_mode, 1); + EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("cif_dbu").to_double ()), "0.125"); + EXPECT_EQ (stream_opt.get_option_by_name ("cif_wire_mode").to_uint (), (unsigned int) 1); + EXPECT_EQ (stream_opt.get_option_by_name ("cif_layer_map").to_user ().to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')"); + EXPECT_EQ (stream_opt.get_option_by_name ("cif_create_other_layers").to_bool (), false); + EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("dxf_dbu").to_double ()), "0.125"); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_layer_map").to_user ().to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')"); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_create_other_layers").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_unit").to_double (), 2.5); + EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("dxf_circle_accuracy").to_double ()), "0.5"); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_circle_points").to_int (), 1000); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_keep_other_cells").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_polyline_mode").to_int (), 3); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_render_texts_as_polygons").to_bool (), true); + EXPECT_EQ (stream_opt.get_option_by_name ("dxf_text_scaling").to_int (), 75); + EXPECT_EQ (stream_opt.get_option_by_name ("layer_map").to_user ().to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')"); + EXPECT_EQ (stream_opt.get_option_by_name ("create_other_layers").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("properties_enabled").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("text_enabled").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_box_mode").to_uint (), (unsigned int) 3); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_allow_big_records").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("gds2_allow_multi_xy_records").to_bool (), false); + EXPECT_EQ (stream_opt.get_option_by_name ("oasis_expect_strict_mode").to_int (), 1); } diff --git a/src/buddies/unit_tests/bdConverterTests.cc b/src/buddies/unit_tests/bdConverterTests.cc index fbc538893..c05e69582 100644 --- a/src/buddies/unit_tests/bdConverterTests.cc +++ b/src/buddies/unit_tests/bdConverterTests.cc @@ -21,13 +21,10 @@ */ #include "bdConverterMain.h" +#include "bdWriterOptions.h" #include "dbStream.h" -#include "dbCIFFormat.h" -#include "dbDXFReader.h" -#include "dbOASISReader.h" -#include "dbGDS2Reader.h" #include "dbTestSupport.h" -#include "contrib/dbGDS2TextReader.h" +#include "dbReader.h" #include "tlUnitTest.h" // Testing the converter main implementation (CIF) @@ -40,14 +37,13 @@ TEST(1) const char *argv[] = { "x", input.c_str (), output.c_str () }; - EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, db::CIFReaderOptions ().format_name ()), 0); + EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::cif_format_name), 0); db::Layout layout; { tl::InputStream stream (output); db::LoadLayoutOptions options; - options.set_options (new db::CIFReaderOptions ()); db::Reader reader (stream); reader.read (layout, options); EXPECT_EQ (reader.format (), "CIF"); @@ -66,14 +62,13 @@ TEST(2) const char *argv[] = { "x", input.c_str (), output.c_str () }; - EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, db::DXFReaderOptions ().format_name ()), 0); + EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::dxf_format_name), 0); db::Layout layout; { tl::InputStream stream (output); db::LoadLayoutOptions options; - options.set_options (new db::DXFReaderOptions ()); db::Reader reader (stream); reader.read (layout, options); EXPECT_EQ (reader.format (), "DXF"); @@ -98,14 +93,13 @@ TEST(3) const char *argv[] = { "x", input.c_str (), output.c_str () }; - EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, db::GDS2ReaderOptions ().format_name ()), 0); + EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::gds2_format_name), 0); db::Layout layout; { tl::InputStream stream (output); db::LoadLayoutOptions options; - options.set_options (new db::GDS2ReaderOptions ()); db::Reader reader (stream); reader.read (layout, options); EXPECT_EQ (reader.format (), "GDS2"); @@ -124,14 +118,13 @@ TEST(4) const char *argv[] = { "x", input.c_str (), output.c_str () }; - EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, db::GDS2ReaderOptions ().format_name () + "Text"), 0); + EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::gds2text_format_name), 0); db::Layout layout; { tl::InputStream stream (output); db::LoadLayoutOptions options; - options.set_options (new db::GDS2ReaderOptions ()); db::Reader reader (stream); reader.read (layout, options); EXPECT_EQ (reader.format (), "GDS2Text"); @@ -150,14 +143,13 @@ TEST(5) const char *argv[] = { "x", input.c_str (), output.c_str () }; - EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, db::OASISReaderOptions ().format_name ()), 0); + EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::oasis_format_name), 0); db::Layout layout; { tl::InputStream stream (output); db::LoadLayoutOptions options; - options.set_options (new db::OASISReaderOptions ()); db::Reader reader (stream); reader.read (layout, options); EXPECT_EQ (reader.format (), "OASIS"); diff --git a/src/buddies/unit_tests/unit_tests.pro b/src/buddies/unit_tests/unit_tests.pro index 702e0cb29..6e2e7825e 100644 --- a/src/buddies/unit_tests/unit_tests.pro +++ b/src/buddies/unit_tests/unit_tests.pro @@ -21,13 +21,3 @@ INCLUDEPATH += $$BD_INC $$DB_INC $$TL_INC $$GSI_INC DEPENDPATH += $$BD_INC $$DB_INC $$TL_INC $$GSI_INC LIBS += -L$$DESTDIR_UT -lklayout_bd -lklayout_db -lklayout_tl -lklayout_gsi - -PLUGINPATH += \ - $$PWD/../../plugins/common \ - $$PWD/../../plugins/streamers/gds2/db_plugin \ - $$PWD/../../plugins/streamers/cif/db_plugin \ - $$PWD/../../plugins/streamers/oasis/db_plugin \ - $$PWD/../../plugins/streamers/dxf/db_plugin \ - -INCLUDEPATH += $$PLUGINPATH -DEPENDPATH += $$PLUGINPATH From 19a3f19378e3bd8c0b3fcc23e1cc90345fdede0c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 9 Oct 2018 21:24:23 +0200 Subject: [PATCH 5/6] Removed some misleading comments. --- src/plugins/streamers/cif/unit_tests/unit_tests.pro | 1 - src/plugins/streamers/dxf/unit_tests/unit_tests.pro | 1 - src/plugins/streamers/gds2/unit_tests/unit_tests.pro | 1 - src/plugins/streamers/lefdef/unit_tests/unit_tests.pro | 1 - src/plugins/streamers/oasis/unit_tests/unit_tests.pro | 1 - src/plugins/streamers/pcb/unit_tests/unit_tests.pro | 1 - 6 files changed, 6 deletions(-) diff --git a/src/plugins/streamers/cif/unit_tests/unit_tests.pro b/src/plugins/streamers/cif/unit_tests/unit_tests.pro index 5fd833951..b29f24c55 100644 --- a/src/plugins/streamers/cif/unit_tests/unit_tests.pro +++ b/src/plugins/streamers/cif/unit_tests/unit_tests.pro @@ -13,7 +13,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../ LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi -# This makes the test pull the mebes library for testing (not installed) PLUGINPATH = $$OUT_PWD/../../../../db_plugins QMAKE_RPATHDIR += $$PLUGINPATH diff --git a/src/plugins/streamers/dxf/unit_tests/unit_tests.pro b/src/plugins/streamers/dxf/unit_tests/unit_tests.pro index 1b352e28e..de728685d 100644 --- a/src/plugins/streamers/dxf/unit_tests/unit_tests.pro +++ b/src/plugins/streamers/dxf/unit_tests/unit_tests.pro @@ -13,7 +13,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../ LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi -# This makes the test pull the mebes library for testing (not installed) PLUGINPATH = $$OUT_PWD/../../../../db_plugins QMAKE_RPATHDIR += $$PLUGINPATH diff --git a/src/plugins/streamers/gds2/unit_tests/unit_tests.pro b/src/plugins/streamers/gds2/unit_tests/unit_tests.pro index 42535fca3..cc5d39a61 100644 --- a/src/plugins/streamers/gds2/unit_tests/unit_tests.pro +++ b/src/plugins/streamers/gds2/unit_tests/unit_tests.pro @@ -14,7 +14,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../ LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi -# This makes the test pull the mebes library for testing (not installed) PLUGINPATH = $$OUT_PWD/../../../../db_plugins QMAKE_RPATHDIR += $$PLUGINPATH diff --git a/src/plugins/streamers/lefdef/unit_tests/unit_tests.pro b/src/plugins/streamers/lefdef/unit_tests/unit_tests.pro index 9b9efb119..93529fc7f 100644 --- a/src/plugins/streamers/lefdef/unit_tests/unit_tests.pro +++ b/src/plugins/streamers/lefdef/unit_tests/unit_tests.pro @@ -13,7 +13,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../ LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi -# This makes the test pull the mebes library for testing (not installed) PLUGINPATH = $$OUT_PWD/../../../../db_plugins QMAKE_RPATHDIR += $$PLUGINPATH diff --git a/src/plugins/streamers/oasis/unit_tests/unit_tests.pro b/src/plugins/streamers/oasis/unit_tests/unit_tests.pro index dc439f6dc..2532285f9 100644 --- a/src/plugins/streamers/oasis/unit_tests/unit_tests.pro +++ b/src/plugins/streamers/oasis/unit_tests/unit_tests.pro @@ -15,7 +15,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../ LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi -# This makes the test pull the mebes library for testing (not installed) PLUGINPATH = $$OUT_PWD/../../../../db_plugins QMAKE_RPATHDIR += $$PLUGINPATH diff --git a/src/plugins/streamers/pcb/unit_tests/unit_tests.pro b/src/plugins/streamers/pcb/unit_tests/unit_tests.pro index 602c0b1b8..fbc1d98fa 100644 --- a/src/plugins/streamers/pcb/unit_tests/unit_tests.pro +++ b/src/plugins/streamers/pcb/unit_tests/unit_tests.pro @@ -13,7 +13,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../ LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi -# This makes the test pull the mebes library for testing (not installed) PLUGINPATH = $$OUT_PWD/../../../../db_plugins QMAKE_RPATHDIR += $$PLUGINPATH From 222b98fd70301d56d306241ee472ae6d3ebbf688 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 9 Oct 2018 13:56:32 -0700 Subject: [PATCH 6/6] Some fixes for the testsuite With these fixes, unit tests pass with MacOS (set DYLD_LIBRARY_PATH!) 1.) MacOS takes popen vs. pclose seriously By using fopen we basically spoil the system and other popen won't work. 2.) For system integrity, MacOS does not propagate DYLD_LIBRARY_PATH to child processes such as sh. This has to be done explictly. 3.) Search the klayout binary in the right path (klayout.app/...) 4.) Reset KLAYOUT_HOME for less intervention by installed macros --- src/buddies/unit_tests/bdStrmrunTests.cc | 19 +++++++++++++++++-- src/pymod/unit_tests/pymod_tests.cc | 15 ++++++++++++++- src/tl/tl/tlStream.cc | 3 ++- testdata/klayout_main/main.rb | 19 ++++++++++++++++++- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/buddies/unit_tests/bdStrmrunTests.cc b/src/buddies/unit_tests/bdStrmrunTests.cc index 4bf980501..1d4d1421e 100644 --- a/src/buddies/unit_tests/bdStrmrunTests.cc +++ b/src/buddies/unit_tests/bdStrmrunTests.cc @@ -30,10 +30,25 @@ TEST(1) std::string fp (tl::testsrc ()); fp += "/testdata/bd/strmrun.py"; - std::string path = tl::combine_path (tl::get_inst_path (), "strmrun ") + fp; - tl::InputPipe pipe (path); + std::string cmd; + +#if defined(__APPLE__) + // NOTE: because of system integrity, MacOS does not inherit DYLD_LIBRARY_PATH to child + // processes like sh. We need to port this variable explicitly. + const char *ldpath_name = "DYLD_LIBRARY_PATH"; + const char *ldpath = getenv (ldpath_name); + if (ldpath) { + cmd += std::string (ldpath_name) + "=\"" + ldpath + "\"; export " + ldpath_name + "; "; + } +#endif + + cmd += tl::combine_path (tl::get_inst_path (), "strmrun ") + fp; + tl::info << cmd; + + tl::InputPipe pipe (cmd); tl::InputStream is (pipe); std::string data = is.read_all (); + tl::info << data; EXPECT_EQ (data, "Hello, world (0,-42;42,0)!\n"); } diff --git a/src/pymod/unit_tests/pymod_tests.cc b/src/pymod/unit_tests/pymod_tests.cc index 73dec29d2..bd534a4c5 100644 --- a/src/pymod/unit_tests/pymod_tests.cc +++ b/src/pymod/unit_tests/pymod_tests.cc @@ -53,7 +53,20 @@ int run_pymodtest (tl::TestBase *_this, const std::string &fn) std::string text; { - std::string cmd = std::string ("\"") + STRINGIFY (PYTHON) + "\" " + fp + " 2>&1"; + std::string cmd; + +#if defined(__APPLE__) + // NOTE: because of system integrity, MacOS does not inherit DYLD_LIBRARY_PATH to child + // processes like sh. We need to port this variable explicitly. + const char *ldpath_name = "DYLD_LIBRARY_PATH"; + const char *ldpath = getenv (ldpath_name); + if (ldpath) { + cmd += std::string (ldpath_name) + "=\"" + ldpath + "\"; export " + ldpath_name + "; "; + } +#endif + + cmd += std::string ("\"") + STRINGIFY (PYTHON) + "\" " + fp + " 2>&1"; + tl::info << cmd; tl::InputPipe pipe (cmd); tl::InputStream is (pipe); diff --git a/src/tl/tl/tlStream.cc b/src/tl/tl/tlStream.cc index fcc6dc2b1..11d7807b8 100644 --- a/src/tl/tl/tlStream.cc +++ b/src/tl/tl/tlStream.cc @@ -967,7 +967,8 @@ void InputPipe::close () { if (m_file != NULL) { - fclose (m_file); + pclose (m_file); + // TODO: pclose delivers the exit code - we should indicate it as return value of close. m_file = NULL; } } diff --git a/testdata/klayout_main/main.rb b/testdata/klayout_main/main.rb index 526167824..20e7ef5d3 100644 --- a/testdata/klayout_main/main.rb +++ b/testdata/klayout_main/main.rb @@ -30,8 +30,25 @@ load("test_prologue.rb") class KLayoutMain_TestClass < TestBase + def setup + @klayout_home_name = "KLAYOUT_HOME" + @klayout_home = ENV[@klayout_home_name] + # setting "KLAYOUT_HOME" to empty means we don't search any place + # for macros + ENV[@klayout_home_name] = "" + end + + def teardown + ENV[@klayout_home_name] = @klayout_home + end + def klayout_bin - File.join(RBA::Application::instance.inst_path, "klayout") + # special location for MacOS + file = File.join(RBA::Application::instance.inst_path, "klayout.app", "Contents", "MacOS", "klayout") + if !File.exists?(file) + file = File.join(RBA::Application::instance.inst_path, "klayout") + end + return file end def test_1