[njs] PCRE code is available via nxt_regex interface.
Igor Sysoev
igor at sysoev.ru
Wed Jun 1 12:50:36 UTC 2016
details: http://hg.nginx.org/njs/rev/b8084a72d667
branches:
changeset: 112:b8084a72d667
user: Igor Sysoev <igor at 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_ */
More information about the nginx-devel
mailing list