Until now it was not easily possible to remove all files but some in a given directory. By enabling Perl regular expressions for NoExtract this is now made possible through negative lookahead. Fixes FS#31749. --- This patch is work in progress. I want to check if there is interest in having this feature available in pacman and how the extra dependency on libpcre is received. If it is well received I might still do some rework for the actual matching of NoExtract items, as currently I'm always recompiling the pattern for each match. configure.ac | 13 ++++++++++++- lib/libalpm/Makefile.am | 6 ++++-- lib/libalpm/add.c | 2 +- lib/libalpm/util.c | 22 ++++++++++++++++++++++ lib/libalpm/util.h | 1 + 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 1ea0fce..29ea101 100644 --- a/configure.ac +++ b/configure.ac @@ -230,6 +230,17 @@ if test "x$with_libcurl" != "xno"; then fi AM_CONDITIONAL(HAVE_LIBCURL, [test "$have_libcurl" = "yes"]) +# Check for PCRE +have_libpcre=no +if test "x$with_libpcre" != "xno"; then + PKG_CHECK_MODULES(LIBPCRE, [libpcre], + [AC_DEFINE(HAVE_LIBPCRE, 1, [Define if libpcre is available]) have_libpcre=yes], have_libpcre=no) + if test "x$have_libpcre" = xno -a "x$with_libpcre" = xyes; then + AC_MSG_ERROR([*** libpcre is required for file matching support]) + fi +fi +AM_CONDITIONAL(HAVE_LIBPCRE, [test "$have_libpcre" = "yes"]) + # Check for gpgme AC_MSG_CHECKING(whether to link with libgpgme) AS_IF([test "x$with_gpgme" != "xno"], @@ -523,7 +534,7 @@ ${PACKAGE_NAME}: compiler : ${CC} preprocessor flags : ${CPPFLAGS} compiler flags : ${WARNING_CFLAGS} ${CFLAGS} - library flags : ${LIBS} ${LIBSSL_LIBS} ${LIBARCHIVE_LIBS} ${LIBCURL_LIBS} ${GPGME_LIBS} + library flags : ${LIBS} ${LIBSSL_LIBS} ${LIBPCRE_LIBS} ${LIBARCHIVE_LIBS} ${LIBCURL_LIBS} ${GPGME_LIBS} linker flags : ${LDFLAGS} Architecture : ${CARCH} diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index 171bc46..0f71aed 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -75,13 +75,15 @@ libalpm_la_CFLAGS = \ $(GPGME_CFLAGS) \ $(LIBARCHIVE_CFLAGS) \ $(LIBCURL_CFLAGS) \ - $(LIBSSL_CFLAGS) + $(LIBSSL_CFLAGS) \ + $(LIBPCRE_CFLAGS) libalpm_la_LIBADD = \ $(LTLIBINTL) \ $(GPGME_LIBS) \ $(LIBARCHIVE_LIBS) \ $(LIBCURL_LIBS) \ - $(LIBSSL_LIBS) + $(LIBSSL_LIBS) \ + $(LIBPCRE_LIBS) # vim:set ts=2 sw=2 noet: diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index c20e7c6..d80dbe4 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -183,7 +183,7 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive, } /* if a file is in NoExtract then we never extract it */ - if(alpm_list_find(handle->noextract, entryname, _alpm_fnmatch)) { + if(alpm_list_find(handle->noextract, entryname, _alpm_regex)) { _alpm_log(handle, ALPM_LOG_DEBUG, "%s is in NoExtract," " skipping extraction of %s\n", entryname, filename); diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index f84fb66..5858d28 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -33,6 +33,7 @@ #include <sys/wait.h> #include <locale.h> /* setlocale */ #include <fnmatch.h> +#include <pcre.h> /* libarchive */ #include <archive.h> @@ -1261,6 +1262,27 @@ int _alpm_fnmatch(const void *pattern, const void *string) return fnmatch(pattern, string, 0); } +/** Checks whether a string matches an extended Perl regular expression. + * @param pattern string to match against + * @param string string to check against pattern + * @return 0 if string matches pattern, non-zero if they don't match and on + * error + */ +int _alpm_regex(const void *pattern, const void *string) +{ + const char *error; + int erroroff; + + pcre *pcre = pcre_compile(pattern, PCRE_EXTENDED | PCRE_ANCHORED, &error, &erroroff, NULL); + if (error != NULL) { + return -1; + } + + int ret = pcre_exec(pcre, NULL, string, strlen(string), 0, 0, NULL, 0); + pcre_free(pcre); + return ret < 0; +} + void _alpm_alloc_fail(size_t size) { fprintf(stderr, "alloc failure: could not allocate %zd bytes\n", size); diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 56031f3..5ec36b6 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -141,6 +141,7 @@ int _alpm_raw_cmp(const char *first, const char *second); int _alpm_raw_ncmp(const char *first, const char *second, size_t max); int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode); int _alpm_fnmatch(const void *pattern, const void *string); +int _alpm_regex(const void *pattern, const void *string); #ifndef HAVE_STRSEP char *strsep(char **, const char *); -- 1.8.3