- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
interp: fix multi-line shell pattern match equality #866
Conversation
@ihar-orca I would love a review, since you submitted the original patch |
3c72dec
to
6f30262
Compare
@lollipopman looks really good! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also thinking about the added API - it seems like we do need the added API, because in some cases we want the partial matching to happen. Or perhaps not - if one needs partial matching, perhaps foobar
could be fed in as *foobar*
, then it will still work as expected.
I had not thought about inverting the need for whole string matches, by converting each pattern into a whole string match as you suggest. I tried doing some rough benchmarks in Go and whole string matches appear significantly slower on larger texts, as I would expect.
|
Ah, good point - "whole" matching is slower, so having it opt-in makes sense even if most use cases within shell will want to opt into the option. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice patch :) Thanks for bearing with me as I review this - it took me a while as I've been travelling.
More than happy to review more patches from you if they are of this quality.
commit be03afe added the multi-line flag to the regexp generated for `==` and `=!` testing. However, this flag is confusing as it allows for a regular expression to match one line out of a multi-line input. (m) multi-line mode: ^ and $ match begin/end line in addition to begin/end text (default false) This means we are now matching against just one line in a multi-line string, rather than the entire text. Instead, to match Bash's behavior, we add the `s` flag to the regexp: (s) let . match \n (default false) With this a `*` in a shell pattern will match `\n`. Glob patterns should always match newline characters, so add the `s` flag when the `.` metacharacter is used. This behavior worked by accident with file globs because rather than matching with `.*` we match with `[^/]*` which does match `\n`.
6f30262
to
5bb30cf
Compare
Thanks, hopefully I will find the time to keep them coming! |
commit be03afe added the multi-line
flag to the regexp generated for
==
and=!
testing. However, thisflag is confusing as it allows for a regular expression to match one
line out of a multi-line input.
This means we are now matching against just one line in a multi-line
string, rather than the entire text. Instead, to match Bash's behavior,
we add the
s
flag to the regexp:With this a
*
in a shell pattern will match\n
.Glob patterns should always match newline characters, so add the
s
flag by default when creating a pattern. Alternately we could add the
s
flag only when the.
meta-character is needed, but that seemedmore fragile. This behavior worked by accident with file globs because
rather than matching with
.*
we match with[^/]*
which does match\n
.