Added buddies to build.

This commit is contained in:
Matthias Koefferlein 2017-08-09 22:37:58 +02:00
parent 5514aa8355
commit 4dea5b40f2
33 changed files with 2065 additions and 4 deletions

13
src/buddies/buddies.pro Normal file
View File

@ -0,0 +1,13 @@
TEMPLATE = subdirs
SUBDIRS = \
strm2cif \
strm2dxf \
strm2gds \
strm2gdstxt \
strm2oas \
strm2txt \
strmclip \
strmcmp \
strmxor \

18
src/buddies/mkbuddies.sh Normal file
View File

@ -0,0 +1,18 @@
for x in *.cc; do
xx=${x/.cc}
echo "" >$xx/$xx.pro
echo 'include($$PWD/../../klayout.pri)' >>$xx/$xx.pro
echo "" >>$xx/$xx.pro
echo "TEMPLATE = app" >>$xx/$xx.pro
echo "" >>$xx/$xx.pro
echo "TARGET = $xx" >>$xx/$xx.pro
echo 'DESTDIR = $$OUT_PWD/../..' >>$xx/$xx.pro
echo "" >> $xx/$xx.pro
echo "SOURCES = $x" >>$xx/$xx.pro
echo "" >> $xx/$xx.pro
echo "INCLUDEPATH += ../../tl ../../db ../../gsi" >> $xx/$xx.pro
echo "DEPENDPATH += ../../tl ../../db ../../gsi" >> $xx/$xx.pro
echo 'LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi' >> $xx/$xx.pro
done

49
src/buddies/strm2cif.cc Normal file
View File

@ -0,0 +1,49 @@
#include "dbLayout.h"
#include "dbReader.h"
#include "dbCIFWriter.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2cif <infile> <outfile>\n");
return 1;
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
try {
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
tl::OutputStream stream (outfile);
db::CIFWriter writer;
writer.write (layout, stream, db::SaveLayoutOptions ());
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,70 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2017 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbLayout.h"
#include "dbReader.h"
#include "dbCIFWriter.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2cif <infile> <outfile>\n");
return 1;
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
try {
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
tl::OutputStream stream (outfile);
db::CIFWriter writer;
writer.write (layout, stream, db::SaveLayoutOptions ());
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,13 @@
include($$PWD/../../klayout.pri)
TEMPLATE = app
TARGET = strm2cif
DESTDIR = $$OUT_PWD/../..
SOURCES = strm2cif.cc
INCLUDEPATH += ../../tl ../../db ../../gsi
DEPENDPATH += ../../tl ../../db ../../gsi
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi

49
src/buddies/strm2dxf.cc Normal file
View File

@ -0,0 +1,49 @@
#include "dbLayout.h"
#include "dbReader.h"
#include "dbDXFWriter.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2dxf <infile> <outfile>\n");
return 1;
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
try {
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
tl::OutputStream stream (outfile);
db::DXFWriter writer;
writer.write (layout, stream, db::SaveLayoutOptions ());
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,70 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2017 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbLayout.h"
#include "dbReader.h"
#include "dbDXFWriter.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2dxf <infile> <outfile>\n");
return 1;
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
try {
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
tl::OutputStream stream (outfile);
db::DXFWriter writer;
writer.write (layout, stream, db::SaveLayoutOptions ());
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,13 @@
include($$PWD/../../klayout.pri)
TEMPLATE = app
TARGET = strm2dxf
DESTDIR = $$OUT_PWD/../..
SOURCES = strm2dxf.cc
INCLUDEPATH += ../../tl ../../db ../../gsi
DEPENDPATH += ../../tl ../../db ../../gsi
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi

49
src/buddies/strm2gds.cc Normal file
View File

@ -0,0 +1,49 @@
#include "dbLayout.h"
#include "dbReader.h"
#include "dbGDS2Writer.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2gds <infile> <outfile>\n");
return 1;
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
try {
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
tl::OutputStream stream (outfile);
db::GDS2Writer writer;
writer.write (layout, stream, db::SaveLayoutOptions ());
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,70 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2017 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbLayout.h"
#include "dbReader.h"
#include "dbGDS2Writer.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2gds <infile> <outfile>\n");
return 1;
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
try {
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
tl::OutputStream stream (outfile);
db::GDS2Writer writer;
writer.write (layout, stream, db::SaveLayoutOptions ());
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,13 @@
include($$PWD/../../klayout.pri)
TEMPLATE = app
TARGET = strm2gds
DESTDIR = $$OUT_PWD/../..
SOURCES = strm2gds.cc
INCLUDEPATH += ../../tl ../../db ../../gsi
DEPENDPATH += ../../tl ../../db ../../gsi
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi

View File

@ -0,0 +1,49 @@
#include "dbLayout.h"
#include "dbReader.h"
#include "contrib/gds2_txt/dbGDS2TextWriter.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2gdstxt <infile> <outfile>\n");
return 1;
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
try {
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
tl::OutputStream stream (outfile);
db::GDS2WriterText writer;
writer.write (layout, stream, db::SaveLayoutOptions ());
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,70 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2017 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbLayout.h"
#include "dbReader.h"
#include "contrib/dbGDS2TextWriter.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2gdstxt <infile> <outfile>\n");
return 1;
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
try {
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
tl::OutputStream stream (outfile);
db::GDS2WriterText writer;
writer.write (layout, stream, db::SaveLayoutOptions ());
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,13 @@
include($$PWD/../../klayout.pri)
TEMPLATE = app
TARGET = strm2gdstxt
DESTDIR = $$OUT_PWD/../..
SOURCES = strm2gdstxt.cc
INCLUDEPATH += ../../tl ../../db ../../gsi
DEPENDPATH += ../../tl ../../db ../../gsi
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi

108
src/buddies/strm2oas.cc Normal file
View File

@ -0,0 +1,108 @@
#include "dbLayout.h"
#include "dbReader.h"
#include "dbOASISWriter.h"
#include "tlTimer.h"
#include <memory>
void
syntax ()
{
printf ("Syntax: strm2oas [-o <optimization-level>] [-c] <infile> <outfile>\n");
printf ("\n");
printf (" -o n Specify optimization level (0..10, default is 2)\n");
printf (" -c Use CBLOCK compression\n");
printf (" -s Use strict mode\n");
printf (" -r Recompression (ignore existing arrays)\n");
printf (" -v Verbose - print timing information\n");
}
int
main (int argc, char *argv [])
{
std::string infile, outfile;
bool verbose = false;
try {
db::OASISWriterOptions writer_options;
for (int i = 1; i < argc; ++i) {
std::string o (argv[i]);
if (o == "-o") {
if (i < argc - 1) {
++i;
tl::from_string (argv[i], writer_options.compression_level);
}
} else if (o == "-v") {
verbose = true;
} else if (o == "-c") {
writer_options.write_cblocks = true;
} else if (o == "-s") {
writer_options.strict_mode = true;
} else if (o == "-r") {
writer_options.recompress = true;
} else if (o == "-h" || o == "-help" || o == "--help") {
syntax ();
return 0;
} else if (argv[i][0] == '-') {
throw tl::Exception ("Unknown option: %s - use '-h' for help", (const char *) argv[i]);
} else if (infile.empty ()) {
infile = argv[i];
} else if (outfile.empty ()) {
outfile = argv[i];
} else {
throw tl::Exception ("Superfluous argument: %s - use '-h' for help", (const char *) argv[i]);
}
}
if (infile.empty ()) {
throw tl::Exception ("Input file not given");
}
if (outfile.empty ()) {
throw tl::Exception ("Output file not given");
}
db::Manager m;
db::Layout layout (false, &m);
db::LayerMap map;
{
std::auto_ptr<tl::SelfTimer> timer;
if (verbose) {
timer.reset (new tl::SelfTimer ("Reading input layout"));
}
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
db::SaveLayoutOptions options;
options.set_specific_options (writer_options);
std::auto_ptr<tl::SelfTimer> timer;
if (verbose) {
timer.reset (new tl::SelfTimer ("Writing OAS"));
}
tl::OutputStream stream (outfile);
db::OASISWriter writer;
writer.write (layout, stream, options);
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,129 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2017 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbLayout.h"
#include "dbReader.h"
#include "dbOASISWriter.h"
#include "tlTimer.h"
#include <memory>
void
syntax ()
{
printf ("Syntax: strm2oas [-o <optimization-level>] [-c] <infile> <outfile>\n");
printf ("\n");
printf (" -o n Specify optimization level (0..10, default is 2)\n");
printf (" -c Use CBLOCK compression\n");
printf (" -s Use strict mode\n");
printf (" -r Recompression (ignore existing arrays)\n");
printf (" -v Verbose - print timing information\n");
}
int
main (int argc, char *argv [])
{
std::string infile, outfile;
bool verbose = false;
try {
db::OASISWriterOptions writer_options;
for (int i = 1; i < argc; ++i) {
std::string o (argv[i]);
if (o == "-o") {
if (i < argc - 1) {
++i;
tl::from_string (argv[i], writer_options.compression_level);
}
} else if (o == "-v") {
verbose = true;
} else if (o == "-c") {
writer_options.write_cblocks = true;
} else if (o == "-s") {
writer_options.strict_mode = true;
} else if (o == "-r") {
writer_options.recompress = true;
} else if (o == "-h" || o == "-help" || o == "--help") {
syntax ();
return 0;
} else if (argv[i][0] == '-') {
throw tl::Exception ("Unknown option: %s - use '-h' for help", (const char *) argv[i]);
} else if (infile.empty ()) {
infile = argv[i];
} else if (outfile.empty ()) {
outfile = argv[i];
} else {
throw tl::Exception ("Superfluous argument: %s - use '-h' for help", (const char *) argv[i]);
}
}
if (infile.empty ()) {
throw tl::Exception ("Input file not given");
}
if (outfile.empty ()) {
throw tl::Exception ("Output file not given");
}
db::Manager m;
db::Layout layout (false, &m);
db::LayerMap map;
{
std::auto_ptr<tl::SelfTimer> timer;
if (verbose) {
timer.reset (new tl::SelfTimer ("Reading input layout"));
}
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
db::SaveLayoutOptions options;
options.set_options (writer_options);
std::auto_ptr<tl::SelfTimer> timer;
if (verbose) {
timer.reset (new tl::SelfTimer ("Writing OAS"));
}
tl::OutputStream stream (outfile);
db::OASISWriter writer;
writer.write (layout, stream, options);
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,13 @@
include($$PWD/../../klayout.pri)
TEMPLATE = app
TARGET = strm2oas
DESTDIR = $$OUT_PWD/../..
SOURCES = strm2oas.cc
INCLUDEPATH += ../../tl ../../db ../../gsi
DEPENDPATH += ../../tl ../../db ../../gsi
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi

50
src/buddies/strm2txt.cc Normal file
View File

@ -0,0 +1,50 @@
#include "dbLayout.h"
#include "dbReader.h"
#include "dbTextWriter.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2txt <infile> <outfile>\n");
return 1;
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
try {
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
reader.set_warnings_as_errors (true);
map = reader.read (layout);
}
{
tl::OutputStream stream (outfile);
db::TextWriter writer (stream);
writer.write (layout);
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,71 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2017 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbLayout.h"
#include "dbReader.h"
#include "dbTextWriter.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2txt <infile> <outfile>\n");
return 1;
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
try {
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
reader.set_warnings_as_errors (true);
map = reader.read (layout);
}
{
tl::OutputStream stream (outfile);
db::TextWriter writer (stream);
writer.write (layout);
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
}
return 0;
}

View File

@ -0,0 +1,13 @@
include($$PWD/../../klayout.pri)
TEMPLATE = app
TARGET = strm2txt
DESTDIR = $$OUT_PWD/../..
SOURCES = strm2txt.cc
INCLUDEPATH += ../../tl ../../db ../../gsi
DEPENDPATH += ../../tl ../../db ../../gsi
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi

235
src/buddies/strmclip.cc Normal file
View File

@ -0,0 +1,235 @@
#include "dbClip.h"
#include "dbLayout.h"
#include "dbGDS2Writer.h"
#include "dbOASISWriter.h"
#include "dbReader.h"
#include "layParsedLayerSource.h"
#include "tlLog.h"
struct ClipData
{
ClipData ()
: file_in (), file_out (), clip_layer (),
oasis (false), gzip (false)
{ }
std::string file_in;
std::string file_out;
lay::ParsedLayerSource clip_layer;
bool oasis;
bool gzip;
std::vector <db::DBox> clip_boxes;
std::string result;
std::string top;
};
void clip (const ClipData &data)
{
db::Manager m;
db::Layout layout (&m);
db::Layout target_layout (&m);
{
tl::InputStream stream (data.file_in);
db::Reader reader (stream);
reader.read (layout);
}
// create the layers in the target layout as well
for (unsigned int i = 0; i < layout.layers (); ++i) {
if (layout.is_valid_layer (i)) {
target_layout.insert_layer (i, layout.get_properties (i));
}
}
// copy the properties repository in order to have the same ID mapping
target_layout.properties_repository () = layout.properties_repository ();
target_layout.dbu (layout.dbu ());
// look for the clip layer
int clip_layer_index = -1;
for (unsigned int i = 0; i < layout.layers (); ++i) {
if (layout.is_valid_layer (i) && data.clip_layer.match (layout.get_properties (i))) {
clip_layer_index = int (i);
break;
}
}
tl::log << "Clip layer index is " << clip_layer_index;
// get top cells
std::vector <db::cell_index_type> top_cells;
if (data.top.empty ()) {
top_cells.assign (layout.begin_top_down (), layout.end_top_cells ());
} else {
std::pair<bool, db::cell_index_type> tc = layout.cell_by_name (data.top.c_str ());
if (! tc.first) {
throw tl::Exception ("Cell %s is not a valid cell in the input layout", data.top);
}
top_cells.push_back (tc.second);
}
// go through the top cells
for (std::vector <db::cell_index_type>::const_iterator tc = top_cells.begin (); tc != top_cells.end (); ++tc) {
std::vector <db::Box> clip_boxes;
// add the explicit boxes first
for (std::vector <db::DBox>::const_iterator b = data.clip_boxes.begin (); b != data.clip_boxes.end (); ++b) {
clip_boxes.push_back (db::Box::from_double (*b * (1.0 / layout.dbu ())));
}
// fetch the boxes of the clip shapes
if (clip_layer_index >= 0) {
collect_clip_boxes (layout, *tc, clip_layer_index, clip_boxes);
}
// sort our duplicate boxes
std::sort (clip_boxes.begin (), clip_boxes.end ());
clip_boxes.erase (std::unique (clip_boxes.begin (), clip_boxes.end ()), clip_boxes.end ());
tl::log << "Clip boxes are:";
for (std::vector <db::Box>::const_iterator cbx = clip_boxes.begin (); cbx != clip_boxes.end (); ++cbx) {
tl::log << " " << cbx->to_string ();
}
std::vector<db::cell_index_type> new_cells = db::clip_layout (layout, target_layout, *tc, clip_boxes);
// create "very top" cells to put the result cells into
std::string result_top;
if (! data.result.empty ()) {
result_top = data.result;
} else {
result_top = std::string ("CLIPPED_") + layout.cell_name (*tc);
}
db::cell_index_type clip_top = target_layout.add_cell (result_top.c_str ());
db::Cell &clip_top_cell = target_layout.cell (clip_top);
for (std::vector <db::cell_index_type>::const_iterator cc = new_cells.begin (); cc != new_cells.end (); ++cc) {
clip_top_cell.insert (db::CellInstArray (db::CellInst (*cc), db::Trans ()));
}
}
// write the layout
tl::OutputStreamBase *out_file = 0;
try {
tl::OutputStream stream (data.file_out, data.gzip ? tl::OutputStream::OM_Zlib : tl::OutputStream::OM_Plain);
if (data.oasis) {
db::OASISWriter writer;
writer.write (target_layout, stream, db::SaveLayoutOptions ());
} else {
db::GDS2Writer writer;
writer.write (target_layout, stream, db::SaveLayoutOptions ());
}
delete out_file;
} catch (...) {
if (out_file) {
delete out_file;
}
throw;
}
}
void print_syntax ()
{
printf ("Syntax: strmclip [<options>] <infile> <outfile>\n");
printf ("\n");
printf ("Options are:\n");
printf (" -l 'l/d' take clip regions from layer l, datatype d\n");
printf (" -o produce oasis output\n");
printf (" -g produce gds output\n");
printf (" -z gzip output\n");
printf (" -t 'cell' use this cell from input (default: determine top cell automatically)\n");
printf (" -x 'name' use this cell as top cell in output\n");
printf (" -r 'l,b,r,t' explicitly specify a clip retangle (can be present multiple times)\n");
}
int
main (int argc, char *argv [])
{
try {
ClipData data;
for (int n = 1; n < argc; ++n) {
if (std::string (argv [n]) == "-h") {
print_syntax ();
return 0;
} else if (std::string (argv [n]) == "-o") {
data.oasis = true;
} else if (std::string (argv [n]) == "-g") {
data.oasis = false;
} else if (std::string (argv [n]) == "-z") {
data.gzip = true;
} else if (std::string (argv [n]) == "-x") {
if (n < argc + 1) {
++n;
data.result = argv [n];
}
} else if (std::string (argv [n]) == "-t") {
if (n < argc + 1) {
++n;
data.top = argv [n];
}
} else if (std::string (argv [n]) == "-r") {
if (n < argc + 1) {
++n;
tl::Extractor ex (argv [n]);
double l = 0.0, b = 0.0, r = 0.0, t = 0.0;
ex.read (l); ex.expect (",");
ex.read (b); ex.expect (",");
ex.read (r); ex.expect (",");
ex.read (t); ex.expect_end ();
data.clip_boxes.push_back (db::DBox (l, b, r, t));
}
} else if (std::string (argv [n]) == "-l") {
if (n < argc + 1) {
++n;
data.clip_layer = lay::ParsedLayerSource (argv [n]);
}
} else if (argv [n][0] == '-') {
print_syntax ();
throw tl::Exception ("Unknown option: " + std::string (argv [n]));
} else if (data.file_in.empty ()) {
data.file_in = argv [n];
} else if (data.file_out.empty ()) {
data.file_out = argv [n];
} else {
print_syntax ();
throw tl::Exception ("Superfluous command element: " + std::string (argv [n]));
}
}
if (data.file_in.empty () || data.file_out.empty ()) {
print_syntax ();
throw tl::Exception ("Input or output file name missing");
}
clip (data);
} 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;
}

View File

@ -0,0 +1,257 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2017 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbClip.h"
#include "dbLayout.h"
#include "dbGDS2Writer.h"
#include "dbOASISWriter.h"
#include "dbReader.h"
#include "tlLog.h"
struct ClipData
{
ClipData ()
: file_in (), file_out (), clip_layer (),
oasis (false), gzip (false)
{ }
std::string file_in;
std::string file_out;
db::LayerProperties clip_layer;
bool oasis;
bool gzip;
std::vector <db::DBox> clip_boxes;
std::string result;
std::string top;
};
void clip (const ClipData &data)
{
db::Manager m;
db::Layout layout (&m);
db::Layout target_layout (&m);
{
tl::InputStream stream (data.file_in);
db::Reader reader (stream);
reader.read (layout);
}
// create the layers in the target layout as well
for (unsigned int i = 0; i < layout.layers (); ++i) {
if (layout.is_valid_layer (i)) {
target_layout.insert_layer (i, layout.get_properties (i));
}
}
// copy the properties repository in order to have the same ID mapping
target_layout.properties_repository () = layout.properties_repository ();
target_layout.dbu (layout.dbu ());
// look for the clip layer
int clip_layer_index = -1;
for (unsigned int i = 0; i < layout.layers (); ++i) {
if (layout.is_valid_layer (i) && data.clip_layer.log_equal (layout.get_properties (i))) {
clip_layer_index = int (i);
break;
}
}
tl::log << "Clip layer index is " << clip_layer_index;
// get top cells
std::vector <db::cell_index_type> top_cells;
if (data.top.empty ()) {
top_cells.assign (layout.begin_top_down (), layout.end_top_cells ());
} else {
std::pair<bool, db::cell_index_type> tc = layout.cell_by_name (data.top.c_str ());
if (! tc.first) {
throw tl::Exception ("Cell %s is not a valid cell in the input layout", data.top);
}
top_cells.push_back (tc.second);
}
// go through the top cells
for (std::vector <db::cell_index_type>::const_iterator tc = top_cells.begin (); tc != top_cells.end (); ++tc) {
std::vector <db::Box> clip_boxes;
// add the explicit boxes first
for (std::vector <db::DBox>::const_iterator b = data.clip_boxes.begin (); b != data.clip_boxes.end (); ++b) {
clip_boxes.push_back (db::VCplxTrans (1.0 / layout.dbu ()) * *b);
}
// fetch the boxes of the clip shapes
if (clip_layer_index >= 0) {
collect_clip_boxes (layout, *tc, clip_layer_index, clip_boxes);
}
// sort our duplicate boxes
std::sort (clip_boxes.begin (), clip_boxes.end ());
clip_boxes.erase (std::unique (clip_boxes.begin (), clip_boxes.end ()), clip_boxes.end ());
tl::log << "Clip boxes are:";
for (std::vector <db::Box>::const_iterator cbx = clip_boxes.begin (); cbx != clip_boxes.end (); ++cbx) {
tl::log << " " << cbx->to_string ();
}
std::vector<db::cell_index_type> new_cells = db::clip_layout (layout, target_layout, *tc, clip_boxes, true /*stable*/);
// create "very top" cells to put the result cells into
std::string result_top;
if (! data.result.empty ()) {
result_top = data.result;
} else {
result_top = std::string ("CLIPPED_") + layout.cell_name (*tc);
}
db::cell_index_type clip_top = target_layout.add_cell (result_top.c_str ());
db::Cell &clip_top_cell = target_layout.cell (clip_top);
for (std::vector <db::cell_index_type>::const_iterator cc = new_cells.begin (); cc != new_cells.end (); ++cc) {
clip_top_cell.insert (db::CellInstArray (db::CellInst (*cc), db::Trans ()));
}
}
// write the layout
tl::OutputStreamBase *out_file = 0;
try {
tl::OutputStream stream (data.file_out, data.gzip ? tl::OutputStream::OM_Zlib : tl::OutputStream::OM_Plain);
if (data.oasis) {
db::OASISWriter writer;
writer.write (target_layout, stream, db::SaveLayoutOptions ());
} else {
db::GDS2Writer writer;
writer.write (target_layout, stream, db::SaveLayoutOptions ());
}
delete out_file;
} catch (...) {
if (out_file) {
delete out_file;
}
throw;
}
}
void print_syntax ()
{
printf ("Syntax: strmclip [<options>] <infile> <outfile>\n");
printf ("\n");
printf ("Options are:\n");
printf (" -l 'l/d' take clip regions from layer l, datatype d\n");
printf (" -o produce oasis output\n");
printf (" -g produce gds output\n");
printf (" -z gzip output\n");
printf (" -t 'cell' use this cell from input (default: determine top cell automatically)\n");
printf (" -x 'name' use this cell as top cell in output\n");
printf (" -r 'l,b,r,t' explicitly specify a clip retangle (can be present multiple times)\n");
}
int
main (int argc, char *argv [])
{
try {
ClipData data;
for (int n = 1; n < argc; ++n) {
if (std::string (argv [n]) == "-h") {
print_syntax ();
return 0;
} else if (std::string (argv [n]) == "-o") {
data.oasis = true;
} else if (std::string (argv [n]) == "-g") {
data.oasis = false;
} else if (std::string (argv [n]) == "-z") {
data.gzip = true;
} else if (std::string (argv [n]) == "-x") {
if (n < argc + 1) {
++n;
data.result = argv [n];
}
} else if (std::string (argv [n]) == "-t") {
if (n < argc + 1) {
++n;
data.top = argv [n];
}
} else if (std::string (argv [n]) == "-r") {
if (n < argc + 1) {
++n;
tl::Extractor ex (argv [n]);
double l = 0.0, b = 0.0, r = 0.0, t = 0.0;
ex.read (l); ex.expect (",");
ex.read (b); ex.expect (",");
ex.read (r); ex.expect (",");
ex.read (t); ex.expect_end ();
data.clip_boxes.push_back (db::DBox (l, b, r, t));
}
} else if (std::string (argv [n]) == "-l") {
if (n < argc + 1) {
++n;
tl::Extractor ex (argv[n]);
db::LayerProperties lp;
lp.read (ex);
data.clip_layer = lp;
}
} else if (argv [n][0] == '-') {
print_syntax ();
throw tl::Exception ("Unknown option: " + std::string (argv [n]));
} else if (data.file_in.empty ()) {
data.file_in = argv [n];
} else if (data.file_out.empty ()) {
data.file_out = argv [n];
} else {
print_syntax ();
throw tl::Exception ("Superfluous command element: " + std::string (argv [n]));
}
}
if (data.file_in.empty () || data.file_out.empty ()) {
print_syntax ();
throw tl::Exception ("Input or output file name missing");
}
clip (data);
} 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;
}

View File

@ -0,0 +1,13 @@
include($$PWD/../../klayout.pri)
TEMPLATE = app
TARGET = strmclip
DESTDIR = $$OUT_PWD/../..
SOURCES = strmclip.cc
INCLUDEPATH += ../../tl ../../db ../../gsi
DEPENDPATH += ../../tl ../../db ../../gsi
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi

54
src/buddies/strmcmp.cc Normal file
View File

@ -0,0 +1,54 @@
#include "dbLayout.h"
#include "dbLayoutDiff.h"
#include "dbReader.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strmcmp <infile-a> <infile-b>\n");
return 1;
}
std::string infile_a (argv[1]);
std::string infile_b (argv[2]);
try {
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)) {
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;
}

View File

@ -0,0 +1,74 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2017 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbLayout.h"
#include "dbLayoutDiff.h"
#include "dbReader.h"
int
main (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strmcmp <infile-a> <infile-b>\n");
return 1;
}
std::string infile_a (argv[1]);
std::string infile_b (argv[2]);
try {
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;
}
return 0;
}

View File

@ -0,0 +1,13 @@
include($$PWD/../../klayout.pri)
TEMPLATE = app
TARGET = strmcmp
DESTDIR = $$OUT_PWD/../..
SOURCES = strmcmp.cc
INCLUDEPATH += ../../tl ../../db ../../gsi
DEPENDPATH += ../../tl ../../db ../../gsi
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi

215
src/buddies/strmxor.cc Normal file
View File

@ -0,0 +1,215 @@
#include "dbLayout.h"
#include "dbReader.h"
#include "dbWriter.h"
#include "dbEdgeProcessor.h"
#include "tlString.h"
void
syntax ()
{
printf ("Syntax: strmxor [-u <undersize>] [-topa <topcell-a>] [-topb <topcell-b>] [-oasis|-oas] [-gds2|-gds] <infile-a> <infile-b> [<outfile>]\n");
}
int
main (int argc, char *argv [])
{
std::string topcell_a;
std::string topcell_b;
std::string infile_a;
std::string infile_b;
std::string outfile;
double undersize = 0.0;
bool format_set = false;
std::string format;
int ret = 0;
try {
for (int i = 1; i < argc; ++i) {
std::string o (argv[i]);
if (o == "-u") {
if (i < argc - 1) {
++i;
tl::from_string (argv[i], undersize);
}
} else if (o == "-topa") {
if (i < argc - 1) {
++i;
topcell_a = argv[i];
}
} else if (o == "-topb") {
if (i < argc - 1) {
++i;
topcell_b = argv[i];
}
} else if (o == "-oasis" || o == "-oas") {
format_set = true;
format = "OASIS";
} else if (o == "-gds2" || o == "-gds") {
format_set = true;
format = "GDS2";
} else if (o == "-h" || o == "-help" || o == "--help") {
syntax ();
return 0;
} else if (argv[i][0] == '-') {
throw tl::Exception("Unknown option: %s - use '-h' for help", (const char *) argv[i]);
} else if (infile_a.empty ()) {
infile_a = argv[i];
} else if (infile_b.empty ()) {
infile_b = argv[i];
} else if (outfile.empty ()) {
outfile = argv[i];
} else {
throw tl::Exception("Superfluous argument: %s - use '-h' for help", (const char *) argv[i]);
}
}
if (infile_a.empty () || infile_b.empty ()) {
throw tl::Exception("Both input files must be specified");
}
db::Manager m;
db::Layout layout_a (&m);
db::Layout layout_b (&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);
}
db::cell_index_type top_a;
if (topcell_a.empty ()) {
db::Layout::top_down_iterator t = layout_a.begin_top_down ();
if (t == layout_a.end_top_cells ()) {
throw tl::Exception ("Layout A (%s) does not have a top cell", infile_a);
}
top_a = *t++;
if (t != layout_a.end_top_cells ()) {
throw tl::Exception ("Layout A (%s) has multiple top cells", infile_a);
}
} else {
std::pair<bool, db::cell_index_type> cn = layout_a.cell_by_name (topcell_a.c_str ());
if (! cn.first) {
throw tl::Exception ("Layout A (%s) does not have a topcell called '%s'", infile_a, topcell_a);
}
top_a = cn.second;
}
db::cell_index_type top_b;
if (topcell_b.empty ()) {
db::Layout::top_down_iterator t = layout_b.begin_top_down ();
if (t == layout_b.end_top_cells ()) {
throw tl::Exception ("Layout B (%s) does not have a top cell", infile_b);
}
top_b = *t++;
if (t != layout_b.end_top_cells ()) {
throw tl::Exception ("Layout B (%s) has multiple top cells", infile_b);
}
} else {
std::pair<bool, db::cell_index_type> cn = layout_b.cell_by_name (topcell_b.c_str ());
if (! cn.first) {
throw tl::Exception ("Layout B (%s) does not have a topcell called '%s'", infile_b, topcell_b);
}
top_b = cn.second;
}
if (fabs (layout_a.dbu () - layout_b.dbu ()) > 1e-6) {
throw tl::Exception("Input file database units differ (A:%g vs. B:%g)", layout_a.dbu (), layout_b.dbu ());
}
std::map<db::LayerProperties, std::pair<int, int> > all_layers;
for (unsigned int i = 0; i < layout_a.layers (); ++i) {
if (layout_a.is_valid_layer (i)) {
all_layers.insert (std::make_pair(layout_a.get_properties (i), std::make_pair(-1, -1))).first->second.first = int (i);
}
}
for (unsigned int i = 0; i < layout_b.layers (); ++i) {
if (layout_b.is_valid_layer (i)) {
all_layers.insert (std::make_pair(layout_b.get_properties (i), std::make_pair(-1, -1))).first->second.second = int (i);
}
}
db::Layout output;
output.dbu (layout_a.dbu ());
db::cell_index_type top_id = output.add_cell (layout_a.cell_name (top_a));
db::Coord us = db::coord_traits<db::Coord>::rounded (undersize / layout_a.dbu ());
db::ShapeProcessor sp;
size_t ndiff = 0;
for (std::map<db::LayerProperties, std::pair<int, int> >::const_iterator l = all_layers.begin (); l != all_layers.end (); ++l) {
int layer_id = output.insert_layer (l->first);
if (l->second.first >= 0 && l->second.second >= 0) {
sp.boolean (layout_a, layout_a.cell (top_a), l->second.first, layout_b, layout_b.cell (top_b), l->second.second,
output.cell (top_id).shapes (layer_id), db::BooleanOp::Xor, true /*recursive*/);
sp.size (output, output.cell (top_id), layer_id, output.cell (top_id).shapes (layer_id), -us, (unsigned int) 2, true /*recursive*/);
} else if (l->second.first >= 0) {
sp.size (layout_a, layout_a.cell (top_a), l->second.first, output.cell (top_id).shapes (layer_id), -us, (unsigned int) 2, true /*recursive*/);
} else if (l->second.second >= 0) {
sp.size (layout_b, layout_b.cell (top_b), l->second.second, output.cell (top_id).shapes (layer_id), -us, (unsigned int) 2, true /*recursive*/);
}
size_t n = output.cell (top_id).shapes (layer_id).size ();
// if (n > 0) {
ndiff += n;
tl::info << " " << l->first.to_string () << ": " << n;
// }
}
if (ndiff > 0) {
tl::info << "----------------------------------------------------";
tl::info << " Total differences: " << ndiff;
ret = 1;
}
if (! outfile.empty ()) {
db::SaveLayoutOptions options;
options.set_format_from_filename (outfile);
if (format_set) {
options.set_format (format);
}
db::Writer writer (options);
tl::OutputStream file (outfile, tl::OutputStream::OM_Auto);
writer.write (output, file);
}
} 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 ret;
}

View File

@ -0,0 +1,235 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2017 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbLayout.h"
#include "dbReader.h"
#include "dbWriter.h"
#include "dbShapeProcessor.h"
#include "tlString.h"
void
syntax ()
{
printf ("Syntax: strmxor [-u <undersize>] [-topa <topcell-a>] [-topb <topcell-b>] [-oasis|-oas] [-gds2|-gds] <infile-a> <infile-b> [<outfile>]\n");
}
int
main (int argc, char *argv [])
{
std::string topcell_a;
std::string topcell_b;
std::string infile_a;
std::string infile_b;
std::string outfile;
double undersize = 0.0;
bool format_set = false;
std::string format;
int ret = 0;
try {
for (int i = 1; i < argc; ++i) {
std::string o (argv[i]);
if (o == "-u") {
if (i < argc - 1) {
++i;
tl::from_string (argv[i], undersize);
}
} else if (o == "-topa") {
if (i < argc - 1) {
++i;
topcell_a = argv[i];
}
} else if (o == "-topb") {
if (i < argc - 1) {
++i;
topcell_b = argv[i];
}
} else if (o == "-oasis" || o == "-oas") {
format_set = true;
format = "OASIS";
} else if (o == "-gds2" || o == "-gds") {
format_set = true;
format = "GDS2";
} else if (o == "-h" || o == "-help" || o == "--help") {
syntax ();
return 0;
} else if (argv[i][0] == '-') {
throw tl::Exception("Unknown option: %s - use '-h' for help", (const char *) argv[i]);
} else if (infile_a.empty ()) {
infile_a = argv[i];
} else if (infile_b.empty ()) {
infile_b = argv[i];
} else if (outfile.empty ()) {
outfile = argv[i];
} else {
throw tl::Exception("Superfluous argument: %s - use '-h' for help", (const char *) argv[i]);
}
}
if (infile_a.empty () || infile_b.empty ()) {
throw tl::Exception("Both input files must be specified");
}
db::Manager m;
db::Layout layout_a (&m);
db::Layout layout_b (&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);
}
db::cell_index_type top_a;
if (topcell_a.empty ()) {
db::Layout::top_down_iterator t = layout_a.begin_top_down ();
if (t == layout_a.end_top_cells ()) {
throw tl::Exception ("Layout A (%s) does not have a top cell", infile_a);
}
top_a = *t++;
if (t != layout_a.end_top_cells ()) {
throw tl::Exception ("Layout A (%s) has multiple top cells", infile_a);
}
} else {
std::pair<bool, db::cell_index_type> cn = layout_a.cell_by_name (topcell_a.c_str ());
if (! cn.first) {
throw tl::Exception ("Layout A (%s) does not have a topcell called '%s'", infile_a, topcell_a);
}
top_a = cn.second;
}
db::cell_index_type top_b;
if (topcell_b.empty ()) {
db::Layout::top_down_iterator t = layout_b.begin_top_down ();
if (t == layout_b.end_top_cells ()) {
throw tl::Exception ("Layout B (%s) does not have a top cell", infile_b);
}
top_b = *t++;
if (t != layout_b.end_top_cells ()) {
throw tl::Exception ("Layout B (%s) has multiple top cells", infile_b);
}
} else {
std::pair<bool, db::cell_index_type> cn = layout_b.cell_by_name (topcell_b.c_str ());
if (! cn.first) {
throw tl::Exception ("Layout B (%s) does not have a topcell called '%s'", infile_b, topcell_b);
}
top_b = cn.second;
}
if (fabs (layout_a.dbu () - layout_b.dbu ()) > 1e-6) {
throw tl::Exception("Input file database units differ (A:%g vs. B:%g)", layout_a.dbu (), layout_b.dbu ());
}
std::map<db::LayerProperties, std::pair<int, int> > all_layers;
for (unsigned int i = 0; i < layout_a.layers (); ++i) {
if (layout_a.is_valid_layer (i)) {
all_layers.insert (std::make_pair(layout_a.get_properties (i), std::make_pair(-1, -1))).first->second.first = int (i);
}
}
for (unsigned int i = 0; i < layout_b.layers (); ++i) {
if (layout_b.is_valid_layer (i)) {
all_layers.insert (std::make_pair(layout_b.get_properties (i), std::make_pair(-1, -1))).first->second.second = int (i);
}
}
db::Layout output;
output.dbu (layout_a.dbu ());
db::cell_index_type top_id = output.add_cell (layout_a.cell_name (top_a));
db::Coord us = db::coord_traits<db::Coord>::rounded (undersize / layout_a.dbu ());
db::ShapeProcessor sp;
size_t ndiff = 0;
for (std::map<db::LayerProperties, std::pair<int, int> >::const_iterator l = all_layers.begin (); l != all_layers.end (); ++l) {
int layer_id = output.insert_layer (l->first);
if (l->second.first >= 0 && l->second.second >= 0) {
sp.boolean (layout_a, layout_a.cell (top_a), l->second.first, layout_b, layout_b.cell (top_b), l->second.second,
output.cell (top_id).shapes (layer_id), db::BooleanOp::Xor, true /*recursive*/);
sp.size (output, output.cell (top_id), layer_id, output.cell (top_id).shapes (layer_id), -us, (unsigned int) 2, true /*recursive*/);
} else if (l->second.first >= 0) {
sp.size (layout_a, layout_a.cell (top_a), l->second.first, output.cell (top_id).shapes (layer_id), -us, (unsigned int) 2, true /*recursive*/);
} else if (l->second.second >= 0) {
sp.size (layout_b, layout_b.cell (top_b), l->second.second, output.cell (top_id).shapes (layer_id), -us, (unsigned int) 2, true /*recursive*/);
}
size_t n = output.cell (top_id).shapes (layer_id).size ();
// if (n > 0) {
ndiff += n;
tl::info << " " << l->first.to_string () << ": " << n;
// }
}
if (ndiff > 0) {
tl::info << "----------------------------------------------------";
tl::info << " Total differences: " << ndiff;
ret = 1;
}
if (! outfile.empty ()) {
db::SaveLayoutOptions options;
options.set_format_from_filename (outfile);
if (format_set) {
options.set_format (format);
}
db::Writer writer (options);
tl::OutputStream file (outfile, tl::OutputStream::OM_Auto);
writer.write (output, file);
}
} 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 ret;
}

View File

@ -0,0 +1,13 @@
include($$PWD/../../klayout.pri)
TEMPLATE = app
TARGET = strmxor
DESTDIR = $$OUT_PWD/../..
SOURCES = strmxor.cc
INCLUDEPATH += ../../tl ../../db ../../gsi
DEPENDPATH += ../../tl ../../db ../../gsi
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi

View File

@ -34,7 +34,7 @@ namespace db
/**
* @brief Generic base class of GDS2 Text reader exceptions
*/
class GDS2ReaderTextException
class DB_PUBLIC GDS2ReaderTextException
: public ReaderException
{
public:
@ -46,7 +46,7 @@ public:
/**
* @brief The GDS2 text format stream reader
*/
class GDS2ReaderText
class DB_PUBLIC GDS2ReaderText
: public GDS2ReaderBase
{

View File

@ -49,10 +49,15 @@ GDS2WriterText::GDS2WriterText()
mProgress.set_unit (1024 * 1024);
}
GDS2WriterText::~GDS2WriterText()
{
// .. nothing yet ..
}
void
GDS2WriterText::write_byte (unsigned char b)
{
ssFormattingStream<<b<<" ";
ssFormattingStream<<b<<" ";
}
void

View File

@ -32,12 +32,13 @@ namespace db
{
class GDS2WriterText
class DB_PUBLIC GDS2WriterText
: public db::GDS2WriterBase
{
public:
GDS2WriterText();
~GDS2WriterText();
protected:
/**

View File

@ -19,6 +19,7 @@ SUBDIRS = \
lib \
ut \
plugins \
buddies \
equals(HAVE_RUBY, "1") {
SUBDIRS += rba
@ -44,6 +45,8 @@ ant.depends += laybasic
img.depends += laybasic
edt.depends += laybasic
buddies.depends += db tl gsi
lay.depends += laybasic ant img edt
equals(HAVE_RUBY, "1") {
lay.depends += rba