diff --git a/src/db/db/dbTestSupport.h b/src/db/db/dbTestSupport.h index 365d7e602..f6dd94803 100644 --- a/src/db/db/dbTestSupport.h +++ b/src/db/db/dbTestSupport.h @@ -58,7 +58,7 @@ enum NormalizationMode * @param tolerance A tolerance applied when comparing shapes in database units * The layout is normalized by writing to a file and reading back */ -void compare_layouts (tl::TestBase *_this, const db::Layout &layout, const std::string &au_file, NormalizationMode norm = WriteGDS2, db::Coord tolerance = 0); +void DB_PUBLIC compare_layouts (tl::TestBase *_this, const db::Layout &layout, const std::string &au_file, NormalizationMode norm = WriteGDS2, db::Coord tolerance = 0); /** * @brief Compares a layout with a golden layout file with layer mapping @@ -70,7 +70,7 @@ void compare_layouts (tl::TestBase *_this, const db::Layout &layout, const std:: * @param tolerance A tolerance applied when comparing shapes in database units * The layout is normalized by writing to a file and reading back */ -void compare_layouts (tl::TestBase *_this, const db::Layout &layout, const std::string &au_file, const db::LayerMap &lmap, bool read_all_others, NormalizationMode norm = WriteGDS2, db::Coord tolerance = 0); +void DB_PUBLIC compare_layouts (tl::TestBase *_this, const db::Layout &layout, const std::string &au_file, const db::LayerMap &lmap, bool read_all_others, NormalizationMode norm = WriteGDS2, db::Coord tolerance = 0); } diff --git a/src/db/unit_tests/dbExpression.cc b/src/db/unit_tests/dbExpression.cc new file mode 100644 index 000000000..9b43315fb --- /dev/null +++ b/src/db/unit_tests/dbExpression.cc @@ -0,0 +1,214 @@ + +/* + + 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 "tlExpression.h" +#include "tlUnitTest.h" +#include "dbBox.h" +#include "dbEdge.h" +#include "dbLayout.h" +#include "gsiDecl.h" +#include "dbLayerProperties.h" +#include "dbLayoutContextHandler.h" + +#include +#include + +// ref layout +TEST(1) +{ + db::Layout l; + l.dbu (0.05); + l.insert_layer (db::LayerProperties (1, 15)); + l.insert_layer (db::LayerProperties ("name")); + l.add_cell ("c1"); + l.add_cell ("c2"); + + tl::Eval e, ee; + db::LayoutContextHandler ctx (&l); + e.set_ctx_handler (&ctx); + tl::Variant v; + + bool error = false; + + v = e.parse ("1um").execute (); + EXPECT_EQ (v.to_string (), std::string ("20")); + v = e.parse ("1um2").execute (); + EXPECT_EQ (v.to_string (), std::string ("400")); + v = e.parse ("1micron").execute (); + EXPECT_EQ (v.to_string (), std::string ("20")); + v = e.parse ("1micron2").execute (); + EXPECT_EQ (v.to_string (), std::string ("400")); + v = e.parse ("1mic").execute (); + EXPECT_EQ (v.to_string (), std::string ("20")); + v = e.parse ("1mic2").execute (); + EXPECT_EQ (v.to_string (), std::string ("400")); + v = e.parse ("1m").execute (); + EXPECT_EQ (v.to_string (), std::string ("20000000")); + v = e.parse ("1m2/1e14").execute (); + EXPECT_EQ (v.to_string (), std::string ("4")); + v = e.parse ("1mm").execute (); + EXPECT_EQ (v.to_string (), std::string ("20000")); + v = e.parse ("1mm2").execute (); + EXPECT_EQ (v.to_string (), std::string ("400000000")); + v = e.parse ("50nm").execute (); + EXPECT_EQ (v.to_string (), std::string ("1")); + v = e.parse ("<1/15>").execute (); + EXPECT_EQ (v.to_string (), std::string ("0")); + v = e.parse ("< name >").execute (); + EXPECT_EQ (v.to_string (), std::string ("1")); + v = e.parse ("<'n' + 'ame'>").execute (); + EXPECT_EQ (v.to_string (), std::string ("1")); + v = e.parse ("<>").execute (); + EXPECT_EQ (v.to_string (), std::string ("0")); + v = e.parse ("<< c2 >>").execute (); + EXPECT_EQ (v.to_string (), std::string ("1")); + v = e.parse ("<<'c' + '2'>>").execute (); + EXPECT_EQ (v.to_string (), std::string ("1")); + + error = true; + try { + v = e.parse ("60nm").execute (); // not a multiple of DBU + error = false; + } catch (...) { } + EXPECT_EQ (error, true); + + error = true; + try { + v = ee.parse ("1 um").execute (); + error = false; + } catch (...) { } + EXPECT_EQ (error, true); + + error = true; + try { + v = e.parse ("<1/1>").execute (); + error = false; + } catch (...) { } + EXPECT_EQ (error, true); + + error = true; + try { + v = ee.parse ("<1/15>").execute (); + error = false; + } catch (...) { } + EXPECT_EQ (error, true); + + error = true; + try { + v = ee.parse ("<>").execute (); + error = false; + } catch (...) { } + EXPECT_EQ (error, true); + + error = true; + try { + v = e.parse ("<>").execute (); + error = false; + } catch (...) { } + EXPECT_EQ (error, true); +} + +// db objects as Variant payload +TEST(10) +{ + tl::Variant v; + v = tl::Variant::make_variant (db::Box (db::Point (0, 10), db::Point (20, 30))); + EXPECT_EQ (v.is_user (), true) + EXPECT_EQ (v.to_parsable_string (), "[box:(0,10;20,30)]"); + + std::string s = v.to_parsable_string () + "," + tl::Variant (15.0).to_parsable_string (); + tl::Variant vv; + tl::Extractor ex (s.c_str ()); + ex.read (vv); + ex.test (","); + ex.read (v); + EXPECT_EQ (vv.is_user (), true) + EXPECT_EQ (vv.to_parsable_string (), "[box:(0,10;20,30)]"); + EXPECT_EQ ((int)v.type_code (), (int)tl::Variant::t_double); + EXPECT_EQ (std::string(v.to_string()), "15"); +} + +// db objects as Variant payload - backward compatibility check +TEST(11) +{ + std::string s = "[box:(0,10;20,30)],##15"; + tl::Variant vv; + tl::Variant v; + tl::Extractor ex (s.c_str ()); + ex.read (vv); + ex.test (","); + ex.read (v); + EXPECT_EQ (vv.is_user (), true) + EXPECT_EQ (vv.to_parsable_string (), "[box:(0,10;20,30)]"); + EXPECT_EQ ((int)v.type_code (), (int)tl::Variant::t_double); + EXPECT_EQ (std::string(v.to_string()), "15"); +} + +// db objects as Variant payload - backward compatibility check +TEST(12) +{ + std::string s = "[Box:(0,10;20,30)],##15"; + tl::Variant vv; + tl::Variant v; + tl::Extractor ex (s.c_str ()); + ex.read (vv); + ex.test (","); + ex.read (v); + EXPECT_EQ (vv.is_user (), true) + EXPECT_EQ (vv.to_parsable_string (), "[box:(0,10;20,30)]"); + EXPECT_EQ ((int)v.type_code (), (int)tl::Variant::t_double); + EXPECT_EQ (std::string(v.to_string()), "15"); +} + +// db objects as Variant payload - backward compatibility check +TEST(13) +{ + std::string s = "[layer:1/0],##15"; + tl::Variant vv; + tl::Variant v; + tl::Extractor ex (s.c_str ()); + ex.read (vv); + ex.test (","); + ex.read (v); + EXPECT_EQ (vv.is_user (), true) + EXPECT_EQ (vv.to_parsable_string (), "[layer:1/0]"); + EXPECT_EQ ((int)v.type_code (), (int)tl::Variant::t_double); + EXPECT_EQ (std::string(v.to_string()), "15"); +} + +// db objects as Variant payload - backward compatibility check +TEST(14) +{ + std::string s = "[LayerInfo:1/0],##15"; + tl::Variant vv; + tl::Variant v; + tl::Extractor ex (s.c_str ()); + ex.read (vv); + ex.test (","); + ex.read (v); + EXPECT_EQ (vv.is_user (), true) + EXPECT_EQ (vv.to_parsable_string (), "[layer:1/0]"); + EXPECT_EQ ((int)v.type_code (), (int)tl::Variant::t_double); + EXPECT_EQ (std::string(v.to_string()), "15"); +} + diff --git a/src/db/unit_tests/unit_tests.pro b/src/db/unit_tests/unit_tests.pro index 2baaf0d73..48df8e9a6 100644 --- a/src/db/unit_tests/unit_tests.pro +++ b/src/db/unit_tests/unit_tests.pro @@ -18,6 +18,7 @@ SOURCES = \ dbCIFReader.cc \ dbClip.cc \ dbDXFReader.cc \ + dbExpression.cc \ dbEdge.cc \ dbEdgePair.cc \ dbEdgePairRelations.cc \ diff --git a/src/gsi/gsi.pro b/src/gsi/gsi.pro index 6e190ecd3..b36a8d105 100644 --- a/src/gsi/gsi.pro +++ b/src/gsi/gsi.pro @@ -1,7 +1,7 @@ TEMPLATE = subdirs -SUBDIRS = gsi gsi_test unit_tests +SUBDIRS = gsi unit_tests gsi_test.depends += gsi -unit_tests.depends += gsi gsi_test +unit_tests.depends += gsi diff --git a/src/gsi/unit_tests/gsiExpression.cc b/src/gsi/unit_tests/gsiExpression.cc index a1a36f2fe..464e487dd 100644 --- a/src/gsi/unit_tests/gsiExpression.cc +++ b/src/gsi/unit_tests/gsiExpression.cc @@ -24,8 +24,6 @@ #include "gsiExpression.h" #include "gsiDecl.h" #include "gsiTest.h" -#include "dbBox.h" -#include "dbEdge.h" #include "tlUnitTest.h" diff --git a/src/gsi/gsi_test/gsiTest.cc b/src/gsi/unit_tests/gsiTest.cc similarity index 99% rename from src/gsi/gsi_test/gsiTest.cc rename to src/gsi/unit_tests/gsiTest.cc index 8cfe1a603..a9b0f8e38 100644 --- a/src/gsi/gsi_test/gsiTest.cc +++ b/src/gsi/unit_tests/gsiTest.cc @@ -1050,7 +1050,8 @@ static gsi::Class decl_e ("E", gsi::method ("x=", &E::set_x) + gsi::method ("x", &E::get_x) + gsi::method ("bindme", &E::bindme) + - gsi::method ("inst_count", &E::inst_count) + gsi::method ("inst_count", &E::inst_count) + + gsi::method ("reset_inst", &E::reset_inst) ); static gsi::Class decl_f ("F", diff --git a/src/gsi/gsi_test/gsiTest.h b/src/gsi/unit_tests/gsiTest.h similarity index 100% rename from src/gsi/gsi_test/gsiTest.h rename to src/gsi/unit_tests/gsiTest.h diff --git a/src/gsi/unit_tests/unit_tests.pro b/src/gsi/unit_tests/unit_tests.pro index ef7b7770c..07f81a911 100644 --- a/src/gsi/unit_tests/unit_tests.pro +++ b/src/gsi/unit_tests/unit_tests.pro @@ -8,9 +8,13 @@ include($$PWD/../../lib_ut.pri) SOURCES = \ gsiExpression.cc \ + gsiTest.cc \ -INCLUDEPATH += $$TL_INC $$GSI_INC $$GSI_TEST_INC $$DB_INC -DEPENDPATH += $$TL_INC $$GSI_INC $$GSI_TEST_INC $$DB_INC +HEADERS += \ + gsiTest.h \ -LIBS += -L$$DESTDIR_UT -lklayout_tl -lklayout_gsi -lgsi_test -lklayout_db +INCLUDEPATH += $$TL_INC $$GSI_INC +DEPENDPATH += $$TL_INC $$GSI_INC + +LIBS += -L$$DESTDIR_UT -lklayout_tl -lklayout_gsi diff --git a/src/klayout.pri b/src/klayout.pri index 0607d16a2..61e18a286 100644 --- a/src/klayout.pri +++ b/src/klayout.pri @@ -15,9 +15,6 @@ LAYBASIC_INC = $$PWD/laybasic/laybasic GSIQT_INC = $$PWD/gsiqt -GSI_TEST_INC = $$PWD/gsi/gsi_test -UT_INC = $$PWD/ut - BD_INC = $$PWD/buddies/src/bd VERSION_INC = $$PWD/version diff --git a/src/klayout.pro b/src/klayout.pro index 9ef1f9a5d..2c4cbfff8 100644 --- a/src/klayout.pro +++ b/src/klayout.pro @@ -7,9 +7,7 @@ SUBDIRS = \ klayout_main \ unit_tests \ tl \ - gsi/gsi \ - gsi/gsi_test \ - gsi/unit_tests \ + gsi \ db \ rdb \ lym \ @@ -29,26 +27,25 @@ LANG_DEPENDS = equals(HAVE_RUBY, "1") { SUBDIRS += rba LANG_DEPENDS += rba - rba.depends += gsi/gsi gsi/gsi_test + rba.depends += gsi } else { SUBDIRS += rbastub - rbastub.depends += gsi/gsi + rbastub.depends += gsi LANG_DEPENDS += rbastub } equals(HAVE_PYTHON, "1") { SUBDIRS += pya LANG_DEPENDS += pya - pya-unit_tests.depends += gsi/gsi gsi/gsi_test + pya-unit_tests.depends += gsi } else { SUBDIRS += pyastub - pyastub.depends += gsi/gsi + pyastub.depends += gsi LANG_DEPENDS += pyastub } -gsi-gsi.depends += tl -gsi-gsi_test.depends += tl gsi/gsi -db.depends += gsi/gsi +gsi.depends += tl +db.depends += gsi rdb.depends += db laybasic.depends += rdb ant.depends += laybasic @@ -56,7 +53,7 @@ img.depends += laybasic edt.depends += laybasic drc.depends += rdb lym -lym.depends += gsi/gsi $$LANG_DEPENDS +lym.depends += gsi $$LANG_DEPENDS lay.depends += laybasic ant img edt lym ext.depends += lay lib.depends += db @@ -64,13 +61,10 @@ buddies.depends += db equals(HAVE_QTBINDINGS, "1") { SUBDIRS += gsiqt - gsiqt.depends += gsi/gsi + gsiqt.depends += gsi laybasic.depends += gsiqt } -# YES. It's gsi-unit_tests (for gsi/unit_tests) -gsi-unit_tests.depends += gsi/gsi_test - plugins.depends += lay ext lib klayout_main.depends += plugins drc diff --git a/src/lym/unit_tests/unit_tests.pro b/src/lym/unit_tests/unit_tests.pro index 01415fef6..9c62e03a9 100644 --- a/src/lym/unit_tests/unit_tests.pro +++ b/src/lym/unit_tests/unit_tests.pro @@ -9,8 +9,8 @@ include($$PWD/../../lib_ut.pri) SOURCES = \ lymBasicTests.cc \ -INCLUDEPATH += $$LYM_INC $$TL_INC $$DB_INC $$GSI_INC -DEPENDPATH += $$LYM_INC $$TL_INC $$DB_INC $$GSI_INC +INCLUDEPATH += $$LYM_INC $$TL_INC $$GSI_INC +DEPENDPATH += $$LYM_INC $$TL_INC $$GSI_INC -LIBS += -L$$DESTDIR_UT -lklayout_lym -lklayout_tl -lklayout_db -lklayout_gsi +LIBS += -L$$DESTDIR_UT -lklayout_lym -lklayout_tl -lklayout_gsi diff --git a/src/pya/unit_tests/pya.cc b/src/pya/unit_tests/pya.cc index 577d3546b..07a20f01c 100644 --- a/src/pya/unit_tests/pya.cc +++ b/src/pya/unit_tests/pya.cc @@ -24,7 +24,7 @@ #ifdef HAVE_PYTHON #include "pya.h" -#include "gsiTest.h" +#include "gsiDecl.h" #include "tlUnitTest.h" @@ -67,12 +67,12 @@ TEST (1) fn += "/testdata/python/basic.py"; try { pya::PythonInterpreter::instance ()->load_file (fn.c_str ()); - gsi_test::E::reset_inst (); + pya::PythonInterpreter::instance ()->eval_string ("pya.E.reset_inst()"); } catch (tl::ExitException &ex) { - gsi_test::E::reset_inst (); + pya::PythonInterpreter::instance ()->eval_string ("pya.E.reset_inst()"); EXPECT_EQ (ex.status (), 0); } catch (...) { - gsi_test::E::reset_inst (); + pya::PythonInterpreter::instance ()->eval_string ("pya.E.reset_inst()"); throw; } } diff --git a/src/pya/unit_tests/unit_tests.pro b/src/pya/unit_tests/unit_tests.pro index cadfe9a40..d7c5d6c9d 100644 --- a/src/pya/unit_tests/unit_tests.pro +++ b/src/pya/unit_tests/unit_tests.pro @@ -9,8 +9,8 @@ include($$PWD/../../lib_ut.pri) SOURCES = \ pya.cc -INCLUDEPATH += $$GSI_TEST_INC $$PYA_INC $$DB_INC $$TL_INC $$GSI_INC -DEPENDPATH += $$GSI_TEST_INC $$PYA_INC $$DB_INC $$TL_INC $$GSI_INC +INCLUDEPATH += $$PYA_INC $$DB_INC $$TL_INC $$GSI_INC +DEPENDPATH += $$PYA_INC $$DB_INC $$TL_INC $$GSI_INC -LIBS += -L$$DESTDIR_UT -lgsi_test -lklayout_db -lklayout_tl -lklayout_gsi +LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi diff --git a/src/rba/unit_tests/rba.cc b/src/rba/unit_tests/rba.cc index fe7bf698c..b650cdab9 100644 --- a/src/rba/unit_tests/rba.cc +++ b/src/rba/unit_tests/rba.cc @@ -24,7 +24,7 @@ #ifdef HAVE_RUBY #include "rba.h" -#include "gsiTest.h" +#include "gsiDecl.h" // On Windows, ruby.h is not compatible with windows.h which is included by utHead - at least not if // windows.h is included before ruby.h ... @@ -68,12 +68,12 @@ TEST (1) fn += "/testdata/ruby/basic.rb"; try { rba::RubyInterpreter::instance ()->load_file (fn.c_str ()); - gsi_test::E::reset_inst (); + rba::RubyInterpreter::instance ()->eval_string ("RBA::E.reset_inst"); } catch (tl::ExitException &ex) { - gsi_test::E::reset_inst (); + rba::RubyInterpreter::instance ()->eval_string ("RBA::E.reset_inst"); EXPECT_EQ (ex.status (), 0); } catch (...) { - gsi_test::E::reset_inst (); + rba::RubyInterpreter::instance ()->eval_string ("RBA::E.reset_inst"); throw; } } diff --git a/src/rba/unit_tests/unit_tests.pro b/src/rba/unit_tests/unit_tests.pro index c17b48e53..bf63c9edd 100644 --- a/src/rba/unit_tests/unit_tests.pro +++ b/src/rba/unit_tests/unit_tests.pro @@ -9,8 +9,8 @@ include($$PWD/../../lib_ut.pri) SOURCES = \ rba.cc -INCLUDEPATH += $$GSI_TEST_INC $$RBA_INC $$TL_INC $$DB_INC $$GSI_INC -DEPENDPATH += $$GSI_TEST_INC $$RBA_INC $$TL_INC $$DB_INC $$GSI_INC +INCLUDEPATH += $$RBA_INC $$TL_INC $$DB_INC $$GSI_INC +DEPENDPATH += $$RBA_INC $$TL_INC $$DB_INC $$GSI_INC -LIBS += -L$$DESTDIR_UT -lgsi_test -lklayout_tl -lklayout_db -lklayout_gsi +LIBS += -L$$DESTDIR_UT -lklayout_tl -lklayout_db -lklayout_gsi diff --git a/src/tl/unit_tests/tlExpression.cc b/src/tl/unit_tests/tlExpression.cc index 5da5401e4..855b1b4d0 100644 --- a/src/tl/unit_tests/tlExpression.cc +++ b/src/tl/unit_tests/tlExpression.cc @@ -24,10 +24,6 @@ #include "tlExpression.h" #include "tlVariantUserClasses.h" #include "tlUnitTest.h" -#include "dbBox.h" -#include "dbEdge.h" -#include "dbLayout.h" -#include "dbLayoutContextHandler.h" #include #include @@ -317,6 +313,134 @@ TEST(1) EXPECT_EQ (v.to_string (), std::string ("aaaa")); } +class Point +{ +public: + Point () : m_x (0), m_y (0) { } + + Point (int x, int y) : m_x (x), m_y (y) { } + + int x () const { return m_x; } + int y () const { return m_y; } + + std::string + to_string () const + { + return tl::db_to_string (m_x) + "," + tl::db_to_string (m_y); + } + +private: + int m_x, m_y; +}; + +class Box +{ +public: + Box (int x1, int y1, int x2, int y2) + : m_p1 (x1 < x2 ? x1 : x2, y1 < y2 ? y1 : y2), + m_p2 (x2 > x1 ? x2 : x1, y2 > y1 ? y2 : y1) + { + // .. nothing else .. + } + + Box () + : m_p1 (1, 1), m_p2 (-1, -1) + { + // .. nothing else .. + } + + inline Box &operator&= (const Box &b) + { + if (b.empty ()) { + *this = Box (); + } else if (! empty ()) { + Point p1 (m_p1.x () > b.m_p1.x () ? m_p1.x () : b.m_p1.x (), + m_p1.y () > b.m_p1.y () ? m_p1.y () : b.m_p1.y ()); + Point p2 (m_p2.x () < b.m_p2.x () ? m_p2.x () : b.m_p2.x (), + m_p2.y () < b.m_p2.y () ? m_p2.y () : b.m_p2.y ()); + m_p1 = p1; + m_p2 = p2; + } + return *this; + } + + Box operator& (const Box &b) const + { + Box r (*this); + r &= b; + return r; + } + + int width () const + { + return m_p2.x () - m_p1.x (); + } + + int height () const + { + return m_p2.y () - m_p1.y (); + } + + bool empty () const + { + return m_p1.x () > m_p2.x (); + } + + std::string to_string () const + { + if (empty ()) { + return "()"; + } else { + return "(" + m_p1.to_string () + ";" + m_p2.to_string () + ")"; + } + } + +private: + Point m_p1, m_p2; +}; + +class Edge +{ +public: + Edge () + : m_p1 (0, 0), m_p2 (0, 0) + { + // .. nothing else .. + } + + Edge (int x1, int y1, int x2, int y2) + : m_p1 (x1, y1), m_p2 (x2, y2) + { + // .. nothing else .. + } + + Edge operator* (double s) const + { + return Edge (int (floor (m_p1.x () * s + 0.5)), + int (floor (m_p1.y () * s + 0.5)), + int (floor (m_p2.x () * s + 0.5)), + int (floor (m_p2.y () * s + 0.5))); + } + + int dx () const + { + return m_p2.x () - m_p1.x (); + } + + int dy () const + { + return m_p2.y () - m_p1.y (); + } + + std::string to_string () const + { + return "(" + m_p1.to_string () + ";" + m_p2.to_string () + ")"; + } + +private: + Point m_p1, m_p2; +}; + class BoxClassClass : public tl::VariantUserClassBase, private tl::EvalClass { public: @@ -342,7 +466,7 @@ public: BoxClassClass BoxClassClass::instance; -class BoxClass : public tl::VariantUserClassImpl, private tl::EvalClass +class BoxClass : public tl::VariantUserClassImpl, private tl::EvalClass { public: virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector &args) const; @@ -356,14 +480,14 @@ BoxClass BoxClass::instance; void BoxClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector &args) const { if (method == "width") { - out = object.to_user ().width (); + out = object.to_user ().width (); } else if (method == "height") { - out = object.to_user ().height (); + out = object.to_user ().height (); } else if (method == "&") { tl_assert (args.size () == 1); - out = tl::Variant (new db::Box (object.to_user () & args[0].to_user ()), &BoxClass::instance, true); + out = tl::Variant (new Box (object.to_user () & args[0].to_user ()), &BoxClass::instance, true); } else if (method == "to_s") { - out = object.to_user ().to_string (); + out = object.to_user ().to_string (); } else if (method == "is_box") { out = true; } else if (method == "is_edge") { @@ -376,7 +500,7 @@ void BoxClass::execute (const tl::ExpressionParserContext &context, tl::Variant void BoxClassClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant & /*object*/, const std::string &method, const std::vector &args) const { if (method == "new") { - out = tl::Variant (new db::Box (args[0].to_long(), args[1].to_long(), args[2].to_long(), args[3].to_long()), &BoxClass::instance, true); + out = tl::Variant (new Box (args[0].to_long(), args[1].to_long(), args[2].to_long(), args[3].to_long()), &BoxClass::instance, true); } else { throw tl::NoMethodError("Box", method, context); } @@ -407,23 +531,23 @@ public: EdgeClassClass EdgeClassClass::instance; -class EdgeClass : public tl::VariantUserClassImpl, private tl::EvalClass +class EdgeClass : public tl::VariantUserClassImpl, private tl::EvalClass { public: virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant &object, const std::string &method, const std::vector &args) const { if (method == "dx") { - out = object.to_user ().dx (); + out = object.to_user ().dx (); } else if (method == "dy") { - out = object.to_user ().dy (); + out = object.to_user ().dy (); } else if (method == "to_s") { - out = object.to_user ().to_string (); + out = object.to_user ().to_string (); } else if (method == "is_box") { out = false; } else if (method == "is_edge") { out = true; } else if (method == "*") { - out.set_user (new db::Edge (object.to_user () * args [0].to_double ()), object.user_cls (), true); + out.set_user (new Edge (object.to_user () * args [0].to_double ()), object.user_cls (), true); } else { throw tl::NoMethodError("Edge", method, context); } @@ -438,22 +562,41 @@ void EdgeClassClass::execute (const tl::ExpressionParserContext &context, tl::Variant &out, tl::Variant & /*object*/, const std::string &method, const std::vector &args) const { if (method == "new") { - out = tl::Variant (new db::Edge (args[0].to_long(), args[1].to_long(), args[2].to_long(), args[3].to_long()), &EdgeClass::instance, true); + out = tl::Variant (new Edge (args[0].to_long(), args[1].to_long(), args[2].to_long(), args[3].to_long()), &EdgeClass::instance, true); } else { throw tl::NoMethodError("Edge", method, context); } } +namespace tl +{ + +template <> +struct type_traits : public type_traits +{ + typedef trivial_relocate_required relocate_requirements; + typedef true_tag supports_to_string; +}; + +template <> +struct type_traits : public type_traits +{ + typedef trivial_relocate_required relocate_requirements; + typedef true_tag supports_to_string; +}; + +} + // basics: custom objects TEST(1b) { tl::Eval e; tl::Variant v; - e.set_var ("XBox", tl::Variant ((db::Box *) 0, &BoxClassClass::instance, false)); - e.set_var ("XEdge", tl::Variant ((db::Edge *) 0, &EdgeClassClass::instance, false)); - e.set_var ("b", tl::Variant (new db::Box (0, 10, 20, 40), &BoxClass::instance, true)); - e.set_var ("e", tl::Variant (new db::Edge (0, 10, 20, 40), &EdgeClass::instance, true)); + e.set_var ("XBox", tl::Variant ((Box *) 0, &BoxClassClass::instance, false)); + e.set_var ("XEdge", tl::Variant ((Edge *) 0, &EdgeClassClass::instance, false)); + e.set_var ("b", tl::Variant (new Box (0, 10, 20, 40), &BoxClass::instance, true)); + e.set_var ("e", tl::Variant (new Edge (0, 10, 20, 40), &EdgeClass::instance, true)); v = e.parse ("b.width").execute (); EXPECT_EQ (v.to_string (), std::string ("20")); @@ -1014,101 +1157,6 @@ TEST(16) EXPECT_EQ (v.to_string (), std::string ("true")); } -// ref layout -TEST(17) -{ - db::Layout l; - l.dbu (0.05); - l.insert_layer (db::LayerProperties (1, 15)); - l.insert_layer (db::LayerProperties ("name")); - l.add_cell ("c1"); - l.add_cell ("c2"); - - tl::Eval e, ee; - db::LayoutContextHandler ctx (&l); - e.set_ctx_handler (&ctx); - tl::Variant v; - - bool error = false; - - v = e.parse ("1um").execute (); - EXPECT_EQ (v.to_string (), std::string ("20")); - v = e.parse ("1um2").execute (); - EXPECT_EQ (v.to_string (), std::string ("400")); - v = e.parse ("1micron").execute (); - EXPECT_EQ (v.to_string (), std::string ("20")); - v = e.parse ("1micron2").execute (); - EXPECT_EQ (v.to_string (), std::string ("400")); - v = e.parse ("1mic").execute (); - EXPECT_EQ (v.to_string (), std::string ("20")); - v = e.parse ("1mic2").execute (); - EXPECT_EQ (v.to_string (), std::string ("400")); - v = e.parse ("1m").execute (); - EXPECT_EQ (v.to_string (), std::string ("20000000")); - v = e.parse ("1m2/1e14").execute (); - EXPECT_EQ (v.to_string (), std::string ("4")); - v = e.parse ("1mm").execute (); - EXPECT_EQ (v.to_string (), std::string ("20000")); - v = e.parse ("1mm2").execute (); - EXPECT_EQ (v.to_string (), std::string ("400000000")); - v = e.parse ("50nm").execute (); - EXPECT_EQ (v.to_string (), std::string ("1")); - v = e.parse ("<1/15>").execute (); - EXPECT_EQ (v.to_string (), std::string ("0")); - v = e.parse ("< name >").execute (); - EXPECT_EQ (v.to_string (), std::string ("1")); - v = e.parse ("<'n' + 'ame'>").execute (); - EXPECT_EQ (v.to_string (), std::string ("1")); - v = e.parse ("<>").execute (); - EXPECT_EQ (v.to_string (), std::string ("0")); - v = e.parse ("<< c2 >>").execute (); - EXPECT_EQ (v.to_string (), std::string ("1")); - v = e.parse ("<<'c' + '2'>>").execute (); - EXPECT_EQ (v.to_string (), std::string ("1")); - - error = true; - try { - v = e.parse ("60nm").execute (); // not a multiple of DBU - error = false; - } catch (...) { } - EXPECT_EQ (error, true); - - error = true; - try { - v = ee.parse ("1 um").execute (); - error = false; - } catch (...) { } - EXPECT_EQ (error, true); - - error = true; - try { - v = e.parse ("<1/1>").execute (); - error = false; - } catch (...) { } - EXPECT_EQ (error, true); - - error = true; - try { - v = ee.parse ("<1/15>").execute (); - error = false; - } catch (...) { } - EXPECT_EQ (error, true); - - error = true; - try { - v = ee.parse ("<>").execute (); - error = false; - } catch (...) { } - EXPECT_EQ (error, true); - - error = true; - try { - v = e.parse ("<>").execute (); - error = false; - } catch (...) { } - EXPECT_EQ (error, true); -} - // polymorphic functions TEST(18) { diff --git a/src/tl/unit_tests/tlVariant.cc b/src/tl/unit_tests/tlVariant.cc index cdb62a453..1f9cce28c 100644 --- a/src/tl/unit_tests/tlVariant.cc +++ b/src/tl/unit_tests/tlVariant.cc @@ -27,10 +27,8 @@ #include "tlObject.h" #include "tlTypeTraits.h" #include "tlUnitTest.h" -#include "gsiDecl.h" -#include "dbBox.h" -#include "dbLayerProperties.h" #include +#include struct A { @@ -793,89 +791,6 @@ TEST(2) } TEST(3) -{ - tl::Variant v; - v = tl::Variant::make_variant (db::Box (db::Point (0, 10), db::Point (20, 30))); - EXPECT_EQ (v.is_user (), true) - EXPECT_EQ (v.to_parsable_string (), "[box:(0,10;20,30)]"); - - std::string s = v.to_parsable_string () + "," + tl::Variant (15.0).to_parsable_string (); - tl::Variant vv; - tl::Extractor ex (s.c_str ()); - ex.read (vv); - ex.test (","); - ex.read (v); - EXPECT_EQ (vv.is_user (), true) - EXPECT_EQ (vv.to_parsable_string (), "[box:(0,10;20,30)]"); - EXPECT_EQ ((int)v.type_code (), (int)tl::Variant::t_double); - EXPECT_EQ (std::string(v.to_string()), "15"); -} - -TEST(4) -{ - // backward compatibility check - std::string s = "[box:(0,10;20,30)],##15"; - tl::Variant vv; - tl::Variant v; - tl::Extractor ex (s.c_str ()); - ex.read (vv); - ex.test (","); - ex.read (v); - EXPECT_EQ (vv.is_user (), true) - EXPECT_EQ (vv.to_parsable_string (), "[box:(0,10;20,30)]"); - EXPECT_EQ ((int)v.type_code (), (int)tl::Variant::t_double); - EXPECT_EQ (std::string(v.to_string()), "15"); -} - -TEST(5) -{ - // backward compatibility check - std::string s = "[Box:(0,10;20,30)],##15"; - tl::Variant vv; - tl::Variant v; - tl::Extractor ex (s.c_str ()); - ex.read (vv); - ex.test (","); - ex.read (v); - EXPECT_EQ (vv.is_user (), true) - EXPECT_EQ (vv.to_parsable_string (), "[box:(0,10;20,30)]"); - EXPECT_EQ ((int)v.type_code (), (int)tl::Variant::t_double); - EXPECT_EQ (std::string(v.to_string()), "15"); -} - -TEST(6) -{ - // backward compatibility check - std::string s = "[layer:1/0],##15"; - tl::Variant vv; - tl::Variant v; - tl::Extractor ex (s.c_str ()); - ex.read (vv); - ex.test (","); - ex.read (v); - EXPECT_EQ (vv.is_user (), true) - EXPECT_EQ (vv.to_parsable_string (), "[layer:1/0]"); - EXPECT_EQ ((int)v.type_code (), (int)tl::Variant::t_double); - EXPECT_EQ (std::string(v.to_string()), "15"); -} - -TEST(7) -{ - // backward compatibility check - std::string s = "[LayerInfo:1/0],##15"; - tl::Variant vv; - tl::Variant v; - tl::Extractor ex (s.c_str ()); - ex.read (vv); - ex.test (","); - ex.read (v); - EXPECT_EQ (vv.is_user (), true) - EXPECT_EQ (vv.to_parsable_string (), "[layer:1/0]"); - EXPECT_EQ ((int)v.type_code (), (int)tl::Variant::t_double); - EXPECT_EQ (std::string(v.to_string()), "15"); -} - -TEST(8) { std::string s = "'1',#1"; tl::Variant v1; diff --git a/src/tl/unit_tests/unit_tests.pro b/src/tl/unit_tests/unit_tests.pro index 16cd8727a..59bcb5b09 100644 --- a/src/tl/unit_tests/unit_tests.pro +++ b/src/tl/unit_tests/unit_tests.pro @@ -33,12 +33,8 @@ SOURCES = \ tlWebDAV.cc \ tlXMLParser.cc \ -INCLUDEPATH += $$TL_INC $$GSI_INC -DEPENDPATH += $$TL_INC $$GSI_INC +INCLUDEPATH += $$TL_INC +DEPENDPATH += $$TL_INC -# because of db types support in ut: -INCLUDEPATH += $$DB_INC -DEPENDPATH += $$DB_INC - -LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi +LIBS += -L$$DESTDIR_UT -lklayout_tl