More options for buddies

* Generic writer options
* Generic reader options
* All converter tools are equipped with writer options
* strm2gds is equipped with reader options already
This commit is contained in:
Matthias Koefferlein 2017-08-17 23:31:05 +02:00
parent dede3afe1b
commit aa3caeca07
13 changed files with 803 additions and 335 deletions

View File

@ -0,0 +1,248 @@
/*
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 "bdReaderOptions.h"
#include "dbLoadLayoutOptions.h"
#include "tlCommandLineParser.h"
namespace bd
{
GenericReaderOptions::GenericReaderOptions ()
: m_create_other_layers (true)
{
// .. nothing yet ..
}
void
GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
{
{
std::string group ("[Input options - General]");
cmd << tl::arg (group +
"!-is|--skip-unknown-layers", &m_create_other_layers, "Skips unknown layers",
"This option is effective with the the --layer-map option. If combined with "
"--skip-unknown-layers, layers not listed in the layer map will not be read. "
"By default, corresponding entries are created also for unknown layers."
)
<< tl::arg (group +
"-im|--layer-map=map", this, &GenericReaderOptions::set_layer_map, "Specifies the layer mapping for the input",
"This option specifies a layer selection or mapping. The selection or mapping is a sequence of source and optional "
"target specifications. The specifications are separated by blanks or double-slash sequences (//).\n"
"\n"
"A source specification can apply to a single or many source layers. If many source layers are "
"selected, they are combined into a single target layer. A source specification is:\n"
"\n"
"* A list of source specs, separated by semicolon characters (;)\n"
"* A layer name (in double or single quotes if necessary)\n"
"* A layer/datatype pair or range separated with a slash\n"
"* Layer and datatype can be simple positive integer numbers\n"
"* Layer and datatype numbers can be enumerated (numbers separated with a comma)\n"
"* Layer and datatype numbers can be ranges formed with a dash separator\n"
"\n"
"Target specifications are added to source specifications with a colon (:). If a target "
"layer is specified, all source layers addressed with the source specification are "
"combined into this target layer.\n"
"\n"
"Examples:\n"
"\n"
"* 1/0 2/0 3/0-255:17/0\n"
" Selects 1/0, 2/0 and maps layer 3, datatype 0 to 255 to layer 17, datatype 0\n"
"\n"
"* A:1/0 B:2/0\n"
" Maps named layer A to 1/0 and named layer B to 2/0"
)
;
}
{
std::string group ("[Input options - GDS2 and OASIS]");
cmd << tl::arg (group +
"#!--disable-texts", &m_common_reader_options.enable_text_objects, "Skips text objects",
"With this option set, text objects won't be read."
)
<< tl::arg (group +
"#!--disable-properties", &m_common_reader_options.enable_properties, "Skips properties",
"With this option set, properties won't be read."
)
;
}
{
std::string group ("[Input options - GDS2]");
cmd << tl::arg (group +
"#!--no-multi-xy-records", &m_gds2_reader_options.allow_multi_xy_records, "Gives an error on multi-XY records",
"This option disables an advanced interpretation of GDS2 which allows unlimited polygon and path "
"complexity. For compatibility with other readers, this option restores the standard behavior and "
"disables this feature."
)
<< tl::arg (group +
"#!--no-big-records", &m_gds2_reader_options.allow_big_records, "Gives an error on big (>32767 bytes) records",
"The GDS2 specification claims the record length to be a signed 16 bit value. So a record "
"can be 32767 bytes max. To allow bigger records (i.e. bigger polygons), the usual approach "
"is to take the length as a unsigned 16 bit value, so the length is up to 65535 bytes. "
"This option restores the original behavior and reports big (>32767 bytes) records are errors."
)
<< tl::arg (group +
"-ib|--box-mode=mode", &m_gds2_reader_options.box_mode, "Specifies how BOX records are read",
"This an option provided for compatibility with other readers. The mode value specifies how "
"BOX records are read:\n"
"\n"
"* 0: ignore BOX records\n"
"* 1: treat as rectangles (the default)\n"
"* 2: treat as boundaries\n"
"* 3: treat as errors"
)
;
}
{
std::string group ("[Input options - OASIS]");
cmd << tl::arg (group +
"#--expect-strict-mode=mode", &m_oasis_reader_options.expect_strict_mode, "Makes the reader expect strict or non-strict mode",
"With this option, the OASIS reader will expect strict mode (mode is 1) or expect non-strict mode "
"(mode is 0). By default, both modes are allowed. This is a diagnostic feature and does not "
"have any other effect than checking the mode."
)
;
}
{
std::string group ("[Input options - CIF and DXF]");
cmd << tl::arg (group +
"-id|--dbu-in=dbu", this, &GenericReaderOptions::set_dbu, "Specifies the database unit to use",
"This option specifies the database unit the resulting layer will have. "
"The value is given in micrometer units. The default value is 1nm (0.001)."
)
;
}
{
std::string group ("[Input options - CIF]");
cmd << tl::arg (group +
"-iw|--wire-mode=mode", &m_cif_reader_options.wire_mode, "Specifies how wires (W) are read",
"This option specifies how wire objects (W) are read:\n"
"\n"
"* 0: as square ended paths (the default)\n"
"* 1: as flush ended paths\n"
"* 2: as round paths"
)
;
}
{
std::string group ("[Input options - DXF]");
cmd << tl::arg (group +
"-iu|--dxf-unit=unit", &m_dxf_reader_options.unit, "Specifies the DXF drawing units",
"Since DXF is unitless, this value needs to be given to specify the drawing units. "
"By default, a drawing unit of micrometers is assumed."
)
<< tl::arg (group +
"#--dxf-text-scaling=factor", &m_dxf_reader_options.text_scaling, "Specifies text scaling",
"This value specifies text scaling in percent. A value of 100 roughly means that the letter "
"pitch of the font will be 92% of the specified text height. That value applies for ROMANS fonts. "
"When generating GDS texts, a value of 100 generates TEXT objects with "
"the specified size. Smaller values generate smaller sizes."
)
<< tl::arg (group +
"#--dxf-polyline-mode=mode", &m_dxf_reader_options.polyline_mode, "Specifies how POLYLINE records are handled",
"This value specifies how POLYLINE records are handled:\n"
"\n"
"* 0: automatic mode\n"
"* 1: keep lines\n"
"* 2: create polygons from closed POLYLINE/LWPOLYLINE with width == 0\n"
"* 3: merge all lines (width width 0)\n"
"* 4: as 3 and auto-close contours"
)
<< tl::arg (group +
"#--dxf-circle-points=points", &m_dxf_reader_options.circle_points, "Specifies the number of points for a full circle for arc interpolation",
"See --dxf-circle-accuracy for another way of specifying the number of points per circle."
)
<< tl::arg (group +
"#--dxf-circle-accuracy=value", &m_dxf_reader_options.circle_accuracy, "Specifies the accuracy of circle approximation",
"This value specifies the approximation accuracy of the circle and other\n"
"\"round\" structures. If this value is a positive number bigger than the\n"
"database unit (see dbu), it will control the number of points the\n"
"circle is resolved into. The number of points will be chosen such that\n"
"the deviation from the ideal curve is less than this value.\n"
"\n"
"The actual number of points used for the circle approximation is\n"
"not larger than circle_points.\n"
"\n"
"The value is given in the units of the DXF file."
)
<< tl::arg (group +
"#--dxf-render-texts-as-polygons", &m_dxf_reader_options.render_texts_as_polygons, "Renders texts as polygons",
"If this option is used, texts are converted to polygons instead of being converted to labels."
)
<< tl::arg (group +
"#--dxf-keep-other-cells", &m_dxf_reader_options.keep_other_cells, "Keeps cells which are not instantiated by the top cell",
"With this option, all cells not found to be instantiated are kept as additional top cells. "
"By default, such cells are removed."
)
;
}
}
void GenericReaderOptions::set_layer_map (const std::string &lm)
{
tl::Extractor ex (lm.c_str ());
int l = 0;
while (! ex.at_end ()) {
m_layer_map.map_expr (ex, l);
ex.test ("//");
++l;
}
}
void GenericReaderOptions::set_dbu (double dbu)
{
m_dxf_reader_options.dbu = dbu;
m_cif_reader_options.dbu = dbu;
}
void
GenericReaderOptions::configure (db::LoadLayoutOptions &load_options)
{
m_common_reader_options.layer_map = m_layer_map;
m_common_reader_options.create_other_layers = m_create_other_layers;
m_dxf_reader_options.layer_map = m_layer_map;
m_dxf_reader_options.create_other_layers = m_create_other_layers;
m_cif_reader_options.layer_map = m_layer_map;
m_cif_reader_options.create_other_layers = m_create_other_layers;
load_options.set_options (m_common_reader_options);
load_options.set_options (m_gds2_reader_options);
load_options.set_options (m_oasis_reader_options);
load_options.set_options (m_cif_reader_options);
load_options.set_options (m_dxf_reader_options);
}
}

View File

@ -0,0 +1,85 @@
/*
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_bdReaderOptions
#define HDR_bdReaderOptions
#include "bdCommon.h"
#include "dbGDS2Reader.h"
#include "dbCommonReader.h"
#include "dbOASISReader.h"
#include "dbDXFReader.h"
#include "dbCIFReader.h"
#include <string>
namespace tl
{
class CommandLineOptions;
}
namespace db
{
class LoadLayoutOptions;
}
namespace bd
{
/**
* @brief Generic reader options
* This class collects generic reader options and provides command line options for this
*/
class BD_PUBLIC GenericReaderOptions
{
public:
/**
* @brief Constructor
*/
GenericReaderOptions ();
/**
* @brief Adds the generic options to the command line parser object
*/
void add_options (tl::CommandLineOptions &cmd);
/**
* @brief Configures the reader options object with the options stored in this object
*/
void configure (db::LoadLayoutOptions &load_options);
private:
db::LayerMap m_layer_map;
bool m_create_other_layers;
db::CommonReaderOptions m_common_reader_options;
db::GDS2ReaderOptions m_gds2_reader_options;
db::OASISReaderOptions m_oasis_reader_options;
db::CIFReaderOptions m_cif_reader_options;
db::DXFReaderOptions m_dxf_reader_options;
void set_layer_map (const std::string &lm);
void set_dbu (double dbu);
};
}
#endif

View File

@ -30,8 +30,8 @@ namespace bd
{
GenericWriterOptions::GenericWriterOptions ()
: scale_factor (1.0), dbu (0.0),
dont_write_empty_cells (false), keep_instances (false), write_context_info (false)
: m_scale_factor (1.0), m_dbu (0.0),
m_dont_write_empty_cells (false), m_keep_instances (false), m_write_context_info (false)
{
// .. nothing yet ..
}
@ -39,17 +39,23 @@ GenericWriterOptions::GenericWriterOptions ()
void
GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::string &format)
{
const std::string gds2_format_name = m_gds2_writer_options.format_name ();
const std::string gds2text_format_name = gds2_format_name + "Text"; // no special options
const std::string oasis_format_name = m_oasis_writer_options.format_name ();
const std::string dxf_format_name = m_dxf_writer_options.format_name ();
const std::string cif_format_name = m_cif_writer_options.format_name ();
std::string group ("[Output options - General]");
cmd << tl::arg (group +
"-os|--scale-factor=factor", &scale_factor, "Scales the layout upon writing",
"-os|--scale-factor=factor", &m_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") {
if (format == gds2_format_name || format == gds2text_format_name || format == oasis_format_name) {
cmd << tl::arg (group +
"-ou|--dbu=dbu", &dbu, "Uses the specified database unit",
"-od|--dbu-out=dbu", &m_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 "
@ -58,13 +64,13 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
}
cmd << tl::arg (group +
"#-ox|--drop-empty-cells", &dont_write_empty_cells, "Drops empty cells",
"#--drop-empty-cells", &m_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") {
if (format == gds2_format_name || format == gds2text_format_name) {
cmd << tl::arg (group +
"#-ok|--keep-instances", &keep_instances, "Keeps instances of dropped cells",
"#--keep-instances", &m_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.\n"
@ -73,16 +79,16 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
);
}
if (format == "GDS2" || format == "GDS2Text" || format == "OASIS") {
if (format == gds2_format_name || format == gds2text_format_name || format == oasis_format_name) {
cmd << tl::arg (group +
"#-oc|--write-context-info", &write_context_info, "Writes context information",
"#--write-context-info", &m_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 (group +
"#-ow|--write-cells=sel", &cell_selection, "Specifies cells to write",
"#--write-cells=sel", &m_cell_selection, "Specifies cells to write",
"This option specifies the cells to write. The value of this option is a sequence of "
"positive and negative cell select operations. "
"A select operation is an optional plus (+) or minus sign (-), followed by "
@ -101,6 +107,142 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
"* \"(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)"
);
if (format.empty () || format == gds2_format_name || format == gds2text_format_name) {
// Add GDS2 and GDS2Text format options
std::string group = "[Output options - GDS2 specific]";
cmd << tl::arg (group +
"-ov|--max-vertex-count=count", &m_gds2_writer_options.max_vertex_count, "Specifies the maximum number of points per polygon",
"If this number is given, polygons are cut into smaller parts if they have more "
"than the specified number of points. If not given, the maximum number of points will be used. "
"This is 8190 unless --multi-xy-records is given."
)
<< tl::arg (group +
"#--multi-xy-records", &m_gds2_writer_options.multi_xy_records, "Allows unlimited number of points",
"If this option is given, multiple XY records will be written to accomodate an unlimited number "
"of points per polygon or path. However, such files may not be compatible with some consumers."
)
<< tl::arg (group +
"#--no-zero-length-paths", &m_gds2_writer_options.no_zero_length_paths, "Converts zero-length paths to polygons",
"If this option is given, zero-length paths (such with one point) are not written as paths "
"but converted to polygons. This avoids compatibility issues with consumers of this layout file."
)
<< tl::arg (group +
"-on|--cellname-length=length", &m_gds2_writer_options.max_cellname_length, "Limits cell names to the given length",
"If this option is given, long cell names will truncated if their length exceeds the given length."
)
<< tl::arg (group +
"-ol|--libname=libname", &m_gds2_writer_options.libname, "Uses the given library name",
"This option can specify the GDS2 LIBNAME for the output file. By default, the original LIBNAME is "
"written."
)
<< tl::arg (group +
"#--user-units=unit", &m_gds2_writer_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 (group +
"#!--no-timestamps", &m_gds2_writer_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)."
)
<< tl::arg (group +
"#--write-cell-properties", &m_gds2_writer_options.write_cell_properties, "Write cell properties",
"This option enables a GDS2 extension that allows writing of cell properties to GDS2 files. "
"Consumers that don't support this feature, may not be able to read such a GDS2 files."
)
<< tl::arg (group +
"#--write-file-properties", &m_gds2_writer_options.write_file_properties, "Write file properties",
"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."
)
;
}
if (format.empty () || format == oasis_format_name) {
// Add OASIS format options
std::string group = "[Output options - OASIS specific]";
cmd << tl::arg (group +
"-ok|--compression-level=level", &m_oasis_writer_options.compression_level, "Specifies the OASIS compression level",
"This level describes how hard the OASIS writer will try to compress the shapes "
"using shape arrays. Building shape arrays may take some time and requires some memory.\n"
"* 0 - no shape array building\n"
"* 1 - nearest neighbor shape array formation\n"
"* 2++ - enhanced shape array search algorithm using 2nd and further neighbor distances as well\n"
)
<< tl::arg (group +
"-ob|--cblocks", &m_oasis_writer_options.write_cblocks, "Uses CBLOCK compression"
)
<< tl::arg (group +
"-ot|--strict-mode", &m_oasis_writer_options.strict_mode, "Uses strict mode"
)
<< tl::arg (group +
"#--recompress", &m_oasis_writer_options.recompress, "Compresses shape arrays again",
"With this option, shape arrays will be expanded and recompressed. This may result in a better "
"compression ratio, but at the cost of slower execution."
)
<< tl::arg (group +
"#--write-std-properties", &m_oasis_writer_options.write_std_properties, "Writes some global standard properties",
"This is an integer describing what standard properties shall be written. 0 is \"none\" (the default), "
"1 means \"global standard properties such as S_TOP_CELL\" are produced. With 2 also per-cell bounding "
"boxes are produced."
)
<< tl::arg (group +
"#--subst-char=char", this, &GenericWriterOptions::set_oasis_substitution_char, "Specifies the substitution character for non-standard characters",
"The first character of the string specified with this option will be used in placed of illegal "
"characters in n-strings and a-strings."
)
;
}
if (format.empty () || format == dxf_format_name) {
// Add DXF format options
std::string group = "[Output options - DXF specific]";
cmd << tl::arg (group +
"-op|--polygon-mode=mode", &m_dxf_writer_options.polygon_mode, "Specifies how to write polygons",
"This option specifies how to write polygons:\n"
"* 0: create POLYLINE\n"
"* 1: create LWPOLYLINE\n"
"* 2: decompose into SOLID\n"
"* 3: create HATCH\n"
)
;
}
if (format.empty () || format == cif_format_name) {
// Add CIF format options
std::string group = "[Output options - CIF specific]";
cmd << tl::arg (group +
"#--dummy-calls", &m_cif_writer_options.dummy_calls, "Produces dummy calls",
"If this option is given, the writer will produce dummy cell calls on global level for all top cells"
)
<< tl::arg (group +
"#--blank-separator", &m_cif_writer_options.blank_separator, "Uses blanks as x/y separators",
"If this option is given, blank characters will be used to separate x and y values. "
"Otherwise comma characters will be used.\n"
"Use this option if your CIF consumer cannot read comma characters as x/y separators."
)
;
}
}
void GenericWriterOptions::set_oasis_substitution_char (const std::string &text)
{
if (! text.empty ()) {
m_oasis_writer_options.subst_char = text[0];
}
}
static void get_selected_cells (tl::Extractor &ex, const db::Layout &layout, std::set<db::cell_index_type> &selected)
@ -149,16 +291,21 @@ static void get_selected_cells (tl::Extractor &ex, const db::Layout &layout, std
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);
save_options.set_scale_factor (m_scale_factor);
save_options.set_dbu (m_dbu);
save_options.set_dont_write_empty_cells (m_dont_write_empty_cells);
save_options.set_keep_instances (m_keep_instances);
save_options.set_write_context_info (m_write_context_info);
if (!cell_selection.empty ()) {
save_options.set_options (m_gds2_writer_options);
save_options.set_options (m_oasis_writer_options);
save_options.set_options (m_dxf_writer_options);
save_options.set_options (m_cif_writer_options);
if (!m_cell_selection.empty ()) {
std::set<db::cell_index_type> selected;
tl::Extractor ex (cell_selection.c_str ());
tl::Extractor ex (m_cell_selection.c_str ());
get_selected_cells (ex, layout, selected);
save_options.clear_cells ();

View File

@ -24,6 +24,10 @@
#define HDR_bdWriterOptions
#include "bdCommon.h"
#include "dbGDS2WriterBase.h"
#include "dbOASISWriter.h"
#include "dbDXFWriter.h"
#include "dbCIFWriter.h"
#include <string>
@ -45,8 +49,9 @@ namespace bd
* @brief Generic writer options
* This class collects generic writer options and provides command line options for this
*/
struct BD_PUBLIC GenericWriterOptions
class BD_PUBLIC GenericWriterOptions
{
public:
/**
* @brief Constructor
*/
@ -59,18 +64,57 @@ struct BD_PUBLIC GenericWriterOptions
*/
void add_options (tl::CommandLineOptions &cmd, const std::string &format);
/**
* @brief Adds the generic options to the command line parser object for the GDS2 format
*/
void add_options_for_gds2 (tl::CommandLineOptions &cmd)
{
add_options (cmd, m_gds2_writer_options.format_name ());
}
/**
* @brief Adds the generic options to the command line parser object for the OASIS format
*/
void add_options_for_oasis (tl::CommandLineOptions &cmd)
{
add_options (cmd, m_oasis_writer_options.format_name ());
}
/**
* @brief Adds the generic options to the command line parser object for the CIF format
*/
void add_options_for_cif (tl::CommandLineOptions &cmd)
{
add_options (cmd, m_cif_writer_options.format_name ());
}
/**
* @brief Adds the generic options to the command line parser object for the DXF format
*/
void add_options_for_dxf (tl::CommandLineOptions &cmd)
{
add_options (cmd, m_dxf_writer_options.format_name ());
}
/**
* @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;
private:
double m_scale_factor;
double m_dbu;
bool m_dont_write_empty_cells;
bool m_keep_instances;
bool m_write_context_info;
std::string m_cell_selection;
db::GDS2WriterOptions m_gds2_writer_options;
db::OASISWriterOptions m_oasis_writer_options;
db::CIFWriterOptions m_cif_writer_options;
db::DXFWriterOptions m_dxf_writer_options;
void set_oasis_substitution_char (const std::string &text);
};
}

View File

@ -21,66 +21,59 @@
*/
#include "bdInit.h"
#include "bdWriterOptions.h"
#include "dbLayout.h"
#include "dbReader.h"
#include "dbCIFWriter.h"
#include "tlLog.h"
#include "tlCommandLineParser.h"
#include <QFileInfo>
int
main (int argc, char *argv [])
int
main_func (int argc, char *argv [])
{
bd::init ();
db::SaveLayoutOptions save_options;
db::CIFWriterOptions cif_options;
bd::GenericWriterOptions generic_writer_options;
std::string infile, outfile;
tl::CommandLineOptions cmd;
generic_writer_options.add_options_for_cif (cmd);
cmd << tl::arg ("-od|--dummy-calls", &cif_options.dummy_calls, "Produces dummy calls",
"If this option is given, the writer will produce dummy cell calls on global level for all top cells"
)
<< tl::arg ("-ob|--blank-separator", &cif_options.blank_separator, "Uses blanks as x/y separators",
"If this option is given, blank characters will be used to separate x and y values. "
"Otherwise comma characters will be used.\n"
"Use this option if your CIF consumer cannot read comma characters as x/y separators."
)
<< 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 ("input", &infile, "The input file (any format, may be gzip compressed)")
cmd << tl::arg ("input", &infile, "The input file (any format, may be gzip compressed)")
<< tl::arg ("output", &outfile, "The output file")
;
save_options.set_options (cif_options);
cmd.brief ("This program will convert the given file to a CIF file");
cmd.parse (argc, argv);
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
db::SaveLayoutOptions save_options;
generic_writer_options.configure (save_options, layout);
tl::OutputStream stream (outfile);
db::CIFWriter writer;
writer.write (layout, stream, save_options);
}
return 0;
}
int
main (int argc, char *argv [])
{
try {
cmd.parse (argc, argv);
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, save_options);
}
} catch (tl::CancelException &ex) {
return main_func (argc, argv);
} catch (tl::CancelException & /*ex*/) {
return 1;
} catch (std::exception &ex) {
tl::error << ex.what ();
@ -91,8 +84,4 @@ main (int argc, char *argv [])
} catch (...) {
tl::error << "ERROR: unspecific error";
}
return 0;
}

View File

@ -21,51 +21,67 @@
*/
#include "bdInit.h"
#include "bdWriterOptions.h"
#include "dbLayout.h"
#include "dbReader.h"
#include "dbDXFWriter.h"
#include "tlCommandLineParser.h"
int
main (int argc, char *argv [])
int
main_func (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2dxf <infile> <outfile>\n");
return 1;
bd::init ();
bd::GenericWriterOptions generic_writer_options;
std::string infile, outfile;
tl::CommandLineOptions cmd;
generic_writer_options.add_options_for_dxf (cmd);
cmd << tl::arg ("input", &infile, "The input file (any format, may be gzip compressed)")
<< tl::arg ("output", &outfile, "The output file")
;
cmd.brief ("This program will convert the given file to a DXF file");
cmd.parse (argc, argv);
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
{
db::SaveLayoutOptions save_options;
generic_writer_options.configure (save_options, layout);
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;
tl::OutputStream stream (outfile);
db::DXFWriter writer;
writer.write (layout, stream, save_options);
}
return 0;
}
int
main (int argc, char *argv [])
{
try {
return main_func (argc, argv);
} catch (tl::CancelException & /*ex*/) {
return 1;
} catch (std::exception &ex) {
tl::error << ex.what ();
return 1;
} catch (tl::Exception &ex) {
tl::error << ex.msg ();
return 1;
} catch (...) {
tl::error << "ERROR: unspecific error";
}
}

View File

@ -22,6 +22,7 @@
#include "bdInit.h"
#include "bdWriterOptions.h"
#include "bdReaderOptions.h"
#include "dbLayout.h"
#include "dbReader.h"
#include "dbGDS2Writer.h"
@ -32,65 +33,18 @@ main_func (int argc, char *argv [])
{
bd::init ();
db::GDS2WriterOptions gds2_options;
bd::GenericWriterOptions generic_writer_options;
bd::GenericReaderOptions generic_reader_options;
std::string infile, outfile;
tl::CommandLineOptions cmd;
generic_writer_options.add_options_for_gds2 (cmd);
generic_reader_options.add_options (cmd);
std::string group = "[Output options - GDS2 specific]";
cmd << tl::arg (group +
"-ov|--max-vertex-count=count", &gds2_options.max_vertex_count, "Specifies the maximum number of points per polygon",
"If this number is given, polygons are cut into smaller parts if they have more "
"than the specified number of points. If not given, the maximum number of points will be used. "
"This is 8190 unless --multi-xy-records is given."
)
<< tl::arg (group +
"#-om|--multi-xy-records", &gds2_options.multi_xy_records, "Allows unlimited number of points",
"If this option is given, multiple XY records will be written to accomodate an unlimited number "
"of points per polygon or path. However, such files may not be compatible with some consumers."
)
<< tl::arg (group +
"#-oz|--no-zero-length-paths", &gds2_options.no_zero_length_paths, "Converts zero-length paths to polygons",
"If this option is given, zero-length paths (such with one point) are not written as paths "
"but converted to polygons. This avoids compatibility issues with consumers of this layout file."
)
<< tl::arg (group +
"-on|--cellname-length=length", &gds2_options.max_cellname_length, "Limits cell names to the given length",
"If this option is given, long cell names will truncated if their length exceeds the given length."
)
<< tl::arg (group +
"-ol|--libname=libname", &gds2_options.libname, "Uses the given library name",
"This option can specify the GDS2 LIBNAME for the output file. By default, the original LIBNAME is "
"written."
)
<< tl::arg (group +
"#-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 (group +
"#!-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)."
)
<< tl::arg (group +
"#-op|--write-cell-properties", &gds2_options.write_cell_properties, "Write cell properties",
"This option enables a GDS2 extension that allows writing of cell properties to GDS2 files. "
"Consumers that don't support this feature, may not be able to read such a GDS2 files."
)
<< tl::arg (group +
"#-oq|--write-file-properties", &gds2_options.write_file_properties, "Write file properties",
"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 ("input", &infile, "The input file (any format, may be gzip compressed)")
cmd << tl::arg ("input", &infile, "The input file (any format, may be gzip compressed)")
<< tl::arg ("output", &outfile, "The output file")
;
generic_writer_options.add_options (cmd, gds2_options.format_name ());
cmd.brief ("This program will convert the given file to a GDS2 file");
cmd.parse (argc, argv);
@ -100,14 +54,16 @@ main_func (int argc, char *argv [])
db::LayerMap map;
{
db::LoadLayoutOptions load_options;
generic_reader_options.configure (load_options);
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
map = reader.read (layout, load_options);
}
{
db::SaveLayoutOptions save_options;
save_options.set_options (gds2_options);
generic_writer_options.configure (save_options, layout);
tl::OutputStream stream (outfile);

View File

@ -20,51 +20,68 @@
*/
#include "bdInit.h"
#include "bdWriterOptions.h"
#include "dbLayout.h"
#include "dbReader.h"
#include "contrib/dbGDS2TextWriter.h"
#include "tlCommandLineParser.h"
int
main (int argc, char *argv [])
int
main_func (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2gdstxt <infile> <outfile>\n");
return 1;
bd::init ();
bd::GenericWriterOptions generic_writer_options;
std::string infile, outfile;
tl::CommandLineOptions cmd;
generic_writer_options.add_options_for_gds2 (cmd);
cmd << tl::arg ("input", &infile, "The input file (any format, may be gzip compressed)")
<< tl::arg ("output", &outfile, "The output file")
;
cmd.brief ("This program will convert the given file to a GDS2Text file");
cmd.parse (argc, argv);
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
std::string infile (argv[1]);
std::string outfile (argv[2]);
{
db::SaveLayoutOptions save_options;
generic_writer_options.configure (save_options, layout);
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;
tl::OutputStream stream (outfile);
db::GDS2WriterText writer;
writer.write (layout, stream, save_options);
}
return 0;
}
int
main (int argc, char *argv [])
{
try {
return main_func (argc, argv);
} catch (tl::CancelException & /*ex*/) {
return 1;
} catch (std::exception &ex) {
tl::error << ex.what ();
return 1;
} catch (tl::Exception &ex) {
tl::error << ex.msg ();
return 1;
} catch (...) {
tl::error << "ERROR: unspecific error";
}
}

View File

@ -21,110 +21,67 @@
*/
#include "bdInit.h"
#include "bdWriterOptions.h"
#include "dbLayout.h"
#include "dbReader.h"
#include "dbOASISWriter.h"
#include "tlTimer.h"
#include "tlCommandLineParser.h"
#include <memory>
void
syntax ()
int
main_func (int argc, char *argv [])
{
printf ("Syntax: strm2oas [-o <optimization-level>] [-c] <infile> <outfile>\n");
printf ("\n");
printf (" -o n Specify optimization level (0..10, default is 2)\n");
printf (" -c Use CBLOCK compression\n");
printf (" -s Use strict mode\n");
printf (" -r Recompression (ignore existing arrays)\n");
printf (" -v Verbose - print timing information\n");
}
bd::init ();
int
main (int argc, char *argv [])
{
bd::GenericWriterOptions generic_writer_options;
std::string infile, outfile;
bool verbose = false;
try {
tl::CommandLineOptions cmd;
generic_writer_options.add_options_for_oasis (cmd);
db::OASISWriterOptions writer_options;
cmd << tl::arg ("input", &infile, "The input file (any format, may be gzip compressed)")
<< tl::arg ("output", &outfile, "The output file")
;
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]);
}
}
cmd.brief ("This program will convert the given file to an OASIS file");
if (infile.empty ()) {
throw tl::Exception ("Input file not given");
}
if (outfile.empty ()) {
throw tl::Exception ("Output file not given");
}
cmd.parse (argc, argv);
db::Manager m;
db::Layout layout (false, &m);
db::LayerMap map;
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
std::auto_ptr<tl::SelfTimer> timer;
if (verbose) {
timer.reset (new tl::SelfTimer ("Reading input layout"));
}
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
{
db::SaveLayoutOptions options;
options.set_options (writer_options);
{
db::SaveLayoutOptions save_options;
generic_writer_options.configure (save_options, layout);
std::auto_ptr<tl::SelfTimer> timer;
if (verbose) {
timer.reset (new tl::SelfTimer ("Writing OAS"));
}
tl::OutputStream stream (outfile);
db::OASISWriter writer;
writer.write (layout, stream, options);
}
} catch (std::exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.what ());
return 1;
} catch (tl::Exception &ex) {
fprintf (stderr, "*** ERROR: %s\n", ex.msg ().c_str ());
return 1;
} catch (...) {
fprintf (stderr, "*** ERROR: unspecific error\n");
return 1;
tl::OutputStream stream (outfile);
db::OASISWriter writer;
writer.write (layout, stream, save_options);
}
return 0;
}
int
main (int argc, char *argv [])
{
try {
return main_func (argc, argv);
} catch (tl::CancelException & /*ex*/) {
return 1;
} catch (std::exception &ex) {
tl::error << ex.what ();
return 1;
} catch (tl::Exception &ex) {
tl::error << ex.msg ();
return 1;
} catch (...) {
tl::error << "ERROR: unspecific error";
}
}

View File

@ -24,49 +24,58 @@
#include "dbLayout.h"
#include "dbReader.h"
#include "dbTextWriter.h"
#include "tlCommandLineParser.h"
int
main (int argc, char *argv [])
int
main_func (int argc, char *argv [])
{
if (argc != 3) {
printf ("Syntax: strm2txt <infile> <outfile>\n");
return 1;
bd::init ();
std::string infile, outfile;
tl::CommandLineOptions cmd;
cmd << tl::arg ("input", &infile, "The input file (any format, may be gzip compressed)")
<< tl::arg ("output", &outfile, "The output file")
;
cmd.brief ("This program will convert the given file to a proprietary text format file");
cmd.parse (argc, argv);
db::Manager m;
db::Layout layout (&m);
db::LayerMap map;
{
tl::InputStream stream (infile);
db::Reader reader (stream);
map = reader.read (layout);
}
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;
{
tl::OutputStream stream (outfile);
db::TextWriter writer (stream);
writer.write (layout);
}
return 0;
}
int
main (int argc, char *argv [])
{
try {
return main_func (argc, argv);
} catch (tl::CancelException & /*ex*/) {
return 1;
} catch (std::exception &ex) {
tl::error << ex.what ();
return 1;
} catch (tl::Exception &ex) {
tl::error << ex.msg ();
return 1;
} catch (...) {
tl::error << "ERROR: unspecific error";
}
}

View File

@ -472,9 +472,15 @@ CommandLineOptions::parse (int argc, char *argv[])
for (std::vector<ArgBase *>::const_iterator i = m_args.begin (); i != m_args.end (); ++i) {
if ((*i)->is_option ()) {
if (! (*i)->option ().short_option.empty ()) {
if (arg_by_short_option.find ((*i)->option ().short_option) != arg_by_short_option.end ()) {
throw tl::Exception ("Command line parser setup: duplicate option -" + (*i)->option ().short_option);
}
arg_by_short_option.insert (std::make_pair ((*i)->option ().short_option, *i));
}
if (! (*i)->option ().long_option.empty ()) {
if (arg_by_long_option.find ((*i)->option ().long_option) != arg_by_long_option.end ()) {
throw tl::Exception ("Command line parser setup: duplicate option --" + (*i)->option ().long_option);
}
arg_by_long_option.insert (std::make_pair ((*i)->option ().long_option, *i));
}
} else {

View File

@ -932,13 +932,7 @@ OutputStream::OutputStream (const std::string &abstract_path, OutputStreamMode o
: m_pos (0), mp_delegate (0), m_owns_delegate (false)
{
// Determine output mode
if (om == OM_Auto) {
if (tl::match_filename_to_format (abstract_path, "(*.gz *.gzip *.GZ *.GZIP)")) {
om = OM_Zlib;
} else {
om = OM_Plain;
}
}
om = output_mode_from_filename (abstract_path, om);
tl::Extractor ex (abstract_path.c_str ());
if (ex.test ("http:") || ex.test ("https:")) {

View File

@ -38,7 +38,7 @@ TEST(1)
<< tl::arg ("?b", &b, "")
<< tl::arg ("-c", &c, "")
<< tl::arg ("!-cc", &c, "")
<< tl::arg ("--dlong|-d", &d, "")
<< tl::arg ("--plong|-p", &d, "")
<< tl::arg ("--elong", &e, "")
<< tl::arg ("-f|--flong=value", &f, "");
@ -84,7 +84,7 @@ TEST(1)
b = 0;
c = false;
{
char *argv[] = { "x", "u", "-c", "-d=21" };
char *argv[] = { "x", "u", "-c", "-p=21" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (a, "u");
@ -95,7 +95,7 @@ TEST(1)
b = 0;
c = false;
{
char *argv[] = { "x", "u", "-d", "22", "-c" };
char *argv[] = { "x", "u", "-p", "22", "-c" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (a, "u");
@ -105,7 +105,7 @@ TEST(1)
e = false;
{
char *argv[] = { "x", "u", "--dlong", "23" };
char *argv[] = { "x", "u", "--plong", "23" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (a, "u");
@ -113,7 +113,7 @@ TEST(1)
EXPECT_EQ (e, false);
{
char *argv[] = { "x", "u", "--dlong=24", "--elong" };
char *argv[] = { "x", "u", "--plong=24", "--elong" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (a, "u");
@ -169,7 +169,7 @@ TEST(2)
<< tl::arg ("?b", &v, &Values::set_b, "")
<< tl::arg ("-c", &v, &Values::set_c, "")
<< tl::arg ("!-cc", &v, &Values::set_c, "")
<< tl::arg ("--dlong|-d", &v, &Values::set_d, "")
<< tl::arg ("--plong|-p", &v, &Values::set_d, "")
<< tl::arg ("--elong", &v, &Values::set_e, "")
<< tl::arg ("-f|--flong=value", &v, &Values::set_f, "");
@ -215,7 +215,7 @@ TEST(2)
v.b = 0;
v.c = false;
{
char *argv[] = { "x", "u", "-c", "-d=21" };
char *argv[] = { "x", "u", "-c", "-p=21" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (v.a, "u");
@ -226,7 +226,7 @@ TEST(2)
v.b = 0;
v.c = false;
{
char *argv[] = { "x", "u", "-d", "22", "-c" };
char *argv[] = { "x", "u", "-p", "22", "-c" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (v.a, "u");
@ -236,7 +236,7 @@ TEST(2)
v.e = false;
{
char *argv[] = { "x", "u", "--dlong", "23" };
char *argv[] = { "x", "u", "--plong", "23" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (v.a, "u");
@ -244,7 +244,7 @@ TEST(2)
EXPECT_EQ (v.e, false);
{
char *argv[] = { "x", "u", "--dlong=24", "--elong" };
char *argv[] = { "x", "u", "--plong=24", "--elong" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (v.a, "u");