summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt8
-rw-r--r--ChangeLog3
-rw-r--r--Makefile.am1
-rw-r--r--README19
-rwxr-xr-xRunGrepTest11
-rw-r--r--configure.ac28
-rw-r--r--doc/pcre2build.321
-rw-r--r--doc/pcre2grep.156
-rwxr-xr-xmaint/ManyConfigTests2
-rw-r--r--src/config.h.in6
-rw-r--r--src/pcre2grep.c302
-rw-r--r--testdata/grepoutputC8
12 files changed, 441 insertions, 24 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3df4af0..6c84dad 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -158,6 +158,9 @@ SET(PCRE2_SUPPORT_JIT OFF CACHE BOOL
SET(PCRE2_SUPPORT_PCRE2GREP_JIT ON CACHE BOOL
"Enable use of Just-in-time compiling in pcre2grep.")
+SET(PCRE2_SUPPORT_PCRE2GREP_CALLOUT ON CACHE BOOL
+ "Enable callout string support in pcre2grep.")
+
SET(PCRE2_SUPPORT_UNICODE ON CACHE BOOL
"Enable support for Unicode and UTF-8/UTF-16/UTF-32 encoding.")
@@ -273,6 +276,10 @@ IF(PCRE2_SUPPORT_PCRE2GREP_JIT)
SET(SUPPORT_PCRE2GREP_JIT 1)
ENDIF(PCRE2_SUPPORT_PCRE2GREP_JIT)
+IF(PCRE2_SUPPORT_PCRE2GREP_CALLOUT)
+ SET(SUPPORT_PCRE2GREP_CALLOUT 1)
+ENDIF(PCRE2_SUPPORT_PCRE2GREP_CALLOUT)
+
IF(PCRE2_SUPPORT_VALGRIND)
SET(SUPPORT_VALGRIND 1)
ENDIF(PCRE2_SUPPORT_VALGRIND)
@@ -753,6 +760,7 @@ IF(PCRE2_SHOW_REPORT)
MESSAGE(STATUS " Build static libs ............... : ${BUILD_STATIC_LIBS}")
MESSAGE(STATUS " Build pcre2grep ................. : ${PCRE2_BUILD_PCRE2GREP}")
MESSAGE(STATUS " Enable JIT in pcre2grep ......... : ${PCRE2_SUPPORT_PCRE2GREP_JIT}")
+ MESSAGE(STATUS " Enable callouts in pcre2grep .... : ${PCRE2_SUPPORT_PCRE2GREP_CALLOUT}")
MESSAGE(STATUS " Buffer size for pcre2grep ....... : ${PCRE2GREP_BUFSIZE}")
MESSAGE(STATUS " Build tests (implies pcre2test . : ${PCRE2_BUILD_TESTS}")
MESSAGE(STATUS " and pcre2grep)")
diff --git a/ChangeLog b/ChangeLog
index 43d5308..7566f9b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -97,6 +97,9 @@ appropriate line terminator: \r\n for Windows, \n otherwise.
21. When a line is too long for pcre2grep's internal buffer, show the maximum
length in the error message.
+22. Added support for string callouts to pcre2grep (Zoltan's patch with PH
+additions).
+
Version 10.21 12-January-2016
-----------------------------
diff --git a/Makefile.am b/Makefile.am
index 19bfb90..38f1d41 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -570,6 +570,7 @@ EXTRA_DIST += \
testdata/greplist \
testdata/grepoutput \
testdata/grepoutput8 \
+ testdata/grepoutputC \
testdata/grepoutputN \
testdata/greppatN4 \
testdata/testinput1 \
diff --git a/README b/README
index 48d2ffd..6cb1bbb 100644
--- a/README
+++ b/README
@@ -168,15 +168,12 @@ library. They are also documented in the pcre2build man page.
built. If you want only the 16-bit or 32-bit library, use --disable-pcre2-8
to disable building the 8-bit library.
-. If you want to include support for just-in-time compiling, which can give
- large performance improvements on certain platforms, add --enable-jit to the
- "configure" command. This support is available only for certain hardware
+. If you want to include support for just-in-time (JIT) compiling, which can
+ give large performance improvements on certain platforms, add --enable-jit to
+ the "configure" command. This support is available only for certain hardware
architectures. If you try to enable it on an unsupported architecture, there
will be a compile time error.
-. When JIT support is enabled, pcre2grep automatically makes use of it, unless
- you add --disable-pcre2grep-jit to the "configure" command.
-
. If you do not want to make use of the support for UTF-8 Unicode character
strings in the 8-bit library, UTF-16 Unicode character strings in the 16-bit
library, or UTF-32 Unicode character strings in the 32-bit library, you can
@@ -324,6 +321,14 @@ library. They are also documented in the pcre2build man page.
running "make" to build PCRE2. There is more information about coverage
reporting in the "pcre2build" documentation.
+. When JIT support is enabled, pcre2grep automatically makes use of it, unless
+ you add --disable-pcre2grep-jit to the "configure" command.
+
+. On non-Windows sytems there is support for calling external scripts during
+ matching in the pcre2grep command via PCRE2's callout facility with string
+ arguments. This support can be disabled by adding --disable-pcre2grep-callout
+ to the "configure" command.
+
. The pcre2grep program currently supports only 8-bit data files, and so
requires the 8-bit PCRE2 library. It is possible to compile pcre2grep to use
libz and/or libbz2, in order to read .gz and .bz2 files (respectively), by
@@ -840,4 +845,4 @@ The distribution should contain the files listed below.
Philip Hazel
Email local part: ph10
Email domain: cam.ac.uk
-Last updated: 16 October 2015
+Last updated: 01 April 2016
diff --git a/RunGrepTest b/RunGrepTest
index 67d672b..dcd2edc 100755
--- a/RunGrepTest
+++ b/RunGrepTest
@@ -614,6 +614,17 @@ $valgrind $pcre2grep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinputgrep >>
$cf $srcdir/testdata/grepoutputN testtrygrep
if [ $? != 0 ] ; then exit 1; fi
+# If pcre2grep supports script callouts, run some tests on them.
+
+if $valgrind $pcre2grep --help | $valgrind $pcre2grep -q 'Callout scripts in patterns are supported'; then
+ echo "Testing pcre2grep script callouts"
+ $valgrind $pcre2grep '(T)(..(.))(?C"/bin/echo|Arg1: [$1] [$2] [$3]|Arg2: $|${1}$| ($4) ($14) ($0)")()' $srcdir/testdata/grepinputv >testtrygrep
+ $valgrind $pcre2grep '(T)(..(.))()()()()()()()(..)(?C"/bin/echo|Arg1: [$11] [${11}]")' $srcdir/testdata/grepinputv >>testtrygrep
+ $cf $srcdir/testdata/grepoutputC testtrygrep
+ if [ $? != 0 ] ; then exit 1; fi
+else
+ echo "Script callouts are not supported"
+fi
# Finally, some tests to exercise code that is not tested above, just to be
# sure that it runs OK. Doing this improves the coverage statistics. The output
diff --git a/configure.ac b/configure.ac
index 9c697f5..087cd58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -148,6 +148,17 @@ AC_ARG_ENABLE(pcre2grep-jit,
[disable JIT support in pcre2grep]),
, enable_pcre2grep_jit=yes)
+# Handle --disable-pcre2grep-callout (enabled by default) but not supported
+# for Windows.
+if test "$HAVE_WINDOWS_H" != "1"; then
+ AC_ARG_ENABLE(pcre2grep-callout,
+ AS_HELP_STRING([--disable-pcre2grep-callout],
+ [disable callout script support in pcre2grep]),
+ , enable_pcre2grep_callout=yes)
+else
+ enable_pcre2grep_callout=no
+fi
+
# Handle --enable-rebuild-chartables
AC_ARG_ENABLE(rebuild-chartables,
AS_HELP_STRING([--enable-rebuild-chartables],
@@ -392,6 +403,7 @@ sure both macros are undefined; an emulation function will then be used. */])
AC_HEADER_STDC
AC_CHECK_HEADERS(limits.h sys/types.h sys/stat.h dirent.h)
AC_CHECK_HEADERS([windows.h], [HAVE_WINDOWS_H=1])
+AC_CHECK_HEADERS([sys/wait.h], [HAVE_SYS_WAIT_H=1])
# Conditional compilation
AM_CONDITIONAL(WITH_PCRE2_8, test "x$enable_pcre2_8" = "xyes")
@@ -546,6 +558,21 @@ if test "$enable_pcre2grep_jit" = "yes"; then
Define to any value to enable JIT support in pcre2grep.])
fi
+# Currently pcre2grep callout string is not supported under Windows.
+
+if test "$enable_pcre2grep_callout" = "yes"; then
+ if test "$HAVE_WINDOWS_H" != "1"; then
+ if test "$HAVE_SYS_WAIT_H" != "1"; then
+ AC_MSG_ERROR([Callout script support needs sys/wait.h.])
+ fi
+ AC_DEFINE([SUPPORT_PCRE2GREP_CALLOUT], [], [
+ Define to any value to enable callout script support in pcre2grep.])
+ else
+ AC_MSG_WARN([Callout script support is not available for Windows: disabled])
+ enable_pcre2grep_callout=no
+ fi
+fi
+
if test "$enable_unicode" = "yes"; then
AC_DEFINE([SUPPORT_UNICODE], [], [
Define to any value to enable support for Unicode and UTF encoding.
@@ -908,6 +935,7 @@ $PACKAGE-$VERSION configuration summary:
Build shared libs ............... : ${enable_shared}
Build static libs ............... : ${enable_static}
Use JIT in pcre2grep ............ : ${enable_pcre2grep_jit}
+ Enable callouts in pcre2grep .... : ${enable_pcre2grep_callout}
Buffer size for pcre2grep ....... : ${with_pcre2grep_bufsize}
Link pcre2grep with libz ........ : ${enable_pcre2grep_libz}
Link pcre2grep with libbz2 ...... : ${enable_pcre2grep_libbz2}
diff --git a/doc/pcre2build.3 b/doc/pcre2build.3
index a90f1b2..588bd4b 100644
--- a/doc/pcre2build.3
+++ b/doc/pcre2build.3
@@ -1,4 +1,4 @@
-.TH PCRE2BUILD 3 "16 October 2015" "PCRE2 10.21"
+.TH PCRE2BUILD 3 "01 April 2016" "PCRE2 10.22"
.SH NAME
PCRE2 - Perl-compatible regular expressions (revised API)
.
@@ -352,6 +352,19 @@ and equivalent run-time options, refer to these character values in an EBCDIC
environment.
.
.
+.SH "PCRE2GREP SUPPORT FOR EXTERNAL SCRIPTS"
+.rs
+.sp
+By default, on non-Windows systems, \fBpcre2grep\fP supports the use of
+callouts with string arguments within the patterns it is matching, in order to
+run external scripts. For details, see the
+.\" HREF
+\fBpcre2grep\fP
+.\"
+documentation. This support can be disabled by adding
+--disable-pcre2grep-callout to the \fBconfigure\fP command.
+.
+.
.SH "PCRE2GREP OPTIONS FOR COMPRESSED FILE SUPPORT"
.rs
.sp
@@ -381,7 +394,7 @@ parameter value by adding, for example,
--with-pcre2grep-bufsize=50K
.sp
to the \fBconfigure\fP command. The caller of \fPpcre2grep\fP can override this
-value by using --buffer-size on the command line..
+value by using --buffer-size on the command line.
.
.
.SH "PCRE2TEST OPTION FOR LIBREADLINE SUPPORT"
@@ -519,6 +532,6 @@ Cambridge, England.
.rs
.sp
.nf
-Last updated: 16 October 2015
-Copyright (c) 1997-2015 University of Cambridge.
+Last updated: 01 April 2016
+Copyright (c) 1997-2016 University of Cambridge.
.fi
diff --git a/doc/pcre2grep.1 b/doc/pcre2grep.1
index 028a91e..513a15f 100644
--- a/doc/pcre2grep.1
+++ b/doc/pcre2grep.1
@@ -1,4 +1,4 @@
-.TH PCRE2GREP 1 "03 January 2015" "PCRE2 10.00"
+.TH PCRE2GREP 1 "01 April 2016" "PCRE2 10.22"
.SH NAME
pcre2grep - a grep with Perl-compatible regular expressions.
.SH SYNOPSIS
@@ -653,6 +653,54 @@ options does have data, it must be given in the first form, using an equals
character. Otherwise \fBpcre2grep\fP will assume that it has no data.
.
.
+.SH "CALLING EXTERNAL SCRIPTS"
+.rs
+.sp
+On non-Windows systems, \fBpcre2grep\fP has, by default, support for calling
+external programs or scripts during matching by making use of PCRE2's callout
+facility. However, this support can be disabled when \fBpcre2grep\fP is built.
+You can find out whether your binary has support for callouts by running it
+with the \fB--help\fP option. If the support is not enabled, all callouts in
+patterns are ignored by \fBpcre2grep\fP.
+.P
+A callout in a PCRE2 pattern is of the form (?C<arg>) where the argument is
+either a number or a quoted string (see the
+.\" HREF
+\fBpcre2callout\fP
+.\"
+documentation for details). Numbered callouts are ignored by \fBpcre2grep\fP.
+String arguments are parsed as a list of substrings separated by pipe (vertical
+bar) characters. The first substring must be an executable name, with the
+following substrings specifying arguments:
+.sp
+ executable_name|arg1|arg2|...
+.sp
+Any substirng (including the executable name) may contain escape sequences
+started by a dollar character: $<digits> or ${<digits>} is replaced by the
+captured substring of the given decimal number, which must be greater than
+zero. If the number is greater than the number of capturing substrings, or if
+the capture is unset, the replacement is empty.
+.P
+Any other character is substituted by itself. In particular, $$ is replaced by
+a single dollar and $| is replaced by a pipe character. Here is an example:
+.sp
+ echo -e "abcde\en12345" | pcre2grep \e
+ '(?x)(.)(..(.))
+ (?C"/bin/echo|Arg1: [$1] [$2] [$3]|Arg2: $|${1}$| ($4)")()' -
+
+ Output:
+
+ Arg1: [a] [bcd] [d] Arg2: |a| ()
+ abcde
+ Arg1: [1] [234] [4] Arg2: |1| ()
+ 12345
+.sp
+Any syntax errors in the string (for example, a dollar not followed by another
+character) cause the callout to be ignored. If running the program fails for
+any reason (including the non-existence of the executable), a local matching
+failure occurs and the matcher backtracks in the normal way.
+.
+.
.SH "MATCHING ERRORS"
.rs
.sp
@@ -683,7 +731,7 @@ affect the return code.
.SH "SEE ALSO"
.rs
.sp
-\fBpcre2pattern\fP(3), \fBpcre2syntax\fP(3).
+\fBpcre2pattern\fP(3), \fBpcre2syntax\fP(3), \fBpcre2callout\fP(3).
.
.
.SH AUTHOR
@@ -700,6 +748,6 @@ Cambridge, England.
.rs
.sp
.nf
-Last updated: 03 January 2015
-Copyright (c) 1997-2015 University of Cambridge.
+Last updated: 01 April 2016
+Copyright (c) 1997-2016 University of Cambridge.
.fi
diff --git a/maint/ManyConfigTests b/maint/ManyConfigTests
index 8ec940c..0156968 100755
--- a/maint/ManyConfigTests
+++ b/maint/ManyConfigTests
@@ -326,7 +326,7 @@ if [ $usemain -ne 0 ]; then
"--disable-shared" \
"--disable-unicode --disable-stack-for-recursion --disable-shared" \
"--disable-stack-for-recursion --disable-shared --enable-never-backslash-C" \
- "--with-link-size=3 --disable-shared" \
+ "--with-link-size=3 --disable-shared --disable-pcre2grep-callout" \
"--disable-unicode --enable-rebuild-chartables --disable-shared" \
"--disable-unicode --enable-newline-is-any --disable-shared" \
"--disable-unicode --enable-newline-is-cr --disable-shared" \
diff --git a/src/config.h.in b/src/config.h.in
index e55d0a0..d4821af 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -111,6 +111,9 @@ sure both macros are undefined; an emulation function will then be used. */
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
@@ -262,6 +265,9 @@ sure both macros are undefined; an emulation function will then be used. */
is able to handle .gz files. */
#undef SUPPORT_LIBZ
+/* Define to any value to enable callout script support in pcre2grep. */
+#undef SUPPORT_PCRE2GREP_CALLOUT
+
/* Define to any value to enable JIT support in pcre2grep. */
#undef SUPPORT_PCRE2GREP_JIT
diff --git a/src/pcre2grep.c b/src/pcre2grep.c
index d2664f4..231d356 100644
--- a/src/pcre2grep.c
+++ b/src/pcre2grep.c
@@ -58,6 +58,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include <sys/types.h>
#include <sys/stat.h>
+#ifdef SUPPORT_PCRE2GREP_CALLOUT
+#include <sys/wait.h>
+#endif
+
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -121,9 +125,9 @@ apply to fprintf(). */
#define FWRITE(a,b,c,d) if (fwrite(a,b,c,d)) {}
-/* Under Windows, we have to set stdout to be binary, so that it does not
-convert \r\n at the ends of output lines to \r\r\n. However, that means that
-any messages written to stdout must have \r\n as their line terminator. This is
+/* Under Windows, we have to set stdout to be binary, so that it does not
+convert \r\n at the ends of output lines to \r\r\n. However, that means that
+any messages written to stdout must have \r\n as their line terminator. This is
handled by using STDOUT_NL as the newline string. */
#if defined(_WIN32) || defined(WIN32)
@@ -899,6 +903,13 @@ option_item *op;
printf("Usage: pcre2grep [OPTION]... [PATTERN] [FILE1 FILE2 ...]" STDOUT_NL);
printf("Search for PATTERN in each FILE or standard input." STDOUT_NL);
printf("PATTERN must be present if neither -e nor -f is used." STDOUT_NL);
+
+#ifdef SUPPORT_PCRE2GREP_CALLOUT
+printf("Callout scripts in patterns are supported." STDOUT_NL);
+#else
+printf("Callout scripts are not supported in this pcre2grep." STDOUT_NL);
+#endif
+
printf("\"-\" can be used as a file name to mean STDIN." STDOUT_NL);
#ifdef SUPPORT_LIBZ
@@ -1484,6 +1495,274 @@ return FALSE; /* No match, no errors */
}
+#ifdef SUPPORT_PCRE2GREP_CALLOUT
+
+/*************************************************
+* Parse and execute callout scripts *
+*************************************************/
+
+/* This function parses a callout string block and executes the
+program specified by the string. The string is a list of substrings
+separated by pipe characters. The first substring represents the
+executable name, and the following substrings specify the arguments:
+
+ program_name|param1|param2|...
+
+Any substirng (including the program name) can contain escape sequences
+started by the dollar character. The escape sequences are substituted as
+follows:
+
+ $<digits> or ${<digits>} is replaced by the captured substring of the given
+ decimal number, which must be greater than zero. If the number is greater
+ than the number of capturing substrings, or if the capture is unset, the
+ replacement is empty.
+
+ Any other character is substituted by itself. E.g: $$ is replaced by a single
+ dollar or $| replaced by a pipe character.
+
+Example:
+
+ echo -e "abcde\n12345" | pcre2grep \
+ '(.)(..(.))(?C"/bin/echo|Arg1: [$1] [$2] [$3]|Arg2: $|${1}$| ($4)")()' -
+
+ Output:
+
+ Arg1: [a] [bcd] [d] Arg2: |a| ()
+ abcde
+ Arg1: [1] [234] [4] Arg2: |1| ()
+ 12345
+
+Arguments:
+ blockptr the callout block
+
+Returns: currently it always returns with 0
+*/
+
+static int
+pcre2grep_callout(pcre2_callout_block *calloutptr, void *unused)
+{
+PCRE2_SIZE length = calloutptr->callout_string_length;
+PCRE2_SPTR string = calloutptr->callout_string;
+PCRE2_SPTR subject = calloutptr->subject;
+PCRE2_SIZE *ovector = calloutptr->offset_vector;
+PCRE2_SIZE capture_top = calloutptr->capture_top;
+PCRE2_SIZE argsvectorlen = 2;
+PCRE2_SIZE argslen = 1;
+char *args;
+char *argsptr;
+char **argsvector;
+char **argsvectorptr;
+pid_t pid;
+int result = 0;
+
+(void)unused; /* Avoid compiler warning */
+
+/* Only callout with strings are supported. */
+if (string == NULL || length == 0) return 0;
+
+/* Checking syntax and compute the number of string fragments. Callout strings
+are ignored in case of a syntax error. */
+
+while (length > 0)
+ {
+ if (*string == '|')
+ {
+ argsvectorlen++;
+
+ /* Maximum 10000 arguments allowed. */
+ if (argsvectorlen > 10000) return 0;
+ }
+ else if (*string == '$')
+ {
+ PCRE2_SIZE capture_id = 0;
+
+ string++;
+ length--;
+
+ /* Syntax error: a character must be present after $. */
+ if (length == 0) return 0;
+
+ if (*string >= '1' && *string <= '9')
+ {
+ do
+ {
+ /* Maximum capture id is 65535. */
+ if (capture_id <= 65535)
+ capture_id = capture_id * 10 + (*string - '0');
+
+ string++;
+ length--;
+ }
+ while (length > 0 && *string >= '0' && *string <= '9');
+
+ /* To negate the effect of string++ below. */
+ string--;
+ length++;
+ }
+ else if (*string == '{')
+ {
+ /* Must be a decimal number in parenthesis, e.g: (5) or (38) */
+ string++;
+ length--;
+
+ /* Syntax error: a decimal number required. */
+ if (length == 0) return 0;
+ if (*string < '1' || *string > '9') return 0;
+
+ do
+ {
+ /* Maximum capture id is 65535. */
+ if (capture_id <= 65535)
+ capture_id = capture_id * 10 + (*string - '0');
+
+ string++;
+ length--;
+
+ /* Syntax error: no more characters */
+ if (length == 0) return 0;
+ }
+ while (*string >= '0' && *string <= '9');
+
+ /* Syntax error: close paren is missing. */
+ if (*string != '}') return 0;
+ }
+
+ if (capture_id > 0)
+ {
+ if (capture_id < capture_top)
+ {
+ capture_id *= 2;
+ argslen += ovector[capture_id + 1] - ovector[capture_id];
+ }
+
+ /* To negate the effect of argslen++ below. */
+ argslen--;
+ }
+ }
+
+ string++;
+ length--;
+ argslen++;
+ }
+
+args = (char*)malloc(argslen);
+if (args == NULL) return 0;
+
+argsvector = (char**)malloc(argsvectorlen * sizeof(char*));
+if (argsvector == NULL)
+ {
+ free(args);
+ return 0;
+ }
+
+argsptr = args;
+argsvectorptr = argsvector;
+
+*argsvectorptr++ = argsptr;
+
+length = calloutptr->callout_string_length;
+string = calloutptr->callout_string;
+
+while (length > 0)
+ {
+ if (*string == '|')
+ {
+ *argsptr++ = '\0';
+ *argsvectorptr++ = argsptr;
+ }
+ else if (*string == '$')
+ {
+ string++;
+ length--;
+
+ if ((*string >= '1' && *string <= '9') || *string == '{')
+ {
+ PCRE2_SIZE capture_id = 0;
+
+ if (*string != '{')
+ {
+ do
+ {
+ /* Maximum capture id is 65535. */
+ if (capture_id <= 65535)
+ capture_id = capture_id * 10 + (*string - '0');
+
+ string++;
+ length--;
+ }
+ while (length > 0 && *string >= '0' && *string <= '9');
+
+ /* To negate the effect of string++ below. */
+ string--;
+ length++;
+ }
+ else
+ {
+ string++;
+ length--;
+
+ do
+ {
+ /* Maximum capture id is 65535. */
+ if (capture_id <= 65535)
+ capture_id = capture_id * 10 + (*string - '0');
+
+ string++;
+ length--;
+ }
+ while (*string != '}');
+ }
+
+ if (capture_id < capture_top)
+ {
+ PCRE2_SIZE capturesize;
+ capture_id *= 2;
+
+ capturesize = ovector[capture_id + 1] - ovector[capture_id];
+ memcpy(argsptr, subject + ovector[capture_id], capturesize);
+ argsptr += capturesize;
+ }
+ }
+ else
+ {
+ *argsptr++ = *string;
+ }
+ }
+ else
+ {
+ *argsptr++ = *string;
+ }
+
+ string++;
+ length--;
+ }
+
+*argsptr++ = '\0';
+*argsvectorptr = NULL;
+
+pid = fork();
+
+if (pid == 0)
+ {
+ (void)execv(argsvector[0], argsvector);
+ /* Control gets here if there is an error, e.g. a non-existent program */
+ exit(1);
+ }
+else if (pid > 0)
+ (void)waitpid(pid, &result, 0);
+
+free(args);
+free(argsvector);
+
+/* Currently negative return values are not supported, only zero (match
+continues) or non-zero (match fails). */
+
+return result != 0;
+}
+
+#endif
+
+
/*************************************************
* Grep an individual file *
@@ -1786,7 +2065,7 @@ while (ptr < endptr)
}
}
- if (printed || printname != NULL || number)
+ if (printed || printname != NULL || number)
fprintf(stdout, STDOUT_NL);
}
@@ -2637,10 +2916,10 @@ const char *locale_from = "--locale";
pcre2_jit_stack *jit_stack = NULL;
#endif
-/* In Windows, stdout is set up as a text stream, which means that \n is
-converted to \r\n. This causes output lines that are copied from the input to
-change from ....\r\n to ....\r\r\n, which is not right. We therefore ensure
-that stdout is a binary stream. Note that this means all other output to stdout
+/* In Windows, stdout is set up as a text stream, which means that \n is
+converted to \r\n. This causes output lines that are copied from the input to
+change from ....\r\n to ....\r\r\n, which is not right. We therefore ensure
+that stdout is a binary stream. Note that this means all other output to stdout
must use STDOUT_NL to terminate lines. */
#if defined(_WIN32) || defined(WIN32)
@@ -2654,6 +2933,13 @@ match_context = pcre2_match_context_create(NULL);
match_data = pcre2_match_data_create(OFFSET_SIZE, NULL);
offsets = pcre2_get_ovector_pointer(match_data);
+/* If string (script) callouts are supported, set up the callout processing
+function. */
+
+#ifdef SUPPORT_PCRE2GREP_CALLOUT
+pcre2_set_callout(match_context, pcre2grep_callout, NULL);
+#endif
+
/* Process the options */
for (i = 1; i < argc; i++)
diff --git a/testdata/grepoutputC b/testdata/grepoutputC
new file mode 100644
index 0000000..0116645
--- /dev/null
+++ b/testdata/grepoutputC
@@ -0,0 +1,8 @@
+Arg1: [T] [he ] [ ] Arg2: |T| () () (0)
+Arg1: [T] [his] [s] Arg2: |T| () () (0)
+The quick brown
+This time it jumps and jumps and jumps.
+Arg1: [qu] [qu]
+Arg1: [ t] [ t]
+The quick brown
+This time it jumps and jumps and jumps.