Re: Official request: Please make GNU grep the default

From: Dimitry Andric <dimitry_at_andric.com>
Date: Mon, 23 Aug 2010 19:13:01 +0200
On 2010-08-20 23:07, b. f. wrote:
> The lisp category is the only category that causes a problem with the
> new bsdgrep, and I didn't take the time to analyze why ( which is why
> I was not more specific in my original message). 'lisp' is preceded by
> 'elisp', which would normally be a match for the 'lisp' in a port
> Makefile, were it not for the -w flag.  'x11' succeeds, but it
> precedes all of the x11-* categories.  I suspect that there is an
> error in the logic of either the -w or the -q flag implementation in
> bsdgrep, which causes problems when the two options are used together.
> The target succeeds as expected with GNU grep.

Can you please try the following patch?  I think this solves more than
one problem in bsdgrep's logic, but it needs to be reviewed by Gabor and
others.

In usr.bin/grep/util.c, in the function procline(), there is the
following fragment:

290                 /* Loop to process the whole line */
291                 while (st <= l->len) {
                            [...]
295                         /* Loop to compare with all the patterns */
296                         for (i = 0; i < patterns; i++) {
                                    [... sets r to 0 if a match was found ...]
336                                 if (r == 0) {
                                            [...]
341                                         /* matches - skip further patterns */
342                                         if ((color != NULL && !oflag) || qflag || lflag)
343                                                 break;
344                                 }
345                         }
                            [...]
351                         /* One pass if we are not recording matches */
352                         if ((color != NULL && !oflag) || qflag || lflag)
353                                 break;
                            [...]
357                 }

If during the first iteration of the "loop to process the whole line"
no match was found (for example, if doing a word search for "lisp" and
the string "elisp" is found instead), AND the -q option was used, the
test in line 352 aborts the whole loop, without searching any further!
Thus it will miss the "lisp" string later in the line.

It looks like line 352 should only be evaluated if the for() loop just
above it resulted in one or or more matches, so it is probably easiest
to just replace line 343 with a goto that jumps out of the two enclosing
loops (it is still a pity C does not have a "break 2" statement), and
delete lines 351..353 entirely.

However, if there are unintended side effects, for example with weird
combinations of the --color, -o and/or -l flags, please let me know. :)

Received on Mon Aug 23 2010 - 15:12:56 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:06 UTC