Control: tags -1 + patch

Please find a patch attached.  Tested with the examples only.  Also
tested discogrok with

$ discogrok --verbose --patterns /usr/share/grok/patterns/base

It hangs at this line:

[855838]   [capture] [grok_capture_add:28] Adding pattern 'YEAR' as capture 0 
(pcrenum 1)

But so does unpatched discogrok from sid.

Note that this patch breaks the libgrok ABI since the library exposes
the PCRE API.  As libgrok does not have any reverse dependencies in
Debian (even grok itself doesn't link with it), the second patch
simply removes it.  Alternatively, if you wish to retain it, you'd
have to bump the SONAME (using a Debian-specific one, perhaps) and the
package has to pass through NEW.  IMHO that's too much trouble for an
unused library, but of course it's up to you as maintainer.
>From 8f984ea80430f973d13a67f87b884d4dd3f7383e Mon Sep 17 00:00:00 2001
From: Yavor Doganov <ya...@gnu.org>
Date: Sat, 9 Dec 2023 09:02:57 +0200
Subject: [PATCH 1/2] Port to PCRE2 (#1000065)

---
 Makefile                      |   2 +-
 debian/control                |   2 +-
 debian/patches/debian-changes | 556 +++++++++++++++++++++++++++++++++-
 grok.c                        |  55 ++--
 grok.h                        |  25 +-
 grok_discover.c               |   2 +-
 grokre.c                      | 100 +++---
 predicates.c                  |  38 ++-
 predicates.h                  |   1 -
 9 files changed, 686 insertions(+), 95 deletions(-)

diff --git a/Makefile b/Makefile
index 564a8c3..fcbf843 100644
--- a/Makefile
+++ b/Makefile
@@ -42,7 +42,7 @@ VERSION=$(shell sh $(BASE)/version.sh)
 #LDFLAGS+=-g
 
 CFLAGS+=-pipe -fPIC -I. -O2
-LDFLAGS+=-lpcre -levent -rdynamic -ltokyocabinet
+LDFLAGS+=-lpcre2-8 -levent -rdynamic -ltokyocabinet
 
 LIBSUFFIX=$(shell sh $(BASE)/platform.sh libsuffix)
 VERLIBSUFFIX=$(shell sh $(BASE)/platform.sh libsuffix $(MAJOR))
diff --git a/debian/control b/debian/control
index b9f6cad..dd9afb1 100644
--- a/debian/control
+++ b/debian/control
@@ -10,7 +10,7 @@ Build-Depends:
  gperf,
  help2man,
  libevent-dev,
- libpcre3-dev,
+ libpcre2-dev,
  libtirpc-dev,
  libtokyocabinet-dev,
 Standards-Version: 3.9.3
diff --git a/debian/patches/debian-changes b/debian/patches/debian-changes
index 8718175..f1563fc 100644
--- a/debian/patches/debian-changes
+++ b/debian/patches/debian-changes
@@ -17,6 +17,15 @@ A single combined diff, containing all the changes, follows.
 
 --- grok-1.20110708.1.orig/Makefile
 +++ grok-1.20110708.1/Makefile
+@@ -42,7 +42,7 @@ VERSION=$(shell sh $(BASE)/version.sh)
+ #LDFLAGS+=-g
+ 
+ CFLAGS+=-pipe -fPIC -I. -O2
+-LDFLAGS+=-lpcre -levent -rdynamic -ltokyocabinet
++LDFLAGS+=-lpcre2-8 -levent -rdynamic -ltokyocabinet
+ 
+ LIBSUFFIX=$(shell sh $(BASE)/platform.sh libsuffix)
+ VERLIBSUFFIX=$(shell sh $(BASE)/platform.sh libsuffix $(MAJOR))
 @@ -162,14 +162,14 @@ cleanver:
  # Binary creation
  grok: LDFLAGS+=-levent
@@ -93,7 +102,12 @@ A single combined diff, containing all the changes, follows.
  
 --- grok-1.20110708.1.orig/grokre.c
 +++ grok-1.20110708.1/grokre.c
-@@ -12,8 +12,8 @@
+@@ -1,4 +1,3 @@
+-#include <pcre.h>
+ #include <assert.h>
+ #include <string.h> 
+ #include <stdlib.h>
+@@ -12,8 +11,8 @@
  
  /* global, static variables */
  
@@ -104,15 +118,268 @@ A single combined diff, containing all the changes, 
follows.
  
  /* internal functions */
  static char *grok_pattern_expand(grok_t *grok); //, int offset, int length);
-@@ -183,7 +183,7 @@ static char *grok_pattern_expand(grok_t
+@@ -24,15 +23,15 @@ static void grok_capture_add_predicate(g
+ 
+ void grok_free_clone(const grok_t *grok) {
+   if (grok->re != NULL) {
+-    pcre_free(grok->re);
++    pcre2_code_free(grok->re);
+   }
+ 
+   if (grok->full_pattern != NULL) {
+     free(grok->full_pattern);
+   }
+ 
+-  if (grok->pcre_capture_vector != NULL) {
+-    free(grok->pcre_capture_vector);
++  if (grok->md != NULL) {
++    pcre2_match_data_free(grok->md);
+   }
+ 
+   if (grok->captures_by_name != NULL) {
+@@ -76,24 +75,28 @@ int grok_compilen(grok_t *grok, const ch
+   grok->full_pattern = grok_pattern_expand(grok);
+ 
+   if (grok->full_pattern == NULL) {
++    const char *errstr;
++
+     grok_log(grok, LOG_COMPILE, "A failure occurred while compiling '%.*s'",
+              length, pattern);
+-    grok->errstr = "failure occurred while expanding pattern "\
+-                   "(too pattern recursion?)";
++    errstr = "failure occurred while expanding pattern "
++             "(too pattern recursion?)";
++    strcpy((char *)grok->errstr, errstr);
+     return GROK_ERROR_COMPILE_FAILED;
+   }
+ 
+-  grok->re = pcre_compile(grok->full_pattern, 0, 
+-                          &grok->pcre_errptr, &grok->pcre_erroffset, NULL);
++  grok->re = pcre2_compile((PCRE2_SPTR)grok->full_pattern,
++                           PCRE2_ZERO_TERMINATED, 0,
++                           &grok->pcre_errno, &grok->pcre_erroffset, NULL);
+ 
+   if (grok->re == NULL) {
+-    grok->errstr = (char *)grok->pcre_errptr;
++    pcre2_get_error_message(grok->pcre_errno, grok->errstr, 
sizeof(grok->errstr));
+     return GROK_ERROR_COMPILE_FAILED;
+   }
+ 
+-  pcre_fullinfo(grok->re, NULL, PCRE_INFO_CAPTURECOUNT, 
&grok->pcre_num_captures);
++  pcre2_pattern_info(grok->re, PCRE2_INFO_CAPTURECOUNT, 
&grok->pcre_num_captures);
+   grok->pcre_num_captures++; /* include the 0th group */
+-  grok->pcre_capture_vector = calloc(3 * grok->pcre_num_captures, 
sizeof(int));
++  grok->md = pcre2_match_data_create(3 * grok->pcre_num_captures, g_gen_ctxt);
+ 
+   /* Walk grok->captures_by_id.
+    * For each, ask grok->re what stringnum it is */
+@@ -103,18 +106,15 @@ int grok_compilen(grok_t *grok, const ch
+ }
+ 
+ const char * const grok_error(grok_t *grok) {
+-  return grok->errstr;
++  return (const char *)grok->errstr;
+ }
+ 
+-int grok_exec(const grok_t *grok, const char *text, grok_match_t *gm) {
++int grok_exec(grok_t *grok, const char *text, grok_match_t *gm) {
+   return grok_execn(grok, text, strlen(text), gm);
+ }
+ 
+-int grok_execn(const grok_t *grok, const char *text, int textlen, 
grok_match_t *gm) {
++int grok_execn(grok_t *grok, const char *text, int textlen, grok_match_t *gm) 
{
+   int ret;
+-  pcre_extra pce;
+-  pce.flags = PCRE_EXTRA_CALLOUT_DATA;
+-  pce.callout_data = (void *)grok;
+ 
+   if (grok->re == NULL) {
+     grok_log(grok, LOG_EXEC, "Error: pcre re is null, meaning you haven't 
called grok_compile yet");
+@@ -122,22 +122,22 @@ int grok_execn(const grok_t *grok, const
+     return GROK_ERROR_UNINITIALIZED;
+   }
+ 
+-  ret = pcre_exec(grok->re, &pce, text, textlen, 0, 0,
+-                  grok->pcre_capture_vector, grok->pcre_num_captures * 3);
++  ret = pcre2_match(grok->re, (PCRE2_SPTR)text, textlen, 0, 0,
++                    grok->md, g_match_ctxt);
+   grok_log(grok, LOG_EXEC, "%.*s =~ /%s/ => %d",
+            textlen, text, grok->pattern, ret);
+   if (ret < 0) {
+     switch (ret) {
+-      case PCRE_ERROR_NOMATCH:
++      case PCRE2_ERROR_NOMATCH:
+         return GROK_ERROR_NOMATCH;
+         break;
+-      case PCRE_ERROR_NULL:
++      case PCRE2_ERROR_NULL:
+         fprintf(stderr, "Null error, one of the arguments was null?\n");
+         break;
+-      case PCRE_ERROR_BADOPTION:
++      case PCRE2_ERROR_BADOPTION:
+         fprintf(stderr, "pcre badoption\n");
+         break;
+-      case PCRE_ERROR_BADMAGIC:
++      case PCRE2_ERROR_BADMAGIC:
+         fprintf(stderr, "pcre badmagic\n");
+         break;
+     }
+@@ -145,6 +145,8 @@ int grok_execn(const grok_t *grok, const
+     return GROK_ERROR_PCRE_ERROR;
+   }
+ 
++  grok->pcre_capture_vector = pcre2_get_ovector_pointer(grok->md);
++
+   /* Push match info into gm only if it is non-NULL */
+   if (gm != NULL) {
+     gm->grok = grok;
+@@ -160,17 +162,18 @@ int grok_execn(const grok_t *grok, const
+ static char *grok_pattern_expand(grok_t *grok) {
+   int capture_id = 0; /* Starting capture_id, doesn't really matter what this 
is */
+   int offset = 0; /* string offset; how far we've expanded so far */
+-  int *capture_vector = NULL;
++  size_t *capture_vector = NULL;
+   int replacement_count = 0; /* count of replacements of %{foo} with a regexp 
*/
+ 
+   int full_len = -1;
+   int full_size = -1;
+   char *full_pattern = NULL;
+   char capture_id_str[CAPTURE_ID_LEN + 1];
++  pcre2_match_data *md;
+ 
+   const char *patname = NULL;
+ 
+-  capture_vector = calloc(3 * g_pattern_num_captures, sizeof(int));
++  md = pcre2_match_data_create(3 * g_pattern_num_captures, g_gen_ctxt);
+   full_len = grok->pattern_len;
+   full_size = full_len;
+   full_pattern = calloc(1, full_size);
+@@ -178,32 +181,37 @@ static char *grok_pattern_expand(grok_t
+   grok_log(grok, LOG_REGEXPAND, "% 20s: %.*s", "start of expand",
+            full_len, full_pattern);
+ 
+-  while (pcre_exec(g_pattern_re, NULL, full_pattern, full_len, offset, 
+-                   0, capture_vector, g_pattern_num_captures * 3) >= 0) {
++  while (pcre2_match(g_pattern_re, (PCRE2_SPTR)full_pattern, full_len, offset,
++                     0, md, g_match_ctxt) >= 0) {
      int start, end, matchlen;
      const char *pattern_regex;
      int patname_len;
 -    size_t regexp_len;
 +    int regexp_len;
      int pattern_regex_needs_free = 0;
++    size_t l;
  
      grok_log(grok, LOG_REGEXPAND, "% 20s: %.*s", "start of loop",
+              full_len, full_pattern);
+ 
+     replacement_count++;
+     if (replacement_count > 500) {
+-      free(capture_vector);
++      const char *errstr;
++
++      pcre2_match_data_free(md);
+       free(full_pattern);
+-      grok->errstr = "Too many replacements have occurred (500), infinite 
recursion?";
++      errstr = "Too many replacements have occurred (500), infinite 
recursion?";
++      strcpy((char *)grok->errstr, errstr);
+       return NULL;
+     }
+ 
++    capture_vector = pcre2_get_ovector_pointer(md);
+     start = capture_vector[0];
+     end = capture_vector[1];
+     matchlen = end - start;
+     grok_log(grok, LOG_REGEXPAND, "Pattern length: %d", matchlen);
+ 
+-    pcre_get_substring(full_pattern, capture_vector, g_pattern_num_captures,
+-                       g_cap_pattern, &patname);
++    pcre2_substring_get_bynumber(md, g_cap_pattern,
++                                 (PCRE2_UCHAR **)&patname, &l);
+     patname_len = capture_vector[g_cap_pattern * 2 + 1] \
+                   - capture_vector[g_cap_pattern * 2];
+     grok_log(grok, LOG_REGEXPAND, "Pattern name: %.*s", patname_len, patname);
+@@ -232,17 +240,17 @@ static char *grok_pattern_expand(grok_t
+     /* Check for nullness again because there could've been an inline
+      * definition found above */
+     if (pattern_regex != NULL) {
+-      int has_predicate = (capture_vector[g_cap_predicate * 2] >= 0);
++      int has_predicate = ((int)capture_vector[g_cap_predicate * 2] >= 0);
+       const char *longname = NULL;
+       const char *subname = NULL;
+       grok_capture *gct = calloc(1, sizeof(grok_capture));;
+ 
+       /* XXX: Change this to not use pcre_get_substring so we can skip a
+        * malloc step? */
+-      pcre_get_substring(full_pattern, capture_vector, g_pattern_num_captures,
+-                         g_cap_name, &longname);
+-      pcre_get_substring(full_pattern, capture_vector, g_pattern_num_captures,
+-                         g_cap_subname, &subname);
++      pcre2_substring_get_bynumber(md, g_cap_name,
++                                   (PCRE2_UCHAR **)&longname, &l);
++      pcre2_substring_get_bynumber(md, g_cap_subname,
++                                   (PCRE2_UCHAR **)&subname, &l);
+ 
+       snprintf(capture_id_str, CAPTURE_ID_LEN + 1, CAPTURE_FORMAT, 
capture_id);
+ 
+@@ -250,6 +258,8 @@ static char *grok_pattern_expand(grok_t
+       gct->id = capture_id;
+       gct->name = (char *)longname; /* XXX: CONST PROBLEM */
+       gct->name_len = strlen(gct->name);
++      if (!subname)
++        subname = "";
+       gct->subname = (char *)subname;
+       gct->subname_len = strlen(gct->subname);
+       grok_capture_add(grok, gct);
+@@ -312,7 +322,7 @@ static char *grok_pattern_expand(grok_t
+       free(pattern_regex);
+     }
+     if (patname != NULL) {
+-      pcre_free_substring(patname);
++      pcre2_substring_free((PCRE2_UCHAR *)patname);
+       patname = NULL;
+     }
+   } /* while pcre_exec */
+@@ -329,7 +339,7 @@ static char *grok_pattern_expand(grok_t
+ 
+   grok_log(grok, LOG_REGEXPAND, "Fully expanded: %.*s", full_len, 
full_pattern);
+ 
+-  free(capture_vector);
++  pcre2_match_data_free(md);
+   grok->full_pattern_len = full_len;
+   grok->full_pattern = full_pattern;
+   return full_pattern;
+@@ -387,23 +397,23 @@ static void grok_capture_add_predicate(g
+ }
+ 
+ static void grok_study_capture_map(grok_t *grok) {
+-  char *nametable;
++  PCRE2_SPTR nametable;
+   grok_capture *gct;
+-  int nametable_size;
+-  int nametable_entrysize;
++  uint32_t nametable_size;
++  uint32_t nametable_entrysize;
+   int i = 0;
+   int offset = 0;
+   int stringnum;
+   int capture_id;
+ 
+-  pcre_fullinfo(grok->re, NULL, PCRE_INFO_NAMECOUNT, &nametable_size);
+-  pcre_fullinfo(grok->re, NULL, PCRE_INFO_NAMEENTRYSIZE, 
&nametable_entrysize);
+-  pcre_fullinfo(grok->re, NULL, PCRE_INFO_NAMETABLE, &nametable);
++  pcre2_pattern_info(grok->re, PCRE2_INFO_NAMECOUNT, &nametable_size);
++  pcre2_pattern_info(grok->re, PCRE2_INFO_NAMEENTRYSIZE, 
&nametable_entrysize);
++  pcre2_pattern_info(grok->re, PCRE2_INFO_NAMETABLE, &nametable);
+ 
+   for (i = 0; i < nametable_size; i++) {
+     offset = i * nametable_entrysize;
+     stringnum = (nametable[offset] << 8) + nametable[offset + 1];
+-    sscanf(nametable + offset + 2, CAPTURE_FORMAT, &capture_id);
++    sscanf((const char *)nametable + offset + 2, CAPTURE_FORMAT, &capture_id);
+     grok_log(grok, LOG_COMPILE, "Studying capture %d", capture_id);
+     gct = (grok_capture *)grok_capture_get_by_id(grok, capture_id);
+     assert(gct != NULL);
 --- grok-1.20110708.1.orig/test/grok_pattern.test.c
 +++ grok-1.20110708.1/test/grok_pattern.test.c
 @@ -4,7 +4,7 @@
@@ -124,3 +391,288 @@ A single combined diff, containing all the changes, 
follows.
  
    grok_pattern_add(&grok, "WORD", 5, "\\w+", 3);
    grok_pattern_add(&grok, "TEST", 5, "TEST", 4);
+--- grok-1.20110708.1.orig/grok.c
++++ grok-1.20110708.1/grok.c
+@@ -1,11 +1,13 @@
+ #include "grok.h"
+ #include <dlfcn.h>
+ 
+-static int grok_pcre_callout(pcre_callout_block *pcb);
++static int grok_pcre_callout(pcre2_callout_block *pcb, void *data);
+ 
+ int g_grok_global_initialized = 0;
+-pcre *g_pattern_re = NULL;
+-int g_pattern_num_captures = 0;
++pcre2_code *g_pattern_re = NULL;
++pcre2_general_context *g_gen_ctxt;
++pcre2_match_context *g_match_ctxt;
++uint32_t g_pattern_num_captures = 0;
+ int g_cap_name = 0;
+ int g_cap_pattern = 0;
+ int g_cap_subname = 0;
+@@ -22,7 +24,9 @@ grok_t *grok_new() {
+ void grok_init(grok_t *grok) {
+   //int ret;
+   /* set global pcre_callout for libpcre */
+-  pcre_callout = grok_pcre_callout;
++  g_gen_ctxt = pcre2_general_context_create(NULL, NULL, NULL);
++  g_match_ctxt = pcre2_match_context_create(g_gen_ctxt);
++  pcre2_set_callout(g_match_ctxt, grok_pcre_callout, grok);
+ 
+   grok->re = NULL;
+   grok->pattern = NULL;
+@@ -30,7 +34,7 @@ void grok_init(grok_t *grok) {
+   grok->pcre_capture_vector = NULL;
+   grok->pcre_num_captures = 0;
+   grok->max_capture_num = 0;
+-  grok->pcre_errptr = NULL;
++  grok->pcre_errno = 0;
+   grok->pcre_erroffset = 0;
+   grok->logmask = 0;
+   grok->logdepth = 0;
+@@ -52,24 +56,33 @@ void grok_init(grok_t *grok) {
+ 
+     /* VALGRIND NOTE: Valgrind complains here, but this is a global variable.
+      * Ignore valgrind here. */
+-    g_pattern_re = pcre_compile(PATTERN_REGEX, 0,
+-                                &grok->pcre_errptr,
+-                                &grok->pcre_erroffset,
+-                                NULL);
++    g_pattern_re = pcre2_compile((PCRE2_SPTR)PATTERN_REGEX,
++                                 PCRE2_ZERO_TERMINATED, 0,
++                                 &grok->pcre_errno,
++                                 &grok->pcre_erroffset,
++                                 NULL);
+     if (g_pattern_re == NULL) {
+-      fprintf(stderr, "Internal compiler error: %s\n", grok->pcre_errptr);
++      PCRE2_UCHAR buf[120];
++
++      pcre2_get_error_message(grok->pcre_errno, buf, sizeof(buf));
++      fprintf(stderr, "Internal compiler error: %s\n", buf);
+       fprintf(stderr, "Regexp: %s\n", PATTERN_REGEX);
+-      fprintf(stderr, "Position: %d\n", grok->pcre_erroffset);
++      fprintf(stderr, "Position: %lu\n", grok->pcre_erroffset);
+     }
+ 
+-    pcre_fullinfo(g_pattern_re, NULL, PCRE_INFO_CAPTURECOUNT,
+-                  &g_pattern_num_captures);
++    pcre2_pattern_info(g_pattern_re, PCRE2_INFO_CAPTURECOUNT,
++                       &g_pattern_num_captures);
+     g_pattern_num_captures++; /* include the 0th group */
+-    g_cap_name = pcre_get_stringnumber(g_pattern_re, "name");
+-    g_cap_pattern = pcre_get_stringnumber(g_pattern_re, "pattern");
+-    g_cap_subname = pcre_get_stringnumber(g_pattern_re, "subname");
+-    g_cap_predicate = pcre_get_stringnumber(g_pattern_re, "predicate");
+-    g_cap_definition = pcre_get_stringnumber(g_pattern_re, "definition");
++    g_cap_name = pcre2_substring_number_from_name(g_pattern_re,
++                                                  (PCRE2_SPTR)"name");
++    g_cap_pattern = pcre2_substring_number_from_name(g_pattern_re,
++                                                     (PCRE2_SPTR)"pattern");
++    g_cap_subname = pcre2_substring_number_from_name(g_pattern_re,
++                                                     (PCRE2_SPTR)"subname");
++    g_cap_predicate = pcre2_substring_number_from_name(g_pattern_re,
++                                                       
(PCRE2_SPTR)"predicate");
++    g_cap_definition = pcre2_substring_number_from_name(g_pattern_re,
++                                                        
(PCRE2_SPTR)"definition");
+   }
+ }
+ 
+@@ -80,8 +93,8 @@ void grok_clone(grok_t *dst, const grok_
+   dst->logdepth = src->logdepth + 1;
+ }
+ 
+-static int grok_pcre_callout(pcre_callout_block *pcb) {
+-  grok_t *grok = pcb->callout_data;
++static int grok_pcre_callout(pcre2_callout_block *pcb, void *data) {
++  grok_t *grok = data;
+   const grok_capture *gct;
+ 
+   gct = (grok_capture *)grok_capture_get_by_capture_number(grok,
+@@ -115,7 +128,7 @@ static int grok_pcre_callout(pcre_callou
+                (lib == NULL ? "grok" : lib), gct->predicate_func_name_len,
+                gct->predicate_func_name);
+       int ret;
+-      ret = predicate(grok, gct, pcb->subject, start, end);
++      ret = predicate(grok, gct, (const char *)pcb->subject, start, end);
+       grok_log(grok, LOG_EXEC, "end pcre_callout func %s/%.*s returned: %d",
+                (lib == NULL ? "grok" : lib), gct->predicate_func_name_len,
+                gct->predicate_func_name, ret);
+--- grok-1.20110708.1.orig/grok.h
++++ grok-1.20110708.1/grok.h
+@@ -4,7 +4,8 @@
+ #ifndef _GROK_H_
+ #define _GROK_H_
+ 
+-#include <pcre.h>
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include <tcutil.h>
+ #include <stdlib.h>
+ #include <stdbool.h>
+@@ -38,9 +39,10 @@ struct grok {
+   /** tokyocabinet TCTREE of patterns */
+   TCTREE *patterns;
+ 
+-  pcre *re;
+-  int *pcre_capture_vector;
+-  int pcre_num_captures;
++  pcre2_code *re;
++  pcre2_match_data *md;
++  size_t *pcre_capture_vector;
++  uint32_t pcre_num_captures;
+   
+   /* Data storage for named-capture (grok capture) information */
+   TCTREE *captures_by_id;
+@@ -50,18 +52,19 @@ struct grok {
+   int max_capture_num;
+   
+   /** PCRE pattern compilation errors */
+-  const char *pcre_errptr;
+-  int pcre_erroffset;
++  size_t pcre_erroffset;
+   int pcre_errno;
+ 
+   unsigned int logmask;
+   unsigned int logdepth;
+-  char *errstr;
++  PCRE2_UCHAR errstr[120];
+ };
+ 
+ extern int g_grok_global_initialized;
+-extern pcre *g_pattern_re;
+-extern int g_pattern_num_captures;
++extern pcre2_code *g_pattern_re;
++extern pcre2_general_context *g_gen_ctxt;
++extern pcre2_match_context *g_match_ctxt;
++extern uint32_t g_pattern_num_captures;
+ extern int g_cap_name;
+ extern int g_cap_pattern;
+ extern int g_cap_subname;
+@@ -232,12 +235,12 @@ int grok_compilen(grok_t *grok, const ch
+  * @param gm The grok_match_t to store match result in.  If NULL, no storing 
is attempted.
+  * @returns GROK_OK if match successful, GROK_ERROR_NOMATCH if no match.
+  */
+-int grok_exec(const grok_t *grok, const char *text, grok_match_t *gm);
++int grok_exec(grok_t *grok, const char *text, grok_match_t *gm);
+ 
+ /**
+  * @see grok_exec
+  * */
+-int grok_execn(const grok_t *grok, const char *text, int textlen, 
grok_match_t *gm);
++int grok_execn(grok_t *grok, const char *text, int textlen, grok_match_t *gm);
+ 
+ int grok_match_get_named_substring(const grok_match_t *gm, const char *name,
+                                    const char **substr, int *len);
+--- grok-1.20110708.1.orig/grok_discover.c
++++ grok-1.20110708.1/grok_discover.c
+@@ -136,7 +136,7 @@ void grok_discover(const grok_discover_t
+       const int *complexity = (const int *)key;
+       int val_len;
+       const grok_t *g = tctreeget(gdt->complexity_tree, key, sizeof(int), 
&val_len);
+-      match = grok_exec(g, cursor, &gm);
++      match = grok_exec((grok_t *)g, cursor, &gm);
+       grok_log(gdt, LOG_DISCOVER, "Test %s against %.*s",
+                (match == GROK_OK ? "succeeded" : "failed"), g->pattern_len, 
g->pattern);
+ 
+--- grok-1.20110708.1.orig/predicates.c
++++ grok-1.20110708.1/predicates.c
+@@ -5,7 +5,7 @@
+ #include "grok_logging.h"
+ #include "predicates.h"
+ 
+-static pcre *regexp_predicate_op = NULL;
++static pcre2_code *regexp_predicate_op = NULL;
+ #define REGEXP_PREDICATE_RE \
+   "(?:\\s*([!=])~" \
+   "\\s*" \
+@@ -68,13 +68,17 @@ int grok_predicate_strcompare(grok_t *gr
+ 
+ static void grok_predicate_regexp_global_init(void) {
+   if (regexp_predicate_op == NULL) {
+-    int erroffset = -1;
+-    const char *errp;
+-    regexp_predicate_op = pcre_compile(REGEXP_PREDICATE_RE, 0, 
+-                                       &errp, &erroffset, NULL);
++    size_t erroffset;
++    int errp;
++    regexp_predicate_op = pcre2_compile((PCRE2_SPTR)REGEXP_PREDICATE_RE,
++                                        PCRE2_ZERO_TERMINATED, 0,
++                                        &errp, &erroffset, NULL);
+     if (regexp_predicate_op == NULL) {
++      PCRE2_UCHAR buf[120];
++
++      pcre2_get_error_message(errp, buf, sizeof(buf));
+       fprintf(stderr, "Internal error (compiling predicate regexp op): %s\n",
+-              errp);
++              buf);
+     }
+   }
+ }
+@@ -82,23 +86,27 @@ static void grok_predicate_regexp_global
+ int grok_predicate_regexp_init(grok_t *grok, grok_capture *gct,
+                                const char *args, int args_len) {
+   #define REGEXP_OVEC_SIZE 6
+-  int capture_vector[REGEXP_OVEC_SIZE * 3];
++  size_t *capture_vector;
+   int ret; 
++  pcre2_match_data *md;
+ 
+   grok_log(grok, LOG_PREDICATE, "Regexp predicate found: '%.*s'", args_len, 
args);
+ 
+   grok_predicate_regexp_global_init();
+-  ret = pcre_exec(regexp_predicate_op, NULL, args, args_len, 0, 0,
+-                  capture_vector, REGEXP_OVEC_SIZE * 3);
++  md = pcre2_match_data_create(REGEXP_OVEC_SIZE * 3, g_gen_ctxt);
++  ret = pcre2_match(regexp_predicate_op, (PCRE2_SPTR)args, args_len, 0, 0,
++                    md, g_match_ctxt);
+   if (ret < 0) {
+     fprintf(stderr, "An error occurred in grok_predicate_regexp_init.\n");
+     fprintf(stderr, "Args: %.*s\n", args_len, args);
+-    fprintf(stderr, "pcre_exec:: %d\n", ret);
++    fprintf(stderr, "pcre2_match:: %d\n", ret);
++    pcre2_match_data_free(md);
+     return 1;
+   }
+ 
+   int start, end;
+   grok_predicate_regexp_t *gprt;
++  capture_vector = pcre2_get_ovector_pointer(md);
+   start = capture_vector[6]; /* capture #3 */
+   end = capture_vector[7];
+ 
+@@ -114,10 +122,14 @@ int grok_predicate_regexp_init(grok_t *g
+   gprt->negative_match = (args[capture_vector[2]] == '!');
+ 
+   if (ret != 0) {
++    PCRE2_UCHAR buf[120];
++
++    pcre2_get_error_message(grok->pcre_errno, buf, sizeof(buf));
+     fprintf(stderr, "An error occurred while compiling the predicate for 
%s:\n",
+             gct->name);
+-    fprintf(stderr, "Error at pos %d: %s\n",
+-            grok->pcre_erroffset, grok->pcre_errptr);
++    fprintf(stderr, "Error at pos %lu: %s\n",
++            grok->pcre_erroffset, buf);
++    pcre2_match_data_free(md);
+     return 1;
+   }
+ 
+@@ -135,6 +147,8 @@ int grok_predicate_regexp_init(grok_t *g
+   grok_capture_set_extra(grok, gct, gprt);
+   grok_capture_add(grok, gct);
+ 
++  pcre2_match_data_free(md);
++
+   return 0;
+ }
+ 
+--- grok-1.20110708.1.orig/predicates.h
++++ grok-1.20110708.1/predicates.h
+@@ -1,7 +1,6 @@
+ #ifndef _PREDICATES_H_
+ #define _PREDICATES_H_
+ 
+-#include <pcre.h>
+ #include "grok.h"
+ 
+ /* Regular Expression Predicate
diff --git a/grok.c b/grok.c
index c6e28a4..f203812 100644
--- a/grok.c
+++ b/grok.c
@@ -1,11 +1,13 @@
 #include "grok.h"
 #include <dlfcn.h>
 
-static int grok_pcre_callout(pcre_callout_block *pcb);
+static int grok_pcre_callout(pcre2_callout_block *pcb, void *data);
 
 int g_grok_global_initialized = 0;
-pcre *g_pattern_re = NULL;
-int g_pattern_num_captures = 0;
+pcre2_code *g_pattern_re = NULL;
+pcre2_general_context *g_gen_ctxt;
+pcre2_match_context *g_match_ctxt;
+uint32_t g_pattern_num_captures = 0;
 int g_cap_name = 0;
 int g_cap_pattern = 0;
 int g_cap_subname = 0;
@@ -22,7 +24,9 @@ grok_t *grok_new() {
 void grok_init(grok_t *grok) {
   //int ret;
   /* set global pcre_callout for libpcre */
-  pcre_callout = grok_pcre_callout;
+  g_gen_ctxt = pcre2_general_context_create(NULL, NULL, NULL);
+  g_match_ctxt = pcre2_match_context_create(g_gen_ctxt);
+  pcre2_set_callout(g_match_ctxt, grok_pcre_callout, grok);
 
   grok->re = NULL;
   grok->pattern = NULL;
@@ -30,7 +34,7 @@ void grok_init(grok_t *grok) {
   grok->pcre_capture_vector = NULL;
   grok->pcre_num_captures = 0;
   grok->max_capture_num = 0;
-  grok->pcre_errptr = NULL;
+  grok->pcre_errno = 0;
   grok->pcre_erroffset = 0;
   grok->logmask = 0;
   grok->logdepth = 0;
@@ -52,24 +56,33 @@ void grok_init(grok_t *grok) {
 
     /* VALGRIND NOTE: Valgrind complains here, but this is a global variable.
      * Ignore valgrind here. */
-    g_pattern_re = pcre_compile(PATTERN_REGEX, 0,
-                                &grok->pcre_errptr,
-                                &grok->pcre_erroffset,
-                                NULL);
+    g_pattern_re = pcre2_compile((PCRE2_SPTR)PATTERN_REGEX,
+                                 PCRE2_ZERO_TERMINATED, 0,
+                                 &grok->pcre_errno,
+                                 &grok->pcre_erroffset,
+                                 NULL);
     if (g_pattern_re == NULL) {
-      fprintf(stderr, "Internal compiler error: %s\n", grok->pcre_errptr);
+      PCRE2_UCHAR buf[120];
+
+      pcre2_get_error_message(grok->pcre_errno, buf, sizeof(buf));
+      fprintf(stderr, "Internal compiler error: %s\n", buf);
       fprintf(stderr, "Regexp: %s\n", PATTERN_REGEX);
-      fprintf(stderr, "Position: %d\n", grok->pcre_erroffset);
+      fprintf(stderr, "Position: %lu\n", grok->pcre_erroffset);
     }
 
-    pcre_fullinfo(g_pattern_re, NULL, PCRE_INFO_CAPTURECOUNT,
-                  &g_pattern_num_captures);
+    pcre2_pattern_info(g_pattern_re, PCRE2_INFO_CAPTURECOUNT,
+                       &g_pattern_num_captures);
     g_pattern_num_captures++; /* include the 0th group */
-    g_cap_name = pcre_get_stringnumber(g_pattern_re, "name");
-    g_cap_pattern = pcre_get_stringnumber(g_pattern_re, "pattern");
-    g_cap_subname = pcre_get_stringnumber(g_pattern_re, "subname");
-    g_cap_predicate = pcre_get_stringnumber(g_pattern_re, "predicate");
-    g_cap_definition = pcre_get_stringnumber(g_pattern_re, "definition");
+    g_cap_name = pcre2_substring_number_from_name(g_pattern_re,
+                                                  (PCRE2_SPTR)"name");
+    g_cap_pattern = pcre2_substring_number_from_name(g_pattern_re,
+                                                     (PCRE2_SPTR)"pattern");
+    g_cap_subname = pcre2_substring_number_from_name(g_pattern_re,
+                                                     (PCRE2_SPTR)"subname");
+    g_cap_predicate = pcre2_substring_number_from_name(g_pattern_re,
+                                                       
(PCRE2_SPTR)"predicate");
+    g_cap_definition = pcre2_substring_number_from_name(g_pattern_re,
+                                                        
(PCRE2_SPTR)"definition");
   }
 }
 
@@ -80,8 +93,8 @@ void grok_clone(grok_t *dst, const grok_t *src) {
   dst->logdepth = src->logdepth + 1;
 }
 
-static int grok_pcre_callout(pcre_callout_block *pcb) {
-  grok_t *grok = pcb->callout_data;
+static int grok_pcre_callout(pcre2_callout_block *pcb, void *data) {
+  grok_t *grok = data;
   const grok_capture *gct;
 
   gct = (grok_capture *)grok_capture_get_by_capture_number(grok,
@@ -115,7 +128,7 @@ static int grok_pcre_callout(pcre_callout_block *pcb) {
                (lib == NULL ? "grok" : lib), gct->predicate_func_name_len,
                gct->predicate_func_name);
       int ret;
-      ret = predicate(grok, gct, pcb->subject, start, end);
+      ret = predicate(grok, gct, (const char *)pcb->subject, start, end);
       grok_log(grok, LOG_EXEC, "end pcre_callout func %s/%.*s returned: %d",
                (lib == NULL ? "grok" : lib), gct->predicate_func_name_len,
                gct->predicate_func_name, ret);
diff --git a/grok.h b/grok.h
index 509bfae..2782028 100644
--- a/grok.h
+++ b/grok.h
@@ -4,7 +4,8 @@
 #ifndef _GROK_H_
 #define _GROK_H_
 
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 #include <tcutil.h>
 #include <stdlib.h>
 #include <stdbool.h>
@@ -38,9 +39,10 @@ struct grok {
   /** tokyocabinet TCTREE of patterns */
   TCTREE *patterns;
 
-  pcre *re;
-  int *pcre_capture_vector;
-  int pcre_num_captures;
+  pcre2_code *re;
+  pcre2_match_data *md;
+  size_t *pcre_capture_vector;
+  uint32_t pcre_num_captures;
   
   /* Data storage for named-capture (grok capture) information */
   TCTREE *captures_by_id;
@@ -50,18 +52,19 @@ struct grok {
   int max_capture_num;
   
   /** PCRE pattern compilation errors */
-  const char *pcre_errptr;
-  int pcre_erroffset;
+  size_t pcre_erroffset;
   int pcre_errno;
 
   unsigned int logmask;
   unsigned int logdepth;
-  char *errstr;
+  PCRE2_UCHAR errstr[120];
 };
 
 extern int g_grok_global_initialized;
-extern pcre *g_pattern_re;
-extern int g_pattern_num_captures;
+extern pcre2_code *g_pattern_re;
+extern pcre2_general_context *g_gen_ctxt;
+extern pcre2_match_context *g_match_ctxt;
+extern uint32_t g_pattern_num_captures;
 extern int g_cap_name;
 extern int g_cap_pattern;
 extern int g_cap_subname;
@@ -232,12 +235,12 @@ int grok_compilen(grok_t *grok, const char *pattern, int 
length);
  * @param gm The grok_match_t to store match result in.  If NULL, no storing 
is attempted.
  * @returns GROK_OK if match successful, GROK_ERROR_NOMATCH if no match.
  */
-int grok_exec(const grok_t *grok, const char *text, grok_match_t *gm);
+int grok_exec(grok_t *grok, const char *text, grok_match_t *gm);
 
 /**
  * @see grok_exec
  * */
-int grok_execn(const grok_t *grok, const char *text, int textlen, grok_match_t 
*gm);
+int grok_execn(grok_t *grok, const char *text, int textlen, grok_match_t *gm);
 
 int grok_match_get_named_substring(const grok_match_t *gm, const char *name,
                                    const char **substr, int *len);
diff --git a/grok_discover.c b/grok_discover.c
index 722852e..e24a6ba 100644
--- a/grok_discover.c
+++ b/grok_discover.c
@@ -136,7 +136,7 @@ void grok_discover(const grok_discover_t *gdt, /*grok_t 
*dest_grok, */
       const int *complexity = (const int *)key;
       int val_len;
       const grok_t *g = tctreeget(gdt->complexity_tree, key, sizeof(int), 
&val_len);
-      match = grok_exec(g, cursor, &gm);
+      match = grok_exec((grok_t *)g, cursor, &gm);
       grok_log(gdt, LOG_DISCOVER, "Test %s against %.*s",
                (match == GROK_OK ? "succeeded" : "failed"), g->pattern_len, 
g->pattern);
 
diff --git a/grokre.c b/grokre.c
index 5704fd6..26d18c0 100644
--- a/grokre.c
+++ b/grokre.c
@@ -1,4 +1,3 @@
-#include <pcre.h>
 #include <assert.h>
 #include <string.h> 
 #include <stdlib.h>
@@ -24,15 +23,15 @@ static void grok_capture_add_predicate(grok_t *grok, int 
capture_id,
 
 void grok_free_clone(const grok_t *grok) {
   if (grok->re != NULL) {
-    pcre_free(grok->re);
+    pcre2_code_free(grok->re);
   }
 
   if (grok->full_pattern != NULL) {
     free(grok->full_pattern);
   }
 
-  if (grok->pcre_capture_vector != NULL) {
-    free(grok->pcre_capture_vector);
+  if (grok->md != NULL) {
+    pcre2_match_data_free(grok->md);
   }
 
   if (grok->captures_by_name != NULL) {
@@ -76,24 +75,28 @@ int grok_compilen(grok_t *grok, const char *pattern, int 
length) {
   grok->full_pattern = grok_pattern_expand(grok);
 
   if (grok->full_pattern == NULL) {
+    const char *errstr;
+
     grok_log(grok, LOG_COMPILE, "A failure occurred while compiling '%.*s'",
              length, pattern);
-    grok->errstr = "failure occurred while expanding pattern "\
-                   "(too pattern recursion?)";
+    errstr = "failure occurred while expanding pattern "
+             "(too pattern recursion?)";
+    strcpy((char *)grok->errstr, errstr);
     return GROK_ERROR_COMPILE_FAILED;
   }
 
-  grok->re = pcre_compile(grok->full_pattern, 0, 
-                          &grok->pcre_errptr, &grok->pcre_erroffset, NULL);
+  grok->re = pcre2_compile((PCRE2_SPTR)grok->full_pattern,
+                           PCRE2_ZERO_TERMINATED, 0,
+                           &grok->pcre_errno, &grok->pcre_erroffset, NULL);
 
   if (grok->re == NULL) {
-    grok->errstr = (char *)grok->pcre_errptr;
+    pcre2_get_error_message(grok->pcre_errno, grok->errstr, 
sizeof(grok->errstr));
     return GROK_ERROR_COMPILE_FAILED;
   }
 
-  pcre_fullinfo(grok->re, NULL, PCRE_INFO_CAPTURECOUNT, 
&grok->pcre_num_captures);
+  pcre2_pattern_info(grok->re, PCRE2_INFO_CAPTURECOUNT, 
&grok->pcre_num_captures);
   grok->pcre_num_captures++; /* include the 0th group */
-  grok->pcre_capture_vector = calloc(3 * grok->pcre_num_captures, sizeof(int));
+  grok->md = pcre2_match_data_create(3 * grok->pcre_num_captures, g_gen_ctxt);
 
   /* Walk grok->captures_by_id.
    * For each, ask grok->re what stringnum it is */
@@ -103,18 +106,15 @@ int grok_compilen(grok_t *grok, const char *pattern, int 
length) {
 }
 
 const char * const grok_error(grok_t *grok) {
-  return grok->errstr;
+  return (const char *)grok->errstr;
 }
 
-int grok_exec(const grok_t *grok, const char *text, grok_match_t *gm) {
+int grok_exec(grok_t *grok, const char *text, grok_match_t *gm) {
   return grok_execn(grok, text, strlen(text), gm);
 }
 
-int grok_execn(const grok_t *grok, const char *text, int textlen, grok_match_t 
*gm) {
+int grok_execn(grok_t *grok, const char *text, int textlen, grok_match_t *gm) {
   int ret;
-  pcre_extra pce;
-  pce.flags = PCRE_EXTRA_CALLOUT_DATA;
-  pce.callout_data = (void *)grok;
 
   if (grok->re == NULL) {
     grok_log(grok, LOG_EXEC, "Error: pcre re is null, meaning you haven't 
called grok_compile yet");
@@ -122,22 +122,22 @@ int grok_execn(const grok_t *grok, const char *text, int 
textlen, grok_match_t *
     return GROK_ERROR_UNINITIALIZED;
   }
 
-  ret = pcre_exec(grok->re, &pce, text, textlen, 0, 0,
-                  grok->pcre_capture_vector, grok->pcre_num_captures * 3);
+  ret = pcre2_match(grok->re, (PCRE2_SPTR)text, textlen, 0, 0,
+                    grok->md, g_match_ctxt);
   grok_log(grok, LOG_EXEC, "%.*s =~ /%s/ => %d",
            textlen, text, grok->pattern, ret);
   if (ret < 0) {
     switch (ret) {
-      case PCRE_ERROR_NOMATCH:
+      case PCRE2_ERROR_NOMATCH:
         return GROK_ERROR_NOMATCH;
         break;
-      case PCRE_ERROR_NULL:
+      case PCRE2_ERROR_NULL:
         fprintf(stderr, "Null error, one of the arguments was null?\n");
         break;
-      case PCRE_ERROR_BADOPTION:
+      case PCRE2_ERROR_BADOPTION:
         fprintf(stderr, "pcre badoption\n");
         break;
-      case PCRE_ERROR_BADMAGIC:
+      case PCRE2_ERROR_BADMAGIC:
         fprintf(stderr, "pcre badmagic\n");
         break;
     }
@@ -145,6 +145,8 @@ int grok_execn(const grok_t *grok, const char *text, int 
textlen, grok_match_t *
     return GROK_ERROR_PCRE_ERROR;
   }
 
+  grok->pcre_capture_vector = pcre2_get_ovector_pointer(grok->md);
+
   /* Push match info into gm only if it is non-NULL */
   if (gm != NULL) {
     gm->grok = grok;
@@ -160,17 +162,18 @@ int grok_execn(const grok_t *grok, const char *text, int 
textlen, grok_match_t *
 static char *grok_pattern_expand(grok_t *grok) {
   int capture_id = 0; /* Starting capture_id, doesn't really matter what this 
is */
   int offset = 0; /* string offset; how far we've expanded so far */
-  int *capture_vector = NULL;
+  size_t *capture_vector = NULL;
   int replacement_count = 0; /* count of replacements of %{foo} with a regexp 
*/
 
   int full_len = -1;
   int full_size = -1;
   char *full_pattern = NULL;
   char capture_id_str[CAPTURE_ID_LEN + 1];
+  pcre2_match_data *md;
 
   const char *patname = NULL;
 
-  capture_vector = calloc(3 * g_pattern_num_captures, sizeof(int));
+  md = pcre2_match_data_create(3 * g_pattern_num_captures, g_gen_ctxt);
   full_len = grok->pattern_len;
   full_size = full_len;
   full_pattern = calloc(1, full_size);
@@ -178,32 +181,37 @@ static char *grok_pattern_expand(grok_t *grok) {
   grok_log(grok, LOG_REGEXPAND, "% 20s: %.*s", "start of expand",
            full_len, full_pattern);
 
-  while (pcre_exec(g_pattern_re, NULL, full_pattern, full_len, offset, 
-                   0, capture_vector, g_pattern_num_captures * 3) >= 0) {
+  while (pcre2_match(g_pattern_re, (PCRE2_SPTR)full_pattern, full_len, offset,
+                     0, md, g_match_ctxt) >= 0) {
     int start, end, matchlen;
     const char *pattern_regex;
     int patname_len;
     int regexp_len;
     int pattern_regex_needs_free = 0;
+    size_t l;
 
     grok_log(grok, LOG_REGEXPAND, "% 20s: %.*s", "start of loop",
              full_len, full_pattern);
 
     replacement_count++;
     if (replacement_count > 500) {
-      free(capture_vector);
+      const char *errstr;
+
+      pcre2_match_data_free(md);
       free(full_pattern);
-      grok->errstr = "Too many replacements have occurred (500), infinite 
recursion?";
+      errstr = "Too many replacements have occurred (500), infinite 
recursion?";
+      strcpy((char *)grok->errstr, errstr);
       return NULL;
     }
 
+    capture_vector = pcre2_get_ovector_pointer(md);
     start = capture_vector[0];
     end = capture_vector[1];
     matchlen = end - start;
     grok_log(grok, LOG_REGEXPAND, "Pattern length: %d", matchlen);
 
-    pcre_get_substring(full_pattern, capture_vector, g_pattern_num_captures,
-                       g_cap_pattern, &patname);
+    pcre2_substring_get_bynumber(md, g_cap_pattern,
+                                 (PCRE2_UCHAR **)&patname, &l);
     patname_len = capture_vector[g_cap_pattern * 2 + 1] \
                   - capture_vector[g_cap_pattern * 2];
     grok_log(grok, LOG_REGEXPAND, "Pattern name: %.*s", patname_len, patname);
@@ -232,17 +240,17 @@ static char *grok_pattern_expand(grok_t *grok) {
     /* Check for nullness again because there could've been an inline
      * definition found above */
     if (pattern_regex != NULL) {
-      int has_predicate = (capture_vector[g_cap_predicate * 2] >= 0);
+      int has_predicate = ((int)capture_vector[g_cap_predicate * 2] >= 0);
       const char *longname = NULL;
       const char *subname = NULL;
       grok_capture *gct = calloc(1, sizeof(grok_capture));;
 
       /* XXX: Change this to not use pcre_get_substring so we can skip a
        * malloc step? */
-      pcre_get_substring(full_pattern, capture_vector, g_pattern_num_captures,
-                         g_cap_name, &longname);
-      pcre_get_substring(full_pattern, capture_vector, g_pattern_num_captures,
-                         g_cap_subname, &subname);
+      pcre2_substring_get_bynumber(md, g_cap_name,
+                                   (PCRE2_UCHAR **)&longname, &l);
+      pcre2_substring_get_bynumber(md, g_cap_subname,
+                                   (PCRE2_UCHAR **)&subname, &l);
 
       snprintf(capture_id_str, CAPTURE_ID_LEN + 1, CAPTURE_FORMAT, capture_id);
 
@@ -250,6 +258,8 @@ static char *grok_pattern_expand(grok_t *grok) {
       gct->id = capture_id;
       gct->name = (char *)longname; /* XXX: CONST PROBLEM */
       gct->name_len = strlen(gct->name);
+      if (!subname)
+        subname = "";
       gct->subname = (char *)subname;
       gct->subname_len = strlen(gct->subname);
       grok_capture_add(grok, gct);
@@ -312,7 +322,7 @@ static char *grok_pattern_expand(grok_t *grok) {
       free(pattern_regex);
     }
     if (patname != NULL) {
-      pcre_free_substring(patname);
+      pcre2_substring_free((PCRE2_UCHAR *)patname);
       patname = NULL;
     }
   } /* while pcre_exec */
@@ -329,7 +339,7 @@ static char *grok_pattern_expand(grok_t *grok) {
 
   grok_log(grok, LOG_REGEXPAND, "Fully expanded: %.*s", full_len, 
full_pattern);
 
-  free(capture_vector);
+  pcre2_match_data_free(md);
   grok->full_pattern_len = full_len;
   grok->full_pattern = full_pattern;
   return full_pattern;
@@ -387,23 +397,23 @@ static void grok_capture_add_predicate(grok_t *grok, int 
capture_id,
 }
 
 static void grok_study_capture_map(grok_t *grok) {
-  char *nametable;
+  PCRE2_SPTR nametable;
   grok_capture *gct;
-  int nametable_size;
-  int nametable_entrysize;
+  uint32_t nametable_size;
+  uint32_t nametable_entrysize;
   int i = 0;
   int offset = 0;
   int stringnum;
   int capture_id;
 
-  pcre_fullinfo(grok->re, NULL, PCRE_INFO_NAMECOUNT, &nametable_size);
-  pcre_fullinfo(grok->re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nametable_entrysize);
-  pcre_fullinfo(grok->re, NULL, PCRE_INFO_NAMETABLE, &nametable);
+  pcre2_pattern_info(grok->re, PCRE2_INFO_NAMECOUNT, &nametable_size);
+  pcre2_pattern_info(grok->re, PCRE2_INFO_NAMEENTRYSIZE, &nametable_entrysize);
+  pcre2_pattern_info(grok->re, PCRE2_INFO_NAMETABLE, &nametable);
 
   for (i = 0; i < nametable_size; i++) {
     offset = i * nametable_entrysize;
     stringnum = (nametable[offset] << 8) + nametable[offset + 1];
-    sscanf(nametable + offset + 2, CAPTURE_FORMAT, &capture_id);
+    sscanf((const char *)nametable + offset + 2, CAPTURE_FORMAT, &capture_id);
     grok_log(grok, LOG_COMPILE, "Studying capture %d", capture_id);
     gct = (grok_capture *)grok_capture_get_by_id(grok, capture_id);
     assert(gct != NULL);
diff --git a/predicates.c b/predicates.c
index 70e4ca8..a0ffa9b 100644
--- a/predicates.c
+++ b/predicates.c
@@ -5,7 +5,7 @@
 #include "grok_logging.h"
 #include "predicates.h"
 
-static pcre *regexp_predicate_op = NULL;
+static pcre2_code *regexp_predicate_op = NULL;
 #define REGEXP_PREDICATE_RE \
   "(?:\\s*([!=])~" \
   "\\s*" \
@@ -68,13 +68,17 @@ int grok_predicate_strcompare(grok_t *grok, const 
grok_capture *gct,
 
 static void grok_predicate_regexp_global_init(void) {
   if (regexp_predicate_op == NULL) {
-    int erroffset = -1;
-    const char *errp;
-    regexp_predicate_op = pcre_compile(REGEXP_PREDICATE_RE, 0, 
-                                       &errp, &erroffset, NULL);
+    size_t erroffset;
+    int errp;
+    regexp_predicate_op = pcre2_compile((PCRE2_SPTR)REGEXP_PREDICATE_RE,
+                                        PCRE2_ZERO_TERMINATED, 0,
+                                        &errp, &erroffset, NULL);
     if (regexp_predicate_op == NULL) {
+      PCRE2_UCHAR buf[120];
+
+      pcre2_get_error_message(errp, buf, sizeof(buf));
       fprintf(stderr, "Internal error (compiling predicate regexp op): %s\n",
-              errp);
+              buf);
     }
   }
 }
@@ -82,23 +86,27 @@ static void grok_predicate_regexp_global_init(void) {
 int grok_predicate_regexp_init(grok_t *grok, grok_capture *gct,
                                const char *args, int args_len) {
   #define REGEXP_OVEC_SIZE 6
-  int capture_vector[REGEXP_OVEC_SIZE * 3];
+  size_t *capture_vector;
   int ret; 
+  pcre2_match_data *md;
 
   grok_log(grok, LOG_PREDICATE, "Regexp predicate found: '%.*s'", args_len, 
args);
 
   grok_predicate_regexp_global_init();
-  ret = pcre_exec(regexp_predicate_op, NULL, args, args_len, 0, 0,
-                  capture_vector, REGEXP_OVEC_SIZE * 3);
+  md = pcre2_match_data_create(REGEXP_OVEC_SIZE * 3, g_gen_ctxt);
+  ret = pcre2_match(regexp_predicate_op, (PCRE2_SPTR)args, args_len, 0, 0,
+                    md, g_match_ctxt);
   if (ret < 0) {
     fprintf(stderr, "An error occurred in grok_predicate_regexp_init.\n");
     fprintf(stderr, "Args: %.*s\n", args_len, args);
-    fprintf(stderr, "pcre_exec:: %d\n", ret);
+    fprintf(stderr, "pcre2_match:: %d\n", ret);
+    pcre2_match_data_free(md);
     return 1;
   }
 
   int start, end;
   grok_predicate_regexp_t *gprt;
+  capture_vector = pcre2_get_ovector_pointer(md);
   start = capture_vector[6]; /* capture #3 */
   end = capture_vector[7];
 
@@ -114,10 +122,14 @@ int grok_predicate_regexp_init(grok_t *grok, grok_capture 
*gct,
   gprt->negative_match = (args[capture_vector[2]] == '!');
 
   if (ret != 0) {
+    PCRE2_UCHAR buf[120];
+
+    pcre2_get_error_message(grok->pcre_errno, buf, sizeof(buf));
     fprintf(stderr, "An error occurred while compiling the predicate for 
%s:\n",
             gct->name);
-    fprintf(stderr, "Error at pos %d: %s\n",
-            grok->pcre_erroffset, grok->pcre_errptr);
+    fprintf(stderr, "Error at pos %lu: %s\n",
+            grok->pcre_erroffset, buf);
+    pcre2_match_data_free(md);
     return 1;
   }
 
@@ -135,6 +147,8 @@ int grok_predicate_regexp_init(grok_t *grok, grok_capture 
*gct,
   grok_capture_set_extra(grok, gct, gprt);
   grok_capture_add(grok, gct);
 
+  pcre2_match_data_free(md);
+
   return 0;
 }
 
diff --git a/predicates.h b/predicates.h
index e8f8fbf..457de69 100644
--- a/predicates.h
+++ b/predicates.h
@@ -1,7 +1,6 @@
 #ifndef _PREDICATES_H_
 #define _PREDICATES_H_
 
-#include <pcre.h>
 #include "grok.h"
 
 /* Regular Expression Predicate
-- 
2.43.0

>From bb646685227f7d7a448229497c5a59d24e945c42 Mon Sep 17 00:00:00 2001
From: Yavor Doganov <ya...@gnu.org>
Date: Sat, 9 Dec 2023 10:04:36 +0200
Subject: [PATCH 2/2] Remove library

---
 Makefile                      | 14 ++----------
 debian/control                | 33 ----------------------------
 debian/grok.install           |  3 ---
 debian/libgrok-dev.install    |  2 --
 debian/libgrok1.install       |  1 -
 debian/patches/debian-changes | 41 +++++++++++++++++++++++++++++++++--
 debian/rules                  |  4 ----
 7 files changed, 41 insertions(+), 57 deletions(-)
 delete mode 100644 debian/grok.install
 delete mode 100644 debian/libgrok-dev.install
 delete mode 100644 debian/libgrok1.install

diff --git a/Makefile b/Makefile
index fcbf843..fd3f257 100644
--- a/Makefile
+++ b/Makefile
@@ -83,23 +83,17 @@ GROKHEADER=grok.h grok_pattern.h grok_capture.h 
grok_capture_xdr.h \
 GROKHEADER+=grok_version.h
 
 .PHONY: all
-all: grok discogrok libgrok.$(LIBSUFFIX) libgrok.$(VERLIBSUFFIX)
+all: grok discogrok
 
 .PHONY: package create-package test-package update-version
 package: 
        $(MAKE) $(MAKEFLAGS) create-package 
        $(MAKE) $(MAKEFLAGS) test-package 
 
-install: libgrok.$(LIBSUFFIX) grok discogrok $(GROKHEADER)
+install: grok discogrok
        install -d $(DESTDIR)$(PREFIX)/bin
-       install -d $(DESTDIR)$(PREFIX)/lib
-       install -d $(DESTDIR)$(PREFIX)/include
        install -m 755 grok $(DESTDIR)$(PREFIX)/bin
        install -m 755 discogrok $(DESTDIR)$(PREFIX)/bin
-       install -m 644 libgrok.$(LIBSUFFIX) $(DESTDIR)$(PREFIX)/lib
-       for header in $(GROKHEADER); do \
-               install -m 644 $$header $(DESTDIR)$(PREFIX)/include; \
-       done 
        install -d $(DESTDIR)$(PREFIX)/share/grok
        install -d $(DESTDIR)$(PREFIX)/share/grok/patterns
        install patterns/base $(DESTDIR)$(PREFIX)/share/grok/patterns/
@@ -107,10 +101,6 @@ install: libgrok.$(LIBSUFFIX) grok discogrok $(GROKHEADER)
 uninstall:
        rm -f $(DESTDIR)$(PREFIX)/bin/grok
        rm -f $(DESTDIR)$(PREFIX)/bin/discogrok
-       rm -f $(DESTDIR)$(PREFIX)/lib/libgrok.$(LIBSUFFIX)
-       for header in $(GROKHEADER); do \
-               rm -f $(DESTDIR)$(PREFIX)/include/$$header; \
-       done 
        rm -f $(DESTDIR)$(PREFIX)/share/grok/patterns/*
 
 pre-create-package:
diff --git a/debian/control b/debian/control
index dd9afb1..67dfc11 100644
--- a/debian/control
+++ b/debian/control
@@ -31,36 +31,3 @@ Description: powerful pattern-matching and reacting tool
  Grok is simple software that allows you to easily parse logs and
  other files. With grok, you can turn unstructured log and event data
  into structured data.
-
-Package: libgrok1
-Section: libs
-Architecture: any
-Pre-Depends: ${misc:Pre-Depends}
-Depends:
- ${misc:Depends},
- ${shlibs:Depends},
-Multi-Arch: same
-Description: shared libraries for grok
- The grok library provides the pattern matching features of grok in
- your own tools. There are currently C and Ruby APIs.
- .
- Grok is simple software that allows you to easily parse logs and
- other files. With grok, you can turn unstructured log and event data
- into structured data.
-
-Package: libgrok-dev
-Section: libdevel
-Architecture: any
-Depends:
- libgrok1 (= ${binary:Version}),
- libtokyocabinet-dev,
- ${misc:Depends},
- ${shlibs:Depends},
-Provides: libgrok-dev
-Conflicts: libgrok-dev
-Description: development files for grok
- Development files for the grok pattern matcher
- .
- Grok is simple software that allows you to easily parse logs and
- other files. With grok, you can turn unstructured log and event data
- into structured data.
diff --git a/debian/grok.install b/debian/grok.install
deleted file mode 100644
index 300bd97..0000000
--- a/debian/grok.install
+++ /dev/null
@@ -1,3 +0,0 @@
-/usr/bin/grok
-/usr/bin/discogrok
-/usr/share/grok/patterns/*
diff --git a/debian/libgrok-dev.install b/debian/libgrok-dev.install
deleted file mode 100644
index 469642e..0000000
--- a/debian/libgrok-dev.install
+++ /dev/null
@@ -1,2 +0,0 @@
-/usr/include/*.h
-/usr/lib/*/*.so
diff --git a/debian/libgrok1.install b/debian/libgrok1.install
deleted file mode 100644
index d6a64d3..0000000
--- a/debian/libgrok1.install
+++ /dev/null
@@ -1 +0,0 @@
-/usr/lib/*/lib*.so.*
diff --git a/debian/patches/debian-changes b/debian/patches/debian-changes
index f1563fc..3140f4e 100644
--- a/debian/patches/debian-changes
+++ b/debian/patches/debian-changes
@@ -26,7 +26,44 @@ A single combined diff, containing all the changes, follows.
  
  LIBSUFFIX=$(shell sh $(BASE)/platform.sh libsuffix)
  VERLIBSUFFIX=$(shell sh $(BASE)/platform.sh libsuffix $(MAJOR))
-@@ -162,14 +162,14 @@ cleanver:
+@@ -83,23 +83,17 @@ GROKHEADER=grok.h grok_pattern.h grok_ca
+ GROKHEADER+=grok_version.h
+ 
+ .PHONY: all
+-all: grok discogrok libgrok.$(LIBSUFFIX) libgrok.$(VERLIBSUFFIX)
++all: grok discogrok
+ 
+ .PHONY: package create-package test-package update-version
+ package: 
+       $(MAKE) $(MAKEFLAGS) create-package 
+       $(MAKE) $(MAKEFLAGS) test-package 
+ 
+-install: libgrok.$(LIBSUFFIX) grok discogrok $(GROKHEADER)
++install: grok discogrok
+       install -d $(DESTDIR)$(PREFIX)/bin
+-      install -d $(DESTDIR)$(PREFIX)/lib
+-      install -d $(DESTDIR)$(PREFIX)/include
+       install -m 755 grok $(DESTDIR)$(PREFIX)/bin
+       install -m 755 discogrok $(DESTDIR)$(PREFIX)/bin
+-      install -m 644 libgrok.$(LIBSUFFIX) $(DESTDIR)$(PREFIX)/lib
+-      for header in $(GROKHEADER); do \
+-              install -m 644 $$header $(DESTDIR)$(PREFIX)/include; \
+-      done 
+       install -d $(DESTDIR)$(PREFIX)/share/grok
+       install -d $(DESTDIR)$(PREFIX)/share/grok/patterns
+       install patterns/base $(DESTDIR)$(PREFIX)/share/grok/patterns/
+@@ -107,10 +101,6 @@ install: libgrok.$(LIBSUFFIX) grok disco
+ uninstall:
+       rm -f $(DESTDIR)$(PREFIX)/bin/grok
+       rm -f $(DESTDIR)$(PREFIX)/bin/discogrok
+-      rm -f $(DESTDIR)$(PREFIX)/lib/libgrok.$(LIBSUFFIX)
+-      for header in $(GROKHEADER); do \
+-              rm -f $(DESTDIR)$(PREFIX)/include/$$header; \
+-      done 
+       rm -f $(DESTDIR)$(PREFIX)/share/grok/patterns/*
+ 
+ pre-create-package:
+@@ -162,14 +152,14 @@ cleanver:
  # Binary creation
  grok: LDFLAGS+=-levent
  grok: $(GROKOBJ) conf.tab.o conf.yy.o main.o grok_config.o
@@ -44,7 +81,7 @@ A single combined diff, containing all the changes, follows.
  
  libgrok.$(VERLIBSUFFIX): libgrok.$(LIBSUFFIX);
        ln -s $< $@
-@@ -213,7 +213,7 @@ grok_capture_xdr.h: grok_capture.x
+@@ -213,7 +203,7 @@ grok_capture_xdr.h: grok_capture.x
        rpcgen -h $< -o $@
  
  %.c: %.gperf
diff --git a/debian/rules b/debian/rules
index 7eb40c9..cb96b2f 100755
--- a/debian/rules
+++ b/debian/rules
@@ -33,10 +33,6 @@ include /usr/share/dpkg/default.mk
 
 override_dh_auto_install:
        dh_auto_install
-       # Move the library
-       install -d debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)
-       mv debian/tmp/usr/lib/libgrok.so 
debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/libgrok.so.1
-       ln -s libgrok.so.1 debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/libgrok.so
 
        help2man --no-info --section=1 \
                --version-string="discogrok $(DEB_VERSION)" \
-- 
2.43.0

Reply via email to