Enhancement to Library#lib_by_name

* Better description
* Allowing "*" for the technology name to capture all
  libraries with that name
This commit is contained in:
Matthias Koefferlein 2026-04-04 14:27:01 +02:00
parent 00c826688f
commit a092d7c6ca
3 changed files with 37 additions and 5 deletions

View File

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

View File

@ -165,10 +165,13 @@ LibraryClass<db::Library> 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<db::Library> 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"

View File

@ -506,6 +506,16 @@ TEST(3)
std::unique_ptr<LIBT_B> 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<LIBT_A> lib_a1_inst (new LIBT_A ());
tl::weak_ptr<LIBT_A> 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<LIBT_A> lib_a2_inst (new LIBT_A ());
tl::weak_ptr<LIBT_A> lib_a2 (lib_a2_inst.get ());
@ -552,12 +571,15 @@ TEST(4)
std::unique_ptr<LIBT_A> lib_a3_inst (new LIBT_A ());
tl::weak_ptr<LIBT_A> 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<LIBT_A> lib_a4_inst (new LIBT_A ());
tl::weak_ptr<LIBT_A> 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