mirror of https://github.com/KLayout/klayout.git
Provide Ruby/Python binding for technology definitions
The respective new classes are RBA::Technology and RBA::TechnologyComponent. This interface will replace the current way of doing tech management from scripts by using the "technology-data" configuration parameter.
This commit is contained in:
parent
47aa38421a
commit
50df9e5b21
|
|
@ -139,30 +139,37 @@ public:
|
|||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> config_decl (new NetTracerPluginDeclaration (), 13000, "NetTracerPlugin");
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// GSI binding
|
||||
|
||||
static void def_connection2 (NetTracerTechnologyComponent *tech, const std::string &la, const std::string &lb)
|
||||
namespace gsi
|
||||
{
|
||||
NetTracerLayerExpressionInfo la_info = NetTracerLayerExpressionInfo::compile (la);
|
||||
NetTracerLayerExpressionInfo lb_info = NetTracerLayerExpressionInfo::compile (lb);
|
||||
tech->add (NetTracerConnectionInfo (la_info, lb_info));
|
||||
|
||||
static void def_connection2 (ext::NetTracerTechnologyComponent *tech, const std::string &la, const std::string &lb)
|
||||
{
|
||||
ext::NetTracerLayerExpressionInfo la_info = ext::NetTracerLayerExpressionInfo::compile (la);
|
||||
ext::NetTracerLayerExpressionInfo lb_info = ext::NetTracerLayerExpressionInfo::compile (lb);
|
||||
tech->add (ext::NetTracerConnectionInfo (la_info, lb_info));
|
||||
}
|
||||
|
||||
static void def_connection3 (NetTracerTechnologyComponent *tech, const std::string &la, const std::string &via, const std::string &lb)
|
||||
static void def_connection3 (ext::NetTracerTechnologyComponent *tech, const std::string &la, const std::string &via, const std::string &lb)
|
||||
{
|
||||
NetTracerLayerExpressionInfo la_info = NetTracerLayerExpressionInfo::compile (la);
|
||||
NetTracerLayerExpressionInfo via_info = NetTracerLayerExpressionInfo::compile (via);
|
||||
NetTracerLayerExpressionInfo lb_info = NetTracerLayerExpressionInfo::compile (lb);
|
||||
tech->add (NetTracerConnectionInfo (la_info, via_info, lb_info));
|
||||
ext::NetTracerLayerExpressionInfo la_info = ext::NetTracerLayerExpressionInfo::compile (la);
|
||||
ext::NetTracerLayerExpressionInfo via_info = ext::NetTracerLayerExpressionInfo::compile (via);
|
||||
ext::NetTracerLayerExpressionInfo lb_info = ext::NetTracerLayerExpressionInfo::compile (lb);
|
||||
tech->add (ext::NetTracerConnectionInfo (la_info, via_info, lb_info));
|
||||
}
|
||||
|
||||
static void def_symbol (NetTracerTechnologyComponent *tech, const std::string &name, const std::string &expr)
|
||||
static void def_symbol (ext::NetTracerTechnologyComponent *tech, const std::string &name, const std::string &expr)
|
||||
{
|
||||
tech->add_symbol (NetTracerSymbolInfo (db::LayerProperties (name), expr));
|
||||
tech->add_symbol (ext::NetTracerSymbolInfo (db::LayerProperties (name), expr));
|
||||
}
|
||||
|
||||
gsi::Class<NetTracerTechnologyComponent> decl_NetTracerTechnology ("NetTracerTechnology",
|
||||
gsi::Class<lay::TechnologyComponent> &decl_layTechnologyComponent ();
|
||||
|
||||
gsi::Class<ext::NetTracerTechnologyComponent> decl_NetTracerTechnology (decl_layTechnologyComponent (), "NetTracerTechnology",
|
||||
gsi::method_ext ("connection", &def_connection2, gsi::arg("a"), gsi::arg("b"),
|
||||
"@brief Defines a connection between two materials\n"
|
||||
"See the class description for details about this method."
|
||||
|
|
@ -194,90 +201,90 @@ gsi::Class<NetTracerTechnologyComponent> decl_NetTracerTechnology ("NetTracerTec
|
|||
"This class has been introduced in version 0.25.\n"
|
||||
);
|
||||
|
||||
static void trace1 (NetTracer *net_tracer, const NetTracerTechnologyComponent &tech, const db::Layout &layout, const db::Cell &cell, const db::Point &start_point, unsigned int start_layer)
|
||||
static void trace1 (ext::NetTracer *net_tracer, const ext::NetTracerTechnologyComponent &tech, const db::Layout &layout, const db::Cell &cell, const db::Point &start_point, unsigned int start_layer)
|
||||
{
|
||||
NetTracerData tracer_data = tech.get_tracer_data (layout);
|
||||
ext::NetTracerData tracer_data = tech.get_tracer_data (layout);
|
||||
net_tracer->trace (layout, cell, start_point, start_layer, tracer_data);
|
||||
}
|
||||
|
||||
static void trace2 (NetTracer *net_tracer, const NetTracerTechnologyComponent &tech, const db::Layout &layout, const db::Cell &cell, const db::Point &start_point, unsigned int start_layer, const db::Point &stop_point, unsigned int stop_layer)
|
||||
static void trace2 (ext::NetTracer *net_tracer, const ext::NetTracerTechnologyComponent &tech, const db::Layout &layout, const db::Cell &cell, const db::Point &start_point, unsigned int start_layer, const db::Point &stop_point, unsigned int stop_layer)
|
||||
{
|
||||
NetTracerData tracer_data = tech.get_tracer_data (layout);
|
||||
ext::NetTracerData tracer_data = tech.get_tracer_data (layout);
|
||||
net_tracer->trace (layout, cell, start_point, start_layer, stop_point, stop_layer, tracer_data);
|
||||
}
|
||||
|
||||
static NetTracerData get_tracer_data_from_cv (const lay::CellViewRef &cv)
|
||||
static ext::NetTracerData get_tracer_data_from_cv (const lay::CellViewRef &cv)
|
||||
{
|
||||
const lay::Technology *tech = cv->technology ();
|
||||
tl_assert (tech != 0);
|
||||
|
||||
const NetTracerTechnologyComponent *tech_component = dynamic_cast <const NetTracerTechnologyComponent *> (tech->component_by_name (net_tracer_component_name));
|
||||
const ext::NetTracerTechnologyComponent *tech_component = dynamic_cast <const ext::NetTracerTechnologyComponent *> (tech->component_by_name (ext::net_tracer_component_name));
|
||||
tl_assert (tech_component != 0);
|
||||
|
||||
return tech_component->get_tracer_data (cv->layout ());
|
||||
}
|
||||
|
||||
static void trace1_cv (NetTracer *net_tracer, const lay::CellViewRef &cv, const db::Point &start_point, unsigned int start_layer)
|
||||
static void trace1_cv (ext::NetTracer *net_tracer, const lay::CellViewRef &cv, const db::Point &start_point, unsigned int start_layer)
|
||||
{
|
||||
NetTracerData tracer_data = get_tracer_data_from_cv (cv);
|
||||
ext::NetTracerData tracer_data = get_tracer_data_from_cv (cv);
|
||||
net_tracer->trace (cv->layout (), *cv.cell (), start_point, start_layer, tracer_data);
|
||||
}
|
||||
|
||||
static void trace2_cv (NetTracer *net_tracer, const lay::CellViewRef &cv, const db::Point &start_point, unsigned int start_layer, const db::Point &stop_point, unsigned int stop_layer)
|
||||
static void trace2_cv (ext::NetTracer *net_tracer, const lay::CellViewRef &cv, const db::Point &start_point, unsigned int start_layer, const db::Point &stop_point, unsigned int stop_layer)
|
||||
{
|
||||
NetTracerData tracer_data = get_tracer_data_from_cv (cv);
|
||||
ext::NetTracerData tracer_data = get_tracer_data_from_cv (cv);
|
||||
net_tracer->trace (cv->layout (), *cv.cell (), start_point, start_layer, stop_point, stop_layer, tracer_data);
|
||||
}
|
||||
|
||||
static NetTracerData get_tracer_data_from_tech (const std::string &tech_name, const db::Layout &layout)
|
||||
static ext::NetTracerData get_tracer_data_from_tech (const std::string &tech_name, const db::Layout &layout)
|
||||
{
|
||||
const lay::Technology *tech = lay::Technologies::instance ()->technology_by_name (tech_name);
|
||||
tl_assert (tech != 0);
|
||||
|
||||
const NetTracerTechnologyComponent *tech_component = dynamic_cast <const NetTracerTechnologyComponent *> (tech->component_by_name (net_tracer_component_name));
|
||||
const ext::NetTracerTechnologyComponent *tech_component = dynamic_cast <const ext::NetTracerTechnologyComponent *> (tech->component_by_name (ext::net_tracer_component_name));
|
||||
tl_assert (tech_component != 0);
|
||||
|
||||
return tech_component->get_tracer_data (layout);
|
||||
}
|
||||
|
||||
static void trace1_tn (NetTracer *net_tracer, const std::string &tech, const db::Layout &layout, const db::Cell &cell, const db::Point &start_point, unsigned int start_layer)
|
||||
static void trace1_tn (ext::NetTracer *net_tracer, const std::string &tech, const db::Layout &layout, const db::Cell &cell, const db::Point &start_point, unsigned int start_layer)
|
||||
{
|
||||
NetTracerData tracer_data = get_tracer_data_from_tech (tech, layout);
|
||||
ext::NetTracerData tracer_data = get_tracer_data_from_tech (tech, layout);
|
||||
net_tracer->trace (layout, cell, start_point, start_layer, tracer_data);
|
||||
}
|
||||
|
||||
static void trace2_tn (NetTracer *net_tracer, const std::string &tech, const db::Layout &layout, const db::Cell &cell, const db::Point &start_point, unsigned int start_layer, const db::Point &stop_point, unsigned int stop_layer)
|
||||
static void trace2_tn (ext::NetTracer *net_tracer, const std::string &tech, const db::Layout &layout, const db::Cell &cell, const db::Point &start_point, unsigned int start_layer, const db::Point &stop_point, unsigned int stop_layer)
|
||||
{
|
||||
NetTracerData tracer_data = get_tracer_data_from_tech (tech, layout);
|
||||
ext::NetTracerData tracer_data = get_tracer_data_from_tech (tech, layout);
|
||||
net_tracer->trace (layout, cell, start_point, start_layer, stop_point, stop_layer, tracer_data);
|
||||
}
|
||||
|
||||
gsi::Class<NetTracerShape> decl_NetElement ("NetElement",
|
||||
gsi::method ("trans", &NetTracerShape::trans,
|
||||
gsi::Class<ext::NetTracerShape> decl_NetElement ("NetElement",
|
||||
gsi::method ("trans", &ext::NetTracerShape::trans,
|
||||
"@brief Gets the transformation to apply for rendering the shape in the original top cell\n"
|
||||
"See the class description for more details about this attribute."
|
||||
) +
|
||||
gsi::method ("shape", (const db::Shape &(NetTracerShape::*) () const) &NetTracerShape::shape,
|
||||
gsi::method ("shape", (const db::Shape &(ext::NetTracerShape::*) () const) &ext::NetTracerShape::shape,
|
||||
"@brief Gets the shape that makes up this net element\n"
|
||||
"See the class description for more details about this attribute."
|
||||
) +
|
||||
#if 0
|
||||
gsi::method ("is_valid?", &NetTracerShape::is_valid,
|
||||
gsi::method ("is_valid?", &ext::NetTracerShape::is_valid,
|
||||
"@brief Gets a value indicating whether the shape is valid\n"
|
||||
"Currently this flag is not used."
|
||||
) +
|
||||
gsi::method ("is_pseudo?", &NetTracerShape::is_pseudo,
|
||||
gsi::method ("is_pseudo?", &ext::NetTracerShape::is_pseudo,
|
||||
"@brief Gets a value indicating whether the shape is a pseudo shape\n"
|
||||
"Currently this flag is not used."
|
||||
) +
|
||||
#endif
|
||||
gsi::method ("cell_index", &NetTracerShape::cell_index,
|
||||
gsi::method ("cell_index", &ext::NetTracerShape::cell_index,
|
||||
"@brief Gets the index of the cell the shape is inside"
|
||||
) +
|
||||
gsi::method ("layer", &NetTracerShape::layer,
|
||||
gsi::method ("layer", &ext::NetTracerShape::layer,
|
||||
"@brief Gets the index of the layer the shape is on"
|
||||
) +
|
||||
gsi::method ("bbox", &NetTracerShape::bbox,
|
||||
gsi::method ("bbox", &ext::NetTracerShape::bbox,
|
||||
"@brief Delivers the bounding box of the shape as seen from the original top cell"
|
||||
),
|
||||
"@brief A net element for the \\NetTracer net tracing facility\n"
|
||||
|
|
@ -297,7 +304,7 @@ gsi::Class<NetTracerShape> decl_NetElement ("NetElement",
|
|||
"This class has been introduced in version 0.25.\n"
|
||||
);
|
||||
|
||||
gsi::Class<NetTracer> decl_NetTracer ("NetTracer",
|
||||
gsi::Class<ext::NetTracer> decl_NetTracer ("NetTracer",
|
||||
gsi::method_ext ("trace", &trace1, gsi::arg ("tech"), gsi::arg ("layout"), gsi::arg ("cell"), gsi::arg ("start_point"), gsi::arg ("start_layer"),
|
||||
"@brief Runs a net extraction\n"
|
||||
"\n"
|
||||
|
|
@ -353,23 +360,23 @@ gsi::Class<NetTracer> decl_NetTracer ("NetTracer",
|
|||
"This method behaves identical as the version with a technology, layout and cell object, except that it will take these "
|
||||
"from the cellview specified."
|
||||
) +
|
||||
gsi::iterator ("each_element", &NetTracer::begin, &NetTracer::end,
|
||||
gsi::iterator ("each_element", &ext::NetTracer::begin, &ext::NetTracer::end,
|
||||
"@brief Iterates over the elements found during extraction\n"
|
||||
"The elements are available only after the extraction has been performed."
|
||||
) +
|
||||
gsi::method ("num_elements", &NetTracer::size,
|
||||
gsi::method ("num_elements", &ext::NetTracer::size,
|
||||
"@brief Returns the number of elements found during extraction\n"
|
||||
"This attribute is useful only after the extraction has been performed."
|
||||
) +
|
||||
gsi::method ("clear", &NetTracer::clear,
|
||||
gsi::method ("clear", &ext::NetTracer::clear,
|
||||
"@brief Clears the data from the last extraction\n"
|
||||
) +
|
||||
gsi::method ("name", &NetTracer::name,
|
||||
gsi::method ("name", &ext::NetTracer::name,
|
||||
"@brief Returns the name of the net found during extraction\n"
|
||||
"The net name is extracted from labels found during the extraction. "
|
||||
"This attribute is useful only after the extraction has been performed."
|
||||
) +
|
||||
gsi::method ("incomplete?", &NetTracer::incomplete,
|
||||
gsi::method ("incomplete?", &ext::NetTracer::incomplete,
|
||||
"@brief Returns a value indicating whether the net is incomplete\n"
|
||||
"A net may be incomplete if the extraction has been stopped by the user for example. "
|
||||
"This attribute is useful only after the extraction has been performed."
|
||||
|
|
|
|||
|
|
@ -0,0 +1,318 @@
|
|||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "gsiDecl.h"
|
||||
#include "layTechnology.h"
|
||||
#include "tlXMLWriter.h"
|
||||
#include "tlXMLParser.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
||||
static std::vector<std::string> technology_names ()
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t) {
|
||||
names.push_back (t->name ());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
static lay::Technology *technology_by_name (const std::string &name)
|
||||
{
|
||||
return lay::Technologies::instance ()->technology_by_name (name);
|
||||
}
|
||||
|
||||
static lay::Technology *create_technology (const std::string &name)
|
||||
{
|
||||
lay::Technology *tech = new lay::Technology ();
|
||||
tech->set_name (name);
|
||||
lay::Technologies::instance ()->add (tech);
|
||||
return tech;
|
||||
}
|
||||
|
||||
static void remove_technology (const std::string &name)
|
||||
{
|
||||
lay::Technologies::instance ()->remove (name);
|
||||
}
|
||||
|
||||
static bool has_technology (const std::string &name)
|
||||
{
|
||||
return lay::Technologies::instance ()->has_technology (name);
|
||||
}
|
||||
|
||||
static std::string technologies_to_xml ()
|
||||
{
|
||||
return lay::Technologies::instance ()->to_xml ();
|
||||
}
|
||||
|
||||
static void technologies_from_xml (const std::string &s)
|
||||
{
|
||||
lay::Technologies::instance ()->load_from_xml (s);
|
||||
}
|
||||
|
||||
static lay::Technology technology_from_xml (const std::string &s)
|
||||
{
|
||||
lay::Technology tech;
|
||||
tl::XMLStringSource source (s);
|
||||
tl::XMLStruct<lay::Technology> xml_struct ("technology", lay::Technology::xml_elements ());
|
||||
xml_struct.parse (source, tech);
|
||||
return tech;
|
||||
}
|
||||
|
||||
static std::string technology_to_xml (const lay::Technology *tech)
|
||||
{
|
||||
if (! tech) {
|
||||
return std::string ();
|
||||
} else {
|
||||
tl::OutputStringStream os;
|
||||
tl::XMLStruct<lay::Technology> xml_struct ("technology", lay::Technology::xml_elements ());
|
||||
tl::OutputStream oss (os);
|
||||
xml_struct.write (oss, *tech);
|
||||
return os.string ();
|
||||
}
|
||||
}
|
||||
|
||||
static lay::TechnologyComponent *get_component (lay::Technology *tech, const std::string &name)
|
||||
{
|
||||
return tech->component_by_name (name);
|
||||
}
|
||||
|
||||
static std::vector<std::string> get_component_names (const lay::Technology *tech)
|
||||
{
|
||||
return tech->component_names ();
|
||||
}
|
||||
|
||||
gsi::Class<lay::TechnologyComponent> technology_component_decl ("TechnologyComponent",
|
||||
gsi::method ("name", &lay::TechnologyComponent::name,
|
||||
"@brief Gets the formal name of the technology component\n"
|
||||
"This is the name by which the component can be obtained from a technology using "
|
||||
"\\Technology#component."
|
||||
) +
|
||||
gsi::method ("description", &lay::TechnologyComponent::description,
|
||||
"@brief Gets the human-readable description string of the technology component\n"
|
||||
),
|
||||
"@brief A part of a technology definition\n"
|
||||
"Technology components extend technology definitions (class \\Technology) by "
|
||||
"specialized subfeature definitions. For example, the net tracer supplies "
|
||||
"it's technology-dependent specification through a technology component called "
|
||||
"\\NetTracerTechnology.\n"
|
||||
"\n"
|
||||
"Components are managed within technologies and can be accessed from a technology "
|
||||
"using \\Technology#component.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.25."
|
||||
);
|
||||
|
||||
LAYBASIC_PUBLIC gsi::Class<lay::TechnologyComponent> &decl_layTechnologyComponent () { return technology_component_decl; }
|
||||
|
||||
gsi::Class<lay::Technology> technology_decl ("Technology",
|
||||
gsi::method ("name", &lay::Technology::name,
|
||||
"@brief Gets the name of the technology"
|
||||
) +
|
||||
gsi::method ("name=", &lay::Technology::set_name, gsi::arg ("name"),
|
||||
"@brief Sets the name of the technology"
|
||||
) +
|
||||
gsi::method ("base_path", &lay::Technology::base_path,
|
||||
"@brief Gets the base path of the technology\n"
|
||||
"\n"
|
||||
"The base path is the effective path where files are read from if their "
|
||||
"file path is a relative one. If the explicit path is set (see \\explicit_base_path=), it is\n"
|
||||
"used. If not, the default path is used. The default path is the one from which\n"
|
||||
"a technology file was imported. The explicit one is the one that is specified\n"
|
||||
"explicitly with \\explicit_base_path=.\n"
|
||||
) +
|
||||
gsi::method ("default_base_path", &lay::Technology::default_base_path,
|
||||
"@brief Gets the default base path\n"
|
||||
"\n"
|
||||
"See \\base_path for details about the default base path.\n"
|
||||
) +
|
||||
gsi::method ("default_base_path=", &lay::Technology::set_default_base_path, gsi::arg ("path"),
|
||||
"@hide\n" // only for testing
|
||||
) +
|
||||
gsi::method ("correct_path", &lay::Technology::correct_path, gsi::arg ("path"),
|
||||
"@brief Makes a file path relative to the base path if one is specified\n"
|
||||
"\n"
|
||||
"This method turns an absolute path into one relative to the base path. "
|
||||
"Only files below the base path will be made relative. Files above or beside "
|
||||
"won't be made relative.\n"
|
||||
"\n"
|
||||
"See \\base_path for details about the default base path.\n"
|
||||
) +
|
||||
gsi::method ("eff_path", &lay::Technology::build_effective_path, gsi::arg ("path"),
|
||||
"@brief Makes a file path relative to the base path if one is specified\n"
|
||||
"\n"
|
||||
"This method will return the actual path for a file from the file's path. "
|
||||
"If the input path is a relative one, it will be made absolute by using the "
|
||||
"base path.\n"
|
||||
"\n"
|
||||
"See \\base_path for details about the default base path.\n"
|
||||
) +
|
||||
gsi::method ("explicit_base_path", &lay::Technology::explicit_base_path,
|
||||
"@brief Gets the explicit base path\n"
|
||||
"\n"
|
||||
"See \\base_path for details about the explicit base path.\n"
|
||||
) +
|
||||
gsi::method ("explicit_base_path=", &lay::Technology::set_explicit_base_path, gsi::arg ("path"),
|
||||
"@brief Sets the explicit base path\n"
|
||||
"\n"
|
||||
"See \\base_path for details about the explicit base path.\n"
|
||||
) +
|
||||
gsi::method ("description", &lay::Technology::description,
|
||||
"@brief Gets the description\n"
|
||||
"\n"
|
||||
"The technology description is shown to the user in technology selection dialogs and for "
|
||||
"display purposes."
|
||||
) +
|
||||
gsi::method ("description=", &lay::Technology::set_description, gsi::arg ("description"),
|
||||
"@brief Sets the description\n"
|
||||
) +
|
||||
gsi::method ("dbu", &lay::Technology::dbu,
|
||||
"@brief Gets the default database unit\n"
|
||||
"\n"
|
||||
"The default database unit is the one used when creating a layout for example."
|
||||
) +
|
||||
gsi::method ("dbu=", &lay::Technology::set_dbu, gsi::arg ("dbu"),
|
||||
"@brief Sets the default database unit\n"
|
||||
) +
|
||||
gsi::method ("layer_properties_file", &lay::Technology::layer_properties_file,
|
||||
"@brief Gets the path of the layer properties file\n"
|
||||
"\n"
|
||||
"If empty, no layer properties file is associated with the technology. "
|
||||
"If non-empty, this path will be corrected by the base path (see \\correct_path) and "
|
||||
"this layer properties file will be loaded for layouts with this technology."
|
||||
) +
|
||||
gsi::method ("layer_properties_file=", &lay::Technology::set_layer_properties_file, gsi::arg ("file"),
|
||||
"@brief Sets the path of the layer properties file\n"
|
||||
"\n"
|
||||
"See \\layer_properties_file for details about this property."
|
||||
) +
|
||||
gsi::method ("eff_layer_properties_file", &lay::Technology::eff_layer_properties_file,
|
||||
"@brief Gets the effective path of the layer properties file\n"
|
||||
) +
|
||||
gsi::method ("add_other_layers?", &lay::Technology::add_other_layers,
|
||||
"@brief Gets the flag indicating whether to add other layers to the layer properties\n"
|
||||
) +
|
||||
gsi::method ("add_other_layers=", &lay::Technology::set_add_other_layers, gsi::arg ("add"),
|
||||
"@brief Sets the flag indicating whether to add other layers to the layer properties\n"
|
||||
) +
|
||||
gsi::method ("load_layout_options", &lay::Technology::load_layout_options,
|
||||
"@brief Gets the layout reader options\n"
|
||||
"\n"
|
||||
"This method returns the layout reader options that are used when reading layouts "
|
||||
"with this technology.\n"
|
||||
"\n"
|
||||
"Change the reader options by modifying the object and using the setter to change it:\n"
|
||||
"\n"
|
||||
"@code\n"
|
||||
"opt = tech.load_layout_options\n"
|
||||
"opt.dxf_dbu = 2.5\n"
|
||||
"tech.load_layout_options = opt\n"
|
||||
"@/code\n"
|
||||
) +
|
||||
gsi::method ("load_layout_options=", &lay::Technology::set_load_layout_options, gsi::arg ("options"),
|
||||
"@brief Sets the layout reader options\n"
|
||||
"\n"
|
||||
"See \\load_layout_options for a description of this property.\n"
|
||||
) +
|
||||
gsi::method ("save_layout_options", &lay::Technology::save_layout_options,
|
||||
"@brief Gets the layout writer options\n"
|
||||
"\n"
|
||||
"This method returns the layout writer options that are used when writing layouts "
|
||||
"with this technology.\n"
|
||||
"\n"
|
||||
"Change the reader options by modifying the object and using the setter to change it:\n"
|
||||
"\n"
|
||||
"@code\n"
|
||||
"opt = tech.save_layout_options\n"
|
||||
"opt.dbu = 0.01\n"
|
||||
"tech.save_layout_options = opt\n"
|
||||
"@/code\n"
|
||||
) +
|
||||
gsi::method ("save_layout_options=", &lay::Technology::set_save_layout_options, gsi::arg ("options"),
|
||||
"@brief Sets the layout writer options\n"
|
||||
"\n"
|
||||
"See \\save_layout_options for a description of this property.\n"
|
||||
) +
|
||||
gsi::method ("load", &lay::Technology::load, gsi::arg ("file"),
|
||||
"@brief Loads the technology definition from a file\n"
|
||||
) +
|
||||
gsi::method ("load", &lay::Technology::save, gsi::arg ("file"),
|
||||
"@brief Saves the technology definition to a file\n"
|
||||
) +
|
||||
gsi::method ("technology_names", &technology_names,
|
||||
"@brief Gets a list of technology names defined in the system\n"
|
||||
) +
|
||||
gsi::method ("technology_by_name", &technology_by_name, gsi::arg ("name"),
|
||||
"@brief Gets the technology object for a given name\n"
|
||||
) +
|
||||
gsi::method ("has_technology?", &has_technology, gsi::arg ("name"),
|
||||
"@brief Returns a value indicating whether there is a technology with this name\n"
|
||||
) +
|
||||
gsi::method ("create_technology", &create_technology, gsi::arg ("name"),
|
||||
"@brief Creates a new (empty) technology with the given name\n"
|
||||
"\n"
|
||||
"This method returns a reference to the new technology."
|
||||
) +
|
||||
gsi::method ("remove_technology", &remove_technology, gsi::arg ("name"),
|
||||
"@brief Removes the technology with the given name\n"
|
||||
) +
|
||||
gsi::method ("technologies_to_xml", &technologies_to_xml,
|
||||
"@brief Returns a XML representation of all technologies registered in the system\n"
|
||||
"\n"
|
||||
"\\technologies_from_xml can be used to restore the technology definitions. "
|
||||
"This method is provided mainly as a substitute for the pre-0.25 way of accessing "
|
||||
"technology data through the 'technology-data' configuration parameter. This method "
|
||||
"will return the equivalent string."
|
||||
) +
|
||||
gsi::method_ext ("to_xml", &technology_to_xml,
|
||||
"@brief Returns a XML representation of this technolog\n"
|
||||
"\n"
|
||||
"\\technology_from_xml can be used to restore the technology definition."
|
||||
) +
|
||||
gsi::method ("technologies_from_xml", &technologies_from_xml, gsi::arg ("xml"),
|
||||
"@brief Loads the technologies from a XML representation\n"
|
||||
"\n"
|
||||
"See \\technologies_to_xml for details. This method is the corresponding setter."
|
||||
) +
|
||||
gsi::method ("technology_from_xml", &technology_from_xml, gsi::arg ("xml"),
|
||||
"@brief Loads the technology from a XML representation\n"
|
||||
"\n"
|
||||
"See \\technology_to_xml for details."
|
||||
) +
|
||||
gsi::method_ext ("component_names", &get_component_names,
|
||||
"@brief Gets the names of all components available for \\component"
|
||||
) +
|
||||
gsi::method_ext ("component", &get_component, gsi::arg ("name"),
|
||||
"@brief Gets the technology component with the given name\n"
|
||||
"The names are unique system identifiers. For all names, use \\component_names."
|
||||
),
|
||||
"@brief Represents a technology\n"
|
||||
"\n"
|
||||
"This class represents one technology from a set of technologies. The set of technologies "
|
||||
"available in the system can be obtained with \\technology_names. Individual technology "
|
||||
"definitions are returned with \\technology_by_name. Use \\create_technology to register "
|
||||
"new technologies and \\remove_technology to delete technologies.\n"
|
||||
"\n"
|
||||
"The Technology class has been introduced in version 0.25.\n"
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
#include "tlString.h"
|
||||
#include "tlEvents.h"
|
||||
#include "tlXMLParser.h"
|
||||
#include "tlTypeTraits.h"
|
||||
#include "dbStreamLayers.h"
|
||||
#include "dbLoadLayoutOptions.h"
|
||||
#include "dbSaveLayoutOptions.h"
|
||||
|
|
@ -821,5 +822,16 @@ public:
|
|||
|
||||
}
|
||||
|
||||
namespace tl
|
||||
{
|
||||
/**
|
||||
* @brief Type traits
|
||||
*/
|
||||
template <> struct type_traits <lay::TechnologyComponent> : public type_traits<void> {
|
||||
typedef tl::false_tag has_default_constructor;
|
||||
typedef tl::false_tag has_copy_constructor;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,8 @@ SOURCES = \
|
|||
layLineStylePalette.cc \
|
||||
layEditLineStylesForm.cc \
|
||||
layEditLineStyleWidget.cc \
|
||||
layBackgroundAwareTreeStyle.cc
|
||||
layBackgroundAwareTreeStyle.cc \
|
||||
gsiDeclLayTechnologies.cc
|
||||
|
||||
HEADERS = \
|
||||
gtf.h \
|
||||
|
|
|
|||
|
|
@ -110,32 +110,58 @@ split_path (const std::string &path, std::vector <std::string> &pc)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static std::vector<std::string> s_klayout_path;
|
||||
static bool s_klayout_path_set = false;
|
||||
|
||||
void
|
||||
set_klayout_path (const std::vector<std::string> &path)
|
||||
{
|
||||
s_klayout_path = path;
|
||||
s_klayout_path_set = true;
|
||||
}
|
||||
|
||||
void
|
||||
reset_klayout_path ()
|
||||
{
|
||||
s_klayout_path.clear ();
|
||||
s_klayout_path_set = false;
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
get_klayout_path ()
|
||||
{
|
||||
std::vector<std::string> klayout_path;
|
||||
if (s_klayout_path_set) {
|
||||
|
||||
// generate the klayout path: the first component is always the appdata path
|
||||
klayout_path.push_back (get_appdata_path ());
|
||||
return s_klayout_path;
|
||||
|
||||
} else {
|
||||
|
||||
std::vector<std::string> klayout_path;
|
||||
|
||||
// generate the klayout path: the first component is always the appdata path
|
||||
klayout_path.push_back (get_appdata_path ());
|
||||
#ifdef _WIN32
|
||||
wchar_t *env = _wgetenv (L"KLAYOUT_PATH");
|
||||
if (env) {
|
||||
split_path (tl::to_string (QString ((const QChar *) env)), klayout_path);
|
||||
} else {
|
||||
get_other_system_paths (klayout_path);
|
||||
klayout_path.push_back (get_inst_path ());
|
||||
}
|
||||
wchar_t *env = _wgetenv (L"KLAYOUT_PATH");
|
||||
if (env) {
|
||||
split_path (tl::to_string (QString ((const QChar *) env)), klayout_path);
|
||||
} else {
|
||||
get_other_system_paths (klayout_path);
|
||||
klayout_path.push_back (get_inst_path ());
|
||||
}
|
||||
#else
|
||||
char *env = getenv ("KLAYOUT_PATH");
|
||||
if (env) {
|
||||
split_path (tl::system_to_string (env), klayout_path);
|
||||
} else {
|
||||
get_other_system_paths (klayout_path);
|
||||
klayout_path.push_back (get_inst_path ());
|
||||
}
|
||||
char *env = getenv ("KLAYOUT_PATH");
|
||||
if (env) {
|
||||
split_path (tl::system_to_string (env), klayout_path);
|
||||
} else {
|
||||
get_other_system_paths (klayout_path);
|
||||
klayout_path.push_back (get_inst_path ());
|
||||
}
|
||||
#endif
|
||||
|
||||
return klayout_path;
|
||||
return klayout_path;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,20 @@ TL_PUBLIC std::string get_inst_path ();
|
|||
*/
|
||||
TL_PUBLIC std::vector<std::string> get_klayout_path ();
|
||||
|
||||
/**
|
||||
* @brief Sets the KLayout path
|
||||
* This method is mainly used for test purposes. It will force the application
|
||||
* is use a specific KLAYOUT_PATH. Use reset_klayout_path to restore the
|
||||
* default behavior.
|
||||
*/
|
||||
TL_PUBLIC void set_klayout_path (const std::vector<std::string> &path);
|
||||
|
||||
/**
|
||||
* @brief Resets the KLayout path
|
||||
* See "set_klayout_path" for a description.
|
||||
*/
|
||||
TL_PUBLIC void reset_klayout_path ();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ void run_pythontest (ut::TestBase *_this, const std::string &fn)
|
|||
}
|
||||
|
||||
#define PYTHONTEST(n, file) \
|
||||
TEST(2_##n) { run_pythontest(_this, file); }
|
||||
TEST(n) { run_pythontest(_this, file); }
|
||||
|
||||
PYTHONTEST (dbLayoutTest, "dbLayoutTest.py")
|
||||
PYTHONTEST (dbRegionTest, "dbRegionTest.py")
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ void run_rubytest (ut::TestBase * /*_this*/, const std::string &fn)
|
|||
}
|
||||
|
||||
#define RUBYTEST(n, file) \
|
||||
TEST(2_##n) { run_rubytest(_this, file); }
|
||||
TEST(n) { run_rubytest(_this, file); }
|
||||
|
||||
RUBYTEST (antTest, "antTest.rb")
|
||||
RUBYTEST (dbBooleanTest, "dbBooleanTest.rb")
|
||||
|
|
@ -123,6 +123,7 @@ RUBYTEST (layLayoutView, "layLayoutView.rb")
|
|||
RUBYTEST (layMarkers, "layMarkers.rb")
|
||||
RUBYTEST (layMenuTest, "layMenuTest.rb")
|
||||
RUBYTEST (laySession, "laySession.rb")
|
||||
RUBYTEST (layTechnologies, "layTechnologies.rb")
|
||||
#if defined(HAVE_QTBINDINGS)
|
||||
RUBYTEST (qtbinding, "qtbinding.rb")
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "pya.h"
|
||||
#include "tlStaticObjects.h"
|
||||
#include "tlTimer.h"
|
||||
#include "tlSystemPaths.h"
|
||||
#include "layApplication.h"
|
||||
#include "gsiExpression.h"
|
||||
#include "gsiExternalMain.h"
|
||||
|
|
@ -762,6 +763,9 @@ main_cont (int argc, char **argv)
|
|||
pya::PythonInterpreter::initialize ();
|
||||
gsi::initialize_external ();
|
||||
|
||||
// No side effects
|
||||
tl::set_klayout_path (std::vector<std::string> ());
|
||||
|
||||
int ac = 2;
|
||||
static char av0[] = "unit_test";
|
||||
static char av1[] = "-z"; // don't show main window
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
$:.push(File::dirname($0))
|
||||
|
||||
load("test_prologue.rb")
|
||||
|
||||
class LAYTechnologies_TestClass < TestBase
|
||||
|
||||
def test_1
|
||||
|
||||
RBA::Technology::technologies_from_xml(<<END)
|
||||
<technologies>
|
||||
<technology>
|
||||
<name/>
|
||||
</technology>
|
||||
<technology>
|
||||
<name>MINE</name>
|
||||
</technology>
|
||||
</technologies>
|
||||
END
|
||||
assert_equal(RBA::Technology::technology_names.inspect, '["", "MINE"]')
|
||||
|
||||
s = RBA::Technology::technologies_to_xml
|
||||
RBA::Technology::technologies_from_xml("<technologies/>")
|
||||
assert_equal(RBA::Technology::technology_names.inspect, '[""]')
|
||||
RBA::Technology::technologies_from_xml(s)
|
||||
assert_equal(RBA::Technology::technology_names.inspect, '["", "MINE"]')
|
||||
|
||||
tech = RBA::Technology::technology_by_name("MINE")
|
||||
assert_equal(tech.name, "MINE")
|
||||
tech.name = "MINE2"
|
||||
assert_equal(tech.name, "MINE2")
|
||||
|
||||
assert_equal(RBA::Technology::technology_names.inspect, '["", "MINE2"]')
|
||||
|
||||
assert_equal(RBA::Technology::has_technology?("MINE"), false)
|
||||
assert_equal(RBA::Technology::has_technology?("MINE2"), true)
|
||||
tech = RBA::Technology::technology_by_name("MINE")
|
||||
assert_equal(tech != nil, true)
|
||||
assert_equal(tech.name, "")
|
||||
tech2 = RBA::Technology::technology_by_name("MINE2")
|
||||
assert_equal(tech != nil, true)
|
||||
|
||||
RBA::Technology::remove_technology("X")
|
||||
assert_equal(RBA::Technology::technology_names.inspect, '["", "MINE2"]')
|
||||
RBA::Technology::remove_technology("MINE2")
|
||||
assert_equal(RBA::Technology::technology_names.inspect, '[""]')
|
||||
|
||||
end
|
||||
|
||||
def test_2
|
||||
|
||||
tech = RBA::Technology::technology_from_xml(<<END)
|
||||
<technology>
|
||||
<name>X</name>
|
||||
</technology>
|
||||
END
|
||||
assert_equal(tech.name, "X")
|
||||
|
||||
tech.name = "Y"
|
||||
assert_equal(tech.name, "Y")
|
||||
|
||||
tech.description = "A big Y"
|
||||
assert_equal(tech.description, "A big Y")
|
||||
|
||||
tech.dbu = 5.0
|
||||
assert_equal(tech.dbu, 5.0)
|
||||
|
||||
tech.default_base_path = "/default/path"
|
||||
assert_equal(tech.default_base_path, "/default/path")
|
||||
assert_equal(tech.base_path, "/default/path")
|
||||
assert_equal(tech.correct_path("/default/path/myfile.xml"), "myfile.xml")
|
||||
assert_equal(tech.eff_path("myfile.xml"), "/default/path/myfile.xml")
|
||||
|
||||
tech.explicit_base_path = "/basic/path"
|
||||
assert_equal(tech.explicit_base_path, "/basic/path")
|
||||
assert_equal(tech.base_path, "/basic/path")
|
||||
assert_equal(tech.correct_path("/basic/path/myfile.xml"), "myfile.xml")
|
||||
assert_equal(tech.eff_path("myfile.xml"), "/basic/path/myfile.xml")
|
||||
|
||||
tech.layer_properties_file = "x.lyp"
|
||||
assert_equal(tech.layer_properties_file, "x.lyp")
|
||||
assert_equal(tech.eff_layer_properties_file, "/basic/path/x.lyp")
|
||||
|
||||
tech.add_other_layers = true
|
||||
assert_equal(tech.add_other_layers?, true)
|
||||
tech.add_other_layers = false
|
||||
assert_equal(tech.add_other_layers?, false)
|
||||
|
||||
opt = tech.load_layout_options
|
||||
opt.dxf_dbu = 2.5
|
||||
tech.load_layout_options = opt
|
||||
assert_equal(tech.load_layout_options.dxf_dbu, 2.5)
|
||||
opt = tech.save_layout_options
|
||||
opt.dbu = 0.125
|
||||
tech.save_layout_options = opt
|
||||
assert_equal(tech.save_layout_options.dbu, 0.125)
|
||||
|
||||
assert_equal(tech.component_names.size > 0, true)
|
||||
assert_equal(tech.component_names.find("connectivity") != nil, true)
|
||||
assert_equal(tech.component("connectivity").class.to_s, "RBA::NetTracerTechnology")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
Loading…
Reference in New Issue