@ 260915.5

240311.1 · a346883f27f43ae68183b400cfbbc7434d591b94

released 5.1.1

fix a problem with POSIX lazy quantifier matching when combined with anchors, causing longer pattern matches than expected

reading declarations

README.md

@@ -5280,9 +5280,16 @@ in markdown:                    $ ugrep -o -C20 -R -n -k -tjs FIXME -           List the C/C++ comments in a file with line numbers: -                  $ ugrep -n -e '//.*' -e '/\*([^*]|(\*+[^*/]))*\*+\/' myfile.cpp+           Find blocks of text between lines matching BEGIN and END by using a lazy+           quantifier `*?' to match only what is necessary and pattern `\n' to match+           newlines:++                  $ ugrep -n 'BEGIN.*\n(.*\n)*?.*END' myfile.txt++           Likewise, list the C/C++ comments in a file and line numbers:++                  $ ugrep -n -e '//.*' -e '/\*(.*\n)*?.*\*+\/' myfile.cpp             The same, but using predefined pattern c++/comments: @@ -5394,7 +5401,7 @@ in markdown:   -    ugrep 5.0.0                     February 15, 2024                       UGREP(1)+    ugrep 5.5.1                      March 11, 2024                         UGREP(1)  🔝 [Back to table of contents](#toc) 

bin/win32/ug.exe

Binary file changed

bin/win32/ugrep.exe

Binary file changed

bin/win64/ug.exe

Binary file changed

bin/win64/ugrep.exe

Binary file changed

lib/pattern.cpp

@@ -944,13 +944,23 @@ void Pattern::parse2(         iter = iter1;     }   }-  for (Positions::const_iterator p = a_pos.begin(); p != a_pos.end(); ++p)+  for (Positions::iterator p = a_pos.begin(); p != a_pos.end(); ++p)   {     for (Positions::const_iterator k = lastpos.begin(); k != lastpos.end(); ++k)       if (at(k->loc()) == ')' && lookahead.find(k->loc()) != lookahead.end())         pos_add(followpos[p->pos()], *k);-    for (Positions::const_iterator k = lastpos.begin(); k != lastpos.end(); ++k)-      pos_add(followpos[k->pos()], p->anchor(!nullable || k->pos() != p->pos()));+    if (!lazypos.empty())+    {+      // make the starting anchors at positions a_pos lazy+      for (Lazypos::const_iterator l = lazypos.begin(); l != lazypos.end(); ++l)+        for (Positions::const_iterator k = lastpos.begin(); k != lastpos.end(); ++k)+          pos_add(followpos[k->pos()], p->lazy(l->lazy()).anchor(!nullable || k->pos() != p->pos()));+    }+    else+    {+      for (Positions::const_iterator k = lastpos.begin(); k != lastpos.end(); ++k)+        pos_add(followpos[k->pos()], p->anchor(!nullable || k->pos() != p->pos()));+    }     lastpos.clear();     pos_add(lastpos, *p);     if (nullable || firstpos.empty())

man.sh

@@ -577,10 +577,17 @@ recursive search, showing only matches with up to 10 characters of context before and after: .IP $ ugrep -o -C20 -R -n -k -tjs FIXME++.PP+Find blocks of text between lines matching BEGIN and END by using a lazy+quantifier `*?' to match only what is necessary and pattern `\\n' to match+newlines:+.IP+$ ugrep -n 'BEGIN.*\\n(.*\\n)*?.*END' myfile.txt .PP-List the C/C++ comments in a file with line numbers:+Likewise, list the C/C++ comments in a file and line numbers: .IP-$ ugrep -n -e '//.*' -e '/\\*([^*]|(\\*+[^*/]))*\\*+\\/' myfile.cpp+$ ugrep -n -e '//.*' -e '/\\*(.*\\n)*?.*\\*+\\/' myfile.cpp .PP The same, but using predefined pattern c++/comments: .IP

man/ugrep.1

@@ -1,4 +1,4 @@-.TH UGREP "1" "March 07, 2024" "ugrep 5.1.0" "User Commands"+.TH UGREP "1" "March 11, 2024" "ugrep 5.5.1" "User Commands" .SH NAME \fBugrep\fR, \fBug\fR -- file pattern searcher .SH SYNOPSIS@@ -1353,10 +1353,17 @@ recursive search, showing only matches with up to 10 characters of context before and after: .IP $ ugrep -o -C20 -R -n -k -tjs FIXME+ .PP-List the C/C++ comments in a file with line numbers:+Find blocks of text between lines matching BEGIN and END by using a lazy+quantifier `*?' to match only what is necessary and pattern `\\n' to match+newlines: .IP-$ ugrep -n -e '//.*' -e '/\\*([^*]|(\\*+[^*/]))*\\*+\\/' myfile.cpp+$ ugrep -n 'BEGIN.*\\n(.*\\n)*?.*END' myfile.txt+.PP+Likewise, list the C/C++ comments in a file and line numbers:+.IP+$ ugrep -n -e '//.*' -e '/\\*(.*\\n)*?.*\\*+\\/' myfile.cpp .PP The same, but using predefined pattern c++/comments: .IP

patterns/c++/comments

@@ -1,2 +1,2 @@ //.*-/\*([^*]|\n|(\*+([^*/]|\n)))*\*+\/+/\*(.*\n)*?.*\*+\/

patterns/c/comments

@@ -1,2 +1,2 @@ //.*-/\*([^*]|\n|(\*+([^*/]|\n)))*\*+\/+/\*(.*\n)*?.*\*+\/

patterns/cpp/comments

@@ -1,2 +1,2 @@ //.*-/\*([^*]|\n|(\*+([^*/]|\n)))*\*+\/+/\*(.*\n)*?.*\*+\/

patterns/cs/comments

@@ -1,2 +1,2 @@ //.*-/\*([^*]|\n|(\*+([^*/]|\n)))*\*+\/+/\*(.*\n)*?.*\*+\/

patterns/java/comments

@@ -1,2 +1,2 @@ //.*-/\*([^*]|\n|(\*+([^*/]|\n)))*\*+\/+/\*(.*\n)*?.*\*+\/

patterns/js/comments

@@ -1,2 +1,2 @@ //.*-/\*([^*]|\n|(\*+([^*/]|\n)))*\*+\/+/\*(.*\n)*?.*\*+\/

patterns/php/comments

@@ -1,3 +1,3 @@ #.* //.*-/\*([^*]|\n|(\*+([^*/]|\n)))*\*+\/+/\*(.*\n)*?.*\*+\/

patterns/rust/comments

@@ -1,2 +1,2 @@ //.*-/\*([^*]|\n|(\*+([^*/]|\n)))*\*+\/+/\*(.*\n)*?.*\*+\/

patterns/scala/comments

@@ -1,2 +1,2 @@ //.*-/\*([^*]|\n|(\*+([^*/]|\n)))*\*+\/+/\*(.*\n)*?.*\*+\/

patterns/swift/comments

@@ -1,2 +1,2 @@ //.*-/\*([^*]|\n|(\*+([^*/]|\n)))*\*+\/+/\*(.*\n)*?.*\*+\/

src/ugrep.hpp

@@ -38,7 +38,7 @@ #define UGREP_HPP  // ugrep version-#define UGREP_VERSION "5.1.0"+#define UGREP_VERSION "5.1.1"  // disable mmap because mmap is almost always slower than the file reading speed improvements since 3.0.0 #define WITH_NO_MMAP