Merge pull request #764 from KLayout/blend-options-for-buddy-scripts

Blend options for buddy scripts
This commit is contained in:
Matthias Köfferlein 2021-04-11 22:41:44 +02:00 committed by GitHub
commit 01b4c13a49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 11 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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");
}

View File

@ -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.

View File

@ -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));
}
}