regex: allow regex selection in cmake Users can now select which regex implementation they want to use: one of the system `regcomp_l`, the system PCRE, the builtin PCRE or the system's `regcomp`. By default the system `regcomp_l` will be used if it exists, otherwise the system PCRE will be used. If neither of those exist, then the builtin PCRE implementation will be used. The system's `regcomp` is not used by default due to problems with locales.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 88eb9ec..f423b82 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -65,6 +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.")
IF (UNIX AND NOT APPLE)
OPTION(ENABLE_REPRODUCIBLE_BUILDS "Enable reproducible builds" OFF)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4cdfe23..6379495 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -48,23 +48,6 @@ IF (ENABLE_TRACE STREQUAL "ON")
ENDIF()
ADD_FEATURE_INFO(tracing GIT_TRACE "tracing support")
-# Use `regcomp_l` if available
-CHECK_SYMBOL_EXISTS(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L)
-IF (HAVE_REGCOMP_L)
- SET(GIT_USE_REGCOMP_L 1)
-ENDIF ()
-
-# Otherwise, we either want to use system's `regcomp` or our
-# bundled regcomp code, if system doesn't provide `regcomp`.
-IF(NOT HAVE_REGCOMP_L)
- CHECK_FUNCTION_EXISTS(regcomp HAVE_REGCOMP)
- IF(NOT HAVE_REGCOMP)
- ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/regex" "${libgit2_BINARY_DIR}/deps/regex")
- LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/regex")
- LIST(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:regex>)
- ENDIF()
-ENDIF()
-
CHECK_FUNCTION_EXISTS(futimens HAVE_FUTIMENS)
IF (HAVE_FUTIMENS)
SET(GIT_USE_FUTIMENS 1)
@@ -306,14 +289,38 @@ ELSE()
MESSAGE(FATAL_ERROR "Asked for unknown SHA1 backend ${SHA1_BACKEND}")
ENDIF()
-# Include PCRE and its POSIX regex compatibility layer when it is required
-IF (HAVE_REGCOMP_L)
+# Specify regular expression implementation
+IF(REGEX STREQUAL "")
+ CHECK_SYMBOL_EXISTS(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L)
+ CHECK_SYMBOL_EXISTS(pcre_regcomp "pcreposix.h" HAVE_PCRE)
+
+ IF(HAVE_REGCOMP_L)
+ SET(REGEX "regcomp_l")
+ ELSEIF(HAVE_PCRE)
+ SET(REGEX "pcre")
+ ELSE()
+ SET(REGEX "builtin")
+ ENDIF()
+ENDIF()
+
+IF(REGEX STREQUAL "regcomp_l")
ADD_FEATURE_INFO(regex ON "using system regcomp_l")
-ELSE()
+ SET(GIT_REGEX_REGCOMP_L 1)
+ELSEIF(REGEX STREQUAL "pcre")
+ ADD_FEATURE_INFO(regex ON "using system PCRE")
+ SET(GIT_REGEX_PCRE 1)
+ELSEIF(REGEX STREQUAL "regcomp")
+ ADD_FEATURE_INFO(regex ON "using system regcomp")
+ SET(GIT_REGEX_REGCOMP 1)
+ELSEIF(REGEX STREQUAL "builtin")
+ ADD_FEATURE_INFO(regex ON "using bundled PCRE")
+ SET(GIT_REGEX_PCRE 1)
+
ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/pcre" "${libgit2_BINARY_DIR}/deps/pcre")
LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/pcre")
LIST(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:pcre>)
- ADD_FEATURE_INFO(regex ON "using bundled PCRE")
+ELSE()
+ MESSAGE(FATAL_ERROR "The REGEX option provided is not supported")
ENDIF()
# Optional external dependency: http-parser
diff --git a/src/features.h.in b/src/features.h.in
index 694a61c..fdc7594 100644
--- a/src/features.h.in
+++ b/src/features.h.in
@@ -15,7 +15,10 @@
#cmakedefine GIT_USE_STAT_MTIMESPEC 1
#cmakedefine GIT_USE_STAT_MTIME_NSEC 1
#cmakedefine GIT_USE_FUTIMENS 1
-#cmakedefine GIT_USE_REGCOMP_L 1
+
+#cmakedefine GIT_REGEX_REGCOMP_L
+#cmakedefine GIT_REGEX_REGCOMP
+#cmakedefine GIT_REGEX_PCRE
#cmakedefine GIT_SSH 1
#cmakedefine GIT_SSH_MEMORY_CREDENTIALS 1
diff --git a/src/posix_regex.h b/src/posix_regex.h
index c39631e..5d0342e 100644
--- a/src/posix_regex.h
+++ b/src/posix_regex.h
@@ -10,32 +10,13 @@
#include "common.h"
/*
- * Regular expressions: if the operating system has p_regcomp_l,
- * use it so that we can override the locale environment variable.
- * Otherwise, use our bundled PCRE implementation.
+ * Regular expressions: if we were asked to use PCRE (either our
+ * bundled version or a system version) then use their regcomp
+ * compatible implementation.
*/
-#ifdef GIT_USE_REGCOMP_L
-# include <regex.h>
-# include <xlocale.h>
-
-#define P_REG_EXTENDED REG_EXTENDED
-#define P_REG_ICASE REG_ICASE
-#define P_REG_NOMATCH REG_NOMATCH
+#ifdef GIT_REGEX_PCRE
-#define p_regex_t regex_t
-#define p_regmatch_t regmatch_t
-
-GIT_INLINE(int) p_regcomp(p_regex_t *preg, const char *pattern, int cflags)
-{
- return regcomp_l(preg, pattern, cflags, (locale_t) 0);
-}
-
-#define p_regerror regerror
-#define p_regexec regexec
-#define p_regfree regfree
-
-#else
# include "pcreposix.h"
# define P_REG_EXTENDED PCRE_REG_EXTENDED
@@ -48,6 +29,35 @@ GIT_INLINE(int) p_regcomp(p_regex_t *preg, const char *pattern, int cflags)
# define p_regerror pcre_regerror
# define p_regexec pcre_regexec
# define p_regfree pcre_regfree
+
+/* Otherwise, use regcomp_l if available, or regcomp if not. */
+#else
+
+# include <regex.h>
+
+# define P_REG_EXTENDED REG_EXTENDED
+# define P_REG_ICASE REG_ICASE
+# define P_REG_NOMATCH REG_NOMATCH
+
+# define p_regex_t regex_t
+# define p_regmatch_t regmatch_t
+
+# define p_regerror regerror
+# define p_regexec regexec
+# define p_regfree regfree
+
+# ifdef GIT_REGEX_REGCOMP_L
+# include <xlocale.h>
+
+GIT_INLINE(int) p_regcomp(p_regex_t *preg, const char *pattern, int cflags)
+{
+ return regcomp_l(preg, pattern, cflags, (locale_t) 0);
+}
+
+# else
+# define p_regcomp regcomp
+# endif /* GIT_REGEX_REGCOMP_L */
+
#endif
#endif