diff --git a/src/db/db/dbLibrary.cc b/src/db/db/dbLibrary.cc index 0af31331c..e0f93dd7b 100644 --- a/src/db/db/dbLibrary.cc +++ b/src/db/db/dbLibrary.cc @@ -55,7 +55,7 @@ Library::~Library () bool Library::is_for_technology (const std::string &name) const { - return m_technologies.find (name) != m_technologies.end (); + return (! m_technologies.empty () && name == "*") || m_technologies.find (name) != m_technologies.end (); } bool diff --git a/src/db/db/gsiDeclDbLibrary.cc b/src/db/db/gsiDeclDbLibrary.cc index 4da1335f2..4f2425eb9 100644 --- a/src/db/db/gsiDeclDbLibrary.cc +++ b/src/db/db/gsiDeclDbLibrary.cc @@ -165,10 +165,13 @@ LibraryClass decl_Library ("db", "LibraryBase", "@brief Gets a library by name\n" "Returns the library object for the given name. If the name is not a valid library name, nil is returned.\n" "\n" - "Different libraries can be registered under the same names for different technologies. When a technology name is given in 'for_technologies', " - "the first library matching this technology is returned. If no technology is given, the first library is returned.\n" + "Different libraries can be registered under the same names for different technologies. By specifying a technology, this method\n" + "will return the first library matching both name and the given technology. It will also return libraries not bound to a specific\n" + "technology in that case. Without a technology name given ('unspecific'), only libraries not bound to a technology are returned.\n" + "You can also specify '*' for the technology - in that case, the first library with the given name is returned, regardless whether\n" + "it is bound to a technology or not.\n" "\n" - "The technology selector has been introduced in version 0.27." + "The technology selector has been introduced in version 0.27. The '*' option for the technology has been added in version 0.30.8." ) + gsi::method ("library_by_id", &library_by_id, gsi::arg ("id"), "@brief Gets the library object for the given ID\n" @@ -274,8 +277,10 @@ LibraryClass decl_Library ("db", "LibraryBase", gsi::method ("is_for_technology", &db::Library::is_for_technology, gsi::arg ("tech"), "@brief Returns a value indicating whether the library is associated with the given technology.\n" "The method is equivalent to checking whether the \\technologies list is empty.\n" + "As a special case, you can pass '*' for the 'tech' argument. In that case, this method\n" + "will return true, if the library is bound to any technology.\n" "\n" - "This method has been introduced in version 0.27" + "This method has been introduced in version 0.27. The '*' option for the technology has been added in version 0.30.8." ) + gsi::method ("for_technologies", &db::Library::for_technologies, "@brief Returns a value indicating whether the library is associated with any technology.\n" diff --git a/src/db/unit_tests/dbLibrariesTests.cc b/src/db/unit_tests/dbLibrariesTests.cc index 1d48e852e..ed10661e4 100644 --- a/src/db/unit_tests/dbLibrariesTests.cc +++ b/src/db/unit_tests/dbLibrariesTests.cc @@ -506,6 +506,16 @@ TEST(3) std::unique_ptr lib_b (new LIBT_B ()); db::LibraryManager::instance ().register_lib (lib_b.get ()); + EXPECT_EQ (lib_a->is_for_technology ("X"), false); + EXPECT_EQ (lib_a->is_for_technology ("*"), false); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A").first, true); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "*").first, true); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "X").first, true); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "").first, true); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A").second, lib_a->get_id ()); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "X").second, lib_a->get_id ()); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "*").second, lib_a->get_id ()); + // This test tests the ability to reference libraries out of other libraries ("B" references "A"), // the ability to persist that and whether this survives a write/read cycle. @@ -545,6 +555,15 @@ TEST(4) std::unique_ptr lib_a1_inst (new LIBT_A ()); tl::weak_ptr lib_a1 (lib_a1_inst.get ()); lib_a1->add_technology ("X"); + EXPECT_EQ (lib_a1->is_for_technology ("Z"), false); + EXPECT_EQ (lib_a1->is_for_technology ("X"), true); + EXPECT_EQ (lib_a1->is_for_technology ("XX"), false); + EXPECT_EQ (lib_a1->is_for_technology ("*"), true); + lib_a1->add_technology ("XX"); + EXPECT_EQ (lib_a1->is_for_technology ("Z"), false); + EXPECT_EQ (lib_a1->is_for_technology ("X"), true); + EXPECT_EQ (lib_a1->is_for_technology ("XX"), true); + EXPECT_EQ (lib_a1->is_for_technology ("*"), true); std::unique_ptr lib_a2_inst (new LIBT_A ()); tl::weak_ptr lib_a2 (lib_a2_inst.get ()); @@ -552,12 +571,15 @@ TEST(4) std::unique_ptr lib_a3_inst (new LIBT_A ()); tl::weak_ptr lib_a3 (lib_a3_inst.get ()); + // same technologies as a1, so it can entirely replace it: lib_a3->add_technology ("X"); + lib_a3->add_technology ("XX"); std::unique_ptr lib_a4_inst (new LIBT_A ()); tl::weak_ptr lib_a4 (lib_a4_inst.get ()); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A").first, false); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "*").first, false); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "Z").first, false); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "").first, false); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "X").first, false); @@ -565,20 +587,25 @@ TEST(4) db::LibraryManager::instance ().register_lib (lib_a1.get ()); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A").first, false); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "*").first, true); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "Z").first, false); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "").first, false); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "X").first, true); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "X").second, lib_a1->get_id ()); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "XX").second, lib_a1->get_id ()); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "*").second, lib_a1->get_id ()); db::LibraryManager::instance ().register_lib (lib_a2.get ()); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A").first, false); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "*").first, true); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "Z").first, false); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "").first, false); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "X").first, true); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "X").second, lib_a1->get_id ()); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "Y").first, true); EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "Y").second, lib_a2->get_id ()); + EXPECT_EQ (db::LibraryManager::instance ().lib_by_name ("A", "*").second, lib_a2->get_id ()); db::LibraryManager::instance ().register_lib (lib_a3.get ()); // lib_a3 replaces lib_a1