friendly ping :)

Omar Polo <[email protected]> wrote:
> Hello everyone,
> 
> one year ago there was a thread for grep --null [0] and there seemed to
> be a general agreement (in the diff, not only in how wrong the name
> --null feels.)  In the end it wasn't committed, I got distracted and
> continued to happily using my patched ~/bin/grep
> 
> [0]: https://marc.info/?l=openbsd-tech&m=160975008513761&w=2
> 
> The attached diff was tweaked by benno@ (also after some comments from
> tedu@) and now i've just fixed an issue in printline which reminded me
> that this is still pending.
> 
> (we need to print the NUL byte after the filename and skip the next
> separator if we want to follow the GNU grep behavior: freebsd' grep does
> this, netbsd by glancing at the code doesn't.)
> 
> One thing that wasn't clear in the other thread is the choice of the
> flag: GNU grep has "-Z, --null" and "-z, --null-data" while our grep has
> -Z to force it to behave as zgrep and no -z.  We also can't use -0
> because it stands for "print 0 lines of context" (both in GNU grep and
> ours grep); while it's unlikely that someone is relying on it, it
> currently "works" and dumping NULs into some pipeline not prepared for
> them is not sensible.  (e.g. a script that does `| grep -$n'...)
> 
> ok?

diff c7b9cff49c7474cbd891cffe3c5679e3c4a02106 
95de83f1c7ec1857cafa9126687508fb00d7a2bb
commit - c7b9cff49c7474cbd891cffe3c5679e3c4a02106
commit + 95de83f1c7ec1857cafa9126687508fb00d7a2bb
blob - 5cc228df222c54a0553f289b5da8bbbe6afd171e
blob + e1edae7e432a155ddf71433717f58c8017744386
--- usr.bin/grep/grep.1
+++ usr.bin/grep/grep.1
@@ -49,6 +49,7 @@
 .Op Fl -context Ns Op = Ns Ar num
 .Op Fl -label Ns = Ns Ar name
 .Op Fl -line-buffered
+.Op Fl -null
 .Op Ar pattern
 .Op Ar
 .Ek
@@ -297,6 +298,16 @@ instead of the filename before lines.
 Force output to be line buffered.
 By default, output is line buffered when standard output is a terminal
 and block buffered otherwise.
+.It Fl -null
+Output a zero byte instead of the character that normally follows a
+file name.
+This option makes the output unambiguous, even in the presence of file
+names containing unusual characters like newlines, making the output
+suitable for use with the
+.Fl 0
+option to
+.Xr xargs 1 .
+This option is a non-POSIX extension and may not be portable.
 .El
 .Sh EXIT STATUS
 The
blob - f41b5e20ca68c9e9a36d2f7dd3c44329c621f29b
blob + 279d949fae764262a350e66ce1c21a6864284eb6
--- usr.bin/grep/grep.c
+++ usr.bin/grep/grep.c
@@ -80,6 +80,7 @@ int    vflag;         /* -v: only show non-matching lines */
 int     wflag;         /* -w: pattern must start and end on word boundaries */
 int     xflag;         /* -x: pattern must match entire line */
 int     lbflag;        /* --line-buffered */
+int     nullflag;      /* --null */
 const char *labelname; /* --label=name */
 
 int binbehave = BIN_FILE_BIN;
@@ -89,6 +90,7 @@ enum {
        HELP_OPT,
        MMAP_OPT,
        LINEBUF_OPT,
+       NULL_OPT,
        LABEL_OPT,
 };
 
@@ -134,6 +136,7 @@ static const struct option long_options[] =
        {"mmap",                no_argument,            NULL, MMAP_OPT},
        {"label",               required_argument,      NULL, LABEL_OPT},
        {"line-buffered",       no_argument,            NULL, LINEBUF_OPT},
+       {"null",                no_argument,            NULL, NULL_OPT},
        {"after-context",       required_argument,      NULL, 'A'},
        {"before-context",      required_argument,      NULL, 'B'},
        {"context",             optional_argument,      NULL, 'C'},
@@ -436,6 +439,9 @@ main(int argc, char *argv[])
                case LINEBUF_OPT:
                        lbflag = 1;
                        break;
+               case NULL_OPT:
+                       nullflag = 1;
+                       break;
                case HELP_OPT:
                default:
                        usage();
blob - 731bbcc35af4cbf870aaf70ce9913e375142d4d8
blob + 16a1e94a0bcf58498dd4df8d6c7692f1ffdb8045
--- usr.bin/grep/grep.h
+++ usr.bin/grep/grep.h
@@ -68,7 +68,7 @@ extern int     cflags, eflags;
 extern int      Aflag, Bflag, Eflag, Fflag, Hflag, Lflag,
                 Rflag, Zflag,
                 bflag, cflag, hflag, iflag, lflag, mflag, nflag, oflag, qflag,
-                sflag, vflag, wflag, xflag;
+                sflag, vflag, wflag, xflag, nullflag;
 extern int      binbehave;
 extern const char *labelname;
 
blob - 33b1094659071e59c719151bc5d0a247ea3cad23
blob + 9aa0a8b5be2fba7f907dd1d065de692a3407e2f7
--- usr.bin/grep/util.c
+++ usr.bin/grep/util.c
@@ -172,13 +172,13 @@ procfile(char *fn)
 
        if (cflag) {
                if (!hflag)
-                       printf("%s:", ln.file);
+                       printf("%s%c", ln.file, nullflag ? '\0' : ':');
                printf("%llu%s\n", c, overflow ? "+" : "");
        }
        if (lflag && c != 0)
-               printf("%s\n", fn);
+               printf("%s%c", fn, nullflag ? '\0' : '\n');
        if (Lflag && c == 0)
-               printf("%s\n", fn);
+               printf("%s%c", fn, nullflag ? '\0' : '\n');
        if (c && !cflag && !lflag && !Lflag &&
            binbehave == BIN_FILE_BIN && nottext && !qflag)
                printf("Binary file %s matches\n", fn);
@@ -653,27 +653,32 @@ grep_revstr(unsigned char *str, int len)
 void
 printline(str_t *line, int sep, regmatch_t *pmatch)
 {
-       int n;
+       int n, printsep;
 
        n = 0;
+       printsep = !nullflag;
        if (!hflag) {
                fputs(line->file, stdout);
+               if (nullflag)
+                       putchar(0);
                ++n;
        }
        if (nflag) {
-               if (n)
+               if (n && printsep)
                        putchar(sep);
                printf("%lld", line->line_no);
+               printsep = 1;
                ++n;
        }
        if (bflag) {
-               if (n)
+               if (n && printsep)
                        putchar(sep);
                printf("%lld", (long long)line->off +
                    (pmatch ? pmatch->rm_so : 0));
+               printsep = 1;
                ++n;
        }
-       if (n)
+       if (n && printsep)
                putchar(sep);
        if (pmatch)
                fwrite(line->dat + pmatch->rm_so,



Reply via email to