Compare commits
7 commits
c9s-patch-
...
2.0
Author | SHA1 | Date | |
---|---|---|---|
ade1527bef | |||
|
c1aab00c40 | ||
|
9887545ab0 | ||
|
c105117b40 | ||
|
9168f7e4d4 | ||
|
58d8b0c028 | ||
|
91405adda5 |
15 changed files with 105 additions and 124 deletions
34
.github/workflows/coverity.yml
vendored
34
.github/workflows/coverity.yml
vendored
|
@ -1,5 +1,7 @@
|
||||||
name: coverity
|
name: coverity
|
||||||
on: [push, pull_request]
|
on:
|
||||||
|
push:
|
||||||
|
branches: [2.0]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
analyze:
|
analyze:
|
||||||
|
@ -7,27 +9,13 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Download Coverity
|
- name: Prepare
|
||||||
run: |
|
|
||||||
cd ..
|
|
||||||
wget -q https://scan.coverity.com/download/linux64 --post-data "token=${{secrets.COVERITY_TOKEN}}&project=r3" -O coverity-linux64.tgz
|
|
||||||
mkdir coverity
|
|
||||||
tar xzf coverity-linux64.tgz --strip 1 -C coverity
|
|
||||||
echo "$(pwd)/coverity/bin" >> $GITHUB_PATH
|
|
||||||
|
|
||||||
- name: Build with Coverity
|
|
||||||
run: |
|
run: |
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
./configure --enable-check --enable-debug
|
./configure --enable-check
|
||||||
cov-build --dir cov-int make V=1
|
- uses: vapier/coverity-scan-action@v1
|
||||||
|
with:
|
||||||
- name: Submit the result to Coverity
|
project: r3
|
||||||
run: |
|
email: yoanlin93+github@gmail.com
|
||||||
tar czvf r3.tgz cov-int
|
token: ${{ secrets.COVERITY_TOKEN }}
|
||||||
curl \
|
|
||||||
--form token=${{secrets.COVERITY_TOKEN}} \
|
|
||||||
--form email=yoanlin93+github@gmail.com \
|
|
||||||
--form file=@r3.tgz \
|
|
||||||
--form version=${GITHUB_SHA} \
|
|
||||||
https://scan.coverity.com/builds?project=r3
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ apt-get install -qq \
|
||||||
cmake \
|
cmake \
|
||||||
graphviz-dev \
|
graphviz-dev \
|
||||||
libjemalloc-dev \
|
libjemalloc-dev \
|
||||||
libpcre3-dev \
|
libpcre2-dev \
|
||||||
libtool \
|
libtool \
|
||||||
ninja-build \
|
ninja-build \
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|
|
@ -5,7 +5,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules)
|
||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
|
||||||
find_package(Check)
|
find_package(Check)
|
||||||
find_package(PCRE REQUIRED)
|
find_package(PCRE2 REQUIRED)
|
||||||
|
|
||||||
include(CheckSymbolExists)
|
include(CheckSymbolExists)
|
||||||
include(CheckIncludeFile)
|
include(CheckIncludeFile)
|
||||||
|
@ -26,7 +26,7 @@ install(
|
||||||
include/r3_json.h
|
include/r3_json.h
|
||||||
include/str_array.h
|
include/str_array.h
|
||||||
include/r3.hpp
|
include/r3.hpp
|
||||||
DESTINATION include)
|
DESTINATION include/r3)
|
||||||
|
|
||||||
# Configure substitutions for r3.pc. The variables set here must match the
|
# Configure substitutions for r3.pc. The variables set here must match the
|
||||||
# @<values>@ in r3.pc.in.
|
# @<values>@ in r3.pc.in.
|
||||||
|
|
10
README.md
10
README.md
|
@ -25,7 +25,7 @@ Requirement
|
||||||
|
|
||||||
### Runtime Requirement
|
### Runtime Requirement
|
||||||
|
|
||||||
* pcre
|
* pcre2
|
||||||
* (optional) graphviz version 2.38.0 (20140413.2041)
|
* (optional) graphviz version 2.38.0 (20140413.2041)
|
||||||
* (optional) libjson-c-dev
|
* (optional) libjson-c-dev
|
||||||
|
|
||||||
|
@ -187,13 +187,13 @@ Optimization
|
||||||
Simple regular expressions are optimized through a regexp pattern to opcode
|
Simple regular expressions are optimized through a regexp pattern to opcode
|
||||||
translator, which translates simple patterns into small & fast scanners.
|
translator, which translates simple patterns into small & fast scanners.
|
||||||
|
|
||||||
By using this method, r3 reduces the matching overhead of pcre library.
|
By using this method, r3 reduces the matching overhead of pcre2 library.
|
||||||
|
|
||||||
Optimized patterns are: `[a-z]+`, `[0-9]+`, `\d+`, `\w+`, `[^/]+`, `[^-]+` or `.*`.
|
Optimized patterns are: `[a-z]+`, `[0-9]+`, `\d+`, `\w+`, `[^/]+`, `[^-]+` or `.*`.
|
||||||
|
|
||||||
Slugs without specified regular expression will be compiled into the `[^/]+` pattern. therefore, it's optimized too.
|
Slugs without specified regular expression will be compiled into the `[^/]+` pattern. therefore, it's optimized too.
|
||||||
|
|
||||||
Complex regular expressions will still use libpcre to match URL (partially).
|
Complex regular expressions will still use libpcre2 to match URL (partially).
|
||||||
|
|
||||||
|
|
||||||
Performance
|
Performance
|
||||||
|
@ -356,7 +356,7 @@ if ( $error ) {
|
||||||
Install
|
Install
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
sudo apt-get install check libpcre3 libpcre3-dev libjemalloc-dev libjemalloc1 build-essential libtool automake autoconf pkg-config
|
sudo apt-get install check libpcre2 libpcre2-dev libjemalloc-dev libjemalloc1 build-essential libtool automake autoconf pkg-config
|
||||||
sudo apt-get install graphviz-dev graphviz # if you want graphviz
|
sudo apt-get install graphviz-dev graphviz # if you want graphviz
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
./configure && make
|
./configure && make
|
||||||
|
@ -364,7 +364,7 @@ Install
|
||||||
|
|
||||||
And we support debian-based distro now!
|
And we support debian-based distro now!
|
||||||
|
|
||||||
sudo apt-get install build-essential autoconf automake libpcre3-dev pkg-config debhelper libtool check
|
sudo apt-get install build-essential autoconf automake libpcre2-dev pkg-config debhelper libtool check
|
||||||
mv dist-debian debian
|
mv dist-debian debian
|
||||||
dpkg-buildpackage -b -us -uc
|
dpkg-buildpackage -b -us -uc
|
||||||
sudo gdebi ../libr3*.deb
|
sudo gdebi ../libr3*.deb
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
# Copyright (C) 2007-2009 LuaDist.
|
|
||||||
# Created by Peter Kapec <kapecp@gmail.com>
|
|
||||||
# Redistribution and use of this file is allowed according to the terms of the MIT license.
|
|
||||||
# For details see the COPYRIGHT file distributed with LuaDist.
|
|
||||||
# Note:
|
|
||||||
# Searching headers and libraries is very simple and is NOT as powerful as scripts
|
|
||||||
# distributed with CMake, because LuaDist defines directories to search for.
|
|
||||||
# Everyone is encouraged to contact the author with improvements. Maybe this file
|
|
||||||
# becomes part of CMake distribution sometimes.
|
|
||||||
|
|
||||||
# - Find pcre
|
|
||||||
# Find the native PCRE headers and libraries.
|
|
||||||
#
|
|
||||||
# PCRE_INCLUDE_DIRS - where to find pcre.h, etc.
|
|
||||||
# PCRE_LIBRARIES - List of libraries when using pcre.
|
|
||||||
# PCRE_FOUND - True if pcre found.
|
|
||||||
|
|
||||||
# Look for the header file.
|
|
||||||
FIND_PATH(PCRE_INCLUDE_DIR NAMES pcre.h)
|
|
||||||
|
|
||||||
# Look for the library.
|
|
||||||
FIND_LIBRARY(PCRE_LIBRARY NAMES pcre)
|
|
||||||
|
|
||||||
# Handle the QUIETLY and REQUIRED arguments and set PCRE_FOUND to TRUE if all listed variables are TRUE.
|
|
||||||
INCLUDE(FindPackageHandleStandardArgs)
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARY PCRE_INCLUDE_DIR)
|
|
||||||
|
|
||||||
# Copy the results to the output variables.
|
|
||||||
IF(PCRE_FOUND)
|
|
||||||
SET(PCRE_LIBRARIES ${PCRE_LIBRARY})
|
|
||||||
SET(PCRE_INCLUDE_DIRS ${PCRE_INCLUDE_DIR})
|
|
||||||
ELSE(PCRE_FOUND)
|
|
||||||
SET(PCRE_LIBRARIES)
|
|
||||||
SET(PCRE_INCLUDE_DIRS)
|
|
||||||
ENDIF(PCRE_FOUND)
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(PCRE_INCLUDE_DIRS PCRE_LIBRARIES)
|
|
37
cmake/Modules/FindPCRE2.cmake
Normal file
37
cmake/Modules/FindPCRE2.cmake
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# Copyright (C) 2007-2009 LuaDist.
|
||||||
|
# Created by Peter Kapec <kapecp@gmail.com>
|
||||||
|
# Redistribution and use of this file is allowed according to the terms of the MIT license.
|
||||||
|
# For details see the COPYRIGHT file distributed with LuaDist.
|
||||||
|
# Note:
|
||||||
|
# Searching headers and libraries is very simple and is NOT as powerful as scripts
|
||||||
|
# distributed with CMake, because LuaDist defines directories to search for.
|
||||||
|
# Everyone is encouraged to contact the author with improvements. Maybe this file
|
||||||
|
# becomes part of CMake distribution sometimes.
|
||||||
|
|
||||||
|
# - Find pcre2
|
||||||
|
# Find the native PCRE2 headers and libraries.
|
||||||
|
#
|
||||||
|
# PCRE2_INCLUDE_DIRS - where to find pcre2.h, etc.
|
||||||
|
# PCRE2_LIBRARIES - List of libraries when using pcre2.
|
||||||
|
# PCRE2_FOUND - True if pcre2 found.
|
||||||
|
|
||||||
|
# Look for the header file.
|
||||||
|
FIND_PATH(PCRE2_INCLUDE_DIR NAMES pcre2.h)
|
||||||
|
|
||||||
|
# Look for the library.
|
||||||
|
FIND_LIBRARY(PCRE2_LIBRARY NAMES pcre2-8)
|
||||||
|
|
||||||
|
# Handle the QUIETLY and REQUIRED arguments and set PCRE2_FOUND to TRUE if all listed variables are TRUE.
|
||||||
|
INCLUDE(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE2 DEFAULT_MSG PCRE2_LIBRARY PCRE2_INCLUDE_DIR)
|
||||||
|
|
||||||
|
# Copy the results to the output variables.
|
||||||
|
IF(PCRE2_FOUND)
|
||||||
|
SET(PCRE2_LIBRARIES ${PCRE2_LIBRARY})
|
||||||
|
SET(PCRE2_INCLUDE_DIRS ${PCRE2_INCLUDE_DIR})
|
||||||
|
ELSE(PCRE2_FOUND)
|
||||||
|
SET(PCRE2_LIBRARIES)
|
||||||
|
SET(PCRE2_INCLUDE_DIRS)
|
||||||
|
ENDIF(PCRE2_FOUND)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(PCRE2_INCLUDE_DIRS PCRE2_LIBRARIES)
|
|
@ -73,7 +73,7 @@ AM_CONDITIONAL(USE_JEMALLOC, test "x$have_jemalloc" = "xyes")
|
||||||
# AC_DEFINE(USE_JEMALLOC, test "x$found_jemalloc" = "xyes" , "use jemalloc")
|
# AC_DEFINE(USE_JEMALLOC, test "x$found_jemalloc" = "xyes" , "use jemalloc")
|
||||||
|
|
||||||
|
|
||||||
PKG_CHECK_MODULES(DEPS, [libpcre])
|
PKG_CHECK_MODULES(DEPS, [libpcre2-8])
|
||||||
AC_SUBST(DEPS_CFLAGS)
|
AC_SUBST(DEPS_CFLAGS)
|
||||||
AC_SUBST(DEPS_LIBS)
|
AC_SUBST(DEPS_LIBS)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ Source: libr3
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Ronmi Ren <ronmi.ren@gmail.com>
|
Maintainer: Ronmi Ren <ronmi.ren@gmail.com>
|
||||||
Build-Depends: debhelper (>= 8.0.0), automake, autotools-dev, autoconf,
|
Build-Depends: debhelper (>= 8.0.0), automake, autotools-dev, autoconf,
|
||||||
libtool, libpcre3-dev, pkg-config, check
|
libtool, libpcre2-dev, pkg-config, check
|
||||||
Standards-Version: 3.9.4
|
Standards-Version: 3.9.4
|
||||||
Section: libs
|
Section: libs
|
||||||
Homepage: https://github.com/c9s/r3
|
Homepage: https://github.com/c9s/r3
|
||||||
|
|
10
include/r3.h
10
include/r3.h
|
@ -10,8 +10,10 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <pcre.h>
|
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||||
|
#include <pcre2.h>
|
||||||
|
|
||||||
|
#if __STDC_VERSION__ <= 201710L
|
||||||
#ifdef HAVE_STDBOOL_H
|
#ifdef HAVE_STDBOOL_H
|
||||||
# include <stdbool.h>
|
# include <stdbool.h>
|
||||||
#elif !defined(bool) && !defined(__cplusplus)
|
#elif !defined(bool) && !defined(__cplusplus)
|
||||||
|
@ -20,6 +22,7 @@ typedef unsigned char bool;
|
||||||
# define false 0
|
# define false 0
|
||||||
# define true 1
|
# define true 1
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "str_array.h"
|
#include "str_array.h"
|
||||||
#include "r3_slug.h"
|
#include "r3_slug.h"
|
||||||
|
@ -41,13 +44,12 @@ struct _node {
|
||||||
R3_VECTOR(R3Edge) edges;
|
R3_VECTOR(R3Edge) edges;
|
||||||
R3_VECTOR(R3Route) routes;
|
R3_VECTOR(R3Route) routes;
|
||||||
char * combined_pattern;
|
char * combined_pattern;
|
||||||
pcre * pcre_pattern;
|
pcre2_code * pcre_pattern;
|
||||||
pcre_extra * pcre_extra;
|
pcre2_match_data * match_data;
|
||||||
|
|
||||||
// edges are mostly less than 255
|
// edges are mostly less than 255
|
||||||
unsigned int compare_type; // compare_type: pcre, opcode, string
|
unsigned int compare_type; // compare_type: pcre, opcode, string
|
||||||
unsigned int endpoint; // endpoint, should be zero for non-endpoint nodes
|
unsigned int endpoint; // endpoint, should be zero for non-endpoint nodes
|
||||||
unsigned int ov_cnt; // capture vector array size for pcre
|
|
||||||
|
|
||||||
// the pointer of R3Route data
|
// the pointer of R3Route data
|
||||||
void * data;
|
void * data;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
|
#if __STDC_VERSION__ <= 201710L
|
||||||
#ifdef HAVE_STDBOOL_H
|
#ifdef HAVE_STDBOOL_H
|
||||||
# include <stdbool.h>
|
# include <stdbool.h>
|
||||||
#elif !defined(bool) && !defined(__cplusplus)
|
#elif !defined(bool) && !defined(__cplusplus)
|
||||||
|
@ -18,6 +19,7 @@ typedef unsigned char bool;
|
||||||
# define false 0
|
# define false 0
|
||||||
# define true 1
|
# define true 1
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _str_array {
|
typedef struct _str_array {
|
||||||
R3_VECTOR(r3_iovec_t) slugs;
|
R3_VECTOR(r3_iovec_t) slugs;
|
||||||
|
|
2
r3.pc.in
2
r3.pc.in
|
@ -6,6 +6,6 @@ libdir=@libdir@
|
||||||
Name: r3
|
Name: r3
|
||||||
Description: High-performance URL router library
|
Description: High-performance URL router library
|
||||||
Version: @PACKAGE_VERSION@
|
Version: @PACKAGE_VERSION@
|
||||||
Requires: libpcre
|
Requires: libpcre2-8
|
||||||
Libs: -L${libdir} -lr3
|
Libs: -L${libdir} -lr3
|
||||||
CFlags: -I${includedir}
|
CFlags: -I${includedir}
|
||||||
|
|
|
@ -13,13 +13,14 @@ target_compile_definitions(r3
|
||||||
|
|
||||||
target_include_directories(r3
|
target_include_directories(r3
|
||||||
PUBLIC
|
PUBLIC
|
||||||
|
${PCRE2_INCLUDE_DIR}
|
||||||
${PROJECT_BINARY_DIR}
|
${PROJECT_BINARY_DIR}
|
||||||
${PROJECT_SOURCE_DIR}/3rdparty
|
${PROJECT_SOURCE_DIR}/3rdparty
|
||||||
${PROJECT_SOURCE_DIR}/include)
|
${PROJECT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
target_link_libraries(r3
|
target_link_libraries(r3
|
||||||
PUBLIC
|
PUBLIC
|
||||||
${PCRE_LIBRARIES})
|
${PCRE2_LIBRARIES})
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS r3
|
TARGETS r3
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
// Jemalloc memory management
|
// Jemalloc memory management
|
||||||
// #include <jemalloc/jemalloc.h>
|
// #include <jemalloc/jemalloc.h>
|
||||||
|
|
||||||
// PCRE
|
|
||||||
#include <pcre.h>
|
|
||||||
#include "r3.h"
|
#include "r3.h"
|
||||||
#include "r3_slug.h"
|
#include "r3_slug.h"
|
||||||
#include "slug.h"
|
#include "slug.h"
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <pcre.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "r3.h"
|
#include "r3.h"
|
||||||
|
|
||||||
|
|
80
src/node.c
80
src/node.c
|
@ -7,9 +7,6 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
// PCRE
|
|
||||||
#include <pcre.h>
|
|
||||||
|
|
||||||
#include "r3.h"
|
#include "r3.h"
|
||||||
#include "r3_slug.h"
|
#include "r3_slug.h"
|
||||||
#include "slug.h"
|
#include "slug.h"
|
||||||
|
@ -75,13 +72,11 @@ void r3_tree_free(R3Node * tree) {
|
||||||
}
|
}
|
||||||
free(tree->routes.entries);
|
free(tree->routes.entries);
|
||||||
if (tree->pcre_pattern) {
|
if (tree->pcre_pattern) {
|
||||||
pcre_free(tree->pcre_pattern);
|
pcre2_code_free(tree->pcre_pattern);
|
||||||
}
|
}
|
||||||
#ifdef PCRE_STUDY_JIT_COMPILE
|
if (tree->match_data) {
|
||||||
if (tree->pcre_extra) {
|
pcre2_match_data_free(tree->match_data);
|
||||||
pcre_free_study(tree->pcre_extra);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
free(tree->combined_pattern);
|
free(tree->combined_pattern);
|
||||||
free(tree);
|
free(tree);
|
||||||
tree = NULL;
|
tree = NULL;
|
||||||
|
@ -223,41 +218,44 @@ int r3_tree_compile_patterns(R3Node * n, char **errstr) {
|
||||||
free(n->combined_pattern);
|
free(n->combined_pattern);
|
||||||
n->combined_pattern = cpat;
|
n->combined_pattern = cpat;
|
||||||
|
|
||||||
const char *pcre_error = NULL;
|
int pcre_errorcode = 0;
|
||||||
int pcre_erroffset = 0;
|
PCRE2_SIZE pcre_erroffset = 0;
|
||||||
unsigned int option_bits = 0;
|
unsigned int option_bits = 0;
|
||||||
|
|
||||||
n->ov_cnt = (1 + n->edges.size) * 3;
|
|
||||||
|
|
||||||
if (n->pcre_pattern) {
|
if (n->pcre_pattern) {
|
||||||
pcre_free(n->pcre_pattern);
|
pcre2_code_free(n->pcre_pattern);
|
||||||
}
|
}
|
||||||
n->pcre_pattern = pcre_compile(
|
n->pcre_pattern = pcre2_compile(
|
||||||
n->combined_pattern, /* the pattern */
|
(PCRE2_SPTR)n->combined_pattern, /* the pattern, 8-bit code units */
|
||||||
|
PCRE2_ZERO_TERMINATED,
|
||||||
option_bits, /* default options */
|
option_bits, /* default options */
|
||||||
&pcre_error, /* for error message */
|
&pcre_errorcode, /* for error code */
|
||||||
&pcre_erroffset, /* for error offset */
|
&pcre_erroffset, /* for error offset */
|
||||||
NULL); /* use default character tables */
|
NULL); /* compile context */
|
||||||
if (n->pcre_pattern == NULL) {
|
if (n->pcre_pattern == NULL) {
|
||||||
if (errstr) {
|
if (errstr) {
|
||||||
int r = asprintf(errstr, "PCRE compilation failed at offset %d: %s, pattern: %s", pcre_erroffset, pcre_error, n->combined_pattern);
|
PCRE2_UCHAR buf[128];
|
||||||
if (r) {};
|
pcre2_get_error_message(pcre_errorcode, buf, sizeof(buf));
|
||||||
|
int r = asprintf(errstr, "PCRE compilation failed at offset %ld: %s, pattern: %s", pcre_erroffset, buf, n->combined_pattern);
|
||||||
|
if (r < 0) {
|
||||||
|
*errstr = NULL; /* the content of errstr is undefined when asprintf() fails */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#ifdef PCRE_STUDY_JIT_COMPILE
|
if (n->match_data) {
|
||||||
if (n->pcre_extra) {
|
pcre2_match_data_free(n->match_data);
|
||||||
pcre_free_study(n->pcre_extra);
|
|
||||||
}
|
}
|
||||||
n->pcre_extra = pcre_study(n->pcre_pattern, 0, &pcre_error);
|
n->match_data = pcre2_match_data_create_from_pattern(n->pcre_pattern, NULL);
|
||||||
if (!n->pcre_extra && pcre_error) {
|
if (n->match_data == NULL) {
|
||||||
if (errstr) {
|
if (errstr) {
|
||||||
int r = asprintf(errstr, "PCRE study failed at offset %s, pattern: %s", pcre_error, n->combined_pattern);
|
int r = asprintf(errstr, "Failed to allocate match data block");
|
||||||
if (r) {};
|
if (r < 0) {
|
||||||
|
*errstr = NULL; /* the content of errstr is undefined when asprintf() fails */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,20 +337,18 @@ static R3Node * r3_tree_matchl_base(const R3Node * n, const char * path,
|
||||||
info("COMPARE PCRE_PATTERN\n");
|
info("COMPARE PCRE_PATTERN\n");
|
||||||
const char *substring_start = 0;
|
const char *substring_start = 0;
|
||||||
int substring_length = 0;
|
int substring_length = 0;
|
||||||
int ov[ n->ov_cnt ];
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
info("pcre matching %s on [%s]\n", n->combined_pattern, path);
|
info("pcre matching %s on [%s]\n", n->combined_pattern, path);
|
||||||
|
|
||||||
rc = pcre_exec(
|
rc = pcre2_match(
|
||||||
n->pcre_pattern, /* the compiled pattern */
|
n->pcre_pattern, /* the compiled pattern */
|
||||||
n->pcre_extra,
|
(PCRE2_SPTR)path,/* the subject string, 8-bit code units */
|
||||||
path, /* the subject string */
|
|
||||||
path_len, /* the length of the subject */
|
path_len, /* the length of the subject */
|
||||||
0, /* start at offset 0 in the subject */
|
0, /* start at offset 0 in the subject */
|
||||||
0, /* default options */
|
0, /* default options */
|
||||||
ov, /* output vector for substring information */
|
n->match_data,/* match data results */
|
||||||
n->ov_cnt); /* number of elements in the output vector */
|
NULL); /* match context */
|
||||||
|
|
||||||
// does not match all edges, return NULL;
|
// does not match all edges, return NULL;
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
@ -360,7 +356,7 @@ static R3Node * r3_tree_matchl_base(const R3Node * n, const char * path,
|
||||||
printf("pcre rc: %d\n", rc );
|
printf("pcre rc: %d\n", rc );
|
||||||
switch(rc)
|
switch(rc)
|
||||||
{
|
{
|
||||||
case PCRE_ERROR_NOMATCH:
|
case PCRE2_ERROR_NOMATCH:
|
||||||
printf("pcre: no match '%s' on pattern '%s'\n", path, n->combined_pattern);
|
printf("pcre: no match '%s' on pattern '%s'\n", path, n->combined_pattern);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -373,23 +369,22 @@ static R3Node * r3_tree_matchl_base(const R3Node * n, const char * path,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PCRE2_SIZE *ov = pcre2_get_ovector_pointer(n->match_data);
|
||||||
|
|
||||||
restlen = path_len - ov[1]; // if it's fully matched to the end (rest string length)
|
restlen = path_len - ov[1]; // if it's fully matched to the end (rest string length)
|
||||||
int *inv = ov + 2;
|
|
||||||
if (!restlen) {
|
if (!restlen) {
|
||||||
// Check the substring to decide we should go deeper on which edge
|
// Check the substring to decide we should go deeper on which edge
|
||||||
for (i = 1; i < rc; i++)
|
for (i = 1; i < rc; i++)
|
||||||
{
|
{
|
||||||
substring_length = *(inv+1) - *inv;
|
substring_length = ov[2*i+1] - ov[2*i];
|
||||||
|
|
||||||
// if it's not matched for this edge, just skip them quickly
|
// if it's not matched for this edge, just skip them quickly
|
||||||
if (!is_end && !substring_length) {
|
if (!is_end && !substring_length) {
|
||||||
inv += 2;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
substring_start = path + *inv;
|
substring_start = path + ov[2*i];
|
||||||
e = n->edges.entries + i - 1;
|
e = n->edges.entries + i - 1;
|
||||||
|
|
||||||
if (entry && e->has_slug) {
|
if (entry && e->has_slug) {
|
||||||
|
@ -404,18 +399,16 @@ static R3Node * r3_tree_matchl_base(const R3Node * n, const char * path,
|
||||||
|
|
||||||
|
|
||||||
// Check the substring to decide we should go deeper on which edge
|
// Check the substring to decide we should go deeper on which edge
|
||||||
inv = ov + 2;
|
|
||||||
for (i = 1; i < rc; i++)
|
for (i = 1; i < rc; i++)
|
||||||
{
|
{
|
||||||
substring_length = *(inv+1) - *inv;
|
substring_length = ov[2*i+1] - ov[2*i];
|
||||||
|
|
||||||
// if it's not matched for this edge, just skip them quickly
|
// if it's not matched for this edge, just skip them quickly
|
||||||
if (!is_end && !substring_length) {
|
if (!is_end && !substring_length) {
|
||||||
inv += 2;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
substring_start = path + *inv;
|
substring_start = path + ov[2*i];
|
||||||
e = n->edges.entries + i - 1;
|
e = n->edges.entries + i - 1;
|
||||||
|
|
||||||
if (entry && e->has_slug) {
|
if (entry && e->has_slug) {
|
||||||
|
@ -520,7 +513,6 @@ inline R3Edge * r3_node_find_edge_str(const R3Node * n, const char * str, int st
|
||||||
// n->endpoint = 0;
|
// n->endpoint = 0;
|
||||||
// n->combined_pattern = NULL;
|
// n->combined_pattern = NULL;
|
||||||
// n->pcre_pattern = NULL;
|
// n->pcre_pattern = NULL;
|
||||||
// n->pcre_extra = NULL;
|
|
||||||
// n->data = NULL;
|
// n->data = NULL;
|
||||||
// return n;
|
// return n;
|
||||||
// }
|
// }
|
||||||
|
|
Loading…
Reference in a new issue