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:
Matthias Koefferlein 2017-04-01 00:45:55 +02:00
parent 47aa38421a
commit 50df9e5b21
10 changed files with 552 additions and 63 deletions

View File

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

View File

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

View File

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

View File

@ -177,7 +177,8 @@ SOURCES = \
layLineStylePalette.cc \
layEditLineStylesForm.cc \
layEditLineStyleWidget.cc \
layBackgroundAwareTreeStyle.cc
layBackgroundAwareTreeStyle.cc \
gsiDeclLayTechnologies.cc
HEADERS = \
gtf.h \

View File

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

View File

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

View File

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

View File

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

View File

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

106
testdata/ruby/layTechnologies.rb vendored Normal file
View File

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