]> mj.ucw.cz Git - xsv.git/commitdiff
Switch to PCRE2
authorMartin Mareš <mj@ucw.cz>
Sun, 17 Aug 2025 13:28:34 +0000 (15:28 +0200)
committerMartin Mareš <mj@ucw.cz>
Sun, 17 Aug 2025 13:28:34 +0000 (15:28 +0200)
Old PCRE is not packaged by Debian any longer.

Makefile
README
xsv.1.txt
xsv.c

index cd99b8756db6fa9510a1e36dcfe31b71d2365098..fa274ef00a0238840449e17cd64459ffc634b1e9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,10 @@
 VERSION=1.0.1
 ARCHIVE=xsv-$(VERSION).tar.gz
 
-PCRE_CFLAGS:=$(shell pcre-config --cflags)
-PCRE_LIBS:=$(shell pcre-config --libs)
+PCRE_CFLAGS:=$(shell pcre2-config --cflags)
+PCRE_LIBS:=$(shell pcre2-config --libs8)
 
-CFLAGS=-O2 -Wall -W -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes -Wundef -Wredundant-decls -std=gnu99 $(PCRE_CFLAGS) -DVERSION='"$(VERSION)"'
+CFLAGS=-O2 -Wall -W -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes -Wundef -Wredundant-decls -Wno-pointer-sign -std=gnu99 $(PCRE_CFLAGS) -DVERSION='"$(VERSION)"'
 LDLIBS=$(PCRE_LIBS)
 
 PREFIX=/usr/local
diff --git a/README b/README
index 2cb8e90b16ff46013bdb695a47faa467ba2438c9..d918637214e237c0db4828a3b949b6e61873621c 100644 (file)
--- a/README
+++ b/README
@@ -2,7 +2,7 @@
 
                   XSV -- Swiss-Army Knife for CSV-Like Files
 
-                   (c) 2012--2013 Martin Mares <mj@ucw.cz>
+                   (c) 2012--2025 Martin Mares <mj@ucw.cz>
 
        You can use and distribute this program under the terms of GPLv2.
 
@@ -22,7 +22,7 @@ Compilation instructions:
      (or anywhere else if you override PREFIX).
 
 The program has been tested on Linux, but it should run on an arbitrary POSIX
-system with a C99 compiler and the PCRE library. Building of the manual page
+system with a C99 compiler and the PCRE2 library. Building of the manual page
 requires AsciiDoc (any reasonably recent version should work).
 
 All bug reports and suggestions are welcome, especially when accompanied by patches.
index da380769f1e58a2a14195b411e92dcf20d37a3e8..f2903eec470c9f944e689c102aa021cf0b02bfad 100644 (file)
--- a/xsv.1.txt
+++ b/xsv.1.txt
@@ -48,7 +48,7 @@ output. If no format is given, *--tsv* is assumed.
        exactly one space is used.
 *-r, --regex=*'regex'::
        The fields are separated by sequences of characters satisfying the given
-       Perl-compatible regular expression (see *pcrepattern*(3) for a full description
+       Perl-compatible regular expression (see *pcre2pattern*(3) for a full description
        of their syntax). For example, `--regex='#+'` separates fields by an arbitrary
        number of hashes. Leading or trailing separators are interpreted as empty
        fields (this can be overridden by *--sloppy*). This format can be used only
diff --git a/xsv.c b/xsv.c
index 0d2d972b055544ddab45ad06132ed09ea4e2b8c6..39891d8ea238e50449cfb31304b6206ebf336c1e 100644 (file)
--- a/xsv.c
+++ b/xsv.c
@@ -1,7 +1,7 @@
 /*
  *     The Swiss-Army Knife for CSV-like Files
  *
- *     (c) 2012 Martin Mares <mj@ucw.cz>
+ *     (c) 2012-2025 Martin Mares <mj@ucw.cz>
  */
 
 #include <stdio.h>
@@ -12,7 +12,8 @@
 #include <wchar.h>
 #include <locale.h>
 
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 
 #ifdef __GNUC__
 #define NONRET __attribute__((noreturn))
@@ -115,8 +116,8 @@ struct format {
        int always_quote;
 
        // regex backend:
-       pcre *pcre;
-       pcre_extra *pcre_extra;
+       pcre2_code *pcre;
+       pcre2_match_data *pcre_mdata;
 
        // Temporary file backend:
        FILE *tmp_file;
@@ -377,15 +378,19 @@ static int ws_read(struct format *fmt)
 
 static const char *regex_set(struct format *f, char *rx)
 {
-       const char *err;
-       int errpos;
-       f->pcre = pcre_compile(rx, PCRE_DOLLAR_ENDONLY, &err, &errpos, NULL);
-       if (!f->pcre)
-               return err;
+       int errcode;
+       PCRE2_SIZE errpos;
+
+       f->pcre = pcre2_compile(rx, PCRE2_ZERO_TERMINATED, PCRE2_DOLLAR_ENDONLY, &errcode, &errpos, NULL);
+       if (!f->pcre) {
+               char *errmsg = xmalloc(256);
+               pcre2_get_error_message(errcode, errmsg, 256);
+               return errmsg;
+       }
+
+       pcre2_jit_compile(f->pcre, PCRE2_JIT_COMPLETE);
 
-       f->pcre_extra = pcre_study(f->pcre, 0, &err);
-       if (!f->pcre_extra)
-               return err;
+       f->pcre_mdata = pcre2_match_data_create_from_pattern(f->pcre, NULL);
 
        return NULL;
 }
@@ -402,10 +407,9 @@ static int regex_read(struct format *fmt)
 
        int i = 0;
        for (;;) {
-               int ovec[3];
-               int err = pcre_exec(fmt->pcre, fmt->pcre_extra, (char *) c, n, i, 0, ovec, 3);
+               int err = pcre2_match(fmt->pcre, (char *) c, n, i, 0, fmt->pcre_mdata, NULL);
                if (err < 0) {
-                       if (err != PCRE_ERROR_NOMATCH)
+                       if (err != PCRE2_ERROR_NOMATCH)
                                warn(fmt, "PCRE matching error %d", err);
                        // No further occurrence of the separator: the rest is a single field
                        if (!fmt->sloppy || i < n) {
@@ -414,6 +418,7 @@ static int regex_read(struct format *fmt)
                        }
                        return 1;
                }
+               PCRE2_SIZE *ovec = pcre2_get_ovector_pointer(fmt->pcre_mdata);
                if (ovec[0] == ovec[1]) {
                        warn(fmt, "Regular expression matched an empty separator.");
                        new_field(i);