Some refactoring of buddy bodies and first strmcmp implementation

* Missing: functionaliy for strmcmp
This commit is contained in:
Matthias Koefferlein 2017-08-18 09:46:28 +02:00
parent bd5c7decce
commit b4a1143588
12 changed files with 279 additions and 215 deletions

View File

@ -24,6 +24,7 @@
#define HDR_bdInit #define HDR_bdInit
#include "bdCommon.h" #include "bdCommon.h"
#include "tlLog.h" // because of BD_MAIN
namespace bd namespace bd
{ {
@ -34,6 +35,44 @@ namespace bd
*/ */
void BD_PUBLIC init (); 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 #endif

View File

@ -28,7 +28,7 @@ namespace bd
{ {
GenericReaderOptions::GenericReaderOptions () GenericReaderOptions::GenericReaderOptions ()
: m_create_other_layers (true) : m_prefix ("i"), m_group_prefix ("Input"), m_create_other_layers (true)
{ {
// .. nothing yet .. // .. nothing yet ..
} }
@ -37,16 +37,16 @@ void
GenericReaderOptions::add_options (tl::CommandLineOptions &cmd) GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
{ {
{ {
std::string group ("[Input options - General]"); std::string group ("[" + m_group_prefix + " options - General]");
cmd << tl::arg (group + 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 " "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. " "--skip-unknown-layers, layers not listed in the layer map will not be read. "
"By default, corresponding entries are created also for unknown layers." "By default, corresponding entries are created also for unknown layers."
) )
<< tl::arg (group + << 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 " "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" "target specifications. The specifications are separated by blanks or double-slash sequences (//).\n"
"\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 + 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." "With this option set, text objects won't be read."
) )
<< tl::arg (group + << 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." "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 + 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 " "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 " "complexity. For compatibility with other readers, this option restores the standard behavior and "
"disables this feature." "disables this feature."
) )
<< tl::arg (group + << 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 " "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 " "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. " "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." "This option restores the original behavior and reports big (>32767 bytes) records are errors."
) )
<< tl::arg (group + << 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 " "This an option provided for compatibility with other readers. The mode value specifies how "
"BOX records are read:\n" "BOX records are read:\n"
"\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 + 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 " "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 " "(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." "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 + 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. " "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)." "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 + 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" "This option specifies how wire objects (W) are read:\n"
"\n" "\n"
"* 0: as square ended paths (the default)\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 + 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. " "Since DXF is unitless, this value needs to be given to specify the drawing units. "
"By default, a drawing unit of micrometers is assumed." "By default, a drawing unit of micrometers is assumed."
) )
<< tl::arg (group + << 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 " "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. " "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 " "When generating GDS texts, a value of 100 generates TEXT objects with "
"the specified size. Smaller values generate smaller sizes." "the specified size. Smaller values generate smaller sizes."
) )
<< tl::arg (group + << 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" "This value specifies how POLYLINE records are handled:\n"
"\n" "\n"
"* 0: automatic mode\n" "* 0: automatic mode\n"
@ -181,11 +181,11 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
"* 4: as 3 and auto-close contours" "* 4: as 3 and auto-close contours"
) )
<< tl::arg (group + << 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", "#--" + 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 --dxf-circle-accuracy for another way of specifying the number of points per circle." "See --" + m_long_prefix + "dxf-circle-accuracy for another way of specifying the number of points per circle."
) )
<< tl::arg (group + << 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" "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" "\"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" "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." "The value is given in the units of the DXF file."
) )
<< tl::arg (group + << 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." "If this option is used, texts are converted to polygons instead of being converted to labels."
) )
<< tl::arg (group + << 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. " "With this option, all cells not found to be instantiated are kept as additional top cells. "
"By default, such cells are removed." "By default, such cells are removed."
) )

View File

@ -67,7 +67,38 @@ public:
*/ */
void configure (db::LoadLayoutOptions &load_options); 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: private:
std::string m_prefix, m_long_prefix, m_group_prefix;
db::LayerMap m_layer_map; db::LayerMap m_layer_map;
bool m_create_other_layers; bool m_create_other_layers;
db::CommonReaderOptions m_common_reader_options; db::CommonReaderOptions m_common_reader_options;

View File

@ -28,11 +28,8 @@
#include "dbCIFWriter.h" #include "dbCIFWriter.h"
#include "tlCommandLineParser.h" #include "tlCommandLineParser.h"
int BD_MAIN_FUNC
main_func (int argc, char *argv [])
{ {
bd::init ();
bd::GenericWriterOptions generic_writer_options; bd::GenericWriterOptions generic_writer_options;
bd::GenericReaderOptions generic_reader_options; bd::GenericReaderOptions generic_reader_options;
std::string infile, outfile; std::string infile, outfile;
@ -49,9 +46,7 @@ main_func (int argc, char *argv [])
cmd.parse (argc, argv); cmd.parse (argc, argv);
db::Manager m; db::Layout layout;
db::Layout layout (&m);
db::LayerMap map;
{ {
db::LoadLayoutOptions load_options; db::LoadLayoutOptions load_options;
@ -59,7 +54,7 @@ main_func (int argc, char *argv [])
tl::InputStream stream (infile); tl::InputStream stream (infile);
db::Reader reader (stream); 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; return 0;
} }
int BD_MAIN
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";
}
}

View File

@ -28,11 +28,8 @@
#include "dbDXFWriter.h" #include "dbDXFWriter.h"
#include "tlCommandLineParser.h" #include "tlCommandLineParser.h"
int BD_MAIN_FUNC
main_func (int argc, char *argv [])
{ {
bd::init ();
bd::GenericWriterOptions generic_writer_options; bd::GenericWriterOptions generic_writer_options;
bd::GenericReaderOptions generic_reader_options; bd::GenericReaderOptions generic_reader_options;
std::string infile, outfile; std::string infile, outfile;
@ -49,9 +46,7 @@ main_func (int argc, char *argv [])
cmd.parse (argc, argv); cmd.parse (argc, argv);
db::Manager m; db::Layout layout;
db::Layout layout (&m);
db::LayerMap map;
{ {
db::LoadLayoutOptions load_options; db::LoadLayoutOptions load_options;
@ -59,7 +54,7 @@ main_func (int argc, char *argv [])
tl::InputStream stream (infile); tl::InputStream stream (infile);
db::Reader reader (stream); 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; return 0;
} }
int BD_MAIN
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";
}
}

View File

@ -28,11 +28,8 @@
#include "dbGDS2Writer.h" #include "dbGDS2Writer.h"
#include "tlCommandLineParser.h" #include "tlCommandLineParser.h"
int BD_MAIN_FUNC
main_func (int argc, char *argv [])
{ {
bd::init ();
bd::GenericWriterOptions generic_writer_options; bd::GenericWriterOptions generic_writer_options;
bd::GenericReaderOptions generic_reader_options; bd::GenericReaderOptions generic_reader_options;
std::string infile, outfile; std::string infile, outfile;
@ -49,9 +46,7 @@ main_func (int argc, char *argv [])
cmd.parse (argc, argv); cmd.parse (argc, argv);
db::Manager m; db::Layout layout;
db::Layout layout (&m);
db::LayerMap map;
{ {
db::LoadLayoutOptions load_options; db::LoadLayoutOptions load_options;
@ -59,7 +54,7 @@ main_func (int argc, char *argv [])
tl::InputStream stream (infile); tl::InputStream stream (infile);
db::Reader reader (stream); 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; return 0;
} }
int BD_MAIN
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";
}
}

View File

@ -28,11 +28,8 @@
#include "contrib/dbGDS2TextWriter.h" #include "contrib/dbGDS2TextWriter.h"
#include "tlCommandLineParser.h" #include "tlCommandLineParser.h"
int BD_MAIN_FUNC
main_func (int argc, char *argv [])
{ {
bd::init ();
bd::GenericWriterOptions generic_writer_options; bd::GenericWriterOptions generic_writer_options;
bd::GenericReaderOptions generic_reader_options; bd::GenericReaderOptions generic_reader_options;
std::string infile, outfile; std::string infile, outfile;
@ -49,9 +46,7 @@ main_func (int argc, char *argv [])
cmd.parse (argc, argv); cmd.parse (argc, argv);
db::Manager m; db::Layout layout;
db::Layout layout (&m);
db::LayerMap map;
{ {
db::LoadLayoutOptions load_options; db::LoadLayoutOptions load_options;
@ -59,7 +54,7 @@ main_func (int argc, char *argv [])
tl::InputStream stream (infile); tl::InputStream stream (infile);
db::Reader reader (stream); 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; return 0;
} }
int BD_MAIN
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";
}
}

View File

@ -28,11 +28,8 @@
#include "dbOASISWriter.h" #include "dbOASISWriter.h"
#include "tlCommandLineParser.h" #include "tlCommandLineParser.h"
int BD_MAIN_FUNC
main_func (int argc, char *argv [])
{ {
bd::init ();
bd::GenericWriterOptions generic_writer_options; bd::GenericWriterOptions generic_writer_options;
bd::GenericReaderOptions generic_reader_options; bd::GenericReaderOptions generic_reader_options;
std::string infile, outfile; std::string infile, outfile;
@ -49,9 +46,7 @@ main_func (int argc, char *argv [])
cmd.parse (argc, argv); cmd.parse (argc, argv);
db::Manager m; db::Layout layout;
db::Layout layout (&m);
db::LayerMap map;
{ {
db::LoadLayoutOptions load_options; db::LoadLayoutOptions load_options;
@ -59,7 +54,7 @@ main_func (int argc, char *argv [])
tl::InputStream stream (infile); tl::InputStream stream (infile);
db::Reader reader (stream); 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; return 0;
} }
int BD_MAIN
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";
}
}

View File

@ -27,11 +27,8 @@
#include "dbTextWriter.h" #include "dbTextWriter.h"
#include "tlCommandLineParser.h" #include "tlCommandLineParser.h"
int BD_MAIN_FUNC
main_func (int argc, char *argv [])
{ {
bd::init ();
bd::GenericReaderOptions generic_reader_options; bd::GenericReaderOptions generic_reader_options;
std::string infile, outfile; std::string infile, outfile;
@ -46,9 +43,7 @@ main_func (int argc, char *argv [])
cmd.parse (argc, argv); cmd.parse (argc, argv);
db::Manager m; db::Layout layout;
db::Layout layout (&m);
db::LayerMap map;
{ {
db::LoadLayoutOptions load_options; db::LoadLayoutOptions load_options;
@ -56,7 +51,7 @@ main_func (int argc, char *argv [])
tl::InputStream stream (infile); tl::InputStream stream (infile);
db::Reader reader (stream); 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; return 0;
} }
int BD_MAIN
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";
}
}

View File

@ -21,55 +21,147 @@
*/ */
#include "bdInit.h" #include "bdInit.h"
#include "bdReaderOptions.h"
#include "dbLayout.h" #include "dbLayout.h"
#include "dbLayoutDiff.h" #include "dbLayoutDiff.h"
#include "dbReader.h" #include "dbReader.h"
#include "tlCommandLineParser.h"
int BD_MAIN_FUNC
main (int argc, char *argv [])
{ {
if (argc != 3) { bd::init ();
printf ("Syntax: strmcmp <infile-a> <infile-b>\n");
return 1;
}
std::string infile_a (argv[1]); bd::GenericReaderOptions generic_reader_options_a;
std::string infile_b (argv[2]); generic_reader_options_a.set_prefix ("a");
generic_reader_options_a.set_long_prefix ("a-");
generic_reader_options_a.set_group_prefix ("Input A");
try { 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");
db::Manager m; std::string infile_a, infile_b;
db::Layout layout_a (false, &m); std::string top_a, top_b;
db::Layout layout_b (false, &m); 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); tl::InputStream stream (infile_a);
db::Reader reader (stream); db::Reader reader (stream);
reader.read (layout_a); reader.read (layout_a, load_options);
} }
{ {
tl::InputStream stream (infile_b); db::LoadLayoutOptions load_options;
generic_reader_options_b.configure (load_options);
tl::InputStream stream (infile_a);
db::Reader reader (stream); db::Reader reader (stream);
reader.read (layout_b); reader.read (layout_b, load_options);
} }
// @@@
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*/)) { 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"); 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;
}
return 0; return 0;
} }
BD_MAIN

View File

@ -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); 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);
}
} }

View File

@ -130,9 +130,9 @@ public:
* @brief Compare two layout objects * @brief Compare two layout objects
* *
* Compare layer definitions, cells, instances and shapes and properties. * Compare layer definitions, cells, instances and shapes and properties.
* Cells are identified by name.
* Only layers with valid layer and datatype are compared. * 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. * 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 a The first input layout
* @param b The second 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); 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 * @brief Compare two layout objects with a custom receiver for the differences
* *