Skip to content

Commit c6e48fe

Browse files
committed
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 parent 0990298 commit c6e48fe

File tree

4 files changed

+66
-45
lines changed

4 files changed

+66
-45
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ OPTION(DEBUG_POOL "Enable debug pool allocator" OFF)
6565
OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF)
6666
OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib" OFF)
6767
OPTION(DEPRECATE_HARD "Do not include deprecated functions in the library" OFF)
68+
SET(REGEX "" CACHE STRING "Regular expression implementation. One of regcomp_l, pcre, regcomp, or builtin.")
6869

6970
IF (UNIX AND NOT APPLE)
7071
OPTION(ENABLE_REPRODUCIBLE_BUILDS "Enable reproducible builds" OFF)

src/CMakeLists.txt

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,6 @@ IF (ENABLE_TRACE STREQUAL "ON")
4848
ENDIF()
4949
ADD_FEATURE_INFO(tracing GIT_TRACE "tracing support")
5050

51-
# Use `regcomp_l` if available
52-
CHECK_SYMBOL_EXISTS(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L)
53-
IF (HAVE_REGCOMP_L)
54-
SET(GIT_USE_REGCOMP_L 1)
55-
ENDIF ()
56-
57-
# Otherwise, we either want to use system's `regcomp` or our
58-
# bundled regcomp code, if system doesn't provide `regcomp`.
59-
IF(NOT HAVE_REGCOMP_L)
60-
CHECK_FUNCTION_EXISTS(regcomp HAVE_REGCOMP)
61-
IF(NOT HAVE_REGCOMP)
62-
ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/regex" "${libgit2_BINARY_DIR}/deps/regex")
63-
LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/regex")
64-
LIST(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:regex>)
65-
ENDIF()
66-
ENDIF()
67-
6851
CHECK_FUNCTION_EXISTS(futimens HAVE_FUTIMENS)
6952
IF (HAVE_FUTIMENS)
7053
SET(GIT_USE_FUTIMENS 1)
@@ -306,14 +289,38 @@ ELSE()
306289
MESSAGE(FATAL_ERROR "Asked for unknown SHA1 backend ${SHA1_BACKEND}")
307290
ENDIF()
308291

309-
# Include PCRE and its POSIX regex compatibility layer when it is required
310-
IF (HAVE_REGCOMP_L)
292+
# Specify regular expression implementation
293+
IF(REGEX STREQUAL "")
294+
CHECK_SYMBOL_EXISTS(regcomp_l "regex.h;xlocale.h" HAVE_REGCOMP_L)
295+
CHECK_SYMBOL_EXISTS(pcre_regcomp "pcreposix.h" HAVE_PCRE)
296+
297+
IF(HAVE_REGCOMP_L)
298+
SET(REGEX "regcomp_l")
299+
ELSEIF(HAVE_PCRE)
300+
SET(REGEX "pcre")
301+
ELSE()
302+
SET(REGEX "builtin")
303+
ENDIF()
304+
ENDIF()
305+
306+
IF(REGEX STREQUAL "regcomp_l")
311307
ADD_FEATURE_INFO(regex ON "using system regcomp_l")
312-
ELSE()
308+
SET(GIT_REGEX_REGCOMP_L 1)
309+
ELSEIF(REGEX STREQUAL "pcre")
310+
ADD_FEATURE_INFO(regex ON "using system PCRE")
311+
SET(GIT_REGEX_PCRE 1)
312+
ELSEIF(REGEX STREQUAL "regcomp")
313+
ADD_FEATURE_INFO(regex ON "using system regcomp")
314+
SET(GIT_REGEX_REGCOMP 1)
315+
ELSEIF(REGEX STREQUAL "builtin")
316+
ADD_FEATURE_INFO(regex ON "using bundled PCRE")
317+
SET(GIT_REGEX_PCRE 1)
318+
313319
ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/pcre" "${libgit2_BINARY_DIR}/deps/pcre")
314320
LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/pcre")
315321
LIST(APPEND LIBGIT2_OBJECTS $<TARGET_OBJECTS:pcre>)
316-
ADD_FEATURE_INFO(regex ON "using bundled PCRE")
322+
ELSE()
323+
MESSAGE(FATAL_ERROR "The REGEX option provided is not supported")
317324
ENDIF()
318325

319326
# Optional external dependency: http-parser

src/features.h.in

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
#cmakedefine GIT_USE_STAT_MTIMESPEC 1
1616
#cmakedefine GIT_USE_STAT_MTIME_NSEC 1
1717
#cmakedefine GIT_USE_FUTIMENS 1
18-
#cmakedefine GIT_USE_REGCOMP_L 1
18+
19+
#cmakedefine GIT_REGEX_REGCOMP_L
20+
#cmakedefine GIT_REGEX_REGCOMP
21+
#cmakedefine GIT_REGEX_PCRE
1922

2023
#cmakedefine GIT_SSH 1
2124
#cmakedefine GIT_SSH_MEMORY_CREDENTIALS 1

src/posix_regex.h

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,13 @@
1010
#include "common.h"
1111

1212
/*
13-
* Regular expressions: if the operating system has p_regcomp_l,
14-
* use it so that we can override the locale environment variable.
15-
* Otherwise, use our bundled PCRE implementation.
13+
* Regular expressions: if we were asked to use PCRE (either our
14+
* bundled version or a system version) then use their regcomp
15+
* compatible implementation.
1616
*/
1717

18-
#ifdef GIT_USE_REGCOMP_L
19-
# include <regex.h>
20-
# include <xlocale.h>
21-
22-
#define P_REG_EXTENDED REG_EXTENDED
23-
#define P_REG_ICASE REG_ICASE
24-
#define P_REG_NOMATCH REG_NOMATCH
18+
#ifdef GIT_REGEX_PCRE
2519

26-
#define p_regex_t regex_t
27-
#define p_regmatch_t regmatch_t
28-
29-
GIT_INLINE(int) p_regcomp(p_regex_t *preg, const char *pattern, int cflags)
30-
{
31-
return regcomp_l(preg, pattern, cflags, (locale_t) 0);
32-
}
33-
34-
#define p_regerror regerror
35-
#define p_regexec regexec
36-
#define p_regfree regfree
37-
38-
#else
3920
# include "pcreposix.h"
4021

4122
# 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)
4829
# define p_regerror pcre_regerror
4930
# define p_regexec pcre_regexec
5031
# define p_regfree pcre_regfree
32+
33+
/* Otherwise, use regcomp_l if available, or regcomp if not. */
34+
#else
35+
36+
# include <regex.h>
37+
38+
# define P_REG_EXTENDED REG_EXTENDED
39+
# define P_REG_ICASE REG_ICASE
40+
# define P_REG_NOMATCH REG_NOMATCH
41+
42+
# define p_regex_t regex_t
43+
# define p_regmatch_t regmatch_t
44+
45+
# define p_regerror regerror
46+
# define p_regexec regexec
47+
# define p_regfree regfree
48+
49+
# ifdef GIT_REGEX_REGCOMP_L
50+
# include <xlocale.h>
51+
52+
GIT_INLINE(int) p_regcomp(p_regex_t *preg, const char *pattern, int cflags)
53+
{
54+
return regcomp_l(preg, pattern, cflags, (locale_t) 0);
55+
}
56+
57+
# else
58+
# define p_regcomp regcomp
59+
# endif /* GIT_REGEX_REGCOMP_L */
60+
5161
#endif
5262

5363
#endif

0 commit comments

Comments
 (0)