@ 260915.5

231111.2 · 2801e5a1f90ba07ceb3d87b7a47ef0662930d512

add brotli decompression #312

tested and working: new m4/ax_check_brotlilib.m4, updated autotools; updated ugrep.cpp

reading declarations

Makefile.in

@@ -90,6 +90,7 @@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_boost_regex.m4 \+	$(top_srcdir)/m4/ax_check_brotlilib.m4 \ 	$(top_srcdir)/m4/ax_check_bzlib.m4 \ 	$(top_srcdir)/m4/ax_check_lz4lib.m4 \ 	$(top_srcdir)/m4/ax_check_lzmalib.m4 \

aclocal.m4

@@ -1247,6 +1247,7 @@ AC_SUBST([am__untar]) ]) # _AM_PROG_TAR  m4_include([m4/ax_boost_regex.m4])+m4_include([m4/ax_check_brotlilib.m4]) m4_include([m4/ax_check_bzlib.m4]) m4_include([m4/ax_check_lz4lib.m4]) m4_include([m4/ax_check_lzmalib.m4])

config.h.in

@@ -22,6 +22,9 @@ /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if you have `brotli' library (-lbrotlidec -lbrotlienc) */+#undef HAVE_LIBBROTLI+ /* Define to 1 if you have `bz2' library (-lbz2) */ #undef HAVE_LIBBZ2 

configure

@@ -777,6 +777,7 @@ with_bzlib with_lzma with_lz4 with_zstd+with_brotlilib with_grep_path with_grep_colors enable_auto_color@@ -1476,6 +1477,10 @@ Optional Packages:   --with-zstd=DIR         root directory path of zstd installation [defaults to                           /usr/local or /usr if not found in /usr/local]   --without-zstd          to disable zstd usage completely+  --with-brotlilib=DIR    root directory path of brotli library installation+                          [defaults to /usr/local or /usr if not found in+                          /usr/local]+  --without-brotlilib     to disable brotli library usage completely   --with-grep-path=GREP_PATH                           specifies the GREP_PATH if different than the                           default DATAROOTDIR/ugrep/patterns@@ -8360,6 +8365,139 @@ printf "%s\n" "#define HAVE_LIBZSTD 1" >>confdefs.h fi  +#+# Handle user hints+#+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if brotlilib is wanted" >&5+printf %s "checking if brotlilib is wanted... " >&6; }+brotlilib_places="/usr/local /usr /opt/homebrew /opt/local /sw"++# Check whether --with-brotlilib was given.+if test ${with_brotlilib+y}+then :+  withval=$with_brotlilib; if test "$withval" != "no" ; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5+printf "%s\n" "yes" >&6; }+  if test -d "$withval"+  then+    brotlilib_places="$withval $brotlilib_places"+  else+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Sorry, $withval does not exist, checking usual places" >&5+printf "%s\n" "$as_me: WARNING: Sorry, $withval does not exist, checking usual places" >&2;}+  fi+else+  brotlilib_places=""+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+else $as_nop+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5+printf "%s\n" "yes" >&6; }+fi++#+# Locate brotlilib, if wanted+#+if test -n "${brotlilib_places}"+then+  # check the user supplied or any other more or less 'standard' place:+  #   Most UNIX systems      : /usr/local and /usr+  #   MacPorts / Fink on OSX : /opt/local respectively /sw+  for BROTLILIB_HOME in ${brotlilib_places} ; do+    if test -f "${BROTLILIB_HOME}/include/brotli/decode.h"; then break; fi+    BROTLILIB_HOME=""+  done++  BROTLILIB_OLD_LDFLAGS=$LDFLAGS+  BROTLILIB_OLD_CPPFLAGS=$CPPFLAGS+  if test -n "${BROTLILIB_HOME}"; then+    LDFLAGS="$LDFLAGS -L${BROTLILIB_HOME}/lib"+    CPPFLAGS="$CPPFLAGS -I${BROTLILIB_HOME}/include"+  fi+  ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BrotliDecoderCreateInstance in -lbrotlidec" >&5+printf %s "checking for BrotliDecoderCreateInstance in -lbrotlidec... " >&6; }+if test ${ac_cv_lib_brotlidec_BrotliDecoderCreateInstance+y}+then :+  printf %s "(cached) " >&6+else $as_nop+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lbrotlidec  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+char BrotliDecoderCreateInstance ();+int+main (void)+{+return BrotliDecoderCreateInstance ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  ac_cv_lib_brotlidec_BrotliDecoderCreateInstance=yes+else $as_nop+  ac_cv_lib_brotlidec_BrotliDecoderCreateInstance=no+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_brotlidec_BrotliDecoderCreateInstance" >&5+printf "%s\n" "$ac_cv_lib_brotlidec_BrotliDecoderCreateInstance" >&6; }+if test "x$ac_cv_lib_brotlidec_BrotliDecoderCreateInstance" = xyes+then :+  brotlilib_cv_libbrotli=yes+else $as_nop+  brotlilib_cv_libbrotli=no+fi++  ac_fn_c_check_header_compile "$LINENO" "brotli/decode.h" "ac_cv_header_brotli_decode_h" "$ac_includes_default"+if test "x$ac_cv_header_brotli_decode_h" = xyes+then :+  brotlilib_cv_brotli_h=yes+else $as_nop+  brotlilib_cv_brotli_h=no+fi++  ac_ext=cpp+ac_cpp='$CXXCPP $CPPFLAGS'+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu++  if test "$brotlilib_cv_libbrotli" = "yes" && test "$brotlilib_cv_brotli_h" = "yes"+  then+    #+    # If both library and header were found, action-if-found+    #++                CPPFLAGS="$CPPFLAGS -I${BROTLILIB_HOME}/include"+                LDFLAGS="$LDFLAGS -L${BROTLILIB_HOME}/lib"+                LIBS="-lbrotlidec -lbrotlienc $LIBS"++printf "%s\n" "#define HAVE_LIBBROTLI 1" >>confdefs.h+++  else+    #+    # If either header or library was not found, action-if-not-found+    #+    echo "brotli library not found: ugrep option -z won't decompress .br files"+  fi+fi++  # Check whether --with-grep-path was given. if test ${with_grep_path+y}

configure.ac

@@ -78,6 +78,8 @@ AX_CHECK_LZ4LIB([], [echo "liblz4 not found: ugrep option -z won't decompress .l  AX_CHECK_ZSTDLIB([], [echo "libzstd not found: ugrep option -z won't decompress .zst files"]) +AX_CHECK_BROTLILIB([], [echo "brotli library not found: ugrep option -z won't decompress .br files"])+ AC_ARG_WITH(grep-path,   [AS_HELP_STRING([--with-grep-path=GREP_PATH],                   [specifies the GREP_PATH if different than the default DATAROOTDIR/ugrep/patterns])],

lib/Makefile.in

@@ -91,6 +91,7 @@ host_triplet = @host@ subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_boost_regex.m4 \+	$(top_srcdir)/m4/ax_check_brotlilib.m4 \ 	$(top_srcdir)/m4/ax_check_bzlib.m4 \ 	$(top_srcdir)/m4/ax_check_lz4lib.m4 \ 	$(top_srcdir)/m4/ax_check_lzmalib.m4 \

m4/ax_check_brotlilib.m4

new file mode 100644@@ -0,0 +1,138 @@+# SYNOPSIS+#+#   AX_CHECK_BROTLILIB([action-if-found], [action-if-not-found])+#+# DESCRIPTION+#+#   This macro searches for an installed brotli library. If nothing was+#   specified when calling configure, it searches first in /usr/local and+#   then in /usr, /opt/local and /sw. If the --with-brotlilib=DIR is specified,+#   it will try to find it in DIR/include/brotli/decode.h and+#   DIR/lib/libbrotlidec. If --without-brotlilib is specified, the library is+#   not searched at all.+#+#   If either the header file (brotli/decode.h) or the library (libbrotlidec)+#   is not found, shell commands 'action-if-not-found' is run. If+#   'action-if-not-found' is not specified, the configuration exits on error,+#   asking for a valid brotli library installation directory or+#   --without-brotlilib.+#+#   If both header file and library are found, shell commands+#   'action-if-found' is run. If 'action-if-found' is not specified, the+#   default action appends '-I${BROTLILIB_HOME}/include' to CPFLAGS, appends+#   '-L${BROTLILIB_HOME}/lib' to LDFLAGS, prepends '-lbrotlidec' and+#   '-lbrotlienc' to LIBS, and calls AC_DEFINE(HAVE_LIBBROTLI). You should use+#   autoheader to include a definition for this symbol in a config.h file.+#   Sample usage in a C/C++ source is as follows:+#+#     #ifdef HAVE_LIBBROTLI+#     #include <brotli/decode.h>+#     #include <brotli/encode.h>+#     #endif /* HAVE_LIBBROTLI */+#+# LICENSE+#+#   Copyright (c) 2023 Robert van Engelen <engelen@acm.org>+#+#   This program is free software; you can redistribute it and/or modify it+#   under the terms of the GNU General Public License as published by the+#   Free Software Foundation; either version 2 of the License, or (at your+#   option) any later version.+#+#   This program is distributed in the hope that it will be useful, but+#   WITHOUT ANY WARRANTY; without even the implied warranty of+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General+#   Public License for more details.+#+#   You should have received a copy of the GNU General Public License along+#   with this program. If not, see <https://www.gnu.org/licenses/>.+#+#   As a special exception, the respective Autoconf Macro's copyright owner+#   gives unlimited permission to copy, distribute and modify the configure+#   scripts that are the output of Autoconf when processing the Macro. You+#   need not follow the terms of the GNU General Public License when using+#   or distributing such scripts, even though portions of the text of the+#   Macro appear in them. The GNU General Public License (GPL) does govern+#   all other use of the material that constitutes the Autoconf Macro.+#+#   This special exception to the GPL applies to versions of the Autoconf+#   Macro released by the Autoconf Archive. When you make and distribute a+#   modified version of the Autoconf Macro, you may extend this special+#   exception to the GPL to apply to your modified version as well.++#serial 1++AC_DEFUN([AX_CHECK_BROTLILIB],+#+# Handle user hints+#+[AC_MSG_CHECKING(if brotlilib is wanted)+brotlilib_places="/usr/local /usr /opt/homebrew /opt/local /sw"+AC_ARG_WITH([brotlilib],+[  --with-brotlilib=DIR    root directory path of brotli library installation+                          @<:@defaults to /usr/local or /usr if not found in+                          /usr/local@:>@+  --without-brotlilib     to disable brotli library usage completely],+[if test "$withval" != "no" ; then+  AC_MSG_RESULT(yes)+  if test -d "$withval"+  then+    brotlilib_places="$withval $brotlilib_places"+  else+    AC_MSG_WARN([Sorry, $withval does not exist, checking usual places])+  fi+else+  brotlilib_places=""+  AC_MSG_RESULT(no)+fi],+[AC_MSG_RESULT(yes)])+#+# Locate brotlilib, if wanted+#+if test -n "${brotlilib_places}"+then+  # check the user supplied or any other more or less 'standard' place:+  #   Most UNIX systems      : /usr/local and /usr+  #   MacPorts / Fink on OSX : /opt/local respectively /sw+  for BROTLILIB_HOME in ${brotlilib_places} ; do+    if test -f "${BROTLILIB_HOME}/include/brotli/decode.h"; then break; fi+    BROTLILIB_HOME=""+  done++  BROTLILIB_OLD_LDFLAGS=$LDFLAGS+  BROTLILIB_OLD_CPPFLAGS=$CPPFLAGS+  if test -n "${BROTLILIB_HOME}"; then+    LDFLAGS="$LDFLAGS -L${BROTLILIB_HOME}/lib"+    CPPFLAGS="$CPPFLAGS -I${BROTLILIB_HOME}/include"+  fi+  AC_LANG_PUSH([C])+  AC_CHECK_LIB([brotlidec], [BrotliDecoderCreateInstance], [brotlilib_cv_libbrotli=yes], [brotlilib_cv_libbrotli=no])+  AC_CHECK_HEADER([brotli/decode.h], [brotlilib_cv_brotli_h=yes], [brotlilib_cv_brotli_h=no])+  AC_LANG_POP([C])+  if test "$brotlilib_cv_libbrotli" = "yes" && test "$brotlilib_cv_brotli_h" = "yes"+  then+    #+    # If both library and header were found, action-if-found+    #+    m4_ifblank([$1],[+                CPPFLAGS="$CPPFLAGS -I${BROTLILIB_HOME}/include"+                LDFLAGS="$LDFLAGS -L${BROTLILIB_HOME}/lib"+                LIBS="-lbrotlidec -lbrotlienc $LIBS"+                AC_DEFINE([HAVE_LIBBROTLI], [1],+                          [Define to 1 if you have `brotli' library (-lbrotlidec -lbrotlienc)])+               ],[+                # Restore variables+                LDFLAGS="$BROTLILIB_OLD_LDFLAGS"+                CPPFLAGS="$BROTLILIB_OLD_CPPFLAGS"+                $1+               ])+  else+    #+    # If either header or library was not found, action-if-not-found+    #+    m4_default([$2],[+                AC_MSG_ERROR([either specify a valid brotli library installation with --with-brotlilib=DIR or disable brotlilib usage with --without-brotlilib])+                ])+  fi+fi+])

src/Makefile.in

@@ -92,6 +92,7 @@ bin_PROGRAMS = ugrep$(EXEEXT) subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_boost_regex.m4 \+	$(top_srcdir)/m4/ax_check_brotlilib.m4 \ 	$(top_srcdir)/m4/ax_check_bzlib.m4 \ 	$(top_srcdir)/m4/ax_check_lz4lib.m4 \ 	$(top_srcdir)/m4/ax_check_lzmalib.m4 \

src/ugrep.cpp

@@ -47,12 +47,13 @@ This program uses RE/flex:  Optional libraries to support options -P and -z: -  -P: PCRE2 or Boost.Regex+  -P: PCRE2 (or Boost.Regex)   -z: zlib (.gz)-  -z: libbz2 (.bz, bz2, .bzip2)-  -z: liblzma (.lzma, .xz)-  -z: liblz4 (.lz4)-  -z: libzstd (.zst, .zstd)+  -z: bz2 (.bz, bz2, .bzip2)+  -z: lzma (.lzma, .xz)+  -z: lz4 (.lz4)+  -z: zstd (.zst, .zstd)+  -z: brotli (.br)  Build ugrep as follows: @@ -120,6 +121,9 @@ After this, you may want to test ugrep and install it (optional): // optionally enable libzstd for -z // #define HAVE_LIBZSTD +// optionally enable brotli library for -z+// #define HAVE_LIBBROTLI+ #include <stringapiset.h>       // internationalization #include <direct.h>             // directory access #include <winsock.h>            // gethostname() for --hyperlink@@ -996,7 +1000,7 @@ struct Zthread {         // notify the decompression thread filter_tar/filter_cpio of the closed pipe         pipe_ready.notify_one(); -        // when an error occurred, we should still need to notify the receiver in case it is waiting on the partname+        // when an error occurred, we still need to notify the receiver in case it is waiting on the partname         std::unique_lock<std::mutex> lock(pipe_mutex);         assigned = true;         part_ready.notify_one();@@ -1248,7 +1252,7 @@ struct Zthread {        extracting = false; -      // when an error occurred or nothing was selected, then we may still need to notify the receiver in case it is waiting on the partname+      // when an error occurred or nothing was selected, then we still need to notify the receiver in case it is waiting on the partname       if (chained)       {         std::unique_lock<std::mutex> lock(pipe_mutex);@@ -4628,7 +4632,7 @@ static void set_depth_long(const char *arg) {   const char *range = arg;   set_depth(range);-  +   if (range[1] != '\0')     usage("invalid argument --depth=", arg); }@@ -7060,14 +7064,6 @@ void terminal()         if (flag_tree.is_undefined())           flag_tree = true;       }-      else if (flag_apply_color != NULL)-      {-        // --colors: if output is to a TTY then enable --color and use the specified --colors--        // enable --color-        if (flag_apply_color == NULL)-          flag_apply_color = "auto";-      }        if (flag_query)       {@@ -7545,6 +7541,12 @@ void ugrep()     flag_all_include.emplace_back("*.tar.zstd");     flag_all_include.emplace_back("*.tzst"); #endif++#ifdef HAVE_LIBBROTLI+    flag_all_include.emplace_back("*.cpio.br");+    flag_all_include.emplace_back("*.pax.br");+    flag_all_include.emplace_back("*.tar.br");+#endif   } #endif #endif@@ -13843,6 +13845,10 @@ void help(std::ostream& out) #ifdef HAVE_LIBZSTD             ",\n\             zstd (requires suffix .zst, .zstd, .tzst)"+#endif+#ifdef HAVE_LIBBROTLI+            ",\n\+            brotli (requires suffix .br)" #endif             ".\n" #endif@@ -14249,6 +14255,9 @@ void version() #ifdef HAVE_LIBZSTD     ",zstd" << #endif+#ifdef HAVE_LIBBROTLI+    ",brotli" <<+#endif #endif     "\n"     "License: BSD-3-Clause;  ugrep user guide:  https://ugrep.com\n"

src/ugrep.hpp

@@ -401,7 +401,7 @@ inline const char *utf8skipn(const char *s, size_t n, size_t k) # define DEFAULT_MAX_MMAP_SIZE MAX_MMAP_SIZE #endif -// pretty is disabled by default, unless enabled with WITH_PRETTY+// pretty is disabled by default for ugrep (enabled by ug), unless enabled with WITH_PRETTY #ifdef WITH_PRETTY # define DEFAULT_PRETTY true #else

tests/archive.tar.br

new file mode 100644Binary file changed

tests/gen.sh

@@ -144,15 +144,16 @@ rm -f archive.* ls $FILES | cpio -o --quiet > archive.cpio ls $FILES | pax -w -f archive.pax tar cf archive.tar $FILES-compress -c archive.tar > archive.tZ-gzip  -9 -c archive.tar > archive.tgz-bzip2 -9 -c archive.tar > archive.tbz-lzma  -9 -c archive.tar > archive.tlz-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 $FILES+compress  -c archive.tar > archive.tZ+gzip   -9 -c archive.tar > archive.tgz+bzip2  -9 -c archive.tar > archive.tbz+lzma   -9 -c archive.tar > archive.tlz+xz     -9 -c archive.tar > archive.txz+lz4    -9 -c archive.tar > archive.tar.lz4+zstd   -9 -c archive.tar > archive.tzst+brotli -9 -c archive.tar > archive.tar.br+zip    -9 -q archive.tar.zip archive.tar+zip    -9 -q archive.zip $FILES  tar cfz archive2.tgz archive.tar $FILES archive.tgz tar cfz archive3.tgz archive.tgz $FILES archive2.tgz@@ -169,6 +170,7 @@ $UG -z -c Hello archive.tlz     > out/archive.tlz.out $UG -z -c Hello archive.txz     > out/archive.txz.out $UG -z -c Hello archive.tar.lz4 > out/archive.tar.lz4.out $UG -z -c Hello archive.tzst    > out/archive.tzst.out+$UG -z -c Hello archive.tar.br  > out/archive.tar.br.out  $UG -z -c -tShell Hello archive.cpio    > out/archive-t.cpio.out $UG -z -c -tShell Hello archive.pax     > out/archive-t.pax.out@@ -182,6 +184,7 @@ $UG -z -c -tShell Hello archive.tlz     > out/archive-t.tlz.out $UG -z -c -tShell Hello archive.txz     > out/archive-t.txz.out $UG -z -c -tShell Hello archive.tar.lz4 > out/archive-t.tar.lz4.out $UG -z -c -tShell Hello archive.tzst    > out/archive-t.tzst.out+$UG -z -c -tShell Hello archive.tar.br  > out/archive-t.tar.br.out  $UG --zmax=2 -z -c Hello archive2.tgz         > out/archive2.tgz.out $UG --zmax=3 -z -c Hello archive3.tgz         > out/archive3.tgz.out

tests/out/archive-t.tar.br.out

new file mode 100644@@ -0,0 +1,2 @@+archive.tar.br{Hello.bat}:1+archive.tar.br{Hello.sh}:1

tests/out/archive.tar.br.out

new file mode 100644@@ -0,0 +1,8 @@+archive.tar.br{Hello.bat}:1+archive.tar.br{Hello.class}:1+archive.tar.br{Hello.java}:2+archive.tar.br{Hello.pdf}:1+archive.tar.br{Hello.sh}:1+archive.tar.br{Hello.txt}:1+archive.tar.br{empty.txt}:0+archive.tar.br{emptyline.txt}:0

tests/verify.sh

@@ -28,7 +28,7 @@ else   have_pcre2=no fi -echo "Have libpcre2?" $have_pcre2+printf "Have libpcre2?  %3s (recommended)\n" $have_pcre2  if test "$have_pcre2" = "no" ; then   if $UG -Fq 'HAVE_BOOST_REGEX 1' "$CONFIGH" ; then@@ -37,7 +37,7 @@ if test "$have_pcre2" = "no" ; then     have_boost_regex=no   fi -  echo "Have libboost_regex?" $have_boost_regex+  printf "Have libboost_regex? %s (optional)\n" $have_boost_regex fi  if $UG -Fq 'HAVE_LIBZ 1' "$CONFIGH" ; then@@ -46,7 +46,7 @@ else   have_libz=no fi -echo "Have libz?" $have_libz+printf "Have libz?      %3s (recommended)\n" $have_libz  if $UG -Fq 'HAVE_LIBBZ2 1' "$CONFIGH" ; then   have_libbz2=yes@@ -54,7 +54,7 @@ else   have_libbz2=no fi -echo "Have libbz2?" $have_libbz2+printf "Have libbz2?    %3s (recommended)\n" $have_libbz2  if $UG -Fq 'HAVE_LIBLZMA 1' "$CONFIGH" ; then   have_liblzma=yes@@ -62,7 +62,7 @@ else   have_liblzma=no fi -echo "Have liblzma?" $have_liblzma+printf "Have liblzma?   %3s (recommended)\n" $have_liblzma  if $UG -Fq 'HAVE_LIBLZ4 1' "$CONFIGH" ; then   have_liblz4=yes@@ -70,7 +70,7 @@ else   have_liblz4=no fi -echo "Have liblz4?" $have_liblz4+printf "Have liblz4?    %3s (optional)\n" $have_liblz4  if $UG -Fq 'HAVE_LIBZSTD 1' "$CONFIGH" ; then   have_libzstd=yes@@ -78,7 +78,15 @@ else   have_libzstd=no fi -echo "Have libzstd?" $have_libzstd+printf "Have libzstd?   %3s (optional)\n" $have_libzstd++if $UG -Fq 'HAVE_LIBBROTLI 1' "$CONFIGH" ; then+  have_libbrotli=yes+else+  have_libbrotli=no+fi++printf "Have libbrotli? %3s (optional)\n" $have_libbrotli  export GREP_COLORS='cx=hb:ms=hug:mc=ib+W:fn=h35:ln=32h:cn=1;32:bn=1;32:se=+36' @@ -366,6 +374,10 @@ if [ "$have_libzstd" == yes ]; then printf . $UG -z -c Hello archive.tzst    | $DIFF out/archive.tzst.out    || ERR "-z -c Hello archive.tzst" fi+if [ "$have_libbrotli" == yes ]; then+printf .+$UG -z -c Hello archive.tar.br  | $DIFF out/archive.tar.br.out  || ERR "-z -c Hello archive.tar.br"+fi fi  if [ "$have_libz" == yes ]; then@@ -401,6 +413,10 @@ if [ "$have_libzstd" == yes ]; then printf . $UG -z -c -tShell Hello archive.tzst    | $DIFF out/archive-t.tzst.out    || ERR "-z -c -tShell Hello archive.tzst" fi+if [ "$have_libbrotli" == yes ]; then+printf .+$UG -z -c -tShell Hello archive.tar.br  | $DIFF out/archive-t.tar.br.out  || ERR "-z -c -tShell Hello archive.tar.br"+fi fi  if [ "$have_libz" == yes ]; then