From: Dmitry Volyntsev Date: Fri, 24 Dec 2021 15:48:11 +0000 (+0000) Subject: Building regexp backend as an external. X-Git-Tag: 0.7.1~6 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=dab37f775147a99c6a8a98a4abe0013062959ec5;p=njs.git Building regexp backend as an external. This allows not to build PCRE specific code as a part of libnjs.a thus supporting nginx builds with flags like --with-pcre=PCRE_DIR. When --no-pcre configure option is provided external code have to implement methods declared in njs_regex.h. This also closes #18 issue on Github. --- diff --git a/auto/options b/auto/options index c4282280..5aab0845 100644 --- a/auto/options +++ b/auto/options @@ -12,6 +12,8 @@ NJS_ADDRESS_SANITIZER=NO NJS_TEST262=YES NJS_OPENSSL=YES + +NJS_PCRE=YES NJS_TRY_PCRE2=YES NJS_CONFIGURE_OPTIONS= @@ -35,6 +37,8 @@ do --test262=*) NJS_TEST262="$value" ;; --no-openssl) NJS_OPENSSL=NO ;; + + --no-pcre) NJS_PCRE=NO ;; --no-pcre2) NJS_TRY_PCRE2=NO ;; --help) diff --git a/auto/pcre b/auto/pcre index e7e696b2..8d51cf8c 100644 --- a/auto/pcre +++ b/auto/pcre @@ -2,72 +2,81 @@ # Copyright (C) Igor Sysoev # Copyright (C) NGINX, Inc. -njs_found=no -NJS_HAVE_PCRE2=NO +NJS_PCRE_CFLAGS= +NJS_PCRE_LIB= -if [ $NJS_TRY_PCRE2 = YES ]; then - if /bin/sh -c "(pcre2-config --version)" >> $NJS_AUTOCONF_ERR 2>&1; then +NJS_HAVE_PCRE=NO - NJS_PCRE_CFLAGS=`pcre2-config --cflags` - NJS_PCRE_LIB=`pcre2-config --libs8` +if [ $NJS_PCRE = YES ]; then - njs_feature="PCRE2 library" - njs_feature_name=NJS_HAVE_PCRE2 - njs_feature_run=no - njs_feature_incs="-DPCRE2_CODE_UNIT_WIDTH=8 $NJS_PCRE_CFLAGS" - njs_feature_libs=$NJS_PCRE_LIB - njs_feature_test="#include + njs_found=no - int main(void) { - pcre2_code *re; + if [ $NJS_TRY_PCRE2 = YES ]; then + if /bin/sh -c "(pcre2-config --version)" >> $NJS_AUTOCONF_ERR 2>&1; then - re = pcre2_compile((PCRE2_SPTR)\"\", - PCRE2_ZERO_TERMINATED, 0, - NULL, NULL, NULL); - return (re == NULL); - }" + NJS_PCRE_CFLAGS=`pcre2-config --cflags` + NJS_PCRE_LIB=`pcre2-config --libs8` - . auto/feature + njs_feature="PCRE2 library" + njs_feature_name=NJS_HAVE_PCRE2 + njs_feature_run=no + njs_feature_incs="-DPCRE2_CODE_UNIT_WIDTH=8 $NJS_PCRE_CFLAGS" + njs_feature_libs=$NJS_PCRE_LIB + njs_feature_test="#include - if [ $njs_found = yes ]; then - NJS_HAVE_PCRE2=YES - echo " + PCRE2 version: `pcre2-config --version`" - fi - fi -fi - -if [ $njs_found = no ]; then - if /bin/sh -c "(pcre-config --version)" >> $NJS_AUTOCONF_ERR 2>&1; then - - NJS_PCRE_CFLAGS=`pcre-config --cflags` - NJS_PCRE_LIB=`pcre-config --libs` + int main(void) { + pcre2_code *re; - njs_feature="PCRE library" - njs_feature_name=NJS_HAVE_PCRE - njs_feature_run=no - njs_feature_incs=$NJS_PCRE_CFLAGS - njs_feature_libs=$NJS_PCRE_LIB - njs_feature_test="#include + re = pcre2_compile((PCRE2_SPTR)\"\", + PCRE2_ZERO_TERMINATED, 0, + NULL, NULL, NULL); + return (re == NULL); + }" - int main(void) { - pcre *re; + . auto/feature - re = pcre_compile(NULL, 0, NULL, 0, NULL); - if (re == NULL) - return 1; - return 0; - }" - . auto/feature + if [ $njs_found = yes ]; then + NJS_HAVE_PCRE=YES + echo " + PCRE2 version: `pcre2-config --version`" + fi + fi + fi - if [ $njs_found = yes ]; then - echo " + PCRE version: `pcre-config --version`" + if [ $njs_found = no ]; then + if /bin/sh -c "(pcre-config --version)" >> $NJS_AUTOCONF_ERR 2>&1; then + + NJS_PCRE_CFLAGS=`pcre-config --cflags` + NJS_PCRE_LIB=`pcre-config --libs` + + njs_feature="PCRE library" + njs_feature_name=NJS_HAVE_PCRE + njs_feature_run=no + njs_feature_incs=$NJS_PCRE_CFLAGS + njs_feature_libs=$NJS_PCRE_LIB + njs_feature_test="#include + + int main(void) { + pcre *re; + + re = pcre_compile(NULL, 0, NULL, 0, NULL); + if (re == NULL) + return 1; + return 0; + }" + . auto/feature + + if [ $njs_found = yes ]; then + NJS_HAVE_PCRE=YES + echo " + PCRE version: `pcre-config --version`" + fi fi fi -fi -if [ $njs_found = no ]; then - echo - echo $0: error: no PCRE library found. - echo - exit 1; + if [ $njs_found = no ]; then + echo + echo $0: error: no PCRE library found. + echo + exit 1; + fi + fi diff --git a/auto/sources b/auto/sources index 21ca3345..cdbda94c 100644 --- a/auto/sources +++ b/auto/sources @@ -59,14 +59,6 @@ NJS_LIB_SRCS=" \ src/njs_async.c \ " -NJS_LIB_PCRE_SRCS=" \ - src/njs_pcre.c \ -" - -NJS_LIB_PCRE2_SRCS=" \ - src/njs_pcre2.c \ -" - NJS_LIB_TEST_SRCS=" \ src/test/lvlhsh_unit_test.c \ src/test/random_unit_test.c \ @@ -79,10 +71,8 @@ NJS_TEST_SRCS=" \ src/test/njs_benchmark.c \ " -if [ "$NJS_HAVE_PCRE2" = "YES" ]; then - NJS_LIB_SRCS="$NJS_LIB_SRCS $NJS_LIB_PCRE2_SRCS" -else - NJS_LIB_SRCS="$NJS_LIB_SRCS $NJS_LIB_PCRE_SRCS" +if [ "$NJS_PCRE" = "YES" ]; then + NJS_LIB_SRCS="$NJS_LIB_SRCS external/njs_regex.c" fi NJS_TS_SRCS=$(find ts/ -name "*.d.ts" -o -name "*.json") diff --git a/auto/summary b/auto/summary index 154d47c6..8d17807b 100644 --- a/auto/summary +++ b/auto/summary @@ -9,7 +9,10 @@ echo echo " + using CC: \"$CC\"" echo " + using CFLAGS: \"$NJS_CFLAGS $NJS_CC_OPT $CFLAGS\"" echo -echo " + using PCRE library: $NJS_PCRE_LIB" + +if [ $NJS_HAVE_PCRE = YES ]; then + echo " + using PCRE library: $NJS_PCRE_LIB" +fi if [ $NJS_HAVE_READLINE = YES ]; then echo " + using readline library: $NJS_READLINE_LIB" diff --git a/src/njs_pcre.c b/external/njs_regex.c similarity index 63% rename from src/njs_pcre.c rename to external/njs_regex.c index c9e6e9ec..183e52e6 100644 --- a/src/njs_pcre.c +++ b/external/njs_regex.c @@ -1,12 +1,23 @@ /* * Copyright (C) Igor Sysoev + * Copyright (C) Dmitry Volyntsev * Copyright (C) NGINX, Inc. */ #include +#ifdef NJS_HAVE_PCRE2 + +#define PCRE2_CODE_UNIT_WIDTH 8 +#include + + +static const u_char* njs_regex_pcre2_error(int errcode, u_char buffer[128]); + +#else + #include @@ -16,11 +27,19 @@ static void njs_pcre_free(void *p); static njs_regex_generic_ctx_t *regex_context; +#endif + njs_regex_generic_ctx_t * njs_regex_generic_ctx_create(njs_pcre_malloc_t private_malloc, njs_pcre_free_t private_free, void *memory_data) { +#ifdef NJS_HAVE_PCRE2 + + return pcre2_general_context_create(private_malloc, private_free, + memory_data); +#else + njs_regex_generic_ctx_t *ctx; ctx = private_malloc(sizeof(njs_regex_generic_ctx_t), memory_data); @@ -32,29 +51,46 @@ njs_regex_generic_ctx_create(njs_pcre_malloc_t private_malloc, } return ctx; + +#endif } njs_regex_compile_ctx_t * njs_regex_compile_ctx_create(njs_regex_generic_ctx_t *ctx) { +#ifdef NJS_HAVE_PCRE2 + + return pcre2_compile_context_create(ctx); + +#else + return ctx; + +#endif } -/* - * 1) PCRE with PCRE_JAVASCRIPT_COMPAT flag rejects regexps with - * lone closing square brackets as invalid. Whereas according - * to ES6: 11.8.5 it is a valid regexp expression. - * - * 2) escaping zero byte characters as "\u0000". - * - * Escaping it here as a workaround. - */ njs_int_t njs_regex_escape(njs_mp_t *mp, njs_str_t *text) { +#ifdef NJS_HAVE_PCRE2 + + return NJS_OK; + +#else + + /* + * 1) PCRE with PCRE_JAVASCRIPT_COMPAT flag rejects regexps with + * lone closing square brackets as invalid. Whereas according + * to ES6: 11.8.5 it is a valid regexp expression. + * + * 2) escaping zero byte characters as "\u0000". + * + * Escaping it here as a workaround. + */ + size_t brackets, zeros; u_char *p, *dst, *start, *end; njs_bool_t in; @@ -151,6 +187,8 @@ done: text->length = dst - text->start; return NJS_OK; + +#endif } @@ -158,6 +196,112 @@ njs_int_t njs_regex_compile(njs_regex_t *regex, u_char *source, size_t len, njs_regex_flags_t flags, njs_regex_compile_ctx_t *cctx, njs_trace_t *trace) { +#ifdef NJS_HAVE_PCRE2 + + int ret; + u_char *error; + size_t erroff; + njs_uint_t options; + u_char errstr[128]; + + options = PCRE2_ALT_BSUX | PCRE2_MATCH_UNSET_BACKREF; + + if ((flags & NJS_REGEX_IGNORE_CASE)) { + options |= PCRE2_CASELESS; + } + + if ((flags & NJS_REGEX_MULTILINE)) { + options |= PCRE2_MULTILINE; + } + + if ((flags & NJS_REGEX_STICKY)) { + options |= PCRE2_ANCHORED; + } + + if ((flags & NJS_REGEX_UTF8)) { + options |= PCRE2_UTF; + } + + regex->code = pcre2_compile(source, len, options, &ret, &erroff, cctx); + + if (njs_slow_path(regex->code == NULL)) { + error = &source[erroff]; + + njs_alert(trace, NJS_LEVEL_ERROR, + "pcre_compile2(\"%s\") failed: %s at \"%s\"", + source, njs_regex_pcre2_error(ret, errstr), error); + + return NJS_DECLINED; + } + + ret = pcre2_pattern_info(regex->code, PCRE2_INFO_CAPTURECOUNT, + ®ex->ncaptures); + + if (njs_slow_path(ret < 0)) { + njs_alert(trace, NJS_LEVEL_ERROR, + "pcre2_pattern_info(\"%s\", PCRE2_INFO_CAPTURECOUNT) failed: %s", + source, njs_regex_pcre2_error(ret, errstr)); + + return NJS_ERROR; + } + + ret = pcre2_pattern_info(regex->code, PCRE2_INFO_BACKREFMAX, + ®ex->backrefmax); + + if (njs_slow_path(ret < 0)) { + njs_alert(trace, NJS_LEVEL_ERROR, + "pcre2_pattern_info(\"%s\", PCRE2_INFO_BACKREFMAX) failed: %s", + source, njs_regex_pcre2_error(ret, errstr)); + + return NJS_ERROR; + } + + /* Reserve additional elements for the first "$0" capture. */ + regex->ncaptures++; + + if (regex->ncaptures > 1) { + ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMECOUNT, + ®ex->nentries); + + if (njs_slow_path(ret < 0)) { + njs_alert(trace, NJS_LEVEL_ERROR, + "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMECOUNT) failed: %s", + source, njs_regex_pcre2_error(ret, errstr)); + + return NJS_ERROR; + } + + if (regex->nentries != 0) { + ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMEENTRYSIZE, + ®ex->entry_size); + + if (njs_slow_path(ret < 0)) { + njs_alert(trace, NJS_LEVEL_ERROR, + "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMEENTRYSIZE)" + " failed: %s", source, + njs_regex_pcre2_error(ret, errstr)); + + return NJS_ERROR; + } + + ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMETABLE, + ®ex->entries); + + if (njs_slow_path(ret < 0)) { + njs_alert(trace, NJS_LEVEL_ERROR, + "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMETABLE) " + "failed: %s", source, + njs_regex_pcre2_error(ret, errstr)); + + return NJS_ERROR; + } + } + } + + return NJS_OK; + +#else + int ret, err, erroff; char *pattern, *error; void *(*saved_malloc)(size_t size); @@ -297,6 +441,8 @@ done: regex_context = NULL; return ret; + +#endif } @@ -332,6 +478,16 @@ njs_regex_named_captures(njs_regex_t *regex, njs_str_t *name, int n) njs_regex_match_data_t * njs_regex_match_data(njs_regex_t *regex, njs_regex_generic_ctx_t *ctx) { +#ifdef NJS_HAVE_PCRE2 + + if (regex != NULL) { + return pcre2_match_data_create_from_pattern(regex->code, ctx); + } + + return pcre2_match_data_create(0, ctx); + +#else + size_t size; njs_uint_t ncaptures; njs_regex_match_data_t *match_data; @@ -354,6 +510,8 @@ njs_regex_match_data(njs_regex_t *regex, njs_regex_generic_ctx_t *ctx) } return match_data; + +#endif } @@ -361,21 +519,15 @@ void njs_regex_match_data_free(njs_regex_match_data_t *match_data, njs_regex_generic_ctx_t *ctx) { - ctx->private_free(match_data, ctx->memory_data); -} +#ifdef NJS_HAVE_PCRE2 + pcre2_match_data_free(match_data); -static void * -njs_pcre_malloc(size_t size) -{ - return regex_context->private_malloc(size, regex_context->memory_data); -} +#else + ctx->private_free(match_data, ctx->memory_data); -static void -njs_pcre_free(void *p) -{ - regex_context->private_free(p, regex_context->memory_data); +#endif } @@ -383,6 +535,27 @@ njs_int_t njs_regex_match(njs_regex_t *regex, const u_char *subject, size_t off, size_t len, njs_regex_match_data_t *match_data, njs_trace_t *trace) { +#ifdef NJS_HAVE_PCRE2 + + int ret; + u_char errstr[128]; + + ret = pcre2_match(regex->code, subject, len, off, 0, match_data, NULL); + + if (ret < 0) { + if (ret == PCRE2_ERROR_NOMATCH) { + return NJS_DECLINED; + } + + njs_alert(trace, NJS_LEVEL_ERROR, "pcre2_match() failed: %s", + njs_regex_pcre2_error(ret, errstr)); + return NJS_ERROR; + } + + return ret; + +#else + int ret; ret = pcre_exec(regex->code, regex->extra, (const char *) subject, len, @@ -398,11 +571,58 @@ njs_regex_match(njs_regex_t *regex, const u_char *subject, size_t off, } return ret; + +#endif } size_t njs_regex_capture(njs_regex_match_data_t *match_data, njs_uint_t n) { +#ifdef NJS_HAVE_PCRE2 + + size_t c; + + c = pcre2_get_ovector_pointer(match_data)[n]; + + if (c == PCRE2_UNSET) { + return NJS_REGEX_UNSET; + } + + return c; + +#else + return match_data->captures[n]; + +#endif +} + +#ifdef NJS_HAVE_PCRE2 + +static const u_char * +njs_regex_pcre2_error(int errcode, u_char buffer[128]) +{ + pcre2_get_error_message(errcode, buffer, 128); + + return buffer; +} + +#else + +static void * +njs_pcre_malloc(size_t size) +{ + return regex_context->private_malloc(size, regex_context->memory_data); +} + + +static void +njs_pcre_free(void *p) +{ + regex_context->private_free(p, regex_context->memory_data); } + +#endif + + diff --git a/nginx/config b/nginx/config index 3b4de102..1cc3c436 100644 --- a/nginx/config +++ b/nginx/config @@ -4,6 +4,7 @@ NJS_DEPS="$ngx_addon_dir/ngx_js.h \ $ngx_addon_dir/ngx_js_fetch.h" NJS_SRCS="$ngx_addon_dir/ngx_js.c \ $ngx_addon_dir/ngx_js_fetch.c \ + $ngx_addon_dir/ngx_js_regex.c \ $ngx_addon_dir/../external/njs_webcrypto_module.c" if [ $HTTP != NO ]; then diff --git a/nginx/config.make b/nginx/config.make index 7210c0da..64e43515 100644 --- a/nginx/config.make +++ b/nginx/config.make @@ -3,7 +3,7 @@ cat << END >> $NGX_MAKEFILE $ngx_addon_dir/../build/libnjs.a: $NGX_MAKEFILE cd $ngx_addon_dir/.. \\ && if [ -f build/Makefile ]; then \$(MAKE) clean; fi \\ - && CFLAGS="\$(CFLAGS)" CC="\$(CC)" ./configure --no-openssl --no-pcre2 \\ - && \$(MAKE) + && CFLAGS="\$(CFLAGS)" CC="\$(CC)" ./configure --no-openssl --no-pcre \\ + && \$(MAKE) libnjs END diff --git a/nginx/ngx_js_regex.c b/nginx/ngx_js_regex.c new file mode 100644 index 00000000..b88316ef --- /dev/null +++ b/nginx/ngx_js_regex.c @@ -0,0 +1,16 @@ + +/* + * Copyright (C) Dmitry Volyntsev + * Copyright (C) NGINX, Inc. + */ + + +#include + +#if (NGX_PCRE2) + +#define NJS_HAVE_PCRE2 1 + +#endif + +#include "../external/njs_regex.c" diff --git a/src/njs_pcre2.c b/src/njs_pcre2.c deleted file mode 100644 index 1cebc45d..00000000 --- a/src/njs_pcre2.c +++ /dev/null @@ -1,240 +0,0 @@ - -/* - * Copyright (C) Dmitry Volyntsev - * Copyright (C) NGINX, Inc. - */ - - -#include - -#define PCRE2_CODE_UNIT_WIDTH 8 -#include - - -static const u_char* njs_regex_pcre2_error(int errcode, u_char buffer[128]); - - -njs_regex_generic_ctx_t * -njs_regex_generic_ctx_create(njs_pcre_malloc_t private_malloc, - njs_pcre_free_t private_free, void *memory_data) -{ - return pcre2_general_context_create(private_malloc, private_free, - memory_data); -} - - -njs_regex_compile_ctx_t * -njs_regex_compile_ctx_create(njs_regex_generic_ctx_t *ctx) -{ - return pcre2_compile_context_create(ctx); -} - - -njs_int_t -njs_regex_escape(njs_mp_t *mp, njs_str_t *text) -{ - return NJS_OK; -} - - -njs_int_t -njs_regex_compile(njs_regex_t *regex, u_char *source, size_t len, - njs_regex_flags_t flags, njs_regex_compile_ctx_t *ctx, njs_trace_t *trace) -{ - int ret; - u_char *error; - size_t erroff; - njs_uint_t options; - u_char errstr[128]; - - options = PCRE2_ALT_BSUX | PCRE2_MATCH_UNSET_BACKREF; - - if ((flags & NJS_REGEX_IGNORE_CASE)) { - options |= PCRE2_CASELESS; - } - - if ((flags & NJS_REGEX_MULTILINE)) { - options |= PCRE2_MULTILINE; - } - - if ((flags & NJS_REGEX_STICKY)) { - options |= PCRE2_ANCHORED; - } - - if ((flags & NJS_REGEX_UTF8)) { - options |= PCRE2_UTF; - } - - regex->code = pcre2_compile(source, len, options, &ret, &erroff, ctx); - - if (njs_slow_path(regex->code == NULL)) { - error = &source[erroff]; - - njs_alert(trace, NJS_LEVEL_ERROR, - "pcre_compile2(\"%s\") failed: %s at \"%s\"", - source, njs_regex_pcre2_error(ret, errstr), error); - - return NJS_DECLINED; - } - - ret = pcre2_pattern_info(regex->code, PCRE2_INFO_CAPTURECOUNT, - ®ex->ncaptures); - - if (njs_slow_path(ret < 0)) { - njs_alert(trace, NJS_LEVEL_ERROR, - "pcre2_pattern_info(\"%s\", PCRE2_INFO_CAPTURECOUNT) failed: %s", - source, njs_regex_pcre2_error(ret, errstr)); - - return NJS_ERROR; - } - - ret = pcre2_pattern_info(regex->code, PCRE2_INFO_BACKREFMAX, - ®ex->backrefmax); - - if (njs_slow_path(ret < 0)) { - njs_alert(trace, NJS_LEVEL_ERROR, - "pcre2_pattern_info(\"%s\", PCRE2_INFO_BACKREFMAX) failed: %s", - source, njs_regex_pcre2_error(ret, errstr)); - - return NJS_ERROR; - } - - /* Reserve additional elements for the first "$0" capture. */ - regex->ncaptures++; - - if (regex->ncaptures > 1) { - ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMECOUNT, - ®ex->nentries); - - if (njs_slow_path(ret < 0)) { - njs_alert(trace, NJS_LEVEL_ERROR, - "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMECOUNT) failed: %s", - source, njs_regex_pcre2_error(ret, errstr)); - - return NJS_ERROR; - } - - if (regex->nentries != 0) { - ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMEENTRYSIZE, - ®ex->entry_size); - - if (njs_slow_path(ret < 0)) { - njs_alert(trace, NJS_LEVEL_ERROR, - "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMEENTRYSIZE)" - " failed: %s", source, - njs_regex_pcre2_error(ret, errstr)); - - return NJS_ERROR; - } - - ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMETABLE, - ®ex->entries); - - if (njs_slow_path(ret < 0)) { - njs_alert(trace, NJS_LEVEL_ERROR, - "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMETABLE) " - "failed: %s", source, - njs_regex_pcre2_error(ret, errstr)); - - return NJS_ERROR; - } - } - } - - return NJS_OK; -} - - -njs_bool_t -njs_regex_is_valid(njs_regex_t *regex) -{ - return (regex->code != NULL); -} - - -njs_int_t -njs_regex_named_captures(njs_regex_t *regex, njs_str_t *name, int n) -{ - char *entry; - - if (name == NULL) { - return regex->nentries; - } - - if (n >= regex->nentries) { - return NJS_ERROR; - } - - entry = regex->entries + regex->entry_size * n; - - name->start = (u_char *) entry + 2; - name->length = njs_strlen(name->start); - - return (entry[0] << 8) + entry[1]; -} - - -njs_regex_match_data_t * -njs_regex_match_data(njs_regex_t *regex, njs_regex_generic_ctx_t *ctx) -{ - if (regex != NULL) { - return pcre2_match_data_create_from_pattern(regex->code, ctx); - } - - return pcre2_match_data_create(0, ctx); -} - - -void -njs_regex_match_data_free(njs_regex_match_data_t *match_data, - njs_regex_generic_ctx_t *unused) -{ - pcre2_match_data_free(match_data); -} - - -njs_int_t -njs_regex_match(njs_regex_t *regex, const u_char *subject, size_t off, - size_t len, njs_regex_match_data_t *match_data, njs_trace_t *trace) -{ - int ret; - u_char errstr[128]; - - ret = pcre2_match(regex->code, subject, len, off, 0, match_data, NULL); - - if (ret < 0) { - if (ret == PCRE2_ERROR_NOMATCH) { - return NJS_DECLINED; - } - - njs_alert(trace, NJS_LEVEL_ERROR, "pcre2_match() failed: %s", - njs_regex_pcre2_error(ret, errstr)); - return NJS_ERROR; - } - - return ret; -} - - -size_t -njs_regex_capture(njs_regex_match_data_t *match_data, njs_uint_t n) -{ - size_t c; - - c = pcre2_get_ovector_pointer(match_data)[n]; - - if (c == PCRE2_UNSET) { - return NJS_REGEX_UNSET; - } - - return c; -} - - -static const u_char * -njs_regex_pcre2_error(int errcode, u_char buffer[128]) -{ - pcre2_get_error_message(errcode, buffer, 128); - - return buffer; -}