details: http://hg.nginx.org/njs/rev/b8084a72d667 branches: changeset: 112:b8084a72d667 user: Igor Sysoev <i...@sysoev.ru> date: Wed Jun 01 15:30:50 2016 +0300 description: PCRE code is available via nxt_regex interface.
diffstat: nxt/Makefile | 35 +++++-- nxt/nxt_pcre.c | 259 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nxt/nxt_pcre.h | 34 +++++++ nxt/nxt_regex.h | 42 +++++++++ 4 files changed, 359 insertions(+), 11 deletions(-) diffs (414 lines): diff -r 1c96b24bcdd2 -r b8084a72d667 nxt/Makefile --- a/nxt/Makefile Fri Apr 29 17:02:52 2016 +0300 +++ b/nxt/Makefile Wed Jun 01 15:30:50 2016 +0300 @@ -10,6 +10,7 @@ NXT_LIB = nxt $(NXT_BUILDDIR)/nxt_rbtree.o \ $(NXT_BUILDDIR)/nxt_lvlhsh.o \ $(NXT_BUILDDIR)/nxt_random.o \ + $(NXT_BUILDDIR)/nxt_pcre.o \ $(NXT_BUILDDIR)/nxt_malloc.o \ $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \ @@ -19,8 +20,9 @@ NXT_LIB = nxt $(NXT_BUILDDIR)/nxt_array.o \ $(NXT_BUILDDIR)/nxt_rbtree.o \ $(NXT_BUILDDIR)/nxt_lvlhsh.o \ + $(NXT_BUILDDIR)/nxt_random.o \ + $(NXT_BUILDDIR)/nxt_pcre.o \ $(NXT_BUILDDIR)/nxt_malloc.o \ - $(NXT_BUILDDIR)/nxt_random.o \ $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \ $(NXT_BUILDDIR)/nxt_murmur_hash.o: \ @@ -95,6 +97,27 @@ NXT_LIB = nxt -I$(NXT_LIB) \ $(NXT_LIB)/nxt_lvlhsh.c +$(NXT_BUILDDIR)/nxt_random.o: \ + $(NXT_LIB)/nxt_types.h \ + $(NXT_LIB)/nxt_clang.h \ + $(NXT_LIB)/nxt_random.h \ + $(NXT_LIB)/nxt_random.c \ + + $(NXT_CC) -c -o $(NXT_BUILDDIR)/nxt_random.o $(NXT_CFLAGS) \ + -I$(NXT_LIB) \ + $(NXT_LIB)/nxt_random.c + +$(NXT_BUILDDIR)/nxt_pcre.o: \ + $(NXT_LIB)/nxt_types.h \ + $(NXT_LIB)/nxt_clang.h \ + $(NXT_LIB)/nxt_regex.h \ + $(NXT_LIB)/nxt_pcre.h \ + $(NXT_LIB)/nxt_pcre.c \ + + $(NXT_CC) -c -o $(NXT_BUILDDIR)/nxt_pcre.o $(NXT_CFLAGS) \ + -I$(NXT_LIB) $(NXT_PCRE_CFLAGS) \ + $(NXT_LIB)/nxt_pcre.c + $(NXT_BUILDDIR)/nxt_malloc.o: \ $(NXT_LIB)/nxt_auto_config.h \ $(NXT_LIB)/nxt_types.h \ @@ -106,16 +129,6 @@ NXT_LIB = nxt -I$(NXT_LIB) \ $(NXT_LIB)/nxt_malloc.c -$(NXT_BUILDDIR)/nxt_random.o: \ - $(NXT_LIB)/nxt_types.h \ - $(NXT_LIB)/nxt_clang.h \ - $(NXT_LIB)/nxt_random.h \ - $(NXT_LIB)/nxt_random.c \ - - $(NXT_CC) -c -o $(NXT_BUILDDIR)/nxt_random.o $(NXT_CFLAGS) \ - -I$(NXT_LIB) \ - $(NXT_LIB)/nxt_random.c - $(NXT_BUILDDIR)/nxt_mem_cache_pool.o: \ $(NXT_LIB)/nxt_types.h \ $(NXT_LIB)/nxt_clang.h \ diff -r 1c96b24bcdd2 -r b8084a72d667 nxt/nxt_pcre.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/nxt_pcre.c Wed Jun 01 15:30:50 2016 +0300 @@ -0,0 +1,259 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#include <nxt_types.h> +#include <nxt_clang.h> +#include <nxt_stub.h> +#include <nxt_regex.h> +#include <nxt_pcre.h> +#include <stdio.h> +#include <string.h> + + +static void *nxt_pcre_malloc(size_t size); +static void nxt_pcre_free(void *p); +static void *nxt_pcre_default_malloc(size_t size, void *memory_data); +static void nxt_pcre_default_free(void *p, void *memory_data); + + +static nxt_regex_context_t *regex_context; + + +nxt_regex_context_t * +nxt_regex_context_create(nxt_pcre_malloc_t private_malloc, + nxt_pcre_free_t private_free, void *memory_data) +{ + nxt_regex_context_t *ctx; + + if (private_malloc == NULL) { + private_malloc = nxt_pcre_default_malloc; + private_free = nxt_pcre_default_free; + } + + ctx = private_malloc(sizeof(nxt_regex_context_t), memory_data); + + if (nxt_fast_path(ctx != NULL)) { + ctx->private_malloc = private_malloc; + ctx->private_free = private_free; + ctx->memory_data = memory_data; + } + + return ctx; +} + + +nxt_int_t +nxt_regex_compile(nxt_regex_t *regex, u_char *source, size_t len, + nxt_uint_t options, nxt_regex_context_t *ctx) +{ + int ret, err, erroff; + char *pattern, *error; + void *(*saved_malloc)(size_t size); + void (*saved_free)(void *p); + size_t size; + const char *errstr; + + ret = NXT_ERROR; + + saved_malloc = pcre_malloc; + pcre_malloc = nxt_pcre_malloc; + saved_free = pcre_free; + pcre_free = nxt_pcre_free; + regex_context = ctx; + + if (len == 0) { + pattern = (char *) source; + + } else { + pattern = ctx->private_malloc(len + 1, ctx->memory_data); + if (nxt_slow_path(pattern == NULL)) { + goto done; + } + + memcpy(pattern, source, len); + pattern[len] = '\0'; + } + + regex->code = pcre_compile(pattern, options, &errstr, &erroff, NULL); + + if (nxt_slow_path(regex->code == NULL)) { + error = pattern + erroff; + + size = sizeof("pcre_compile(\"\") failed: at \"\"") + + strlen(errstr) + strlen(error) * 2 + erroff; + + ctx->error = ctx->private_malloc(size, ctx->memory_data); + if (nxt_slow_path(ctx->error == NULL)) { + goto done; + } + + if (*error != '\0') { + (void) snprintf((char *) ctx->error, size, + "pcre_compile(\"%s\") failed: %s at \"%s\"", + pattern, errstr, error); + } else { + (void) snprintf((char *) ctx->error, size, + "pcre_compile(\"%s\") failed: %s", + pattern, errstr); + } + + goto done; + } + + regex->extra = pcre_study(regex->code, 0, &errstr); + + if (nxt_slow_path(errstr != NULL)) { + size = sizeof("pcre_study(\"\") failed: ") + + strlen(pattern) + strlen(errstr); + + ctx->error = ctx->private_malloc(size, ctx->memory_data); + if (nxt_slow_path(ctx->error == NULL)) { + goto done; + } + + (void) snprintf((char *) ctx->error, size, + "pcre_study(\"%s\") failed: %s", pattern, errstr); + + goto done; + } + + err = pcre_fullinfo(regex->code, NULL, PCRE_INFO_CAPTURECOUNT, + ®ex->ncaptures); + + if (nxt_slow_path(err < 0)) { + size = sizeof("pcre_fullinfo(\"\", PCRE_INFO_CAPTURECOUNT) failed: ") + + strlen(pattern) + sizeof("-2147483647"); + + ctx->error = ctx->private_malloc(size, ctx->memory_data); + if (nxt_slow_path(ctx->error == NULL)) { + goto done; + } + + (void) snprintf((char *) ctx->error, size, + "pcre_fullinfo(\"%s\", PCRE_INFO_CAPTURECOUNT) failed: %d", + pattern, err); + + goto done; + } + + /* Reserve additional elements for the first "$0" capture. */ + regex->ncaptures++; + + ret = NXT_OK; + +done: + + pcre_malloc = saved_malloc; + pcre_free = saved_free; + regex_context = NULL; + + return ret; +} + + +nxt_regex_match_data_t * +nxt_regex_match_data(nxt_regex_t *regex, nxt_regex_context_t *ctx) +{ + size_t size; + nxt_uint_t ncaptures; + nxt_regex_match_data_t *match_data; + + if (regex != NULL) { + ncaptures = regex->ncaptures - 1; + + } else { + ncaptures = 0; + } + + /* Each capture is stored in 3 "int" vector elements. */ + ncaptures *= 3; + size = sizeof(nxt_regex_match_data_t) + ncaptures * sizeof(int); + + match_data = ctx->private_malloc(size, ctx->memory_data); + + if (nxt_fast_path(match_data != NULL)) { + match_data->ncaptures = ncaptures + 3; + } + + return match_data; +} + + +void +nxt_regex_match_data_free(nxt_regex_match_data_t *match_data, + nxt_regex_context_t *ctx) +{ + ctx->private_free(match_data, ctx->memory_data); +} + + +static void * +nxt_pcre_malloc(size_t size) +{ + return regex_context->private_malloc(size, regex_context->memory_data); +} + + +static void +nxt_pcre_free(void *p) +{ + regex_context->private_free(p, regex_context->memory_data); +} + + +static void * +nxt_pcre_default_malloc(size_t size, void *memory_data) +{ + return malloc(size); +} + + +static void +nxt_pcre_default_free(void *p, void *memory_data) +{ + free(p); +} + + +nxt_bool_t +nxt_regex_is_valid(nxt_regex_t *regex) +{ + return (regex->code != NULL); +} + + +nxt_int_t +nxt_regex_match(nxt_regex_t *regex, u_char *subject, size_t len, + nxt_regex_match_data_t *match_data, nxt_regex_context_t *ctx) +{ + int ret; + size_t size; + + ret = pcre_exec(regex->code, regex->extra, (char *) subject, len, 0, 0, + match_data->captures, match_data->ncaptures); + + /* PCRE_ERROR_NOMATCH is -1. */ + + if (nxt_slow_path(ret < PCRE_ERROR_NOMATCH)) { + size = sizeof("pcre_exec() failed: ") + sizeof("-2147483647"); + + ctx->error = ctx->private_malloc(size, ctx->memory_data); + + if (nxt_fast_path(ctx->error != NULL)) { + (void) snprintf((char *) ctx->error, size, "pcre_exec() failed: %d", + ret); + } + } + + return ret; +} + + +int * +nxt_regex_captures(nxt_regex_match_data_t *match_data) +{ + return (match_data)->captures; +} diff -r 1c96b24bcdd2 -r b8084a72d667 nxt/nxt_pcre.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/nxt_pcre.h Wed Jun 01 15:30:50 2016 +0300 @@ -0,0 +1,34 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#ifndef _NXT_PCRE_H_INCLUDED_ +#define _NXT_PCRE_H_INCLUDED_ + + +#include <pcre.h> + + +#define NGX_REGEX_NOMATCH PCRE_ERROR_NOMATCH + + +struct nxt_regex_s { + pcre *code; + pcre_extra *extra; + int ncaptures; +}; + + +struct nxt_regex_match_data_s { + int ncaptures; + /* + * Each capture is stored in 3 "int" vector elements. + * The first vector is for the "$0" capture and it is always allocated. + */ + int captures[3]; +}; + + +#endif /* _NXT_PCRE_H_INCLUDED_ */ diff -r 1c96b24bcdd2 -r b8084a72d667 nxt/nxt_regex.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/nxt_regex.h Wed Jun 01 15:30:50 2016 +0300 @@ -0,0 +1,42 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#ifndef _NXT_REGEX_H_INCLUDED_ +#define _NXT_REGEX_H_INCLUDED_ + + +typedef void *(*nxt_pcre_malloc_t)(size_t size, void *memory_data); +typedef void (*nxt_pcre_free_t)(void *p, void *memory_data); + + +typedef struct nxt_regex_s nxt_regex_t; +typedef struct nxt_regex_match_data_s nxt_regex_match_data_t; + + +typedef struct { + nxt_pcre_malloc_t private_malloc; + nxt_pcre_free_t private_free; + void *memory_data; + u_char *error; +} nxt_regex_context_t; + + +NXT_EXPORT nxt_regex_context_t * + nxt_regex_context_create(nxt_pcre_malloc_t private_malloc, + nxt_pcre_free_t private_free, void *memory_data); +NXT_EXPORT nxt_int_t nxt_regex_compile(nxt_regex_t *regex, u_char *source, + size_t len, nxt_uint_t options, nxt_regex_context_t *ctx); +NXT_EXPORT nxt_bool_t nxt_regex_is_valid(nxt_regex_t *regex); +NXT_EXPORT nxt_regex_match_data_t *nxt_regex_match_data(nxt_regex_t *regex, + nxt_regex_context_t *ctx); +NXT_EXPORT void nxt_regex_match_data_free(nxt_regex_match_data_t *match_data, + nxt_regex_context_t *ctx); +NXT_EXPORT nxt_int_t nxt_regex_match(nxt_regex_t *regex, u_char *subject, + size_t len, nxt_regex_match_data_t *match_data, nxt_regex_context_t *ctx); +NXT_EXPORT int *nxt_regex_captures(nxt_regex_match_data_t *match_data); + + +#endif /* _NXT_REGEX_H_INCLUDED_ */ _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel