From 15515f390c5e3316a7faf0cf85d661a297d45a50 Mon Sep 17 00:00:00 2001 From: Julien Schueller Date: Tue, 4 Jan 2022 13:50:02 +0100 Subject: [PATCH] PCRE2 Closes #2120 --- CMakeLists.txt | 10 ++++----- Doc/Manual/Preface.html | 6 +++--- Doc/Manual/Windows.html | 22 ++++++++++++-------- Source/Swig/misc.c | 41 ++++++++++++++++++++++++------------- Source/Swig/naming.c | 22 ++++++++++++-------- Tools/cmake/FindPCRE.cmake | 37 --------------------------------- Tools/cmake/FindPCRE2.cmake | 21 +++++++++++++++++++ Tools/mkwindows.sh | 2 +- Tools/nuget-install.cmd | 28 ------------------------- Tools/pcre-build.sh | 4 ++-- appveyor.yml | 15 ++++++++------ configure.ac | 19 +++++++++-------- 12 files changed, 106 insertions(+), 121 deletions(-) delete mode 100644 Tools/cmake/FindPCRE.cmake create mode 100644 Tools/cmake/FindPCRE2.cmake delete mode 100644 Tools/nuget-install.cmd diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a195de54..21412aa7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,11 +73,11 @@ if (MSVC) set (CMAKE_CXX_FLAGS "/EHsc ${CMAKE_CXX_FLAGS}") endif () -option (WITH_PCRE "Enable pcre" ON) +option (WITH_PCRE "Enable PCRE" ON) if (WITH_PCRE) - find_package (PCRE REQUIRED) + find_package (PCRE2 REQUIRED) set (HAVE_PCRE 1) - include_directories (${PCRE_INCLUDE_DIRS}) + include_directories (${PCRE2_INCLUDE_DIRS}) endif() if (WIN32) @@ -145,8 +145,8 @@ add_executable (swig ${PROJECT_BINARY_DIR}/Source/CParse/parser.c ${PROJECT_BINARY_DIR}/Source/CParse/parser.h ) -if (PCRE_FOUND) - target_link_libraries (swig ${PCRE_LIBRARIES}) +if (PCRE2_FOUND) + target_link_libraries (swig ${PCRE2_LIBRARIES}) endif () install (TARGETS swig DESTINATION bin) diff --git a/Doc/Manual/Preface.html b/Doc/Manual/Preface.html index 36a99bd1f..24e844c51 100644 --- a/Doc/Manual/Preface.html +++ b/Doc/Manual/Preface.html @@ -283,9 +283,9 @@ You must use GNU make to build a

PCRE needs to be installed on your system to build SWIG, in particular -pcre-config must be available. If you have PCRE headers and libraries but not -pcre-config itself or, alternatively, wish to override the compiler or linker -flags returned by pcre-config, you may set PCRE_LIBS and PCRE_CFLAGS variables +pcre2-config must be available. If you have PCRE headers and libraries but not +pcre2-config itself or, alternatively, wish to override the compiler or linker +flags returned by pcre-config, you may set PCRE2_LIBS and PCRE2_CFLAGS variables to be used instead. And if you don't have PCRE at all, the configure script will provide instructions for obtaining it.

diff --git a/Doc/Manual/Windows.html b/Doc/Manual/Windows.html index 0e4ffc3e2..5aef29460 100644 --- a/Doc/Manual/Windows.html +++ b/Doc/Manual/Windows.html @@ -239,7 +239,7 @@ For fully working build steps always check the Continuous Integration setups cur
  1. Install Nuget from https://www.nuget.org/downloads (v5.8.1 is used in this example, and installed to C:\Tools). Nuget is the package manager - for .NET, but allows us to easily install PCRE and other dependencies required by SWIG. + for .NET, but allows us to easily install CMake and other dependencies required by SWIG.
  2. Install CMake using the following command:
    C:\Tools\nuget install CMake-win64 -Version 3.15.5 -OutputDirectory C:\Tools\CMake
    @@ -251,8 +251,14 @@ For fully working build steps always check the Continuous Integration setups cur and save to a folder e.g. C:\Tools\Bison
  3. - Install PCRE using Nuget using the following command:
    C:\Tools\nuget install pcre -Version 8.33.0.1 -OutputDirectory C:\Tools\pcre
    . - Alternatively, use WITH_PCRE option to disable PCRE support if you are sure not to need it. + Install PCRE2 using the following commands: +
    +git clone https://github.com/PhilipHazel/pcre2.git
    +cd pcre2
    +cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX=C:/pcre .
    +cmake --build . --config Release --target install
    +
    +Alternatively, use WITH_PCRE option to disable PCRE support if you are sure not to need it.
  4. We will also need the SWIG source code. Either download a zipped archive from GitHub, or if git is installed clone the latest codebase @@ -272,10 +278,10 @@ For fully working build steps always check the Continuous Integration setups cur
     cd C:\swig
     SET PATH=C:\Tools\CMake\CMake-win64.3.15.5\bin;C:\Tools\bison\bison-win32.2.4.1.1\tools\native\bin;%PATH%
    -SET PCRE_ROOT=C:\Tools\pcre\pcre.8.33.0.1\build\native
    +SET PCRE_ROOT=C:/pcre
     SET PCRE_PLATFORM=x64
    -cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX="%CD:\=/%/install2" -DCMAKE_C_FLAGS="/DPCRE_STATIC" ^
    -  -DPCRE_INCLUDE_DIR=%PCRE_ROOT%/include -DPCRE_LIBRARY=%PCRE_ROOT%/lib/v110/%PCRE_PLATFORM%/Release/static/utf8/pcre8.lib .
    +cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX="%CD:\=/%/install2" -DCMAKE_C_FLAGS="/DPCRE2_STATIC" ^
    +  -DPCRE2_INCLUDE_DIR=%PCRE_ROOT%/include -DPCRE2_LIBRARY=%PCRE_ROOT%/lib/pcre2-8.lib .
     cmake --build . --config Release
     
     REM to test the exe
    @@ -311,7 +317,7 @@ Install the packages needed to build swig:
    -pacman -S git autoconf automake bison gcc make pcre-devel
    +pacman -S git autoconf automake bison gcc make pcre2-devel
     
    @@ -446,7 +452,7 @@ the autotools will fail miserably on those.
  5. The PCRE third party library needs to be built next. -Download the latest PCRE source tarball, such as pcre-8.10.tar.bz2, from +Download the latest PCRE source tarball, such as pcre2-10.39.tar.bz2, from PCRE and place in the /usr/src/swig directory. Build PCRE as a static library using the Tools/pcre-build.sh script as follows: diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index ef6fcc02f..1324f4d51 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -1312,7 +1312,8 @@ void Swig_offset_string(String *s, int number) { #ifdef HAVE_PCRE -#include +#define PCRE2_CODE_UNIT_WIDTH 8 +#include static int split_regex_pattern_subst(String *s, String **pattern, String **subst, const char **input) { @@ -1375,7 +1376,7 @@ static void copy_with_maybe_case_conversion(String *dst, const char *src, int le } } -String *replace_captures(int num_captures, const char *input, String *subst, int captures[], String *pattern, String *s) +String *replace_captures(int num_captures, const char *input, String *subst, size_t captures[], String *pattern, String *s) { int convertCase = 0, convertNextOnly = 0; String *result = NewStringEmpty(); @@ -1397,7 +1398,7 @@ String *replace_captures(int num_captures, const char *input, String *subst, int } else if (isdigit((unsigned char)*p)) { int group = *p++ - '0'; if (group < num_captures) { - int l = captures[group*2], r = captures[group*2 + 1]; + int l = (int)captures[group*2], r = (int)captures[group*2 + 1]; if (l != -1) { copy_with_maybe_case_conversion(result, input + l, r - l, &convertCase, convertNextOnly); } @@ -1449,26 +1450,31 @@ String *Swig_string_regex(String *s) { const int pcre_options = 0; String *res = 0; - pcre *compiled_pat = 0; - const char *pcre_error, *input; - int pcre_errorpos; + pcre2_code *compiled_pat = 0; + const char *input; + PCRE2_UCHAR pcre_error[256]; + int pcre_errornum; + size_t pcre_errorpos; String *pattern = 0, *subst = 0; - int captures[30]; - + size_t *captures = 0; + pcre2_match_data *match_data = 0; if (split_regex_pattern_subst(s, &pattern, &subst, &input)) { int rc; - compiled_pat = pcre_compile( - Char(pattern), pcre_options, &pcre_error, &pcre_errorpos, NULL); + compiled_pat = pcre2_compile( + (PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, pcre_options, &pcre_errornum, &pcre_errorpos, NULL); if (!compiled_pat) { + pcre2_get_error_message (pcre_errornum, pcre_error, sizeof pcre_error); Swig_error("SWIG", Getline(s), "PCRE compilation failed: '%s' in '%s':%i.\n", pcre_error, Char(pattern), pcre_errorpos); SWIG_exit(EXIT_FAILURE); } - rc = pcre_exec(compiled_pat, NULL, input, (int)strlen(input), 0, 0, captures, 30); + match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL); + rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)input, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL); + captures = pcre2_get_ovector_pointer (match_data); if (rc >= 0) { res = replace_captures(rc, input, subst, captures, pattern, s); - } else if (rc != PCRE_ERROR_NOMATCH) { + } else if (rc != PCRE2_ERROR_NOMATCH) { Swig_error("SWIG", Getline(s), "PCRE execution failed: error %d while matching \"%s\" using \"%s\".\n", rc, Char(pattern), input); SWIG_exit(EXIT_FAILURE); @@ -1477,12 +1483,19 @@ String *Swig_string_regex(String *s) { DohDelete(pattern); DohDelete(subst); - pcre_free(compiled_pat); + pcre2_code_free(compiled_pat); + pcre2_match_data_free(match_data); return res ? res : NewStringEmpty(); } String *Swig_pcre_version(void) { - return NewStringf("PCRE Version: %s", pcre_version()); + int len = pcre2_config(PCRE2_CONFIG_VERSION, NULL); + char *buf = malloc(len); + String *result; + pcre2_config(PCRE2_CONFIG_VERSION, buf); + result = NewStringf("PCRE Version: %s", buf); + free(buf); + return result; } #else diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index 871a9e5bb..a1a03819c 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -1092,26 +1092,32 @@ static DOH *get_lattr(Node *n, List *lattr) { } #ifdef HAVE_PCRE -#include +#define PCRE2_CODE_UNIT_WIDTH 8 +#include static int name_regexmatch_value(Node *n, String *pattern, String *s) { - pcre *compiled_pat; - const char *err; - int errpos; + pcre2_code *compiled_pat; + PCRE2_UCHAR err[256]; + int errornum; + size_t errpos; int rc; - compiled_pat = pcre_compile(Char(pattern), 0, &err, &errpos, NULL); + compiled_pat = pcre2_compile((PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, 0, &errornum, &errpos, NULL); if (!compiled_pat) { + pcre2_get_error_message (errornum, err, sizeof err); Swig_error("SWIG", Getline(n), "Invalid regex \"%s\": compilation failed at %d: %s\n", Char(pattern), errpos, err); SWIG_exit(EXIT_FAILURE); } - rc = pcre_exec(compiled_pat, NULL, Char(s), Len(s), 0, 0, NULL, 0); - pcre_free(compiled_pat); + pcre2_match_data *match_data = 0; + match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL); + rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)Char(s), PCRE2_ZERO_TERMINATED, 0, 0, match_data, 0); + pcre2_code_free(compiled_pat); + pcre2_match_data_free(match_data); - if (rc == PCRE_ERROR_NOMATCH) + if (rc == PCRE2_ERROR_NOMATCH) return 0; if (rc < 0 ) { diff --git a/Tools/cmake/FindPCRE.cmake b/Tools/cmake/FindPCRE.cmake deleted file mode 100644 index dbbd60ada..000000000 --- a/Tools/cmake/FindPCRE.cmake +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (C) 2007-2009 LuaDist. -# Created by Peter Kapec -# 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) diff --git a/Tools/cmake/FindPCRE2.cmake b/Tools/cmake/FindPCRE2.cmake new file mode 100644 index 000000000..08c216347 --- /dev/null +++ b/Tools/cmake/FindPCRE2.cmake @@ -0,0 +1,21 @@ +# - Find PCRE2 +# Perl Compatible Regular Expressions +# https://www.pcre.org/ + +# The following variables are set: +# PCRE2_FOUND - System has the PCRE library +# PCRE2_LIBRARIES - The PCRE library file +# PCRE2_INCLUDE_DIRS - The folder with the PCRE headers + +find_library(PCRE2_LIBRARY NAMES pcre2 pcre2-8) +find_path(PCRE2_INCLUDE_DIR pcre2.h) + +set (PCRE2_LIBRARIES ${PCRE2_LIBRARY}) +set (PCRE2_INCLUDE_DIRS ${PCRE2_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PCRE2 DEFAULT_MSG PCRE2_LIBRARIES PCRE2_INCLUDE_DIRS) + +mark_as_advanced ( + PCRE2_LIBRARY + PCRE2_INCLUDE_DIR) diff --git a/Tools/mkwindows.sh b/Tools/mkwindows.sh index 5e4d2f0fd..4717e1ce6 100755 --- a/Tools/mkwindows.sh +++ b/Tools/mkwindows.sh @@ -84,7 +84,7 @@ export CXXFLAGS="$compileflags" swigbasename=swig-$version swigwinbasename=swigwin-$version tarball=$swigbasename.tar.gz -pcre_tarball=`ls pcre-*.tar.*` +pcre_tarball=`ls pcre2-*.tar.*` if ! test -f "$pcre_tarball"; then echo "Could not find PCRE tarball. Please download a PCRE source tarball from http://www.pcre.org" diff --git a/Tools/nuget-install.cmd b/Tools/nuget-install.cmd deleted file mode 100644 index eec7f8787..000000000 --- a/Tools/nuget-install.cmd +++ /dev/null @@ -1,28 +0,0 @@ -rem Workaround 'nuget install' not being reliable by retrying a few times -@echo off -rem initiate the retry number -set errorCode=1 -set retryNumber=0 -set maxRetries=5 - -:RESTORE -nuget install %* - -rem problem? -IF ERRORLEVEL %errorCode% GOTO :RETRY - -rem everything is fine! -@echo Installed nuget, retries: %reTryNumber% -GOTO :EXIT - -:RETRY -@echo Oops, nuget restore exited with code %errorCode% - let us try again! -set /a retryNumber=%retryNumber%+1 -IF %reTryNumber% LSS %maxRetries% (GOTO :RESTORE) -IF %retryNumber% EQU %maxRetries% (GOTO :ERR) - -:ERR -@echo Sorry, we tried restoring nuget packages for %maxRetries% times and all attempts were unsuccessful! -EXIT /B 1 - -:EXIT diff --git a/Tools/pcre-build.sh b/Tools/pcre-build.sh index 92f645da2..ffa7a69f8 100755 --- a/Tools/pcre-build.sh +++ b/Tools/pcre-build.sh @@ -37,8 +37,8 @@ fi echo "Looking for PCRE tarball..." rm -rf pcre -pcre_tarball=`ls pcre-*.tar*` -test -n "$pcre_tarball" || bail "Could not find tarball matching pattern: pcre-*.tar*" +pcre_tarball=`ls pcre2-*.tar*` +test -n "$pcre_tarball" || bail "Could not find tarball matching pattern: pcre2-*.tar*" test -f "$pcre_tarball" || bail "Could not find a single PCRE tarball. Found: $pcre_tarball" echo "Extracting tarball: $pcre_tarball" diff --git a/appveyor.yml b/appveyor.yml index 5eaa77b2f..6959346b2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -123,15 +123,16 @@ install: } - if "%OSVARIANT%"=="" bash -c "cd /usr/bin && curl --retry 15 -s -L https://github.com/swig/cccl/archive/cccl-1.2.tar.gz | tar -xz --strip 1 cccl-cccl-1.2/cccl" - if "%OSVARIANT%"=="" call "%VCVARSBAT%" %VCVARSARG% -- if "%OSVARIANT%"=="" Tools\nuget-install.cmd pcre -Verbosity quiet -Version 8.33.0.1 -OutputDirectory C:\pcre -- if "%OSVARIANT%"=="" set PCRE_ROOT=C:/pcre/pcre.8.33.0.1/build/native +- if "%OSVARIANT%"=="" appveyor-retry appveyor DownloadFile https://github.com/PhilipHazel/pcre2/archive/refs/tags/pcre2-10.39.zip +- if "%OSVARIANT%"=="" 7z x pcre2-10.39.zip +- if "%OSVARIANT%"=="" set PCRE_ROOT=C:/pcre - if not "%OSVARIANT%"=="cygwin" set PATH=C:\Python%VER%%LANG_PLATFORM%;%PATH% - if "%OSVARIANT%"=="" bash -c "which cl.exe" - if "%OSVARIANT%"=="" bash -c "cl.exe /? 2>&1 | head -n 1" - if "%OSVARIANT%"=="" bash -c "which csc.exe" - if "%OSVARIANT%"=="" bash -c "csc.exe /? | head -n 1" -- if "%OSVARIANT%"=="cygwin" %CYGWINSETUP% --quiet-mode --packages python2-devel,libpcre-devel,libboost-devel > cygwin-install.txt || bash -c "cat cygwin-install.txt" -- if "%OSVARIANT%"=="mingw" bash -c "pacman --noconfirm --sync mingw%MBITS%/mingw-w64-%MARCH%-autotools mingw%MBITS%/mingw-w64-%MARCH%-pcre mingw%MBITS%/mingw-w64-%MARCH%-boost" +- if "%OSVARIANT%"=="cygwin" %CYGWINSETUP% --quiet-mode --packages python2-devel,libpcre2-devel,libboost-devel > cygwin-install.txt || bash -c "cat cygwin-install.txt" +- if "%OSVARIANT%"=="mingw" bash -c "pacman --noconfirm --sync mingw%MBITS%/mingw-w64-%MARCH%-autotools mingw%MBITS%/mingw-w64-%MARCH%-pcre2 mingw%MBITS%/mingw-w64-%MARCH%-boost" - if not "%WITHLANG%"=="" set SWIGWITHLANG==%WITHLANG% - if not "%WITHLANG%"=="" where %WITHLANG% - bash -c "which $CC" @@ -148,9 +149,11 @@ install: build_script: - set CCCL_OPTIONS=--cccl-muffle /W3 /EHsc - set CHECK_OPTIONS=CSHARPOPTIONS=-platform:%Platform% -- if "%BUILDSYSTEM%"=="cmake" cmake --version && cmake -G "Visual Studio 14 2015%VSARCH%" -DCMAKE_INSTALL_PREFIX="%CD:\=/%/install2" -DCMAKE_C_FLAGS="/WX /DPCRE_STATIC" -DCMAKE_CXX_FLAGS="/WX /DPCRE_STATIC" -DPCRE_INCLUDE_DIR=%PCRE_ROOT%/include -DPCRE_LIBRARY=%PCRE_ROOT%/lib/v110/%PCRE_PLATFORM%/Release/static/utf8/pcre8.lib -DBISON_EXECUTABLE=C:/cygwin/bin/bison.exe . && cmake --build . --config Release --target install && ctest --output-on-failure -V -C Release && appveyor exit +- if "%BUILDSYSTEM%"=="cmake" cd pcre2-pcre2-10.39 && cmake -G "Visual Studio 14 2015%VSARCH%" -DCMAKE_INSTALL_PREFIX="%PCRE_ROOT:\=/%" . && cmake --build . --config Release --target install && cd .. +- if "%BUILDSYSTEM%"=="cmake" cmake --version && cmake -G "Visual Studio 14 2015%VSARCH%" -DCMAKE_INSTALL_PREFIX="%CD:\=/%/install2" -DCMAKE_C_FLAGS="/WX /DPCRE_STATIC" -DCMAKE_CXX_FLAGS="/WX /DPCRE2_STATIC" -DPCRE2_INCLUDE_DIR=%PCRE_ROOT%/include -DPCRE2_LIBRARY=%PCRE_ROOT%/lib/pcre2-8-static.lib -DBISON_EXECUTABLE=C:/cygwin/bin/bison.exe . && cmake --build . --config Release --target install && ctest --output-on-failure -V -C Release && appveyor exit +- if "%OSVARIANT%"=="" bash -c "exec 0