<div dir="ltr">heh... funny you should mention "." in the first position...<div><br></div><div>$ echo "foo.jar" | old-toybox grep '\.jar'<br>foo.jar<br>$ echo "foo.jar" | new-toybox grep '\.jar'<br></div><div>$ </div><div><br></div><div>that a simplified case based on the real-world build break caused by <a href="https://cs.android.com/android/platform/superproject/+/master:prebuilts/cmdline-tools/Android.bp;l=94;drc=6fa24e3c9dce05b5440b68997b58df791dddd617">https://cs.android.com/android/platform/superproject/+/master:prebuilts/cmdline-tools/Android.bp;l=94;drc=6fa24e3c9dce05b5440b68997b58df791dddd617</a> merging zero jar files into one instead of all the jar files :-)</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Sep 27, 2022 at 1:03 AM Rob Landley <<a href="mailto:rob@landley.net">rob@landley.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 9/27/22 01:47, Yi-yo Chiang wrote:<br>
> (I suffered a system failure during the weekend and lost all my browser tabs and<br>
> consequently lost track of all my work...)<br>
> <br>
> Might be a stupid question, but what's so special about ". in first position"?<br>
<br>
Because the new fast path iterates over each character in the input string, and<br>
at each position checks the patterns that start with that character:<br>
<br>
  for (ss = start; ss-line<ulen; ss++) {<br>
    ii = FLAG(i) ? toupper(*ss) : *ss;<br>
    for (seek = TT.fixed[ii]; seek; seek = seek->next) {<br>
<br>
If I allow "." in first position then I need to repeat the inner loop starting<br>
with seek = TT.fixed['.'] at each position, which is doable but awkward enough I<br>
thought I'd wait for somebody to complain. :)<br>
<br>
> Doesn't ANY '.' in ANY position (sans <backslash><dot>) indicate a regex (not<br>
> fixed pattern)?<br>
<br>
The new fixed pattern search logic can (when FLAG(F) isn't set) handle some<br>
simple regex logic: the "." single character wildcard character, ^ at start and<br>
$ at end, and \ escapes that make regex chars literal. (This is a subset of what<br>
the openbsd one was doing. They also did unicode stuff which I punted on: any<br>
byte > 127 puts the pattern into the slow path that falls back to the old<br>
regcomp and have regexec scan each string from start to finish for each pattern.)<br>
<br>
The new fast path logic has two main chunks, in parse_regex() after the comment:<br>
<br>
// Convert to regex where appropriate<br>
<br>
It works out which patterns the fast path can handle. (Including some magic<br>
tests like if what you've \ escaped is a ( and you're not in -E extended regex<br>
mode, then the escape is actually ACTIVATING it not deactivating it. Regex<br>
escaping is generally weird, as I believe I complained here. The fast path logic<br>
only handles a subset of it, and punts to the rest to the slow path.)<br>
<br>
Once it's identified which patterns can be peeled out into the fast path, it<br>
then bucket sorts them by first character into a 256 entry array. (Since I punt<br>
anything with UTF-8 in it to the slow path the array would only need to be 128<br>
bytes long... except -F can make ANY string take the fast path because it forces<br>
literal match with no special behavior of any character. So I need the top half<br>
of the array for that.)<br>
<br>
Then the logic that actually USES the -F patterns is in do_grep() after the comment:<br>
<br>
// Handle "fixed" (literal) matches (if any)<br>
<br>
Which includes those two loops I pasted above.<br>
<br>
I can complicate the fast path a bit more if additional use cases show up, but<br>
in the absence of people giving me real world data... I implemented more than<br>
just the new test case, but less than openbsd was doing.<br>
<br>
Rob<br>
<br>
P.S. if you have a file of filenames you probably want both -F and -f because<br>
otherwise "potato.txt" will match "potatootxt" because regex. But presumably<br>
that was true of the gnu/dammit and openbsd vesions too...<br>
</blockquote></div>