mirror of https://github.com/KLayout/klayout.git
Some refactoring of buddy bodies and first strmcmp implementation
* Missing: functionaliy for strmcmp
This commit is contained in:
parent
bd5c7decce
commit
b4a1143588
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 <infile-a> <infile-b>\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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue