diff --git a/scripts/deploy-win-mingw.sh b/scripts/deploy-win-mingw.sh index 6dff07d93..c4f654995 100644 --- a/scripts/deploy-win-mingw.sh +++ b/scripts/deploy-win-mingw.sh @@ -83,7 +83,7 @@ echo " rev = $KLAYOUT_VERSION_REV" echo "" # Force a minimum rebuild for the version update -touch src/klayout_main/version.h +touch src/version/version.h rm -rf $target ./build.sh -python $python -ruby $ruby -bin $target -build $build -j2 diff --git a/src/buddies/bd/bd.pro b/src/buddies/bd/bd.pro new file mode 100644 index 000000000..c4cafc503 --- /dev/null +++ b/src/buddies/bd/bd.pro @@ -0,0 +1,27 @@ + +DESTDIR = $$OUT_PWD/../.. +TARGET = klayout_bd + +include($$PWD/../../klayout.pri) + +DEFINES += MAKE_BD_LIBRARY + +TEMPLATE = lib + +SOURCES = \ + bdInit.cc \ + bdReaderOptions.cc \ + bdWriterOptions.cc \ + +HEADERS = \ + bdCommon.h \ + bdInit.h \ + bdReaderOptions.h \ + bdWriterOptions.h \ + +RESOURCES = \ + +INCLUDEPATH += ../../tl ../../db ../../gsi ../../version +DEPENDPATH += ../../tl ../../db ../../gsi ../../version +LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi + diff --git a/src/buddies/bd/bdCommon.h b/src/buddies/bd/bdCommon.h new file mode 100644 index 000000000..fc9120f92 --- /dev/null +++ b/src/buddies/bd/bdCommon.h @@ -0,0 +1,48 @@ + +/* + + 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 + +*/ + + +#if !defined(HDR_bdCommon_h) +# define HDR_bdCommon_h + +# if defined _WIN32 || defined __CYGWIN__ + +# ifdef MAKE_BD_LIBRARY +# define BD_PUBLIC __declspec(dllexport) +# else +# define BD_PUBLIC __declspec(dllimport) +# endif +# define BD_LOCAL + +# else + +# if __GNUC__ >= 4 +# define BD_PUBLIC __attribute__ ((visibility ("default"))) +# define BD_LOCAL __attribute__ ((visibility ("hidden"))) +# else +# define BD_PUBLIC +# define BD_LOCAL +# endif + +# endif + +#endif diff --git a/src/buddies/bd/bdInit.cc b/src/buddies/bd/bdInit.cc new file mode 100644 index 000000000..7021a79b7 --- /dev/null +++ b/src/buddies/bd/bdInit.cc @@ -0,0 +1,50 @@ + +/* + + 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 "bdInit.h" +#include "tlCommandLineParser.h" +#include "version.h" + +namespace bd +{ + +void init () +{ + std::string version = prg_version; + version += " r"; + version += prg_rev; + tl::CommandLineOptions::set_version (version); + + std::string license (prg_author); + license += "\n"; + license += prg_date; + license += ", Version "; + license += prg_version; + license += " r"; + license += prg_rev; + license += "\n"; + license += "\n"; + license += prg_about_text; + tl::CommandLineOptions::set_license (license); +} + +} diff --git a/src/buddies/bd/bdInit.h b/src/buddies/bd/bdInit.h new file mode 100644 index 000000000..10ce971ed --- /dev/null +++ b/src/buddies/bd/bdInit.h @@ -0,0 +1,39 @@ + +/* + + 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 + +*/ + +#ifndef HDR_bdInit +#define HDR_bdInit + +#include "bdCommon.h" + +namespace bd +{ + +/** + * @brief Provides basic initialization + * This function must be called at the very beginning of the main program. + */ +void BD_PUBLIC init (); + +} + +#endif diff --git a/src/buddies/bd/bdReaderOptions.cc b/src/buddies/bd/bdReaderOptions.cc new file mode 100644 index 000000000..e69de29bb diff --git a/src/buddies/bd/bdReaderOptions.h b/src/buddies/bd/bdReaderOptions.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/buddies/bd/bdWriterOptions.cc b/src/buddies/bd/bdWriterOptions.cc new file mode 100644 index 000000000..c74448d36 --- /dev/null +++ b/src/buddies/bd/bdWriterOptions.cc @@ -0,0 +1,160 @@ + +/* + + 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 "bdWriterOptions.h" +#include "dbLayout.h" +#include "dbSaveLayoutOptions.h" +#include "tlCommandLineParser.h" +#include "tlGlobPattern.h" + +namespace bd +{ + +GenericWriterOptions::GenericWriterOptions () + : scale_factor (1.0), dbu (0.0), + dont_write_empty_cells (false), keep_instances (false), write_context_info (false) +{ + // .. nothing yet .. +} + +void +GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::string &format) +{ + cmd << tl::arg ("-os|--scale-factor=factor", &scale_factor, "Scales the layout upon writing", + "Specifies layout scaling. If given, the saved layout will be scaled by the " + "given factor." + ); + + if (format == "GDS2" || format == "GDS2Text" || format == "OASIS") { + cmd << tl::arg ("-ou|--dbu=dbu", &dbu, "Uses the specified database unit", + "Specifies the database unit to save the layout in. The database unit is given " + "in micron units. By default, the original unit is used. The layout will not " + "change physically because internally, the coordinates are scaled to match the " + "new database unit." + ); + } + + cmd << tl::arg ("-ox|--drop-empty-cells", &dont_write_empty_cells, "Drops empty cells", + "If given, empty cells won't be written. See --keep-instances for more options." + ); + + if (format == "GDS2" || format == "GDS2Text") { + cmd << tl::arg ("-ok|--keep-instances", &keep_instances, "Keeps instances of dropped cells", + "If given, instances of dropped cell's won't be removed. Hence, ghost cells are " + "produced. The resulting layout may not be readable by consumers that require " + "all instantiated cells to be present as actual cells." + ); + } + + if (format == "GDS2" || format == "GDS2Text" || format == "OASIS") { + cmd << tl::arg ("-oc|--write-context-info", &write_context_info, "Writes context information", + "Include context information for PCell instances and other information in a format-specific " + "way. The resulting layout may show unexpected features for other consumers." + ); + } + + cmd << tl::arg ("-ow|--write-cells=sel", &cell_selection, "Specifies cells to write", + "This option specifies the cells to write. The value of this option is a sequence of " + "select/unselect operations. A select operation is an optional plus sign (+), followed by " + "a cell filter. An unselect operation is a minus sign (-) followed by a cell filter. " + "A cell filter is a plain cell name, a glob pattern (using '*' and '?' for placeholders). " + "If a cell filter is enclosed in round brackets, only this cell is specified. Otherwise " + "the cell and it's children are specified.\n" + "\n" + "Multiple operations can be specified by adding them with a comma separator. " + "Cell selection and unselection happens in the order given. Hence it's possible " + "to select a cell with it's children and then unselect some children of this cell.\n" + "\n" + "Examples:\n\n" + "* \"TOP1,TOP2\" - Select cells TOP1 and TOP2 with all of their children\n" + "* \"(TOP)\" - Select only cell TOP, but none of it's child cells\n" + "* \"TOP,-A\" - Select cell TOP (plus children), then remove A (with children)" + ); +} + +static void get_selected_cells (tl::Extractor &ex, const db::Layout &layout, std::set &selected) +{ + while (! ex.at_end ()) { + + bool remove = ex.test ("-"); + ex.test ("+"); + + bool without_children = ex.test ("("); + std::string filter; + ex.read_word_or_quoted (filter, "_-.*?{}$[]"); + + if (without_children) { + ex.expect (")"); + } + + if (! ex.at_end ()) { + ex.expect (","); + } + + tl::GlobPattern pat (filter); + for (db::Layout::const_iterator c = layout.begin (); c != layout.end (); ++c) { + + if (pat.match (layout.cell_name (c->cell_index ()))) { + + std::set cells; + cells.insert (c->cell_index ()); + if (! without_children) { + c->collect_called_cells (cells); + } + + if (! remove) { + selected.insert (cells.begin (), cells.end ()); + } else { + selected.erase (cells.begin (), cells.end ()); + } + + } + + } + + } +} + +void +GenericWriterOptions::configure (db::SaveLayoutOptions &save_options, const db::Layout &layout) +{ + save_options.set_scale_factor (scale_factor); + save_options.set_dbu (dbu); + save_options.set_dont_write_empty_cells (dont_write_empty_cells); + save_options.set_keep_instances (keep_instances); + save_options.set_write_context_info (write_context_info); + + if (!cell_selection.empty ()) { + + std::set selected; + tl::Extractor ex (cell_selection.c_str ()); + get_selected_cells (ex, layout, selected); + + save_options.clear_cells (); + for (std::set::const_iterator s = selected.begin (); s != selected.end (); ++s) { + save_options.add_this_cell (*s); + } + + } +} + +} diff --git a/src/buddies/bd/bdWriterOptions.h b/src/buddies/bd/bdWriterOptions.h new file mode 100644 index 000000000..78a000f55 --- /dev/null +++ b/src/buddies/bd/bdWriterOptions.h @@ -0,0 +1,78 @@ + +/* + + 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 + +*/ + +#ifndef HDR_bdWriterOptions +#define HDR_bdWriterOptions + +#include "bdCommon.h" + +#include + +namespace tl +{ + class CommandLineOptions; +} + +namespace db +{ + class Layout; + class SaveLayoutOptions; +} + +namespace bd +{ + +/** + * @brief Generic writer options + * This class collects generic writer options and provides command line options for this + */ +struct BD_PUBLIC GenericWriterOptions +{ + /** + * @brief Constructor + */ + GenericWriterOptions (); + + /** + * @brief Adds the generic options to the command line parser object + * The format string gives a hint about the target format. Certain options will be + * suppressed if they are known to be unavailable for the given format. + */ + void add_options (tl::CommandLineOptions &cmd, const std::string &format); + + /** + * @brief Configures the writer options object with the options stored in this object + * The layout is required in order to derive the cell and layer ID's. + */ + void configure (db::SaveLayoutOptions &save_options, const db::Layout &layout); + + double scale_factor; + double dbu; + bool dont_write_empty_cells; + bool keep_instances; + bool write_context_info; + std::string cell_selection; +}; + +} + +#endif diff --git a/src/buddies/buddies.pro b/src/buddies/buddies.pro index dffddf3ff..2dcaa2e9a 100644 --- a/src/buddies/buddies.pro +++ b/src/buddies/buddies.pro @@ -2,6 +2,7 @@ TEMPLATE = subdirs SUBDIRS = \ + bd \ strm2cif \ strm2dxf \ strm2gds \ @@ -11,3 +12,13 @@ SUBDIRS = \ strmclip \ strmcmp \ strmxor \ + +strm2cif.depends += bd +strm2dxf.depends += bd +strm2gds.depends += bd +strm2gdstxt.depends += bd +strm2oas.depends += bd +strm2txt.depends += bd +strmclip.depends += bd +strmcmp.depends += bd +strmxor.depends += bd diff --git a/src/buddies/strm2cif/strm2cif.cc b/src/buddies/strm2cif/strm2cif.cc index 32c9f1c77..b5e492889 100644 --- a/src/buddies/strm2cif/strm2cif.cc +++ b/src/buddies/strm2cif/strm2cif.cc @@ -20,6 +20,7 @@ */ +#include "bdInit.h" #include "dbLayout.h" #include "dbReader.h" #include "dbCIFWriter.h" @@ -31,6 +32,8 @@ int main (int argc, char *argv []) { + bd::init (); + db::SaveLayoutOptions save_options; db::CIFWriterOptions cif_options; std::string infile, outfile; diff --git a/src/buddies/strm2cif/strm2cif.pro b/src/buddies/strm2cif/strm2cif.pro index 5d04935da..b90ecaa01 100644 --- a/src/buddies/strm2cif/strm2cif.pro +++ b/src/buddies/strm2cif/strm2cif.pro @@ -8,6 +8,6 @@ DESTDIR = $$OUT_PWD/../.. SOURCES = strm2cif.cc -INCLUDEPATH += ../../tl ../../db ../../gsi -DEPENDPATH += ../../tl ../../db ../../gsi -LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi +INCLUDEPATH += ../bd ../../tl ../../db ../../gsi +DEPENDPATH += ../bd ../../tl ../../db ../../gsi +LIBS += -L$$DESTDIR -lklayout_bd -lklayout_tl -lklayout_db -lklayout_gsi diff --git a/src/buddies/strm2dxf/strm2dxf.cc b/src/buddies/strm2dxf/strm2dxf.cc index a2be3dc1a..10d9f5086 100644 --- a/src/buddies/strm2dxf/strm2dxf.cc +++ b/src/buddies/strm2dxf/strm2dxf.cc @@ -20,6 +20,7 @@ */ +#include "bdInit.h" #include "dbLayout.h" #include "dbReader.h" #include "dbDXFWriter.h" diff --git a/src/buddies/strm2dxf/strm2dxf.pro b/src/buddies/strm2dxf/strm2dxf.pro index e1fecb892..d6bbd7980 100644 --- a/src/buddies/strm2dxf/strm2dxf.pro +++ b/src/buddies/strm2dxf/strm2dxf.pro @@ -8,6 +8,6 @@ DESTDIR = $$OUT_PWD/../.. SOURCES = strm2dxf.cc -INCLUDEPATH += ../../tl ../../db ../../gsi -DEPENDPATH += ../../tl ../../db ../../gsi -LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi +INCLUDEPATH += ../bd ../../tl ../../db ../../gsi +DEPENDPATH += ../bd ../../tl ../../db ../../gsi +LIBS += -L$$DESTDIR -lklayout_bd -lklayout_tl -lklayout_db -lklayout_gsi diff --git a/src/buddies/strm2gds/strm2gds.cc b/src/buddies/strm2gds/strm2gds.cc index 7ade4fe20..620512231 100644 --- a/src/buddies/strm2gds/strm2gds.cc +++ b/src/buddies/strm2gds/strm2gds.cc @@ -20,6 +20,8 @@ */ +#include "bdInit.h" +#include "bdWriterOptions.h" #include "dbLayout.h" #include "dbReader.h" #include "dbGDS2Writer.h" @@ -28,8 +30,10 @@ int main (int argc, char *argv []) { - db::SaveLayoutOptions save_options; + bd::init (); + db::GDS2WriterOptions gds2_options; + bd::GenericWriterOptions generic_writer_options; std::string infile, outfile; tl::CommandLineOptions cmd; @@ -54,10 +58,10 @@ main (int argc, char *argv []) "This option can specify the GDS2 LIBNAME for the output file. By default, the original LIBNAME is " "written." ) - << tl::arg ("-om|--user-units=unit", &gds2_options.user_units, "Specifies the user unit to use", + << tl::arg ("-or|--user-units=unit", &gds2_options.user_units, "Specifies the user unit to use", "Specifies the GDS2 user unit. By default micrometers are used for the user unit." ) - << tl::arg ("!-ot|--no-timestamps", &gds2_options.write_timestamps, "Don't write timestamps", + << tl::arg ("!-ot|--no-timestamps", &gds2_options.write_timestamps, "Don't write timestamps", "Writes a dummy time stamp instead of the actual time. With this option, GDS2 files become " "bytewise indentical even if written at different times. This option is useful if binary " "identity is important (i.e. in regression scenarios)." @@ -70,33 +74,11 @@ main (int argc, char *argv []) "This option enables a GDS2 extension that allows writing of file properties to GDS2 files. " "Consumers that don't support this feature, may not be able to read such a GDS2 files." ) - << tl::arg ("-os|--scale-factor=factor", &save_options, &db::SaveLayoutOptions::set_scale_factor, "Scales the layout upon writing", - "Specifies layout scaling. If given, the saved layout will be scaled by the " - "given factor." - ) - << tl::arg ("-ou|--dbu=dbu", &save_options, &db::SaveLayoutOptions::set_dbu, "Uses the specified database unit", - "Specifies the database unit to save the layout in. The database unit is given " - "in micron units. By default, the original unit is used. The layout will not " - "change physically because internally, the coordinates are scaled to match the " - "new database unit." - ) - << tl::arg ("-ox|--drop-empty-cells", &save_options, &db::SaveLayoutOptions::set_dont_write_empty_cells, "Drops empty cells", - "If given, empty cells won't be written. See --keep-instances for more options." - ) - << tl::arg ("-ok|--keep-instances", &save_options, &db::SaveLayoutOptions::set_keep_instances, "Keeps instances of dropped cells", - "If given, instances of dropped cell's won't be removed. Hence, ghost cells are " - "produced. The resulting layout may not be readable by consumers that require " - "all instantiated cells to be present as actual cells." - ) - << tl::arg ("-oc|--write-context-info", &save_options, &db::SaveLayoutOptions::set_write_context_info, "Writes context information", - "Include context information for PCell instances and other information in a format-specific " - "way. The resulting layout may show unexpected features for other consumers." - ) << tl::arg ("input", &infile, "The input file (any format, may be gzip compressed)") << tl::arg ("output", &outfile, "The output file") ; - save_options.set_options (gds2_options); + generic_writer_options.add_options (cmd, gds2_options.format_name ()); cmd.brief ("This program will convert the given file to a GDS2 file"); @@ -115,6 +97,10 @@ main (int argc, char *argv []) } { + db::SaveLayoutOptions save_options; + save_options.set_options (gds2_options); + generic_writer_options.configure (save_options, layout); + tl::OutputStream stream (outfile); db::GDS2Writer writer; writer.write (layout, stream, save_options); @@ -134,5 +120,3 @@ main (int argc, char *argv []) return 0; } - - diff --git a/src/buddies/strm2gds/strm2gds.pro b/src/buddies/strm2gds/strm2gds.pro index 59a3d7c13..9f6fb2acf 100644 --- a/src/buddies/strm2gds/strm2gds.pro +++ b/src/buddies/strm2gds/strm2gds.pro @@ -8,6 +8,6 @@ DESTDIR = $$OUT_PWD/../.. SOURCES = strm2gds.cc -INCLUDEPATH += ../../tl ../../db ../../gsi -DEPENDPATH += ../../tl ../../db ../../gsi -LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi +INCLUDEPATH += ../bd ../../tl ../../db ../../gsi +DEPENDPATH += ../bd ../../tl ../../db ../../gsi +LIBS += -L$$DESTDIR -lklayout_bd -lklayout_tl -lklayout_db -lklayout_gsi diff --git a/src/buddies/strm2gdstxt/strm2gdstxt.pro b/src/buddies/strm2gdstxt/strm2gdstxt.pro index d26a5619d..3bd8de7cf 100644 --- a/src/buddies/strm2gdstxt/strm2gdstxt.pro +++ b/src/buddies/strm2gdstxt/strm2gdstxt.pro @@ -8,6 +8,6 @@ DESTDIR = $$OUT_PWD/../.. SOURCES = strm2gdstxt.cc -INCLUDEPATH += ../../tl ../../db ../../gsi -DEPENDPATH += ../../tl ../../db ../../gsi -LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi +INCLUDEPATH += ../bd ../../tl ../../db ../../gsi +DEPENDPATH += ../bd ../../tl ../../db ../../gsi +LIBS += -L$$DESTDIR -lklayout_bd -lklayout_tl -lklayout_db -lklayout_gsi diff --git a/src/buddies/strm2oas/strm2oas.cc b/src/buddies/strm2oas/strm2oas.cc index 87bdbc136..16ea7cdc8 100644 --- a/src/buddies/strm2oas/strm2oas.cc +++ b/src/buddies/strm2oas/strm2oas.cc @@ -20,6 +20,7 @@ */ +#include "bdInit.h" #include "dbLayout.h" #include "dbReader.h" #include "dbOASISWriter.h" diff --git a/src/buddies/strm2oas/strm2oas.pro b/src/buddies/strm2oas/strm2oas.pro index b334cfe5b..0f72fe651 100644 --- a/src/buddies/strm2oas/strm2oas.pro +++ b/src/buddies/strm2oas/strm2oas.pro @@ -8,6 +8,6 @@ DESTDIR = $$OUT_PWD/../.. SOURCES = strm2oas.cc -INCLUDEPATH += ../../tl ../../db ../../gsi -DEPENDPATH += ../../tl ../../db ../../gsi -LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi +INCLUDEPATH += ../bd ../../tl ../../db ../../gsi +DEPENDPATH += ../bd ../../tl ../../db ../../gsi +LIBS += -L$$DESTDIR -lklayout_bd -lklayout_tl -lklayout_db -lklayout_gsi diff --git a/src/buddies/strm2txt/strm2txt.cc b/src/buddies/strm2txt/strm2txt.cc index 31fa1db19..3381e3155 100644 --- a/src/buddies/strm2txt/strm2txt.cc +++ b/src/buddies/strm2txt/strm2txt.cc @@ -20,6 +20,7 @@ */ +#include "bdInit.h" #include "dbLayout.h" #include "dbReader.h" #include "dbTextWriter.h" diff --git a/src/buddies/strm2txt/strm2txt.pro b/src/buddies/strm2txt/strm2txt.pro index 9a0cda006..5f0a41326 100644 --- a/src/buddies/strm2txt/strm2txt.pro +++ b/src/buddies/strm2txt/strm2txt.pro @@ -8,6 +8,6 @@ DESTDIR = $$OUT_PWD/../.. SOURCES = strm2txt.cc -INCLUDEPATH += ../../tl ../../db ../../gsi -DEPENDPATH += ../../tl ../../db ../../gsi -LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi +INCLUDEPATH += ../bd ../../tl ../../db ../../gsi +DEPENDPATH += ../bd ../../tl ../../db ../../gsi +LIBS += -L$$DESTDIR -lklayout_bd -lklayout_tl -lklayout_db -lklayout_gsi diff --git a/src/buddies/strmclip/strmclip.pro b/src/buddies/strmclip/strmclip.pro index 3f65c9dba..1b589be8b 100644 --- a/src/buddies/strmclip/strmclip.pro +++ b/src/buddies/strmclip/strmclip.pro @@ -8,6 +8,6 @@ DESTDIR = $$OUT_PWD/../.. SOURCES = strmclip.cc -INCLUDEPATH += ../../tl ../../db ../../gsi -DEPENDPATH += ../../tl ../../db ../../gsi -LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi +INCLUDEPATH += ../bd ../../tl ../../db ../../gsi +DEPENDPATH += ../bd ../../tl ../../db ../../gsi +LIBS += -L$$DESTDIR -lklayout_bd -lklayout_tl -lklayout_db -lklayout_gsi diff --git a/src/buddies/strmcmp/strmcmp.cc b/src/buddies/strmcmp/strmcmp.cc index d31a6e292..44219e048 100644 --- a/src/buddies/strmcmp/strmcmp.cc +++ b/src/buddies/strmcmp/strmcmp.cc @@ -20,6 +20,7 @@ */ +#include "bdInit.h" #include "dbLayout.h" #include "dbLayoutDiff.h" #include "dbReader.h" diff --git a/src/buddies/strmcmp/strmcmp.pro b/src/buddies/strmcmp/strmcmp.pro index de2f53e3f..94633f5af 100644 --- a/src/buddies/strmcmp/strmcmp.pro +++ b/src/buddies/strmcmp/strmcmp.pro @@ -8,6 +8,6 @@ DESTDIR = $$OUT_PWD/../.. SOURCES = strmcmp.cc -INCLUDEPATH += ../../tl ../../db ../../gsi -DEPENDPATH += ../../tl ../../db ../../gsi -LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi +INCLUDEPATH += ../bd ../../tl ../../db ../../gsi +DEPENDPATH += ../bd ../../tl ../../db ../../gsi +LIBS += -L$$DESTDIR -lklayout_bd -lklayout_tl -lklayout_db -lklayout_gsi diff --git a/src/buddies/strmxor/strmxor.cc b/src/buddies/strmxor/strmxor.cc index 4297bffa2..622e46fc6 100644 --- a/src/buddies/strmxor/strmxor.cc +++ b/src/buddies/strmxor/strmxor.cc @@ -20,6 +20,7 @@ */ +#include "bdInit.h" #include "dbLayout.h" #include "dbReader.h" #include "dbWriter.h" diff --git a/src/buddies/strmxor/strmxor.pro b/src/buddies/strmxor/strmxor.pro index 8bf542b4f..78b09623d 100644 --- a/src/buddies/strmxor/strmxor.pro +++ b/src/buddies/strmxor/strmxor.pro @@ -8,6 +8,6 @@ DESTDIR = $$OUT_PWD/../.. SOURCES = strmxor.cc -INCLUDEPATH += ../../tl ../../db ../../gsi -DEPENDPATH += ../../tl ../../db ../../gsi -LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi +INCLUDEPATH += ../bd ../../tl ../../db ../../gsi +DEPENDPATH += ../bd ../../tl ../../db ../../gsi +LIBS += -L$$DESTDIR -lklayout_bd -lklayout_tl -lklayout_db -lklayout_gsi diff --git a/src/klayout_main/klayout_main.pro b/src/klayout_main/klayout_main.pro index 77e9c646f..d85f09aae 100644 --- a/src/klayout_main/klayout_main.pro +++ b/src/klayout_main/klayout_main.pro @@ -16,8 +16,8 @@ SOURCES = \ RESOURCES = \ -INCLUDEPATH += ../tl ../gsi ../db ../rdb ../laybasic ../lay ../ext ../img ../ant ../lib -DEPENDPATH += ../tl ../gsi ../db ../rdb ../laybasic ../lay ../ext ../img ../ant ../lib +INCLUDEPATH += ../tl ../gsi ../db ../rdb ../laybasic ../lay ../ext ../img ../ant ../lib ../version +DEPENDPATH += ../tl ../gsi ../db ../rdb ../laybasic ../lay ../ext ../img ../ant ../lib ../version LIBS += $$PYTHONLIBFILE $$RUBYLIBFILE -L$$DESTDIR -lklayout_tl -lklayout_gsi -lklayout_db -lklayout_rdb -lklayout_laybasic -lklayout_lay -lklayout_ant -lklayout_img -lklayout_edt -lklayout_ext -lklayout_lib win32 { diff --git a/src/tl/tlCommandLineParser.cc b/src/tl/tlCommandLineParser.cc index aff604149..33ff81e3d 100644 --- a/src/tl/tlCommandLineParser.cc +++ b/src/tl/tlCommandLineParser.cc @@ -78,13 +78,85 @@ ArgBase::is_option () const return !m_option.short_option.empty () || !m_option.long_option.empty (); } +// ------------------------------------------------------------------------ +// Internal argument classes to implement info arguments + +class HelpArg + : public ArgBase +{ +public: + HelpArg () + : ArgBase ("-h|--help", "Shows the usage and exits", "") + { + // .. nothing yet .. + } + + ArgBase *clone () const + { + return new HelpArg (); + } + + void action (CommandLineOptions *options) const + { + options->produce_help (options->program_name ()); + throw tl::CancelException (); + } +}; + +class LicenseArg + : public ArgBase +{ +public: + LicenseArg () + : ArgBase ("--license", "Shows the license and exits", "") + { + // .. nothing yet .. + } + + ArgBase *clone () const + { + return new LicenseArg (); + } + + void action (CommandLineOptions *options) const + { + options->produce_license (); + throw tl::CancelException (); + } +}; + +class VersionArg + : public ArgBase +{ +public: + VersionArg () + : ArgBase ("--version", "Produces the version and exits", "") + { + // .. nothing yet .. + } + + ArgBase *clone () const + { + return new VersionArg (); + } + + void action (CommandLineOptions *options) const + { + options->produce_version (); + throw tl::CancelException (); + } +}; + // ------------------------------------------------------------------------ // CommandLineOptions implementation +std::string CommandLineOptions::m_version; +std::string CommandLineOptions::m_license; + CommandLineOptions::CommandLineOptions () { // Populate with the built-in options - *this << ArgBase ("-h|--help", "Shows the usage", ""); + *this << HelpArg () << VersionArg () << LicenseArg (); } CommandLineOptions::~CommandLineOptions () @@ -119,11 +191,12 @@ print_string_formatted (const std::string &indent, unsigned int columns, const s if (c == columns && !at_beginning) { tl::info << ""; tl::info << indent << tl::noendl; - c = 0; + c = (unsigned int) (t - tt); } } tl::info << std::string (tt, 0, t - tt) << tl::noendl; + while (*t == ' ') { ++t; } @@ -159,15 +232,38 @@ pad_string (unsigned int columns, const std::string &text) return s; } +struct NameCompare +{ + bool operator() (ArgBase *a, ArgBase *b) + { + if (a->is_option () != b->is_option ()) { + return a->is_option () < b->is_option (); + } + if (! a->is_option ()) { + return false; + } + if (a->option ().short_option.empty () != b->option ().short_option.empty ()) { + return a->option ().short_option.empty () < b->option ().short_option.empty (); + } + if (a->option ().short_option != b->option ().short_option) { + return a->option ().short_option < b->option ().short_option; + } + return a->option ().long_option < b->option ().long_option; + } +}; + void CommandLineOptions::produce_help (const std::string &program_name) { - int columns = 60; + int columns = 80; tl::info << "Usage:" << tl::endl; tl::info << " " << program_name << " [options]" << tl::noendl; - for (std::vector::const_iterator a = m_args.begin (); a != m_args.end (); ++a) { + std::vector sorted_args = m_args; + std::stable_sort (sorted_args.begin (), sorted_args.end (), NameCompare ()); + + for (std::vector::const_iterator a = sorted_args.begin (); a != sorted_args.end (); ++a) { if (! (*a)->is_option ()) { if ((*a)->option ().optional) { tl::info << " [<" << (*a)->option ().name << ">]" << tl::noendl; @@ -185,7 +281,7 @@ CommandLineOptions::produce_help (const std::string &program_name) unsigned int long_option_width = 0; unsigned int name_width = 0; - for (std::vector::const_iterator a = m_args.begin (); a != m_args.end (); ++a) { + for (std::vector::const_iterator a = sorted_args.begin (); a != sorted_args.end (); ++a) { name_width = std::max (name_width, (unsigned int) (*a)->option ().name.size ()); short_option_width = std::max (short_option_width, (unsigned int) (*a)->option ().short_option.size ()); long_option_width = std::max (long_option_width, (unsigned int) (*a)->option ().long_option.size ()); @@ -193,7 +289,7 @@ CommandLineOptions::produce_help (const std::string &program_name) tl::info << "Arguments:" << tl::endl; - for (std::vector::const_iterator a = m_args.begin (); a != m_args.end (); ++a) { + for (std::vector::const_iterator a = sorted_args.begin (); a != sorted_args.end (); ++a) { if ((*a)->is_option ()) { continue; } @@ -218,12 +314,6 @@ CommandLineOptions::produce_help (const std::string &program_name) "(with two dashes). If a value is required, it can be specified either " "as the following argument or added to the option with an equal sign (=)."); - tl::info << tl::endl << " Examples:" << tl::endl << tl::endl - << " -a 1" << tl::endl - << " -a=1" << tl::endl - << " --long 1" << tl::endl - << " --long=1" << tl::endl; - tl::info << " List of options:" << tl::endl; tl::info << " " @@ -231,7 +321,7 @@ CommandLineOptions::produce_help (const std::string &program_name) << pad_string (long_option_width + 5, "Long") << " " << pad_string (name_width + 3, "Value") << " " << "Description" << tl::endl; - for (std::vector::const_iterator a = m_args.begin (); a != m_args.end (); ++a) { + for (std::vector::const_iterator a = sorted_args.begin (); a != sorted_args.end (); ++a) { if (! (*a)->is_option ()) { continue; } @@ -256,16 +346,22 @@ CommandLineOptions::produce_help (const std::string &program_name) } } +void +CommandLineOptions::produce_license () +{ + tl::info << m_license; +} + +void +CommandLineOptions::produce_version () +{ + tl::info << m_version; +} + void CommandLineOptions::parse (int argc, char *argv[]) { - for (int i = 0; i < argc; ++i) { - std::string arg_as_utf8 = tl::to_string (QString::fromLocal8Bit (argv [i])); - if (arg_as_utf8 == "-h" || arg_as_utf8 == "--help") { - produce_help (tl::to_string (QFileInfo (QString::fromLocal8Bit (argv [0])).fileName ())); - throw tl::CancelException (); - } - } + m_program_name = tl::to_string (QFileInfo (QString::fromLocal8Bit (argv [0])).fileName ()); std::vector::const_iterator next_plain_arg = m_args.begin (); while (next_plain_arg != m_args.end () && (*next_plain_arg)->is_option ()) { @@ -349,6 +445,9 @@ CommandLineOptions::parse (int argc, char *argv[]) } } + // Exection the action if there is one + arg->action (this); + } if (next_plain_arg != m_args.end () && !(*next_plain_arg)->option ().optional) { diff --git a/src/tl/tlCommandLineParser.h b/src/tl/tlCommandLineParser.h index 64cef66b3..99ee13718 100644 --- a/src/tl/tlCommandLineParser.h +++ b/src/tl/tlCommandLineParser.h @@ -31,6 +31,8 @@ namespace tl { +class CommandLineOptions; + /** * @brief A base class for argument getters * @@ -146,6 +148,15 @@ public: return false; } + /** + * @brief Performs the action this argument is associated with + * This method is used to implement "active" arguments such as "-h" or "--version". + */ + virtual void action (CommandLineOptions *) const + { + // The default implementation does nothing + } + private: ParsedOption m_option; std::string m_brief_doc; @@ -156,7 +167,7 @@ private: * @brief A helper for extracting values by type */ template -void extract (tl::Extractor &ex, T &t, bool /*for_list*/ = false) +inline void extract (tl::Extractor &ex, T &t, bool /*for_list*/ = false) { ex.read (t); } @@ -164,7 +175,7 @@ void extract (tl::Extractor &ex, T &t, bool /*for_list*/ = false) /** * @brief A specialization for the string type */ -void extract (tl::Extractor &ex, std::string &t, bool for_list = false) +inline void extract (tl::Extractor &ex, std::string &t, bool for_list = false) { if (*ex == '"' || *ex == '\'') { ex.read_quoted (t); @@ -179,7 +190,7 @@ void extract (tl::Extractor &ex, std::string &t, bool for_list = false) * @brief A specialization for a list of any type (vector) */ template -void extract (tl::Extractor &ex, std::vector &t, bool /*for_list*/ = false) +inline void extract (tl::Extractor &ex, std::vector &t, bool /*for_list*/ = false) { while (! ex.at_end ()) { t.push_back (T ()); @@ -192,24 +203,24 @@ void extract (tl::Extractor &ex, std::vector &t, bool /*for_list*/ = false) * @brief A helper to mark "presence" */ template -void mark_presence (T &, bool) +inline void mark_presence (T &, bool) { // .. the default implementation does nothing .. } -void mark_presence (bool &t, bool invert) +inline void mark_presence (bool &t, bool invert) { t = !invert; } template -void mark_presence_setter (C *, void (C::*) (T), bool) +inline void mark_presence_setter (C *, void (C::*) (T), bool) { // .. the default implementation does nothing .. } template -void mark_presence_setter (C *c, void (C::*ptr) (bool), bool invert) +inline void mark_presence_setter (C *c, void (C::*ptr) (bool), bool invert) { (c->*ptr) (!invert); } @@ -409,11 +420,56 @@ public: */ void parse (int argc, char *argv[]); + /** + * @brief Produces the help text + */ + void produce_help (const std::string &program_name); + + /** + * @brief Produces the version text + */ + void produce_version (); + + /** + * @brief Produces the license text + */ + void produce_license (); + + /** + * @brief Gets the program name + * This name is set by the "parse" method. + */ + const std::string &program_name () const + { + return m_program_name; + } + + /** + * @brief Sets the version text + * + * This text is printed with the --version option. + */ + static void set_version (const std::string &text) + { + m_version = text; + } + + /** + * @brief Sets the license text + * + * This text is printed with the --license option. + */ + static void set_license (const std::string &text) + { + m_license = text; + } + private: std::string m_brief; std::vector m_args; - - void produce_help (const std::string &program_name); + std::string m_program_name; + static std::string m_version; + static std::string m_license; }; } diff --git a/src/klayout_main/version.h b/src/version/version.h similarity index 100% rename from src/klayout_main/version.h rename to src/version/version.h