summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Mejia <amejia004@gmail.com>2013-01-31 18:39:39 -0500
committerAndres Mejia <amejia004@gmail.com>2013-01-31 18:39:39 -0500
commitb708276ac543fb1c3d48fbd57f5592334a0dea28 (patch)
tree70958d75d3c94dc4412670e4378c4d61eba79c11
parent1148d8d933c6f82033ce19e1d67c8fa1dea50c44 (diff)
downloadlibarchive-b708276ac543fb1c3d48fbd57f5592334a0dea28.tar.gz
Support POSIX regular expression support using PCRE in CMake builds.
This change is mainly meant for Windows regex support, where PCRE Windows development is much more active than development of the regex library found in the GNUWin32 packages. I found that the latest release of PCRE built right out of the box, unlike the GNUWin32 regex library released 6 years ago which failed to build from source for me using the mingw toolchain.
-rw-r--r--CMakeLists.txt136
-rw-r--r--build/cmake/config.h.in3
-rw-r--r--tar/bsdtar.c4
-rw-r--r--tar/bsdtar.h2
-rw-r--r--tar/subst.c8
-rw-r--r--tar/util.c2
6 files changed, 110 insertions, 45 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0c8bf812..6a77ff51 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -150,6 +150,7 @@ OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" FALSE)
OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
OPTION(ENABLE_ACL "Enable ACL support" ON)
OPTION(ENABLE_ICONV "Enable iconv support" ON)
+OPTION(ENABLE_PCREPOSIX "Enable POSIX regular expression support using PCRE" OFF)
OPTION(ENABLE_TEST "Enable unit and regression tests" ON)
IF(ENABLE_TEST)
@@ -868,50 +869,107 @@ ELSE(LIBXML2_FOUND)
ENDIF(LIBXML2_FOUND)
MARK_AS_ADVANCED(CLEAR LIBXML2_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR LIBXML2_LIBRARIES)
+
#
-# Find Libregex
+# POSIX Regular Expression support
#
-FIND_PATH(REGEX_INCLUDE_DIR regex.h)
-IF(REGEX_INCLUDE_DIR)
- CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBC)
+IF(ENABLE_PCREPOSIX)
#
- # If libc does not provide regex, find libregex.
+ # If requested, try finding library for PCREPOSIX
#
- IF(NOT HAVE_REGCOMP_LIBC)
- CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
- FIND_LIBRARY(REGEX_LIBRARY regex)
- IF(REGEX_LIBRARY)
- SET(CMAKE_REQUIRED_LIBRARIES ${REGEX_LIBRARY})
- CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBREGEX)
- IF(HAVE_REGCOMP_LIBREGEX)
- LIST(APPEND ADDITIONAL_LIBS ${REGEX_LIBRARY})
- #
- # If regex.h is not found, retry looking for regex.h at
- # REGEX_INCLUDE_DIR
- #
- IF(NOT HAVE_REGEX_H)
- UNSET(HAVE_REGEX_H CACHE)
- INCLUDE_DIRECTORIES(${REGEX_INCLUDE_DIR})
- SET(CMAKE_REQUIRED_INCLUDES ${REGEX_INCLUDE_DIR})
- LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
- ENDIF(NOT HAVE_REGEX_H)
- # Test if a macro is needed for the library.
- TRY_MACRO_FOR_LIBRARY(
- "${REGEX_INCLUDE_DIR}" "${REGEX_LIBRARY}"
- COMPILES
- "#include <stddef.h>\n#include <regex.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
- "USE_REGEX_DLL;USE_REGEX_STATIC")
- IF(USE_REGEX_DLL)
- ADD_DEFINITIONS(-DUSE_REGEX_DLL)
- ELSEIF(USE_REGEX_STATIC)
- ADD_DEFINITIONS(-DUSE_REGEX_STATIC)
- ENDIF(USE_REGEX_DLL)
- ENDIF(HAVE_REGCOMP_LIBREGEX)
- ENDIF(REGEX_LIBRARY)
- CMAKE_POP_CHECK_STATE() # Restore the state of the variables
- ENDIF(NOT HAVE_REGCOMP_LIBC)
-ENDIF(REGEX_INCLUDE_DIR)
+ IF (PCREPOSIX_INCLUDE_DIRS)
+ # Already in cache, be silent
+ SET(PCREPOSIX_FIND_QUIETLY TRUE)
+ ENDIF (PCREPOSIX_INCLUDE_DIRS)
+
+ FIND_PATH(PCREPOSIX_INCLUDE_DIR pcreposix.h)
+
+ SET(PCREPOSIX_NAMES pcreposix)
+ FIND_LIBRARY(PCREPOSIX_LIBRARY NAMES ${PCREPOSIX_NAMES} )
+
+ # handle the QUIETLY and REQUIRED arguments and set PCREPOSIX_FOUND to TRUE if
+ # all listed variables are TRUE
+ INCLUDE(FindPackageHandleStandardArgs)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCREPOSIX DEFAULT_MSG PCREPOSIX_LIBRARY PCREPOSIX_INCLUDE_DIR)
+ IF(PCREPOSIX_FOUND)
+ SET( PCREPOSIX_LIBRARIES ${PCREPOSIX_LIBRARY} )
+ SET( PCREPOSIX_INCLUDE_DIRS ${PCREPOSIX_INCLUDE_DIR} )
+
+ IF(PCREPOSIX_LIBRARY)
+ SET(CMAKE_REQUIRED_LIBRARIES ${PCREPOSIX_LIBRARY})
+ ENDIF(PCREPOSIX_LIBRARY)
+
+ IF(PCREPOSIX_INCLUDE_DIR)
+ INCLUDE_DIRECTORIES(${PCREPOSIX_INCLUDE_DIR})
+ SET(CMAKE_REQUIRED_INCLUDES ${PCREPOSIX_INCLUDE_DIR})
+ ENDIF(PCREPOSIX_INCLUDE_DIR)
+ LA_CHECK_INCLUDE_FILE("pcreposix.h" HAVE_PCREPOSIX_H)
+
+ # Test if a macro is needed for the library.
+ TRY_MACRO_FOR_LIBRARY(
+ "${PCREPOSIX_INCLUDE_DIR}" "${PCREPOSIX_LIBRARY}"
+ COMPILES
+ "#include <stddef.h>\n#include <pcreposix.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
+ "PCRE_STATIC")
+ IF(PCRE_STATIC)
+ # TODO: Need to link against libpcre if static linking
+ ADD_DEFINITIONS(-DPCRE_STATIC)
+ ENDIF(PCRE_STATIC)
+ ELSE(PCREPOSIX_FOUND)
+ SET( PCREPOSIX_LIBRARIES )
+ SET( PCREPOSIX_INCLUDE_DIRS )
+ ENDIF(PCREPOSIX_FOUND)
+
+ MARK_AS_ADVANCED( PCREPOSIX_LIBRARIES PCREPOSIX_INCLUDE_DIRS )
+ENDIF(ENABLE_PCREPOSIX)
+
+IF(NOT PCREPOSIX_FOUND)
+ #
+ # If PCREPOSIX is not found or not requested, try using regex
+ # from libc or libregex
+ #
+ FIND_PATH(REGEX_INCLUDE_DIR regex.h)
+ IF(REGEX_INCLUDE_DIR)
+ CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBC)
+ #
+ # If libc does not provide regex, find libregex.
+ #
+ IF(NOT HAVE_REGCOMP_LIBC)
+ CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
+ FIND_LIBRARY(REGEX_LIBRARY regex)
+ IF(REGEX_LIBRARY)
+ SET(CMAKE_REQUIRED_LIBRARIES ${REGEX_LIBRARY})
+ CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBREGEX)
+ IF(HAVE_REGCOMP_LIBREGEX)
+ LIST(APPEND ADDITIONAL_LIBS ${REGEX_LIBRARY})
+ #
+ # If regex.h is not found, retry looking for regex.h at
+ # REGEX_INCLUDE_DIR
+ #
+ IF(NOT HAVE_REGEX_H)
+ UNSET(HAVE_REGEX_H CACHE)
+ INCLUDE_DIRECTORIES(${REGEX_INCLUDE_DIR})
+ SET(CMAKE_REQUIRED_INCLUDES ${REGEX_INCLUDE_DIR})
+ LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
+ ENDIF(NOT HAVE_REGEX_H)
+ # Test if a macro is needed for the library.
+ TRY_MACRO_FOR_LIBRARY(
+ "${REGEX_INCLUDE_DIR}" "${REGEX_LIBRARY}"
+ COMPILES
+ "#include <stddef.h>\n#include <regex.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
+ "USE_REGEX_DLL;USE_REGEX_STATIC")
+ IF(USE_REGEX_DLL)
+ ADD_DEFINITIONS(-DUSE_REGEX_DLL)
+ ELSEIF(USE_REGEX_STATIC)
+ ADD_DEFINITIONS(-DUSE_REGEX_STATIC)
+ ENDIF(USE_REGEX_DLL)
+ ENDIF(HAVE_REGCOMP_LIBREGEX)
+ ENDIF(REGEX_LIBRARY)
+ CMAKE_POP_CHECK_STATE() # Restore the state of the variables
+ ENDIF(NOT HAVE_REGCOMP_LIBC)
+ ENDIF(REGEX_INCLUDE_DIR)
+ENDIF(NOT PCREPOSIX_FOUND)
#
# Check functions
#
diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in
index ab2ef2f1..77b8d3bd 100644
--- a/build/cmake/config.h.in
+++ b/build/cmake/config.h.in
@@ -706,6 +706,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the <paths.h> header file. */
#cmakedefine HAVE_PATHS_H 1
+/* Define to 1 if you have the <pcreposix.h> header file. */
+#cmakedefine HAVE_PCREPOSIX_H 1
+
/* Define to 1 if you have the `pipe' function. */
#cmakedefine HAVE_PIPE 1
diff --git a/tar/bsdtar.c b/tar/bsdtar.c
index 4d421dfb..47267579 100644
--- a/tar/bsdtar.c
+++ b/tar/bsdtar.c
@@ -570,7 +570,7 @@ main(int argc, char **argv)
bsdtar->extract_flags |= ARCHIVE_EXTRACT_SPARSE;
break;
case 's': /* NetBSD pax-as-tar */
-#if HAVE_REGEX_H
+#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
add_substitution(bsdtar, bsdtar->argument);
#else
lafe_warnc(0,
@@ -806,7 +806,7 @@ main(int argc, char **argv)
}
archive_match_free(bsdtar->matching);
-#if HAVE_REGEX_H
+#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
cleanup_substitution(bsdtar);
#endif
cset_free(bsdtar->cset);
diff --git a/tar/bsdtar.h b/tar/bsdtar.h
index a03d05ad..637e1b9d 100644
--- a/tar/bsdtar.h
+++ b/tar/bsdtar.h
@@ -173,7 +173,7 @@ void tar_mode_x(struct bsdtar *bsdtar);
void usage(void);
int yes(const char *fmt, ...);
-#if HAVE_REGEX_H
+#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
void add_substitution(struct bsdtar *, const char *);
int apply_substitution(struct bsdtar *, const char *, char **, int, int);
void cleanup_substitution(struct bsdtar *);
diff --git a/tar/subst.c b/tar/subst.c
index 0ef95b91..fd6f8e22 100644
--- a/tar/subst.c
+++ b/tar/subst.c
@@ -26,11 +26,15 @@
#include "bsdtar_platform.h"
__FBSDID("$FreeBSD: src/usr.bin/tar/subst.c,v 1.4 2008/06/15 10:08:16 kientzle Exp $");
-#if HAVE_REGEX_H
+#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
#include "bsdtar.h"
#include <errno.h>
+#ifdef HAVE_PCREPOSIX_H
+#include <pcreposix.h>
+#else
#include <regex.h>
+#endif
#include <stdlib.h>
#include <string.h>
@@ -317,4 +321,4 @@ cleanup_substitution(struct bsdtar *bsdtar)
}
free(subst);
}
-#endif /* HAVE_REGEX_H */
+#endif /* defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H) */
diff --git a/tar/util.c b/tar/util.c
index ff4cd4fc..b1b9b93d 100644
--- a/tar/util.c
+++ b/tar/util.c
@@ -382,7 +382,7 @@ int
edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
{
const char *name = archive_entry_pathname(entry);
-#if HAVE_REGEX_H
+#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
char *subst_name;
int r;