231112.1 · 8dd59688c4386b8b699cffdd18b46730a832da23
add bzip3 decompression #311
tested and working: new m4/ax_check_bzip3lib.m4, updated autotools; updated ugrep.cpp; updated tests
reading declarations
@@ -70,7 +70,8 @@ install-data-hook: echo "| alias zpgrep = 'ug -zP' |"; \ echo "| alias ux = 'ugrep -U --hexdump' |"; \ echo "| alias zxgrep = 'ugrep -zU --hexdump' |"; \- echo "| alias xdump = 'ugrep -X \"\"' |"; \+ echo "| alias xdump = 'ugrep --hexdump \"\"' |"; \+ echo "| alias zmore = 'ugrep+ -z -I -+ --pager \"\"' |"; \ echo "| |"; \ echo "| Thank you for using ugrep! |"; \ echo "| |"; \
@@ -91,7 +91,8 @@ 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_bz2lib.m4 \+ $(top_srcdir)/m4/ax_check_bzip3lib.m4 \ $(top_srcdir)/m4/ax_check_lz4lib.m4 \ $(top_srcdir)/m4/ax_check_lzmalib.m4 \ $(top_srcdir)/m4/ax_check_pcre2.m4 \@@ -955,7 +956,8 @@ install-data-hook: echo "| alias zpgrep = 'ug -zP' |"; \ echo "| alias ux = 'ugrep -U --hexdump' |"; \ echo "| alias zxgrep = 'ugrep -zU --hexdump' |"; \- echo "| alias xdump = 'ugrep -X \"\"' |"; \+ echo "| alias xdump = 'ugrep --hexdump \"\"' |"; \+ echo "| alias zmore = 'ugrep+ -z -I -+ --pager \"\"' |"; \ echo "| |"; \ echo "| Thank you for using ugrep! |"; \ echo "| |"; \
@@ -1248,7 +1248,8 @@ AC_SUBST([am__untar]) 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_bz2lib.m4])+m4_include([m4/ax_check_bzip3lib.m4]) m4_include([m4/ax_check_lz4lib.m4]) m4_include([m4/ax_check_lzmalib.m4]) m4_include([m4/ax_check_pcre2.m4])
@@ -28,6 +28,9 @@ /* Define to 1 if you have `bz2' library (-lbz2) */ #undef HAVE_LIBBZ2 +/* Define to 1 if you have `bzip3' library (-lbzip3) */+#undef HAVE_LIBBZIP3+ /* Define to 1 if you have `lz4' library (-llz4) */ #undef HAVE_LIBLZ4
@@ -777,7 +777,8 @@ with_bzlib with_lzma with_lz4 with_zstd-with_brotlilib+with_brotli+with_bzip3 with_grep_path with_grep_colors enable_auto_color@@ -1477,10 +1478,14 @@ 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+ --with-brotli=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+ --without-brotli to disable brotli library usage completely+ --with-bzip3=DIR root directory path of bzip3 library installation+ [defaults to /usr/local or /usr if not found in+ /usr/local]+ --without-bzip3 to disable bzip3 library usage completely --with-grep-path=GREP_PATH specifies the GREP_PATH if different than the default DATAROOTDIR/ugrep/patterns@@ -7871,16 +7876,16 @@ 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 BZLIB_HOME in ${bzlib_places} ; do- if test -f "${BZLIB_HOME}/include/bzlib.h"; then break; fi- BZLIB_HOME=""+ for B2ZLIB_HOME in ${bzlib_places} ; do+ if test -f "${B2ZLIB_HOME}/include/bzlib.h"; then break; fi+ B2ZLIB_HOME="" done - BZLIB_OLD_LDFLAGS=$LDFLAGS- BZLIB_OLD_CPPFLAGS=$CPPFLAGS- if test -n "${BZLIB_HOME}"; then- LDFLAGS="$LDFLAGS -L${BZLIB_HOME}/lib"- CPPFLAGS="$CPPFLAGS -I${BZLIB_HOME}/include"+ B2ZLIB_OLD_LDFLAGS=$LDFLAGS+ B2ZLIB_OLD_CPPFLAGS=$CPPFLAGS+ if test -n "${B2ZLIB_HOME}"; then+ LDFLAGS="$LDFLAGS -L${B2ZLIB_HOME}/lib"+ CPPFLAGS="$CPPFLAGS -I${B2ZLIB_HOME}/include" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS'@@ -7950,8 +7955,8 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # If both library and header were found, action-if-found # - CPPFLAGS="$CPPFLAGS -I${BZLIB_HOME}/include"- LDFLAGS="$LDFLAGS -L${BZLIB_HOME}/lib"+ CPPFLAGS="$CPPFLAGS -I${B2ZLIB_HOME}/include"+ LDFLAGS="$LDFLAGS -L${B2ZLIB_HOME}/lib" LIBS="-lbz2 $LIBS" printf "%s\n" "#define HAVE_LIBBZ2 1" >>confdefs.h@@ -8368,25 +8373,25 @@ 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"+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if brotli is wanted" >&5+printf %s "checking if brotli is wanted... " >&6; }+brotli_places="/usr/local /usr /opt/homebrew /opt/local /sw" -# Check whether --with-brotlilib was given.-if test ${with_brotlilib+y}+# Check whether --with-brotli was given.+if test ${with_brotli+y} then :- withval=$with_brotlilib; if test "$withval" != "no" ; then+ withval=$with_brotli; 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"+ brotli_places="$withval $brotli_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=""+ brotli_places="" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi@@ -8396,23 +8401,23 @@ printf "%s\n" "yes" >&6; } fi #-# Locate brotlilib, if wanted+# Locate brotli, if wanted #-if test -n "${brotlilib_places}"+if test -n "${brotli_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+ for BROTLI_HOME in ${brotli_places} ; do if test -f "${BROTLILIB_HOME}/include/brotli/decode.h"; then break; fi- BROTLILIB_HOME=""+ BROTLI_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"+ BROTLI_OLD_LDFLAGS=$LDFLAGS+ BROTLI_OLD_CPPFLAGS=$CPPFLAGS+ if test -n "${BROTLI_HOME}"; then+ LDFLAGS="$LDFLAGS -L${BROTLI_HOME}/lib"+ CPPFLAGS="$CPPFLAGS -I${BROTLI_HOME}/include" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS'@@ -8457,17 +8462,17 @@ fi printf "%s\n" "$ac_cv_lib_brotlidec_BrotliDecoderCreateInstance" >&6; } if test "x$ac_cv_lib_brotlidec_BrotliDecoderCreateInstance" = xyes then :- brotlilib_cv_libbrotli=yes+ brotli_cv_libbrotli=yes else $as_nop- brotlilib_cv_libbrotli=no+ brotli_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+ brotli_cv_brotli_h=yes else $as_nop- brotlilib_cv_brotli_h=no+ brotli_cv_brotli_h=no fi ac_ext=cpp@@ -8476,14 +8481,14 @@ 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"+ if test "$brotli_cv_libbrotli" = "yes" && test "$brotli_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"+ CPPFLAGS="$CPPFLAGS -I${BROTLI_HOME}/include"+ LDFLAGS="$LDFLAGS -L${BROTLI_HOME}/lib" LIBS="-lbrotlidec -lbrotlienc $LIBS" printf "%s\n" "#define HAVE_LIBBROTLI 1" >>confdefs.h@@ -8498,6 +8503,139 @@ printf "%s\n" "#define HAVE_LIBBROTLI 1" >>confdefs.h fi +#+# Handle user hints+#+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if bzip3 is wanted" >&5+printf %s "checking if bzip3 is wanted... " >&6; }+bzip3_places="/usr/local /usr /opt/homebrew /opt/local /sw"++# Check whether --with-bzip3 was given.+if test ${with_bzip3+y}+then :+ withval=$with_bzip3; 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+ bzip3_places="$withval $bzip3_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+ bzip3_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 bzip3 library, if wanted+#+if test -n "${bzip3_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 BZIP3_HOME in ${bzip3_places} ; do+ if test -f "${BZIP3_HOME}/include/libbz3.h"; then break; fi+ BZIP3_HOME=""+ done++ BZIP3_OLD_LDFLAGS=$LDFLAGS+ BZIP3_OLD_CPPFLAGS=$CPPFLAGS+ if test -n "${BZIP3_HOME}"; then+ LDFLAGS="$LDFLAGS -L${BZIP3_HOME}/lib"+ CPPFLAGS="$CPPFLAGS -I${BZIP3_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 bz3_new in -lbzip3" >&5+printf %s "checking for bz3_new in -lbzip3... " >&6; }+if test ${ac_cv_lib_bzip3_bz3_new+y}+then :+ printf %s "(cached) " >&6+else $as_nop+ ac_check_lib_save_LIBS=$LIBS+LIBS="-lbzip3 $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 bz3_new ();+int+main (void)+{+return bz3_new ();+ ;+ return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+ ac_cv_lib_bzip3_bz3_new=yes+else $as_nop+ ac_cv_lib_bzip3_bz3_new=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_bzip3_bz3_new" >&5+printf "%s\n" "$ac_cv_lib_bzip3_bz3_new" >&6; }+if test "x$ac_cv_lib_bzip3_bz3_new" = xyes+then :+ bzip3_cv_libbzip3=yes+else $as_nop+ bzip3_cv_libbzip3=no+fi++ ac_fn_c_check_header_compile "$LINENO" "libbz3.h" "ac_cv_header_libbz3_h" "$ac_includes_default"+if test "x$ac_cv_header_libbz3_h" = xyes+then :+ bzip3_cv_libbz3_h=yes+else $as_nop+ bzip3_cv_libbz3_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 "$bzip3_cv_libbzip3" = "yes" && test "$bzip3_cv_libbz3_h" = "yes"+ then+ #+ # If both library and header were found, action-if-found+ #++ CPPFLAGS="$CPPFLAGS -I${BZIP3_HOME}/include"+ LDFLAGS="$LDFLAGS -L${BZIP3_HOME}/lib"+ LIBS="-lbzip3 $LIBS"++printf "%s\n" "#define HAVE_LIBBZIP3 1" >>confdefs.h+++ else+ #+ # If either header or library was not found, action-if-not-found+ #+ echo "libbzip3 not found: ugrep option -z won't decompress .bz3 files"+ fi+fi++ # Check whether --with-grep-path was given. if test ${with_grep_path+y}
@@ -70,7 +70,7 @@ fi AX_CHECK_ZLIB([], [echo "zlib not found: ugrep option -z is not available"]) -AX_CHECK_BZLIB([], [echo "libbz2 not found: ugrep option -z won't decompress .bz and .bz2 files"])+AX_CHECK_BZ2LIB([], [echo "libbz2 not found: ugrep option -z won't decompress .bz and .bz2 files"]) AX_CHECK_LZMALIB([], [echo "liblzma not found: ugrep option -z won't decompress .lzma and .xz files"]) @@ -80,6 +80,8 @@ AX_CHECK_ZSTDLIB([], [echo "libzstd not found: ugrep option -z won't decompress AX_CHECK_BROTLILIB([], [echo "brotli library not found: ugrep option -z won't decompress .br files"]) +AX_CHECK_BZIP3LIB([], [echo "libbzip3 not found: ugrep option -z won't decompress .bz3 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])],
@@ -92,7 +92,8 @@ 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_bz2lib.m4 \+ $(top_srcdir)/m4/ax_check_bzip3lib.m4 \ $(top_srcdir)/m4/ax_check_lz4lib.m4 \ $(top_srcdir)/m4/ax_check_lzmalib.m4 \ $(top_srcdir)/m4/ax_check_pcre2.m4 \
@@ -6,21 +6,21 @@ # # 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,+# then in /usr, /opt/local and /sw. If the --with-brotli=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+# DIR/lib/libbrotlidec. If --without-brotli 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.+# --without-brotli. # # 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+# default action appends '-I${BROTLI_HOME}/include' to CPFLAGS, appends+# '-L${BROTLI_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:@@ -66,64 +66,64 @@ 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+[AC_MSG_CHECKING(if brotli is wanted)+brotli_places="/usr/local /usr /opt/homebrew /opt/local /sw"+AC_ARG_WITH([brotli],+[ --with-brotli=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],+ --without-brotli 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"+ brotli_places="$withval $brotli_places" else AC_MSG_WARN([Sorry, $withval does not exist, checking usual places]) fi else- brotlilib_places=""+ brotli_places="" AC_MSG_RESULT(no) fi], [AC_MSG_RESULT(yes)]) #-# Locate brotlilib, if wanted+# Locate brotli, if wanted #-if test -n "${brotlilib_places}"+if test -n "${brotli_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+ for BROTLI_HOME in ${brotli_places} ; do if test -f "${BROTLILIB_HOME}/include/brotli/decode.h"; then break; fi- BROTLILIB_HOME=""+ BROTLI_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"+ BROTLI_OLD_LDFLAGS=$LDFLAGS+ BROTLI_OLD_CPPFLAGS=$CPPFLAGS+ if test -n "${BROTLI_HOME}"; then+ LDFLAGS="$LDFLAGS -L${BROTLI_HOME}/lib"+ CPPFLAGS="$CPPFLAGS -I${BROTLI_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_CHECK_LIB([brotlidec], [BrotliDecoderCreateInstance], [brotli_cv_libbrotli=yes], [brotli_cv_libbrotli=no])+ AC_CHECK_HEADER([brotli/decode.h], [brotli_cv_brotli_h=yes], [brotli_cv_brotli_h=no]) AC_LANG_POP([C])- if test "$brotlilib_cv_libbrotli" = "yes" && test "$brotlilib_cv_brotli_h" = "yes"+ if test "$brotli_cv_libbrotli" = "yes" && test "$brotli_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"+ CPPFLAGS="$CPPFLAGS -I${BROTLI_HOME}/include"+ LDFLAGS="$LDFLAGS -L${BROTLI_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"+ LDFLAGS="$BROTLI_OLD_LDFLAGS"+ CPPFLAGS="$BROTLI_OLD_CPPFLAGS" $1 ]) else@@ -131,7 +131,7 @@ then # 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])+ AC_MSG_ERROR([either specify a valid brotli library installation with --with-brotli=DIR or disable brotli usage with --without-brotli]) ]) fi fi
@@ -0,0 +1,134 @@+# SYNOPSIS+#+# AX_CHECK_BZ2LIB([action-if-found], [action-if-not-found])+#+# DESCRIPTION+#+# This macro searches for an installed bzlib/bz2 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-bzlib=DIR is specified,+# it will try to find it in DIR/include/bzlib.h and DIR/lib/libbz2. If+# --without-bzlib is specified, the library is not searched at all.+#+# If either the header file (bzlib.h) or the library (libbz2) 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 bzlib+# installation directory or --without-bzlib.+#+# 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${BZ2LIB_HOME}/include' to CPFLAGS, appends+# '-L${BZ2LIB_HOME}/lib' to LDFLAGS, prepends '-lbz2' to LIBS, and calls+# AC_DEFINE(HAVE_LIBBZ2). 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_LIBBZ2+# #include <bzlib.h>+# #endif /* HAVE_LIBBZ2 */+#+# LICENSE+#+# Copyright (c) 2019 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_BZ2LIB],+#+# Handle user hints+#+[AC_MSG_CHECKING(if bzlib is wanted)+bzlib_places="/usr/local /usr /opt/homebrew /opt/local /sw"+AC_ARG_WITH([bzlib],+[ --with-bzlib=DIR root directory path of bzlib installation @<:@defaults to+ /usr/local or /usr if not found in /usr/local@:>@+ --without-bzlib to disable bzlib usage completely],+[if test "$withval" != "no" ; then+ AC_MSG_RESULT(yes)+ if test -d "$withval"+ then+ bzlib_places="$withval $bzlib_places"+ else+ AC_MSG_WARN([Sorry, $withval does not exist, checking usual places])+ fi+else+ bzlib_places=""+ AC_MSG_RESULT(no)+fi],+[AC_MSG_RESULT(yes)])+#+# Locate bzlib, if wanted+#+if test -n "${bzlib_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 B2ZLIB_HOME in ${bzlib_places} ; do+ if test -f "${B2ZLIB_HOME}/include/bzlib.h"; then break; fi+ B2ZLIB_HOME=""+ done++ B2ZLIB_OLD_LDFLAGS=$LDFLAGS+ B2ZLIB_OLD_CPPFLAGS=$CPPFLAGS+ if test -n "${B2ZLIB_HOME}"; then+ LDFLAGS="$LDFLAGS -L${B2ZLIB_HOME}/lib"+ CPPFLAGS="$CPPFLAGS -I${B2ZLIB_HOME}/include"+ fi+ AC_LANG_PUSH([C])+ AC_CHECK_LIB([bz2], [BZ2_bzRead], [bzlib_cv_libbz2=yes], [bzlib_cv_libbz2=no])+ AC_CHECK_HEADER([bzlib.h], [bzlib_cv_bzlib_h=yes], [bzlib_cv_bzlib_h=no])+ AC_LANG_POP([C])+ if test "$bzlib_cv_libbz2" = "yes" && test "$bzlib_cv_bzlib_h" = "yes"+ then+ #+ # If both library and header were found, action-if-found+ #+ m4_ifblank([$1],[+ CPPFLAGS="$CPPFLAGS -I${B2ZLIB_HOME}/include"+ LDFLAGS="$LDFLAGS -L${B2ZLIB_HOME}/lib"+ LIBS="-lbz2 $LIBS"+ AC_DEFINE([HAVE_LIBBZ2], [1],+ [Define to 1 if you have `bz2' library (-lbz2)])+ ],[+ # Restore variables+ LDFLAGS="$B2ZLIB_OLD_LDFLAGS"+ CPPFLAGS="$B2ZLIB_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 bzlib installation with --with-bzlib=DIR or disable bzlib usage with --without-bzlib])+ ])+ fi+fi+])
@@ -0,0 +1,135 @@+# SYNOPSIS+#+# AX_CHECK_BZIP3LIB([action-if-found], [action-if-not-found])+#+# DESCRIPTION+#+# This macro searches for an installed bzip3 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-bzip3=DIR is specified,+# it will try to find it in DIR/include/libbz3.h and DIR/lib/libbzip3. If+# --without-bzip3 is specified, the library is not searched at all.+#+# If either the header file (libbz3.h) or the library (libbzip3) 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 bzip3+# installation directory or --without-bzip3.+#+# 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${BZIP3_HOME}/include' to CPFLAGS, appends+# '-L${BZIP3_HOME}/lib' to LDFLAGS, prepends '-lbzip3' to LIBS, and calls+# AC_DEFINE(HAVE_LIBBZIP3). 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_LIBBZIP3+# #include <libbz3.h>+# #endif /* HAVE_LIBBZIP3 */+#+# 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_BZIP3LIB],+#+# Handle user hints+#+[AC_MSG_CHECKING(if bzip3 is wanted)+bzip3_places="/usr/local /usr /opt/homebrew /opt/local /sw"+AC_ARG_WITH([bzip3],+[ --with-bzip3=DIR root directory path of bzip3 library installation+ @<:@defaults to /usr/local or /usr if not found in+ /usr/local@:>@+ --without-bzip3 to disable bzip3 library usage completely],+[if test "$withval" != "no" ; then+ AC_MSG_RESULT(yes)+ if test -d "$withval"+ then+ bzip3_places="$withval $bzip3_places"+ else+ AC_MSG_WARN([Sorry, $withval does not exist, checking usual places])+ fi+else+ bzip3_places=""+ AC_MSG_RESULT(no)+fi],+[AC_MSG_RESULT(yes)])+#+# Locate bzip3 library, if wanted+#+if test -n "${bzip3_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 BZIP3_HOME in ${bzip3_places} ; do+ if test -f "${BZIP3_HOME}/include/libbz3.h"; then break; fi+ BZIP3_HOME=""+ done++ BZIP3_OLD_LDFLAGS=$LDFLAGS+ BZIP3_OLD_CPPFLAGS=$CPPFLAGS+ if test -n "${BZIP3_HOME}"; then+ LDFLAGS="$LDFLAGS -L${BZIP3_HOME}/lib"+ CPPFLAGS="$CPPFLAGS -I${BZIP3_HOME}/include"+ fi+ AC_LANG_PUSH([C])+ AC_CHECK_LIB([bzip3], [bz3_new], [bzip3_cv_libbzip3=yes], [bzip3_cv_libbzip3=no])+ AC_CHECK_HEADER([libbz3.h], [bzip3_cv_libbz3_h=yes], [bzip3_cv_libbz3_h=no])+ AC_LANG_POP([C])+ if test "$bzip3_cv_libbzip3" = "yes" && test "$bzip3_cv_libbz3_h" = "yes"+ then+ #+ # If both library and header were found, action-if-found+ #+ m4_ifblank([$1],[+ CPPFLAGS="$CPPFLAGS -I${BZIP3_HOME}/include"+ LDFLAGS="$LDFLAGS -L${BZIP3_HOME}/lib"+ LIBS="-lbzip3 $LIBS"+ AC_DEFINE([HAVE_LIBBZIP3], [1],+ [Define to 1 if you have `bzip3' library (-lbzip3)])+ ],[+ # Restore variables+ LDFLAGS="$BZLIB_OLD_LDFLAGS"+ CPPFLAGS="$BZLIB_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 bzip3 library installation with --with-bzip3=DIR or disable bzip3 library usage with --without-bzip3])+ ])+ fi+fi+])
m4/ax_check_bzlib.m4
@@ -1,134 +0,0 @@-# SYNOPSIS-#-# AX_CHECK_BZLIB([action-if-found], [action-if-not-found])-#-# DESCRIPTION-#-# This macro searches for an installed bzlib/bz2 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-bzlib=DIR is specified,-# it will try to find it in DIR/include/bzlib.h and DIR/lib/libbz2. If-# --without-bzlib is specified, the library is not searched at all.-#-# If either the header file (bzlib.h) or the library (libbz2) 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 bzlib-# installation directory or --without-bzlib.-#-# 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${BZLIB_HOME}/include' to CPFLAGS, appends-# '-L${BZLIB_HOME}/lib' to LDFLAGS, prepends '-lbz2' to LIBS, and calls-# AC_DEFINE(HAVE_LIBBZ2). 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_LIBBZ2-# #include <bzlib.h>-# #endif /* HAVE_LIBBZ2 */-#-# LICENSE-#-# Copyright (c) 2019 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_BZLIB],-#-# Handle user hints-#-[AC_MSG_CHECKING(if bzlib is wanted)-bzlib_places="/usr/local /usr /opt/homebrew /opt/local /sw"-AC_ARG_WITH([bzlib],-[ --with-bzlib=DIR root directory path of bzlib installation @<:@defaults to- /usr/local or /usr if not found in /usr/local@:>@- --without-bzlib to disable bzlib usage completely],-[if test "$withval" != "no" ; then- AC_MSG_RESULT(yes)- if test -d "$withval"- then- bzlib_places="$withval $bzlib_places"- else- AC_MSG_WARN([Sorry, $withval does not exist, checking usual places])- fi-else- bzlib_places=""- AC_MSG_RESULT(no)-fi],-[AC_MSG_RESULT(yes)])-#-# Locate bzlib, if wanted-#-if test -n "${bzlib_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 BZLIB_HOME in ${bzlib_places} ; do- if test -f "${BZLIB_HOME}/include/bzlib.h"; then break; fi- BZLIB_HOME=""- done-- BZLIB_OLD_LDFLAGS=$LDFLAGS- BZLIB_OLD_CPPFLAGS=$CPPFLAGS- if test -n "${BZLIB_HOME}"; then- LDFLAGS="$LDFLAGS -L${BZLIB_HOME}/lib"- CPPFLAGS="$CPPFLAGS -I${BZLIB_HOME}/include"- fi- AC_LANG_PUSH([C])- AC_CHECK_LIB([bz2], [BZ2_bzRead], [bzlib_cv_libbz2=yes], [bzlib_cv_libbz2=no])- AC_CHECK_HEADER([bzlib.h], [bzlib_cv_bzlib_h=yes], [bzlib_cv_bzlib_h=no])- AC_LANG_POP([C])- if test "$bzlib_cv_libbz2" = "yes" && test "$bzlib_cv_bzlib_h" = "yes"- then- #- # If both library and header were found, action-if-found- #- m4_ifblank([$1],[- CPPFLAGS="$CPPFLAGS -I${BZLIB_HOME}/include"- LDFLAGS="$LDFLAGS -L${BZLIB_HOME}/lib"- LIBS="-lbz2 $LIBS"- AC_DEFINE([HAVE_LIBBZ2], [1],- [Define to 1 if you have `bz2' library (-lbz2)])- ],[- # Restore variables- LDFLAGS="$BZLIB_OLD_LDFLAGS"- CPPFLAGS="$BZLIB_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 bzlib installation with --with-bzlib=DIR or disable bzlib usage with --without-bzlib])- ])- fi-fi-])
@@ -1,4 +1,4 @@-.TH UGREP "1" "November 06, 2023" "ugrep 4.3.2" "User Commands"+.TH UGREP "1" "November 12, 2023" "ugrep 4.3.2" "User Commands" .SH NAME \fBugrep\fR, \fBug\fR -- file pattern searcher .SH SYNOPSIS@@ -904,7 +904,9 @@ 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 suffix .zst, .zstd, .tzst).+zstd (requires suffix .zst, .zstd, .tzst),+brotli (requires suffix .br),+bzip3 (requires suffix .bz3). .TP \fB\-\-zmax\fR=\fINUM\fR When used with option \fB\-z\fR (\fB\-\-decompress\fR), searches the contents of
@@ -93,7 +93,8 @@ 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_bz2lib.m4 \+ $(top_srcdir)/m4/ax_check_bzip3lib.m4 \ $(top_srcdir)/m4/ax_check_lz4lib.m4 \ $(top_srcdir)/m4/ax_check_lzmalib.m4 \ $(top_srcdir)/m4/ax_check_pcre2.m4 \
@@ -49,11 +49,12 @@ Optional libraries to support options -P and -z: -P: PCRE2 (or Boost.Regex) -z: zlib (.gz)- -z: bz2 (.bz, bz2, .bzip2)+ -z: bzip2 (.bz, bz2, .bzip2) -z: lzma (.lzma, .xz) -z: lz4 (.lz4) -z: zstd (.zst, .zstd) -z: brotli (.br)+ -z: bzip3 (.bz3) Build ugrep as follows: @@ -124,6 +125,9 @@ After this, you may want to test ugrep and install it (optional): // optionally enable brotli library for -z // #define HAVE_LIBBROTLI +// optionally enable libbzip3 for -z+// #define HAVE_LIBBZIP3+ #include <stringapiset.h> // internationalization #include <direct.h> // directory access #include <winsock.h> // gethostname() for --hyperlink@@ -155,7 +159,7 @@ After this, you may want to test ugrep and install it (optional): // #define Z_BUF_LEN 16384 // #define Z_BUF_LEN 32768 -// use zlib, libbz2, liblzma for option -z+// use zlib, libbz2, liblzma etc for option -z #ifdef HAVE_LIBZ # include "zstream.hpp" #endif@@ -7547,6 +7551,12 @@ void ugrep() flag_all_include.emplace_back("*.pax.br"); flag_all_include.emplace_back("*.tar.br"); #endif++#ifdef HAVE_LIBBZIP3+ flag_all_include.emplace_back("*.cpio.bz3");+ flag_all_include.emplace_back("*.pax.bz3");+ flag_all_include.emplace_back("*.tar.bz3");+#endif } #endif #endif@@ -13849,6 +13859,10 @@ void help(std::ostream& out) #ifdef HAVE_LIBBROTLI ",\n\ brotli (requires suffix .br)"+#endif+#ifdef HAVE_LIBBZIP3+ ",\n\+ bzip3 (requires suffix .bz3)" #endif ".\n" #endif@@ -14258,6 +14272,9 @@ void version() #ifdef HAVE_LIBBROTLI ",brotli" << #endif+#ifdef HAVE_LIBBZIP3+ ",bzip3" <<+#endif #endif "\n" "License: BSD-3-Clause; ugrep user guide: https://ugrep.com\n"
@@ -47,21 +47,21 @@ // Z decompress z_open(), z_read(), z_close() #include "zopen.h" -// if we have libbz2 (bzip2), otherwise declare incomplete bz_stream+// if we have libbz2 (bzip2), otherwise declare incomplete bz_stream for ZipInfo #ifdef HAVE_LIBBZ2 #include <bzlib.h> #else struct bz_stream; #endif -// if we have liblzma (xz utils), otherwise declare incomplete lzma_stream+// if we have liblzma (xz utils), otherwise declare incomplete lzma_stream for ZipInfo #ifdef HAVE_LIBLZMA #include <lzma.h> #else struct lzma_stream; #endif -// if we have liblz4, otherwise declare incomplete lz4_stream+// if we have liblz4, otherwise declare incomplete lz4_stream for ZipInfo #ifdef HAVE_LIBLZ4 #include <lz4.h> typedef LZ4_streamDecode_t *lz4_stream;@@ -73,7 +73,7 @@ typedef LZ4_streamDecode_t *lz4_stream; struct lz4_stream; #endif -// if we have libzstd, otherwise declare incomplete zstd_stream+// if we have libzstd, otherwise declare incomplete zstd_stream for ZipInfo #ifdef HAVE_LIBZSTD #include <zstd.h> typedef ZSTD_DStream zstd_stream;@@ -86,6 +86,13 @@ struct zstd_stream; #include <brotli/decode.h> #endif +// if we have libbzip3+#ifdef HAVE_LIBBZIP3+extern "C" {+#include <libbz3.h>+}+#endif+ // zip decompression crc check disabled as this is too slow, we should optimize crc32() with a table // use zip crc integrity check at the cost of a significant slow down? // #define WITH_ZIP_CRC32@@ -933,6 +940,12 @@ class zstreambuf : public std::streambuf { return has_ext(pathname, ".br"); } + // return true if pathname has a bz3 filename extension+ static bool is_bz3(const char *pathname)+ {+ return has_ext(pathname, ".bz3");+ }+ // return true if pathname has a (tar) compress (Z) filename extension static bool is_Z(const char *pathname) {@@ -984,6 +997,7 @@ class zstreambuf : public std::streambuf { lz4file_(NULL), zstdfile_(NULL), brfile_(NULL),+ bz3file_(NULL), zipinfo_(NULL), cur_(0), len_(0)@@ -1001,6 +1015,7 @@ class zstreambuf : public std::streambuf { lz4file_(NULL), zstdfile_(NULL), brfile_(NULL),+ bz3file_(NULL), zipinfo_(NULL), cur_(0), len_(0)@@ -1035,14 +1050,14 @@ class zstreambuf : public std::streambuf { if (is_bz(pathname)) { #ifdef HAVE_LIBBZ2- // open bzip2 compressed file+ // open bzip/bzip2 compressed file try { bzfile_ = new BZ(); int ret = BZ2_bzDecompressInit(&bzfile_->strm, 0, 0); if (ret != BZ_OK) {- warning("BZ2_bzDecompressInit error", pathname);+ warning("BZ2_bzDecompressInit failed", pathname); delete bzfile_; bzfile_ = NULL;@@ -1070,7 +1085,7 @@ class zstreambuf : public std::streambuf { lzma_ret ret = lzma_auto_decoder(&xzfile_->strm, UINT64_MAX, LZMA_TELL_UNSUPPORTED_CHECK | LZMA_CONCATENATED); if (ret != LZMA_OK) {- warning("lzma_stream_decoder error", pathname);+ warning("lzma_stream_decoder failed", pathname); delete xzfile_; xzfile_ = NULL;@@ -1095,6 +1110,14 @@ class zstreambuf : public std::streambuf { try { lz4file_ = new LZ4();+ if (lz4file_->strm == NULL || lz4file_->buf == NULL || lz4file_->zbuf == NULL)+ {+ warning("LZ4_createStreamDecode failed", pathname);++ delete lz4file_;+ lz4file_ = NULL;+ file_ = NULL;+ } } catch (const std::bad_alloc&)@@ -1114,6 +1137,14 @@ class zstreambuf : public std::streambuf { try { zstdfile_ = new ZSTD();+ if (zstdfile_->strm == NULL || zstdfile_->zbuf == NULL)+ {+ warning("ZSTD_createDStream failed", pathname);++ delete zstdfile_;+ zstdfile_ = NULL;+ file_ = NULL;+ } } catch (const std::bad_alloc&)@@ -1133,6 +1164,60 @@ class zstreambuf : public std::streambuf { try { brfile_ = new BR();+ if (brfile_->strm == NULL)+ {+ warning("BrotliDecoderCreateInstance failed", pathname);++ delete brfile_;+ brfile_ = NULL;+ file_ = NULL;+ }+ }++ catch (const std::bad_alloc&)+ {+ cannot_decompress(pathname_, "out of memory");+ file_ = NULL;+ }+#else+ cannot_decompress("unsupported compression format", pathname);+ file_ = NULL;+#endif+ }+ else if (is_bz3(pathname))+ {+#ifdef HAVE_LIBBZIP3+ // try to read the compression format magic bytes+ if (fread(buf_, 1, 9, file) < 9 || strncmp(reinterpret_cast<char*>(buf_), "BZ3v1", 5) != 0)+ {+ cannot_decompress(pathname_, "an error was detected in the bzip3 compressed data");+ delete bz3file_;+ bz3file_ = NULL;+ file_ = NULL;+ }++ uint32_t block_size = u32(buf_ + 5);++ if (block_size < 65 * 1024 || block_size > 511 * 1024 * 1024)+ {+ cannot_decompress(pathname_, "an error was detected in the bzip3 compressed data");+ delete bz3file_;+ bz3file_ = NULL;+ file_ = NULL;+ }++ // open bzip3 compressed file+ try+ {+ bz3file_ = new BZ3(block_size);+ if (bz3file_->strm == NULL || bz3file_->buf == NULL)+ {+ warning("bz3_new failed", pathname);++ delete bz3file_;+ bz3file_ = NULL;+ file_ = NULL;+ } } catch (const std::bad_alloc&)@@ -1199,7 +1284,7 @@ class zstreambuf : public std::streambuf { // open compress (Z) compressed file if ((zzfile_ = z_open(file, "r", 0, 1)) == NULL) {- warning("zopen error", pathname);+ warning("zopen failed", pathname); file_ = NULL; } }@@ -1306,6 +1391,13 @@ class zstreambuf : public std::streambuf { delete brfile_; brfile_ = NULL; }+#endif+#ifdef HAVE_LIBBZIP3+ else if (bz3file_ != NULL)+ {+ delete bz3file_;+ bz3file_ = NULL;+ } #endif else if (zipinfo_ != NULL) {@@ -1400,7 +1492,7 @@ class zstreambuf : public std::streambuf { #ifdef HAVE_LIBBZ2 - // bzip2 decompression state data+ // bzip/bzip2 decompression state data struct BZ { BZ()@@ -1538,7 +1630,8 @@ class zstreambuf : public std::streambuf { struct ZSTD { ZSTD()- : strm(ZSTD_createDStream()),+ :+ strm(ZSTD_createDStream()), zbuf(static_cast<unsigned char*>(malloc(ZSTD_DStreamInSize()))), zloc(0), zlen(0),@@ -1577,7 +1670,8 @@ class zstreambuf : public std::streambuf { struct BR { BR()- : strm(BrotliDecoderCreateInstance(NULL, NULL, NULL)),+ :+ strm(BrotliDecoderCreateInstance(NULL, NULL, NULL)), next_in(NULL), avail_in(0), next_out(NULL),@@ -1588,7 +1682,8 @@ class zstreambuf : public std::streambuf { ~BR() {- BrotliDecoderDestroyInstance(strm);+ if (strm != NULL)+ BrotliDecoderDestroyInstance(strm); } BrotliDecoderState *strm; // brotli decompression stream state@@ -1610,6 +1705,46 @@ class zstreambuf : public std::streambuf { // unused brotli file handle typedef void *brotliFile; +#endif++#ifdef HAVE_LIBBZIP3++ // bzip3 decompression state data+ struct BZ3 {++ BZ3(uint32_t block_size)+ :+ strm(bz3_new(block_size)),+ max(bz3_bound(block_size)),+ buf(static_cast<uint8_t*>(malloc(max))),+ loc(0),+ len(0)+ { }++ ~BZ3()+ {+ if (buf != NULL)+ free(buf);+ if (strm != NULL)+ bz3_free(strm);+ }++ bz3_state *strm;+ uint32_t max;+ uint8_t *buf;+ uint32_t loc;+ uint32_t len;++ };+ + // bzip3 file handle+ typedef struct BZ3 *bz3File;++#else++ // unused bzip3 file handle+ typedef void *bz3File;+ #endif // fetch and decompress the next block of data into buf[0..len-1], return number of bytes decompressed, zero on EOF or negative on error@@ -2219,7 +2354,7 @@ class zstreambuf : public std::streambuf { { BrotliDecoderResult ret = BROTLI_DECODER_RESULT_SUCCESS; - // decompress non-empty brfile_->zbuf[] into the given buf[]+ // decompress non-empty brfile_->zbuf[] into the given buf[], strange we can't limit this to brfile_->avail_in > 0 if (brfile_->avail_out == 0) { brfile_->next_out = buf;@@ -2291,6 +2426,63 @@ class zstreambuf : public std::streambuf { break; } }+#endif+#ifdef HAVE_LIBBZIP3+ else if (bz3file_ != NULL)+ {+ while (bz3file_->loc >= bz3file_->len)+ {+ // read decompressed and compressed size+ if (fread(bz3file_->buf, 1, 8, file_) < 8)+ {+ if (ferror(file_))+ {+ warning("cannot read", pathname_);+ num = -1;+ }++ break;+ }++ // compressed ("new") size+ uint32_t block_size = u32(bz3file_->buf);++ // decompressed ("old") size+ bz3file_->len = u32(bz3file_->buf + 4);+ bz3file_->loc = 0;++ if (block_size > bz3file_->max ||+ bz3file_->len > bz3file_->max ||+ fread(bz3file_->buf, 1, block_size, file_) < block_size ||+ bz3_decode_block(bz3file_->strm, bz3file_->buf, block_size, bz3file_->len) < 0)+ {+ if (ferror(file_))+ warning("cannot read", pathname_);+ else+ cannot_decompress(pathname_, "an error was detected in the bzip3 compressed data");++ num = -1;++ break;+ }+ }++ // if all OK then copy the next part of the decompressed block into buf[]+ if (num != -1 && bz3file_->loc < bz3file_->len)+ {+ num = bz3file_->len - bz3file_->loc;+ if (num > static_cast<std::streamsize>(len))+ num = len;+ memcpy(buf, bz3file_->buf + bz3file_->loc, num);+ bz3file_->loc += num;+ }+ else if (num <= 0)+ {+ delete bz3file_;+ bz3file_ = NULL;+ file_ = NULL;+ }+ } #endif else if (zipinfo_ != NULL) {@@ -2398,11 +2590,12 @@ class zstreambuf : public std::streambuf { FILE *file_; // the compressed file zFile zfile_; // zlib file handle zzFile zzfile_; // compress (Z) file handle- bzFile bzfile_; // bzip2 file handle+ bzFile bzfile_; // bzip/bzip2 file handle xzFile xzfile_; // xz/lzma file handle lz4File lz4file_; // lz4 file handle zstdFile zstdfile_; // zstd file handle brotliFile brfile_; // brotli file handle+ bz3File bz3file_; // bzip3 file handle ZipInfo *zipinfo_; // zip file and zip info handle unsigned char buf_[Z_BUF_LEN]; // buffer with decompressed stream data std::streamsize cur_; // current position in buffer to read the stream data, less or equal to len_
@@ -152,6 +152,7 @@ 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+bzip3 -c archive.tar > archive.tar.bz3 zip -9 -q archive.tar.zip archive.tar zip -9 -q archive.zip $FILES @@ -171,6 +172,7 @@ $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 Hello archive.tar.bz3 > out/archive.tar.bz3.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@@ -185,6 +187,7 @@ $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 -z -c -tShell Hello archive.tar.bz3 > out/archive-t.tar.bz3.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.bz3.out
@@ -0,0 +1,2 @@+[1;35marchive.tar.bz3{Hello.bat}[m[1;36m:[m1+[1;35marchive.tar.bz3{Hello.sh}[m[1;36m:[m1
@@ -0,0 +1,8 @@+[1;35marchive.tar.bz3{Hello.bat}[m[1;36m:[m1+[1;35marchive.tar.bz3{Hello.class}[m[1;36m:[m1+[1;35marchive.tar.bz3{Hello.java}[m[1;36m:[m2+[1;35marchive.tar.bz3{Hello.pdf}[m[1;36m:[m1+[1;35marchive.tar.bz3{Hello.sh}[m[1;36m:[m1+[1;35marchive.tar.bz3{Hello.txt}[m[1;36m:[m1+[1;35marchive.tar.bz3{empty.txt}[m[1;36m:[m0+[1;35marchive.tar.bz3{emptyline.txt}[m[1;36m:[m0
@@ -88,6 +88,14 @@ fi printf "Have libbrotli? %3s (optional)\n" $have_libbrotli +if $UG -Fq 'HAVE_LIBBZIP3 1' "$CONFIGH" ; then+ have_libbzip3=yes+else+ have_libbzip3=no+fi++printf "Have libbzip3? %3s (optional)\n" $have_libbzip3+ export GREP_COLORS='cx=hb:ms=hug:mc=ib+W:fn=h35:ln=32h:cn=1;32:bn=1;32:se=+36' function ERR() {@@ -378,6 +386,10 @@ 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+if [ "$have_libbzip3" == yes ]; then+printf .+$UG -z -c Hello archive.tar.bz3 | $DIFF out/archive.tar.bz3.out || ERR "-z -c Hello archive.tar.bz3"+fi fi if [ "$have_libz" == yes ]; then@@ -417,6 +429,10 @@ 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+if [ "$have_libbzip3" == yes ]; then+printf .+$UG -z -c -tShell Hello archive.tar.bz3 | $DIFF out/archive-t.tar.bz3.out || ERR "-z -c -tShell Hello archive.tar.bz3"+fi fi if [ "$have_libz" == yes ]; then