Commit ce6d624af223a855a83664106957d4453dd56fcd

Edward Thomson 2019-05-19T10:30:04

regex: optionally use PCRE2 Use PCRE2 and its POSIX compatibility layer if requested by the user. Although PCRE2 is adequate for our needs, the PCRE2 POSIX layer as installed on Debian and Ubuntu systems is broken, so we do not opt-in to it by default to avoid breaking users on those platforms.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f423b82..de7e53c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -65,7 +65,7 @@ OPTION(DEBUG_POOL			"Enable debug pool allocator"				OFF)
 OPTION(ENABLE_WERROR			"Enable compilation with -Werror"			OFF)
 OPTION(USE_BUNDLED_ZLIB    		"Use the bundled version of zlib"			OFF)
 OPTION(DEPRECATE_HARD			"Do not include deprecated functions in the library"	OFF)
-   SET(REGEX				"" CACHE STRING "Regular expression implementation. One of regcomp_l, pcre, regcomp, or builtin.")
+   SET(REGEX				"" CACHE STRING "Regular expression implementation. One of regcomp_l, pcre2, pcre, regcomp, or builtin.")
 
 IF (UNIX AND NOT APPLE)
 	OPTION(ENABLE_REPRODUCIBLE_BUILDS "Enable reproducible builds"				OFF)
diff --git a/cmake/Modules/FindPCRE2.cmake b/cmake/Modules/FindPCRE2.cmake
new file mode 100644
index 0000000..122f0e9
--- /dev/null
+++ b/cmake/Modules/FindPCRE2.cmake
@@ -0,0 +1,38 @@
+# 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 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 pcre2posix.h)
+
+# Look for the library.
+FIND_LIBRARY(PCRE2_LIBRARY NAMES pcre2-8)
+FIND_LIBRARY(PCRE2_POSIX_LIBRARY NAMES pcre2-posix)
+
+# 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_POSIX_LIBRARY PCRE2_INCLUDE_DIR)
+
+# Copy the results to the output variables.
+IF(PCRE2_FOUND)
+	SET(PCRE2_LIBRARIES ${PCRE2_LIBRARY} ${PCRE2_POSIX_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)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 852a2af..cd4c688 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -307,6 +307,18 @@ ENDIF()
 IF(REGEX STREQUAL "regcomp_l")
 	ADD_FEATURE_INFO(regex ON "using system regcomp_l")
 	SET(GIT_REGEX_REGCOMP_L 1)
+ELSEIF(REGEX STREQUAL "pcre2")
+	FIND_PACKAGE(PCRE2)
+
+	IF(NOT PCRE2_FOUND)
+		MESSAGE(FATAL_ERROR "PCRE2 support was requested but not found")
+	ENDIF()
+
+	ADD_FEATURE_INFO(regex ON "using system PCRE2")
+	SET(GIT_REGEX_PCRE2 1)
+
+	LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${PCRE2_INCLUDE_DIRS})
+	LIST(APPEND LIBGIT2_LIBS ${PCRE2_LIBRARIES})
 ELSEIF(REGEX STREQUAL "pcre")
 	ADD_FEATURE_INFO(regex ON "using system PCRE")
 	SET(GIT_REGEX_PCRE 1)
diff --git a/src/features.h.in b/src/features.h.in
index 5468cee..4090fad 100644
--- a/src/features.h.in
+++ b/src/features.h.in
@@ -19,6 +19,7 @@
 #cmakedefine GIT_REGEX_REGCOMP_L
 #cmakedefine GIT_REGEX_REGCOMP
 #cmakedefine GIT_REGEX_PCRE
+#cmakedefine GIT_REGEX_PCRE2
 #cmakedefine GIT_REGEX_BUILTIN 1
 
 #cmakedefine GIT_SSH 1
diff --git a/src/posix_regex.h b/src/posix_regex.h
index e76f69c..421ffeb 100644
--- a/src/posix_regex.h
+++ b/src/posix_regex.h
@@ -37,7 +37,9 @@
 
 #else
 
-# ifdef GIT_REGEX_PCRE
+# if defined(GIT_REGEX_PCRE2)
+#  include <pcre2posix.h>
+# elif defined(GIT_REGEX_PCRE)
 #  include <pcreposix.h>
 # else
 #  include <regex.h>