Skip to content

Commit 7db8784

Browse files
authored
pcre2grep: correctly handle multiple passes (#35)
* tests: use a explicit filehandle to share in testing -m The way stdin is shared to all participants of a subshell varies per shell, and at least the standard /bin/sh in Solaris seem to create a new copy for each command, defeating the purpose of the test. Use instead exec to create a filehandle that could then be used explicitly in the test to confirm that the stream is set. * pcre2grep: correctly handle multiple passes When the -m option is used, pcre2grep is meant to exit after enough matches are found but while leaving the stream pinned to the next position after the last match. Unfortunately, it wasn't tracking correctly the beginning of the stream on subsequent passes, and therefore it will fail to use the right seek value. Grab the position of the stream at the beginning and while at it, make sure that the stream passed hasn't been consumed already.
1 parent 072717a commit 7db8784

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

RunGrepTest

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,10 +674,14 @@ echo "---------------------------- Test 131 -----------------------------" >>tes
674674
echo "RC=$?" >>testtrygrep
675675

676676
echo "---------------------------- Test 132 -----------------------------" >>testtrygrep
677-
(cd $srcdir; $valgrind $vjs $pcre2grep -m1 -A3 '^match'; echo '---'; head -1) <$srcdir/testdata/grepinput >>testtrygrep 2>&1
677+
(cd $srcdir; exec 3<$srcdir/testdata/grepinput; $valgrind $vjs $pcre2grep -m1 -A3 '^match' <&3; echo '---'; head -1 <&3; exec 3<&-) >>testtrygrep 2>&1
678678
echo "RC=$?" >>testtrygrep
679679

680680
echo "---------------------------- Test 133 -----------------------------" >>testtrygrep
681+
(cd $srcdir; exec 3<$srcdir/testdata/grepinput; $valgrind $vjs $pcre2grep -m1 -A3 '^match' <&3; echo '---'; $valgrind $vjs $pcre2grep -m1 -A3 '^match' <&3; exec 3<&-) >>testtrygrep 2>&1
682+
echo "RC=$?" >>testtrygrep
683+
684+
echo "---------------------------- Test 134 -----------------------------" >>testtrygrep
681685
(cd $srcdir; $valgrind $vjs $pcre2grep -m1 -O '=$x{41}$x423$o{103}$o1045=' 'fox') <$srcdir/testdata/grepinputv >>testtrygrep 2>&1
682686
echo "RC=$?" >>testtrygrep
683687

src/pcre2grep.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2538,6 +2538,7 @@ BOOL endhyphenpending = FALSE;
25382538
BOOL lines_printed = FALSE;
25392539
BOOL input_line_buffered = line_buffered;
25402540
FILE *in = NULL; /* Ensure initialized */
2541+
long stream_start = -1; /* Only non-negative if relevant */
25412542

25422543
/* Do the first read into the start of the buffer and set up the pointer to end
25432544
of what we have. In the case of libz, a non-zipped .gz file will be read as a
@@ -2547,7 +2548,15 @@ fail. */
25472548
if (frtype != FR_LIBZ && frtype != FR_LIBBZ2)
25482549
{
25492550
in = (FILE *)handle;
2550-
if (is_file_tty(in)) input_line_buffered = TRUE;
2551+
if (feof(in))
2552+
return 1;
2553+
if (is_file_tty(in))
2554+
input_line_buffered = TRUE;
2555+
else
2556+
{
2557+
if (count_limit >= 0 && filename == stdin_name)
2558+
stream_start = ftell(in);
2559+
}
25512560
}
25522561
else input_line_buffered = FALSE;
25532562

@@ -2594,8 +2603,8 @@ while (ptr < endptr)
25942603

25952604
if (count_limit >= 0 && count_matched_lines >= count_limit)
25962605
{
2597-
if (frtype == FR_PLAIN && filename == stdin_name && !is_file_tty(handle))
2598-
(void)fseek(handle, (long int)filepos, SEEK_SET);
2606+
if (stream_start >= 0)
2607+
(void)fseek(handle, stream_start + (long int)filepos, SEEK_SET);
25992608
rc = (count_limit == 0)? 1 : 0;
26002609
break;
26012610
}

testdata/grepoutput

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,5 +978,16 @@ match 2:
978978
a
979979
RC=0
980980
---------------------------- Test 133 -----------------------------
981+
match 1:
982+
a
983+
match 2:
984+
b
985+
---
986+
match 2:
987+
b
988+
match 3:
989+
c
990+
RC=0
991+
---------------------------- Test 134 -----------------------------
981992
=AB3CD5=
982993
RC=0

0 commit comments

Comments
 (0)