diff --git a/src/buddies/bd/bdInit.h b/src/buddies/bd/bdInit.h index 10ce971ed..e83290885 100644 --- a/src/buddies/bd/bdInit.h +++ b/src/buddies/bd/bdInit.h @@ -24,6 +24,7 @@ #define HDR_bdInit #include "bdCommon.h" +#include "tlLog.h" // because of BD_MAIN namespace bd { @@ -34,6 +35,44 @@ namespace bd */ void BD_PUBLIC init (); +/** + * @brief Provides a main () implementation + * + * Use this macro like this: + * + * @code + * #include "bdInit.h" + * + * BD_MAIN_FUNC + * { + * .. your code. Use argc and argv for the arguments. + * } + * + * BD_MAIN + */ + +#define BD_MAIN \ + int main (int argc, char *argv []) \ + { \ + try { \ + bd::init (); \ + return main_func (argc, argv); \ + } catch (tl::CancelException & /*ex*/) { \ + return 1; \ + } catch (std::exception &ex) { \ + tl::error << ex.what (); \ + return 1; \ + } catch (tl::Exception &ex) { \ + tl::error << ex.msg (); \ + return 1; \ + } catch (...) { \ + tl::error << "unspecific error"; \ + } \ + } + +#define BD_MAIN_FUNC \ + int main_func (int argc, char *argv []) + } #endif diff --git a/src/buddies/bd/bdReaderOptions.cc b/src/buddies/bd/bdReaderOptions.cc index 7c0018f1c..0309a760e 100644 --- a/src/buddies/bd/bdReaderOptions.cc +++ b/src/buddies/bd/bdReaderOptions.cc @@ -28,7 +28,7 @@ namespace bd { GenericReaderOptions::GenericReaderOptions () - : m_create_other_layers (true) + : m_prefix ("i"), m_group_prefix ("Input"), m_create_other_layers (true) { // .. nothing yet .. } @@ -37,16 +37,16 @@ void GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) { { - std::string group ("[Input options - General]"); + std::string group ("[" + m_group_prefix + " options - General]"); cmd << tl::arg (group + - "!-is|--skip-unknown-layers", &m_create_other_layers, "Skips unknown layers", + "!-" + m_prefix + "s|--" + m_long_prefix + "skip-unknown-layers", &m_create_other_layers, "Skips unknown layers", "This option is effective with the the --layer-map option. If combined with " "--skip-unknown-layers, layers not listed in the layer map will not be read. " "By default, corresponding entries are created also for unknown layers." ) << tl::arg (group + - "-im|--layer-map=map", this, &GenericReaderOptions::set_layer_map, "Specifies the layer mapping for the input", + "-" + m_prefix + "m|--" + m_long_prefix + "layer-map=map", this, &GenericReaderOptions::set_layer_map, "Specifies the layer mapping for the input", "This option specifies a layer selection or mapping. The selection or mapping is a sequence of source and optional " "target specifications. The specifications are separated by blanks or double-slash sequences (//).\n" "\n" @@ -76,37 +76,37 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) } { - std::string group ("[Input options - GDS2 and OASIS]"); + std::string group ("[" + m_group_prefix + " options - GDS2 and OASIS specific]"); cmd << tl::arg (group + - "#!--disable-texts", &m_common_reader_options.enable_text_objects, "Skips text objects", + "#!--" + m_long_prefix + "disable-texts", &m_common_reader_options.enable_text_objects, "Skips text objects", "With this option set, text objects won't be read." ) << tl::arg (group + - "#!--disable-properties", &m_common_reader_options.enable_properties, "Skips properties", + "#!--" + m_long_prefix + "disable-properties", &m_common_reader_options.enable_properties, "Skips properties", "With this option set, properties won't be read." ) ; } { - std::string group ("[Input options - GDS2]"); + std::string group ("[" + m_group_prefix + " options - GDS2 specific]"); cmd << tl::arg (group + - "#!--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_reader_options.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 + - "#!--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_reader_options.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 + - "-ib|--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_reader_options.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" @@ -119,10 +119,10 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) } { - std::string group ("[Input options - OASIS]"); + std::string group ("[" + m_group_prefix + " options - OASIS specific]"); cmd << tl::arg (group + - "#--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_reader_options.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." @@ -131,10 +131,10 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) } { - std::string group ("[Input options - CIF and DXF]"); + std::string group ("[" + m_group_prefix + " options - CIF and DXF specific]"); cmd << tl::arg (group + - "-id|--dbu-in=dbu", this, &GenericReaderOptions::set_dbu, "Specifies the database unit to use", + "-" + m_prefix + "d|--" + m_long_prefix + "dbu-in=dbu", this, &GenericReaderOptions::set_dbu, "Specifies the database unit to use", "This option specifies the database unit the resulting layer will have. " "The value is given in micrometer units. The default value is 1nm (0.001)." ) @@ -142,10 +142,10 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) } { - std::string group ("[Input options - CIF]"); + std::string group ("[" + m_group_prefix + " options - CIF specific]"); cmd << tl::arg (group + - "-iw|--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_reader_options.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" @@ -156,22 +156,22 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) } { - std::string group ("[Input options - DXF]"); + std::string group ("[" + m_group_prefix + " options - DXF specific]"); cmd << tl::arg (group + - "-iu|--dxf-unit=unit", &m_dxf_reader_options.unit, "Specifies the DXF drawing units", + "-" + m_prefix + "u|--" + m_long_prefix + "dxf-unit=unit", &m_dxf_reader_options.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 + - "#--dxf-text-scaling=factor", &m_dxf_reader_options.text_scaling, "Specifies text scaling", + "#--" + m_long_prefix + "dxf-text-scaling=factor", &m_dxf_reader_options.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 + - "#--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_reader_options.polyline_mode, "Specifies how POLYLINE records are handled", "This value specifies how POLYLINE records are handled:\n" "\n" "* 0: automatic mode\n" @@ -181,11 +181,11 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) "* 4: as 3 and auto-close contours" ) << tl::arg (group + - "#--dxf-circle-points=points", &m_dxf_reader_options.circle_points, "Specifies the number of points for a full circle for arc interpolation", - "See --dxf-circle-accuracy for another way of specifying the number of points per circle." + "#--" + 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", + "See --" + m_long_prefix + "dxf-circle-accuracy for another way of specifying the number of points per circle." ) << tl::arg (group + - "#--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_reader_options.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" @@ -198,11 +198,11 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) "The value is given in the units of the DXF file." ) << tl::arg (group + - "#--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_reader_options.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 + - "#--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_reader_options.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." ) diff --git a/src/buddies/bd/bdReaderOptions.h b/src/buddies/bd/bdReaderOptions.h index 1df5e9e52..93dfaa4d7 100644 --- a/src/buddies/bd/bdReaderOptions.h +++ b/src/buddies/bd/bdReaderOptions.h @@ -67,7 +67,38 @@ public: */ void configure (db::LoadLayoutOptions &load_options); + /** + * @brief Sets the option prefix for the short option name + * By default, the prefix is set to "i", so the short options are + * called "-is", "-id" etc. + */ + void set_prefix (const std::string &s) + { + m_prefix = s; + } + + /** + * @brief Sets the option prefix for the long option name + * The prefix is prepended to the name, so with "a-", the long names + * are "--a-unit" etc. By default, this prefix is empty. + */ + void set_long_prefix (const std::string &s) + { + m_long_prefix = s; + } + + /** + * @brief Sets the group name prefix + * By default, this prefix is "Input", so the group names are + * "Input options - GDS2" for example. + */ + void set_group_prefix (const std::string &s) + { + m_group_prefix = s; + } + private: + std::string m_prefix, m_long_prefix, m_group_prefix; db::LayerMap m_layer_map; bool m_create_other_layers; db::CommonReaderOptions m_common_reader_options; diff --git a/src/buddies/strm2cif/strm2cif.cc b/src/buddies/strm2cif/strm2cif.cc index 5b33abdd5..669f007fa 100644 --- a/src/buddies/strm2cif/strm2cif.cc +++ b/src/buddies/strm2cif/strm2cif.cc @@ -28,11 +28,8 @@ #include "dbCIFWriter.h" #include "tlCommandLineParser.h" -int -main_func (int argc, char *argv []) +BD_MAIN_FUNC { - bd::init (); - bd::GenericWriterOptions generic_writer_options; bd::GenericReaderOptions generic_reader_options; std::string infile, outfile; @@ -49,9 +46,7 @@ main_func (int argc, char *argv []) cmd.parse (argc, argv); - db::Manager m; - db::Layout layout (&m); - db::LayerMap map; + db::Layout layout; { db::LoadLayoutOptions load_options; @@ -59,7 +54,7 @@ main_func (int argc, char *argv []) tl::InputStream stream (infile); db::Reader reader (stream); - map = reader.read (layout, load_options); + reader.read (layout, load_options); } { @@ -74,20 +69,4 @@ main_func (int argc, char *argv []) return 0; } -int -main (int argc, char *argv []) -{ - try { - return main_func (argc, argv); - } catch (tl::CancelException & /*ex*/) { - return 1; - } catch (std::exception &ex) { - tl::error << ex.what (); - return 1; - } catch (tl::Exception &ex) { - tl::error << ex.msg (); - return 1; - } catch (...) { - tl::error << "ERROR: unspecific error"; - } -} +BD_MAIN diff --git a/src/buddies/strm2dxf/strm2dxf.cc b/src/buddies/strm2dxf/strm2dxf.cc index bddbf658b..1de3b265d 100644 --- a/src/buddies/strm2dxf/strm2dxf.cc +++ b/src/buddies/strm2dxf/strm2dxf.cc @@ -28,11 +28,8 @@ #include "dbDXFWriter.h" #include "tlCommandLineParser.h" -int -main_func (int argc, char *argv []) +BD_MAIN_FUNC { - bd::init (); - bd::GenericWriterOptions generic_writer_options; bd::GenericReaderOptions generic_reader_options; std::string infile, outfile; @@ -49,9 +46,7 @@ main_func (int argc, char *argv []) cmd.parse (argc, argv); - db::Manager m; - db::Layout layout (&m); - db::LayerMap map; + db::Layout layout; { db::LoadLayoutOptions load_options; @@ -59,7 +54,7 @@ main_func (int argc, char *argv []) tl::InputStream stream (infile); db::Reader reader (stream); - map = reader.read (layout, load_options); + reader.read (layout, load_options); } { @@ -74,20 +69,4 @@ main_func (int argc, char *argv []) return 0; } -int -main (int argc, char *argv []) -{ - try { - return main_func (argc, argv); - } catch (tl::CancelException & /*ex*/) { - return 1; - } catch (std::exception &ex) { - tl::error << ex.what (); - return 1; - } catch (tl::Exception &ex) { - tl::error << ex.msg (); - return 1; - } catch (...) { - tl::error << "ERROR: unspecific error"; - } -} +BD_MAIN diff --git a/src/buddies/strm2gds/strm2gds.cc b/src/buddies/strm2gds/strm2gds.cc index eb05b9b28..6da35ce8e 100644 --- a/src/buddies/strm2gds/strm2gds.cc +++ b/src/buddies/strm2gds/strm2gds.cc @@ -28,11 +28,8 @@ #include "dbGDS2Writer.h" #include "tlCommandLineParser.h" -int -main_func (int argc, char *argv []) +BD_MAIN_FUNC { - bd::init (); - bd::GenericWriterOptions generic_writer_options; bd::GenericReaderOptions generic_reader_options; std::string infile, outfile; @@ -49,9 +46,7 @@ main_func (int argc, char *argv []) cmd.parse (argc, argv); - db::Manager m; - db::Layout layout (&m); - db::LayerMap map; + db::Layout layout; { db::LoadLayoutOptions load_options; @@ -59,7 +54,7 @@ main_func (int argc, char *argv []) tl::InputStream stream (infile); db::Reader reader (stream); - map = reader.read (layout, load_options); + reader.read (layout, load_options); } { @@ -74,20 +69,4 @@ main_func (int argc, char *argv []) return 0; } -int -main (int argc, char *argv []) -{ - try { - return main_func (argc, argv); - } catch (tl::CancelException & /*ex*/) { - return 1; - } catch (std::exception &ex) { - tl::error << ex.what (); - return 1; - } catch (tl::Exception &ex) { - tl::error << ex.msg (); - return 1; - } catch (...) { - tl::error << "ERROR: unspecific error"; - } -} +BD_MAIN diff --git a/src/buddies/strm2gdstxt/strm2gdstxt.cc b/src/buddies/strm2gdstxt/strm2gdstxt.cc index 703161374..c5be4ebe4 100644 --- a/src/buddies/strm2gdstxt/strm2gdstxt.cc +++ b/src/buddies/strm2gdstxt/strm2gdstxt.cc @@ -28,11 +28,8 @@ #include "contrib/dbGDS2TextWriter.h" #include "tlCommandLineParser.h" -int -main_func (int argc, char *argv []) +BD_MAIN_FUNC { - bd::init (); - bd::GenericWriterOptions generic_writer_options; bd::GenericReaderOptions generic_reader_options; std::string infile, outfile; @@ -49,9 +46,7 @@ main_func (int argc, char *argv []) cmd.parse (argc, argv); - db::Manager m; - db::Layout layout (&m); - db::LayerMap map; + db::Layout layout; { db::LoadLayoutOptions load_options; @@ -59,7 +54,7 @@ main_func (int argc, char *argv []) tl::InputStream stream (infile); db::Reader reader (stream); - map = reader.read (layout, load_options); + reader.read (layout, load_options); } { @@ -74,20 +69,4 @@ main_func (int argc, char *argv []) return 0; } -int -main (int argc, char *argv []) -{ - try { - return main_func (argc, argv); - } catch (tl::CancelException & /*ex*/) { - return 1; - } catch (std::exception &ex) { - tl::error << ex.what (); - return 1; - } catch (tl::Exception &ex) { - tl::error << ex.msg (); - return 1; - } catch (...) { - tl::error << "ERROR: unspecific error"; - } -} +BD_MAIN diff --git a/src/buddies/strm2oas/strm2oas.cc b/src/buddies/strm2oas/strm2oas.cc index b042ec3b6..7832e2747 100644 --- a/src/buddies/strm2oas/strm2oas.cc +++ b/src/buddies/strm2oas/strm2oas.cc @@ -28,11 +28,8 @@ #include "dbOASISWriter.h" #include "tlCommandLineParser.h" -int -main_func (int argc, char *argv []) +BD_MAIN_FUNC { - bd::init (); - bd::GenericWriterOptions generic_writer_options; bd::GenericReaderOptions generic_reader_options; std::string infile, outfile; @@ -49,9 +46,7 @@ main_func (int argc, char *argv []) cmd.parse (argc, argv); - db::Manager m; - db::Layout layout (&m); - db::LayerMap map; + db::Layout layout; { db::LoadLayoutOptions load_options; @@ -59,7 +54,7 @@ main_func (int argc, char *argv []) tl::InputStream stream (infile); db::Reader reader (stream); - map = reader.read (layout, load_options); + reader.read (layout, load_options); } { @@ -74,20 +69,4 @@ main_func (int argc, char *argv []) return 0; } -int -main (int argc, char *argv []) -{ - try { - return main_func (argc, argv); - } catch (tl::CancelException & /*ex*/) { - return 1; - } catch (std::exception &ex) { - tl::error << ex.what (); - return 1; - } catch (tl::Exception &ex) { - tl::error << ex.msg (); - return 1; - } catch (...) { - tl::error << "ERROR: unspecific error"; - } -} +BD_MAIN diff --git a/src/buddies/strm2txt/strm2txt.cc b/src/buddies/strm2txt/strm2txt.cc index eff133517..6a05edb91 100644 --- a/src/buddies/strm2txt/strm2txt.cc +++ b/src/buddies/strm2txt/strm2txt.cc @@ -27,11 +27,8 @@ #include "dbTextWriter.h" #include "tlCommandLineParser.h" -int -main_func (int argc, char *argv []) +BD_MAIN_FUNC { - bd::init (); - bd::GenericReaderOptions generic_reader_options; std::string infile, outfile; @@ -46,9 +43,7 @@ main_func (int argc, char *argv []) cmd.parse (argc, argv); - db::Manager m; - db::Layout layout (&m); - db::LayerMap map; + db::Layout layout; { db::LoadLayoutOptions load_options; @@ -56,7 +51,7 @@ main_func (int argc, char *argv []) tl::InputStream stream (infile); db::Reader reader (stream); - map = reader.read (layout, load_options); + reader.read (layout, load_options); } { @@ -68,20 +63,4 @@ main_func (int argc, char *argv []) return 0; } -int -main (int argc, char *argv []) -{ - try { - return main_func (argc, argv); - } catch (tl::CancelException & /*ex*/) { - return 1; - } catch (std::exception &ex) { - tl::error << ex.what (); - return 1; - } catch (tl::Exception &ex) { - tl::error << ex.msg (); - return 1; - } catch (...) { - tl::error << "ERROR: unspecific error"; - } -} +BD_MAIN diff --git a/src/buddies/strmcmp/strmcmp.cc b/src/buddies/strmcmp/strmcmp.cc index 44219e048..079c33ef4 100644 --- a/src/buddies/strmcmp/strmcmp.cc +++ b/src/buddies/strmcmp/strmcmp.cc @@ -21,55 +21,147 @@ */ #include "bdInit.h" +#include "bdReaderOptions.h" #include "dbLayout.h" #include "dbLayoutDiff.h" #include "dbReader.h" +#include "tlCommandLineParser.h" -int -main (int argc, char *argv []) +BD_MAIN_FUNC { - if (argc != 3) { - printf ("Syntax: strmcmp \n"); - return 1; + bd::init (); + + bd::GenericReaderOptions generic_reader_options_a; + generic_reader_options_a.set_prefix ("a"); + generic_reader_options_a.set_long_prefix ("a-"); + generic_reader_options_a.set_group_prefix ("Input A"); + + bd::GenericReaderOptions generic_reader_options_b; + generic_reader_options_a.set_prefix ("b"); + generic_reader_options_a.set_long_prefix ("b-"); + generic_reader_options_a.set_group_prefix ("Input B"); + + std::string infile_a, infile_b; + std::string top_a, top_b; + bool silent = false; + bool no_text_orientation = true; + bool no_text_details = true; + bool no_properties = false; + bool no_layer_names = false; + bool verbose = true; + bool as_polygons = false; + bool boxes_as_polygons = false; + bool flatten_array_insts = false; + bool smart_cell_mapping = false; + bool paths_as_polygons = false; + bool dont_summarize_missing_layers = false; + double tolerance = 0.0; + int max_count = 0; + bool print_properties = false; + + tl::CommandLineOptions cmd; + generic_reader_options_a.add_options (cmd); + generic_reader_options_b.add_options (cmd); + + cmd << tl::arg ("input_a", &infile_a, "The first input file (any format, may be gzip compressed)") + << tl::arg ("input_b", &infile_b, "The second input file (any format, may be gzip compressed)") + << tl::arg ("-ta|--top-a=name", &top_a, "Specifies the cell to take as top cell from the first layout", + "Use this option to take a specific cell as the top cell from the first layout. All " + "cells not called directly or indirectly from this cell are ignored. If you use this option, " + "--top-b must be specified too and can be different from the first layout's top cell." + ) + << tl::arg ("-tb|--top-b=name", &top_b, "Specifies the cell to take as top cell from the second layout", + "See --top-a for details." + ) + << tl::arg ("-s|--silent", &silent, "Enables silent mode", + "In silent mode, no differences are printed, but the exit code indicates whether " + "the layout are the same (0) or differences exist (> 0)." + ) + << tl::arg ("#!--with-text-orientation", &no_text_orientation, "Compares orientations for texts", + "With this option, text orientation is compared too. The position of the " + "text is always compared, but the rotation angle is compared only when this option " + "is present." + ) + << tl::arg ("#!--with-text-details", &no_text_details, "Compares font and alignment for texts", + "With this option, text font and alignment is compared too." + ) + << tl::arg ("-np|--without-properties", &no_properties, "Ignores properties", + "With this option, shape, cell and file properties are not compared." + ) + << tl::arg ("-nl|--without-layer-names", &no_layer_names, "Ignores layer names", + "With this option, layer names are not compared." + ) + << tl::arg ("!-u|--terse", &verbose, "Skips too many details", + "With this option, no details about differences are printed." + ) + << tl::arg ("-r|--print-properties", &print_properties, "Prints shape properties too", + "This option, shape properties are printed too." + ) + << tl::arg ("-p|--as-polygons", &as_polygons, "Compares shapes are polygons", + "This option is equivalent to using --boxes-as-polygons and --paths-as-polygons." + ) + << tl::arg ("--boxes-as-polygons", &boxes_as_polygons, "Turns boxes into polygons before compare", + "With this option, boxes and equivalent polygons are treated identical." + ) + << tl::arg ("--paths-as-polygons", &paths_as_polygons, "Turns paths into polygons before compare", + "With this option, paths and equivalent polygons are treated identical." + ) + << tl::arg ("--expand-arrays", &flatten_array_insts, "Expands array instances before compare", + "With this option, arrays are equivalent single instances are treated identical." + ) + << tl::arg ("-l|--layer-details", &dont_summarize_missing_layers, "Prints details about differences for missing layers", + "With this option, missing layers are treated as \"empty\" and details about differences to " + "other, non-empty layers are printed. Essentially the content of the non-empty counterpart " + "is printed. Without this option, missing layers are treated as a single difference of type " + "\"missing layer\"." + ) + << tl::arg ("-c|--cell-mapping", &smart_cell_mapping, "Attempts to identify cells by their properties", + "If this option is given, the algorithm will try to identify identical cells by their " + "geometrical properties (placement, size etc.) instead of their name. This way, cell renaming can " + "be detected" + ) + << tl::arg ("-t|--tolerance=value", &tolerance, "Specifies a tolerance for geometry compare", + "If this value is given, shape comparison allows for this tolerance when comparing " + "coordinates. The tolerance value is given in micrometer units." + ) + << tl::arg ("-m|--max-count=value", &max_count, "Specifies the maximum number of differences to report", + "If the value is 1, only a warning saying that the log has been abbreviated is printed. " + "If the value is >1, max-count-1 differences plus one warning about abbreviation is printed. " + "A value of 0 means \"no limitation\". To suppress all output, use --silent." + ) + ; + + cmd.brief ("This program will compare two layout files on a per-object basis"); + + cmd.parse (argc, argv); + + db::Layout layout_a; + db::Layout layout_b; + + { + db::LoadLayoutOptions load_options; + generic_reader_options_a.configure (load_options); + + tl::InputStream stream (infile_a); + db::Reader reader (stream); + reader.read (layout_a, load_options); } - std::string infile_a (argv[1]); - std::string infile_b (argv[2]); + { + db::LoadLayoutOptions load_options; + generic_reader_options_b.configure (load_options); - try { + tl::InputStream stream (infile_a); + db::Reader reader (stream); + reader.read (layout_b, load_options); + } - db::Manager m; - db::Layout layout_a (false, &m); - db::Layout layout_b (false, &m); - - { - tl::InputStream stream (infile_a); - db::Reader reader (stream); - reader.read (layout_a); - } - - { - tl::InputStream stream (infile_b); - db::Reader reader (stream); - reader.read (layout_b); - } - - if (! db::compare_layouts (layout_a, layout_b, db::layout_diff::f_boxes_as_polygons | db::layout_diff::f_no_text_orientation | db::layout_diff::f_verbose, 0 /*exact match*/)) { - throw tl::Exception ("layouts differ"); - } - - } catch (std::exception &ex) { - tl::error << ex.what (); - return 1; - } catch (tl::Exception &ex) { - tl::error << ex.msg (); - return 1; - } catch (...) { - tl::error << "unspecific error"; - return 1; + // @@@ + if (! db::compare_layouts (layout_a, layout_b, db::layout_diff::f_boxes_as_polygons | db::layout_diff::f_no_text_orientation | db::layout_diff::f_verbose, 0 /*exact match*/)) { + throw tl::Exception ("layouts differ"); } return 0; } - +BD_MAIN diff --git a/src/db/dbLayoutDiff.cc b/src/db/dbLayoutDiff.cc index e18ac947e..6c75eea44 100644 --- a/src/db/dbLayoutDiff.cc +++ b/src/db/dbLayoutDiff.cc @@ -1580,5 +1580,14 @@ compare_layouts (const db::Layout &a, const db::Layout &b, unsigned int flags, d return compare_layouts (a, b, flags, tolerance, r); } +bool +compare_layouts (const db::Layout &a, db::cell_index_type top_a, const db::Layout &b, db::cell_index_type top_b, unsigned int flags, db::Coord tolerance, size_t max_count, bool print_properties) +{ + PrintingDifferenceReceiver r; + r.set_max_count (max_count); + r.set_print_properties (print_properties); + return compare_layouts (a, top_a, b, top_b, flags, tolerance, r); +} + } diff --git a/src/db/dbLayoutDiff.h b/src/db/dbLayoutDiff.h index 6d62ada1b..3d45a77c9 100644 --- a/src/db/dbLayoutDiff.h +++ b/src/db/dbLayoutDiff.h @@ -130,9 +130,9 @@ public: * @brief Compare two layout objects * * Compare layer definitions, cells, instances and shapes and properties. - * Cells are identified by name. * Only layers with valid layer and datatype are compared. * Several flags can be specified as a bitwise or combination of the layout_diff::f_xxx constants. + * The results are printed to the info channel. * * @param a The first input layout * @param b The second input layout @@ -148,6 +148,25 @@ public: */ bool DB_PUBLIC compare_layouts (const db::Layout &a, const db::Layout &b, unsigned int flags, db::Coord tolerance, size_t max_count = 0, bool print_properties = false); +/** + * @brief Compare two layout objects + * + * This is an extended version that allows specification of two top cells to compare. + * It will print the results to the info channel. + * + * @param a The first input layout + * @param top_a The first top cell's index + * @param b The second input layout + * @param top_b The second top cell's index + * @param flags Flags to use for the comparison + * @param tolerance A coordinate tolerance to apply (0: exact match, 1: one DBU tolerance is allowed ...) + * @param max_count The maximum number of lines printed to the logger - the compare result will reflect all differences however + * @param print_properties If true, property differences are printed as well + * + * @return True, if the layouts are identical + */ +bool DB_PUBLIC compare_layouts (const db::Layout &a, db::cell_index_type top_a, const db::Layout &b, db::cell_index_type top_b, unsigned int flags, db::Coord tolerance, size_t max_count = 0, bool print_properties = false); + /** * @brief Compare two layout objects with a custom receiver for the differences *