Christopher Zimmermann wrote:
> Hi,
> 
> I just tried to find the byte position of a string within a binary file
> using grep. Our base grep -bo let me down because it will only display
> the position of the '\n' delimited line, not the position of the
> pattern.
> 
> That's what our grep(1) says:
> -b    The offset in bytes of a matched pattern is displayed in
>       front of the respective matched line.
> 
> what it actually does is displaying the offset of the line, not the
> pattern. I think it should read as following:
> 
> -b    Each output line is preceded by its position (in bytes) in the
>       file.  If option -o is also specified, the offset in bytes of
> the actual matched pattern is displayed.

This seems like the right behavior. But the diff can be simpler?

> Index: util.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/grep/util.c,v
> retrieving revision 1.59
> diff -u -p -r1.59 util.c
> --- util.c    23 Jan 2019 23:00:54 -0000      1.59
> +++ util.c    16 Jul 2019 21:16:18 -0000
> @@ -250,9 +250,9 @@ print:
>                       if (Bflag > 0)
>                               printqueue();
>                       linesqueued = 0;
> -                     printline(l, ':', oflag ? &pmatch : NULL);
> +                     printline(l, ':', &pmatch);
>               } else {
> -                     printline(l, '-', oflag ? &pmatch : NULL);
> +                     printline(l, '-', &pmatch);
>                       tail--;
>               }
>       }
> @@ -651,12 +651,14 @@ printline(str_t *line, int sep, regmatch
>       if (bflag) {
>               if (n)
>                       putchar(sep);
> -             printf("%lld", (long long)line->off);
> +             printf("%lld",
> +                 (long long)line->off
> +                 + (pmatch && oflag ? pmatch->rm_so : 0));
>               ++n;
>       }
>       if (n)
>               putchar(sep);
> -     if (pmatch)
> +     if (oflag && pmatch)
>               fwrite(line->dat + pmatch->rm_so,
>                   pmatch->rm_eo - pmatch->rm_so, 1, stdout);
>       else

I don't see why you needed to change this much.

-               printf("%lld", (long long)line->off);
+               printf("%lld",
+                   (long long)line->off
+                   + (pmatch ? pmatch->rm_so : 0));

That should be enough, no?

Reply via email to