From 16e4a580e7f250a2c01caa03faab308079c70396 Mon Sep 17 00:00:00 2001 Message-Id: <16e4a580e7f250a2c01caa03faab308079c70396.1714844831.git.mdw@distorted.org.uk> From: Mark Wooding Date: Wed, 29 Nov 2017 11:37:56 +0000 Subject: [PATCH] configure.ac, acinclude.m4, lib/regexp.[ch]: Support `libpcre2'. Organization: Straylight/Edgeware From: Mark Wooding This is the future of `pcre', so we'll have to support it sooner or later. Indeed, I think this probably counts as `later'. --- README | 2 +- acinclude.m4 | 38 ++++++++++++++++++++++++++++++++ configure.ac | 30 ++++++++++++++++++++----- debian/control | 2 +- lib/regexp.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/regexp.h | 10 ++++++++- 6 files changed, 132 insertions(+), 9 deletions(-) diff --git a/README b/README index 3e917a9..1be8298 100644 --- a/README +++ b/README @@ -28,7 +28,7 @@ Build dependencies: libdb 4.5.20 not 4.6; 4.[78] seem to be ok libgc 6.8 libvorbisfile 1.2.0 - libpcre 7.6 need UTF-8 support + libpcre 10.22 or 7.6 need UTF-8 support libmad 0.15.1b libgcrypt 1.4.1 libasound 1.0.16 diff --git a/acinclude.m4 b/acinclude.m4 index 5ab8672..287c256 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -101,6 +101,44 @@ AC_DEFUN([RJK_REQUIRE_PCRE_UTF8],[ fi ]) +AC_DEFUN([RJK_REQUIRE_PCRE2_UTF8],[ + AC_CACHE_CHECK([whether libpcre2 was built with UTF-8 support], + [rjk_cv_pcre_utf8],[ + save_CFLAGS="$CFLAGS" save_LIBS="$LIBS" + CFLAGS="$CFLAGS $1" LIBS="$LIBS $2" + AC_RUN_IFELSE([AC_LANG_PROGRAM([ + #define PCRE2_CODE_UNIT_WIDTH 8 + #include + #include + ], + [ + pcre2_code *r; + int errcode; + int erroffset; + char errbuf[[128]]; + + r = pcre2_compile("\x80\x80", 2, PCRE2_UTF, + &errcode, &erroffset, 0); + if(!r) { + pcre2_get_error_message(errcode, errbuf, sizeof(errbuf)); + fprintf(stderr, "pcre2_compile: %s at %d", + errbuf, erroffset); + exit(0); + } else { + fprintf(stderr, "accepted bogus UTF-8 string\n"); + exit(1); + } + ])], + [rjk_cv_pcre_utf8=yes], + [rjk_cv_pcre_utf8=no], + [AC_MSG_WARN([cross-compiling, cannot check libpcre2 behaviour])]) + CFLAGS="$save_CFLAGS" LIBS="$save_LIBS" + ]) + if test $rjk_cv_pcre_utf8 = no; then + AC_MSG_ERROR([please rebuild your pcre library with --enable-utf8]) + fi +]) + AC_DEFUN([RJK_GCOV],[ GCOV=${GCOV:-true} AC_ARG_WITH([gcov], diff --git a/configure.ac b/configure.ac index 9a6bf70..306b338 100644 --- a/configure.ac +++ b/configure.ac @@ -503,9 +503,18 @@ LIBS=$mdw_SAVE_LIBS AC_CHECK_LIB(gcrypt, gcry_md_open, [AC_SUBST(LIBGCRYPT,[-lgcrypt])], [missing_libraries="$missing_libraries libgcrypt"]) -AC_CHECK_LIB(pcre, pcre_compile, - [AC_SUBST(LIBPCRE,[-lpcre])], - [missing_libraries="$missing_libraries libpcre"]) +PKG_CHECK_MODULES([PCRE2], [libpcre2-8], [have_pcre2=yes], [have_pcre2=no]) +case $have_pcre2 in + yes) + CFLAGS="$CFLAGS $PCRE2_CFLAGS" LIBPCRE=$PCRE2_LIBS + AC_DEFINE([HAVE_LIBPCRE2], [1], [Define if building with libpcre2.]) + ;; + no) + AC_CHECK_LIB(pcre, pcre_compile, + [AC_SUBST(LIBPCRE,[-lpcre])], + [missing_libraries="$missing_libraries libpcre"]) + ;; +esac if test $want_alsa = yes; then AC_CHECK_LIB([asound], [snd_pcm_open], [AC_SUBST(LIBASOUND,[-lasound])]) @@ -586,7 +595,7 @@ if test $want_coreaudio = yes; then AC_CHECK_HEADERS([CoreAudio/AudioHardware.h]) fi AC_CHECK_HEADERS([inttypes.h sys/time.h sys/socket.h netinet/in.h \ - arpa/inet.h sys/un.h netdb.h pcre.h pwd.h langinfo.h]) + arpa/inet.h sys/un.h netdb.h pwd.h langinfo.h]) # We don't bother checking very standard stuff # Compilation will fail if any of these headers are missing, so we # check for them here and fail early. @@ -597,10 +606,16 @@ if test $want_server = yes; then fi AC_CHECK_HEADERS([dlfcn.h gcrypt.h \ getopt.h iconv.h langinfo.h \ - pcre.h sys/ioctl.h \ + sys/ioctl.h \ syslog.h unistd.h],[:],[ missing_headers="$missing_headers $ac_header" ]) +case $have_pcre2 in + no) + AC_CHECK_HEADERS([pcre.h], [:], + [missing_headers="$missing_headers $ac_header"]) + ;; +esac AC_CHECK_HEADERS([samplerate.h]) if test ! -z "$missing_headers"; then @@ -608,7 +623,10 @@ if test ! -z "$missing_headers"; then fi # We require that libpcre support UTF-8 -RJK_REQUIRE_PCRE_UTF8([-lpcre]) +case $have_pcre2 in + yes) RJK_REQUIRE_PCRE2_UTF8([$PCRE2_CFLAGS], [$PCRE2_LIBS]) ;; + no) RJK_REQUIRE_PCRE_UTF8([-lpcre]) ;; +esac # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git a/debian/control b/debian/control index d4a9f0f..d1f9426 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Maintainer: Richard Kettlewell Section: sound Priority: optional Standards-Version: 3.8.1.0 -Build-Depends: libgc6-dev | libgc-dev, libgcrypt-dev, libdb4.3-dev | libdb4.5-dev | libdb4.7-dev | libdb4.8-dev | libdb5.1-dev, libpcre3-dev, libvorbis-dev, libmad0-dev, libasound2-dev, libpulse-dev, python, libflac-dev, libgtk2.0-dev (>= 2.12.12), pkg-config, libgstreamer1.0-dev | libgstreamer0.10-dev, libgstreamer-plugins-base1.0-dev | libgstreamer-plugins-base0.10-dev, libsamplerate0-dev +Build-Depends: libgc6-dev | libgc-dev, libgcrypt-dev, libdb4.3-dev | libdb4.5-dev | libdb4.7-dev | libdb4.8-dev | libdb5.1-dev, libpcre2-dev | libpcre3-dev, libvorbis-dev, libmad0-dev, libasound2-dev, libpulse-dev, python, libflac-dev, libgtk2.0-dev (>= 2.12.12), pkg-config, libgstreamer1.0-dev | libgstreamer0.10-dev, libgstreamer-plugins-base1.0-dev | libgstreamer-plugins-base0.10-dev, libsamplerate0-dev Vcs-Git: https://code.google.com/p/disorder/ Homepage: http://www.greenend.org.uk/rjk/disorder/ diff --git a/lib/regexp.c b/lib/regexp.c index cb5ecc6..5199339 100644 --- a/lib/regexp.c +++ b/lib/regexp.c @@ -23,6 +23,63 @@ #include "regexp.h" #include "mem.h" +#ifdef HAVE_LIBPCRE2 + +static pcre2_general_context *genctx = 0; +static pcre2_compile_context *compctx = 0; + +static void *rxalloc(size_t sz, void attribute((unused)) *q) + { return xmalloc(sz); } +static void rxfree(void *p, void attribute((unused)) *q) + { xfree(p); } + +void regexp_setup(void) +{ + if(genctx) { + pcre2_compile_context_free(compctx); + pcre2_general_context_free(genctx); + } + genctx = pcre2_general_context_create(rxalloc, rxfree, 0); + compctx = pcre2_compile_context_create(genctx); +} + +regexp *regexp_compile(const char *pat, unsigned f, + char *errbuf, size_t errlen, size_t *erroff_out) +{ + int errcode; + PCRE2_SIZE erroff; + regexp *re; + + re = pcre2_compile((PCRE2_SPTR)pat, strlen(pat), f, + &errcode, &erroff, compctx); + if(!re) { + *erroff_out = erroff; + pcre2_get_error_message(errcode, (PCRE2_UCHAR *)errbuf, errlen); + } + return re; +} + +int regexp_match(const regexp *re, const char *s, size_t n, unsigned f, + size_t *ov, size_t on) +{ + int rc; + pcre2_match_data *m; + PCRE2_SIZE *ovp; + size_t i; + + m = pcre2_match_data_create(on, genctx); + rc = pcre2_match(re, (PCRE2_SPTR)s, n, 0, f, m, 0); + ovp = pcre2_get_ovector_pointer(m); + for(i = 0; i < on; i++) ov[i] = ovp[i]; + pcre2_match_data_free(m); + return rc; +} + +void regexp_free(regexp *re) + { pcre2_code_free(re); } + +#else + void regexp_setup(void) { pcre_malloc = xmalloc; @@ -64,6 +121,8 @@ int regexp_match(const regexp *re, const char *s, size_t n, unsigned f, void regexp_free(regexp *re) { pcre_free(re); } +#endif + /* Local Variables: c-basic-offset:2 diff --git a/lib/regexp.h b/lib/regexp.h index ea9bfaf..94c1019 100644 --- a/lib/regexp.h +++ b/lib/regexp.h @@ -21,7 +21,15 @@ #ifndef REGEXP_H #define REGEXP_H -#if defined(HAVE_PCRE_H) +#if defined(HAVE_LIBPCRE2) +# ifndef PCRE2_CODE_UNIT_WIDTH +# define PCRE2_CODE_UNIT_WIDTH 8 +# endif +# include + typedef pcre2_code regexp; +# define RXF_CASELESS PCRE2_CASELESS +# define RXERR_NOMATCH PCRE2_ERROR_NOMATCH +#elif defined(HAVE_PCRE_H) # include typedef pcre regexp; # define RXF_CASELESS PCRE_CASELESS -- [mdw]