#!/bin/bash
UGREP=${UGREP_ABS_PATH:-../src/ugrep}
CONFIGH=${CONFIGH_ABS_PATH:-../config.h}
UG="$UGREP --color=always --sort $@"
FILES="Hello.bat Hello.class Hello.java Hello.pdf Hello.sh Hello.txt empty.txt emptyline.txt"
# check for errors in the installation
if test ! -x "$UGREP" ; then
echo "$UGREP not found, exiting"
exit 1
fi
if test ! -e "$CONFIGH" ; then
echo "$CONFIGH not found, exiting"
exit 1
fi
if ! $UG --version | head -n1 ; then
echo "$UGREP failed to execute, exiting"
exit 1
fi
# check for recommended libraries
if $UG -Fq 'HAVE_PCRE2 1' "$CONFIGH" ; then
have_pcre2=yes
else
have_pcre2=no
fi
printf "Have libpcre2? %3s (recommended)\n" $have_pcre2
if test "$have_pcre2" = "no" ; then
if $UG -Fq 'HAVE_BOOST_REGEX 1' "$CONFIGH" ; then
have_boost_regex=yes
else
have_boost_regex=no
fi
printf "Have libboost_regex? %s (optional)\n" $have_boost_regex
fi
if $UG -Fq 'HAVE_LIBZ 1' "$CONFIGH" ; then
have_libz=yes
else
have_libz=no
fi
printf "Have libz? %3s (recommended)\n" $have_libz
if $UG -Fq 'HAVE_LIBBZ2 1' "$CONFIGH" ; then
have_libbz2=yes
else
have_libbz2=no
fi
printf "Have libbz2? %3s (recommended)\n" $have_libbz2
if $UG -Fq 'HAVE_LIBLZMA 1' "$CONFIGH" ; then
have_liblzma=yes
else
have_liblzma=no
fi
printf "Have liblzma? %3s (recommended)\n" $have_liblzma
# check for optional libraries
if $UG -Fq 'HAVE_LIBLZ4 1' "$CONFIGH" ; then
have_liblz4=yes
else
have_liblz4=no
fi
printf "Have liblz4? %3s (optional)\n" $have_liblz4
if $UG -Fq 'HAVE_LIBZSTD 1' "$CONFIGH" ; then
have_libzstd=yes
else
have_libzstd=no
fi
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
if $UG -Fq 'HAVE_7ZIP 1' "$CONFIGH" ; then
have_7zip=yes
else
have_7zip=no
fi
printf "Have 7zip? %3s (optional)\n" $have_7zip
# check for libraries that aren't typically installed, don't report
if $UG -Fq 'HAVE_LIBBZIP3 1' "$CONFIGH" ; then
have_libbzip3=yes
printf "Have libbzip3? yes (requested)\n"
else
have_libbzip3=no
fi
# set special color scheme
export GREP_COLORS='cx=hb:ms=hug:mc=ib+W:fn=h35:ln=32h:cn=1;32:bn=1;32:se=+36'
# set ERR to report
function ERR() {
echo "[1;31mError:[0m[1m ugrep --sort $1 [1;31mfailed[0m"
exit 1
}
# set DIFF to compare and report, MinGW should ignore CRL<->LF and ignore "binary" characters
if test "$OSTYPE" = "msys" || ( test "$OSTYPE" = "cygwin" && test ! -z "$MSYSTEM" ) ; then
DIFF="diff -a -b -U1 -"
else
DIFF="diff -U1 -"
fi
# prepare to test, w/o MinGW dir tests (no symlinks)
if test "$OSTYPE" != "msys" && ( test "$OSTYPE" != "cygwin" || test -z "$MSYSTEM" ) ; then
rm -rf dir1/ dir2/
mkdir -p dir1 dir2
ln -s ../Hello.java dir1
cp Hello.sh dir1
cp Hello.bat dir1
cp makefile 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
# ignore shells
*.sh
# ignore dir2 (sub)directories
**/dir2/
END
# tests
printf .
$UG -rl Hello dir1 | $DIFF out/dir.out || ERR "-rl Hello dir1"
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,make Hello dir1 | $DIFF out/dir-t.out || ERR "-Rl -tShell,make Hello dir1"
printf .
$UG -1l Hello dir1 | $DIFF out/dir-1.out || ERR "-1l Hello dir1"
printf .
$UG -2l Hello dir1 | $DIFF out/dir-2.out || ERR "-2l Hello dir1"
printf .
$UG -Rl --include='*.sh' Hello dir1 | $DIFF out/dir--include.out || ERR "-Rl --include='*.sh' Hello dir1"
printf .
$UG -Rl --exclude='*.sh' Hello dir1 | $DIFF out/dir--exclude.out || ERR "-Rl --exclude='*.sh' Hello dir1"
printf .
$UG -Rl --exclude-dir='dir2' Hello dir1 | $DIFF out/dir--exclude-dir.out || ERR "-Rl --exclude-dir='dir2' Hello dir1"
printf .
$UG -Rl --include-dir='dir1' Hello dir1 | $DIFF out/dir--include-dir.out || ERR "-Rl --include-dir='dir1' Hello dir1"
printf .
$UG -Rl --exclude-dir='dir2' Hello dir1 | $DIFF out/dir--exclude-dir.out || ERR "-Rl --exclude-dir='dir2' Hello dir1"
printf .
$UG -Rl --include-from='dir1/.gitignore' Hello dir2 | $DIFF out/dir--include-from.out || ERR "-Rl --include-from='dir1/.gitignore' Hello dir2"
printf .
$UG -Rl --exclude-from='dir1/.gitignore' Hello dir1 | $DIFF out/dir--exclude-from.out || ERR "-Rl --exclude-from='dir1/.gitignore' Hello dir1"
printf .
$UG -Rl --ignore-files Hello dir1 | $DIFF out/dir--ignore-files.out || ERR "-Rl -ignore-files Hello Hello dir1"
printf .
$UG -Rl --filter='sh:head -n1' Hello dir1 | $DIFF out/dir--filter.out || ERR "-Rl --filter='sh:head -n1' Hello dir1"
rm -rf dir1 dir2
fi
for OPS in '' '-F' '-G' ; do
printf .
$UG $OPS -iwco -f lorem lorem.utf8.txt \
| $DIFF "out/lorem.utf8$OPS-iwco.out" \
|| ERR "$OPS -iwco -f lorem lorem.utf8.txt"
printf .
$UG $OPS -iwco -f lorem lorem.utf16.txt \
| $DIFF "out/lorem.utf8$OPS-iwco.out" \
|| ERR "$OPS -iwco -f lorem lorem.utf16.txt"
printf .
$UG $OPS -iwco -f lorem lorem.utf32.txt \
| $DIFF "out/lorem.utf8$OPS-iwco.out" \
|| ERR "$OPS -iwco -f lorem lorem.utf32.txt"
printf .
cat lorem | $UG $OPS -iwco --encoding=LATIN1 -f - lorem.latin1.txt \
| $DIFF "out/lorem.latin1$OPS-iwco.out" \
|| ERR "$OPS -iwco -f lorem lorem.latin1.txt"
done
if [ "$have_pcre2" == yes ]; then
printf .
$UG -P -iwco -f lorem lorem.utf8.txt \
| $DIFF "out/lorem.utf8-P-iwco.out" \
|| ERR "-P -iwco -f lorem lorem.utf8.txt"
printf .
$UG -P -iwco -f lorem lorem.utf16.txt \
| $DIFF "out/lorem.utf8-P-iwco.out" \
|| ERR "-P -iwco -f lorem lorem.utf16.txt"
printf .
$UG -P -iwco -f lorem lorem.utf32.txt \
| $DIFF "out/lorem.utf8-P-iwco.out" \
|| ERR "-P -iwco -f lorem lorem.utf32.txt"
printf .
cat lorem | $UG -P -iwco --encoding=LATIN1 -f - lorem.latin1.txt \
| $DIFF "out/lorem.latin1-P-iwco.out" \
|| ERR "-P -iwco -f lorem lorem.latin1.txt"
fi
for PAT in '' 'Lorem' 'nomatch' ; do
FN=`echo "lorem_$PAT" | tr -Cd '[:alnum:]_'`
for OPS in '-Zio' '-ioZbest1' ; do
printf .
$UG $OPS "$PAT" lorem.utf8.txt | $DIFF out/$FN$OPS.out || ERR "$OPS '$PAT' lorem.utf8.txt"
done
done
printf .
$UG -ci hello $FILES \
| $DIFF out/Hello_Hello-ci.out \
|| ERR "-ci hello $FILES"
printf .
$UG -cj hello $FILES \
| $DIFF out/Hello_Hello-cj.out \
|| ERR "-cj hello $FILES"
printf .
$UG -e Hello -e '".*?"' $FILES \
| $DIFF out/Hello_Hello-ee.out \
|| ERR "-e Hello -e '\".*?\"' $FILES"
printf .
$UG -e Hello -N '".*?"' $FILES \
| $DIFF out/Hello_Hello-eN.out \
|| ERR "-e Hello -N '\".*?\"' $FILES"
printf .
$UG --max-count=1 Hello $FILES \
| $DIFF out/Hello_Hello--max-count.out \
|| ERR "--max-count=1 Hello $FILES"
printf .
$UG --max-files=1 Hello $FILES \
| $DIFF out/Hello_Hello--max-files.out \
|| ERR "--max-files=1 Hello $FILES"
printf .
$UG --range=1,1 Hello $FILES \
| $DIFF out/Hello_Hello--range.out \
|| ERR "--range=1,1 Hello $FILES"
for PAT in '' 'Hello' '\w+[\n\h]+\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' '-onC10' '-y' '-ny' '-vy' '-nvy' ; do
printf .
$UG -U $OUT $OPS "$PAT" $FILES \
| $DIFF "out/$FN$OUT$OPS.out" \
|| 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" $FILES \
| $DIFF "out/$FN$OUT$OPS.out" \
|| ERR "$OUT $OPS '$PAT' $FILES"
done
done
printf .
$UG -U --tag "$PAT" $FILES \
| $DIFF "out/$FN--tag.out" \
|| ERR "--tag '$PAT' $FILES"
printf .
$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' $FILES"
printf .
$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' $FILES"
printf .
$UG -U --replace='(%m:%o)' "$PAT" $FILES \
| $DIFF "out/$FN--replace.out" \
|| ERR "--replace='(%m:%o)' '$PAT' $FILES"
printf .
$UG -U -Iw "$PAT" $FILES \
| $DIFF "out/$FN-Iw.out" \
|| ERR "-Iw '$PAT' $FILES"
printf .
$UG -U -Ix "$PAT" $FILES \
| $DIFF "out/$FN-Ix.out" \
|| ERR "-Ix '$PAT' $FILES"
printf .
$UG -U -F "$PAT" $FILES \
| $DIFF "out/$FN-F.out" \
|| ERR "-F '$PAT' $FILES"
printf .
$UG -U -Fw "$PAT" $FILES \
| $DIFF "out/$FN-Fw.out" \
|| ERR "-Fw '$PAT' $FILES"
printf .
$UG -U -Fx "$PAT" $FILES \
| $DIFF "out/$FN-Fx.out" \
|| ERR "-Fx '$PAT' $FILES"
printf .
if [ "$PAT" == '\w+[\n\h]+\S+' ]; then
$UG -U -G '\w\+[\n\h]\+\S\+' $FILES \
| $DIFF "out/$FN-G.out" \
|| ERR "-G '\w\+[\n\h]\+\S\+' $FILES"
$UG -U -Gw '\w\+[\n\h]\+\S\+' $FILES \
| $DIFF "out/$FN-Gw.out" \
|| ERR "-Gw '\w\+[\n\h]\+\S\+' $FILES"
$UG -U -Gx '\w\+[\n\h]\+\S\+' $FILES \
| $DIFF "out/$FN-Gx.out" \
|| ERR "-Gx '\w\+[\n\h]\+\S\+' $FILES"
else
$UG -U -G "$PAT" $FILES \
| $DIFF "out/$FN-G.out" \
|| ERR "-G '$PAT' $FILES"
$UG -U -Gw "$PAT" $FILES \
| $DIFF "out/$FN-Gw.out" \
|| ERR "-Gw '$PAT' $FILES"
$UG -U -Gx "$PAT" $FILES \
| $DIFF "out/$FN-Gx.out" \
|| ERR "-Gx '$PAT' $FILES"
fi
if [ "$have_pcre2" == yes ] || [ "$have_boost_regex" == yes ]; then
printf .
$UG -U -IP "$PAT" $FILES \
| $DIFF "out/$FN-IP.out" \
|| ERR "-IP '$PAT' $FILES"
printf .
$UG -U -IPw "$PAT" $FILES \
| $DIFF "out/$FN-IPw.out" \
|| ERR "-IPw '$PAT' $FILES"
printf .
$UG -U -IPx "$PAT" $FILES \
| $DIFF "out/$FN-IPx.out" \
|| ERR "-IPx '$PAT' $FILES"
fi
done
for PAT in '' 'Hello World' 'Hello -World' 'Hello -bin' 'bin -Hello' 'bin -greeting' 'Hello -World|greeting' 'Hello -bin|greeting' 'Hello -(greeting|World)' '"a Hello" greeting' ; do
FN=`echo "Hello_$PAT" | tr -Cd '[:alnum:]_-'`
for OPS in '' '-l' '-c' '-co' '-o' '-C2' '-y' '--json' ; do
printf .
$UG -U --bool $OPS "$PAT" $FILES \
| $DIFF "out/$FN--bool$OPS.out" \
|| ERR "--bool $OPS '$PAT' $FILES"
$UG -U --files --bool $OPS "$PAT" $FILES \
| $DIFF "out/$FN--files--bool$OPS.out" \
|| ERR "--files --bool $OPS '$PAT' $FILES"
done
done
printf .
$UG -U -e 'Hello' --and 'World' $FILES \
| $DIFF "out/Hello--and.out" \
|| ERR "-e 'Hello' --and 'World' $FILES"
printf .
$UG -U -e 'Hello' --andnot 'World' $FILES \
| $DIFF "out/Hello--andnot.out" \
|| ERR "-e 'Hello' --andnot 'World' $FILES"
printf .
$UG -U -e 'Hello' --and --not 'World' -e 'greeting' $FILES \
| $DIFF "out/Hello--and--not.out" \
|| ERR "-e 'Hello' --and --not 'World' -e 'greeting' $FILES"
if [ "$have_libz" == yes ]; then
printf .
$UG -z -c Hello archive.cpio | $DIFF out/archive.cpio.out || ERR "-z -c Hello archive.cpio"
printf .
$UG -z -c Hello archive.pax | $DIFF out/archive.pax.out || ERR "-z -c Hello archive.pax"
printf .
$UG -z -c Hello archive.tar | $DIFF out/archive.tar.out || ERR "-z -c Hello archive.tar"
printf .
$UG -z -c Hello archive.tgz | $DIFF out/archive.tgz.out || ERR "-z -c Hello archive.tgz"
printf .
$UG -z -c Hello archive.tZ | $DIFF out/archive.tZ.out || ERR "-z -c Hello archive.tZ"
printf .
$UG -z -c Hello archive.tar.zip | $DIFF out/archive.tar.zip.out || ERR "-z -c Hello archive.tar.zip"
printf .
$UG -z -c Hello archive.zip | $DIFF out/archive.zip.out || ERR "-z -c Hello archive.zip"
printf .
if [ "$have_7zip" == yes ]; then
printf .
$UG -z -c Hello archive.7z | $DIFF out/archive.7z.out || ERR "-z -c Hello archive.7z"
fi
if [ "$have_libbz2" == yes ]; then
printf .
$UG -z -c Hello archive.tbz | $DIFF out/archive.tbz.out || ERR "-z -c Hello archive.tbz"
fi
if [ "$have_liblzma" == yes ]; then
printf .
$UG -z -c Hello archive.tlz | $DIFF out/archive.tlz.out || ERR "-z -c Hello archive.tlz"
printf .
$UG -z -c Hello archive.txz | $DIFF out/archive.txz.out || ERR "-z -c Hello archive.txz"
fi
if [ "$have_liblz4" == yes ]; then
printf .
$UG -z -c Hello archive.tar.lz4 | $DIFF out/archive.tar.lz4.out || ERR "-z -c Hello archive.tar.lz4"
fi
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
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
printf .
$UG -z -c -tShell Hello archive.cpio | $DIFF out/archive-t.cpio.out || ERR "-z -c -tShell Hello archive.cpio"
printf .
$UG -z -c -tShell Hello archive.pax | $DIFF out/archive-t.pax.out || ERR "-z -c -tShell Hello archive.pax"
printf .
$UG -z -c -tShell Hello archive.tar | $DIFF out/archive-t.tar.out || ERR "-z -c -tShell Hello archive.tar"
printf .
$UG -z -c -tShell Hello archive.tgz | $DIFF out/archive-t.tgz.out || ERR "-z -c -tShell Hello archive.tgz"
printf .
$UG -z -c -tShell Hello archive.tZ | $DIFF out/archive-t.tZ.out || ERR "-z -c -tShell Hello archive.tZ"
printf .
$UG -z -c -tShell Hello archive.tar.zip | $DIFF out/archive-t.tar.zip.out || ERR "-z -c -tShell Hello archive.tar.zip"
printf .
$UG -z -c -tShell Hello archive.zip | $DIFF out/archive-t.zip.out || ERR "-z -c -tShell Hello archive.zip"
if [ "$have_7zip" == yes ]; then
printf .
$UG -z -c -tShell Hello archive.7z | $DIFF out/archive-t.7z.out || ERR "-z -c -tShell Hello archive.7z"
fi
if [ "$have_libbz2" == yes ]; then
printf .
$UG -z -c -tShell Hello archive.tbz | $DIFF out/archive-t.tbz.out || ERR "-z -c -tShell Hello archive.tbz"
fi
if [ "$have_liblzma" == yes ]; then
printf .
$UG -z -c -tShell Hello archive.tlz | $DIFF out/archive-t.tlz.out || ERR "-z -c -tShell Hello archive.tlz"
printf .
$UG -z -c -tShell Hello archive.txz | $DIFF out/archive-t.txz.out || ERR "-z -c -tShell Hello archive.txz"
fi
if [ "$have_liblz4" == yes ]; then
printf .
$UG -z -c -tShell Hello archive.tar.lz4 | $DIFF out/archive-t.tar.lz4.out || ERR "-z -c -tShell Hello archive.tar.lz4"
fi
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
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
printf .
$UG --zmax=2 -z -c Hello archive2.tgz | $DIFF out/archive2.tgz.out || ERR "-zmax=2 -z -c Hello archive2.tgz"
printf .
$UG --zmax=3 -z -c Hello archive3.tgz | $DIFF out/archive3.tgz.out || ERR "-zmax=3 -z -c Hello archive3.tgz"
printf .
$UG --zmax=2 -z -c -tShell Hello archive2.tgz | $DIFF out/archive2-t.tgz.out || ERR "-zmax=2 -z -c -tShell Hello archive2.tgz"
printf .
$UG --zmax=3 -z -c -tShell Hello archive3.tgz | $DIFF out/archive3-t.tgz.out || ERR "-zmax=3 -z -c -tShell Hello archive3.tgz"
fi
if [ "$have_libz" == yes ]; then
printf .
$UG -z -c '' archive.gz | $DIFF out/archive.gz.out || ERR "-z -c '' archive.gz"
for PAT in '\.' 'et' 'hendrerit' 'aliquam' 'sit amet aliquam' 'Nunc hendrerit at metus sit amet aliquam' 'adip[a-z]{1,}' 'adip[a-z]{4,}' 'adip[a-z]{6}' '[a-z]+' 'a[a-z]+' 'ad[a-z]+' 'adi[a-z]+' ; do
FN=`echo "archive_$PAT" | tr -Cd '[:alnum:]_'`
printf .
$UG -z -co "$PAT" archive.gz | $DIFF out/$FN-co.gz.out || ERR "-z -co '$PAT' archive.gz"
done
fi
# optional: verify SIMD, PM-4, Bitap, and Bloom filter optimizations
# a=
# for (( i = 1; i <= 8; ++i )); do
# a=a$a
# for (( k = 1; k <= 32; ++k )); do
# kk=$((k+i-1))
# for (( x = 61; x <= 69; ++x )); do
# printf .
# echo "$k:$a" > out/column.out
# printf "%${kk}s" "$a" | $UG --no-color -ok "[a-\x$x]{$i}" | $DIFF out/column.out || ERR "-ok [a-\x$x]{$i} $k:$a"
# done
# done
# done
rm -f out/column.out
echo
echo "ALL TESTS PASSED"