diff --git a/src/buddies/buddies.pro b/src/buddies/buddies.pro new file mode 100644 index 000000000..dffddf3ff --- /dev/null +++ b/src/buddies/buddies.pro @@ -0,0 +1,13 @@ + +TEMPLATE = subdirs + +SUBDIRS = \ + strm2cif \ + strm2dxf \ + strm2gds \ + strm2gdstxt \ + strm2oas \ + strm2txt \ + strmclip \ + strmcmp \ + strmxor \ diff --git a/src/buddies/mkbuddies.sh b/src/buddies/mkbuddies.sh new file mode 100644 index 000000000..86d4c265b --- /dev/null +++ b/src/buddies/mkbuddies.sh @@ -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 + diff --git a/src/buddies/strm2cif.cc b/src/buddies/strm2cif.cc new file mode 100644 index 000000000..251a86d2e --- /dev/null +++ b/src/buddies/strm2cif.cc @@ -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 \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; +} + + diff --git a/src/buddies/strm2cif/strm2cif.cc b/src/buddies/strm2cif/strm2cif.cc new file mode 100644 index 000000000..198f47d83 --- /dev/null +++ b/src/buddies/strm2cif/strm2cif.cc @@ -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 \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; +} + + diff --git a/src/buddies/strm2cif/strm2cif.pro b/src/buddies/strm2cif/strm2cif.pro new file mode 100644 index 000000000..5d04935da --- /dev/null +++ b/src/buddies/strm2cif/strm2cif.pro @@ -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 diff --git a/src/buddies/strm2dxf.cc b/src/buddies/strm2dxf.cc new file mode 100644 index 000000000..54fd99ed3 --- /dev/null +++ b/src/buddies/strm2dxf.cc @@ -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 \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; +} + + diff --git a/src/buddies/strm2dxf/strm2dxf.cc b/src/buddies/strm2dxf/strm2dxf.cc new file mode 100644 index 000000000..a2be3dc1a --- /dev/null +++ b/src/buddies/strm2dxf/strm2dxf.cc @@ -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 \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; +} + + diff --git a/src/buddies/strm2dxf/strm2dxf.pro b/src/buddies/strm2dxf/strm2dxf.pro new file mode 100644 index 000000000..e1fecb892 --- /dev/null +++ b/src/buddies/strm2dxf/strm2dxf.pro @@ -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 diff --git a/src/buddies/strm2gds.cc b/src/buddies/strm2gds.cc new file mode 100644 index 000000000..25b1a1981 --- /dev/null +++ b/src/buddies/strm2gds.cc @@ -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 \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; +} + + diff --git a/src/buddies/strm2gds/strm2gds.cc b/src/buddies/strm2gds/strm2gds.cc new file mode 100644 index 000000000..e0c75c226 --- /dev/null +++ b/src/buddies/strm2gds/strm2gds.cc @@ -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 \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; +} + + diff --git a/src/buddies/strm2gds/strm2gds.pro b/src/buddies/strm2gds/strm2gds.pro new file mode 100644 index 000000000..59a3d7c13 --- /dev/null +++ b/src/buddies/strm2gds/strm2gds.pro @@ -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 diff --git a/src/buddies/strm2gdstxt.cc b/src/buddies/strm2gdstxt.cc new file mode 100644 index 000000000..cc281f048 --- /dev/null +++ b/src/buddies/strm2gdstxt.cc @@ -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 \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; +} + + diff --git a/src/buddies/strm2gdstxt/strm2gdstxt.cc b/src/buddies/strm2gdstxt/strm2gdstxt.cc new file mode 100644 index 000000000..3756327e9 --- /dev/null +++ b/src/buddies/strm2gdstxt/strm2gdstxt.cc @@ -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 \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; +} + + diff --git a/src/buddies/strm2gdstxt/strm2gdstxt.pro b/src/buddies/strm2gdstxt/strm2gdstxt.pro new file mode 100644 index 000000000..d26a5619d --- /dev/null +++ b/src/buddies/strm2gdstxt/strm2gdstxt.pro @@ -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 diff --git a/src/buddies/strm2oas.cc b/src/buddies/strm2oas.cc new file mode 100644 index 000000000..8376b6bc3 --- /dev/null +++ b/src/buddies/strm2oas.cc @@ -0,0 +1,108 @@ + +#include "dbLayout.h" +#include "dbReader.h" +#include "dbOASISWriter.h" +#include "tlTimer.h" + +#include + +void +syntax () +{ + printf ("Syntax: strm2oas [-o ] [-c] \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 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 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; +} + + diff --git a/src/buddies/strm2oas/strm2oas.cc b/src/buddies/strm2oas/strm2oas.cc new file mode 100644 index 000000000..87bdbc136 --- /dev/null +++ b/src/buddies/strm2oas/strm2oas.cc @@ -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 + +void +syntax () +{ + printf ("Syntax: strm2oas [-o ] [-c] \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 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 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; +} + + diff --git a/src/buddies/strm2oas/strm2oas.pro b/src/buddies/strm2oas/strm2oas.pro new file mode 100644 index 000000000..b334cfe5b --- /dev/null +++ b/src/buddies/strm2oas/strm2oas.pro @@ -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 diff --git a/src/buddies/strm2txt.cc b/src/buddies/strm2txt.cc new file mode 100644 index 000000000..76205a542 --- /dev/null +++ b/src/buddies/strm2txt.cc @@ -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 \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; +} + + diff --git a/src/buddies/strm2txt/strm2txt.cc b/src/buddies/strm2txt/strm2txt.cc new file mode 100644 index 000000000..31fa1db19 --- /dev/null +++ b/src/buddies/strm2txt/strm2txt.cc @@ -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 \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; +} + + diff --git a/src/buddies/strm2txt/strm2txt.pro b/src/buddies/strm2txt/strm2txt.pro new file mode 100644 index 000000000..9a0cda006 --- /dev/null +++ b/src/buddies/strm2txt/strm2txt.pro @@ -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 diff --git a/src/buddies/strmclip.cc b/src/buddies/strmclip.cc new file mode 100644 index 000000000..e9fa18a51 --- /dev/null +++ b/src/buddies/strmclip.cc @@ -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 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 top_cells; + if (data.top.empty ()) { + top_cells.assign (layout.begin_top_down (), layout.end_top_cells ()); + } else { + std::pair 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 ::const_iterator tc = top_cells.begin (); tc != top_cells.end (); ++tc) { + + std::vector clip_boxes; + + // add the explicit boxes first + for (std::vector ::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 ::const_iterator cbx = clip_boxes.begin (); cbx != clip_boxes.end (); ++cbx) { + tl::log << " " << cbx->to_string (); + } + + std::vector 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 ::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 [] \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; +} + + diff --git a/src/buddies/strmclip/strmclip.cc b/src/buddies/strmclip/strmclip.cc new file mode 100644 index 000000000..7166c3106 --- /dev/null +++ b/src/buddies/strmclip/strmclip.cc @@ -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 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 top_cells; + if (data.top.empty ()) { + top_cells.assign (layout.begin_top_down (), layout.end_top_cells ()); + } else { + std::pair 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 ::const_iterator tc = top_cells.begin (); tc != top_cells.end (); ++tc) { + + std::vector clip_boxes; + + // add the explicit boxes first + for (std::vector ::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 ::const_iterator cbx = clip_boxes.begin (); cbx != clip_boxes.end (); ++cbx) { + tl::log << " " << cbx->to_string (); + } + + std::vector 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 ::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 [] \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; +} + + diff --git a/src/buddies/strmclip/strmclip.pro b/src/buddies/strmclip/strmclip.pro new file mode 100644 index 000000000..3f65c9dba --- /dev/null +++ b/src/buddies/strmclip/strmclip.pro @@ -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 diff --git a/src/buddies/strmcmp.cc b/src/buddies/strmcmp.cc new file mode 100644 index 000000000..bbfae5767 --- /dev/null +++ b/src/buddies/strmcmp.cc @@ -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 \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; +} + + diff --git a/src/buddies/strmcmp/strmcmp.cc b/src/buddies/strmcmp/strmcmp.cc new file mode 100644 index 000000000..d31a6e292 --- /dev/null +++ b/src/buddies/strmcmp/strmcmp.cc @@ -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 \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; +} + + diff --git a/src/buddies/strmcmp/strmcmp.pro b/src/buddies/strmcmp/strmcmp.pro new file mode 100644 index 000000000..de2f53e3f --- /dev/null +++ b/src/buddies/strmcmp/strmcmp.pro @@ -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 diff --git a/src/buddies/strmxor.cc b/src/buddies/strmxor.cc new file mode 100644 index 000000000..107d34a51 --- /dev/null +++ b/src/buddies/strmxor.cc @@ -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 ] [-topa ] [-topb ] [-oasis|-oas] [-gds2|-gds] []\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 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 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 > 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::rounded (undersize / layout_a.dbu ()); + + db::ShapeProcessor sp; + + size_t ndiff = 0; + + for (std::map >::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; +} + + diff --git a/src/buddies/strmxor/strmxor.cc b/src/buddies/strmxor/strmxor.cc new file mode 100644 index 000000000..4297bffa2 --- /dev/null +++ b/src/buddies/strmxor/strmxor.cc @@ -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 ] [-topa ] [-topb ] [-oasis|-oas] [-gds2|-gds] []\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 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 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 > 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::rounded (undersize / layout_a.dbu ()); + + db::ShapeProcessor sp; + + size_t ndiff = 0; + + for (std::map >::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; +} + + diff --git a/src/buddies/strmxor/strmxor.pro b/src/buddies/strmxor/strmxor.pro new file mode 100644 index 000000000..8bf542b4f --- /dev/null +++ b/src/buddies/strmxor/strmxor.pro @@ -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 diff --git a/src/db/contrib/dbGDS2TextReader.h b/src/db/contrib/dbGDS2TextReader.h index 84df056b5..e4b26f5ae 100644 --- a/src/db/contrib/dbGDS2TextReader.h +++ b/src/db/contrib/dbGDS2TextReader.h @@ -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 { diff --git a/src/db/contrib/dbGDS2TextWriter.cc b/src/db/contrib/dbGDS2TextWriter.cc index c85afcc38..d3a1fb4f7 100644 --- a/src/db/contrib/dbGDS2TextWriter.cc +++ b/src/db/contrib/dbGDS2TextWriter.cc @@ -49,10 +49,15 @@ GDS2WriterText::GDS2WriterText() mProgress.set_unit (1024 * 1024); } +GDS2WriterText::~GDS2WriterText() +{ + // .. nothing yet .. +} + void GDS2WriterText::write_byte (unsigned char b) { - ssFormattingStream<