diff --git a/oi/CMakeLists.txt b/oi/CMakeLists.txt index 64dbcae..bb73871 100644 --- a/oi/CMakeLists.txt +++ b/oi/CMakeLists.txt @@ -34,6 +34,8 @@ add_library(container_info ) target_link_libraries(container_info features + + Boost::regex glog::glog toml ) diff --git a/oi/ContainerInfo.cpp b/oi/ContainerInfo.cpp index 4cb20b8..980ec61 100644 --- a/oi/ContainerInfo.cpp +++ b/oi/ContainerInfo.cpp @@ -75,12 +75,12 @@ const char* containerTypeEnumToStr(ContainerTypeEnum ty) { return nullptr; } - std::regex matcher; + boost::regex matcher; if (std::optional str = (*info)["matcher"].value()) { - matcher = std::regex(*str, std::regex_constants::grep); + matcher = boost::regex(*str, boost::regex_constants::grep); } else { - matcher = std::regex("^" + typeName, std::regex_constants::grep); + matcher = boost::regex("^" + typeName, boost::regex_constants::grep); } std::optional numTemplateParams = @@ -194,8 +194,9 @@ namespace { * * The type name "name" should match "name" and "name". */ -std::regex getMatcher(const std::string& typeName) { - return std::regex("^" + typeName + "$|^" + typeName + "<.*>$"); +boost::regex getMatcher(const std::string& typeName) { + return boost::regex("^" + typeName + "$|^" + typeName + "<.*>$", + boost::regex_constants::extended); } } // namespace @@ -225,7 +226,7 @@ ContainerInfo::ContainerInfo(const fs::path& path) { throw ContainerInfoError(path, "`info.type_name` is a required field"); } - matcher = getMatcher(typeName); + matcher_ = getMatcher(typeName); if (std::optional str = info["ctype"].value()) { ctype = containerTypeEnumFromStr(*str); @@ -334,9 +335,9 @@ ContainerInfo::ContainerInfo(std::string typeName_, ContainerTypeEnum ctype_, std::string header_) : typeName(std::move(typeName_)), - matcher(getMatcher(typeName)), ctype(ctype_), header(std::move(header_)), codegen(Codegen{ - "// DummyDecl %1%\n", "// DummyFunc %1%\n", "// DummyFunc\n"}) { + "// DummyDecl %1%\n", "// DummyFunc %1%\n", "// DummyFunc\n"}), + matcher_(getMatcher(typeName)) { } diff --git a/oi/ContainerInfo.h b/oi/ContainerInfo.h index 9733601..a43404c 100644 --- a/oi/ContainerInfo.h +++ b/oi/ContainerInfo.h @@ -14,9 +14,9 @@ * limitations under the License. */ #pragma once +#include #include #include -#include #include #include #include @@ -49,7 +49,7 @@ struct ContainerInfo { // Old ctors, remove with OICodeGen: ContainerInfo() = default; ContainerInfo(std::string typeName_, - std::regex matcher_, + boost::regex matcher, std::optional numTemplateParams_, ContainerTypeEnum ctype_, std::string header_, @@ -61,7 +61,6 @@ struct ContainerInfo { oi::detail::FeatureSet requiredFeatures, ContainerInfo::Codegen codegen_) : typeName(std::move(typeName_)), - matcher(std::move(matcher_)), numTemplateParams(numTemplateParams_), ctype(ctype_), header(std::move(header_)), @@ -71,7 +70,8 @@ struct ContainerInfo { underlyingContainerIndex(underlyingContainerIndex_), stubTemplateParams(std::move(stubTemplateParams_)), requiredFeatures(requiredFeatures), - codegen(std::move(codegen_)) { + codegen(std::move(codegen_)), + matcher_(std::move(matcher)) { } ContainerInfo(ContainerInfo&&) = default; @@ -83,8 +83,11 @@ struct ContainerInfo { return copy; } + bool matches(std::string_view sv) const { + return boost::regex_search(sv.begin(), sv.end(), matcher_); + } + std::string typeName; - std::regex matcher; std::optional numTemplateParams; ContainerTypeEnum ctype = UNKNOWN_TYPE; std::string header; @@ -110,6 +113,8 @@ struct ContainerInfo { private: ContainerInfo(const ContainerInfo&) = default; ContainerInfo& operator=(const ContainerInfo& other) = default; + + boost::regex matcher_; }; class ContainerInfoError : public std::runtime_error { diff --git a/oi/OICodeGen.cpp b/oi/OICodeGen.cpp index 9024439..79f1958 100644 --- a/oi/OICodeGen.cpp +++ b/oi/OICodeGen.cpp @@ -150,7 +150,7 @@ OICodeGen::getContainerInfo(drgn_type* type) { for (auto it = containerInfoList.rbegin(); it != containerInfoList.rend(); ++it) { const ContainerInfo& info = **it; - if (std::regex_search(nameStr, info.matcher)) { + if (info.matches(nameStr)) { return info; } } diff --git a/oi/type_graph/ClangTypeParser.cpp b/oi/type_graph/ClangTypeParser.cpp index 5280aa1..c36fad7 100644 --- a/oi/type_graph/ClangTypeParser.cpp +++ b/oi/type_graph/ClangTypeParser.cpp @@ -24,7 +24,6 @@ #include #include -#include #include #include "oi/type_graph/Types.h" @@ -423,7 +422,7 @@ bool ClangTypeParser::chasePointer() const { ContainerInfo* ClangTypeParser::getContainerInfo( const std::string& fqName) const { for (const auto& containerInfo : containers_) { - if (std::regex_search(fqName, containerInfo->matcher)) { + if (containerInfo->matches(fqName)) { return containerInfo.get(); } } diff --git a/oi/type_graph/IdentifyContainers.cpp b/oi/type_graph/IdentifyContainers.cpp index 1a4f648..1cdae24 100644 --- a/oi/type_graph/IdentifyContainers.cpp +++ b/oi/type_graph/IdentifyContainers.cpp @@ -15,8 +15,6 @@ */ #include "IdentifyContainers.h" -#include - #include "TypeGraph.h" #include "oi/ContainerInfo.h" @@ -53,7 +51,7 @@ Type& IdentifyContainers::mutate(Type& type) { Type& IdentifyContainers::visit(Class& c) { for (const auto& containerInfo : containers_) { - if (!std::regex_search(c.fqName(), containerInfo->matcher)) { + if (!containerInfo->matches(c.fqName())) { continue; } diff --git a/oi/type_graph/TypeIdentifier.cpp b/oi/type_graph/TypeIdentifier.cpp index bba08f8..4f05a88 100644 --- a/oi/type_graph/TypeIdentifier.cpp +++ b/oi/type_graph/TypeIdentifier.cpp @@ -71,7 +71,7 @@ void TypeIdentifier::visit(Container& c) { if (Class* paramClass = dynamic_cast(¶m.type())) { bool replaced = false; for (const auto& info : passThroughTypes_) { - if (std::regex_search(paramClass->fqName(), info.matcher)) { + if (info.matches(paramClass->fqName())) { // Create dummy containers. Use a map so previously deduplicated nodes // remain deduplicated. Container* dummy; diff --git a/test/test_container_info.cpp b/test/test_container_info.cpp index 868597a..7093b97 100644 --- a/test/test_container_info.cpp +++ b/test/test_container_info.cpp @@ -5,19 +5,17 @@ TEST(ContainerInfoTest, matcher) { ContainerInfo info{"std::vector", SEQ_TYPE, "vector"}; - EXPECT_TRUE(std::regex_search("std::vector", info.matcher)); - EXPECT_TRUE(std::regex_search("std::vector>", info.matcher)); - EXPECT_TRUE(std::regex_search("std::vector", info.matcher)); + EXPECT_TRUE(info.matches("std::vector")); + EXPECT_TRUE(info.matches("std::vector>")); + EXPECT_TRUE(info.matches("std::vector")); - EXPECT_FALSE(std::regex_search("vector", info.matcher)); - EXPECT_FALSE(std::regex_search("non_std::vector", info.matcher)); - EXPECT_FALSE(std::regex_search("std::vector_other", info.matcher)); - EXPECT_FALSE(std::regex_search("std::list>", info.matcher)); - EXPECT_FALSE(std::regex_search("std::vector::value_type", info.matcher)); - EXPECT_FALSE(std::regex_search("std::vector::value_type", info.matcher)); - EXPECT_FALSE(std::regex_search("std::vector>::value_type", - info.matcher)); + EXPECT_FALSE(info.matches("vector")); + EXPECT_FALSE(info.matches("non_std::vector")); + EXPECT_FALSE(info.matches("std::vector_other")); + EXPECT_FALSE(info.matches("std::list>")); + EXPECT_FALSE(info.matches("std::vector::value_type")); + EXPECT_FALSE(info.matches("std::vector::value_type")); + EXPECT_FALSE(info.matches("std::vector>::value_type")); // Uh-oh, here's a case that I don't think regexes are powerful enough to - // match: EXPECT_FALSE(std::regex_search("std::vector::subtype", - // info.matcher)); + // match: EXPECT_FALSE(info.matches("std::vector::subtype")); }