chiark / gitweb /
configure.ac, acinclude.m4, lib/regexp.[ch]: Support `libpcre2'.
authorMark Wooding <mdw@distorted.org.uk>
Wed, 29 Nov 2017 11:37:56 +0000 (11:37 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Wed, 29 Nov 2017 11:50:12 +0000 (11:50 +0000)
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
acinclude.m4
configure.ac
debian/control
lib/regexp.c
lib/regexp.h

diff --git a/README b/README
index 3e917a9..1be8298 100644 (file)
--- 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
index 5ab8672..287c256 100644 (file)
@@ -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 <pcre2.h>
+                    #include <stdio.h>
+                  ],
+                  [
+                    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],
index 9a6bf70..306b338 100644 (file)
@@ -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
index d4a9f0f..d1f9426 100644 (file)
@@ -3,7 +3,7 @@ Maintainer: Richard Kettlewell <rjk@greenend.org.uk>
 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/
 
index cb5ecc6..5199339 100644 (file)
 #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
index ea9bfaf..94c1019 100644 (file)
 #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 <pcre2.h>
+  typedef pcre2_code regexp;
+# define RXF_CASELESS PCRE2_CASELESS
+# define RXERR_NOMATCH PCRE2_ERROR_NOMATCH
+#elif defined(HAVE_PCRE_H)
 # include <pcre.h>
   typedef pcre regexp;
 # define RXF_CASELESS PCRE_CASELESS