diff --git a/include/iocore/net/SSLSNIConfig.h b/include/iocore/net/SSLSNIConfig.h index 856c1b9f301..af78eeaf206 100644 --- a/include/iocore/net/SSLSNIConfig.h +++ b/include/iocore/net/SSLSNIConfig.h @@ -37,6 +37,14 @@ #include #include +#if __has_include("pcre/pcre.h") +#include +#elif __has_include("pcre.h") +#include +#else +#error "Unable to locate PCRE heeader" +#endif + #include "tscpp/util/ts_ip.h" #include "iocore/eventsystem/ConfigProcessor.h" diff --git a/include/proxy/ControlMatcher.h b/include/proxy/ControlMatcher.h index f3536bc01c8..2ccf3461f16 100644 --- a/include/proxy/ControlMatcher.h +++ b/include/proxy/ControlMatcher.h @@ -94,9 +94,17 @@ #include "tscore/ink_apidefs.h" #include "tscore/ink_defs.h" #include "proxy/hdrs/HTTP.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "proxy/hdrs/URL.h" +#if __has_include("pcre/pcre.h") +#include +#elif __has_include("pcre.h") +#include +#else +#error "Unable to locate PCRE heeader" +#endif + #include #ifdef HAVE_CTYPE_H diff --git a/include/proxy/hdrs/HdrToken.h b/include/proxy/hdrs/HdrToken.h index 0c2ef0ee33a..23f3ce03f8f 100644 --- a/include/proxy/hdrs/HdrToken.h +++ b/include/proxy/hdrs/HdrToken.h @@ -30,7 +30,7 @@ #include "tscore/ink_defs.h" #include "tscore/ink_string.h" #include "tscore/Allocator.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "tscore/ink_apidefs.h" //////////////////////////////////////////////////////////////////////////// diff --git a/include/proxy/http/HttpConfig.h b/include/proxy/http/HttpConfig.h index da253a150fb..1d0f6261c9f 100644 --- a/include/proxy/http/HttpConfig.h +++ b/include/proxy/http/HttpConfig.h @@ -46,7 +46,7 @@ #include "tscore/ink_platform.h" #include "tscore/ink_inet.h" #include "tscore/ink_resolver.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "tscpp/util/ts_bw.h" #include "iocore/eventsystem/ConfigProcessor.h" #include "iocore/net/ConnectionTracker.h" diff --git a/include/proxy/http/remap/UrlMapping.h b/include/proxy/http/remap/UrlMapping.h index 2de926286b3..d51e909843b 100644 --- a/include/proxy/http/remap/UrlMapping.h +++ b/include/proxy/http/remap/UrlMapping.h @@ -26,13 +26,21 @@ #include +#if __has_include("pcre/pcre.h") +#include +#elif __has_include("pcre.h") +#include +#else +#error "Unable to locate PCRE heeader" +#endif + #include "tscore/ink_config.h" #include "proxy/http/remap/AclFiltering.h" #include "proxy/hdrs/URL.h" #include "proxy/http/remap/RemapHitCount.h" #include "proxy/http/remap/RemapPluginInfo.h" #include "proxy/http/remap/PluginFactory.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "tscore/List.h" class NextHopSelectionStrategy; diff --git a/include/proxy/http/remap/UrlRewrite.h b/include/proxy/http/remap/UrlRewrite.h index f59b4b769c4..62ac8d048e9 100644 --- a/include/proxy/http/remap/UrlRewrite.h +++ b/include/proxy/http/remap/UrlRewrite.h @@ -28,7 +28,7 @@ #include "proxy/http/remap/UrlMapping.h" #include "proxy/http/remap/UrlMappingPathIndex.h" #include "proxy/http/HttpTransact.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "proxy/http/remap/PluginFactory.h" #include "proxy/http/remap/NextHopStrategyFactory.h" diff --git a/include/tscore/DiagsTypes.h b/include/tscore/DiagsTypes.h index 73a4760adfe..ab754e58121 100644 --- a/include/tscore/DiagsTypes.h +++ b/include/tscore/DiagsTypes.h @@ -39,7 +39,7 @@ #include "tscore/ink_apidefs.h" #include "tscore/ink_inet.h" #include "tscore/ink_mutex.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "tscore/SourceLocation.h" #include "tscpp/util/ts_diag_levels.h" diff --git a/include/tscore/Regression.h b/include/tscore/Regression.h index 518edfb3164..6c56b62d2d4 100644 --- a/include/tscore/Regression.h +++ b/include/tscore/Regression.h @@ -24,7 +24,7 @@ #pragma once #include "tscore/ink_platform.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "tscore/Diags.h" // Each module should provide one or more regression tests diff --git a/include/tscore/Regex.h b/include/tscpp/util/Regex.h similarity index 79% rename from include/tscore/Regex.h rename to include/tscpp/util/Regex.h index 7394dfebe71..a1c51e3661e 100644 --- a/include/tscore/Regex.h +++ b/include/tscpp/util/Regex.h @@ -28,13 +28,7 @@ #include #include -#include "tscore/ink_config.h" - -#ifdef HAVE_PCRE_PCRE_H -#include -#else -#include -#endif +#include "swoc/MemSpan.h" /// Match flags for regular expression evaluation. enum REFlags { @@ -90,12 +84,30 @@ class Regex */ bool exec(std::string_view const &str, int *ovector, int ovecsize) const; + /** Execute the regular expression. + * + * @param str String to match against. + * @param ovector Capture results. + * @param ovecsize Number of elements in @a ovector. + * @return @c true if the pattern matched, @a false if not. + * + * It is safe to call this method concurrently on the same instance of @a this. + * + * Each capture group takes 3 elements of @a ovector, therefore @a ovecsize must + * be a multiple of 3 and at least three times the number of desired capture groups. + */ + bool exec(std::string_view str, swoc::MemSpan groups) const; + /// @return The number of groups captured in the last call to @c exec. int get_capture_count(); private: - pcre *regex = nullptr; - pcre_extra *regex_extra = nullptr; + // @internal - Because the PCRE header is badly done, we can't forward declare the PCRE + // enough to use as pointers. For some reason the header defines in name only a struct and + // then aliases it to the standard name, rather than simply declare the latter in name only. + // The goal is completely wrap PCRE and not include that header in client code. + void *regex = nullptr; ///< Compiled expression. + void *regex_extra = nullptr; ///< Extra information about the expression. }; /** Deterministic Finite state Automata container. diff --git a/plugins/experimental/tls_bridge/tls_bridge.cc b/plugins/experimental/tls_bridge/tls_bridge.cc index 2990b56fe42..2799bbe85e9 100644 --- a/plugins/experimental/tls_bridge/tls_bridge.cc +++ b/plugins/experimental/tls_bridge/tls_bridge.cc @@ -21,7 +21,7 @@ #include "ts/ts.h" #include "swoc/TextView.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" using swoc::TextView; diff --git a/src/iocore/cache/CachePages.cc b/src/iocore/cache/CachePages.cc index 10e13671671..7c21f500725 100644 --- a/src/iocore/cache/CachePages.cc +++ b/src/iocore/cache/CachePages.cc @@ -26,6 +26,15 @@ #include "proxy/Show.h" #include "iocore/eventsystem/Tasks.h" #include "proxy/CacheControl.h" + +#if __has_include("pcre/pcre.h") +#include +#elif __has_include("pcre.h") +#include +#else +#error "Unable to locate PCRE heeader" +#endif + namespace { diff --git a/src/iocore/net/SSLCertLookup.cc b/src/iocore/net/SSLCertLookup.cc index 57cd2fe9f23..7cc864741a2 100644 --- a/src/iocore/net/SSLCertLookup.cc +++ b/src/iocore/net/SSLCertLookup.cc @@ -26,7 +26,7 @@ #include "tscore/ink_config.h" #include "tscore/Layout.h" #include "tscore/MatcherUtils.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "tscore/Trie.h" #include "tscore/ink_config.h" diff --git a/src/mgmt/rpc/CMakeLists.txt b/src/mgmt/rpc/CMakeLists.txt index cdf60a8f91e..20847a19335 100644 --- a/src/mgmt/rpc/CMakeLists.txt +++ b/src/mgmt/rpc/CMakeLists.txt @@ -26,7 +26,7 @@ set_target_properties(jsonrpc_protocol PROPERTIES POSITION_INDEPENDENT_CODE TRUE target_link_libraries( jsonrpc_protocol - PUBLIC ts::tscore + PUBLIC tscpputil ts::tscore PRIVATE ts::tsapicore ) diff --git a/src/mgmt/rpc/handlers/common/RecordsUtils.cc b/src/mgmt/rpc/handlers/common/RecordsUtils.cc index 767ba02c5ce..9a5276ef6ae 100644 --- a/src/mgmt/rpc/handlers/common/RecordsUtils.cc +++ b/src/mgmt/rpc/handlers/common/RecordsUtils.cc @@ -17,6 +17,15 @@ See the License for the specific language governing permissions and limitations under the License. */ + +#if __has_include("pcre/pcre.h") +#include +#elif __has_include("pcre.h") +#include +#else +#error "Unable to locate PCRE heeader" +#endif + #include "mgmt/rpc/handlers/common/RecordsUtils.h" #include diff --git a/src/proxy/CacheControl.cc b/src/proxy/CacheControl.cc index a62fce25049..7cdbac065b1 100644 --- a/src/proxy/CacheControl.cc +++ b/src/proxy/CacheControl.cc @@ -39,7 +39,7 @@ #include "proxy/hdrs/HTTP.h" #include "proxy/http/HttpConfig.h" #include "../iocore/cache/P_Cache.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" static const char modulePrefix[] = "[CacheControl]"; diff --git a/src/proxy/hdrs/CMakeLists.txt b/src/proxy/hdrs/CMakeLists.txt index 5555a302511..c39caedd5b8 100644 --- a/src/proxy/hdrs/CMakeLists.txt +++ b/src/proxy/hdrs/CMakeLists.txt @@ -55,6 +55,6 @@ if(BUILD_TESTING) add_test(NAME test_proxy_hdrs COMMAND test_proxy_hdrs) add_executable(test_proxy_hdrs_xpack XPACK.cc HuffmanCodec.cc unit_tests/test_XPACK.cc) - target_link_libraries(test_proxy_hdrs_xpack PRIVATE ts::tscore ts::tsapicore libswoc catch2::catch2) + target_link_libraries(test_proxy_hdrs_xpack PRIVATE ts::tscore ts::tsapicore tscpputil libswoc catch2::catch2) add_test(NAME test_proxy_hdrs_xpack COMMAND test_proxy_hdrs_xpack) endif() diff --git a/src/proxy/hdrs/HdrToken.cc b/src/proxy/hdrs/HdrToken.cc index 0ac036c5ed2..4a61b72540d 100644 --- a/src/proxy/hdrs/HdrToken.cc +++ b/src/proxy/hdrs/HdrToken.cc @@ -30,7 +30,7 @@ #include "proxy/hdrs/HTTP.h" #include "proxy/hdrs/HdrToken.h" #include "proxy/hdrs/MIME.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "proxy/hdrs/URL.h" /* diff --git a/src/proxy/hdrs/test_urlhash.cc b/src/proxy/hdrs/test_urlhash.cc index 341cf01e26b..cd1a424d376 100644 --- a/src/proxy/hdrs/test_urlhash.cc +++ b/src/proxy/hdrs/test_urlhash.cc @@ -27,7 +27,7 @@ #include "tscore/Arena.h" #include "proxy/hdrs/HTTP.h" #include "proxy/hdrs/MIME.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "proxy/hdrs/URL.h" #include "proxy/hdrs/HttpCompat.h" diff --git a/src/proxy/hdrs/unit_tests/test_Hdrs.cc b/src/proxy/hdrs/unit_tests/test_Hdrs.cc index 90dcc329f4b..f36c4dac07e 100644 --- a/src/proxy/hdrs/unit_tests/test_Hdrs.cc +++ b/src/proxy/hdrs/unit_tests/test_Hdrs.cc @@ -29,7 +29,7 @@ #include #include -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "tscore/ink_time.h" #include "tscore/Random.h" #include "tscpp/util/PostScript.h" diff --git a/src/traffic_cache_tool/CMakeLists.txt b/src/traffic_cache_tool/CMakeLists.txt index 18e8ba6a683..13aae6f2230 100644 --- a/src/traffic_cache_tool/CMakeLists.txt +++ b/src/traffic_cache_tool/CMakeLists.txt @@ -17,5 +17,5 @@ add_executable(traffic_cache_tool CacheDefs.cc CacheTool.cc CacheScan.cc) -target_link_libraries(traffic_cache_tool PRIVATE ts::tscore libswoc ts::tsapicore) +target_link_libraries(traffic_cache_tool PRIVATE tscpputil ts::tscore libswoc ts::tsapicore) install(TARGETS traffic_cache_tool) diff --git a/src/traffic_cache_tool/CacheDefs.h b/src/traffic_cache_tool/CacheDefs.h index 2a3feadd2a3..13fc622bd42 100644 --- a/src/traffic_cache_tool/CacheDefs.h +++ b/src/traffic_cache_tool/CacheDefs.h @@ -34,7 +34,7 @@ #include "tscore/Version.h" #include "tscore/ink_memory.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "tscore/ink_file.h" #include "tscore/CryptoHash.h" diff --git a/src/traffic_layout/info.cc b/src/traffic_layout/info.cc index 6468977136d..2271599973c 100644 --- a/src/traffic_layout/info.cc +++ b/src/traffic_layout/info.cc @@ -31,6 +31,14 @@ #include "info.h" #include "iocore/eventsystem/RecProcess.h" +#if __has_include("pcre/pcre.h") +#include +#elif __has_include("pcre.h") +#include +#else +#error "Unable to locate PCRE heeader" +#endif + #if TS_USE_HWLOC #include #endif diff --git a/src/traffic_via/traffic_via.cc b/src/traffic_via/traffic_via.cc index 7bf905c14cb..561a4e00cfb 100644 --- a/src/traffic_via/traffic_via.cc +++ b/src/traffic_via/traffic_via.cc @@ -28,7 +28,7 @@ #include #include #include -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" /// XXX Use DFA or Regex wrappers? #ifdef HAVE_PCRE_PCRE_H diff --git a/src/tscore/CMakeLists.txt b/src/tscore/CMakeLists.txt index a5a771a17fd..8539181386c 100644 --- a/src/tscore/CMakeLists.txt +++ b/src/tscore/CMakeLists.txt @@ -54,7 +54,6 @@ add_library( MatcherUtils.cc ParseRules.cc Random.cc - Regex.cc Regression.cc SourceLocation.cc TextBuffer.cc @@ -150,7 +149,6 @@ if(BUILD_TESTING) unit_tests/test_PriorityQueue.cc unit_tests/test_Ptr.cc unit_tests/test_Random.cc - unit_tests/test_Regex.cc unit_tests/test_Throttler.cc unit_tests/test_Tokenizer.cc unit_tests/test_arena.cc diff --git a/src/tscpp/util/CMakeLists.txt b/src/tscpp/util/CMakeLists.txt index 281f263570e..92ee544a3b1 100644 --- a/src/tscpp/util/CMakeLists.txt +++ b/src/tscpp/util/CMakeLists.txt @@ -15,9 +15,9 @@ # ####################### -add_library(tscpputil SHARED ts_bwf.cc ts_ip.cc ts_diags.cc YamlCfg.cc ts_unit_parser.cc) +add_library(tscpputil SHARED ts_bwf.cc ts_ip.cc ts_diags.cc YamlCfg.cc ts_unit_parser.cc Regex.cc) add_library(ts::tscpputil ALIAS tscpputil) -target_link_libraries(tscpputil PUBLIC libswoc yaml-cpp::yaml-cpp ts::tscore) +target_link_libraries(tscpputil PUBLIC PCRE::PCRE libswoc yaml-cpp::yaml-cpp) set(TSCPPUTIL_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/tscpp/util/Bravo.h ${PROJECT_SOURCE_DIR}/include/tscpp/util/Convert.h @@ -26,6 +26,7 @@ set(TSCPPUTIL_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/tscpp/util/LocalBuffer.h ${PROJECT_SOURCE_DIR}/include/tscpp/util/PostScript.h ${PROJECT_SOURCE_DIR}/include/tscpp/util/Strerror.h + ${PROJECT_SOURCE_DIR}/include/tscpp/util/Regex.h ${PROJECT_SOURCE_DIR}/include/tscpp/util/TsSharedMutex.h ${PROJECT_SOURCE_DIR}/include/tscpp/util/YamlCfg.h ${PROJECT_SOURCE_DIR}/include/tscpp/util/ts_bw.h @@ -43,8 +44,14 @@ install(TARGETS tscpputil PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ if(BUILD_TESTING) add_executable( - test_tscpputil unit_tests/test_LocalBuffer.cc unit_tests/test_PostScript.cc unit_tests/test_Strerror.cc - unit_tests/test_ts_meta.cc unit_tests/test_time_parser.cc unit_tests/unit_test_main.cc + test_tscpputil + unit_tests/test_LocalBuffer.cc + unit_tests/test_PostScript.cc + unit_tests/test_Strerror.cc + unit_tests/test_Regex.cc + unit_tests/test_ts_meta.cc + unit_tests/test_time_parser.cc + unit_tests/unit_test_main.cc ) target_link_libraries(test_tscpputil PRIVATE tscpputil libswoc catch2::catch2) diff --git a/src/tscore/Regex.cc b/src/tscpp/util/Regex.cc similarity index 80% rename from src/tscore/Regex.cc rename to src/tscpp/util/Regex.cc index 516d51e8037..04adf3d8426 100644 --- a/src/tscore/Regex.cc +++ b/src/tscpp/util/Regex.cc @@ -21,12 +21,32 @@ limitations under the License. */ +#include "tscpp/util/Regex.h" + #include +#include + +#if __has_include() +#include +#else +#include +#endif -#include "tscore/ink_platform.h" -#include "tscore/ink_thread.h" -#include "tscore/ink_memory.h" -#include "tscore/Regex.h" +#include "tscore/ink_memory.h" // ats_pagesize() + +namespace +{ +inline pcre * +as_pcre(void *p) +{ + return static_cast(p); +} +inline pcre_extra * +as_extra(void *p) +{ + return static_cast(p); +} +} // namespace #ifdef PCRE_CONFIG_JIT /* @@ -48,6 +68,7 @@ struct JitStackCleanup { } } }; + thread_local JitStackCleanup jsc; pcre_jit_stack * @@ -98,11 +119,11 @@ Regex::compile(const char *pattern, const unsigned flags) study_opts |= PCRE_STUDY_JIT_COMPILE; #endif - regex_extra = pcre_study(regex, study_opts, &error); + regex_extra = pcre_study(as_pcre(regex), study_opts, &error); #ifdef PCRE_CONFIG_JIT if (regex_extra) { - pcre_assign_jit_stack(regex_extra, &get_jit_stack, nullptr); + pcre_assign_jit_stack(as_extra(regex_extra), &get_jit_stack, nullptr); } #endif @@ -113,7 +134,7 @@ int Regex::get_capture_count() { int captures = -1; - if (pcre_fullinfo(regex, regex_extra, PCRE_INFO_CAPTURECOUNT, &captures) != 0) { + if (pcre_fullinfo(as_pcre(regex), as_extra(regex_extra), PCRE_INFO_CAPTURECOUNT, &captures) != 0) { return -1; } @@ -124,7 +145,7 @@ bool Regex::exec(std::string_view const &str) const { std::array ovector = {{0}}; - return this->exec(str, ovector.data(), ovector.size()); + return this->exec(str, ovector); } bool @@ -132,15 +153,22 @@ Regex::exec(std::string_view const &str, int *ovector, int ovecsize) const { int rv; - rv = pcre_exec(regex, regex_extra, str.data(), static_cast(str.size()), 0, 0, ovector, ovecsize); + rv = pcre_exec(as_pcre(regex), as_extra(regex_extra), str.data(), static_cast(str.size()), 0, 0, ovector, ovecsize); return rv > 0; } +bool +Regex::exec(std::string_view str, swoc::MemSpan groups) const +{ + return 0 < + pcre_exec(as_pcre(regex), as_extra(regex_extra), str.data(), int(str.size()), 0, 0, groups.data(), int(groups.count())); +} + Regex::~Regex() { if (regex_extra) { #ifdef PCRE_CONFIG_JIT - pcre_free_study(regex_extra); + pcre_free_study(as_extra(regex_extra)); #else pcre_free(regex_extra); #endif @@ -172,7 +200,7 @@ DFA::build(std::string_view const &pattern, unsigned flags) int DFA::compile(std::string_view const &pattern, unsigned flags) { - ink_assert(_patterns.empty()); + assert(_patterns.empty()); this->build(pattern, flags); return _patterns.size(); } diff --git a/src/tscore/unit_tests/test_Regex.cc b/src/tscpp/util/unit_tests/test_Regex.cc similarity index 98% rename from src/tscore/unit_tests/test_Regex.cc rename to src/tscpp/util/unit_tests/test_Regex.cc index bb1aa301727..a0074af6a75 100644 --- a/src/tscore/unit_tests/test_Regex.cc +++ b/src/tscpp/util/unit_tests/test_Regex.cc @@ -25,7 +25,7 @@ #include "tscore/ink_assert.h" #include "tscore/ink_defs.h" -#include "tscore/Regex.h" +#include "tscpp/util/Regex.h" #include "catch.hpp" struct subject_match_t {