@ 260915.5

210609.1 · b17614048bea532f23d3779e8d37e65bf4526743

released 3.3.2

improved UI and GNU grep compatibility

reading declarations

Dockerfile

@@ -15,7 +15,7 @@ RUN apt-get install -y \     make \     vim \     git \-    g\+\+ \+    clang \     wget \     unzip \     libpcre2-dev \

README.md

@@ -1043,9 +1043,8 @@ The configuration is written to standard output when `FILE` is a `-`.             Shift-Tab to navigate directories and to select a file to search.             Press Enter to select lines to output.  Press ALT-l for option -l             to list files, ALT-n for -n, etc.  Non-option commands include-            ALT-] to increase fuzziness and ALT-} to increase context.  Press-            F1 or CTRL-Z for help.  Enables --heading.  See also options-            --confirm and --view+            ALT-] to increase fuzziness and ALT-} to increase context.  Enables+            --heading.  See also options --confirm and --view.     --no-confirm             Do not confirm actions in -Q query mode.  The default is confirm.     --view[=COMMAND]@@ -4006,32 +4005,31 @@ in markdown:                   tories  and  to  select a file to search.  Press Enter to select                   lines to output.  Press ALT-l for option -l to list files, ALT-n                   for  -n,  etc.   Non-option  commands  include ALT-] to increase-                  fuzziness and ALT-} to increase context.  Press F1 or CTRL-Z for-                  help.   Enables  --heading.   See  also  options  --confirm  and-                  --view.+                  fuzziness and ALT-} to  increase  context.   Enables  --heading.+                  See also options --confirm and --view.             -q, --quiet, --silent                   Quiet mode: suppress all output.  ugrep will only search until a                   match has been found.             -R, --dereference-recursive-                  Recursively  read  all  files  under each directory.  Follow all-                  symbolic links, unlike -r.  When -J1  is  specified,  files  are+                  Recursively read all files under  each  directory.   Follow  all+                  symbolic  links,  unlike  -r.   When -J1 is specified, files are                   searched in the same order as specified.  Note that when no FILE-                  arguments are specified and  input  is  read  from  a  terminal,+                  arguments  are  specified  and  input  is  read from a terminal,                   recursive searches are performed as if -R is specified.             -r, --recursive-                  Recursively  read all files under each directory, following sym--                  bolic links only if they are on the command line.  When  -J1  is+                  Recursively read all files under each directory, following  sym-+                  bolic  links  only if they are on the command line.  When -J1 is                   specified, files are searched in the same order as specified.             -S, --dereference-                  If  -r  is  specified, all symbolic links are followed, like -R.+                  If -r is specified, all symbolic links are  followed,  like  -R.                   The default is not to follow symbolic links.             -s, --no-messages-                  Silent mode: nonexistent and unreadable files are ignored,  i.e.+                  Silent  mode: nonexistent and unreadable files are ignored, i.e.                   their error messages are suppressed.             --save-config[=FILE]@@ -4039,21 +4037,21 @@ in markdown:                   is a `-', write the configuration to standard output.             --separator[=SEP]-                  Use SEP as field separator between file name, line number,  col-+                  Use  SEP as field separator between file name, line number, col-                   umn number, byte offset, and the matched line.  The default is a                   colon (`:').             --sort[=KEY]-                  Displays matching files in the order specified by KEY in  recur-+                  Displays  matching files in the order specified by KEY in recur-                   sive searches.  KEY can be `name' to sort by pathname (default),-                  `best' to sort by best match with option -Z (sort by best  match-                  requires  two  passes  over  the input files), `size' to sort by+                  `best'  to sort by best match with option -Z (sort by best match+                  requires two passes over the input files),  `size'  to  sort  by                   file size, `used' to sort by last access time, `changed' to sort-                  by  last  modification  time,  and `created' to sort by creation-                  time.  Sorting  is  reversed  with  `rname',  `rbest',  `rsize',-                  `rused',  `rchanged',  or  `rcreated'.  Archive contents are not-                  sorted.  Subdirectories are sorted and displayed after  matching-                  files.   FILE arguments are searched in the same order as speci-+                  by last modification time, and `created'  to  sort  by  creation+                  time.   Sorting  is  reversed  with  `rname',  `rbest', `rsize',+                  `rused', `rchanged', or `rcreated'.  Archive  contents  are  not+                  sorted.   Subdirectories are sorted and displayed after matching+                  files.  FILE arguments are searched in the same order as  speci-                   fied.  Normally ugrep displays matches in no particular order to                   improve performance. @@ -4062,30 +4060,30 @@ in markdown:                   searched, and the inclusion and exclusion constraints applied.             -T, --initial-tab-                  Add a tab space to separate the file name, line  number,  column+                  Add  a  tab space to separate the file name, line number, column                   number, and byte offset with the matched line.             -t TYPES, --file-type=TYPES-                  Search  only files associated with TYPES, a comma-separated list-                  of file types.  Each file type corresponds to a set of  filename+                  Search only files associated with TYPES, a comma-separated  list+                  of  file types.  Each file type corresponds to a set of filename                   extensions passed to option -O.  For capitalized file types, the                   search is expanded to include files with matching file signature                   magic bytes, as if passed to option -M.  When a type is preceded-                  by a `!' or a `^', excludes files of the specified  type.   This-                  option  may  be repeated.  The possible file types can be (where-                  -tlist displays a detailed list): `actionscript', `ada',  `asm',-                  `asp',  `aspx',  `autoconf',  `automake', `awk', `Awk', `basic',+                  by  a  `!' or a `^', excludes files of the specified type.  This+                  option may be repeated.  The possible file types can  be  (where+                  -tlist  displays a detailed list): `actionscript', `ada', `asm',+                  `asp', `aspx', `autoconf', `automake',  `awk',  `Awk',  `basic',                   `batch', `bison', `c', `c++', `clojure', `csharp', `css', `csv',-                  `dart',  `Dart',  `delphi',  `elisp',  `elixir', `erlang', `for--                  tran', `gif', `Gif', `go', `groovy', `gsp',  `haskell',  `html',-                  `jade',  `java',  `jpeg',  `Jpeg', `js', `json', `jsp', `julia',-                  `kotlin', `less', `lex', `lisp',  `lua',  `m4',  `make',  `mark--                  down',  `matlab',  `node',  `Node',  `objc',  `objc++', `ocaml',-                  `parrot', `pascal', `pdf', `Pdf', `perl', `Perl', `php',  `Php',-                  `png',  `Png',  `prolog', `python', `Python', `r', `rpm', `Rpm',-                  `rst', `rtf', `Rtf', `ruby', `Ruby', `rust', `scala',  `scheme',-                  `shell',  `Shell',  `smalltalk',  `sql',  `svg', `swift', `tcl',-                  `tex', `text', `tiff', `Tiff',  `tt',  `typescript',  `verilog',+                  `dart', `Dart', `delphi',  `elisp',  `elixir',  `erlang',  `for-+                  tran',  `gif',  `Gif', `go', `groovy', `gsp', `haskell', `html',+                  `jade', `java', `jpeg', `Jpeg', `js',  `json',  `jsp',  `julia',+                  `kotlin',  `less',  `lex',  `lisp',  `lua', `m4', `make', `mark-+                  down', `matlab',  `node',  `Node',  `objc',  `objc++',  `ocaml',+                  `parrot',  `pascal', `pdf', `Pdf', `perl', `Perl', `php', `Php',+                  `png', `Png', `prolog', `python', `Python', `r',  `rpm',  `Rpm',+                  `rst',  `rtf', `Rtf', `ruby', `Ruby', `rust', `scala', `scheme',+                  `shell', `Shell', `smalltalk',  `sql',  `svg',  `swift',  `tcl',+                  `tex',  `text',  `tiff',  `Tiff', `tt', `typescript', `verilog',                   `vhdl', `vim', `xml', `Xml', `yacc', `yaml'.             --tabs[=NUM]@@ -4093,18 +4091,18 @@ in markdown:                   of NUM may be 1, 2, 4, or 8.  The default tab size is 8.             --tag[=TAG[,END]]-                  Disables colors to mark up matches with TAG.  END marks the  end+                  Disables  colors to mark up matches with TAG.  END marks the end                   of a match if specified, otherwise TAG.  The default is `___'.             -U, --binary                   Disables Unicode matching for binary file matching, forcing PAT--                  TERN to match bytes, not Unicode characters.   For  example,  -U-                  '\xa3'  matches  byte A3 (hex) instead of the Unicode code point+                  TERN  to  match  bytes, not Unicode characters.  For example, -U+                  '\xa3' matches byte A3 (hex) instead of the Unicode  code  point                   U+00A3 represented by the UTF-8 sequence C2 A3.  See also option                   --dotall.             -u, --ungroup-                  Do  not group multiple pattern matches on the same matched line.+                  Do not group multiple pattern matches on the same matched  line.                   Output the matched line again for each additional pattern match,                   using `+' as the field separator. @@ -4112,27 +4110,27 @@ in markdown:                   Display version information and exit.             -v, --invert-match-                  Selected  lines are those not matching any of the specified pat-+                  Selected lines are those not matching any of the specified  pat-                   terns.             --view[=COMMAND]-                  Use COMMAND to view/edit a file  in  query  mode  when  pressing+                  Use  COMMAND  to  view/edit  a  file in query mode when pressing                   CTRL-Y.             -W, --with-hex-                  Output  binary  matches  in  hexadecimal,  leaving  text matches+                  Output binary  matches  in  hexadecimal,  leaving  text  matches                   alone.  This option is equivalent to the --binary-files=with-hex                   option.             -w, --word-regexp-                  The  PATTERN  is  searched for as a word, such that the matching-                  text is preceded by a non-word character and is  followed  by  a-                  non-word  character.   Word  characters are letters, digits, and-                  the underscore.  With option -P,  word  characters  are  Unicode-                  letters,  digits,  and underscore.  This option has no effect if-                  -x is also specified.  If a PATTERN is specified, or -e  PATTERN-                  or  -N  PATTERN,  then this option has no effect on -f FILE pat--                  terns to allow -f FILE patterns to narrow or widen the scope  of+                  The PATTERN is searched for as a word, such  that  the  matching+                  text  is  preceded  by a non-word character and is followed by a+                  non-word character.  Word characters are  letters,  digits,  and+                  the  underscore.   With  option  -P, word characters are Unicode+                  letters, digits, and underscore.  This option has no  effect  if+                  -x  is also specified.  If a PATTERN is specified, or -e PATTERN+                  or -N PATTERN, then this option has no effect on  -f  FILE  pat-+                  terns  to allow -f FILE patterns to narrow or widen the scope of                   the PATTERN search.             -X, --hex@@ -4140,69 +4138,69 @@ in markdown:                   --binary-files=hex option.  See also option --hexdump.             -x, --line-regexp-                  Select only those matches that exactly match the whole line,  as-                  if  the  patterns  are  surrounded  by ^ and $.  If a PATTERN is-                  specified, or -e PATTERN or -N PATTERN, then this option has  no-                  effect  on  -f FILE patterns to allow -f FILE patterns to narrow+                  Select  only those matches that exactly match the whole line, as+                  if the patterns are surrounded by ^ and  $.   If  a  PATTERN  is+                  specified,  or -e PATTERN or -N PATTERN, then this option has no+                  effect on -f FILE patterns to allow -f FILE patterns  to  narrow                   or widen the scope of the PATTERN search. -           --xml  Output file matches in XML.  If -H, -n, -k, or -b is  specified,+           --xml  Output  file matches in XML.  If -H, -n, -k, or -b is specified,                   additional values are output.  See also options --format and -u.             -Y, --empty-                  Permits empty matches.  By default, empty matches are  disabled,-                  unless  a  pattern  begins with `^' or ends with `$'.  With this-                  option, empty-matching patterns such as x?  and  x*,  match  all+                  Permits  empty matches.  By default, empty matches are disabled,+                  unless a pattern begins with `^' or ends with  `$'.   With  this+                  option,  empty-matching  patterns  such  as x? and x*, match all                   input, not only lines containing the character `x'.             -y, --any-line                   Any matching or non-matching line is output.  Non-matching lines-                  are output with the `-' separator as  context  of  the  matching+                  are  output  with  the  `-' separator as context of the matching                   lines.  See also options -A, -B, and -C.             -Z[[+-~]MAX], --fuzzy[=[+-~]MAX]                   Fuzzy  mode:  report  approximate  pattern  matches  within  MAX-                  errors.  By default, MAX is 1: one deletion, insertion  or  sub--                  stitution  is  allowed.   When  `+' and/or `-' precede MAX, only+                  errors.   By  default, MAX is 1: one deletion, insertion or sub-+                  stitution is allowed.  When `+' and/or  `-'  precede  MAX,  only                   insertions and/or deletions are allowed, respectively.  When `~'-                  precedes  MAX,  substitution  counts as one error.  For example,-                  -Z+~3 allows up to three insertions  or  substitutions,  but  no-                  deletions.   The  first character of an approximate match always-                  matches the begin  of  a  pattern.   Option  --sort=best  orders-                  matching  files  by  best  match.   No  whitespace  may be given+                  precedes MAX, substitution counts as one  error.   For  example,+                  -Z+~3  allows  up  to  three insertions or substitutions, but no+                  deletions.  The first character of an approximate  match  always+                  matches  the  begin  of  a  pattern.   Option --sort=best orders+                  matching files by  best  match.   No  whitespace  may  be  given                   between -Z and its argument.             -z, --decompress-                  Decompress files to search, when compressed.   Archives  (.cpio,-                  .pax,  .tar  and .zip) and compressed archives (e.g. .taz, .tgz,-                  .tpz, .tbz, .tbz2, .tb2, .tz2, .tlz, .txz, .tzst)  are  searched-                  and  matching  pathnames  of  files  in  archives  are output in-                  braces.  If -g, -O, -M,  or  -t  is  specified,  searches  files-                  within  archives  whose  name  matches  globs, matches file name-                  extensions, matches file signature magic bytes, or matches  file+                  Decompress  files  to search, when compressed.  Archives (.cpio,+                  .pax, .tar and .zip) and compressed archives (e.g.  .taz,  .tgz,+                  .tpz,  .tbz,  .tbz2, .tb2, .tz2, .tlz, .txz, .tzst) are searched+                  and matching pathnames  of  files  in  archives  are  output  in+                  braces.   If  -g,  -O,  -M,  or  -t is specified, searches files+                  within archives whose name  matches  globs,  matches  file  name+                  extensions,  matches file signature magic bytes, or matches file                   types, respectively.  Supported compression formats: gzip (.gz),-                  compress (.Z), zip, bzip2 (requires suffix  .bz,  .bz2,  .bzip2,-                  .tbz,  .tbz2,  .tb2,  .tz2), lzma and xz (requires suffix .lzma,-                  .tlz, .xz, .txz), lz4 (requires  suffix  .lz4),  zstd  (requires+                  compress  (.Z),  zip,  bzip2 (requires suffix .bz, .bz2, .bzip2,+                  .tbz, .tbz2, .tb2, .tz2), lzma and xz  (requires  suffix  .lzma,+                  .tlz,  .xz,  .txz),  lz4  (requires suffix .lz4), zstd (requires                   suffix .zst, .zstd, .tzst).             -0, --null-                  Prints  a  zero-byte (NUL) after the file name.  This option can-                  be used with commands such as `find -print0' and `xargs  -0'  to+                  Prints a zero-byte (NUL) after the file name.  This  option  can+                  be  used  with commands such as `find -print0' and `xargs -0' to                   process arbitrary file names. -           A  `--' signals the end of options; the rest of the parameters are FILE+           A `--' signals the end of options; the rest of the parameters are  FILE            arguments, allowing filenames to begin with a `-' character.             Long options may start with `--no-' to disable, when applicable. -           The regular expression pattern syntax is an extended form of the  POSIX+           The  regular expression pattern syntax is an extended form of the POSIX            ERE syntax.  For an overview of the syntax see README.md or visit:                    https://github.com/Genivia/ugrep -           Note  that `.' matches any non-newline character.  Pattern `\n' matches-           a newline character.  Multiple lines may be matched with patterns  that+           Note that `.' matches any non-newline character.  Pattern `\n'  matches+           a  newline character.  Multiple lines may be matched with patterns that            match one or more newline characters.      EXIT STATUS@@ -4214,53 +4212,53 @@ in markdown:             >1     An error occurred. -           If  -q  or --quiet or --silent is used and a line is selected, the exit+           If -q or --quiet or --silent is used and a line is selected,  the  exit            status is 0 even if an error occurred.      CONFIGURATION-           The ug command is intended for context-dependent interactive  searching-           and  is  equivalent  to  the ugrep --config command to load the default+           The  ug command is intended for context-dependent interactive searching+           and is equivalent to the ugrep --config command  to  load  the  default            configuration file `.ugrep' when present in the working directory or in            the home directory.             A configuration file contains `NAME=VALUE' pairs per line, where `NAME`-           is the name of a long option (without `--') and `=VALUE'  is  an  argu--           ment,  which  is  optional  and may be omitted depending on the option.+           is  the  name  of a long option (without `--') and `=VALUE' is an argu-+           ment, which is optional and may be omitted  depending  on  the  option.            Empty lines and lines starting with a `#' are ignored. -           The --config=FILE option and its  abbreviated  form  ---FILE  load  the-           specified  configuration file located in the working directory or, when-           not found, located in the home directory.  An error  is  produced  when+           The  --config=FILE  option  and  its  abbreviated form ---FILE load the+           specified configuration file located in the working directory or,  when+           not  found,  located  in the home directory.  An error is produced when            FILE is not found or cannot be read. -           Command  line options are parsed in the following order: the configura--           tion file is loaded first, followed by the remaining options and  argu-+           Command line options are parsed in the following order: the  configura-+           tion  file is loaded first, followed by the remaining options and argu-            ments on the command line. -           The  --save-config  option  saves  a `.ugrep' configuration file to the-           working directory with a subset of the current  options.   The  --save--           config=FILE  option saves the configuration to FILE.  The configuration+           The --save-config option saves a `.ugrep'  configuration  file  to  the+           working  directory  with  a subset of the current options.  The --save-+           config=FILE option saves the configuration to FILE.  The  configuration            is written to standard output when FILE is a `-'.      GLOBBING-           Globbing is used by options -g,  --include,  --include-dir,  --include--           from,  --exclude,  --exclude-dir, --exclude-from to match pathnames and-           basenames in recursive searches.   Glob  arguments  for  these  options+           Globbing  is  used  by options -g, --include, --include-dir, --include-+           from, --exclude, --exclude-dir, --exclude-from to match  pathnames  and+           basenames  in  recursive  searches.   Glob  arguments for these options            should be quoted to prevent shell globbing. -           Globbing  supports  gitignore  syntax  and  the  corresponding matching-           rules.  When a glob ends in a path separator it matches directories  as+           Globbing supports  gitignore  syntax  and  the  corresponding  matching+           rules.   When a glob ends in a path separator it matches directories as            if --include-dir or --exclude-dir is specified.  When a glob contains a-           path separator `/', the full pathname is matched.  Otherwise the  base-+           path  separator `/', the full pathname is matched.  Otherwise the base-            name of a file or directory is matched.  For example, *.h matches foo.h-           and bar/foo.h.   bar/*.h  matches  bar/foo.h  but  not  foo.h  and  not-           bar/bar/foo.h.   Use a leading `/' to force /*.h to match foo.h but not+           and  bar/foo.h.   bar/*.h  matches  bar/foo.h  but  not  foo.h  and not+           bar/bar/foo.h.  Use a leading `/' to force /*.h to match foo.h but  not            bar/foo.h. -           When a glob starts with a `^' or a `!' as  in  -g^GLOB,  the  match  is+           When  a  glob  starts  with  a `^' or a `!' as in -g^GLOB, the match is            negated.  Likewise, a `!' (but not a `^') may be used with globs in the-           files specified --include-from, --exclude-from, and  --ignore-files  to-           negate  the  glob  match.  Empty lines or lines starting with a `#' are+           files  specified  --include-from, --exclude-from, and --ignore-files to+           negate the glob match.  Empty lines or lines starting with  a  `#'  are            ignored.             Glob Syntax and Conventions@@ -4275,12 +4273,12 @@ in markdown:             [!a-z] Matches one character not in the selected range of characters. -           /      When used at the begin of a glob, matches if pathname has no  /.+           /      When  used at the begin of a glob, matches if pathname has no /.                   When used at the end of a glob, matches directories only.             **/    Matches zero or more directories. -           /**    When  used at the end of a glob, matches everything after the /.+           /**    When used at the end of a glob, matches everything after the  /.             \?     Matches a ? (or any character specified after the backslash). @@ -4317,46 +4315,46 @@ in markdown:             a\?b   Matches a?b,                 but not a, b, ab, axb, a/b -           Note that exclude glob patterns take priority over  include  glob  pat--           terns   when  specified  with  options  -g,  --exclude,  --exclude-dir,+           Note  that  exclude  glob patterns take priority over include glob pat-+           terns  when  specified  with  options  -g,  --exclude,   --exclude-dir,            --include and include-dir. -           Glob patterns specified with prefix `!' in any of the files  associated-           with  --include-from,  --exclude-from  and --ignore-files will negate a-           previous glob match.  That is, any matching file or directory  excluded-           by  a  previous  glob  pattern  specified  in the files associated with-           --exclude-from or --ignore-file will become included again.   Likewise,-           any  matching  file  or  directory  included by a previous glob pattern-           specified in the  files  associated  with  --include-from  will  become+           Glob  patterns specified with prefix `!' in any of the files associated+           with --include-from, --exclude-from and --ignore-files  will  negate  a+           previous  glob match.  That is, any matching file or directory excluded+           by a previous glob pattern  specified  in  the  files  associated  with+           --exclude-from  or --ignore-file will become included again.  Likewise,+           any matching file or directory included  by  a  previous  glob  pattern+           specified  in  the  files  associated  with  --include-from will become            excluded again.      ENVIRONMENT            GREP_PATH-                  May  be  used to specify a file path to pattern files.  The file-                  path is used by option -f to open a pattern file, when the  pat-+                  May be used to specify a file path to pattern files.   The  file+                  path  is used by option -f to open a pattern file, when the pat-                   tern file does not exist.             GREP_COLOR-                  May  be used to specify ANSI SGR parameters to highlight matches-                  when option --color is used, e.g. 1;35;40 shows pattern  matches+                  May be used to specify ANSI SGR parameters to highlight  matches+                  when  option --color is used, e.g. 1;35;40 shows pattern matches                   in bold magenta text on a black background.  Deprecated in favor                   of GREP_COLORS, but still supported.             GREP_COLORS-                  May be used to specify ANSI SGR parameters to highlight  matches-                  and  other attributes when option --color is used.  Its value is-                  a colon-separated list of ANSI SGR parameters that  defaults  to+                  May  be used to specify ANSI SGR parameters to highlight matches+                  and other attributes when option --color is used.  Its value  is+                  a  colon-separated  list of ANSI SGR parameters that defaults to                   cx=33:mt=1;31:fn=1;35:ln=1;32:cn=1;32:bn=1;32:se=36.   The  mt=,-                  ms=, and mc= capabilities  of  GREP_COLORS  take  priority  over+                  ms=,  and  mc=  capabilities  of  GREP_COLORS take priority over                   GREP_COLOR.  Option --colors takes priority over GREP_COLORS.      GREP_COLORS-           Colors  are  specified as string of colon-separated ANSI SGR parameters-           of the form `what=substring', where `substring'  is  a  semicolon-sepa--           rated  list  of  ANSI SGR codes or `k' (black), `r' (red), `g' (green),-           `y' (yellow), `b' (blue),  `m'  (magenta),  `c'  (cyan),  `w'  (white).-           Upper  case  specifies  background  colors.  A `+' qualifies a color as-           bright.  A foreground and a background color may be combined  with  one+           Colors are specified as string of colon-separated ANSI  SGR  parameters+           of  the  form  `what=substring', where `substring' is a semicolon-sepa-+           rated list of ANSI SGR codes or `k' (black), `r'  (red),  `g'  (green),+           `y'  (yellow),  `b'  (blue),  `m'  (magenta),  `c' (cyan), `w' (white).+           Upper case specifies background colors.  A `+'  qualifies  a  color  as+           bright.   A  foreground and a background color may be combined with one            or more font properties `n' (normal), `f' (faint), `h' (highlight), `i'            (invert), `u' (underline).  Substrings may be specified for: @@ -4368,10 +4366,10 @@ in markdown:             mt=    SGR substring for matching text in any matching line. -           ms=    SGR substring for matching text in a selected  line.   The  sub-+           ms=    SGR  substring  for  matching text in a selected line.  The sub-                   string mt= by default. -           mc=    SGR  substring  for  matching  text in a context line.  The sub-+           mc=    SGR substring for matching text in a  context  line.   The  sub-                   string mt= by default.             fn=    SGR substring for filenames.@@ -4386,12 +4384,12 @@ in markdown:             rv     a Boolean parameter, switches sl= and cx= with option -v. -           hl     a Boolean parameter, enables filename hyperlinks  (\33]8;;link).+           hl     a  Boolean parameter, enables filename hyperlinks (\33]8;;link).             ne     a Boolean parameter, disables ``erase in line'' \33[K.      FORMAT-           Option  --format=FORMAT  specifies  an  output format for file matches.+           Option --format=FORMAT specifies an output  format  for  file  matches.            Fields may be used in FORMAT, which expand into the following values:             %[ARG]F@@ -4490,7 +4488,7 @@ in markdown:             %u     select unique lines only, unless option -u is used. -           %1     the  first  regex  group  capture  of the match, and so on up to+           %1     the first regex group capture of the match,  and  so  on  up  to                   group %9, same as %[1]#; requires option -P.             %[NUM]#@@ -4500,24 +4498,24 @@ in markdown:                   the first group capture NUM that matched; requires option -P.             %[NAME]#-                  the NAMEd group capture; requires option -P and  capturing  pat-+                  the  NAMEd  group capture; requires option -P and capturing pat-                   tern `(?<NAME>PATTERN)', see also %G.             %[NAME1|NAME2|...]#-                  the  first  NAMEd group capture that matched; requires option -P+                  the first NAMEd group capture that matched; requires  option  -P                   and capturing pattern `(?<NAME>PATTERN)', see also %G. -           %G     list of  group  capture  indices/names  that  matched;  requires+           %G     list  of  group  capture  indices/names  that  matched; requires                   option -P.             %[TEXT1|TEXT2|...]G-                  list  of  TEXT  indexed  by  group capture indices that matched;+                  list of TEXT indexed by  group  capture  indices  that  matched;                   requires option -P.             %g     the group capture index/name matched or 1; requires option -P.             %[TEXT1|TEXT2|...]g-                  the first TEXT indexed by the first  group  capture  index  that+                  the  first  TEXT  indexed  by the first group capture index that                   matched; requires option -P.             %%     the percentage sign.@@ -4525,22 +4523,22 @@ in markdown:            Formatted output is written without a terminating newline, unless %~ or            `\n' is explicitly specified in the format string. -           The [ARG] part of a  field  is  optional  and  may  be  omitted.   When-           present,  the argument must be placed in [] brackets, for example %[,]F+           The  [ARG]  part  of  a  field  is  optional  and may be omitted.  When+           present, the argument must be placed in [] brackets, for example  %[,]F            to output a comma, the pathname, and a separator.             %[SEP]$ and %u are switches and do not send anything to the output. -           The separator used by the %F, %H, %N, %K, %B, %S and %G fields  may  be+           The  separator  used by the %F, %H, %N, %K, %B, %S and %G fields may be            changed by preceding the field by %[SEP]$.  When [SEP] is not provided,-           this reverts the separator to the default separator  or  the  separator+           this  reverts  the  separator to the default separator or the separator            specified with --separator.             Formatted output is written for each matching pattern, which means that-           a line may be output multiple times when patterns match more than  once-           on  the  same  line.   If  field  %u  is specified anywhere in a format+           a  line may be output multiple times when patterns match more than once+           on the same line.  If field  %u  is  specified  anywhere  in  a  format            string,  matching  lines  are  output  only  once,  unless  option  -u,-           --ungroup  is specified or when more than one line of input matched the+           --ungroup is specified or when more than one line of input matched  the            search pattern.             Additional formatting options:@@ -4557,8 +4555,8 @@ in markdown:            --format-end=FORMAT                   the FORMAT when ending the search. -           The context options -A,  -B,  -C,  -y,  and  display  options  --break,-           --heading,  --color, -T, and --null have no effect on formatted output.+           The  context  options  -A,  -B,  -C,  -y,  and display options --break,+           --heading, --color, -T, and --null have no effect on formatted  output.      EXAMPLES            Display lines containing the word `patricia' in `myfile.txt':@@ -4619,7 +4617,7 @@ in markdown:                    $ ugrep -n -f c++/comments myfile.cpp -           List  the  lines that need fixing in a C/C++ source file by looking for+           List the lines that need fixing in a C/C++ source file by  looking  for            the word `FIXME' while skipping any `FIXME' in quoted strings:                    $ ugrep -e FIXME -N '"(\\.|\\\r?\n|[^\\\n"])*"' myfile.cpp@@ -4649,7 +4647,7 @@ in markdown:                    $ ugrep -z -tc++ -n FIXME project.tgz -           Recursively find lines with `FIXME' in C/C++ files, but do  not  search+           Recursively  find  lines with `FIXME' in C/C++ files, but do not search            any `bak' and `old' directories:                    $ ugrep -n FIXME -tc++ -g^bak/,^old/@@ -4659,9 +4657,9 @@ in markdown:                    $ ugrep -z -w --filter='pdf:pdftotext % -' copyright -           Match the binary pattern `A3hhhhA3hh' (hex) in a  binary  file  without-           Unicode  pattern  matching  -U (which would otherwise match `\xaf' as a-           Unicode character U+00A3 with UTF-8 byte sequence C2  A3)  and  display+           Match  the  binary  pattern `A3hhhhA3hh' (hex) in a binary file without+           Unicode pattern matching -U (which would otherwise match  `\xaf'  as  a+           Unicode  character  U+00A3  with UTF-8 byte sequence C2 A3) and display            the results in hex with -X using `less -R' as a pager:                    $ ugrep --pager -UXo '\xa3[\x00-\xff]{2}\xa3[\x00-\xff]' a.out@@ -4674,12 +4672,12 @@ in markdown:                    $ ugrep -l '' --ignore-files -           List  all files containing a RPM signature, located in the `rpm' direc-+           List all files containing a RPM signature, located in the `rpm'  direc-            tory and recursively below up to two levels deeper (3 levels total):                    $ ugrep -3 -l -tRpm '' rpm/ -           Monitor the system log for bug reports and ungroup multiple matches  on+           Monitor  the system log for bug reports and ungroup multiple matches on            a line:                    $ tail -f /var/log/system.log | ugrep -u -i -w bug@@ -4703,8 +4701,8 @@ in markdown:       LICENSE-           ugrep  is  released under the BSD-3 license.  All parts of the software-           have reasonable copyright terms permitting free  redistribution.   This+           ugrep is released under the BSD-3 license.  All parts of  the  software+           have  reasonable  copyright terms permitting free redistribution.  This            includes the ability to reuse all or parts of the ugrep source tree.      SEE ALSO@@ -4712,7 +4710,7 @@ in markdown:   -    ugrep 3.3.1                      June 03, 2021                        UGREP(1)+    ugrep 3.3.2                      June 09, 2021                        UGREP(1)  🔝 [Back to table of contents](#toc) 

bin/win32/ugrep.exe

Binary file changed

bin/win64/ugrep.exe

Binary file changed

build.sh

@@ -12,10 +12,9 @@ echo echo "Building ugrep..."  # configure with the specified command arguments-OPTIONS=$@  echo-echo "./configure $OPTIONS"+echo "./configure $@" echo  # appease automake when the original timestamps are lost, when using git clone@@ -25,7 +24,11 @@ touch config.h.in Makefile.in lib/Makefile.in src/Makefile.in sleep 1 touch configure -./configure $OPTIONS+if ! ./configure "$@" ; then+echo "Failed to complete ./configure $@"+echo "See config.log for more details"+exit 1+fi  echo echo "make -j clean all"

configure

@@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles.-# Generated by GNU Autoconf 2.69 for ugrep 3.0.+# Generated by GNU Autoconf 2.69 for ugrep 3.3. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.@@ -579,8 +579,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ugrep' PACKAGE_TARNAME='ugrep'-PACKAGE_VERSION='3.0'-PACKAGE_STRING='ugrep 3.0'+PACKAGE_VERSION='3.3'+PACKAGE_STRING='ugrep 3.3' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1313,7 +1313,7 @@ if test "$ac_init_help" = "long"; then   # Omit some internal or obsolete options to make the list less imposing.   # This message is too long to be a string in the A/UX 3.1 sh.   cat <<_ACEOF-\`configure' configures ugrep 3.0 to adapt to many kinds of systems.+\`configure' configures ugrep 3.3 to adapt to many kinds of systems.  Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1383,7 +1383,7 @@ fi  if test -n "$ac_init_help"; then   case $ac_init_help in-     short | recursive ) echo "Configuration of ugrep 3.0:";;+     short | recursive ) echo "Configuration of ugrep 3.3:";;    esac   cat <<\_ACEOF @@ -1421,8 +1421,9 @@ Optional Packages:   --without-pcre2         to disable PCRE2 usage completely   --with-boost-regex[=special-lib]                           use the Regex library from boost - it is possible to-                          specify a certain library for the linker e.g.-                          --with-boost-regex=boost_regex-gcc-mt-d-1_33_1+                          specify a path to include/boost and+                          lib/libboost_regex-mt e.g.+                          --with-boost-regex=/opt/local   --with-zlib=DIR         root directory path of zlib installation [defaults to                           /usr/local or /usr if not found in /usr/local]   --without-zlib          to disable zlib usage completely@@ -1524,7 +1525,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then   cat <<\_ACEOF-ugrep configure 3.0+ugrep configure 3.3 generated by GNU Autoconf 2.69  Copyright (C) 2012 Free Software Foundation, Inc.@@ -2241,7 +2242,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by ugrep $as_me 3.0, which was+It was created by ugrep $as_me 3.3, which was generated by GNU Autoconf 2.69.  Invocation command line was    $ $0 $@@@ -3107,7 +3108,7 @@ fi  # Define the identity of the package.  PACKAGE='ugrep'- VERSION='3.0'+ VERSION='3.3'   cat >>confdefs.h <<_ACEOF@@ -3208,6 +3209,7 @@ ac_config_headers="$ac_config_headers config.h"  # if CXXFLAGS is undefined, set it to our preferred default flags : ${CXXFLAGS="-Wall -Wextra -Wunused -O2"}+: ${CFLAGS="-Wall -Wextra -Wunused -O2"}  ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS'@@ -6959,10 +6961,12 @@ $as_echo "#define HAVE_PCRE2 1" >>confdefs.h     # If either header or library was not found, action-if-not-found     #     echo "checking for Boost.Regex because PCRE2 is not usable"+   fi fi  +if test "x$pcre2_cv_libpcre2" != "xyes" || test "x$pcre2_cv_pcre2_h" != "xyes"; then   # Check whether --with-boost-regex was given.@@ -6972,23 +6976,29 @@ if test "${with_boost_regex+set}" = set; then :             want_boost="no"         elif test "$withval" = "yes"; then             want_boost="yes"-            ax_boost_regex_lib="-lboost_regex"+            ax_boost_regex_lib="-lboost_regex-mt"         else             want_boost="yes"-            ax_boost_regex_lib="$withval"+            BOOST_REGEX_HOME="$withval"+            ax_boost_regex_lib="-lboost_regex-mt"         fi  else          want_boost="yes"-        ax_boost_regex_lib="-lboost_regex"+        ax_boost_regex_lib="-lboost_regex-mt"   fi       if test "x$want_boost" = "xyes"; then-+        BOOST_REGEX_OLD_LDFLAGS=$LDFLAGS+        BOOST_REGEX_OLD_CPPFLAGS=$CPPFLAGS+        if test -n "${BOOST_REGEX_HOME}"; then+            CPPFLAGS="$LDFLAGS -L${BOOST_REGEX_HOME}/lib"+            CPPFLAGS="$CPPFLAGS -I${BOOST_REGEX_HOME}/include"+        fi          { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the Boost::Regex library is available" >&5 $as_echo_n "checking whether the Boost::Regex library is available... " >&6; }@@ -7034,9 +7044,13 @@ $as_echo "$ax_cv_boost_regex" >&6; } $as_echo "#define HAVE_BOOST_REGEX 1" >>confdefs.h              LIBS="$LIBS $ax_boost_regex_lib"+        else+            LDFLAGS=$BOOST_REGEX_OLD_LDFLAGS+            CPPFLAGS=$BOOST_REGEX_OLD_CPPFLAGS         fi     fi +fi  ac_ext=c ac_cpp='$CPP $CPPFLAGS'@@ -8752,7 +8766,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log="-This file was extended by ugrep $as_me 3.0, which was+This file was extended by ugrep $as_me 3.3, which was generated by GNU Autoconf 2.69.  Invocation command line was    CONFIG_FILES    = $CONFIG_FILES@@ -8818,7 +8832,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\-ugrep config.status 3.0+ugrep config.status 3.3 configured by $0, generated by GNU Autoconf 2.69,   with options \\"\$ac_cs_config\\" 

configure.ac

@@ -1,4 +1,4 @@-AC_INIT(ugrep,3.0)+AC_INIT(ugrep,3.3) AM_INIT_AUTOMAKE([foreign]) AM_CONFIG_HEADER(config.h) AC_COPYRIGHT([Copyright (C) 2019-2020 Robert van Engelen, Genivia Inc.])@@ -7,6 +7,7 @@ AC_CONFIG_MACRO_DIR([m4])  # if CXXFLAGS is undefined, set it to our preferred default flags : ${CXXFLAGS="-Wall -Wextra -Wunused -O2"}+: ${CFLAGS="-Wall -Wextra -Wunused -O2"}  AC_LANG([C++]) AX_CXX_COMPILE_STDCXX_11([ext], [mandatory])@@ -62,9 +63,14 @@ AC_TRY_COMPILE([ ], AC_MSG_RESULT(no) ) -AX_CHECK_PCRE2([8], [], [echo "checking for Boost.Regex because PCRE2 is not usable"])+AX_CHECK_PCRE2([8],+[],+[echo "checking for Boost.Regex because PCRE2 is not usable"]+) -AX_BOOST_REGEX+if test "x$pcre2_cv_libpcre2" != "xyes" || test "x$pcre2_cv_pcre2_h" != "xyes"; then+  AX_BOOST_REGEX+fi  AX_CHECK_ZLIB([], [echo "zlib not found: ugrep option -z is not available"]) 

include/reflex/pattern.h

@@ -869,7 +869,7 @@ class Pattern {       Char  hi,       Index index)   {-    return is_meta(lo) ? (lo << 24) | index : (lo << 24) | (hi << 16) | index;+    return is_meta(lo) ? (static_cast<Opcode>(lo) << 24) | index : (static_cast<Opcode>(lo) << 24) | (hi << 16) | index;   }   static inline Opcode opcode_halt()   {

lib/error.cpp

@@ -111,7 +111,7 @@ size_t regex_error::displen(const char *s, size_t k)         ++n;         if (k < 4)           break;-        s += 3;+        s += (s[0] != '\0') + (s[1] != '\0') + (s[2] != 0);         k -= 3;       }       else@@ -147,7 +147,7 @@ const char *regex_error::disppos(const char *s, size_t k)         // U+1F18E (UTF-8 F0 9F 86 8E) and higher is usually double width         if (k < 4)           break;-        s += ((s[0] != '\0') && (s[1] != '\0') && (s[2] != '\0'));+        s += (s[0] != '\0') + (s[1] != '\0') + (s[2] != 0);         k -= 3;       }       else

m4/ax_boost_regex.m4

@@ -13,7 +13,7 @@ # #   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> #   Copyright (c) 2008 Michael Tindal-#   Copyright (c) 2019 Robert van Engelen <engelen@acm.org>+#   Copyright (c) 2021 Robert van Engelen <engelen@acm.org> # #   Copying and distribution of this file, with or without modification, are #   permitted in any medium without royalty provided the copyright notice@@ -24,40 +24,50 @@ AC_DEFUN([AX_BOOST_REGEX], [     AC_ARG_WITH([boost-regex],     AS_HELP_STRING([--with-boost-regex@<:@=special-lib@:>@],-                   [use the Regex library from boost - it is possible to specify a certain library for the linker-                        e.g. --with-boost-regex=boost_regex-gcc-mt-d-1_33_1 ]),+                   [use the Regex library from boost - it is possible to specify a path to include/boost and lib/libboost_regex-mt+                        e.g. --with-boost-regex=/opt/local ]),         [         if test "$withval" = "no"; then             want_boost="no"         elif test "$withval" = "yes"; then             want_boost="yes"-            ax_boost_regex_lib="-lboost_regex"+            ax_boost_regex_lib="-lboost_regex-mt"         else             want_boost="yes"-            ax_boost_regex_lib="$withval"+            BOOST_REGEX_HOME="$withval"+            ax_boost_regex_lib="-lboost_regex-mt"         fi         ],         [         want_boost="yes"-        ax_boost_regex_lib="-lboost_regex"+        ax_boost_regex_lib="-lboost_regex-mt"         ]     )      if test "x$want_boost" = "xyes"; then+        BOOST_REGEX_OLD_LDFLAGS=$LDFLAGS+        BOOST_REGEX_OLD_CPPFLAGS=$CPPFLAGS+        if test -n "${BOOST_REGEX_HOME}"; then+            CPPFLAGS="$LDFLAGS -L${BOOST_REGEX_HOME}/lib"+            CPPFLAGS="$CPPFLAGS -I${BOOST_REGEX_HOME}/include"+        fi         AC_REQUIRE([AC_PROG_CC])--        AC_CACHE_CHECK(whether the Boost::Regex library is available,-                       ax_cv_boost_regex,+        AC_CACHE_CHECK([whether the Boost::Regex library is available],+                       [ax_cv_boost_regex],         [AC_LANG_PUSH([C++])              AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/regex.hpp>                                                 ]],                                    [[boost::regex r(); return 0;]])],-                   ax_cv_boost_regex=yes, ax_cv_boost_regex=no)+                   [ax_cv_boost_regex=yes],+                   [ax_cv_boost_regex=no])          AC_LANG_POP([C++])         ])         if test "x$ax_cv_boost_regex" = "xyes"; then             AC_DEFINE(HAVE_BOOST_REGEX,1,[define if the Boost::Regex library is available])             LIBS="$LIBS $ax_boost_regex_lib"+        else+            LDFLAGS=$BOOST_REGEX_OLD_LDFLAGS+            CPPFLAGS=$BOOST_REGEX_OLD_CPPFLAGS         fi     fi ])

man/ugrep.1

@@ -1,4 +1,4 @@-.TH UGREP "1" "June 03, 2021" "ugrep 3.3.1" "User Commands"+.TH UGREP "1" "June 09, 2021" "ugrep 3.3.2" "User Commands" .SH NAME \fBugrep\fR, \fBug\fR -- file pattern searcher .SH SYNOPSIS@@ -541,9 +541,8 @@ environment variable PAGER if defined, or EDITOR.  Press Tab and Shift\-Tab to navigate directories and to select a file to search. Press Enter to select lines to output.  Press ALT\-l for option \fB\-l\fR to list files, ALT\-n for \fB\-n\fR, etc.  Non\-option commands include-ALT\-] to increase fuzziness and ALT\-} to increase context.  Press-F1 or CTRL\-Z for help.  Enables \fB\-\-heading\fR.  See also options-\fB\-\-confirm\fR and \fB\-\-view\fR.+ALT\-] to increase fuzziness and ALT\-} to increase context.  Enables+\fB\-\-heading\fR.  See also options \fB\-\-confirm\fR and \fB\-\-view\fR. .TP \fB\-q\fR, \fB\-\-quiet\fR, \fB\-\-silent\fR Quiet mode: suppress all output.  ugrep will only search until a

src/query.cpp

@@ -226,16 +226,29 @@ void Query::draw()   {     if (select_ == -1)     {+      start_ = 0;       Screen::home(); -      start_ = static_cast<int>(prompt_.size());+      if (row_ > 0)+      {+        char down[16];++        snprintf(down, sizeof(down), "%3d ", row_);++        if (!Screen::mono)+          Screen::put(PROMPT);+        Screen::put(down);++        start_ = strlen(down);+      }        if (!dirs_.empty())       {         int width = Screen::mbstring_width(dirs_.c_str());         int offset = 0;-        if (width + 2 > Screen::cols/2)-          offset = width + 2 - Screen::cols/2;+        int split = Screen::cols/2 - start_;+        if (width + 2 > split)+          offset = width + 2 - split;          Screen::normal();         if (offset > 0)@@ -261,6 +274,8 @@ void Query::draw()        Screen::normal(); +      start_ += static_cast<int>(prompt_.size());+       int pos;       if (len_ - col_ < shift_)         pos = Screen::cols - start_ - (len_ - col_) - 1;@@ -401,7 +416,7 @@ void Query::draw() }  // view one row of text by drawing it on screen-void Query::view(int row)+void Query::disp(int row) {   Screen::normal();   if (selected_[row])@@ -509,7 +524,7 @@ void Query::redraw()     if (end > row_ + Screen::rows - 1)       end = row_ + Screen::rows - 1;     for (int i = row_; i < end; ++i)-      view(i);+      disp(i);     if (!message_)       draw();   }@@ -920,7 +935,7 @@ void Query::query_ui()             else             {               selected_[select_] = !selected_[select_];-              view(select_);+              disp(select_);               down();             }           }@@ -1036,7 +1051,7 @@ void Query::query_ui()             {               up();               selected_[select_] = !selected_[select_];-              view(select_);+              disp(select_);             }           }           else if (mode_ == Mode::EDIT)@@ -1063,7 +1078,7 @@ void Query::query_ui()           {             up();             selected_[select_] = !selected_[select_];-            view(select_);+            disp(select_);           }           break; @@ -1395,7 +1410,7 @@ bool Query::update()       begin = row_;      for (int i = begin; i < end; ++i)-      view(i);+      disp(i);   }    // display final status line if in view@@ -1733,7 +1748,7 @@ void Query::up()   }   if (row_ > 0)   {-    view(row_ - 1);+    disp(row_ - 1);     --row_;     Screen::pan_down();     draw();@@ -1758,7 +1773,7 @@ void Query::down()     Screen::normal();     Screen::pan_up();     if (row_ + Screen::rows - 2 < rows_)-      view(row_ + Screen::rows - 2);+      disp(row_ + Screen::rows - 2);     draw();   } }@@ -1780,7 +1795,7 @@ void Query::pgup(bool half_page)   }   if (row_ > 0)   {-    view(row_ - 1);+    disp(row_ - 1);     int oldrow = row_;     if (half_page)       row_ -= Screen::rows / 2;@@ -1790,7 +1805,7 @@ void Query::pgup(bool half_page)       row_ = 0;     Screen::pan_down(oldrow - row_);     for (int i = row_; i < oldrow - 1; ++i)-      view(i);+      disp(i);     draw();   } }@@ -1830,7 +1845,7 @@ void Query::pgdn(bool half_page)       Screen::pan_up(diff);       for (int i = row_ + Screen::rows - diff - 1; i < row_ + Screen::rows - 1; ++i)         if (i < rows_)-          view(i);+          disp(i);       draw();     }   }@@ -2090,6 +2105,12 @@ void Query::view()     return;   } +  if (flag_stdin)+  {+    message("cannot view or edit standard input");+    return;+  }+   const char *pager = flag_view;    if (pager != NULL && *pager == '\0')@@ -2098,6 +2119,9 @@ void Query::view()      if (pager == NULL)       pager = getenv("EDITOR");++    if (pager == NULL)+      pager = DEFAULT_VIEW_COMMAND;   }    if (pager == NULL || *pager == '\0')@@ -2185,6 +2209,7 @@ void Query::view()       }     }   }+   if (!found)     message(std::string("cannot edit file ").append(filename)); }

src/query.hpp

@@ -112,6 +112,8 @@ class Query {      bool restore(Line& line_, int& col_, int& row_, Flags flags_[])     {+      row_ = 0;+       if (row < 0)         return false; @@ -176,7 +178,7 @@ class Query {    static void draw(); -  static void view(int row);+  static void disp(int row);    static void redraw(); 

src/ugrep.cpp

@@ -68,12 +68,6 @@ After this, you may want to test ugrep and install it (optional):  */ -// ugrep version-#define UGREP_VERSION "3.3.1"--// disable mmap because mmap is almost always slower than the file reading speed improvements since 3.0.0-#define WITH_NO_MMAP- #include "ugrep.hpp" #include "glob.hpp" #include "mmap.hpp"@@ -157,67 +151,6 @@ After this, you may want to test ugrep and install it (optional): # include "zstream.hpp" #endif -// use a task-parallel thread to decompress the stream into a pipe to search, handles archives and increases decompression speed for larger files-#define WITH_DECOMPRESSION_THREAD--// drain stdin until eof - this is disabled for speed, almost all utilities handle SIGPIPE these days anyway-// #define WITH_STDIN_DRAIN--// the default GREP_COLORS-#ifndef DEFAULT_GREP_COLORS-# ifdef OS_WIN-#  define DEFAULT_GREP_COLORS "sl=1;37:cx=33:mt=1;31:fn=1;35:ln=1;32:cn=1;32:bn=1;32:se=36"-# else-#  define DEFAULT_GREP_COLORS "cx=33:mt=1;31:fn=1;35:ln=1;32:cn=1;32:bn=1;32:se=36"-# endif-#endif--// the default --tabs-#ifndef DEFAULT_TABS-# define DEFAULT_TABS 8-#endif--// the default --tag-#ifndef DEFAULT_TAG-# define DEFAULT_TAG "___"-#endif--// the default pager command when --pager is used-#ifndef DEFAULT_PAGER_COMMAND-# ifdef OS_WIN-#  define DEFAULT_PAGER_COMMAND "more"-# else-#  define DEFAULT_PAGER_COMMAND "less -R"-# endif-#endif--// the default ignore file-#ifndef DEFAULT_IGNORE_FILE-# define DEFAULT_IGNORE_FILE ".gitignore"-#endif--// color is disabled by default, unless enabled with WITH_COLOR-#ifdef WITH_COLOR-# define DEFAULT_COLOR "auto"-#else-# define DEFAULT_COLOR NULL-#endif--// pager is disabled by default, unless enabled with WITH_PAGER-#ifdef WITH_PAGER-# define DEFAULT_PAGER DEFAULT_PAGER_COMMAND-#else-# define DEFAULT_PAGER NULL-#endif--// enable easy-to-use abbreviated ANSI SGR color codes with WITH_EASY_GREP_COLORS-// semicolons are not required and abbreviations can be mixed with numeric ANSI SGR codes-// foreground colors: k=black, r=red, g=green, y=yellow b=blue, m=magenta, c=cyan, w=white-// background colors: K=black, R=red, G=green, Y=yellow B=blue, M=magenta, C=cyan, W=white-// bright colors: +k, +r, +g, +y, +b, +m, +c, +w, +K, +R, +G, +Y, +B, +M, +C, +W-// modifiers: h=highlight, u=underline, i=invert, f=faint, n=normal, H=highlight off, U=underline off, I=invert off-#define WITH_EASY_GREP_COLORS- // ugrep exit codes #define EXIT_OK    0 // One or more lines were selected #define EXIT_FAIL  1 // No lines were selected@@ -243,37 +176,6 @@ After this, you may want to test ugrep and install it (optional): # define MIN_STEAL 3U #endif -// default --mmap-#define DEFAULT_MIN_MMAP_SIZE MIN_MMAP_SIZE--// default --max-mmap: mmap is disabled by default with WITH_NO_MMAP-#ifdef WITH_NO_MMAP-# define DEFAULT_MAX_MMAP_SIZE 0-#else-# define DEFAULT_MAX_MMAP_SIZE MAX_MMAP_SIZE-#endif--// pretty is disabled by default, unless enabled with WITH_PRETTY-#ifdef WITH_PRETTY-# define DEFAULT_PRETTY true-#else-# define DEFAULT_PRETTY false-#endif--// hidden file and directory search is enabled by default, unless disabled with WITH_HIDDEN-#ifdef WITH_HIDDEN-# define DEFAULT_HIDDEN true-#else-# define DEFAULT_HIDDEN false-#endif--// do not confirm query UI actions-#ifdef WITH_NO_CONFIRM-# define DEFAULT_CONFIRM false-#else-# define DEFAULT_CONFIRM true-#endif- // use dirent d_type when available to improve performance #ifdef HAVE_STRUCT_DIRENT_D_TYPE # define DIRENT_TYPE_UNKNOWN DT_UNKNOWN@@ -844,11 +746,12 @@ struct Grep {   // extend the reflex::AbstractMatcher::Handler with a grep object reference and references to some of the grep::search locals   struct GrepHandler : public reflex::AbstractMatcher::Handler { -    GrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& hex, bool& binary, size_t& matches, bool& stop)+    GrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& binfile, bool& hex, bool& binary, size_t& matches, bool& stop)       :         grep(grep),         pathname(pathname),         lineno(lineno),+        binfile(binfile),         hex(hex),         binary(binary),         matches(matches),@@ -858,6 +761,7 @@ struct Grep {     Grep&        grep;     // grep object     const char*& pathname; // grep::search argument pathname     size_t&      lineno;   // grep::search lineno local variable+    bool&        binfile;  // grep::search binfile local variable     bool&        hex;      // grep::search hex local variable     bool&        binary;   // grep::search binary local variable     size_t&      matches;  // grep::search matches local variable@@ -936,9 +840,9 @@ struct Grep {   // extend event GrepHandler to output invert match lines for -v   struct InvertMatchGrepHandler : public GrepHandler { -    InvertMatchGrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& hex, bool& binary, size_t& matches, bool& stop)+    InvertMatchGrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& binfile, bool& hex, bool& binary, size_t& matches, bool& stop)       :-        GrepHandler(grep, pathname, lineno, hex, binary, matches, stop)+        GrepHandler(grep, pathname, lineno, binfile, hex, binary, matches, stop)     { }      // functor invoked by the reflex::AbstractMatcher when the buffer contents are shifted out, also called explicitly in grep::search@@ -978,7 +882,7 @@ struct Grep {          binary = binary || flag_hex || (!flag_text && is_binary(ptr, size)); -        if (binary && !flag_hex && !flag_with_hex)+        if (binfile || (binary && !flag_hex && !flag_with_hex))           break;          if (hex && !binary)@@ -1017,9 +921,9 @@ struct Grep {   // extend event GrepHandler to output formatted invert match lines for --format -v   struct FormatInvertMatchGrepHandler : public GrepHandler { -    FormatInvertMatchGrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& hex, bool& binary, size_t& matches, bool& stop)+    FormatInvertMatchGrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& binfile, bool& hex, bool& binary, size_t& matches, bool& stop)       :-        GrepHandler(grep, pathname, lineno, hex, binary, matches, stop)+        GrepHandler(grep, pathname, lineno, binfile, hex, binary, matches, stop)     { }      // functor invoked by the reflex::AbstractMatcher when the buffer contents are shifted out, also called explicitly in grep::search@@ -1076,9 +980,9 @@ struct Grep {   // extend event GrepHandler to output any context lines for -y   struct AnyLineGrepHandler : public GrepHandler { -    AnyLineGrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& hex, bool& binary, size_t& matches, bool& stop, const char*& rest_line_data, size_t& rest_line_size, size_t& rest_line_last)+    AnyLineGrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& binfile, bool& hex, bool& binary, size_t& matches, bool& stop, const char*& rest_line_data, size_t& rest_line_size, size_t& rest_line_last)       :-        GrepHandler(grep, pathname, lineno, hex, binary, matches, stop),+        GrepHandler(grep, pathname, lineno, binfile, hex, binary, matches, stop),         rest_line_data(rest_line_data),         rest_line_size(rest_line_size),         rest_line_last(rest_line_last)@@ -1148,15 +1052,15 @@ struct Grep {         if (grep.out.eof)           break; -        if (flag_invert_match)-          ++matches;-         if (flag_with_hex)           binary = false; +        if (flag_invert_match)+          ++matches;+         binary = binary || flag_hex || (!flag_text && is_binary(ptr, size)); -        if (binary && !flag_hex && !flag_with_hex)+        if (binfile || (binary && !flag_hex && !flag_with_hex))           break;          if (hex && !binary)@@ -1225,9 +1129,9 @@ struct Grep {      }; -    ContextGrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& hex, bool& binary, size_t& matches, bool& stop, const char*& rest_line_data, size_t& rest_line_size, size_t& rest_line_last)+    ContextGrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& binfile, bool& hex, bool& binary, size_t& matches, bool& stop, const char*& rest_line_data, size_t& rest_line_size, size_t& rest_line_last)       :-        AnyLineGrepHandler(grep, pathname, lineno, hex, binary, matches, stop, rest_line_data, rest_line_size, rest_line_last)+        AnyLineGrepHandler(grep, pathname, lineno, binfile, hex, binary, matches, stop, rest_line_data, rest_line_size, rest_line_last)     { }      // display the before context@@ -1371,7 +1275,7 @@ struct Grep {          binary = binary || flag_hex || (!flag_text && is_binary(ptr, size)); -        if (binary && !flag_hex && !flag_with_hex)+        if (binfile || (binary && !flag_hex && !flag_with_hex))           break;          if (state.after_lineno > 0 && state.after_length < flag_after_context)@@ -1476,9 +1380,9 @@ struct Grep {      }; -    InvertContextGrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& hex, bool& binary, size_t& matches, bool& stop, const char*& rest_line_data, size_t& rest_line_size, size_t& rest_line_last)+    InvertContextGrepHandler(Grep& grep, const char*& pathname, size_t& lineno, bool& binfile, bool& hex, bool& binary, size_t& matches, bool& stop, const char*& rest_line_data, size_t& rest_line_size, size_t& rest_line_last)       :-        AnyLineGrepHandler(grep, pathname, lineno, hex, binary, matches, stop, rest_line_data, rest_line_size, rest_line_last)+        AnyLineGrepHandler(grep, pathname, lineno, binfile, hex, binary, matches, stop, rest_line_data, rest_line_size, rest_line_last)     { }      // display the before context@@ -1680,7 +1584,7 @@ struct Grep {          binary = binary || flag_hex || (!flag_text && is_binary(ptr, size)); -        if (binary && !flag_hex && !flag_with_hex)+        if (binfile || (binary && !flag_hex && !flag_with_hex))           break;          if (hex && !binary)@@ -2985,22 +2889,9 @@ struct Grep { #endif     } -    // -I: do not match binary, check if the initial 16K of the file is binary-    if (flag_binary_without_match)-    {-      size_t avail = matcher->avail();-      if (avail < 16384 && !input.eof())-      {-        // less than 16K available and not EOF, e.g. piped input, get until the first EOL to check-        matcher->eol();-        avail = matcher->avail();-      }-      // limit checking to first 16K of input to improve performance-      if (avail > 16384)-        avail = 16384;-      if (is_binary(matcher->begin(), avail))-        return false;-    }+    // -I: do not match binary+    if (flag_binary_without_match && init_is_binary())+      return false;      // --range=NUM1[,NUM2]: start searching at line NUM1     for (size_t i = flag_min_line; i > 1; --i)@@ -3010,6 +2901,22 @@ struct Grep {     return true;   } +  // after opening a file with init_read, check if it is binary+  bool init_is_binary()+  {+    size_t avail = matcher->avail();+    if (avail < 16384 && !input.eof())+    {+      // less than 16K available and not EOF, e.g. piped input, get until the first EOL to check+      matcher->eol();+      avail = matcher->avail();+    }+    // limit checking to first 16K of input, which should suffice, to improve performance+    if (avail > 16384)+      avail = 16384;+    return is_binary(matcher->begin(), avail);+  }+   const char              *filename;      // the name of the file being searched   std::string              partname;      // the name of an extracted file from an archive   std::string              restline;      // a buffer to store the rest of a line to search@@ -5136,6 +5043,14 @@ void init(int argc, const char **argv)   else if (strcmp(flag_binary_files, "binary") != 0)     usage("invalid argument --binary-files=TYPE, valid arguments are 'binary', 'without-match', 'text', 'hex', and 'with-hex'"); +  // --hex takes priority over --with-hex takes priority over -I takes priority over -a+  if (flag_hex)+    flag_with_hex = (flag_binary_without_match = flag_text = false);+  else if (flag_with_hex)+    flag_binary_without_match = (flag_text = false);+  else if (flag_binary_without_match)+    flag_text = false;+   // --hexdump: normalize by assigning flags   if (flag_hexdump != NULL)   {@@ -7847,12 +7762,13 @@ void Grep::search(const char *pathname)         {           // FormatInvertMatchHandler requires lineno to be set precisely, i.e. after skipping --range lines           size_t lineno = flag_min_line > 0 ? flag_min_line - 1 : 0;-          bool hex = false;    // unused-          bool binary = false; // unused+          bool binfile = false; // unused+          bool hex = false;     // unused+          bool binary = false;  // unused           bool stop = false;            // construct event handler functor with captured *this and some of the locals-          FormatInvertMatchGrepHandler invert_match_handler(*this, pathname, lineno, hex, binary, matches, stop);+          FormatInvertMatchGrepHandler invert_match_handler(*this, pathname, lineno, binfile, hex, binary, matches, stop);            // register an event handler to display non-matching lines           matcher->set_handler(&invert_match_handler);@@ -8019,6 +7935,7 @@ void Grep::search(const char *pathname)           goto exit_search;          size_t lineno = 0;+        bool binfile = !flag_text && !flag_hex && !flag_with_hex && init_is_binary();         bool hex = false;         bool nl = false; @@ -8074,9 +7991,7 @@ void Grep::search(const char *pathname)             if (matches == 0 && !Stats::found_part())               goto exit_search; -            ++matches;--            if (binary && !flag_hex && !flag_with_hex)+            if (binfile || (binary && !flag_hex && !flag_with_hex))             {               if (flag_binary_without_match)               {@@ -8091,6 +8006,8 @@ void Grep::search(const char *pathname)               goto done_search;             } +            ++matches;+             if (!flag_no_header)             {               const char *separator = lineno != current_lineno ? flag_separator : "+";@@ -8179,6 +8096,7 @@ void Grep::search(const char *pathname)           goto exit_search;          size_t lineno = 0;+        bool binfile = !flag_text && !flag_hex && !flag_with_hex && init_is_binary();         bool hex = false;         bool binary = false;         const char *restline_data = NULL;@@ -8240,7 +8158,7 @@ void Grep::search(const char *pathname)              binary = flag_hex || (!flag_text && is_binary(bol, eol - bol)); -            if (binary && !flag_hex && !flag_with_hex)+            if (binfile || (binary && !flag_hex && !flag_with_hex))             {               if (flag_binary_without_match)               {@@ -8516,12 +8434,13 @@ void Grep::search(const char *pathname)          // InvertMatchHandler requires lineno to be set precisely, i.e. after skipping --range lines         size_t lineno = flag_min_line > 0 ? flag_min_line - 1 : 0;+        bool binfile = !flag_text && !flag_hex && !flag_with_hex && init_is_binary();         bool hex = false;         bool binary = false;         bool stop = false;          // construct event handler functor with captured *this and some of the locals-        InvertMatchGrepHandler invert_match_handler(*this, pathname, lineno, hex, binary, matches, stop);+        InvertMatchGrepHandler invert_match_handler(*this, pathname, lineno, binfile, hex, binary, matches, stop);          // register an event handler to display non-matching lines         matcher->set_handler(&invert_match_handler);@@ -8552,7 +8471,7 @@ void Grep::search(const char *pathname)             if (context.len > 0)               invert_match_handler(*matcher, context.buf, context.len, context.num); -            if (binary && !flag_hex && !flag_with_hex)+            if (matches > 0 && (binfile || (binary && !flag_hex && !flag_with_hex)))               break;              if (binary)@@ -8584,11 +8503,11 @@ void Grep::search(const char *pathname)         if (context.len > 0)           invert_match_handler(*matcher, context.buf, context.len, context.num); -        if (binary && !flag_hex && !flag_with_hex)+        if (matches > 0 && (binfile || (binary && !flag_hex && !flag_with_hex)))         {           if (flag_binary_without_match)             matches = 0;-          else if (matches > 0)+          else             out.binary_file_matches(pathname, partname);         } @@ -8604,6 +8523,7 @@ void Grep::search(const char *pathname)          // AnyLineGrepHandler requires lineno to be set precisely, i.e. after skipping --range lines         size_t lineno = flag_min_line > 0 ? flag_min_line - 1 : 0;+        bool binfile = !flag_text && !flag_hex && !flag_with_hex && init_is_binary();         bool hex = false;         bool binary = false;         bool stop = false;@@ -8614,7 +8534,7 @@ void Grep::search(const char *pathname)         size_t restline_last = 0;          // construct event handler functor with captured *this and some of the locals-        AnyLineGrepHandler any_line_handler(*this, pathname, lineno, hex, binary, matches, stop, restline_data, restline_size, restline_last);+        AnyLineGrepHandler any_line_handler(*this, pathname, lineno, binfile, hex, binary, matches, stop, restline_data, restline_size, restline_last);          // register an event handler functor to display non-matching lines         matcher->set_handler(&any_line_handler);@@ -8669,23 +8589,28 @@ void Grep::search(const char *pathname)             context = matcher->before();              if (context.len > 0)+            {               any_line_handler(*matcher, context.buf, context.len, context.num); -            if (binary && !flag_hex && !flag_with_hex)-            {-              if (flag_binary_without_match)+              if (matches > 0 && (binfile || (binary && !flag_hex && !flag_with_hex)))               {-                matches = 0;-              }-              else-              {-                out.binary_file_matches(pathname, partname);-                matches = 1;-              }+                if (flag_binary_without_match)+                {+                  matches = 0;+                }+                else+                {+                  out.binary_file_matches(pathname, partname);+                  matches = 1;+                } -              goto done_search;+                goto done_search;+              }             } +            if (!flag_invert_match)+              ++matches;+             // --range: max line exceeded?             if (flag_max_line > 0 && current_lineno > flag_max_line)               break;@@ -8708,12 +8633,17 @@ void Grep::search(const char *pathname)              binary = flag_hex || (!flag_text && is_binary(bol, eol - bol)); -            if (binary && !flag_hex && !flag_with_hex)+            if (binfile || (binary && !flag_hex && !flag_with_hex))             {               if (flag_binary_without_match)               {                 matches = 0;               }+              else if (flag_invert_match)+              {+                lineno = current_lineno + matcher->lines() - 1;+                continue;+              }               else               {                 out.binary_file_matches(pathname, partname);@@ -8723,9 +8653,6 @@ void Grep::search(const char *pathname)               goto done_search;             } -            if (!flag_invert_match)-              ++matches;-             size_t border = matcher->border();             size_t first = matcher->first();             const char *begin = matcher->begin();@@ -8826,7 +8753,7 @@ void Grep::search(const char *pathname)               }             }           }-          else+          else if (!binfile && (!binary || flag_hex || flag_with_hex))           {             size_t size = matcher->size(); @@ -8979,11 +8906,11 @@ void Grep::search(const char *pathname)         if (context.len > 0)           any_line_handler(*matcher, context.buf, context.len, context.num); -        if (binary && !flag_hex && !flag_with_hex)+        if (matches > 0 && (binfile || (binary && !flag_hex && !flag_with_hex)))         {           if (flag_binary_without_match)             matches = 0;-          else if (matches > 0)+          else             out.binary_file_matches(pathname, partname);         } @@ -8999,6 +8926,7 @@ void Grep::search(const char *pathname)          // ContextGrepHandler requires lineno to be set precisely, i.e. after skipping --range lines         size_t lineno = flag_min_line > 0 ? flag_min_line - 1 : 0;+        bool binfile = !flag_text && !flag_hex && !flag_with_hex && init_is_binary();         bool hex = false;         bool binary = false;         bool stop = false;@@ -9009,7 +8937,7 @@ void Grep::search(const char *pathname)         size_t restline_last = 0;          // construct event handler functor with captured *this and some of the locals-        ContextGrepHandler context_handler(*this, pathname, lineno, hex, binary, matches, stop, restline_data, restline_size, restline_last);+        ContextGrepHandler context_handler(*this, pathname, lineno, binfile, hex, binary, matches, stop, restline_data, restline_size, restline_last);          // register an event handler functor to display non-matching lines         matcher->set_handler(&context_handler);@@ -9060,7 +8988,7 @@ void Grep::search(const char *pathname)             if (context.len > 0)               context_handler(*matcher, context.buf, context.len, context.num); -            if (binary && !flag_hex && !flag_with_hex)+            if (binfile || (binary && !flag_hex && !flag_with_hex))             {               if (flag_binary_without_match)               {@@ -9099,7 +9027,7 @@ void Grep::search(const char *pathname)              binary = flag_hex || (!flag_text && is_binary(bol, eol - bol)); -            if (binary && !flag_hex && !flag_with_hex)+            if (binfile || (binary && !flag_hex && !flag_with_hex))             {               if (flag_binary_without_match)               {@@ -9372,7 +9300,7 @@ void Grep::search(const char *pathname)         if (context.len > 0)           context_handler(*matcher, context.buf, context.len, context.num); -        if (binary && !flag_hex && !flag_with_hex)+        if (binfile || (binary && !flag_hex && !flag_with_hex))         {           if (flag_binary_without_match)             matches = 0;@@ -9394,6 +9322,7 @@ void Grep::search(const char *pathname)         size_t lineno = flag_min_line > 0 ? flag_min_line - 1 : 0;         size_t last_lineno = 0;         size_t after = flag_after_context;+        bool binfile = !flag_text && !flag_hex && !flag_with_hex && init_is_binary();         bool hex = false;         bool binary = false;         bool stop = false;@@ -9404,7 +9333,7 @@ void Grep::search(const char *pathname)         size_t restline_last = 0;          // construct event handler functor with captured *this and some of the locals-        InvertContextGrepHandler invert_context_handler(*this, pathname, lineno, hex, binary, matches, stop, restline_data, restline_size, restline_last);+        InvertContextGrepHandler invert_context_handler(*this, pathname, lineno, binfile, hex, binary, matches, stop, restline_data, restline_size, restline_last);          // register an event handler functor to display non-matching lines         matcher->set_handler(&invert_context_handler);@@ -9459,21 +9388,23 @@ void Grep::search(const char *pathname)             context = matcher->before();              if (context.len > 0)+            {               invert_context_handler(*matcher, context.buf, context.len, context.num); -            if (binary && !flag_hex && !flag_with_hex)-            {-              if (flag_binary_without_match)-              {-                matches = 0;-              }-              else+              if (matches > 0 && (binfile || (binary && !flag_hex && !flag_with_hex)))               {-                out.binary_file_matches(pathname, partname);-                matches = 1;-              }+                if (flag_binary_without_match)+                {+                  matches = 0;+                }+                else+                {+                  out.binary_file_matches(pathname, partname);+                  matches = 1;+                } -              goto done_search;+                goto done_search;+              }             }              lineno = current_lineno;@@ -9502,12 +9433,17 @@ void Grep::search(const char *pathname)             {               binary = flag_hex || (!flag_text && is_binary(bol, eol - bol)); -              if (binary && !flag_hex && !flag_with_hex)+              if (binfile || (binary && !flag_hex && !flag_with_hex))               {                 if (flag_binary_without_match)                 {                   matches = 0;                 }+                else if (flag_invert_match)+                {+                  lineno = last_lineno = current_lineno + matcher->lines() - 1;+                  continue;+                }                 else                 {                   out.binary_file_matches(pathname, partname);@@ -9589,12 +9525,17 @@ void Grep::search(const char *pathname)             {               binary = flag_hex || (!flag_text && is_binary(bol, eol - bol)); -              if (binary && !flag_hex && !flag_with_hex)+              if (binfile || (binary && !flag_hex && !flag_with_hex))               {                 if (flag_binary_without_match)                 {                   matches = 0;                 }+                else if (flag_invert_match)+                {+                  lineno = last_lineno = current_lineno + matcher->lines() - 1;+                  continue;+                }                 else                 {                   out.binary_file_matches(pathname, partname);@@ -9774,12 +9715,17 @@ void Grep::search(const char *pathname)                  binary = flag_hex || (!flag_text && is_binary(end, eol - end)); -                if (binary && !flag_hex && !flag_with_hex)+                if (binfile || (binary && !flag_hex && !flag_with_hex))                 {                   if (flag_binary_without_match)                   {                     matches = 0;                   }+                  else if (flag_invert_match)+                  {+                    lineno = last_lineno = current_lineno + matcher->lines() - 1;+                    continue;+                  }                   else                   {                     out.binary_file_matches(pathname, partname);@@ -9816,8 +9762,7 @@ void Grep::search(const char *pathname)             }           } -          lineno = current_lineno + lines - 1;-          last_lineno = lineno;+          lineno = last_lineno = current_lineno + lines - 1;         }          if (restline_data != NULL)@@ -9850,11 +9795,11 @@ void Grep::search(const char *pathname)         if (context.len > 0)           invert_context_handler(*matcher, context.buf, context.len, context.num); -        if (binary && !flag_hex && !flag_with_hex)+        if (matches > 0 && (binfile || (binary && !flag_hex && !flag_with_hex)))         {           if (flag_binary_without_match)             matches = 0;-          else if (matches > 0)+          else             out.binary_file_matches(pathname, partname);         } @@ -10752,9 +10697,8 @@ void help(std::ostream& out)             Shift-Tab to navigate directories and to select a file to search.\n\             Press Enter to select lines to output.  Press ALT-l for option -l\n\             to list files, ALT-n for -n, etc.  Non-option commands include\n\-            ALT-] to increase fuzziness and ALT-} to increase context.  Press\n\-            F1 or CTRL-Z for help.  Enables --heading.  See also options\n\-            --confirm and --view.\n\+            ALT-] to increase fuzziness and ALT-} to increase context.  Enables\n\+            --heading.  See also options --confirm and --view.\n\     -q, --quiet, --silent\n\             Quiet mode: suppress all output.  ugrep will only search until a\n\             match has been found.\n\

src/ugrep.hpp

@@ -37,6 +37,26 @@ #ifndef UGREP_HPP #define UGREP_HPP +// ugrep version+#define UGREP_VERSION "3.3.2"++// disable mmap because mmap is almost always slower than the file reading speed improvements since 3.0.0+#define WITH_NO_MMAP++// use a task-parallel thread to decompress the stream into a pipe to search, handles archives and increases decompression speed for larger files+#define WITH_DECOMPRESSION_THREAD++// drain stdin until eof - this is disabled for speed, almost all utilities handle SIGPIPE these days anyway+// #define WITH_STDIN_DRAIN++// enable easy-to-use abbreviated ANSI SGR color codes with WITH_EASY_GREP_COLORS+// semicolons are not required and abbreviations can be mixed with numeric ANSI SGR codes+// foreground colors: k=black, r=red, g=green, y=yellow b=blue, m=magenta, c=cyan, w=white+// background colors: K=black, R=red, G=green, Y=yellow B=blue, M=magenta, C=cyan, W=white+// bright colors: +k, +r, +g, +y, +b, +m, +c, +w, +K, +R, +G, +Y, +B, +M, +C, +W+// modifiers: h=highlight, u=underline, i=invert, f=faint, n=normal, H=highlight off, U=underline off, I=invert off+#define WITH_EASY_GREP_COLORS+ // check if we are compiling for a windows OS, but not Cygwin or MinGW #if (defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__BORLANDC__)) && !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) # define OS_WIN@@ -256,6 +276,93 @@ inline char *getcwd0() # endif #endif +// the default GREP_COLORS+#ifndef DEFAULT_GREP_COLORS+# ifdef OS_WIN+#  define DEFAULT_GREP_COLORS "sl=1;37:cx=33:mt=1;31:fn=1;35:ln=1;32:cn=1;32:bn=1;32:se=36"+# else+#  define DEFAULT_GREP_COLORS "cx=33:mt=1;31:fn=1;35:ln=1;32:cn=1;32:bn=1;32:se=36"+# endif+#endif++// the default --tabs+#ifndef DEFAULT_TABS+# define DEFAULT_TABS 8+#endif++// the default --tag+#ifndef DEFAULT_TAG+# define DEFAULT_TAG "___"+#endif++// the default pager command when --pager is used+#ifndef DEFAULT_PAGER_COMMAND+# ifdef OS_WIN+#  define DEFAULT_PAGER_COMMAND "more"+# else+#  define DEFAULT_PAGER_COMMAND "less -R"+# endif+#endif++// the default -Q UI view command when --view is used and PAGER or EDITOR are not set+#ifndef DEFAULT_VIEW_COMMAND+# ifdef OS_WIN+#  define DEFAULT_VIEW_COMMAND "ugrep"+# else+#  define DEFAULT_VIEW_COMMAND "less"+# endif+#endif++// the default ignore file+#ifndef DEFAULT_IGNORE_FILE+# define DEFAULT_IGNORE_FILE ".gitignore"+#endif++// color is disabled by default, unless enabled with WITH_COLOR+#ifdef WITH_COLOR+# define DEFAULT_COLOR "auto"+#else+# define DEFAULT_COLOR NULL+#endif++// pager is disabled by default, unless enabled with WITH_PAGER+#ifdef WITH_PAGER+# define DEFAULT_PAGER DEFAULT_PAGER_COMMAND+#else+# define DEFAULT_PAGER NULL+#endif++// default --mmap+#define DEFAULT_MIN_MMAP_SIZE MIN_MMAP_SIZE++// default --max-mmap: mmap is disabled by default with WITH_NO_MMAP+#ifdef WITH_NO_MMAP+# define DEFAULT_MAX_MMAP_SIZE 0+#else+# define DEFAULT_MAX_MMAP_SIZE MAX_MMAP_SIZE+#endif++// pretty is disabled by default, unless enabled with WITH_PRETTY+#ifdef WITH_PRETTY+# define DEFAULT_PRETTY true+#else+# define DEFAULT_PRETTY false+#endif++// hidden file and directory search is enabled by default, unless disabled with WITH_HIDDEN+#ifdef WITH_HIDDEN+# define DEFAULT_HIDDEN true+#else+# define DEFAULT_HIDDEN false+#endif++// do not confirm query UI actions+#ifdef WITH_NO_CONFIRM+# define DEFAULT_CONFIRM false+#else+# define DEFAULT_CONFIRM true+#endif+ #include "flag.hpp" #include "cnf.hpp" #include <reflex/input.h>

src/zopen.c

@@ -523,13 +523,13 @@ z_read(void *handle, unsigned char *rbp, int num) 	}  	/* Check the magic number */-	if (fread(header,+	if ((char)fread(header, 	    sizeof(char), zmagic + 1, fp) != zmagic + 1 || 	    memcmp(header, magic_header, zmagic) != 0) { 		errno = EINVAL; 		return (-1); 	}-	maxbits = header[zmagic];	/* Set -b from file. */+	maxbits = header[(int)zmagic];	/* Set -b from file. */ 	block_compress = maxbits & BLOCK_MASK; 	maxbits &= BIT_MASK; 	maxmaxcode = 1L << maxbits;

tests/archive.gz

Binary file changed

tests/archive.tar.zip

Binary file changed

tests/archive.tgz

Binary file changed

tests/archive.zip

Binary file changed

tests/gen.sh

@@ -2,6 +2,8 @@  UG="../src/ugrep --color=always --sort" +FILES="Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+ if [ ! -x "../src/ugrep" ] ; then   echo "../src/ugrep not found, exiting"   exit 1@@ -28,8 +30,10 @@ mkdir -p out dir1 dir2  ln -s ../Hello.java dir1 cp Hello.sh dir1+cp Hello.bat dir1 ln -s ../Hello.java dir2 cp Hello.sh dir2+cp Hello.bat dir2 ln -s ../dir2 dir1 ln -s ../dir1 dir2 cat > dir1/.gitignore << END@@ -41,6 +45,8 @@ END  $UG -rl                                  Hello dir1 > out/dir.out $UG -Rl                                  Hello dir1 > out/dir-S.out+$UG -Rl -Osh                             Hello dir1 > out/dir-O.out+$UG -Rl -M'#!/bin/sh'                    Hello dir1 > out/dir-M.out $UG -Rl -tShell                          Hello dir1 > out/dir-t.out $UG -1l                                  Hello dir1 > out/dir-1.out $UG -2l                                  Hello dir1 > out/dir-2.out@@ -74,64 +80,64 @@ done  $UG -Zio Lorem lorem.utf8.txt > out/lorem_Lorem-Zio.out -$UG -ci hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > out/Hello_Hello-ci.out-$UG -cj hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > out/Hello_Hello-cj.out+$UG -ci hello $FILES > out/Hello_Hello-ci.out+$UG -cj hello $FILES > out/Hello_Hello-cj.out -$UG -e Hello -e '".*?"' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > out/Hello_Hello-ee.out-$UG -e Hello -N '".*?"' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > out/Hello_Hello-eN.out-$UG --max-count=1 Hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > out/Hello_Hello--max-count.out-$UG --max-files=1 Hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > out/Hello_Hello--max-files.out-$UG --range=1,1   Hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > out/Hello_Hello--range.out+$UG -e Hello -e '".*?"' $FILES > out/Hello_Hello-ee.out+$UG -e Hello -N '".*?"' $FILES > out/Hello_Hello-eN.out+$UG --max-count=1 Hello $FILES > out/Hello_Hello--max-count.out+$UG --max-files=1 Hello $FILES > out/Hello_Hello--max-files.out+$UG --range=1,1   Hello $FILES > out/Hello_Hello--range.out  for PAT in '' 'Hello' '\w+\s+\S+' '\S\n\S' 'nomatch' ; do   FN=`echo "Hello_$PAT" | tr -Cd '[:alnum:]_'`   for OUT in '' '-I' '-W' '-X' ; do     for OPS in '' '-l' '-lv' '-c' '-co' '-cv' '-n' '-nkbT' '-unkbT' '-o' '-on' '-onkbT' '-ounkbT' '-v' '-nv' '-C2' '-nC2' '-vC2' '-nvC2' '-y' '-ny' '-vy' '-nvy' ; do-      $UG -U $OUT $OPS "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN$OUT$OPS.out"+      $UG -U $OUT $OPS "$PAT" $FILES > "out/$FN$OUT$OPS.out"     done   done   for OUT in '--csv' '--json' '--xml' ; do     for OPS in '' '-l' '-lv' '-c' '-co' '-cv' '-n' '-v' '-nv' '-nkb' '-unkb' '-o' '-on' '-onkb' '-ounkb' ; do-      $UG -U $OUT $OPS "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN$OUT$OPS.out"+      $UG -U $OUT $OPS "$PAT" $FILES > "out/$FN$OUT$OPS.out"     done   done-  $UG -U --tag "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN--tag.out"-  $UG -U --format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN--format.out"-  $UG -U -v --format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-v--format.out"-  $UG -U -Iw "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-Iw.out"-  $UG -U -Ix "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-Ix.out"-  $UG -U -F  "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-F.out"-  $UG -U -Fw "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-Fw.out"-  $UG -U -Fx "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-Fx.out"+  $UG -U --tag "$PAT" $FILES > "out/$FN--tag.out"+  $UG -U --format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' "$PAT" $FILES > "out/$FN--format.out"+  $UG -U -v --format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' "$PAT" $FILES > "out/$FN-v--format.out"+  $UG -U -Iw "$PAT" $FILES > "out/$FN-Iw.out"+  $UG -U -Ix "$PAT" $FILES > "out/$FN-Ix.out"+  $UG -U -F  "$PAT" $FILES > "out/$FN-F.out"+  $UG -U -Fw "$PAT" $FILES > "out/$FN-Fw.out"+  $UG -U -Fx "$PAT" $FILES > "out/$FN-Fx.out"   if [ "$PAT" == '\w+\s+\S+' ]; then-    $UG -U -G  '\w\+\s\+\S\+' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-G.out"-    $UG -U -Gw '\w\+\s\+\S\+' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-Gw.out"-    $UG -U -Gx '\w\+\s\+\S\+' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-Gx.out"+    $UG -U -G  '\w\+\s\+\S\+' $FILES > "out/$FN-G.out"+    $UG -U -Gw '\w\+\s\+\S\+' $FILES > "out/$FN-Gw.out"+    $UG -U -Gx '\w\+\s\+\S\+' $FILES > "out/$FN-Gx.out"   else-    $UG -U -G  "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-G.out"-    $UG -U -Gw "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-Gw.out"-    $UG -U -Gx "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-Gx.out"+    $UG -U -G  "$PAT" $FILES > "out/$FN-G.out"+    $UG -U -Gw "$PAT" $FILES > "out/$FN-Gw.out"+    $UG -U -Gx "$PAT" $FILES > "out/$FN-Gx.out"   fi-  $UG -U -IP  "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-IP.out"-  $UG -U -IPw "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-IPw.out"-  $UG -U -IPx "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN-IPx.out"+  $UG -U -IP  "$PAT" $FILES > "out/$FN-IP.out"+  $UG -U -IPw "$PAT" $FILES > "out/$FN-IPw.out"+  $UG -U -IPx "$PAT" $FILES > "out/$FN-IPx.out" done  for PAT in '' 'Hello World' 'Hello -World' 'Hello -World|greeting' 'Hello -(greeting|World)' '"a Hello" greeting' ; do   FN=`echo "Hello_$PAT" | tr -Cd '[:alnum:]_-'`-  $UG -U --bool "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/$FN--bool.out"+  $UG -U --bool "$PAT" $FILES > "out/$FN--bool.out" done -$UG -U -e 'Hello' --and 'World' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/Hello--and.out"-$UG -U -e 'Hello' --andnot 'World' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/Hello--andnot.out"-$UG -U -e 'Hello' --and --not 'World' -e 'greeting' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt > "out/Hello--and--not.out"+$UG -U -e 'Hello' --and 'World' $FILES > "out/Hello--and.out"+$UG -U -e 'Hello' --andnot 'World' $FILES > "out/Hello--andnot.out"+$UG -U -e 'Hello' --and --not 'World' -e 'greeting' $FILES > "out/Hello--and--not.out"  echo "GENERATING TEST ARCHIVES"  rm -f archive.* -ls Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt empty.txt | cpio -o --quiet > archive.cpio-ls Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt empty.txt | pax -w -f archive.pax+ls $FILES empty.txt | cpio -o --quiet > archive.cpio+ls $FILES empty.txt | pax -w -f archive.pax tar cf archive.tar Hello.* empty.txt compress -c archive.tar > archive.tZ gzip  -9 -c archive.tar > archive.tgz@@ -141,7 +147,7 @@ xz    -9 -c archive.tar > archive.txz lz4   -9 -c archive.tar > archive.tar.lz4 zstd  -9 -c archive.tar > archive.tzst zip   -9 -q archive.tar.zip archive.tar-zip   -9 -q archive.zip Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt empty.txt+zip   -9 -q archive.zip $FILES empty.txt  $UG -z -c Hello archive.cpio    > out/archive.cpio.out $UG -z -c Hello archive.pax     > out/archive.pax.out

tests/out/Hello--and--not.out

@@ -1,3 +1,3 @@ Hello.java:public class Hello // prints a Hello World! greeting-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.txt:Hello

tests/out/Hello--andnot.out

@@ -1,2 +1,2 @@-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.txt:Hello

tests/out/Hello_--bool.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_--tag.out

@@ -8,7 +8,6 @@ Hello.java:{ public static void main(String[] arg) Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_-C2.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_-F.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_-Fw.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_-G.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_-Gw.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_-n.out

@@ -8,7 +8,6 @@ Hello.java:5:  { System.out.println("Hello World!"); Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.sh:2:echo "Hello World!"

tests/out/Hello_-nC2.out

@@ -8,7 +8,6 @@ Hello.java:5:  { System.out.println("Hello World!"); Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.sh:2:echo "Hello World!"

tests/out/Hello_-nkbT.out

@@ -8,7 +8,6 @@ Hello.java:     5:  1:    114:	  { System.out.println("Hello World!"); Hello.java:     6:  1:    154:	  } Hello.java:     7:  1:    158:	}-Hello.pdf:     1:  1:      0:	%PDF-1.3 Binary file Hello.pdf matches Hello.sh:     1:  1:      0:	#!/bin/sh Hello.sh:     2:  1:     10:	echo "Hello World!"

tests/out/Hello_-nvC2.out

@@ -1,2 +0,0 @@-Binary file Hello.class matches-Binary file Hello.pdf matches

tests/out/Hello_-nvy.out

@@ -1,6 +1,5 @@ Hello.bat-1-#!/bin/sh Hello.bat-2-echo "Hello World!"-Binary file Hello.class matches Hello.java-1-import java.lang.*; Hello.java-2- Hello.java-3-public class Hello // prints a Hello World! greeting@@ -8,8 +7,6 @@ Hello.java-5-  { System.out.println("Hello World!"); Hello.java-6-  } Hello.java-7-}-Hello.pdf-1-%PDF-1.3-Binary file Hello.pdf matches Hello.sh-1-#!/bin/sh Hello.sh-2-echo "Hello World!" Hello.txt-1-Hello

tests/out/Hello_-ny.out

@@ -8,7 +8,6 @@ Hello.java:5:  { System.out.println("Hello World!"); Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.sh:2:echo "Hello World!"

tests/out/Hello_-o.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_-on.out

@@ -8,7 +8,6 @@ Hello.java:5:  { System.out.println("Hello World!"); Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.sh:2:echo "Hello World!"

tests/out/Hello_-onkbT.out

@@ -8,7 +8,6 @@ Hello.java:     5:  1:    114:	  { System.out.println("Hello World!"); Hello.java:     6:  1:    154:	  } Hello.java:     7:  1:    158:	}-Hello.pdf:     1:  1:      0:	%PDF-1.3 Binary file Hello.pdf matches Hello.sh:     1:  1:      0:	#!/bin/sh Hello.sh:     2:  1:     10:	echo "Hello World!"

tests/out/Hello_-ounkbT.out

@@ -8,7 +8,6 @@ Hello.java:     5:  1:    114:	  { System.out.println("Hello World!"); Hello.java:     6:  1:    154:	  } Hello.java:     7:  1:    158:	}-Hello.pdf:     1:  1:      0:	%PDF-1.3 Binary file Hello.pdf matches Hello.sh:     1:  1:      0:	#!/bin/sh Hello.sh:     2:  1:     10:	echo "Hello World!"

tests/out/Hello_-unkbT.out

@@ -8,7 +8,6 @@ Hello.java:     5:  1:    114:	  { System.out.println("Hello World!"); Hello.java:     6:  1:    154:	  } Hello.java:     7:  1:    158:	}-Hello.pdf:     1:  1:      0:	%PDF-1.3 Binary file Hello.pdf matches Hello.sh:     1:  1:      0:	#!/bin/sh Hello.sh:     2:  1:     10:	echo "Hello World!"

tests/out/Hello_-vC2.out

@@ -1,2 +0,0 @@-Binary file Hello.class matches-Binary file Hello.pdf matches

tests/out/Hello_-vy.out

@@ -1,6 +1,5 @@ Hello.bat-#!/bin/sh Hello.bat-echo "Hello World!"-Binary file Hello.class matches Hello.java-import java.lang.*; Hello.java- Hello.java-public class Hello // prints a Hello World! greeting@@ -8,8 +7,6 @@ Hello.java-  { System.out.println("Hello World!"); Hello.java-  } Hello.java-}-Hello.pdf-%PDF-1.3-Binary file Hello.pdf matches Hello.sh-#!/bin/sh Hello.sh-echo "Hello World!" Hello.txt-Hello

tests/out/Hello_-y.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_Hello--max-count.out

@@ -1,6 +1,6 @@ Hello.bat:echo "Hello World!" Binary file Hello.class matches Hello.java:public class Hello // prints a Hello World! greeting-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.sh:echo "Hello World!" Hello.txt:Hello

tests/out/Hello_Hello--tag.out

@@ -2,6 +2,6 @@ Hello.bat:echo "___Hello___ World!" Binary file Hello.class matches Hello.java:public class ___Hello___ // prints a ___Hello___ World! greeting Hello.java:  { System.out.println("___Hello___ World!");-Hello.pdf:(___Hello___)+Binary file Hello.pdf matches Hello.sh:echo "___Hello___ World!" Hello.txt:___Hello___

tests/out/Hello_Hello-F.out

@@ -2,6 +2,6 @@ Binary file Hello.class matches Hello.java:public class Hello // prints a Hello World! greeting Hello.java:  { System.out.println("Hello World!");-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.sh:echo "Hello World!" Hello.txt:Hello

tests/out/Hello_Hello-Fw.out

@@ -2,6 +2,6 @@ Binary file Hello.class matches Hello.java:public class Hello // prints a Hello World! greeting Hello.java:  { System.out.println("Hello World!");-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.sh:echo "Hello World!" Hello.txt:Hello

tests/out/Hello_Hello-G.out

@@ -2,6 +2,6 @@ Binary file Hello.class matches Hello.java:public class Hello // prints a Hello World! greeting Hello.java:  { System.out.println("Hello World!");-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.sh:echo "Hello World!" Hello.txt:Hello

tests/out/Hello_Hello-Gw.out

@@ -2,6 +2,6 @@ Binary file Hello.class matches Hello.java:public class Hello // prints a Hello World! greeting Hello.java:  { System.out.println("Hello World!");-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.sh:echo "Hello World!" Hello.txt:Hello

tests/out/Hello_Hello-World--bool.out

@@ -1,2 +1,2 @@-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.txt:Hello

tests/out/Hello_Hello-Worldgreeting--bool.out

@@ -1,3 +1,3 @@ Hello.java:public class Hello // prints a Hello World! greeting-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.txt:Hello

tests/out/Hello_Hello-eN.out

@@ -1,4 +1,4 @@ Binary file Hello.class matches Hello.java:public class Hello // prints a Hello World! greeting-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.txt:Hello

tests/out/Hello_Hello-greetingWorld--bool.out

@@ -1,2 +1,2 @@-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.txt:Hello

tests/out/Hello_Hello-n.out

@@ -2,6 +2,6 @@ Binary file Hello.class matches Hello.java:3:public class Hello // prints a Hello World! greeting Hello.java:5:  { System.out.println("Hello World!");-Hello.pdf:85:(Hello)+Binary file Hello.pdf matches Hello.sh:2:echo "Hello World!" Hello.txt:1:Hello

tests/out/Hello_Hello-nkbT.out

@@ -2,6 +2,6 @@ Binary file Hello.class matches Hello.java:     3: 14:     34:	public class Hello // prints a Hello World! greeting Hello.java:     5: 25:    138:	  { System.out.println("Hello World!");-Hello.pdf:    85:  2:   5217:	(Hello)+Binary file Hello.pdf matches Hello.sh:     2:  7:     16:	echo "Hello World!" Hello.txt:     1:  1:      0:	Hello

tests/out/Hello_Hello-nv.out

@@ -5,6 +5,5 @@ Hello.java:4:{ public static void main(String[] arg) Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh

tests/out/Hello_Hello-nvC2.out

@@ -8,7 +8,6 @@ Hello.java-5-  { System.out.println("Hello World!"); Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.sh-2-echo "Hello World!"

tests/out/Hello_Hello-nvy.out

@@ -8,7 +8,6 @@ Hello.java-5-  { System.out.println("Hello World!"); Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.sh-2-echo "Hello World!"

tests/out/Hello_Hello-ny.out

@@ -8,7 +8,6 @@ Hello.java:5:  { System.out.println("Hello World!"); Hello.java-6-  } Hello.java-7-}-Hello.pdf-1-%PDF-1.3 Binary file Hello.pdf matches Hello.sh-1-#!/bin/sh Hello.sh:2:echo "Hello World!"

tests/out/Hello_Hello-o.out

@@ -1,10 +1,8 @@ Hello.bat:Hello-Hello.class:Hello-Hello-Hello+Binary file Hello.class matches Hello.java:Hello Hello Hello.java:Hello-Hello.pdf:Hello+Binary file Hello.pdf matches Hello.sh:Hello Hello.txt:Hello

tests/out/Hello_Hello-on.out

@@ -1,10 +1,8 @@ Hello.bat:2:Hello-Hello.class:5:Hello-Hello-Hello+Binary file Hello.class matches Hello.java:3:Hello Hello Hello.java:5:Hello-Hello.pdf:85:Hello+Binary file Hello.pdf matches Hello.sh:2:Hello Hello.txt:1:Hello

tests/out/Hello_Hello-onkbT.out

@@ -1,10 +1,8 @@ Hello.bat:     2:  7:     16:	Hello-Hello.class:     5:  1:    122:	Hello-Hello-Hello+Binary file Hello.class matches Hello.java:     3: 14:     34:	Hello Hello Hello.java:     5: 25:    138:	Hello-Hello.pdf:    85:  2:   5217:	Hello+Binary file Hello.pdf matches Hello.sh:     2:  7:     16:	Hello Hello.txt:     1:  1:      0:	Hello

tests/out/Hello_Hello-ounkbT.out

@@ -1,10 +1,8 @@ Hello.bat:     2:  7:     16:	Hello-Hello.class:     5:  1:    122:	Hello-Hello.class+     5+ 27+    148+	Hello-Hello.class+     5+ 50+    171+	Hello+Binary file Hello.class matches Hello.java:     3: 14:     34:	Hello Hello.java+     3+ 32+     52+	Hello Hello.java:     5: 25:    138:	Hello-Hello.pdf:    85:  2:   5217:	Hello+Binary file Hello.pdf matches Hello.sh:     2:  7:     16:	Hello Hello.txt:     1:  1:      0:	Hello

tests/out/Hello_Hello-unkbT.out

@@ -3,6 +3,6 @@ Hello.java:     3: 14:     34:	public class Hello // prints a Hello World! greeting Hello.java+     3+ 32+     52+	public class Hello // prints a Hello World! greeting Hello.java:     5: 25:    138:	  { System.out.println("Hello World!");-Hello.pdf:    85:  2:   5217:	(Hello)+Binary file Hello.pdf matches Hello.sh:     2:  7:     16:	echo "Hello World!" Hello.txt:     1:  1:      0:	Hello

tests/out/Hello_Hello-v.out

@@ -5,6 +5,5 @@ Hello.java:{ public static void main(String[] arg) Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh

tests/out/Hello_Hello-vC2.out

@@ -8,7 +8,6 @@ Hello.java-  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh-echo "Hello World!"

tests/out/Hello_Hello-vy.out

@@ -8,7 +8,6 @@ Hello.java-  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh-echo "Hello World!"

tests/out/Hello_Hello-y.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java-  } Hello.java-}-Hello.pdf-%PDF-1.3 Binary file Hello.pdf matches Hello.sh-#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_Hello.out

@@ -2,6 +2,6 @@ Binary file Hello.class matches Hello.java:public class Hello // prints a Hello World! greeting Hello.java:  { System.out.println("Hello World!");-Hello.pdf:(Hello)+Binary file Hello.pdf matches Hello.sh:echo "Hello World!" Hello.txt:Hello

tests/out/Hello_SnS-nv.out

@@ -1,24 +1,5 @@ Hello.java:1:import java.lang.*; Hello.java:2: Hello.java:5:  { System.out.println("Hello World!");-Hello.pdf:109:0000005392 00000 n -Hello.pdf:110:0000000238 00000 n -Hello.pdf:111:0000001714 00000 n -Hello.pdf:112:0000000022 00000 n -Hello.pdf:113:0000000219 00000 n -Hello.pdf:114:0000000342 00000 n -Hello.pdf:115:0000001679 00000 n -Hello.pdf:116:0000001847 00000 n -Hello.pdf:117:0000000439 00000 n -Hello.pdf:118:0000001658 00000 n -Hello.pdf:119:0000001797 00000 n -Hello.pdf:120:0000002110 00000 n -Hello.pdf:121:0000002362 00000 n -Hello.pdf:122:0000005186 00000 n -Hello.pdf:123:0000005207 00000 n -Hello.pdf:124:0000005231 00000 n -Hello.pdf:125:0000005284 00000 n -Hello.pdf:126:0000005311 00000 n -Hello.pdf:127:0000005353 00000 n -Hello.pdf:128:0000005372 00000 n +Binary file Hello.pdf matches Hello.txt:1:Hello

tests/out/Hello_SnS-nvC2.out

@@ -1,4 +1,3 @@-Binary file Hello.class matches Hello.java:1:import java.lang.*; Hello.java:2: Hello.java-3-public class Hello // prints a Hello World! greeting

tests/out/Hello_SnS-nvy.out

@@ -1,6 +1,5 @@ Hello.bat-1-#!/bin/sh Hello.bat|2|echo "Hello World!"-Binary file Hello.class matches Hello.java:1:import java.lang.*; Hello.java:2: Hello.java-3-public class Hello // prints a Hello World! greeting

tests/out/Hello_SnS-o.out

@@ -5,8 +5,6 @@ Hello.java|{ Hello.java:} Hello.java|}-Hello.pdf:3-Hello.pdf|% Binary file Hello.pdf matches Hello.sh:h Hello.sh|e

tests/out/Hello_SnS-on.out

@@ -5,8 +5,6 @@ Hello.java|4|{ Hello.java:6:} Hello.java|7|}-Hello.pdf:1:3-Hello.pdf|2|% Binary file Hello.pdf matches Hello.sh:1:h Hello.sh|2|e

tests/out/Hello_SnS-onkbT.out

@@ -5,8 +5,6 @@ Hello.java|     4|  1|     74|	{ Hello.java:     6:  3:    156:	} Hello.java|     7|  1|    158|	}-Hello.pdf:     1:  8:      7:	3-Hello.pdf|     2|  1|      9|	% Binary file Hello.pdf matches Hello.sh:     1:  9:      8:	h Hello.sh|     2|  1|     10|	e

tests/out/Hello_SnS-ounkbT.out

@@ -5,8 +5,6 @@ Hello.java|     4|  1|     74|	{ Hello.java:     6:  3:    156:	} Hello.java|     7|  1|    158|	}-Hello.pdf:     1:  8:      7:	3-Hello.pdf|     2|  1|      9|	% Binary file Hello.pdf matches Hello.sh:     1:  9:      8:	h Hello.sh|     2|  1|     10|	e

tests/out/Hello_SnS-v.out

@@ -1,24 +1,5 @@ Hello.java:import java.lang.*; Hello.java: Hello.java:  { System.out.println("Hello World!");-Hello.pdf:0000005392 00000 n -Hello.pdf:0000000238 00000 n -Hello.pdf:0000001714 00000 n -Hello.pdf:0000000022 00000 n -Hello.pdf:0000000219 00000 n -Hello.pdf:0000000342 00000 n -Hello.pdf:0000001679 00000 n -Hello.pdf:0000001847 00000 n -Hello.pdf:0000000439 00000 n -Hello.pdf:0000001658 00000 n -Hello.pdf:0000001797 00000 n -Hello.pdf:0000002110 00000 n -Hello.pdf:0000002362 00000 n -Hello.pdf:0000005186 00000 n -Hello.pdf:0000005207 00000 n -Hello.pdf:0000005231 00000 n -Hello.pdf:0000005284 00000 n -Hello.pdf:0000005311 00000 n -Hello.pdf:0000005353 00000 n -Hello.pdf:0000005372 00000 n +Binary file Hello.pdf matches Hello.txt:Hello

tests/out/Hello_SnS-vC2.out

@@ -1,4 +1,3 @@-Binary file Hello.class matches Hello.java:import java.lang.*; Hello.java: Hello.java-public class Hello // prints a Hello World! greeting

tests/out/Hello_SnS-vy.out

@@ -1,6 +1,5 @@ Hello.bat-#!/bin/sh Hello.bat|echo "Hello World!"-Binary file Hello.class matches Hello.java:import java.lang.*; Hello.java: Hello.java-public class Hello // prints a Hello World! greeting

tests/out/Hello_nomatch-nv.out

@@ -8,7 +8,6 @@ Hello.java:5:  { System.out.println("Hello World!"); Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.sh:2:echo "Hello World!"

tests/out/Hello_nomatch-nvC2.out

@@ -8,7 +8,6 @@ Hello.java:5:  { System.out.println("Hello World!"); Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.sh:2:echo "Hello World!"

tests/out/Hello_nomatch-nvy.out

@@ -8,7 +8,6 @@ Hello.java:5:  { System.out.println("Hello World!"); Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.sh:2:echo "Hello World!"

tests/out/Hello_nomatch-ny.out

@@ -7,7 +7,6 @@ Hello.java-5-  { System.out.println("Hello World!"); Hello.java-6-  } Hello.java-7-}-Hello.pdf-1-%PDF-1.3 Hello.sh-1-#!/bin/sh Hello.sh-2-echo "Hello World!" Hello.txt-1-Hello

tests/out/Hello_nomatch-v.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_nomatch-vC2.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_nomatch-vy.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_nomatch-y.out

@@ -7,7 +7,6 @@ Hello.java-  { System.out.println("Hello World!"); Hello.java-  } Hello.java-}-Hello.pdf-%PDF-1.3 Hello.sh-#!/bin/sh Hello.sh-echo "Hello World!" Hello.txt-Hello

tests/out/Hello_wsS--tag.out

@@ -4,7 +4,5 @@ Hello.java:___import java.lang.*;___ Hello.java:___public class___ ___Hello //___ ___prints a___ ___Hello World!___ greeting Hello.java:{ ___public static___ ___void main(String[]___ arg) Hello.java:  { System.out.println("___Hello World!");___-Hello.pdf:___4 0___ obj-Hello.pdf:<< /___Length 5___ ___0 R___ /___Filter /FlateDecode___ >> Binary file Hello.pdf matches Hello.sh:___echo "Hello___ World!"

tests/out/Hello_wsS-G.out

@@ -4,7 +4,5 @@ Hello.java:public class Hello // prints a Hello World! greeting Hello.java:{ public static void main(String[] arg) Hello.java:  { System.out.println("Hello World!");-Hello.pdf:4 0 obj-Hello.pdf:<< /Length 5 0 R /Filter /FlateDecode >> Binary file Hello.pdf matches Hello.sh:echo "Hello World!"

tests/out/Hello_wsS-Gw.out

@@ -4,7 +4,5 @@ Hello.java:public class Hello // prints a Hello World! greeting Hello.java:{ public static void main(String[] arg) Hello.java:  { System.out.println("Hello World!");-Hello.pdf:4 0 obj-Hello.pdf:<< /Length 5 0 R /Filter /FlateDecode >> Binary file Hello.pdf matches Hello.sh:echo "Hello World!"

tests/out/Hello_wsS-Gx.out

@@ -1,2 +1,2 @@ Hello.java:import java.lang.*;-Hello.pdf:0 21+Binary file Hello.pdf matches

tests/out/Hello_wsS-n.out

@@ -4,7 +4,5 @@ Hello.java:3:public class Hello // prints a Hello World! greeting Hello.java:4:{ public static void main(String[] arg) Hello.java:5:  { System.out.println("Hello World!");-Hello.pdf:3:4 0 obj-Hello.pdf:4:<< /Length 5 0 R /Filter /FlateDecode >> Binary file Hello.pdf matches Hello.sh:2:echo "Hello World!"

tests/out/Hello_wsS-nkbT.out

@@ -4,7 +4,5 @@ Hello.java:     3:  1:     21:	public class Hello // prints a Hello World! greeting Hello.java:     4:  3:     76:	{ public static void main(String[] arg) Hello.java:     5: 25:    138:	  { System.out.println("Hello World!");-Hello.pdf:     3:  1:     22:	4 0 obj-Hello.pdf:     4:  5:     34:	<< /Length 5 0 R /Filter /FlateDecode >> Binary file Hello.pdf matches Hello.sh:     2:  1:     10:	echo "Hello World!"

tests/out/Hello_wsS-nv.out

@@ -3,7 +3,6 @@ Hello.java:2: Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.txt:1:Hello

tests/out/Hello_wsS-nvC2.out

@@ -8,7 +8,6 @@ Hello.java-5-  { System.out.println("Hello World!"); Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.sh-2-echo "Hello World!"

tests/out/Hello_wsS-nvy.out

@@ -8,7 +8,6 @@ Hello.java-5-  { System.out.println("Hello World!"); Hello.java:6:  } Hello.java:7:}-Hello.pdf:1:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:1:#!/bin/sh Hello.sh-2-echo "Hello World!"

tests/out/Hello_wsS-ny.out

@@ -8,7 +8,6 @@ Hello.java:5:  { System.out.println("Hello World!"); Hello.java-6-  } Hello.java-7-}-Hello.pdf-1-%PDF-1.3 Binary file Hello.pdf matches Hello.sh-1-#!/bin/sh Hello.sh:2:echo "Hello World!"

tests/out/Hello_wsS-o.out

@@ -8,9 +8,5 @@ Hello.java:public static void main(String[] Hello.java:Hello World!");-Hello.pdf:4 0-Hello.pdf:Length 5-0 R-Filter /FlateDecode Binary file Hello.pdf matches Hello.sh:echo "Hello

tests/out/Hello_wsS-on.out

@@ -8,9 +8,5 @@ Hello.java:4:public static void main(String[] Hello.java:5:Hello World!");-Hello.pdf:3:4 0-Hello.pdf:4:Length 5-0 R-Filter /FlateDecode Binary file Hello.pdf matches Hello.sh:2:echo "Hello

tests/out/Hello_wsS-onkbT.out

@@ -8,9 +8,5 @@ Hello.java:     4:  3:     76:	public static void main(String[] Hello.java:     5: 25:    138:	Hello World!");-Hello.pdf:     3:  1:     22:	4 0-Hello.pdf:     4:  5:     34:	Length 5-0 R-Filter /FlateDecode Binary file Hello.pdf matches Hello.sh:     2:  1:     10:	echo "Hello

tests/out/Hello_wsS-ounkbT.out

@@ -8,9 +8,5 @@ Hello.java:     4:  3:     76:	public static Hello.java+     4+ 17+     90+	void main(String[] Hello.java:     5: 25:    138:	Hello World!");-Hello.pdf:     3:  1:     22:	4 0-Hello.pdf:     4:  5:     34:	Length 5-Hello.pdf+     4+ 14+     43+	0 R-Hello.pdf+     4+ 19+     48+	Filter /FlateDecode Binary file Hello.pdf matches Hello.sh:     2:  1:     10:	echo "Hello

tests/out/Hello_wsS-unkbT.out

@@ -8,9 +8,5 @@ Hello.java:     4:  3:     76:	{ public static void main(String[] arg) Hello.java+     4+ 17+     90+	{ public static void main(String[] arg) Hello.java:     5: 25:    138:	  { System.out.println("Hello World!");-Hello.pdf:     3:  1:     22:	4 0 obj-Hello.pdf:     4:  5:     34:	<< /Length 5 0 R /Filter /FlateDecode >>-Hello.pdf+     4+ 14+     43+	<< /Length 5 0 R /Filter /FlateDecode >>-Hello.pdf+     4+ 19+     48+	<< /Length 5 0 R /Filter /FlateDecode >> Binary file Hello.pdf matches Hello.sh:     2:  1:     10:	echo "Hello World!"

tests/out/Hello_wsS-v.out

@@ -3,7 +3,6 @@ Hello.java: Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.txt:Hello

tests/out/Hello_wsS-vC2.out

@@ -8,7 +8,6 @@ Hello.java-  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh-echo "Hello World!"

tests/out/Hello_wsS-vy.out

@@ -8,7 +8,6 @@ Hello.java-  { System.out.println("Hello World!"); Hello.java:  } Hello.java:}-Hello.pdf:%PDF-1.3 Binary file Hello.pdf matches Hello.sh:#!/bin/sh Hello.sh-echo "Hello World!"

tests/out/Hello_wsS-y.out

@@ -8,7 +8,6 @@ Hello.java:  { System.out.println("Hello World!"); Hello.java-  } Hello.java-}-Hello.pdf-%PDF-1.3 Binary file Hello.pdf matches Hello.sh-#!/bin/sh Hello.sh:echo "Hello World!"

tests/out/Hello_wsS.out

@@ -4,7 +4,5 @@ Hello.java:public class Hello // prints a Hello World! greeting Hello.java:{ public static void main(String[] arg) Hello.java:  { System.out.println("Hello World!");-Hello.pdf:4 0 obj-Hello.pdf:<< /Length 5 0 R /Filter /FlateDecode >> Binary file Hello.pdf matches Hello.sh:echo "Hello World!"

tests/out/dir--exclude-dir.out

@@ -1,2 +1,3 @@+dir1/Hello.bat dir1/Hello.java dir1/Hello.sh

tests/out/dir--exclude-from.out

@@ -1 +1,2 @@+dir1/Hello.bat dir1/Hello.java

tests/out/dir--exclude.out

@@ -1,2 +1,4 @@+dir1/Hello.bat dir1/Hello.java+dir1/dir2/Hello.bat dir1/dir2/Hello.java

tests/out/dir--filter.out

@@ -1,2 +1,4 @@+dir1/Hello.bat dir1/Hello.java+dir1/dir2/Hello.bat dir1/dir2/Hello.java

tests/out/dir--ignore-files.out

@@ -1 +1,2 @@+dir1/Hello.bat dir1/Hello.java

tests/out/dir--include-dir.out

@@ -1,2 +1,3 @@+dir1/Hello.bat dir1/Hello.java dir1/Hello.sh

tests/out/dir-1.out

@@ -1,2 +1,3 @@+dir1/Hello.bat dir1/Hello.java dir1/Hello.sh

tests/out/dir-2.out

@@ -1,4 +1,6 @@+dir1/Hello.bat dir1/Hello.java dir1/Hello.sh+dir1/dir2/Hello.bat dir1/dir2/Hello.java dir1/dir2/Hello.sh

tests/out/dir-M.out

new file mode 100644@@ -0,0 +1,4 @@+dir1/Hello.bat+dir1/Hello.sh+dir1/dir2/Hello.bat+dir1/dir2/Hello.sh

tests/out/dir-O.out

new file mode 100644@@ -0,0 +1,2 @@+dir1/Hello.sh+dir1/dir2/Hello.sh

tests/out/dir-S.out

@@ -1,4 +1,6 @@+dir1/Hello.bat dir1/Hello.java dir1/Hello.sh+dir1/dir2/Hello.bat dir1/dir2/Hello.java dir1/dir2/Hello.sh

tests/out/dir-t.out

@@ -1,2 +1,4 @@+dir1/Hello.bat dir1/Hello.sh+dir1/dir2/Hello.bat dir1/dir2/Hello.sh

tests/out/dir.out

@@ -1 +1,2 @@+dir1/Hello.bat dir1/Hello.sh

tests/verify.sh

@@ -2,6 +2,8 @@  UG="../src/ugrep --color=always --sort $@" +FILES="Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+ if test ! -x "../src/ugrep" ; then   echo "../src/ugrep not found, exiting"   exit 1@@ -90,8 +92,10 @@ mkdir -p dir1 dir2  ln -s ../Hello.java dir1 cp Hello.sh dir1+cp Hello.bat dir1 ln -s ../Hello.java dir2 cp Hello.sh dir2+cp Hello.bat dir2 ln -s ../dir2 dir1 ln -s ../dir1 dir2 cat > dir1/.gitignore << END@@ -106,6 +110,10 @@ $UG -rl                                  Hello dir1 | $DIFF out/dir.out printf . $UG -Rl                                  Hello dir1 | $DIFF out/dir-S.out             || ERR "-Rl Hello dir1" printf .+$UG -Rl -Osh                             Hello dir1 | $DIFF out/dir-O.out             || ERR "-Rl -Osh Hello dir1"+printf .+$UG -Rl -M'#!/bin/sh'                    Hello dir1 | $DIFF out/dir-M.out             || ERR "-Rl -M'#!/bin/sh' Hello dir1"+printf . $UG -Rl -tShell                          Hello dir1 | $DIFF out/dir-t.out             || ERR "-Rl -tShell Hello dir1" printf . $UG -1l                                  Hello dir1 | $DIFF out/dir-1.out             || ERR "-1l Hello dir1"@@ -174,143 +182,143 @@ printf . $UG -Zio Lorem lorem.utf8.txt | $DIFF out/lorem_Lorem-Zio.out  || ERR "-Zio Lorem lorem.utf8.txt"  printf .-$UG -ci hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+$UG -ci hello $FILES \     | $DIFF out/Hello_Hello-ci.out \-    || ERR "-ci hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-ci hello $FILES" printf .-$UG -cj hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+$UG -cj hello $FILES \     | $DIFF out/Hello_Hello-cj.out \-    || ERR "-cj hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-cj hello $FILES"  printf .-$UG -e Hello -e '".*?"' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+$UG -e Hello -e '".*?"' $FILES \     | $DIFF out/Hello_Hello-ee.out \-    || ERR "-e Hello -e '\".*?\"' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-e Hello -e '\".*?\"' $FILES" printf .-$UG -e Hello -N '".*?"' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+$UG -e Hello -N '".*?"' $FILES \     | $DIFF out/Hello_Hello-eN.out \-    || ERR "-e Hello -N '\".*?\"' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-e Hello -N '\".*?\"' $FILES" printf .-$UG --max-count=1 Hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+$UG --max-count=1 Hello $FILES \     | $DIFF out/Hello_Hello--max-count.out \-    || ERR "--max-count=1 Hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "--max-count=1 Hello $FILES" printf .-$UG --max-files=1 Hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+$UG --max-files=1 Hello $FILES \     | $DIFF out/Hello_Hello--max-files.out \-    || ERR "--max-files=1 Hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "--max-files=1 Hello $FILES" printf .-$UG --range=1,1   Hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+$UG --range=1,1   Hello $FILES \     | $DIFF out/Hello_Hello--range.out \-    || ERR "--range=1,1 Hello Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "--range=1,1 Hello $FILES"  for PAT in '' 'Hello' '\w+\s+\S+' '\S\n\S' 'nomatch' ; do   FN=`echo "Hello_$PAT" | tr -Cd '[:alnum:]_'`   for OUT in '' '-I' '-W' '-X' ; do     for OPS in '' '-l' '-lv' '-c' '-co' '-cv' '-n' '-nkbT' '-unkbT' '-o' '-on' '-onkbT' '-ounkbT' '-v' '-nv' '-C2' '-nC2' '-vC2' '-nvC2' '-y' '-ny' '-vy' '-nvy' ; do       printf .-      $UG -U $OUT $OPS "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+      $UG -U $OUT $OPS "$PAT" $FILES \         | $DIFF "out/$FN$OUT$OPS.out" \-        || ERR "$OUT $OPS '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+        || ERR "$OUT $OPS '$PAT' $FILES"     done   done   for OUT in '--csv' '--json' '--xml' ; do     for OPS in '' '-l' '-lv' '-c' '-co' '-cv' '-n' '-v' '-nv' '-nkb' '-unkb' '-o' '-on' '-onkb' '-ounkb' ; do       printf .-      $UG -U $OUT $OPS "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+      $UG -U $OUT $OPS "$PAT" $FILES \         | $DIFF "out/$FN$OUT$OPS.out" \-        || ERR "$OUT $OPS '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+        || ERR "$OUT $OPS '$PAT' $FILES"     done   done   printf .-  $UG -U --tag "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+  $UG -U --tag "$PAT" $FILES \     | $DIFF "out/$FN--tag.out" \-    || ERR "--tag '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "--tag '$PAT' $FILES"   printf .-  $UG -U --format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+  $UG -U --format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' "$PAT" $FILES \     | $DIFF "out/$FN--format.out" \-    || ERR "--format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "--format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' '$PAT' $FILES"   printf .-  $UG -U -v --format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+  $UG -U -v --format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' "$PAT" $FILES \     | $DIFF "out/$FN-v--format.out" \-    || ERR "-v --format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-v --format-open='%m) %f:%~' --format='  %m) %n,%k %w-%d%~' --format-close='%~' '$PAT' $FILES"   printf .-  $UG -U -Iw "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+  $UG -U -Iw "$PAT" $FILES \     | $DIFF "out/$FN-Iw.out" \-    || ERR "-Iw '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-Iw '$PAT' $FILES"   printf .-  $UG -U -Ix "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+  $UG -U -Ix "$PAT" $FILES \     | $DIFF "out/$FN-Ix.out" \-    || ERR "-Ix '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-Ix '$PAT' $FILES"   printf .-  $UG -U -F  "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+  $UG -U -F  "$PAT" $FILES \     | $DIFF "out/$FN-F.out" \-    || ERR "-F '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-F '$PAT' $FILES"   printf .-  $UG -U -Fw "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+  $UG -U -Fw "$PAT" $FILES \     | $DIFF "out/$FN-Fw.out" \-    || ERR "-Fw '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-Fw '$PAT' $FILES"   printf .-  $UG -U -Fx "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+  $UG -U -Fx "$PAT" $FILES \     | $DIFF "out/$FN-Fx.out" \-    || ERR "-Fx '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-Fx '$PAT' $FILES"   printf .   if [ "$PAT" == '\w+\s+\S+' ]; then-    $UG -U -G  '\w\+\s\+\S\+' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+    $UG -U -G  '\w\+\s\+\S\+' $FILES \       | $DIFF "out/$FN-G.out" \-      || ERR "-G '\w\+\s\+\S\+' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"-    $UG -U -Gw '\w\+\s\+\S\+' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+      || ERR "-G '\w\+\s\+\S\+' $FILES"+    $UG -U -Gw '\w\+\s\+\S\+' $FILES \       | $DIFF "out/$FN-Gw.out" \-      || ERR "-Gw '\w\+\s\+\S\+' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"-    $UG -U -Gx '\w\+\s\+\S\+' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+      || ERR "-Gw '\w\+\s\+\S\+' $FILES"+    $UG -U -Gx '\w\+\s\+\S\+' $FILES \       | $DIFF "out/$FN-Gx.out" \-      || ERR "-Gx '\w\+\s\+\S\+' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+      || ERR "-Gx '\w\+\s\+\S\+' $FILES"   else-    $UG -U -G  "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+    $UG -U -G  "$PAT" $FILES \       | $DIFF "out/$FN-G.out" \-      || ERR "-G '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"-    $UG -U -Gw "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+      || ERR "-G '$PAT' $FILES"+    $UG -U -Gw "$PAT" $FILES \       | $DIFF "out/$FN-Gw.out" \-      || ERR "-Gw '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"-    $UG -U -Gx "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+      || ERR "-Gw '$PAT' $FILES"+    $UG -U -Gx "$PAT" $FILES \       | $DIFF "out/$FN-Gx.out" \-      || ERR "-Gx '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+      || ERR "-Gx '$PAT' $FILES"   fi   if [ "$have_pcre2" == yes ] || [ "$have_boost_regex" == yes ]; then     printf .-    $UG -U -IP  "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+    $UG -U -IP  "$PAT" $FILES \       | $DIFF "out/$FN-IP.out" \-      || ERR "-IP '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+      || ERR "-IP '$PAT' $FILES"     printf .-    $UG -U -IPw "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+    $UG -U -IPw "$PAT" $FILES \       | $DIFF "out/$FN-IPw.out" \-      || ERR "-IPw '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+      || ERR "-IPw '$PAT' $FILES"     printf .-    $UG -U -IPx "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+    $UG -U -IPx "$PAT" $FILES \       | $DIFF "out/$FN-IPx.out" \-      || ERR "-IPx '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+      || ERR "-IPx '$PAT' $FILES"   fi done  for PAT in '' 'Hello World' 'Hello -World' 'Hello -World|greeting' 'Hello -(greeting|World)' '"a Hello" greeting' ; do   FN=`echo "Hello_$PAT" | tr -Cd '[:alnum:]_-'`   printf .-  $UG -U --bool "$PAT" Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+  $UG -U --bool "$PAT" $FILES \     | $DIFF "out/$FN--bool.out" \-    || ERR "--bool '$PAT' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "--bool '$PAT' $FILES" done  printf .-$UG -U -e 'Hello' --and 'World' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+$UG -U -e 'Hello' --and 'World' $FILES \     | $DIFF "out/Hello--and.out" \-    || ERR "-e 'Hello' --and 'World' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-e 'Hello' --and 'World' $FILES" printf .-$UG -U -e 'Hello' --andnot 'World' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+$UG -U -e 'Hello' --andnot 'World' $FILES \     | $DIFF "out/Hello--andnot.out" \-    || ERR "-e 'Hello' --andnot 'World' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-e 'Hello' --andnot 'World' $FILES" printf .-$UG -U -e 'Hello' --and --not 'World' -e 'greeting' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt \+$UG -U -e 'Hello' --and --not 'World' -e 'greeting' $FILES \     | $DIFF "out/Hello--and--not.out" \-    || ERR "-e 'Hello' --and --not 'World' -e 'greeting' Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt"+    || ERR "-e 'Hello' --and --not 'World' -e 'greeting' $FILES"  if [ "$have_libz" == yes ]; then printf .