Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ugrep for openSUSE:Factory checked 
in at 2023-03-02 23:03:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ugrep (Old)
 and      /work/SRC/openSUSE:Factory/.ugrep.new.31432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ugrep"

Thu Mar  2 23:03:39 2023 rev:37 rq:1068539 version:3.10.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/ugrep/ugrep.changes      2023-02-01 
16:39:52.077916133 +0100
+++ /work/SRC/openSUSE:Factory/.ugrep.new.31432/ugrep.changes   2023-03-02 
23:04:11.692061157 +0100
@@ -1,0 +2,10 @@
+Wed Mar  1 19:42:06 UTC 2023 - Andreas Stieger <andreas.stie...@gmx.de>
+
+- update to 3.10.0:
+  * This release adds the option --tree to output directory trees
+    of files for the options -l (--files-with-matches),
+    -L (--files-withou-match), and -c (--count)
+  * The option --pretty was updated to to enable --tree when output
+    is sent to  a terminal. This can be disabled with --no-tree.
+
+-------------------------------------------------------------------

Old:
----
  ugrep-3.9.7.tar.gz

New:
----
  ugrep-3.10.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ugrep.spec ++++++
--- /var/tmp/diff_new_pack.FM67gY/_old  2023-03-02 23:04:12.484065114 +0100
+++ /var/tmp/diff_new_pack.FM67gY/_new  2023-03-02 23:04:12.488065134 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           ugrep
-Version:        3.9.7
+Version:        3.10.0
 Release:        0
 Summary:        Universal grep: a feature-rich grep implementation with focus 
on speed
 License:        BSD-3-Clause

++++++ ugrep-3.9.7.tar.gz -> ugrep-3.10.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ugrep-3.9.7/Makefile.am new/ugrep-3.10.0/Makefile.am
--- old/ugrep-3.9.7/Makefile.am 2023-01-31 17:06:32.000000000 +0100
+++ new/ugrep-3.10.0/Makefile.am        2023-03-01 02:59:57.000000000 +0100
@@ -18,14 +18,14 @@
                  cp -f $< $(top_builddir)/bin/ugrep$(EXEEXT); \
                  cd $(top_builddir)/bin; \
                  rm -f ug$(EXEEXT); \
-                 $(LN_S) ugrep$(EXEEXT) ug$(EXEEXT)
+                 cp -f ugrep$(EXEEXT) ug$(EXEEXT)
                @echo
                @echo "OK"
                @echo
 
 install-exec-hook:
                rm -f $(DESTDIR)$(bindir)/ug$(EXEEXT)
-               cd $(DESTDIR)$(bindir) && $(LN_S) ugrep$(EXEEXT) ug$(EXEEXT)
+               cd $(DESTDIR)$(bindir) && cp -f ugrep$(EXEEXT) ug$(EXEEXT)
 
 install-data-hook:
                mkdir -p $(DESTDIR)$(datadir)/ugrep && \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ugrep-3.9.7/Makefile.in new/ugrep-3.10.0/Makefile.in
--- old/ugrep-3.9.7/Makefile.in 2023-01-31 17:06:32.000000000 +0100
+++ new/ugrep-3.10.0/Makefile.in        2023-03-01 02:59:57.000000000 +0100
@@ -902,14 +902,14 @@
                  cp -f $< $(top_builddir)/bin/ugrep$(EXEEXT); \
                  cd $(top_builddir)/bin; \
                  rm -f ug$(EXEEXT); \
-                 $(LN_S) ugrep$(EXEEXT) ug$(EXEEXT)
+                 cp -f ugrep$(EXEEXT) ug$(EXEEXT)
                @echo
                @echo "OK"
                @echo
 
 install-exec-hook:
                rm -f $(DESTDIR)$(bindir)/ug$(EXEEXT)
-               cd $(DESTDIR)$(bindir) && $(LN_S) ugrep$(EXEEXT) ug$(EXEEXT)
+               cd $(DESTDIR)$(bindir) && cp -f ugrep$(EXEEXT) ug$(EXEEXT)
 
 install-data-hook:
                mkdir -p $(DESTDIR)$(datadir)/ugrep && \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ugrep-3.9.7/README.md new/ugrep-3.10.0/README.md
--- old/ugrep-3.9.7/README.md   2023-01-31 17:06:32.000000000 +0100
+++ new/ugrep-3.10.0/README.md  2023-03-01 02:59:57.000000000 +0100
@@ -1,6 +1,6 @@
 [![build status][travis-image]][travis-url] 
[![license][bsd-3-image]][bsd-3-url]
 
-**ugrep v3.9 is now available: more features & even faster than before**
+**ugrep v3.10 is now available: more features & even faster than before**
 
 Search for anything in everything... ultra fast
 
@@ -398,9 +398,8 @@
 - `--help` display build options
 
 After the build completes, copy `ugrep/bin/ugrep` and `ugrep/bin/ug` to a
-convenient location, for example in your `~/bin` directory.
-
-You may want to install the `ugrep` and `ug` commands and man pages with:
+convenient location, for example in your `~/bin` directory. Or, if you may want
+to install the `ugrep` and `ug` commands and man pages:
 
     $ sudo make install
 
@@ -1358,13 +1357,15 @@
             Only the names of files not containing selected lines are written
             to standard output.  Pathnames are listed once per file searched.
             If the standard input is searched, the string ``(standard input)''
-            is written.
+            is written.  If --tree is specified, outputs directories in a
+            tree-like format.
     -l, --files-with-matches
             Only the names of files containing selected lines are written to
             standard output.  ugrep will only search a file until a match has
             been found, making searches potentially less expensive.  Pathnames
             are listed once per file searched.  If the standard input is
-            searched, the string ``(standard input)'' is written.
+            searched, the string ``(standard input)'' is written.  If --tree is
+            specified, outputs directories in a tree-like format.
     -R, --dereference-recursive
             Recursively read all files under each directory.  Follow all
             symbolic links, unlike -r.  See also option --sort.
@@ -3004,9 +3005,10 @@
 ### Counting the number of matches with -c and -co
 
     -c, --count
-            Only a count of selected lines is written to standard output.
-            If -o or -u is specified, counts the number of patterns matched.
-            If -v is specified, counts the number of non-matching lines.
+            Only a count of selected lines is written to standard output.  If
+            -o or -u is specified, counts the number of patterns matched.  If
+            -v is specified, counts the number of non-matching lines.  If
+            --tree is specified, outputs directories in a tree-like format.
 
 To count the number of lines in a file:
 
@@ -3124,7 +3126,7 @@
             and --line-buffered.
     --pretty
             When output is sent to a terminal, enables --color, --heading, -n,
-            --sort and -T when not explicitly disabled.
+            --sort, --tree and -T when not explicitly disabled.
 
 To change the color palette, set the `GREP_COLORS` environment variable or use
 `--colors=COLORS`.  The value is a colon-separated list of ANSI SGR parameters
@@ -3983,7 +3985,9 @@
                   --lines.
 
            --break
-                  Adds a line break between results from different files.
+                  Adds a line break between results from different files.  This
+                  option is enabled by --pretty when the output is sent to a
+                  terminal.
 
            -C NUM, --context=NUM
                   Output NUM lines of leading and trailing context surrounding 
each
@@ -3995,7 +3999,8 @@
            -c, --count
                   Only a count of selected lines is written to standard 
output.  If
                   -o or -u is specified, counts the number of patterns 
matched.  If
-                  -v is specified, counts the number of non-matching lines.
+                  -v is specified, counts the number of non-matching lines.  If
+                  --tree is specified, outputs directories in a tree-like 
format.
 
            --color[=WHEN], --colour[=WHEN]
                   Mark up the matching text with the expression stored in the
@@ -4207,7 +4212,8 @@
 
            --heading, -+
                   Group matches per file.  Adds a heading and a line break 
between
-                  results from different files.
+                  results from different files.  This option is enabled by 
--pretty
+                  when the output is sent to a terminal.
 
            --help [WHAT], -? [WHAT]
                   Display a help message, specifically on WHAT when specified. 
 In
@@ -4322,14 +4328,16 @@
                   Only the names of files not containing selected lines are 
written
                   to standard output.  Pathnames are listed once per file 
searched.
                   If the standard input is searched, the string ``(standard 
input)''
-                  is written.
+                  is written.  If --tree is specified, outputs directories in a
+                  tree-like format.
 
            -l, --files-with-matches
                   Only the names of files containing selected lines are 
written to
                   standard output.  ugrep will only search a file until a 
match has
                   been found, making searches potentially less expensive.  
Pathnames
                   are listed once per file searched.  If the standard input is
-                  searched, the string ``(standard input)'' is written.
+                  searched, the string ``(standard input)'' is written.  If 
--tree
+                  is specified, outputs directories in a tree-like format.
 
            --label=LABEL
                   Displays the LABEL value when input is read from standard 
input
@@ -4443,7 +4451,7 @@
 
            --pretty
                   When output is sent to a terminal, enables --color, 
--heading, -n,
-                  --sort and -T when not explicitly disabled.
+                  --sort, --tree and -T when not explicitly disabled.
 
            -Q[DELAY], --query[=DELAY]
                   Query mode: user interface to perform interactive searches.  
This
@@ -4558,6 +4566,11 @@
                   Disables colors to mark up matches with TAG.  END marks the 
end of
                   a match if specified, otherwise TAG.  The default is `___'.
 
+           --tree, -^
+                  Output directories with matching files in a tree-like format 
when
+                  options -c, -l or -L are used.  This option is enabled by 
--pretty
+                  when the output is sent to a terminal.
+
            -U, --binary
                   Disables Unicode matching for binary file matching, forcing
                   PATTERN to match bytes, not Unicode characters.  For 
example, -U
@@ -5237,7 +5250,7 @@
 
 
 
-    ugrep 3.9.3                     December 29, 2022                       
UGREP(1)
+    ugrep 3.10.0                    February 28, 2023                       
UGREP(1)
 
 🔝 [Back to table of contents](#toc)
 
@@ -5251,8 +5264,9 @@
 has more features than the pattern syntax described below.  For the patterns in
 common the syntax and meaning are the same.
 
-Note that `\s` and inverted bracket lists `[^...]` are modified to prevent
-matching newlines `\n` to replicate the behavior of grep.
+Note that `\s` and inverted bracket lists `[^...]` are modified in **ugrep** to
+prevent matching newlines `\n`.  This modification is done to replicate the
+behavior of grep.
 
 <a name="posix-syntax"/>
 
Binary files old/ugrep-3.9.7/bin/win32/ugrep.exe and 
new/ugrep-3.10.0/bin/win32/ugrep.exe differ
Binary files old/ugrep-3.9.7/bin/win64/ugrep.exe and 
new/ugrep-3.10.0/bin/win64/ugrep.exe differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ugrep-3.9.7/man/ugrep.1 new/ugrep-3.10.0/man/ugrep.1
--- old/ugrep-3.9.7/man/ugrep.1 2023-01-31 17:06:32.000000000 +0100
+++ new/ugrep-3.10.0/man/ugrep.1        2023-03-01 02:59:57.000000000 +0100
@@ -1,4 +1,4 @@
-.TH UGREP "1" "December 29, 2022" "ugrep 3.9.3" "User Commands"
+.TH UGREP "1" "February 28, 2023" "ugrep 3.10.0" "User Commands"
 .SH NAME
 \fBugrep\fR, \fBug\fR -- file pattern searcher
 .SH SYNOPSIS
@@ -128,7 +128,9 @@
 \fB\-\-andnot\fR, \fB\-\-not\fR, \fB\-\-files\fR and \fB\-\-lines\fR.
 .TP
 \fB\-\-break\fR
-Adds a line break between results from different files.
+Adds a line break between results from different files.  This
+option is enabled by \fB\-\-pretty\fR when the output is sent to a
+terminal.
 .TP
 \fB\-C\fR \fINUM\fR, \fB\-\-context\fR=\fINUM\fR
 Output NUM lines of leading and trailing context surrounding each
@@ -140,7 +142,8 @@
 \fB\-c\fR, \fB\-\-count\fR
 Only a count of selected lines is written to standard output.
 If \fB\-o\fR or \fB\-u\fR is specified, counts the number of patterns matched.
-If \fB\-v\fR is specified, counts the number of non\-matching lines.
+If \fB\-v\fR is specified, counts the number of non\-matching lines.  If
+\fB\-\-tree\fR is specified, outputs directories in a tree\-like format.
 .TP
 \fB\-\-color\fR[=\fIWHEN\fR], \fB\-\-colour\fR[=\fIWHEN\fR]
 Mark up the matching text with the expression stored in the
@@ -348,7 +351,8 @@
 .TP
 \fB\-\-heading\fR, \fB\-+\fR
 Group matches per file.  Adds a heading and a line break between
-results from different files.
+results from different files.  This option is enabled by \fB\-\-pretty\fR
+when the output is sent to a terminal.
 .TP
 \fB\-\-help\fR [\fIWHAT\fR], \fB\-?\fR [\fIWHAT\fR]
 Display a help message, specifically on WHAT when specified.
@@ -461,14 +465,16 @@
 Only the names of files not containing selected lines are written
 to standard output.  Pathnames are listed once per file searched.
 If the standard input is searched, the string ``(standard input)''
-is written.
+is written.  If \fB\-\-tree\fR is specified, outputs directories in a
+tree\-like format.
 .TP
 \fB\-l\fR, \fB\-\-files\-with\-matches\fR
 Only the names of files containing selected lines are written to
 standard output.  ugrep will only search a file until a match has
 been found, making searches potentially less expensive.  Pathnames
 are listed once per file searched.  If the standard input is
-searched, the string ``(standard input)'' is written.
+searched, the string ``(standard input)'' is written.  If \fB\-\-tree\fR is
+specified, outputs directories in a tree\-like format.
 .TP
 \fB\-\-label\fR=\fILABEL\fR
 Displays the LABEL value when input is read from standard input
@@ -580,7 +586,7 @@
 .TP
 \fB\-\-pretty\fR
 When output is sent to a terminal, enables \fB\-\-color\fR, \fB\-\-heading\fR, 
\fB\-n\fR,
-\fB\-\-sort\fR and \fB\-T\fR when not explicitly disabled.
+\fB\-\-sort\fR, \fB\-\-tree\fR and \fB\-T\fR when not explicitly disabled.
 .TP
 \fB\-Q\fR[\fIDELAY\fR], \fB\-\-query\fR[=\fIDELAY\fR]
 Query mode: user interface to perform interactive searches.  This
@@ -694,6 +700,11 @@
 Disables colors to mark up matches with TAG.  END marks the end of
 a match if specified, otherwise TAG.  The default is `___'.
 .TP
+\fB\-\-tree\fR, \-^
+Output directories with matching files in a tree\-like format when
+options \fB\-c\fR, \fB\-l\fR or \fB\-L\fR are used.  This option is enabled by 
\fB\-\-pretty\fR
+when the output is sent to a terminal.
+.TP
 \fB\-U\fR, \fB\-\-binary\fR
 Disables Unicode matching for binary file matching, forcing PATTERN
 to match bytes, not Unicode characters.  For example, \fB\-U\fR '\\xa3'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ugrep-3.9.7/src/flag.hpp 
new/ugrep-3.10.0/src/flag.hpp
--- old/ugrep-3.9.7/src/flag.hpp        2023-01-31 17:06:32.000000000 +0100
+++ new/ugrep-3.10.0/src/flag.hpp       2023-03-01 02:59:57.000000000 +0100
@@ -127,6 +127,7 @@
 extern Flag flag_line_number;
 extern Flag flag_smart_case;
 extern Flag flag_text;
+extern Flag flag_tree;
 extern Flag flag_ungroup;
 extern Sort flag_sort_key;
 extern Action flag_devices_action;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ugrep-3.9.7/src/output.cpp 
new/ugrep-3.10.0/src/output.cpp
--- old/ugrep-3.9.7/src/output.cpp      2023-01-31 17:06:32.000000000 +0100
+++ new/ugrep-3.10.0/src/output.cpp     2023-03-01 02:59:57.000000000 +0100
@@ -360,6 +360,129 @@
   }
 }
 
+// output the pathname header for --files_with_matches and --count
+void Output::header(const char *pathname, const std::string& partname)
+{
+  bool nul = flag_query > 0; // -Q: mark pathname with three NUL bytes
+
+  if (flag_tree)
+  {
+    // acquire lock on output and to access global Tree::path and Tree::depth
+    acquire();
+
+    int up = 0;
+
+    while (!Tree::path.empty() && Tree::path.compare(0, Tree::path.size(), 
pathname, Tree::path.size()) != 0)
+    {
+      Tree::path.pop_back();
+
+      size_t len = Tree::path.rfind(PATHSEPCHR);
+      if (len == std::string::npos)
+        Tree::path.clear();
+      else
+        Tree::path.resize(len + 1);
+
+      ++up;
+      --Tree::depth;
+    }
+
+    if (up > 0)
+    {
+      for (int i = 0; i < Tree::depth; ++i)
+        str(Tree::bar);
+      while (--up > 0)
+        str(Tree::end);
+      nl();
+    }
+
+    const char *sep;
+
+    while ((sep = strchr(pathname + Tree::path.size(), PATHSEPCHR)) != NULL)
+    {
+      for (int i = 1; i < Tree::depth; ++i)
+        str(Tree::bar);
+      if (Tree::depth > 0)
+        str(Tree::ptr);
+      else if (nul)
+        str("\0\0", 2);
+
+      str(pathname + Tree::path.size(), sep - (pathname + Tree::path.size()) + 
1);
+
+      if (nul && Tree::depth == 0)
+        chr('\0');
+      nl();
+
+      Tree::path.assign(pathname, sep - pathname + 1);
+      ++Tree::depth;
+    }
+
+    for (int i = 1; i < Tree::depth; ++i)
+      str(Tree::bar);
+    if (Tree::depth > 0)
+      str(Tree::ptr);
+    else if (nul)
+      chr('\0');
+
+    str(color_fn);
+
+    if (color_hl != NULL)
+    {
+      str(color_hl);
+      uri(color_wd);
+      uri(pathname);
+      str(color_st);
+    }
+
+    if (nul && Tree::depth == 0)
+      chr('\0');
+
+    str(pathname + Tree::path.size());
+
+    if (nul && Tree::depth == 0)
+      chr('\0');
+
+  }
+  else
+  {
+    if (nul)
+      chr('\0');
+
+    str(color_fn);
+
+    if (color_hl != NULL)
+    {
+      str(color_hl);
+      uri(color_wd);
+      uri(pathname);
+      str(color_st);
+    }
+
+    if (nul)
+      chr('\0');
+
+    str(pathname);
+
+    if (nul)
+      chr('\0');
+
+    if (color_hl != NULL)
+    {
+      str(color_hl);
+      str(color_st);
+    }
+
+  }
+
+  if (!partname.empty())
+  {
+    chr('{');
+    str(partname);
+    chr('}');
+  }
+
+  str(color_off);
+}
+
 // output "Binary file ... matches"
 void Output::binary_file_matches(const char *pathname, const std::string& 
partname)
 {
@@ -452,6 +575,107 @@
   return std::pair<const char*,size_t>(NULL, 0);
 }
 
+// output format with option --format-begin and --format-end
+void Output::format(const char *format, size_t matches)
+{
+  const char *sep = NULL;
+  size_t len = 0;
+  const char *s = format;
+  while (*s != '\0')
+  {
+    const char *a = NULL;
+    const char *t = s;
+    while (*s != '\0' && *s != '%')
+      ++s;
+    str(t, s - t);
+    if (*s == '\0' || *(s + 1) == '\0')
+      break;
+    ++s;
+    if (*s == '[')
+    {
+      a = ++s;
+      while (*s != '\0' && *s != ']')
+        ++s;
+      if (*s == '\0' || *(s + 1) == '\0')
+        break;
+      ++s;
+    }
+    int c = *s;
+    switch (c)
+    {
+      case 'T':
+        if (flag_initial_tab)
+        {
+          if (a)
+            str(a, s - a - 1);
+          chr('\t');
+        }
+        break;
+
+      case 'S':
+        if (matches > 1)
+        {
+          if (a)
+            str(a, s - a - 1);
+          if (sep != NULL)
+            str(sep, len);
+          else
+            str(flag_separator);
+        }
+        break;
+
+      case '$':
+        sep = a;
+        len = s - a - 1;
+        break;
+
+      case 't':
+        fputc('\t', output);
+        break;
+
+      case 's':
+        if (sep != NULL)
+          str(sep, len);
+        else
+          str(flag_separator);
+        break;
+
+      case '~':
+#ifdef OS_WIN
+        chr('\r');
+#endif
+        chr('\n');
+        break;
+
+      case 'm':
+        num(matches);
+        break;
+
+      case '<':
+        if (matches <= 1 && a)
+          str(a, s - a - 1);
+        break;
+
+      case '>':
+        if (matches > 1 && a)
+          str(a, s - a - 1);
+        break;
+
+      case ',':
+      case ':':
+      case ';':
+      case '|':
+        if (matches > 1)
+          chr(c);
+        break;
+
+      default:
+        chr(c);
+    }
+    ++s;
+  }
+}
+
 // output formatted match with options --format, --format-open, --format-close
 void Output::format(const char *format, const char *& pathname, const 
std::string& partname, size_t matches, reflex::AbstractMatcher *matcher, bool 
body, bool next)
 {
@@ -934,9 +1158,9 @@
         break;
 
       case 'Z':
-        if (flag_fuzzy > 0)
+        if (flag_fuzzy > 0 && !flag_files_with_matches && !flag_count)
         {
-          // --Z: we used the fuzzy matcher to search, so a dynamic cast is 
fine
+          // -Z: we used the fuzzy matcher to search, so a dynamic cast is fine
           reflex::FuzzyMatcher *fuzzy_matcher = 
dynamic_cast<reflex::FuzzyMatcher*>(matcher);
           num(fuzzy_matcher->edits());
         }
@@ -1836,3 +2060,10 @@
 }
 
 const char *Output::Dump::color_hex[4] = { match_ms, color_sl, match_mc, 
color_cx };
+
+const char *Output::Tree::bar = "|  ";
+const char *Output::Tree::ptr = "|_ ";
+const char *Output::Tree::end = "~  ";
+
+std::string Output::Tree::path;
+int Output::Tree::depth;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ugrep-3.9.7/src/output.hpp 
new/ugrep-3.10.0/src/output.hpp
--- old/ugrep-3.9.7/src/output.hpp      2023-01-31 17:06:32.000000000 +0100
+++ new/ugrep-3.10.0/src/output.hpp     2023-03-01 02:59:57.000000000 +0100
@@ -70,9 +70,7 @@
  public:
 
   // sync state to synchronize output produced by multiple threads, UNORDERED 
or ORDERED by slot number
-  class Sync {
-
-   public:
+  struct Sync {
 
     enum class Mode { UNORDERED, ORDERED };
 
@@ -229,9 +227,7 @@
   };
 
   // hex dump state
-  class Dump {
-
-   public:
+  struct Dump {
 
     // hex dump mode for color highlighting
     static constexpr short HEX_MATCH         = 0;
@@ -299,6 +295,18 @@
 
   };
 
+  // global directory tree state for output, protected by acquire()
+  struct Tree {
+
+    static const char  *bar;    // fixed string to display a vertical line
+    static const char  *ptr;    // fixed string to display a vertical line and 
connector
+    static const char  *end;    // fixed string to display a vertical line 
ending
+
+    static std::string  path;   // tree directory path buffer
+    static int          depth;  // tree directory depth
+
+  };
+
   // constructor
   Output(FILE *file)
     :
@@ -320,6 +328,7 @@
   // destructor
   ~Output()
   {
+    flush();
     if (lock_ != NULL)
       delete lock_;
   }
@@ -710,9 +719,15 @@
   // output the header part of the match, preceding the matched line
   void header(const char *& pathname, const std::string& partname, size_t 
lineno, reflex::AbstractMatcher *matcher, size_t byte_offset, const char *sep, 
bool newline);
 
+  // output the pathname header for --files_with_matches and --count
+  void header(const char *pathname, const std::string& partname);
+
   // output "Binary file ... matches"
   void binary_file_matches(const char *pathname, const std::string& partname);
 
+  // output format with option --format-begin and --format-end
+  void format(const char *format, size_t matches);
+
   // output formatted match with options --format, --format-open, 
--format-close
   void format(const char *format, const char *& pathname, const std::string& 
partname, size_t matches, reflex::AbstractMatcher *matcher, bool body, bool 
next);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ugrep-3.9.7/src/query.cpp 
new/ugrep-3.10.0/src/query.cpp
--- old/ugrep-3.9.7/src/query.cpp       2023-01-31 17:06:32.000000000 +0100
+++ new/ugrep-3.10.0/src/query.cpp      2023-03-01 02:59:57.000000000 +0100
@@ -3513,54 +3513,26 @@
 // true if line starts with a valid filename/filepath identified by three \0 
markers and differs from the given filename, then assigns filename
 bool Query::is_filename(const std::string& line, std::string& filename, bool 
compare_dir)
 {
-  size_t start = 0;
-  size_t pos = 0;
   size_t end = line.size();
 
-  if (flag_files_with_matches || flag_count)
-  {
-    while (pos < end)
-    {
-      unsigned char c = line.at(pos);
-
-      if (c != '\033')
-        break;
-
-      while (++pos < end && !isalpha(line.at(pos)))
-        continue;
-
-      ++pos;
-    }
-
-    if (pos >= end)
-      return false;
-
-    start = pos;
-
-    while (pos < end && line.at(pos) != '\033')
-      ++pos;
-  }
-  else
-  {
-    if (end < 4 || line.front() != '\0')
-      return false;
+  if (end < 4 || line.front() != '\0')
+    return false;
 
-    pos = 1;
+  size_t pos = 1;
 
-    while (pos < end && line.at(pos) != '\0')
-      ++pos;
+  while (pos < end && line.at(pos) != '\0')
+    ++pos;
 
-    if (++pos >= end)
-      return false;
+  if (++pos >= end)
+    return false;
 
-    start = pos;
+  size_t start = pos;
 
-    while (pos < end && line.at(pos) != '\0')
-      ++pos;
+  while (pos < end && line.at(pos) != '\0')
+    ++pos;
 
-    if (pos == start || pos >= end)
-      return false;
-  }
+  if (pos == start || pos >= end)
+    return false;
 
   if (compare_dir)
   {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ugrep-3.9.7/src/stats.cpp 
new/ugrep-3.10.0/src/stats.cpp
--- old/ugrep-3.9.7/src/stats.cpp       2023-01-31 17:06:32.000000000 +0100
+++ new/ugrep-3.10.0/src/stats.cpp      2023-03-01 02:59:57.000000000 +0100
@@ -124,7 +124,7 @@
     fprintf(output, "  --no-hidden (default)" NEWLINESTR);
 #endif
   for (auto& i : flag_ignore_files)
-    fprintf(output, "  --ignore-files='%s'" NEWLINESTR, i.c_str());
+    fprintf(output, "  --ignore-files=\"%s\"" NEWLINESTR, i.c_str());
   if (flag_min_count > 0)
     fprintf(output, "  --min-count=%zu" NEWLINESTR, flag_min_count);
   if (flag_max_count > 0)
@@ -136,22 +136,22 @@
   for (auto& i : flag_file_magic)
   {
     if (!i.empty() && (i.front() == '!' || i.front() == '^'))
-      fprintf(output, "  --file-magic='!%s' (negation)" NEWLINESTR, i.c_str() 
+ 1);
+      fprintf(output, "  --file-magic=\"!%s\" (negated)" NEWLINESTR, i.c_str() 
+ 1);
     else
-      fprintf(output, "  --file-magic='%s'" NEWLINESTR, i.c_str());
+      fprintf(output, "  --file-magic=\"%s\"" NEWLINESTR, i.c_str());
   }
   for (auto& i : flag_include_fs)
-    fprintf(output, "  --include-fs='%s'" NEWLINESTR, i.c_str());
+    fprintf(output, "  --include-fs=\"%s\"" NEWLINESTR, i.c_str());
   for (auto& i : flag_exclude_fs)
-    fprintf(output, "  --exclude-fs='%s'" NEWLINESTR, i.c_str());
+    fprintf(output, "  --exclude-fs=\"%s\"" NEWLINESTR, i.c_str());
   for (auto& i : flag_all_include)
-    fprintf(output, "  --include='%s'%s" NEWLINESTR, i.c_str(), i.front() == 
'!' ? " (negated)" : "");
+    fprintf(output, "  --include=\"%s\"%s" NEWLINESTR, i.c_str(), i.front() == 
'!' ? " (negated)" : "");
   for (auto& i : flag_all_exclude)
-    fprintf(output, "  --exclude='%s'%s" NEWLINESTR, i.c_str(), i.front() == 
'!' ? " (negated)" : "");
+    fprintf(output, "  --exclude=\"%s\"%s" NEWLINESTR, i.c_str(), i.front() == 
'!' ? " (negated)" : "");
   for (auto& i : flag_all_include_dir)
-    fprintf(output, "  --include-dir='%s'%s" NEWLINESTR, i.c_str(), i.front() 
== '!' ? " (negated)" : "");
+    fprintf(output, "  --include-dir=\"%s\"%s" NEWLINESTR, i.c_str(), 
i.front() == '!' ? " (negated)" : "");
   for (auto& i : flag_all_exclude_dir)
-    fprintf(output, "  --exclude-dir='%s'%s" NEWLINESTR, i.c_str(), i.front() 
== '!' ? " (negated)" : "");
+    fprintf(output, "  --exclude-dir=\"%s\"%s" NEWLINESTR, i.c_str(), 
i.front() == '!' ? " (negated)" : "");
 }
 
 reflex::timer_type       Stats::timer;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ugrep-3.9.7/src/ugrep.cpp 
new/ugrep-3.10.0/src/ugrep.cpp
--- old/ugrep-3.9.7/src/ugrep.cpp       2023-01-31 17:06:32.000000000 +0100
+++ new/ugrep-3.10.0/src/ugrep.cpp      2023-03-01 02:59:57.000000000 +0100
@@ -368,6 +368,7 @@
 Flag flag_line_number;
 Flag flag_smart_case;
 Flag flag_text;
+Flag flag_tree;
 Flag flag_ungroup;
 Sort flag_sort_key                 = Sort::NA;
 Action flag_devices_action         = Action::UNSP;
@@ -474,7 +475,6 @@
 void strtopos2(const char *string, size_t& pos1, size_t& pos2, const char 
*message);
 size_t strtofuzzy(const char *string, const char *message);
 void import_globs(FILE *file, std::vector<std::string>& files, 
std::vector<std::string>& dirs);
-void format(const char *format, size_t matches);
 void usage(const char *message, const char *arg = NULL, const char *valid = 
NULL);
 void help(std::ostream& out);
 void help(const char *what = NULL);
@@ -695,7 +695,7 @@
   }
 
   // start decompression thread and open new pipe, returns pipe or NULL on 
failure, this function is called by the main Grep thread
-  FILE *start(int ztstage, const char *pathname, FILE *file_in)
+  FILE *start(size_t ztstage, const char *pathname, FILE *file_in)
   {
     // return pipe
     FILE *pipe_in = NULL;
@@ -1138,12 +1138,13 @@
           // tar header fields name, size and prefix and make them 
\0-terminated by overwriting fields we do not use
           buf[100] = '\0';
           const char *name = reinterpret_cast<const char*>(buf);
+
           // path prefix is up to 155 bytes (ustar) or up to 131 bytes (gnutar)
           buf[345 + (is_ustar ? 155 : 131)] = '\0';
           const char *prefix = reinterpret_cast<const char*>(buf + 345);
 
-          // check GNU tar extension with leading byte 0x80 (unsigned 
positive) or leading byte 0xff (negative)
-          size_t size = 0;
+          // check gnutar size with leading byte 0x80 (unsigned positive) or 
leading byte 0xff (negative)
+          uint64_t size = 0;
           if (buf[124] == 0x80)
           {
             // 11 byte big-endian size field without the leading 0x80
@@ -1192,7 +1193,7 @@
           memmove(buf, buf + BLOCKSIZE, static_cast<size_t>(len));
 
           // check if archived file meets selection criteria
-          size_t minlen = std::min(static_cast<size_t>(len), size);
+          size_t minlen = 
static_cast<size_t>(std::min(static_cast<uint64_t>(len), size)); // size_t is 
OK: len is streamsize but non-negative
           bool is_selected = select_matching(path.c_str(), buf, minlen, 
is_regular);
 
           // if extended headers are present
@@ -1255,7 +1256,7 @@
 
           while (len > 0 && !stop)
           {
-            size_t len_out = std::min(static_cast<size_t>(len), size);
+            size_t len_out = 
static_cast<size_t>(std::min(static_cast<uint64_t>(len), size)); // size_t is 
OK: len is streamsize but non-negative
 
             if (ok)
             {
@@ -1270,7 +1271,7 @@
             if (size == 0)
             {
               len -= len_out;
-              memmove(buf, buf + len_out, static_cast<size_t>(len));
+              memmove(buf, buf + len_out, static_cast<size_t>(len)); // size_t 
is OK: len is streamsize but non-negative
 
               break;
             }
@@ -1563,7 +1564,7 @@
 
           while (len > 0 && !stop)
           {
-            size_t len_out = std::min(static_cast<size_t>(len), size);
+            size_t len_out = std::min(static_cast<size_t>(len), size); // 
size_t is OK: len is streamsize but non-negative
 
             if (ok)
             {
@@ -4215,8 +4216,10 @@
 # specifies background colors.  A `+' qualifies a color as bright.  A\n\
 # foreground and a background color may be combined with font properties `n'\n\
 # (normal), `f' (faint), `h' (highlight), `i' (invert), `u' (underline).\n\n");
+
   fprintf(file, "# Enable/disable color\n%s\n\n", flag_color != NULL ? "color" 
: "no-color");
   fprintf(file, "# Enable/disable query UI confirmation prompts, default: 
confirm\n%s\n\n", flag_confirm ? "confirm" : "no-confirm");
+
   fprintf(file, "# Enable/disable query UI file viewing command with CTRL-Y, 
default: view\n");
   if (flag_view != NULL && *flag_view == '\0')
     fprintf(file, "view\n\n");
@@ -4224,16 +4227,23 @@
     fprintf(file, "view=%s\n\n", flag_view);
   else
     fprintf(file, "no-view\n\n");
+
   fprintf(file, "# Enable/disable or specify a pager for terminal output, 
default: no-pager\n");
   if (flag_pager != NULL)
     fprintf(file, "pager=%s\n\n", flag_pager);
   else
     fprintf(file, "no-pager\n\n");
+
   fprintf(file, "# Enable/disable pretty output to the terminal, default: 
no-pretty\n%s\n\n", flag_pretty ? "pretty" : "no-pretty");
-  fprintf(file, "# Enable/disable headings for terminal output, default: 
no-heading\n%s\n\n", flag_heading.is_undefined() ? "# no-heading" : 
flag_heading ? "heading" : "no-heading");
 
-  if (flag_break.is_defined())
-    fprintf(file, "# Enable/disable break for terminal output\n%s\n\n", 
flag_break ? "break" : "no-break");
+  if (flag_tree.is_defined() && flag_tree != flag_pretty)
+    fprintf(file, "# Enable/disable directory tree output for 
--files-with-matches and --count\n%s\n\n", flag_tree ? "tree" : "no-tree");
+
+  if (flag_heading.is_defined() && flag_heading != flag_pretty)
+    fprintf(file, "# Enable/disable headings\n%s\n\n", 
flag_heading.is_undefined() ? "# no-heading" : flag_heading ? "heading" : 
"no-heading");
+
+  if (flag_break.is_defined() && flag_break != flag_pretty)
+    fprintf(file, "# Enable/disable break after matching files\n%s\n\n", 
flag_break ? "break" : "no-break");
 
   if (flag_line_number.is_defined() && flag_line_number != flag_pretty)
     fprintf(file, "# Enable/disable line numbers\n%s\n\n", flag_line_number ? 
"line-number" : "no-line-number");
@@ -4251,6 +4261,7 @@
     fprintf(file, "# Hex output\nhex\n\n");
   else if (strcmp(flag_binary_files, "with-hex") == 0)
     fprintf(file, "# Output with hex for binary matches\nwith-hex\n\n");
+
   if (flag_hexdump != NULL)
     fprintf(file, "# Hex dump (columns, no space breaks, no character column, 
no hex spacing)\nhexdump=%s\n\n", flag_hexdump);
 
@@ -4269,6 +4280,7 @@
     if (flag_before_context > 0)
       fprintf(file, "# Display lines before context\nbefore-context=%zu\n\n", 
flag_before_context);
   }
+
   if (flag_group_separator == NULL)
     fprintf(file, "# Disable group separator for 
contexts\nno-group-separator\n\n");
   else if (strcmp(flag_group_separator, "--") != 0)
@@ -4729,6 +4741,8 @@
                   flag_smart_case = false;
                 else if (strcmp(arg, "no-sort") == 0)
                   flag_sort = NULL;
+                else if (strcmp(arg, "no-tree") == 0)
+                  flag_tree = false;
                 else if (strcmp(arg, "no-stats") == 0)
                   flag_stats = NULL;
                 else if (strcmp(arg, "no-ungroup") == 0)
@@ -4740,7 +4754,7 @@
                 else if (strcmp(arg, "neg-regexp") == 0)
                   usage("missing argument for --", arg);
                 else
-                  usage("invalid option --", arg, "--neg-regexp, --not, 
--no-any-line, --no-binary, --no-bool, --no-break, --no-byte-offset, 
--no-color, --no-confirm, --no-decompress, --no-dereference, --no-dotall, 
--no-empty, --no-filename, --no-group-separator, --no-heading, --no-hidden, 
--no-ignore-binary, --no-ignore-case, --no-ignore-files --no-initial-tab, 
--no-invert-match, --no-line-number, --no-only-line-number, --no-only-matching, 
--no-messages, --no-mmap, --no-pager, --no-pretty, --no-smart-case, --no-sort, 
--no-stats, --no-ungroup, --no-view or --null");
+                  usage("invalid option --", arg, "--neg-regexp, --not, 
--no-any-line, --no-binary, --no-bool, --no-break, --no-byte-offset, 
--no-color, --no-confirm, --no-decompress, --no-dereference, --no-dotall, 
--no-empty, --no-filename, --no-group-separator, --no-heading, --no-hidden, 
--no-ignore-binary, --no-ignore-case, --no-ignore-files --no-initial-tab, 
--no-invert-match, --no-line-number, --no-only-line-number, --no-only-matching, 
--no-messages, --no-mmap, --no-pager, --no-pretty, --no-smart-case, --no-sort, 
--no-stats, --no-tree, --no-ungroup, --no-view or --null");
                 break;
 
               case 'o':
@@ -4829,8 +4843,10 @@
                   flag_tag = arg + 4;
                 else if (strcmp(arg, "text") == 0)
                   flag_binary_files = "text";
+                else if (strcmp(arg, "tree") == 0)
+                  flag_tree = true;
                 else
-                  usage("invalid option --", arg, "--tabs, --tag or --text");
+                  usage("invalid option --", arg, "--tabs, --tag, --text or 
--tree");
                 break;
 
               case 'u':
@@ -5252,6 +5268,10 @@
             flag_bool = true;
             break;
 
+          case '^':
+            flag_tree = true;
+            break;
+
           case '+':
             flag_heading = true;
             break;
@@ -5585,6 +5605,10 @@
   if (flag_query > 0)
     flag_pager = NULL;
 
+  // --tree: require sort to produce directory tree
+  if (flag_tree && flag_sort == NULL)
+    flag_sort = "name";
+
   // check TTY info and set colors (warnings and errors may occur from here on)
   terminal();
 
@@ -6362,7 +6386,7 @@
     {
       if (flag_pretty)
       {
-        // --pretty: if output is to a TTY then enable --color, --heading, -T, 
-n, and --sort
+        // --pretty: if output is to a TTY then enable --color, --heading, -T, 
-n, --sort and --tree
 
         // enable --color
         if (flag_apply_color == NULL)
@@ -6383,6 +6407,10 @@
         // enable --sort=name if no --sort specified
         if (flag_sort == NULL)
           flag_sort = "name";
+
+        // enable --tree
+        if (flag_tree.is_undefined())
+          flag_tree = true;
       }
       else if (flag_apply_color != NULL)
       {
@@ -6426,6 +6454,22 @@
       }
     }
 
+#ifndef OS_WIN
+
+    if (flag_tree && (flag_files_with_matches || flag_files_without_match || 
flag_count))
+    {
+      const char *lang = getenv("LANG");
+
+      if (lang != NULL && strstr(lang, "UTF-8"))
+      {
+        Output::Tree::bar = "│ ";
+        Output::Tree::ptr = "╰╴";
+        Output::Tree::end = "▔ ";
+      }
+    }
+
+#endif
+
     // --color: (re)set flag_apply_color depending on color_term and TTY output
     if (flag_apply_color != NULL)
     {
@@ -6595,6 +6639,10 @@
   // reset stats
   Stats::reset();
 
+  // --tree: reset directory tree output
+  Output::Tree::path.clear();
+  Output::Tree::depth = 0;
+
   // populate the combined all-include and all-exclude
   flag_all_include = flag_include;
   flag_all_include_dir = flag_include_dir;
@@ -6786,16 +6834,16 @@
       flag_sort_key = Sort::BEST;
     else if (strcmp(sort_by, "size") == 0)
       flag_sort_key = Sort::SIZE;
-    else if (strcmp(sort_by, "used") == 0)
+    else if (strcmp(sort_by, "used") == 0 || strcmp(sort_by, "atime") == 0)
       flag_sort_key = Sort::USED;
-    else if (strcmp(sort_by, "changed") == 0)
+    else if (strcmp(sort_by, "changed") == 0 || strcmp(sort_by, "mtime") == 0)
       flag_sort_key = Sort::CHANGED;
-    else if (strcmp(sort_by, "created") == 0)
+    else if (strcmp(sort_by, "created") == 0 || strcmp(sort_by, "ctime") == 0)
       flag_sort_key = Sort::CREATED;
     else if (strcmp(sort_by, "list") == 0)
       flag_sort_key = Sort::LIST;
     else
-      usage("invalid argument --sort=KEY, valid arguments are 'name', 'best', 
'size', 'used', 'changed', 'created', 'list', 'rname', 'rbest', 'rsize', 
'rused', 'rchanged', 'rcreated' and 'rlist'");
+      usage("invalid argument --sort=KEY, valid arguments are 'name', 'best', 
'size', 'used' ('atime'), 'changed' ('mtime'), 'created' ('ctime'), 'list', 
'rname', 'rbest', 'rsize', 'rused' ('ratime'), 'rchanged' ('rmtime'), 
'rcreated' ('rctime') and 'rlist'");
   }
 
   // add PATTERN to the CNF
@@ -7177,7 +7225,7 @@
 
   // --format-begin
   if (flag_format_begin != NULL)
-    format(flag_format_begin, 0);
+    Output(output).format(flag_format_begin, 0);
 
   size_t nodes = 0;
   size_t edges = 0;
@@ -7437,9 +7485,18 @@
     words_time = static_cast<size_t>(pattern.words_time());
   }
 
+  // --tree with -l or -c
+  if (flag_tree && (flag_files_with_matches || flag_count))
+  {
+    Output out(output);
+    for (int i = 1; i < Output::Tree::depth; ++i)
+      out.str(Output::Tree::end);
+    out.nl();
+  }
+
   // --format-end
   if (flag_format_end != NULL)
-    format(flag_format_end, Stats::found_parts());
+    Output(output).format(flag_format_end, Stats::found_parts());
 
   // --stats: display stats when we're done
   if (flag_stats != NULL)
@@ -8561,27 +8618,7 @@
             }
             else
             {
-              out.str(color_fn);
-              if (color_hl != NULL)
-              {
-                out.str(color_hl);
-                out.uri(color_wd);
-                out.uri(pathname);
-                out.str(color_st);
-              }
-              out.str(pathname);
-              if (color_hl != NULL)
-              {
-                out.str(color_hl);
-                out.str(color_st);
-              }
-              if (!partname.empty())
-              {
-                out.chr('{');
-                out.str(partname);
-                out.chr('}');
-              }
-              out.str(color_off);
+              out.header(pathname, partname);
 
               if (flag_null)
                 out.chr('\0');
@@ -8713,27 +8750,7 @@
         {
           if (flag_with_filename || !partname.empty())
           {
-            out.str(color_fn);
-            if (color_hl != NULL)
-            {
-              out.str(color_hl);
-              out.uri(color_wd);
-              out.uri(pathname);
-              out.str(color_st);
-            }
-            out.str(pathname);
-            if (color_hl != NULL)
-            {
-              out.str(color_hl);
-              out.str(color_st);
-            }
-            if (!partname.empty())
-            {
-              out.chr('{');
-              out.str(partname);
-              out.chr('}');
-            }
-            out.str(color_off);
+            out.header(pathname, partname);
 
             if (flag_null)
             {
@@ -11334,107 +11351,6 @@
   }
 }
 
-// display format with option --format-begin and --format-end
-void format(const char *format, size_t matches)
-{
-  const char *sep = NULL;
-  size_t len = 0;
-  const char *s = format;
-  while (*s != '\0')
-  {
-    const char *a = NULL;
-    const char *t = s;
-    while (*s != '\0' && *s != '%')
-      ++s;
-    fwrite(t, 1, s - t, output);
-    if (*s == '\0' || *(s + 1) == '\0')
-      break;
-    ++s;
-    if (*s == '[')
-    {
-      a = ++s;
-      while (*s != '\0' && *s != ']')
-        ++s;
-      if (*s == '\0' || *(s + 1) == '\0')
-        break;
-      ++s;
-    }
-    int c = *s;
-    switch (c)
-    {
-      case 'T':
-        if (flag_initial_tab)
-        {
-          if (a)
-            fwrite(a, 1, s - a - 1, output);
-          fputc('\t', output);
-        }
-        break;
-
-      case 'S':
-        if (matches > 1)
-        {
-          if (a)
-            fwrite(a, 1, s - a - 1, output);
-          if (sep != NULL)
-            fwrite(sep, 1, len, output);
-          else
-            fputs(flag_separator, output);
-        }
-        break;
-
-      case '$':
-        sep = a;
-        len = s - a - 1;
-        break;
-
-      case 't':
-        fputc('\t', output);
-        break;
-
-      case 's':
-        if (sep != NULL)
-          fwrite(sep, 1, len, output);
-        else
-          fputs(flag_separator, output);
-        break;
-
-      case '~':
-#ifdef OS_WIN
-        fputc('\r', output);
-#endif
-        fputc('\n', output);
-        break;
-
-      case 'm':
-        fprintf(output, "%zu", matches);
-        break;
-
-      case '<':
-        if (matches <= 1 && a)
-          fwrite(a, 1, s - a - 1, output);
-        break;
-
-      case '>':
-        if (matches > 1 && a)
-          fwrite(a, 1, s - a - 1, output);
-        break;
-
-      case ',':
-      case ':':
-      case ';':
-      case '|':
-        if (matches > 1)
-          fputc(c, output);
-        break;
-
-      default:
-        fputc(c, output);
-    }
-    ++s;
-  }
-}
-
 // trim white space from either end of the line
 void trim(std::string& line)
 {
@@ -11823,7 +11739,9 @@
             displays the search patterns applied.  See also options --and,\n\
             --andnot, --not, --files and --lines.\n\
     --break\n\
-            Adds a line break between results from different files.\n\
+            Adds a line break between results from different files.  This\n\
+            option is enabled by --pretty when the output is sent to a\n\
+            terminal.\n\
     -C NUM, --context=NUM\n\
             Output NUM lines of leading and trailing context surrounding 
each\n\
             matching line.  Places a --group-separator between contiguous\n\
@@ -11833,7 +11751,8 @@
     -c, --count\n\
             Only a count of selected lines is written to standard output.\n\
             If -o or -u is specified, counts the number of patterns matched.\n\
-            If -v is specified, counts the number of non-matching lines.\n\
+            If -v is specified, counts the number of non-matching lines.  If\n\
+            --tree is specified, outputs directories in a tree-like format.\n\
     --color[=WHEN], --colour[=WHEN]\n\
             Mark up the matching text with the expression stored in the\n\
             GREP_COLOR or GREP_COLORS environment variable.  WHEN can be\n\
@@ -12031,7 +11950,8 @@
             when there is only one file (or only standard input) to search.\n\
     --heading, -+\n\
             Group matches per file.  Adds a heading and a line break between\n\
-            results from different files.\n\
+            results from different files.  This option is enabled by 
--pretty\n\
+            when the output is sent to a terminal.\n\
     --help [WHAT], -? [WHAT]\n\
             Display a help message, specifically on WHAT when specified.\n\
             In addition, `--help format' displays an overview of FORMAT 
fields,\n\
@@ -12136,13 +12056,15 @@
             Only the names of files not containing selected lines are 
written\n\
             to standard output.  Pathnames are listed once per file 
searched.\n\
             If the standard input is searched, the string ``(standard 
input)''\n\
-            is written.\n\
+            is written.  If --tree is specified, outputs directories in a\n\
+            tree-like format.\n\
     -l, --files-with-matches\n\
             Only the names of files containing selected lines are written to\n\
             standard output.  ugrep will only search a file until a match 
has\n\
             been found, making searches potentially less expensive.  
Pathnames\n\
             are listed once per file searched.  If the standard input is\n\
-            searched, the string ``(standard input)'' is written.\n\
+            searched, the string ``(standard input)'' is written.  If --tree 
is\n\
+            specified, outputs directories in a tree-like format.\n\
     --label=LABEL\n\
             Displays the LABEL value when input is read from standard input\n\
             where a file name would normally be printed in the output.\n\
@@ -12243,7 +12165,7 @@
             and --line-buffered.\n\
     --pretty\n\
             When output is sent to a terminal, enables --color, --heading, 
-n,\n\
-            --sort and -T when not explicitly disabled.\n\
+            --sort, --tree and -T when not explicitly disabled.\n\
     -Q[DELAY], --query[=DELAY]\n\
             Query mode: user interface to perform interactive searches.  
This\n\
             mode requires an ANSI capable terminal.  An optional DELAY 
argument\n\
@@ -12329,6 +12251,10 @@
     --tag[=TAG[,END]]\n\
             Disables colors to mark up matches with TAG.  END marks the end 
of\n\
             a match if specified, otherwise TAG.  The default is `___'.\n\
+    --tree, -^\n\
+            Output directories with matching files in a tree-like format 
when\n\
+            options -c, -l or -L are used.  This option is enabled by 
--pretty\n\
+            when the output is sent to a terminal.\n\
     -U, --binary\n\
             Disables Unicode matching for binary file matching, forcing 
PATTERN\n\
             to match bytes, not Unicode characters.  For example, -U '\\xa3'\n\
@@ -12572,9 +12498,9 @@
  %t          tab                         %[name]d    named capture byte size\n\
  %T %[...]T  ... + tab, if -T            %[name]e    named capture end 
offset\n\
  %u          unique lines, unless -u     %[n|...]#   capture n,... that 
matched\n\
- %v          matching pattern, as CSV    %[n|...]b   cpature n,... byte 
offset\n\
- %V          matching line, as CSV       %[n|...]d   cpature n,... byte size\n\
- %w          match width in wide chars   %[n|...]e   cpature n,... end 
offset\n\
+ %v          matching pattern, as CSV    %[n|...]b   capture n,... byte 
offset\n\
+ %V          matching line, as CSV       %[n|...]d   capture n,... byte size\n\
+ %w          match width in wide chars   %[n|...]e   capture n,... end 
offset\n\
  %x          matching pattern, as XML    %g          capture number or name\n\
  %X          matching line, as XML       %G          all capture 
numbers/names\n\
  %z          path in archive             %[t|...]g   text t indexed by 
capture\n\
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ugrep-3.9.7/src/ugrep.hpp 
new/ugrep-3.10.0/src/ugrep.hpp
--- old/ugrep-3.9.7/src/ugrep.hpp       2023-01-31 17:06:32.000000000 +0100
+++ new/ugrep-3.10.0/src/ugrep.hpp      2023-03-01 02:59:57.000000000 +0100
@@ -38,7 +38,7 @@
 #define UGREP_HPP
 
 // ugrep version
-#define UGREP_VERSION "3.9.7"
+#define UGREP_VERSION "3.10.0"
 
 // disable mmap because mmap is almost always slower than the file reading 
speed improvements since 3.0.0
 #define WITH_NO_MMAP

Reply via email to