-regexp REGEXP matches with an (extended) regular expression\n\
"
#endif
-#ifdef HAVE_PCRE
+#if defined(HAVE_PCRE) || defined(HAVE_PCRE2)
"\
-pcre REGEXP matches with a Perl-like regular expression\n\
"
#ifdef HAVE_REGCOMP
{ "regexp", 1, 0, O_REGEXP },
#endif
-#ifdef HAVE_PCRE
+#if defined(HAVE_PCRE) || defined(HAVE_PCRE2)
{ "pcre", 1, 0, O_PCRE },
#endif
{ "length", 1, 0, O_LENGTH },
#ifdef HAVE_REGCOMP
case O_REGEXP: *nn = regexp(p->a + 1); break;
#endif
-#ifdef HAVE_PCRE
+#if defined(HAVE_PCRE) || defined(HAVE_PCRE2)
case O_PCRE: *nn = pcrenode(p->a + 1); break;
#endif
case O_MONO: *nn = mono(p->a + 1); break;
AM_CONDITIONAL([HAVE_REGCOMP], [test $ac_cv_func_regcomp = yes])
mdw_have_pcre2=nil mdw_have_pcre=nil
-PKG_CHECK_MODULES([PCRE], [libpcre],
- [mdw_have_pcre=t AM_CFLAGS="$AM_CFLAGS $PCRE_CFLAGS"], [])
+PKG_CHECK_MODULES([PCRE2], [libpcre2-8],
+ [mdw_have_pcre2=t AM_CFLAGS="$AM_CFLAGS $PCRE2_CFLAGS"],
+ [PKG_CHECK_MODULES([PCRE], [libpcre],
+ [mdw_have_pcre=t AM_CFLAGS="$AM_CFLAGS $PCRE_CFLAGS"], [])])
+AM_CONDITIONAL([HAVE_PCRE2], [test $mdw_have_pcre2 = t])
+case $mdw_have_pcre2 in
+ t) AC_DEFINE([HAVE_PCRE2], [1], [PCRE2 library is available.]) ;;
+esac
AM_CONDITIONAL([HAVE_PCRE], [test $mdw_have_pcre = t])
case $mdw_have_pcre in
t) AC_DEFINE([HAVE_PCRE], [1], [PCRE library is available.]) ;;
#include "anag.h"
-#include <pcre.h>
+#ifdef HAVE_PCRE2
+# define PCRE2_CODE_UNIT_WIDTH 8
+# include <pcre2.h>
+#endif
+
+#ifdef HAVE_PCRE
+# include <pcre.h>
+#endif
/*----- Data structures ---------------------------------------------------*/
typedef struct node_pcre {
node n;
const char *s;
+#ifdef HAVE_PCRE2
+ pcre2_code *rx;
+ pcre2_match_data *m;
+#endif
+#ifdef HAVE_PCRE
pcre *rx;
pcre_extra *rx_study;
int *ovec;
int ovecsz;
+#endif
} node_pcre;
/*----- Main code ---------------------------------------------------------*/
static int n_pcre(node *nn, const char *p, size_t sz)
{
node_pcre *n = (node_pcre *)nn;
+#ifdef HAVE_PCRE2
+ char buf[128];
+ int rc;
+#endif
+#ifdef HAVE_PCRE
int e;
-
+#endif
+
+#ifdef HAVE_PCRE2
+ rc = pcre2_match(n->rx, (PCRE2_SPTR)p, sz, 0, 0, n->m, 0);
+ if (rc >= 0) return (1);
+ else switch (rc) {
+ case PCRE2_ERROR_NOMATCH: return (0);
+ default:
+ rc = pcre2_get_error_message(rc, (PCRE2_UCHAR *)buf, sizeof(buf));
+ assert(!rc); die("pcre2 matching failed': %s", buf);
+ }
+#endif
+#ifdef HAVE_PCRE
e = pcre_exec(n->rx, n->rx_study, p, sz, 0, 0, n->ovec, n->ovecsz);
if (e >= 0) return (1);
if (e == PCRE_ERROR_NOMATCH) return (0);
die("unexpected PCRE error code %d", e);
+#endif
}
/* --- Node creation --- */
node *pcrenode(const char *const *av)
{
node_pcre *n = xmalloc(sizeof(*n));
+#ifdef HAVE_PCRE2
+ char buf[128];
+ int err;
+ PCRE2_SIZE eo;
+ uint32_t c;
+#endif
+#ifdef HAVE_PCRE
const char *e;
int eo;
int c;
+#endif
n->n.func = n_pcre;
+#ifdef HAVE_PCRE2
+ n->rx = pcre2_compile((PCRE2_SPTR)av[0], strlen(av[0]), PCRE2_CASELESS,
+ &err, &eo, 0);
+ if (!n->rx) {
+ err = pcre2_get_error_message(err, (PCRE2_UCHAR *)buf, sizeof(buf));
+ assert(!err); die("bad regular expression `%s': %s", av[0], buf);
+ }
+ err = pcre2_pattern_info(n->rx, PCRE2_INFO_BACKREFMAX, &c);
+ assert(!err);
+ n->m = pcre2_match_data_create_from_pattern(n->rx, 0);
+ if (!n->m) {
+ err = pcre2_get_error_message(err, (PCRE2_UCHAR *)buf, sizeof(buf));
+ assert(!err); die("failed to allocate match data: %s", buf);
+ }
+ pcre2_jit_compile(n->rx, PCRE2_JIT_COMPLETE);
+#endif
+#ifdef HAVE_PCRE
n->rx = pcre_compile(av[0], PCRE_CASELESS, &e, &eo, 0);
if (!n->rx) die("bad regular expression `%s': %s", av[0], e);
n->rx_study = pcre_study(n->rx, 0, &e);
pcre_fullinfo(n->rx, n->rx_study, PCRE_INFO_CAPTURECOUNT, &c);
n->ovecsz = 2*c;
n->ovec = xmalloc(n->ovecsz*sizeof(*n->ovec));
+#endif
return (&n->n);
}