Skip to content

grep: don't short-circuit -v empty pattern under -x/-w - #107

Open
MsfPablo wants to merge 1 commit into
uutils:mainfrom
MsfPablo:empty-pattern-invert-word-line
Open

grep: don't short-circuit -v empty pattern under -x/-w#107
MsfPablo wants to merge 1 commit into
uutils:mainfrom
MsfPablo:empty-pattern-invert-word-line

Conversation

@MsfPablo

Copy link
Copy Markdown

Fixes #65.

The -v + empty-pattern fast path returned "no lines selected, exit 1" without reading input, on the assumption that an empty pattern matches every line. Under -x the empty pattern matches only an empty line, and under -w only an empty match at a word boundary, so the inversion should still select the remaining lines. Gated the short-circuit on neither flag being set.

$ printf 'abc\ndef\n' | grep -e '' -x -v
abc
def

Diffed against GNU grep across -x/-w combined with -v, -i, -c, -n, -o and -E. All -x cases now agree, including exit codes, and the plain -v short-circuit is untouched (its existing test still passes).

One divergence remains under -w, and it is separate from this change. uu_grep treats an empty line as matching -w with an empty pattern; GNU does not:

$ printf 'abc\n\ndef\n' | grep -e '' -w    # uu: prints the empty line, exit 0
$ printf 'abc\n\ndef\n' | grep -e '' -w    # GNU: no output, exit 1

That reproduces on main with no -v involved, so it is a -w matcher issue rather than a short-circuit one — the consequence is that -w -v still drops empty lines that GNU keeps. I left it alone to keep this change to what the issue describes; happy to open a separate issue for it, or fold a fix in here if you would rather.

Tests cover -x/-w on input without empty lines and -x on input with one. cargo test: 95 passed. clippy -D warnings and cargo fmt --check clean.

Comment thread src/lib.rs
Comment on lines 447 to -448
// An empty pattern matches every line; with `-v`, GNU grep selects no lines
// and exits as "no match" without reading any input files.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert this comment. IMO the two-line comment is sufficient to explain why the early-return is necessary. The new comment is redundant with the code which already states the logic via && !word_regexp && !line_regexp.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Empty pattern with -v plus -w/-x selects nothing instead of the non-matching lines

2 participants