vmtester: Add create function name search heuristic
@@ -35,6 +35,38 @@ evmc_instance* get_vm_instance()
return vm.get();
}
+std::vector<std::string> get_vm_names(const fs::path path)
+{
+ std::vector<std::string> names;
+
+ // Get the filename without extension.
+ auto name = path.stem().string();
+
+ // Skip the optional library name prefix.
+ const std::string lib_name_prefix{"lib"};
+ if (name.find(lib_name_prefix) == 0)
+ name = name.substr(lib_name_prefix.size());
+
+ size_t hyphen_pos = 0;
+ const std::string hyphen{"-"};
+ if ((hyphen_pos = name.find(hyphen)) != std::string::npos)
+ {
+ // Replace the hyphen with underscore.
+ name.replace(hyphen_pos, hyphen.size(), "_");
+ names.emplace_back(name);
+
+ // Also add the name without the hyphen-separated prefix.
+ names.emplace_back(name.substr(hyphen_pos + hyphen.size()));
+ }
+ else
+ {
+ // Add the filename as the name.
+ names.emplace_back(std::move(name));
+ }
+
+ return names;
+}
+
int main(int argc, char* argv[])
{
try
@@ -65,23 +97,37 @@ int main(int argc, char* argv[])
opts::notify(variables_map);
- auto symbols = dll::library_info{vm_path}.symbols();
- auto it = std::find_if(symbols.begin(), symbols.end(), [](const std::string& symbol) {
- return symbol.find("evmc_create_") == 0;
- });
- if (it == symbols.end())
+ std::cout << "Testing " << vm_path.filename().string() << "\n"
+ << "Path: " << vm_path.string() << "\n";
+
+ for (auto&& name : get_vm_names(vm_path))
+ {
+ try
+ {
+ const std::string create_fn_name = "evmc_create_" + name;
+ std::cout << "Seeking `" << create_fn_name << "`... ";
+ create_fn = dll::import<evmc_create_fn>(vm_path, create_fn_name);
+ std::cout << "found.\n";
+ break;
+ }
+ catch (boost::system::system_error& err)
+ {
+ using namespace boost::system;
+ const error_code windows_error{127, system_category()};
+ constexpr auto posix_error = errc::invalid_seek;
+ if (err.code() != posix_error && err.code() != windows_error)
+ throw; // Error other than "symbol not found".
+ std::cout << "not found.\n";
+ }
+ }
+
+ if (!create_fn)
{
std::cerr << "EVMC create function not found in " << vm_path.string() << "\n";
return 2;
}
- const std::string& create_fn_name = *it;
-
- std::cout << "Testing " << vm_path.filename().string() << "\n "
- << "Path: " << vm_path.string() << "\n "
- << "Create function: " << create_fn_name << "()\n\n";
-
- create_fn = dll::import<evmc_create_fn>(vm_path, create_fn_name);
+ std::cout << std::endl;
return RUN_ALL_TESTS();
}
catch (const std::exception& ex)
