mirror of https://github.com/KLayout/klayout.git
Added more options for strm2cif and strm2gds.
This commit is contained in:
parent
7280a56ee9
commit
492351519e
|
|
@ -31,23 +31,30 @@
|
|||
int
|
||||
main (int argc, char *argv [])
|
||||
{
|
||||
db::SaveLayoutOptions save_options;
|
||||
db::CIFWriterOptions cif_options;
|
||||
std::string infile, outfile;
|
||||
|
||||
tl::CommandLineOptions 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("input", &infile, "The input file (any format, may be gzip compressed)")
|
||||
<< tl::arg("output", &outfile, "The output file")
|
||||
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)")
|
||||
<< 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");
|
||||
|
||||
try {
|
||||
|
|
@ -67,8 +74,6 @@ main (int argc, char *argv [])
|
|||
{
|
||||
tl::OutputStream stream (outfile);
|
||||
db::CIFWriter writer;
|
||||
db::SaveLayoutOptions save_options;
|
||||
save_options.set_options (cif_options);
|
||||
writer.write (layout, stream, save_options);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,20 +23,86 @@
|
|||
#include "dbLayout.h"
|
||||
#include "dbReader.h"
|
||||
#include "dbGDS2Writer.h"
|
||||
#include "tlCommandLineParser.h"
|
||||
|
||||
int
|
||||
int
|
||||
main (int argc, char *argv [])
|
||||
{
|
||||
if (argc != 3) {
|
||||
printf ("Syntax: strm2gds <infile> <outfile>\n");
|
||||
return 1;
|
||||
}
|
||||
db::SaveLayoutOptions save_options;
|
||||
db::GDS2WriterOptions gds2_options;
|
||||
std::string infile, outfile;
|
||||
|
||||
std::string infile (argv[1]);
|
||||
std::string outfile (argv[2]);
|
||||
tl::CommandLineOptions cmd;
|
||||
|
||||
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 {
|
||||
|
||||
cmd.parse (argc, argv);
|
||||
|
||||
db::Manager m;
|
||||
db::Layout layout (&m);
|
||||
db::LayerMap map;
|
||||
|
|
@ -50,7 +116,7 @@ main (int argc, char *argv [])
|
|||
{
|
||||
tl::OutputStream stream (outfile);
|
||||
db::GDS2Writer writer;
|
||||
writer.write (layout, stream, db::SaveLayoutOptions ());
|
||||
writer.write (layout, stream, save_options);
|
||||
}
|
||||
|
||||
} catch (std::exception &ex) {
|
||||
|
|
|
|||
|
|
@ -32,9 +32,14 @@ namespace tl
|
|||
// ArgBase implementation
|
||||
|
||||
ArgBase::ParsedOption::ParsedOption (const std::string &option)
|
||||
: optional (false)
|
||||
: optional (false), inverted (false)
|
||||
{
|
||||
tl::Extractor ex (option.c_str ());
|
||||
|
||||
if (ex.test ("!")) {
|
||||
inverted = true;
|
||||
}
|
||||
|
||||
while (! ex.at_end ()) {
|
||||
if (ex.test ("--")) {
|
||||
optional = true;
|
||||
|
|
@ -322,7 +327,7 @@ CommandLineOptions::parse (int argc, char *argv[])
|
|||
if (ex.test ("=")) {
|
||||
arg->take_value (ex);
|
||||
} else {
|
||||
arg->mark_present ();
|
||||
arg->mark_present (arg->option ().inverted);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public:
|
|||
*/
|
||||
ParsedOption (const std::string &option);
|
||||
|
||||
bool optional;
|
||||
bool optional, inverted;
|
||||
std::string long_option, short_option, name;
|
||||
};
|
||||
|
||||
|
|
@ -69,6 +69,7 @@ public:
|
|||
* "name" - A mandatory input parameter with name "name"
|
||||
* "?name" - An optional input parameter with name "name"
|
||||
* "-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"
|
||||
* "--long-option" - A long option
|
||||
* "--long-option=value" - A long option with a value
|
||||
|
|
@ -122,7 +123,7 @@ public:
|
|||
/**
|
||||
* @brief Marks an option to be present (for boolean options)
|
||||
*/
|
||||
virtual void mark_present ()
|
||||
virtual void mark_present (bool)
|
||||
{
|
||||
// .. 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"
|
||||
*/
|
||||
template <class T>
|
||||
void mark_presence (T &)
|
||||
void mark_presence (T &, bool)
|
||||
{
|
||||
// .. 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>
|
||||
void mark_presence_setter (C *, void (C::*) (T))
|
||||
void mark_presence_setter (C *, void (C::*) (T), bool)
|
||||
{
|
||||
// .. the default implementation does nothing ..
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
virtual void mark_present ()
|
||||
virtual void mark_present (bool inverted)
|
||||
{
|
||||
mark_presence (*mp_value);
|
||||
mark_presence (*mp_value, inverted);
|
||||
}
|
||||
|
||||
virtual ArgBase *clone () const
|
||||
|
|
@ -304,9 +305,9 @@ public:
|
|||
(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
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ TEST(1)
|
|||
cmd << tl::arg ("a", &a, "")
|
||||
<< tl::arg ("?b", &b, "")
|
||||
<< tl::arg ("-c", &c, "")
|
||||
<< tl::arg ("!-cc", &c, "")
|
||||
<< tl::arg ("--dlong|-d", &d, "")
|
||||
<< tl::arg ("--elong", &e, "")
|
||||
<< tl::arg ("-f|--flong=value", &f, "");
|
||||
|
|
@ -64,6 +65,22 @@ TEST(1)
|
|||
EXPECT_EQ (b, 0);
|
||||
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;
|
||||
c = false;
|
||||
{
|
||||
|
|
@ -151,6 +168,7 @@ TEST(2)
|
|||
cmd << tl::arg ("a", &v, &Values::set_a, "")
|
||||
<< 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 ("--elong", &v, &Values::set_e, "")
|
||||
<< tl::arg ("-f|--flong=value", &v, &Values::set_f, "");
|
||||
|
|
@ -178,6 +196,22 @@ TEST(2)
|
|||
EXPECT_EQ (v.b, 0);
|
||||
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.c = false;
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue