Skip to content

Commit

Permalink
Add support for PCRE2 library
Browse files Browse the repository at this point in the history
Signed-off-by: Sven Strickroth <[email protected]>
  • Loading branch information
csware authored and xuhdev committed Nov 9, 2018
1 parent f61320b commit ffb01f6
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 14 deletions.
13 changes: 11 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@ compiler:
- gcc
- clang

dist: xenial

addons:
apt:
packages:
- libpcre2-dev

# Settings to try
env:
- OPTIONS="-DCMAKE_BUILD_TYPE=Release -DBUILD_STATICALLY_LINKED_EXE=ON"
- OPTIONS="-DCMAKE_BUILD_TYPE=Release -DBUILD_STATICALLY_LINKED_EXE=OFF"
- OPTIONS="-DCMAKE_BUILD_TYPE=Release -DBUILD_STATICALLY_LINKED_EXE=ON -DPCRE=ON"
- OPTIONS="-DCMAKE_BUILD_TYPE=Release -DBUILD_STATICALLY_LINKED_EXE=OFF -DPCRE=ON"
- OPTIONS="-DCMAKE_BUILD_TYPE=Release -DBUILD_STATICALLY_LINKED_EXE=ON -DPCRE=OFF"
- OPTIONS="-DCMAKE_BUILD_TYPE=Release -DBUILD_STATICALLY_LINKED_EXE=OFF -DPCRE=OFF"

# Run the Build script
script:
Expand Down
38 changes: 38 additions & 0 deletions CMake_Modules/FindPCRE2.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright (C) 2018 Sven Strickroth <email AT cs-ware DOT de>
# Copyright (C) 2007-2009 LuaDist.
# Created by Peter Kapec <[email protected]>
# 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 pcre.h, etc.
# PCRE2_LIBRARIES - List of libraries when using pcre.
# PCRE2_FOUND - True if pcre 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)
23 changes: 15 additions & 8 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,37 @@ environment:
CONFIG: Release
ARCH: x64
CMAKE_INSTALL_PREFIX: ..\build
PCRE_DEST: C:\projects\bin\%ARCH%-static\pcre
CORE_DEST: C:\projects\bin\%ARCH%-static\core

PCRE_DEST: C:\projects\bin\%ARCH%-static\pcre
matrix:
- USE_PCRE: 1
PCRE_FILENAME: pcre-8.41
- USE_PCRE2: 1
PCRE_FILENAME: pcre2-10.32

install:
- cmake --version
- git submodule init
- git submodule update
- cd C:\projects
# Download PCRE sources
- curl -o pcre.zip https://ftp.pcre.org/pub/pcre/pcre-8.41.zip
# Prepare pcre
- curl -o pcre.zip https://ftp.pcre.org/pub/pcre/%PCRE_FILENAME%.zip
- 7z x -y pcre.zip > nul
- rename pcre-8.41 pcre
- rename %PCRE_FILENAME% pcre
# Build and install PCRE
- mkdir %PCRE_DEST%
- cd %PCRE_DEST%
- cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX="%CMAKE_INSTALL_PREFIX%" -DPCRE_STATIC_RUNTIME="ON" -DBUILD_SHARED_LIBS="OFF" -DPCRE_BUILD_PCRECPP=OFF -DPCRE_BUILD_PCREGREP=OFF -DPCRE_BUILD_TESTS=OFF C:\projects\pcre
- if "%USE_PCRE%"=="1" cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX="%CMAKE_INSTALL_PREFIX%" -DPCRE_STATIC_RUNTIME="ON" -DBUILD_SHARED_LIBS="OFF" -DPCRE_BUILD_PCRECPP=OFF -DPCRE_BUILD_PCREGREP=OFF -DPCRE_BUILD_TESTS=OFF C:\projects\pcre
- if "%USE_PCRE2%"=="1" cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX="%CMAKE_INSTALL_PREFIX%" -DPCRE2_STATIC_RUNTIME="ON" -DBUILD_SHARED_LIBS="OFF" -DPCRE2_BUILD_PCRE2GREP="OFF" -DPCRE2_BUILD_TESTS="OFF" C:\projects\pcre
- cd %PCRE_DEST%
- cmake --build %PCRE_DEST% --target install -- /p:Configuration=%CONFIG%

build_script:
# Build and install editorconfig-core-c
- mkdir %CORE_DEST%
- cd %CORE_DEST%
- cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX="%CMAKE_INSTALL_PREFIX%" -DMSVC_MD="OFF" -DPCRE_STATIC="ON" C:\projects\editorconfig-core-c
- if "%USE_PCRE%"=="1" cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX="%CMAKE_INSTALL_PREFIX%" -DMSVC_MD="OFF" -DPCRE="ON" -DPCRE_STATIC="ON" C:\projects\editorconfig-core-c
- if "%USE_PCRE2%"=="1" cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX="%CMAKE_INSTALL_PREFIX%" -DMSVC_MD="OFF" -DPCRE="OFF" -DPCRE2_STATIC="ON" C:\projects\editorconfig-core-c
- cmake --build %CORE_DEST% --target install -- /p:Configuration=%CONFIG%

test_script:
Expand Down
13 changes: 11 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,18 @@
include(CheckFunctionExists)
include(CheckTypeSize)

find_package(PCRE REQUIRED)
option(PCRE "Use PCRE instead of PCRE2" ON)
if(NOT PCRE)
find_package(PCRE2 REQUIRED)
else()
find_package(PCRE REQUIRED)
endif()

if(PCRE_FOUND)
if(PCRE2_FOUND)
include_directories(BEFORE ${PCRE2_INCLUDE_DIRS})
option(PCRE2_STATIC "Turn this option ON when linking to PCRE2 static library" OFF)
add_compile_definitions(HAVE_PCRE2)
elseif(PCRE_FOUND)
include_directories(BEFORE ${PCRE_INCLUDE_DIRS})
option(PCRE_STATIC "Turn this option ON when linking to PCRE static library" OFF)
endif()
Expand Down
3 changes: 3 additions & 0 deletions src/bin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ if(CMAKE_COMPILER_IS_GNUCC)
if(BUILD_STATICALLY_LINKED_EXE)
# Add -static for linker if we want a statically linked executable
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")

# libpcre2 might be dynamically linked against pthreads (at least on Ubuntu Xenial)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
endif(BUILD_STATICALLY_LINKED_EXE)
endif(CMAKE_COMPILER_IS_GNUCC)

Expand Down
7 changes: 7 additions & 0 deletions src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@
#cmakedefine CMAKE_COMPILER_IS_GNUCC
#cmakedefine MSVC

#cmakedefine HAVE_PCRE2

#ifdef HAVE_PCRE2
#cmakedefine PCRE2_STATIC
#define PCRE2_CODE_UNIT_WIDTH 8
#else
#cmakedefine PCRE_STATIC
#endif

/* For gcc, we define _GNU_SOURCE to use gcc extensions */
#ifdef CMAKE_COMPILER_IS_GNUCC
Expand Down
4 changes: 2 additions & 2 deletions src/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ set_target_properties(editorconfig_shared PROPERTIES
if(WIN32)
target_link_libraries(editorconfig_shared Shlwapi)
endif()
target_link_libraries(editorconfig_shared ${PCRE_LIBRARIES})
target_link_libraries(editorconfig_shared ${PCRE_LIBRARIES} ${PCRE2_LIBRARIES})

add_library(editorconfig_static STATIC ${editorconfig_LIBSRCS})
set_target_properties(editorconfig_static PROPERTIES
Expand All @@ -53,7 +53,7 @@ set_target_properties(editorconfig_static PROPERTIES
if(WIN32)
target_link_libraries(editorconfig_static Shlwapi)
endif()
target_link_libraries(editorconfig_static ${PCRE_LIBRARIES})
target_link_libraries(editorconfig_static ${PCRE_LIBRARIES} ${PCRE2_LIBRARIES})

# EditorConfig package name for find_package() and the CMake package registry.
# On UNIX the system registry is usually just "lib/cmake/<package>".
Expand Down
57 changes: 57 additions & 0 deletions src/lib/ec_glob.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2014 Hong Xu <hong AT topbug DOT net>
* Copyright (c) 2018 Sven Strickroth <email AT cs-ware DOT de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -28,7 +29,11 @@

#include <ctype.h>
#include <string.h>
#ifdef HAVE_PCRE2
#include <pcre2.h>
#else
#include <pcre.h>
#endif

#define oom() { return -1; }
#include "utarray.h"
Expand Down Expand Up @@ -70,12 +75,21 @@ int ec_glob(const char *pattern, const char *string)
char * pcre_str_end;
int brace_level = 0;
_Bool is_in_bracket = 0;
#ifdef HAVE_PCRE2
int error_code;
size_t erroffset;
pcre2_code * re;
int rc;
size_t * pcre_result;
pcre2_match_data * pcre_match_data;
#else
const char * error_msg;
int erroffset;
pcre * re;
int rc;
int * pcre_result;
size_t pcre_result_len;
#endif
char l_pattern[2 * PATTERN_MAX];
_Bool are_brace_paired;
UT_array * nums; /* number ranges */
Expand Down Expand Up @@ -106,8 +120,13 @@ int ec_glob(const char *pattern, const char *string)
}

/* used to search for {num1..num2} case */
#ifdef HAVE_PCRE2
re = pcre2_compile("^\\{[\\+\\-]?\\d+\\.\\.[\\+\\-]?\\d+\\}$", PCRE2_ZERO_TERMINATED, 0,
&error_code, &erroffset, NULL);
#else
re = pcre_compile("^\\{[\\+\\-]?\\d+\\.\\.[\\+\\-]?\\d+\\}$", 0,
&error_msg, &erroffset, NULL);
#endif
if (!re) /* failed to compile */
return -1;

Expand Down Expand Up @@ -247,11 +266,21 @@ int ec_glob(const char *pattern, const char *string)
{
const char * double_dots;
int_pair pair;

#ifdef HAVE_PCRE2
pcre2_match_data * match_data = pcre2_match_data_create_from_pattern(re, NULL);

/* Check the case of {num1..num2} */
rc = pcre2_match(re, c, cc - c + 1, 0, 0, match_data, NULL);

pcre2_match_data_free(match_data);
#else
int pcre_res[3];

/* Check the case of {num1..num2} */
rc = pcre_exec(re, NULL, c, (int) (cc - c + 1), 0, 0,
pcre_res, 3);
#endif

if (rc < 0) /* not {num1..num2} case */
{
Expand Down Expand Up @@ -321,36 +350,59 @@ int ec_glob(const char *pattern, const char *string)

*(p_pcre ++) = '$';

#ifdef HAVE_PCRE2
pcre2_code_free(re); /* ^\\d+\\.\\.\\d+$ */

re = pcre2_compile(pcre_str, PCRE2_ZERO_TERMINATED, 0, &error_code, &erroffset, NULL);
#else
pcre_free(re); /* ^\\d+\\.\\.\\d+$ */

re = pcre_compile(pcre_str, 0, &error_msg, &erroffset, NULL);
#endif

if (!re) /* failed to compile */
{
utarray_free(nums);
return -1;
}

#ifdef HAVE_PCRE2
pcre_match_data = pcre2_match_data_create_from_pattern(re, NULL);
rc = pcre2_match(re, string, strlen(string), 0, 0, pcre_match_data, NULL);
#else
pcre_result_len = 3 * (utarray_len(nums) + 1);
pcre_result = (int *) calloc(pcre_result_len, sizeof(int_pair));
rc = pcre_exec(re, NULL, string, (int) strlen(string), 0, 0,
pcre_result, pcre_result_len);
#endif

if (rc < 0) /* failed to match */
{
#ifdef HAVE_PCRE2
if (rc == PCRE2_ERROR_NOMATCH)
#else
if (rc == PCRE_ERROR_NOMATCH)
#endif
ret = EC_GLOB_NOMATCH;
else
ret = rc;

#ifdef HAVE_PCRE2
pcre2_code_free(re);
pcre2_match_data_free(pcre_match_data);
#else
pcre_free(re);
free(pcre_result);
#endif
utarray_free(nums);

return ret;
}

/* Whether the numbers are in the desired range? */
#ifdef HAVE_PCRE2
pcre_result = pcre2_get_ovector_pointer(pcre_match_data);
#endif
for(p = (int_pair *) utarray_front(nums), i = 1; p;
++ i, p = (int_pair *) utarray_next(nums, p))
{
Expand All @@ -374,8 +426,13 @@ int ec_glob(const char *pattern, const char *string)
if (p != NULL) /* numbers not matched */
ret = EC_GLOB_NOMATCH;

#ifdef HAVE_PCRE2
pcre2_code_free(re);
pcre2_match_data_free(pcre_match_data);
#else
pcre_free(re);
free(pcre_result);
#endif
utarray_free(nums);

return ret;
Expand Down

0 comments on commit ffb01f6

Please sign in to comment.