Added more options for strm2cif and strm2gds.

This commit is contained in:
Matthias Koefferlein 2017-08-14 22:42:12 +02:00
parent 7280a56ee9
commit 492351519e
5 changed files with 145 additions and 34 deletions

View File

@ -31,23 +31,30 @@
int int
main (int argc, char *argv []) main (int argc, char *argv [])
{ {
db::SaveLayoutOptions save_options;
db::CIFWriterOptions cif_options; db::CIFWriterOptions cif_options;
std::string infile, outfile; std::string infile, outfile;
tl::CommandLineOptions cmd; tl::CommandLineOptions cmd;
cmd << tl::arg("-od|--dummy-calls", &cif_options.dummy_calls, "Produces dummy calls", 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" "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", << 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. " "If this option is given, blank characters will be used to separate x and y values. "
"Otherwise comma characters will be used.\n" "Otherwise comma characters will be used.\n"
"Use this option if your CIF consumer cannot read comma characters as x/y separators." "Use this option if your CIF consumer cannot read comma characters as x/y separators."
) )
<< tl::arg("input", &infile, "The input file (any format, may be gzip compressed)") << tl::arg ("-os|--scale-factor=factor", &save_options, &db::SaveLayoutOptions::set_scale_factor, "Scales the layout upon writing",
<< tl::arg("output", &outfile, "The output file") "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)")
<< 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.brief ("This program will convert the given file to a CIF file");
try { try {
@ -67,8 +74,6 @@ main (int argc, char *argv [])
{ {
tl::OutputStream stream (outfile); tl::OutputStream stream (outfile);
db::CIFWriter writer; db::CIFWriter writer;
db::SaveLayoutOptions save_options;
save_options.set_options (cif_options);
writer.write (layout, stream, save_options); writer.write (layout, stream, save_options);
} }

View File

@ -23,20 +23,86 @@
#include "dbLayout.h" #include "dbLayout.h"
#include "dbReader.h" #include "dbReader.h"
#include "dbGDS2Writer.h" #include "dbGDS2Writer.h"
#include "tlCommandLineParser.h"
int int
main (int argc, char *argv []) main (int argc, char *argv [])
{ {
if (argc != 3) { db::SaveLayoutOptions save_options;
printf ("Syntax: strm2gds <infile> <outfile>\n"); db::GDS2WriterOptions gds2_options;
return 1; std::string infile, outfile;
}
std::string infile (argv[1]); tl::CommandLineOptions cmd;
std::string outfile (argv[2]);
cmd << tl::arg ("-ov|--max-vertex-count=count", &gds2_options.max_vertex_count, "Specify 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 ("-om|--multi-xy-records", &gds2_options.multi_xy_records, "Allow 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 ("-oz|--no-zero-length-paths", &gds2_options.no_zero_length_paths, "Don't allow zero-length paths",
"If this option is given, zero-length paths (such with one point) are not written."
)
<< tl::arg ("-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 ("-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 ("-om|--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",
"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 ("-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 ("-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 ("-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);
cmd.brief ("This program will convert the given file to a GDS2 file");
try { try {
cmd.parse (argc, argv);
db::Manager m; db::Manager m;
db::Layout layout (&m); db::Layout layout (&m);
db::LayerMap map; db::LayerMap map;
@ -50,7 +116,7 @@ main (int argc, char *argv [])
{ {
tl::OutputStream stream (outfile); tl::OutputStream stream (outfile);
db::GDS2Writer writer; db::GDS2Writer writer;
writer.write (layout, stream, db::SaveLayoutOptions ()); writer.write (layout, stream, save_options);
} }
} catch (std::exception &ex) { } catch (std::exception &ex) {

View File

@ -32,9 +32,14 @@ namespace tl
// ArgBase implementation // ArgBase implementation
ArgBase::ParsedOption::ParsedOption (const std::string &option) ArgBase::ParsedOption::ParsedOption (const std::string &option)
: optional (false) : optional (false), inverted (false)
{ {
tl::Extractor ex (option.c_str ()); tl::Extractor ex (option.c_str ());
if (ex.test ("!")) {
inverted = true;
}
while (! ex.at_end ()) { while (! ex.at_end ()) {
if (ex.test ("--")) { if (ex.test ("--")) {
optional = true; optional = true;
@ -322,7 +327,7 @@ CommandLineOptions::parse (int argc, char *argv[])
if (ex.test ("=")) { if (ex.test ("=")) {
arg->take_value (ex); arg->take_value (ex);
} else { } else {
arg->mark_present (); arg->mark_present (arg->option ().inverted);
} }
} }

View File

@ -54,7 +54,7 @@ public:
*/ */
ParsedOption (const std::string &option); ParsedOption (const std::string &option);
bool optional; bool optional, inverted;
std::string long_option, short_option, name; std::string long_option, short_option, name;
}; };
@ -69,6 +69,7 @@ public:
* "name" - A mandatory input parameter with name "name" * "name" - A mandatory input parameter with name "name"
* "?name" - An optional input parameter with name "name" * "?name" - An optional input parameter with name "name"
* "-o" - A short option without a parameter (boolean) * "-o" - A short option without a parameter (boolean)
* "!-o" - Sets the value to false if present
* "-o=value" - A short option with a value named "value" * "-o=value" - A short option with a value named "value"
* "--long-option" - A long option * "--long-option" - A long option
* "--long-option=value" - A long option with a value * "--long-option=value" - A long option with a value
@ -122,7 +123,7 @@ public:
/** /**
* @brief Marks an option to be present (for boolean options) * @brief Marks an option to be present (for boolean options)
*/ */
virtual void mark_present () virtual void mark_present (bool)
{ {
// .. nothing yet .. // .. nothing yet ..
} }
@ -191,26 +192,26 @@ void extract (tl::Extractor &ex, std::vector<T> &t, bool /*for_list*/ = false)
* @brief A helper to mark "presence" * @brief A helper to mark "presence"
*/ */
template <class T> template <class T>
void mark_presence (T &) void mark_presence (T &, bool)
{ {
// .. the default implementation does nothing .. // .. the default implementation does nothing ..
} }
void mark_presence (bool &t) void mark_presence (bool &t, bool invert)
{ {
t = true; t = !invert;
} }
template <class C, class T> template <class C, class T>
void mark_presence_setter (C *, void (C::*) (T)) void mark_presence_setter (C *, void (C::*) (T), bool)
{ {
// .. the default implementation does nothing .. // .. the default implementation does nothing ..
} }
template <class C> template <class C>
void mark_presence_setter (C *c, void (C::*ptr) (bool)) void mark_presence_setter (C *c, void (C::*ptr) (bool), bool invert)
{ {
(c->*ptr) (true); (c->*ptr) (!invert);
} }
@ -263,9 +264,9 @@ public:
extract (ex, *mp_value); extract (ex, *mp_value);
} }
virtual void mark_present () virtual void mark_present (bool inverted)
{ {
mark_presence (*mp_value); mark_presence (*mp_value, inverted);
} }
virtual ArgBase *clone () const virtual ArgBase *clone () const
@ -304,9 +305,9 @@ public:
(mp_object->*mp_setter) (t); (mp_object->*mp_setter) (t);
} }
virtual void mark_present () virtual void mark_present (bool inverted)
{ {
mark_presence_setter (mp_object, mp_setter); mark_presence_setter (mp_object, mp_setter, inverted);
} }
virtual ArgBase *clone () const virtual ArgBase *clone () const

View File

@ -37,6 +37,7 @@ TEST(1)
cmd << tl::arg ("a", &a, "") cmd << tl::arg ("a", &a, "")
<< tl::arg ("?b", &b, "") << tl::arg ("?b", &b, "")
<< tl::arg ("-c", &c, "") << tl::arg ("-c", &c, "")
<< tl::arg ("!-cc", &c, "")
<< tl::arg ("--dlong|-d", &d, "") << tl::arg ("--dlong|-d", &d, "")
<< tl::arg ("--elong", &e, "") << tl::arg ("--elong", &e, "")
<< tl::arg ("-f|--flong=value", &f, ""); << tl::arg ("-f|--flong=value", &f, "");
@ -64,6 +65,22 @@ TEST(1)
EXPECT_EQ (b, 0); EXPECT_EQ (b, 0);
EXPECT_EQ (c, true); EXPECT_EQ (c, true);
b = 0;
c = true;
{
char *argv[] = { "x", "u", "-cc" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (a, "u");
EXPECT_EQ (b, 0);
EXPECT_EQ (c, false);
{
char *argv[] = { "x", "u", "-c", "-cc" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (c, false);
b = 0; b = 0;
c = false; c = false;
{ {
@ -151,6 +168,7 @@ TEST(2)
cmd << tl::arg ("a", &v, &Values::set_a, "") cmd << tl::arg ("a", &v, &Values::set_a, "")
<< tl::arg ("?b", &v, &Values::set_b, "") << tl::arg ("?b", &v, &Values::set_b, "")
<< tl::arg ("-c", &v, &Values::set_c, "") << tl::arg ("-c", &v, &Values::set_c, "")
<< tl::arg ("!-cc", &v, &Values::set_c, "")
<< tl::arg ("--dlong|-d", &v, &Values::set_d, "") << tl::arg ("--dlong|-d", &v, &Values::set_d, "")
<< tl::arg ("--elong", &v, &Values::set_e, "") << tl::arg ("--elong", &v, &Values::set_e, "")
<< tl::arg ("-f|--flong=value", &v, &Values::set_f, ""); << tl::arg ("-f|--flong=value", &v, &Values::set_f, "");
@ -178,6 +196,22 @@ TEST(2)
EXPECT_EQ (v.b, 0); EXPECT_EQ (v.b, 0);
EXPECT_EQ (v.c, true); EXPECT_EQ (v.c, true);
v.b = 0;
v.c = true;
{
char *argv[] = { "x", "u", "-cc" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (v.a, "u");
EXPECT_EQ (v.b, 0);
EXPECT_EQ (v.c, false);
{
char *argv[] = { "x", "u", "-c", "-cc" };
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
}
EXPECT_EQ (v.c, false);
v.b = 0; v.b = 0;
v.c = false; v.c = false;
{ {