mirror of https://github.com/KLayout/klayout.git
Bugfix: re-run of include-expanded DRC/LVS wasn't working
Reworked include-expansion scheme for DRC/LVS such that include expansion is done by the interpreter, hence is also available for re-running the script from the marker/netlist browser. This also affects the D25 implementation.
This commit is contained in:
parent
304800e4c5
commit
e6c9872ea2
|
|
@ -19,7 +19,7 @@ module DRC
|
||||||
|
|
||||||
class DRCExecutable < RBA::Executable
|
class DRCExecutable < RBA::Executable
|
||||||
|
|
||||||
def initialize(macro, generator, rdb_index = nil)
|
def initialize(macro, interpreter, generator, rdb_index = nil)
|
||||||
|
|
||||||
@drc = DRCEngine::new
|
@drc = DRCEngine::new
|
||||||
@drc._rdb_index = rdb_index
|
@drc._rdb_index = rdb_index
|
||||||
|
|
@ -27,6 +27,8 @@ module DRC
|
||||||
|
|
||||||
@macro = macro
|
@macro = macro
|
||||||
|
|
||||||
|
@interpreter = interpreter
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
|
|
@ -38,9 +40,11 @@ module DRC
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
encoded_file, expanded_text = @interpreter.include_expansion(@macro)
|
||||||
|
|
||||||
# No verbosity set in drc engine - we cannot use the engine's logger
|
# No verbosity set in drc engine - we cannot use the engine's logger
|
||||||
RBA::Logger::verbosity >= 10 && RBA::Logger::info("Running #{@macro.path}")
|
RBA::Logger::verbosity >= 10 && RBA::Logger::info("Running #{@macro.path}")
|
||||||
@drc.instance_eval(@macro.text, @macro.path)
|
@drc.instance_eval(expanded_text, encoded_file)
|
||||||
|
|
||||||
rescue => ex
|
rescue => ex
|
||||||
|
|
||||||
|
|
@ -66,13 +70,40 @@ module DRC
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A recipe implementation allowing the DRC run to be redone
|
||||||
|
class DRCRecipe < RBA::Recipe
|
||||||
|
|
||||||
|
def initialize(interpreter)
|
||||||
|
|
||||||
|
super("drc", "DRC recipe")
|
||||||
|
|
||||||
|
@interpreter = interpreter
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def executable(params)
|
||||||
|
|
||||||
|
script = params["script"]
|
||||||
|
if ! script
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
macro = RBA::Macro::macro_by_path(script)
|
||||||
|
macro || raise("Can't find DRC script #{script} - unable to re-run")
|
||||||
|
|
||||||
|
DRCExecutable::new(macro, @interpreter, self.generator("script" => script), params["rdb_index"])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
# A DSL implementation for a DRC language (XML format)
|
# A DSL implementation for a DRC language (XML format)
|
||||||
class DRCInterpreter < RBA::MacroInterpreter
|
class DRCInterpreter < RBA::MacroInterpreter
|
||||||
|
|
||||||
# Constructor
|
# Constructor
|
||||||
def initialize(recipe)
|
def initialize
|
||||||
|
|
||||||
@recipe = recipe
|
@recipe = DRCRecipe::new(self)
|
||||||
|
|
||||||
# Make the DSL use ruby syntax highlighting
|
# Make the DSL use ruby syntax highlighting
|
||||||
self.syntax_scheme = "ruby"
|
self.syntax_scheme = "ruby"
|
||||||
|
|
@ -97,7 +128,7 @@ module DRC
|
||||||
|
|
||||||
# Implements the execute method
|
# Implements the execute method
|
||||||
def executable(macro)
|
def executable(macro)
|
||||||
DRCExecutable::new(macro, @recipe.generator("script" => macro.path))
|
DRCExecutable::new(macro, self, @recipe.generator("script" => macro.path))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
@ -106,9 +137,9 @@ module DRC
|
||||||
class DRCPlainTextInterpreter < RBA::MacroInterpreter
|
class DRCPlainTextInterpreter < RBA::MacroInterpreter
|
||||||
|
|
||||||
# Constructor
|
# Constructor
|
||||||
def initialize(recipe)
|
def initialize
|
||||||
|
|
||||||
@recipe = recipe
|
@recipe = DRCRecipe::new(self)
|
||||||
|
|
||||||
# Make the DSL use ruby syntax highlighting
|
# Make the DSL use ruby syntax highlighting
|
||||||
self.syntax_scheme = "ruby"
|
self.syntax_scheme = "ruby"
|
||||||
|
|
@ -124,40 +155,14 @@ module DRC
|
||||||
|
|
||||||
# Implements the execute method
|
# Implements the execute method
|
||||||
def executable(macro)
|
def executable(macro)
|
||||||
DRCExecutable::new(macro, @recipe.generator("script" => macro.path))
|
DRCExecutable::new(macro, self, @recipe.generator("script" => macro.path))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# A recipe implementation allowing the DRC run to be redone
|
|
||||||
class DRCRecipe < RBA::Recipe
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
super("drc", "DRC recipe")
|
|
||||||
end
|
|
||||||
|
|
||||||
def executable(params)
|
|
||||||
|
|
||||||
script = params["script"]
|
|
||||||
if ! script
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
macro = RBA::Macro::macro_by_path(script)
|
|
||||||
macro || raise("Can't find DRC script #{script} - unable to re-run")
|
|
||||||
|
|
||||||
DRCExecutable::new(macro, self.generator("script" => script), params["rdb_index"])
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# Register the recipe
|
|
||||||
drc_recipe = DRCRecipe::new
|
|
||||||
|
|
||||||
# Register the new interpreters
|
# Register the new interpreters
|
||||||
DRCInterpreter::new(drc_recipe)
|
DRCInterpreter::new
|
||||||
DRCPlainTextInterpreter::new(drc_recipe)
|
DRCPlainTextInterpreter::new
|
||||||
|
|
||||||
# Creates a new macro category
|
# Creates a new macro category
|
||||||
if RBA.constants.member?(:Application) && RBA::Application::instance
|
if RBA.constants.member?(:Application) && RBA::Application::instance
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ module LVS
|
||||||
|
|
||||||
class LVSExecutable < RBA::Executable
|
class LVSExecutable < RBA::Executable
|
||||||
|
|
||||||
def initialize(macro, generator, l2ndb_index = nil)
|
def initialize(macro, interpreter, generator, l2ndb_index = nil)
|
||||||
|
|
||||||
@lvs = LVSEngine::new
|
@lvs = LVSEngine::new
|
||||||
@lvs._l2ndb_index = l2ndb_index
|
@lvs._l2ndb_index = l2ndb_index
|
||||||
|
|
@ -27,6 +27,8 @@ module LVS
|
||||||
|
|
||||||
@macro = macro
|
@macro = macro
|
||||||
|
|
||||||
|
@interpreter = interpreter
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
|
|
@ -38,9 +40,11 @@ module LVS
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
encoded_file, expanded_text = @interpreter.include_expansion(@macro)
|
||||||
|
|
||||||
# No verbosity set in lvs engine - we cannot use the engine's logger
|
# No verbosity set in lvs engine - we cannot use the engine's logger
|
||||||
RBA::Logger::verbosity >= 10 && RBA::Logger::info("Running #{@macro.path}")
|
RBA::Logger::verbosity >= 10 && RBA::Logger::info("Running #{@macro.path}")
|
||||||
@lvs.instance_eval(@macro.text, @macro.path)
|
@lvs.instance_eval(expanded_text, encoded_file)
|
||||||
|
|
||||||
rescue => ex
|
rescue => ex
|
||||||
|
|
||||||
|
|
@ -66,13 +70,40 @@ module LVS
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A recipe implementation allowing the LVS run to be redone
|
||||||
|
class LVSRecipe < RBA::Recipe
|
||||||
|
|
||||||
|
def initialize(interpreter)
|
||||||
|
|
||||||
|
super("lvs", "LVS recipe")
|
||||||
|
|
||||||
|
@interpreter = interpreter
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def executable(params)
|
||||||
|
|
||||||
|
script = params["script"]
|
||||||
|
if ! script
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
macro = RBA::Macro::macro_by_path(script)
|
||||||
|
macro || raise("Can't find LVS script #{script} - unable to re-run")
|
||||||
|
|
||||||
|
LVSExecutable::new(macro, @interpreter, self.generator("script" => script), params["l2ndb_index"])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
# A DSL implementation for a LVS language (XML format)
|
# A DSL implementation for a LVS language (XML format)
|
||||||
class LVSInterpreter < RBA::MacroInterpreter
|
class LVSInterpreter < RBA::MacroInterpreter
|
||||||
|
|
||||||
# Constructor
|
# Constructor
|
||||||
def initialize(recipe)
|
def initialize
|
||||||
|
|
||||||
@recipe = recipe
|
@recipe = LVSRecipe::new(self)
|
||||||
|
|
||||||
# Make the DSL use ruby syntax highlighting
|
# Make the DSL use ruby syntax highlighting
|
||||||
self.syntax_scheme = "ruby"
|
self.syntax_scheme = "ruby"
|
||||||
|
|
@ -97,7 +128,7 @@ module LVS
|
||||||
|
|
||||||
# Implements the execute method
|
# Implements the execute method
|
||||||
def executable(macro)
|
def executable(macro)
|
||||||
LVSExecutable::new(macro, @recipe.generator("script" => macro.path))
|
LVSExecutable::new(macro, self, @recipe.generator("script" => macro.path))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
@ -106,9 +137,9 @@ module LVS
|
||||||
class LVSPlainTextInterpreter < RBA::MacroInterpreter
|
class LVSPlainTextInterpreter < RBA::MacroInterpreter
|
||||||
|
|
||||||
# Constructor
|
# Constructor
|
||||||
def initialize(recipe)
|
def initialize
|
||||||
|
|
||||||
@recipe = recipe
|
@recipe = LVSRecipe::new(self)
|
||||||
|
|
||||||
# Make the DSL use ruby syntax highlighting
|
# Make the DSL use ruby syntax highlighting
|
||||||
self.syntax_scheme = "ruby"
|
self.syntax_scheme = "ruby"
|
||||||
|
|
@ -124,40 +155,14 @@ module LVS
|
||||||
|
|
||||||
# Implements the execute method
|
# Implements the execute method
|
||||||
def executable(macro)
|
def executable(macro)
|
||||||
LVSExecutable::new(macro, @recipe.generator("script" => macro.path))
|
LVSExecutable::new(macro, self, @recipe.generator("script" => macro.path))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# A recipe implementation allowing the LVS run to be redone
|
|
||||||
class LVSRecipe < RBA::Recipe
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
super("lvs", "LVS recipe")
|
|
||||||
end
|
|
||||||
|
|
||||||
def executable(params)
|
|
||||||
|
|
||||||
script = params["script"]
|
|
||||||
if ! script
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
macro = RBA::Macro::macro_by_path(script)
|
|
||||||
macro || raise("Can't find LVS script #{script} - unable to re-run")
|
|
||||||
|
|
||||||
LVSExecutable::new(macro, self.generator("script" => script), params["l2ndb_index"])
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# Register the recipe
|
|
||||||
lvs_recipe = LVSRecipe::new
|
|
||||||
|
|
||||||
# Register the new interpreters
|
# Register the new interpreters
|
||||||
LVSInterpreter::new(lvs_recipe)
|
LVSInterpreter::new
|
||||||
LVSPlainTextInterpreter::new(lvs_recipe)
|
LVSPlainTextInterpreter::new
|
||||||
|
|
||||||
# Creates a new macro category
|
# Creates a new macro category
|
||||||
if RBA.constants.member?(:Application) && RBA::Application::instance
|
if RBA.constants.member?(:Application) && RBA::Application::instance
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,18 @@ private:
|
||||||
bool m_supports_include_expansion;
|
bool m_supports_include_expansion;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::vector<std::string>
|
||||||
|
include_expansion (MacroInterpreterImpl *interp, lym::Macro *macro)
|
||||||
|
{
|
||||||
|
std::vector<std::string> res;
|
||||||
|
|
||||||
|
auto sp = interp->include_expansion (macro);
|
||||||
|
res.push_back (sp.first);
|
||||||
|
res.push_back (sp.second);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
gsi::EnumIn<lym::Macro, lym::Macro::Format> decl_FormatEnum ("lay", "Format",
|
gsi::EnumIn<lym::Macro, lym::Macro::Format> decl_FormatEnum ("lay", "Format",
|
||||||
gsi::enum_const ("PlainTextFormat", lym::Macro::PlainTextFormat,
|
gsi::enum_const ("PlainTextFormat", lym::Macro::PlainTextFormat,
|
||||||
"@brief The macro has plain text format"
|
"@brief The macro has plain text format"
|
||||||
|
|
@ -298,6 +310,13 @@ Class<MacroInterpreterImpl> decl_MacroInterpreter ("lay", "MacroInterpreter",
|
||||||
gsi::method ("NoDebugger", &const_NoDebugger,
|
gsi::method ("NoDebugger", &const_NoDebugger,
|
||||||
"@brief Indicates no debugging for \\debugger_scheme\n"
|
"@brief Indicates no debugging for \\debugger_scheme\n"
|
||||||
) +
|
) +
|
||||||
|
gsi::method_ext ("include_expansion", &include_expansion, gsi::arg ("macro"),
|
||||||
|
"@brief Provides include expansion as defined by the interpreter\n"
|
||||||
|
"The return value will be a two-element array with the encoded file path "
|
||||||
|
"and the include-expanded text.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.28.12."
|
||||||
|
) +
|
||||||
gsi::method ("register", &MacroInterpreterImpl::register_gsi, gsi::arg ("name"),
|
gsi::method ("register", &MacroInterpreterImpl::register_gsi, gsi::arg ("name"),
|
||||||
"@brief Registers the macro interpreter\n"
|
"@brief Registers the macro interpreter\n"
|
||||||
"@param name The interpreter name. This is an arbitrary string which should be unique.\n"
|
"@param name The interpreter name. This is an arbitrary string which should be unique.\n"
|
||||||
|
|
|
||||||
|
|
@ -130,31 +130,15 @@ MacroInterpreter::execute_macro (const lym::Macro *macro)
|
||||||
|
|
||||||
if (cls.current_name () == macro->dsl_interpreter ()) {
|
if (cls.current_name () == macro->dsl_interpreter ()) {
|
||||||
|
|
||||||
std::pair<std::string, std::string> et = cls->include_expansion (macro);
|
std::unique_ptr<tl::Executable> eo (cls->executable (macro));
|
||||||
if (et.first.empty () || et.first == macro->path ()) {
|
if (eo.get ()) {
|
||||||
|
eo->do_execute ();
|
||||||
std::unique_ptr<tl::Executable> eo (cls->executable (macro));
|
|
||||||
if (eo.get ()) {
|
|
||||||
eo->do_execute ();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// provide a copy which takes the include-expanded version
|
|
||||||
lym::Macro tmp_macro;
|
|
||||||
tmp_macro.assign (*macro);
|
|
||||||
tmp_macro.set_text (et.second);
|
|
||||||
tmp_macro.set_file_path (et.first);
|
|
||||||
std::unique_ptr<tl::Executable> eo (cls->executable (&tmp_macro));
|
|
||||||
if (eo.get ()) {
|
|
||||||
eo->do_execute ();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw tl::Exception (tl::to_string (tr ("No interpreter registered for DSL type '")) + macro->dsl_interpreter () + "'");
|
throw tl::Exception (tl::to_string (tr ("No interpreter registered for DSL type '")) + macro->dsl_interpreter () + "'");
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,15 @@ module D25
|
||||||
|
|
||||||
class D25Executable < RBA::Executable
|
class D25Executable < RBA::Executable
|
||||||
|
|
||||||
def initialize(macro, generator)
|
def initialize(macro, interpreter, generator)
|
||||||
|
|
||||||
@d25 = D25Engine::new
|
@d25 = D25Engine::new
|
||||||
@d25._generator = generator
|
@d25._generator = generator
|
||||||
|
|
||||||
@macro = macro
|
@macro = macro
|
||||||
|
|
||||||
|
@interpreter = interpreter
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
|
|
@ -37,9 +39,11 @@ module D25
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
encoded_file, expanded_text = @interpreter.include_expansion(@macro)
|
||||||
|
|
||||||
# No verbosity set in d25 engine - we cannot use the engine's logger
|
# No verbosity set in d25 engine - we cannot use the engine's logger
|
||||||
RBA::Logger::verbosity >= 10 && RBA::Logger::info("Running #{@macro.path}")
|
RBA::Logger::verbosity >= 10 && RBA::Logger::info("Running #{@macro.path}")
|
||||||
@d25.instance_eval(@macro.text, @macro.path)
|
@d25.instance_eval(expanded_text, encoded_file)
|
||||||
|
|
||||||
rescue => ex
|
rescue => ex
|
||||||
|
|
||||||
|
|
@ -67,13 +71,40 @@ module D25
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A recipe implementation allowing the D25 run to be redone
|
||||||
|
class D25Recipe < RBA::Recipe
|
||||||
|
|
||||||
|
def initialize(interpreter)
|
||||||
|
|
||||||
|
super("d25", "D25 recipe")
|
||||||
|
|
||||||
|
@interpreter = interpreter
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def executable(params)
|
||||||
|
|
||||||
|
script = params["script"]
|
||||||
|
if ! script
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
macro = RBA::Macro::macro_by_path(script)
|
||||||
|
macro || raise("Can't find D25 script #{script} - unable to re-run")
|
||||||
|
|
||||||
|
D25Executable::new(macro, @interpreter, self.generator("script" => script))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
# A DSL implementation for a D25 language (XML format)
|
# A DSL implementation for a D25 language (XML format)
|
||||||
class D25Interpreter < RBA::MacroInterpreter
|
class D25Interpreter < RBA::MacroInterpreter
|
||||||
|
|
||||||
# Constructor
|
# Constructor
|
||||||
def initialize(recipe)
|
def initialize
|
||||||
|
|
||||||
@recipe = recipe
|
@recipe = D25Recipe::new(self)
|
||||||
|
|
||||||
# Make the DSL use ruby syntax highlighting
|
# Make the DSL use ruby syntax highlighting
|
||||||
self.syntax_scheme = "ruby"
|
self.syntax_scheme = "ruby"
|
||||||
|
|
@ -98,7 +129,7 @@ module D25
|
||||||
|
|
||||||
# Implements the execute method
|
# Implements the execute method
|
||||||
def executable(macro)
|
def executable(macro)
|
||||||
D25Executable::new(macro, @recipe.generator("script" => macro.path))
|
D25Executable::new(macro, self, @recipe.generator("script" => macro.path))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
@ -107,9 +138,9 @@ module D25
|
||||||
class D25PlainTextInterpreter < RBA::MacroInterpreter
|
class D25PlainTextInterpreter < RBA::MacroInterpreter
|
||||||
|
|
||||||
# Constructor
|
# Constructor
|
||||||
def initialize(recipe)
|
def initialize
|
||||||
|
|
||||||
@recipe = recipe
|
@recipe = D25Recipe::new(self)
|
||||||
|
|
||||||
# Make the DSL use ruby syntax highlighting
|
# Make the DSL use ruby syntax highlighting
|
||||||
self.syntax_scheme = "ruby"
|
self.syntax_scheme = "ruby"
|
||||||
|
|
@ -125,40 +156,14 @@ module D25
|
||||||
|
|
||||||
# Implements the execute method
|
# Implements the execute method
|
||||||
def executable(macro)
|
def executable(macro)
|
||||||
D25Executable::new(macro, @recipe.generator("script" => macro.path))
|
D25Executable::new(macro, self, @recipe.generator("script" => macro.path))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# A recipe implementation allowing the D25 run to be redone
|
|
||||||
class D25Recipe < RBA::Recipe
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
super("d25", "D25 recipe")
|
|
||||||
end
|
|
||||||
|
|
||||||
def executable(params)
|
|
||||||
|
|
||||||
script = params["script"]
|
|
||||||
if ! script
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
macro = RBA::Macro::macro_by_path(script)
|
|
||||||
macro || raise("Can't find D25 script #{script} - unable to re-run")
|
|
||||||
|
|
||||||
D25Executable::new(macro, self.generator("script" => script))
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# Register the recipe
|
|
||||||
d25_recipe = D25Recipe::new
|
|
||||||
|
|
||||||
# Register the new interpreters
|
# Register the new interpreters
|
||||||
D25Interpreter::new(d25_recipe)
|
D25Interpreter::new
|
||||||
D25PlainTextInterpreter::new(d25_recipe)
|
D25PlainTextInterpreter::new
|
||||||
|
|
||||||
# Creates a new macro category
|
# Creates a new macro category
|
||||||
if RBA::Application::instance
|
if RBA::Application::instance
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue