mirror of https://github.com/KLayout/klayout.git
Merge pull request #764 from KLayout/blend-options-for-buddy-scripts
Blend options for buddy scripts
This commit is contained in:
commit
01b4c13a49
|
|
@ -80,6 +80,8 @@
|
|||
Iterated OASIS instances are stored and handled in a leaner way in viewer mode
|
||||
* Enhancement: Buddy scripts can concatenate files with "+" for input
|
||||
Concatenation happens by "blending files". Beware of the risk this implies.
|
||||
A new option "--blend-mode" has been introduced for supporting overwrite, skip
|
||||
and variant formation in case of cell name conflicts. See buddy script help.
|
||||
* Enhancement: Layer maps now support n:m layer mapping
|
||||
This allows mapping n input layers to one logical layer (merging) and also
|
||||
one input layer to m logical ones (clone layer). This applies to the
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ GenericReaderOptions::GenericReaderOptions ()
|
|||
|
||||
m_common_enable_text_objects = load_options.get_option_by_name ("text_enabled").to_bool ();
|
||||
m_common_enable_properties = load_options.get_option_by_name ("properties_enabled").to_bool ();
|
||||
m_cell_conflict_resolution = (unsigned int) db::CellConflictResolution::RenameCell;
|
||||
|
||||
m_gds2_box_mode = load_options.get_option_by_name ("gds2_box_mode").to_uint ();
|
||||
m_gds2_allow_big_records = load_options.get_option_by_name ("gds2_allow_big_records").to_bool ();
|
||||
|
|
@ -197,6 +198,15 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
|
|||
"Each line in this file is read as one layer mapping expression. "
|
||||
"Empty lines or lines starting with a hash (#) character or with double slashes (//) are ignored."
|
||||
)
|
||||
<< tl::arg (group +
|
||||
"--" + m_long_prefix + "blend-mode=mode", &m_cell_conflict_resolution, "Specifies how cell conflicts are resolved when using file concatenation",
|
||||
"When concatenating files with '+', the reader will handle cells with identical names according to this mode:\n"
|
||||
"\n"
|
||||
"* 0: joins everything (unsafe)\n"
|
||||
"* 1: overwrite\n"
|
||||
"* 2: skip new cell\n"
|
||||
"* 3: rename cell (safe, default)"
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
|
|
@ -684,6 +694,7 @@ GenericReaderOptions::configure (db::LoadLayoutOptions &load_options) const
|
|||
load_options.set_option_by_name ("create_other_layers", m_create_other_layers);
|
||||
load_options.set_option_by_name ("text_enabled", m_common_enable_text_objects);
|
||||
load_options.set_option_by_name ("properties_enabled", m_common_enable_properties);
|
||||
load_options.get_options<db::CommonReaderOptions> ().cell_conflict_resolution = db::CellConflictResolution (m_cell_conflict_resolution);
|
||||
|
||||
load_options.set_option_by_name ("gds2_box_mode", m_gds2_box_mode);
|
||||
load_options.set_option_by_name ("gds2_allow_big_records", m_gds2_allow_big_records);
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ private:
|
|||
bool m_create_other_layers;
|
||||
double m_dbu;
|
||||
bool m_keep_layer_names;
|
||||
unsigned int m_cell_conflict_resolution;
|
||||
|
||||
// common GDS2+OASIS
|
||||
bool m_common_enable_text_objects;
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ TEST(10)
|
|||
// General
|
||||
"-im=1/0 3,4/0-255 A:17/0",
|
||||
"-is",
|
||||
"--blend-mode=1",
|
||||
// OASIS
|
||||
"--expect-strict-mode=1"
|
||||
};
|
||||
|
|
@ -258,6 +259,7 @@ TEST(10)
|
|||
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_text_scaling").to_int (), 100);
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("layer_map").to_user<db::LayerMap> ().to_string (), "layer_map()");
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("create_other_layers").to_bool (), true);
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("cell_conflict_resolution").to_string (), "AddToCell");
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("properties_enabled").to_bool (), true);
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("text_enabled").to_bool (), true);
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_box_mode").to_uint (), (unsigned int) 1);
|
||||
|
|
@ -283,6 +285,7 @@ TEST(10)
|
|||
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_text_scaling").to_int (), 75);
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("layer_map").to_user<db::LayerMap> ().to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')");
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("create_other_layers").to_bool (), false);
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("cell_conflict_resolution").to_string (), "OverwriteCell");
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("properties_enabled").to_bool (), false);
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("text_enabled").to_bool (), false);
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_box_mode").to_uint (), (unsigned int) 3);
|
||||
|
|
@ -291,3 +294,22 @@ TEST(10)
|
|||
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_expect_strict_mode").to_int (), 1);
|
||||
}
|
||||
|
||||
|
||||
// Testing reader options - blend mode "Rename" is default
|
||||
TEST(11)
|
||||
{
|
||||
bd::GenericReaderOptions opt;
|
||||
tl::CommandLineOptions cmd;
|
||||
|
||||
opt.add_options (cmd);
|
||||
|
||||
const char *argv[] = { "x" };
|
||||
|
||||
cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv);
|
||||
|
||||
db::LoadLayoutOptions stream_opt;
|
||||
opt.configure (stream_opt);
|
||||
|
||||
EXPECT_EQ (stream_opt.get_option_by_name ("cell_conflict_resolution").to_string (), "RenameCell");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -642,7 +642,6 @@ static void collect_classes (const gsi::ClassBase *cls, std::list<const gsi::Cla
|
|||
unsorted_classes.push_back (cls);
|
||||
|
||||
for (tl::weak_collection<gsi::ClassBase>::const_iterator cc = cls->begin_child_classes (); cc != cls->end_child_classes (); ++cc) {
|
||||
tl_assert (cc->declaration () != 0);
|
||||
collect_classes (cc.operator-> (), unsorted_classes);
|
||||
}
|
||||
}
|
||||
|
|
@ -678,9 +677,8 @@ ClassBase::classes_in_definition_order (const char *mod_name)
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((*c)->declaration () != *c && taken.find ((*c)->declaration ()) == taken.end ()) {
|
||||
if ((*c)->declaration () && (*c)->declaration () != *c && taken.find ((*c)->declaration ()) == taken.end ()) {
|
||||
// can't produce this class yet - it's a reference to another class which is not produced yet.
|
||||
tl_assert ((*c)->declaration () != 0);
|
||||
more_classes.push_back (*c);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -710,8 +708,8 @@ ClassBase::classes_in_definition_order (const char *mod_name)
|
|||
// don't handle classes twice
|
||||
if (taken.find (*c) != taken.end ()) {
|
||||
// not considered.
|
||||
} else if ((*c)->declaration () != *c && taken.find ((*c)->declaration ()) == taken.end ()) {
|
||||
// can't produce this class yet - it's a child of a parent that is not produced yet.
|
||||
} else if ((*c)->declaration () && (*c)->declaration () != *c && taken.find ((*c)->declaration ()) == taken.end ()) {
|
||||
// can't produce this class yet - it refers to a class whic is not available.
|
||||
tl::error << tl::sprintf ("class %s.%s refers to another class (%s.%s) which is not available", (*c)->module (), (*c)->name (), (*c)->declaration ()->module (), (*c)->declaration ()->name ());
|
||||
} else if ((*c)->parent () != 0 && taken.find ((*c)->parent ()) == taken.end ()) {
|
||||
// can't produce this class yet - it's a child of a parent that is not produced yet.
|
||||
|
|
|
|||
|
|
@ -1074,21 +1074,29 @@ initialize_expressions ()
|
|||
gsi::initialize ();
|
||||
|
||||
// Go through all classes (maybe again)
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
std::list<const gsi::ClassBase *> classes = gsi::ClassBase::classes_in_definition_order ();
|
||||
for (std::list<const gsi::ClassBase *>::const_iterator c = classes.begin (); c != classes.end (); ++c) {
|
||||
|
||||
// Skip external classes
|
||||
if (c->is_external ()) {
|
||||
if ((*c)->is_external ()) {
|
||||
// skip external classes
|
||||
continue;
|
||||
} else if ((*c)->declaration () != *c) {
|
||||
// we might encounter a child class which is a reference to a top-level class (e.g.
|
||||
// duplication of enums into child classes). In this case we should create a reference inside the
|
||||
// target class.
|
||||
tl_assert ((*c)->parent () != 0); // top-level classes should be merged
|
||||
// TODO: implement (see rba.cc:1544 for example)
|
||||
continue;
|
||||
}
|
||||
|
||||
// install the method table:
|
||||
ExpressionMethodTable::initialize_class (&*c);
|
||||
ExpressionMethodTable::initialize_class (*c);
|
||||
|
||||
// register a function that creates a class object (use a function to avoid issues with
|
||||
// late destruction of global variables which the class object is already gone)
|
||||
const tl::VariantUserClassBase *cc = c->var_cls_cls ();
|
||||
const tl::VariantUserClassBase *cc = (*c)->var_cls_cls ();
|
||||
if (cc) {
|
||||
tl::Eval::define_global_function (c->name (), new EvalClassFunction (cc));
|
||||
tl::Eval::define_global_function ((*c)->name (), new EvalClassFunction (cc));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue