Hi,
the diff looks good, i would change the wording in the manpage a bit, see below. Anyone else who wants to ok it? /Benno Omar Polo(o...@omarpolo.com) on 2021.01.22 12:19:08 +0100: > > quasi three-weekly ping. > > Is this such a bad idea? > > (TBH: I have still to look at how to write a regression test for this) > > Omar Polo <o...@omarpolo.com> writes: > > > Hello, > > > > There are various program, especially the one written with GNU grep in > > mind, that expects various flags that grep in base doesn't have. While > > some of the flags (like --color) can be easily worked out (i.e. by > > patching/customising these programs) one thing that it isn't easily > > workable is --null, because it alters the way grep outputs its data. > > > > --null makes grep output an ASCII NUL byte after the file name, so a > > program can parse the output of grep unambiguously even when the file > > names contains "funny" characters, such as a newline. > > > > GNU grep isn't the only one with a --null flag, also FreeBSD and NetBSD > > grep do (at least by looking at their manpages), so it's somewhat > > widespread. > > > > I searched the archives on marc.info but I haven't seen a previous > > discussion about this. > > > > The following patch was tried against GNU grep (installed from packages) > > and seem to behave consistently. > > > > I used the same text of the FreeBSD/NetBSD manpage for the description > > of the --null option, but I really dislike it: it feels way to verbose > > for what it's trying to say, but I wasn't able to come up with something > > better. > > > > I'm not familiar at all with the grep codebase, so I hope I'm not > > missing something. If this has some chances of being accepted, I guess > > I should also add some regress test; I'll try to work on them soon, but > > in the meantime I'm sending this. > > > > Thanks, > > > > Omar Polo > > > diff e992327fc31d0277a6f8518613a7db1b9face78b /home/op/w/openbsd-src > blob - 5cc228df222c54a0553f289b5da8bbbe6afd171e > file + usr.bin/grep/grep.1 > --- 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,25 @@ 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 (the ASCII NUL character) instead of the character > +that normally follows a file name. > +For example, > +.Nm Fl l Fl -null > +outputs a zero byte after each file name instead of the usual newline. > +This option makes the output unambiguous, even in the presence of file > +names containing unusual characters like newlines. > +This option can be used with commands like > +.Xr find 1 > +.Fl print0 Ns , > +.Xr perl 1 > +.Fl 0 Ns , > +.Xr sort 1 > +.Fl z Ns , and > +.Xr args 1 xargs ? > +.Fl 0 > +to process arbitrary file names, even those that contain newline > +characters. This list of commands is a bit verbose. I would rephrase it to match find(1): -null Print the pathname of the current file to standard output, followed by a null character, suitable for use with the -0 option to xargs(1). If we dont list all these commands in find(1), why here? The list might be incomplete anyway. > .El > .Sh EXIT STATUS > The > blob - f41b5e20ca68c9e9a36d2f7dd3c44329c621f29b > file + usr.bin/grep/grep.c > --- 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 - b3d24ae662beb72c5632190c5c819bcc92f0389a > file + usr.bin/grep/grep.h > --- 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 - e16d08e7d859609c2ccbc0ac4bba670188f81abf > file + usr.bin/grep/util.c > --- 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); > @@ -266,9 +266,9 @@ print: > if (Bflag > 0) > printqueue(); > linesqueued = 0; > - printline(l, ':', oflag ? &pmatch : NULL); > + printline(l, nullflag ? '\0' : ':', oflag ? &pmatch : > NULL); > } else { > - printline(l, '-', oflag ? &pmatch : NULL); > + printline(l, nullflag ? '\0' : '-', oflag ? &pmatch : > NULL); > tail--; > } > } > @@ -660,7 +660,7 @@ printline(str_t *line, int sep, regmatch_t *pmatch) > } > if (nflag) { > if (n) > - putchar(sep); > + putchar(nullflag ? '\0' : sep); > printf("%lld", line->line_no); > ++n; > } >