feat: add pcre2 lib to precheck geometry wkt
This commit is contained in:
parent
a34b644640
commit
a7a736b6d6
|
@ -64,13 +64,6 @@ IF(${TD_WINDOWS})
|
||||||
ON
|
ON
|
||||||
)
|
)
|
||||||
|
|
||||||
MESSAGE("build geos Win32")
|
|
||||||
option(
|
|
||||||
BUILD_GEOS
|
|
||||||
"If build geos on Windows"
|
|
||||||
ON
|
|
||||||
)
|
|
||||||
|
|
||||||
ELSEIF (TD_DARWIN_64)
|
ELSEIF (TD_DARWIN_64)
|
||||||
IF(${BUILD_TEST})
|
IF(${BUILD_TEST})
|
||||||
add_definitions(-DCOMPILER_SUPPORTS_CXX13)
|
add_definitions(-DCOMPILER_SUPPORTS_CXX13)
|
||||||
|
@ -79,7 +72,7 @@ ENDIF ()
|
||||||
|
|
||||||
option(
|
option(
|
||||||
BUILD_GEOS
|
BUILD_GEOS
|
||||||
"If build geos on Windows"
|
"If build with geos"
|
||||||
ON
|
ON
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -95,6 +88,12 @@ option(
|
||||||
ON
|
ON
|
||||||
)
|
)
|
||||||
|
|
||||||
|
option(
|
||||||
|
BUILD_PCRE2
|
||||||
|
"If build with pcre2"
|
||||||
|
ON
|
||||||
|
)
|
||||||
|
|
||||||
option(
|
option(
|
||||||
JEMALLOC_ENABLED
|
JEMALLOC_ENABLED
|
||||||
"If build with jemalloc"
|
"If build with jemalloc"
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
# pcre2
|
||||||
|
ExternalProject_Add(pcre2
|
||||||
|
GIT_REPOSITORY https://github.com/PCRE2Project/pcre2.git
|
||||||
|
GIT_TAG pcre2-10.43
|
||||||
|
SOURCE_DIR "${TD_CONTRIB_DIR}/pcre2"
|
||||||
|
#BINARY_DIR "${TD_CONTRIB_DIR}/pcre2"
|
||||||
|
#BUILD_IN_SOURCE TRUE
|
||||||
|
CONFIGURE_COMMAND ""
|
||||||
|
BUILD_COMMAND ""
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
TEST_COMMAND ""
|
||||||
|
)
|
|
@ -183,6 +183,11 @@ if(${BUILD_GEOS})
|
||||||
cat("${TD_SUPPORT_DIR}/geos_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
cat("${TD_SUPPORT_DIR}/geos_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
#
|
||||||
|
if(${BUILD_PCRE2})
|
||||||
|
cat("${TD_SUPPORT_DIR}/pcre2_CMakeLists.txt.in" ${CONTRIB_TMP_FILE})
|
||||||
|
endif()
|
||||||
|
|
||||||
# download dependencies
|
# download dependencies
|
||||||
configure_file(${CONTRIB_TMP_FILE} "${TD_CONTRIB_DIR}/deps-download/CMakeLists.txt")
|
configure_file(${CONTRIB_TMP_FILE} "${TD_CONTRIB_DIR}/deps-download/CMakeLists.txt")
|
||||||
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
|
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
|
||||||
|
@ -601,6 +606,10 @@ if(${BUILD_GEOS})
|
||||||
)
|
)
|
||||||
endif(${BUILD_GEOS})
|
endif(${BUILD_GEOS})
|
||||||
|
|
||||||
|
if (${BUILD_PCRE2})
|
||||||
|
add_subdirectory(pcre2 EXCLUDE_FROM_ALL)
|
||||||
|
endif(${BUILD_PCRE2})
|
||||||
|
|
||||||
# ================================================================================================
|
# ================================================================================================
|
||||||
# Build test
|
# Build test
|
||||||
# ================================================================================================
|
# ================================================================================================
|
||||||
|
|
|
@ -21,6 +21,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <geos_c.h>
|
#include <geos_c.h>
|
||||||
|
#include <tpcre2.h>
|
||||||
|
|
||||||
typedef struct SGeosContext {
|
typedef struct SGeosContext {
|
||||||
GEOSContextHandle_t handle;
|
GEOSContextHandle_t handle;
|
||||||
|
@ -31,6 +32,9 @@ typedef struct SGeosContext {
|
||||||
GEOSWKBReader *WKBReader;
|
GEOSWKBReader *WKBReader;
|
||||||
GEOSWKBWriter *WKBWriter;
|
GEOSWKBWriter *WKBWriter;
|
||||||
|
|
||||||
|
pcre2_code *WKTRegex;
|
||||||
|
pcre2_match_data *WKTMatchData;
|
||||||
|
|
||||||
char errMsg[512];
|
char errMsg[512];
|
||||||
} SGeosContext;
|
} SGeosContext;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TD_ULIT_PCRE2_H_
|
||||||
|
#define _TD_ULIT_PCRE2_H_
|
||||||
|
|
||||||
|
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||||
|
#include "pcre2.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int32_t doRegComp(pcre2_code** ppRegex, pcre2_match_data** ppMatchData, const char* pattern);
|
||||||
|
int32_t doRegExec(const char* pString, pcre2_code* pRegex, pcre2_match_data* pMatchData);
|
||||||
|
void destroyRegexes(pcre2_code* pWktRegex, pcre2_match_data* pWktMatchData);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _TD_UTIL_PAGEDBUF_H_
|
|
@ -86,6 +86,62 @@ _exit:
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int initWktRegex(pcre2_code **ppRegex, pcre2_match_data **ppMatchData) {
|
||||||
|
int ret = 0;
|
||||||
|
char *wktPatternWithSpace = taosMemoryCalloc(4, 1024);
|
||||||
|
sprintf(
|
||||||
|
wktPatternWithSpace,
|
||||||
|
"^( *)point( *)z?m?( *)((empty)|(\\(( *)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}( *)\\)))|linestring( *)z?m?( "
|
||||||
|
"*)((empty)|(\\(( *)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}(( *)(,)( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}( *))*( *)\\)))|polygon( *)z?m?( "
|
||||||
|
"*)((empty)|(\\(( *)((empty)|(\\(( *)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}(( *)(,)( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}( *))*( *)\\)))(( *)(,)( "
|
||||||
|
"*)((empty)|(\\(( *)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}(( *)(,)( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}( *))*( *)\\)))( *))*( "
|
||||||
|
"*)\\)))|multipoint( *)z?m?( *)((empty)|(\\(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}(( *)(,)( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}( *))*( *)\\)))|multilinestring( "
|
||||||
|
"*)z?m?( *)((empty)|(\\(( *)((empty)|(\\(( *)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}(( *)(,)( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}( *))*( *)\\)))(( *)(,)( "
|
||||||
|
"*)((empty)|(\\(( *)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}(( *)(,)( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}( *))*( *)\\)))( *))*( "
|
||||||
|
"*)\\)))|multipolygon( *)z?m?( *)((empty)|(\\(( *)((empty)|(\\(( *)((empty)|(\\(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}(( *)(,)( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}( *))*( *)\\)))(( *)(,)( "
|
||||||
|
"*)((empty)|(\\(( *)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}(( *)(,)( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}( *))*( *)\\)))( *))*( *)\\)))(( *)(,)( "
|
||||||
|
"*)((empty)|(\\(( *)((empty)|(\\(( *)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}(( *)(,)( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}( *))*( *)\\)))(( *)(,)( "
|
||||||
|
"*)((empty)|(\\(( *)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}(( *)(,)( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?(( "
|
||||||
|
"*)(([-+]?[0-9]+\\.?[0-9]*)|([-+]?[0-9]*\\.?[0-9]+))(e[-+]?[0-9]+)?){1,3}( *))*( *)\\)))( *))*( *)\\)))( *))*( "
|
||||||
|
"*)\\)))|(GEOCOLLECTION\\((?R)(( *)(,)( *)(?R))*( *)\\))( *)$");
|
||||||
|
|
||||||
|
ret = doRegComp(ppRegex, ppMatchData, wktPatternWithSpace);
|
||||||
|
taosMemoryFree(wktPatternWithSpace);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t initCtxGeomFromText() {
|
int32_t initCtxGeomFromText() {
|
||||||
int32_t code = TSDB_CODE_FAILED;
|
int32_t code = TSDB_CODE_FAILED;
|
||||||
SGeosContext* geosCtx = getThreadLocalGeosCtx();
|
SGeosContext* geosCtx = getThreadLocalGeosCtx();
|
||||||
|
@ -113,6 +169,10 @@ int32_t initCtxGeomFromText() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (geosCtx->WKTRegex == NULL) {
|
||||||
|
if (initWktRegex(&geosCtx->WKTRegex, &geosCtx->WKTMatchData) != 0) return code;
|
||||||
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +185,11 @@ int32_t doGeomFromText(const char *inputWKT, unsigned char **outputGeom, size_t
|
||||||
GEOSGeometry *geom = NULL;
|
GEOSGeometry *geom = NULL;
|
||||||
unsigned char *wkb = NULL;
|
unsigned char *wkb = NULL;
|
||||||
|
|
||||||
|
if (doRegExec(inputWKT, geosCtx->WKTRegex, geosCtx->WKTMatchData) != 0) {
|
||||||
|
code = TSDB_CODE_FUNC_FUNTION_PARA_VALUE;
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
|
||||||
geom = GEOSWKTReader_read_r(geosCtx->handle, geosCtx->WKTReader, inputWKT);
|
geom = GEOSWKTReader_read_r(geosCtx->handle, geosCtx->WKTReader, inputWKT);
|
||||||
if (geom == NULL) {
|
if (geom == NULL) {
|
||||||
code = TSDB_CODE_FUNC_FUNTION_PARA_VALUE;
|
code = TSDB_CODE_FUNC_FUNTION_PARA_VALUE;
|
||||||
|
|
|
@ -21,27 +21,27 @@ target_include_directories(
|
||||||
PRIVATE "${TD_SOURCE_DIR}/utils/TSZ/sz/inc"
|
PRIVATE "${TD_SOURCE_DIR}/utils/TSZ/sz/inc"
|
||||||
PRIVATE "${TD_SOURCE_DIR}/utils/TSZ/zstd/"
|
PRIVATE "${TD_SOURCE_DIR}/utils/TSZ/zstd/"
|
||||||
PRIVATE "${TD_SOURCE_DIR}/contrib/lzma2/"
|
PRIVATE "${TD_SOURCE_DIR}/contrib/lzma2/"
|
||||||
|
PRIVATE "${TD_SOURCE_DIR}/contrib/pcre2/"
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_directories(
|
target_link_directories(
|
||||||
util
|
util
|
||||||
PUBLIC "${TD_SOURCE_DIR}/contrib/lzma2"
|
PUBLIC "${TD_SOURCE_DIR}/contrib/lzma2"
|
||||||
|
PUBLIC "${TD_SOURCE_DIR}/contrib/pcre2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if (TD_LINUX)
|
if (TD_LINUX)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
util
|
util
|
||||||
PUBLIC os common
|
PUBLIC os common
|
||||||
PUBLIC lz4_static fast-lzma2
|
PUBLIC lz4_static fast-lzma2 pcre2-8
|
||||||
PUBLIC api cjson geos_c TSZ
|
PUBLIC api cjson geos_c TSZ
|
||||||
|
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
util
|
util
|
||||||
PUBLIC os common
|
PUBLIC os common
|
||||||
PUBLIC lz4_static
|
PUBLIC lz4_static pcre2-8
|
||||||
PUBLIC api cjson geos_c TSZ
|
PUBLIC api cjson geos_c TSZ
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -43,6 +43,10 @@ void destroyThreadLocalGeosCtx() {
|
||||||
tlGeosCtx.WKBWriter = NULL;
|
tlGeosCtx.WKBWriter = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tlGeosCtx.WKTRegex) {
|
||||||
|
destroyRegexes(tlGeosCtx.WKTRegex, tlGeosCtx.WKTMatchData);
|
||||||
|
}
|
||||||
|
|
||||||
if(tlGeosCtx.handle) {
|
if(tlGeosCtx.handle) {
|
||||||
GEOS_finish_r(tlGeosCtx.handle);
|
GEOS_finish_r(tlGeosCtx.handle);
|
||||||
tlGeosCtx.handle = NULL;
|
tlGeosCtx.handle = NULL;
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
#include "tpcre2.h"
|
||||||
|
|
||||||
|
int32_t doRegComp(pcre2_code** ppRegex, pcre2_match_data** ppMatchData, const char* pattern) {
|
||||||
|
uint32_t options = PCRE2_CASELESS;
|
||||||
|
int errorcode;
|
||||||
|
PCRE2_SIZE erroroffset;
|
||||||
|
|
||||||
|
*ppRegex = pcre2_compile((PCRE2_SPTR8)pattern, PCRE2_ZERO_TERMINATED, options, &errorcode, &erroroffset, NULL);
|
||||||
|
if (*ppRegex == NULL) {
|
||||||
|
PCRE2_UCHAR buffer[256];
|
||||||
|
pcre2_get_error_message(errorcode, buffer, sizeof(buffer));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppMatchData = pcre2_match_data_create_from_pattern(*ppRegex, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t doRegExec(const char* pString, pcre2_code* pRegex, pcre2_match_data* pMatchData) {
|
||||||
|
int32_t ret = 0;
|
||||||
|
ret = pcre2_match(pRegex, (PCRE2_SPTR)pString, PCRE2_ZERO_TERMINATED, 0, 0, pMatchData, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
PCRE2_UCHAR buffer[256];
|
||||||
|
pcre2_get_error_message(ret, buffer, sizeof(buffer));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ret > 0) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyRegexes(pcre2_code* pWktRegex, pcre2_match_data* pWktMatchData) {
|
||||||
|
pcre2_code_free(pWktRegex);
|
||||||
|
pcre2_match_data_free(pWktMatchData);
|
||||||
|
}
|
Loading…
Reference in New Issue