#! /bin/sh

###############################################################################
# Run the PCRE2 tests using the pcre2test program. The appropriate tests are
# selected, depending on which build-time options were used.
#
# When JIT support is available, all appropriate tests are run with and without
# JIT, unless "-nojit" is given on the command line. There are also two tests
# for JIT-specific features, one to be run when JIT support is available
# (unless "-nojit" is specified), and one when it is not.
#
# Whichever of the 8-, 16- and 32-bit libraries exist are tested. It is also
# possible to select which to test by giving "-8", "-16" or "-32" on the
# command line.
#
# As well as "-nojit", "-8", "-16", and "-32", arguments for this script are
# individual test numbers, ranges of tests such as 3-6 or 3- (meaning 3 to the
# end), or a number preceded by ~ to exclude a test. For example, "3-15 ~10"
# runs tests 3 to 15, excluding test 10, and just "~10" runs all the tests
# except test 10. Whatever order the arguments are in, these tests are always
# run in numerical order.
#
# If no specific tests are selected (which is the case when this script is run
# via 'make check') the default is to run all the numbered tests.
#
# There may also be named (as well as numbered) tests for special purposes. At
# present there is just one, called "heap". This test's output contains the
# sizes of heap frames and frame vectors, which depend on the environment. It
# is therefore not run unless explicitly requested.
#
# Inappropriate tests are automatically skipped (with a comment to say so). For
# example, if JIT support is not compiled, test 16 is skipped, whereas if JIT
# support is compiled, test 15 is skipped.
#
# Other arguments can be one of the words "-valgrind", "-valgrind-log", or
# "-sim" followed by an argument to run cross-compiled executables under a
# simulator, for example:
#
# RunTest 3 -sim "qemu-arm -s 8388608"
#
# For backwards compatibility, -nojit, -valgrind, -valgrind-log, and -sim may
# be given without the leading "-" character.
#
# When PCRE2 is compiled by clang with -fsanitize arguments, some tests need
# very much more stack than normal. In environments where the stack can be
# set at runtime, -bigstack sets a gigantic stack.
#
# Special cases where only one argument is allowed:
#   - If the script is invoked as "RunTest list", a list of available tests is
#     output, but none of them are run.
###############################################################################

# Define test titles in variables so that they can be output as a list. Some
# of them are modified (e.g. with -8 or -16) when used in the actual tests.

title0="Test 0: Unchecked pcre2test argument tests (to improve coverage)"
title1="Test 1: Main non-UTF, non-UCP functionality (compatible with Perl >= 5.10)"
title2="Test 2: API, errors, internals and non-Perl stuff"
title3="Test 3: Locale-specific features"
title4A="Test 4: UTF"
title4B=" and Unicode property support (compatible with Perl >= 5.10)"
title5A="Test 5: API, internals, and non-Perl stuff for UTF"
title5B=" and UCP support"
title6="Test 6: DFA matching main non-UTF, non-UCP functionality"
title7A="Test 7: DFA matching with UTF"
title7B=" and Unicode property support"
title8="Test 8: Internal offsets and code size tests"
title9="Test 9: Specials for the basic 8-bit library"
title10="Test 10: Specials for the 8-bit library with UTF-8 and UCP support"
title11="Test 11: Specials for the basic 16-bit and 32-bit libraries"
title12="Test 12: Specials for the 16-bit and 32-bit libraries UTF and UCP support"
title13="Test 13: DFA specials for the basic 16-bit and 32-bit libraries"
title14="Test 14: DFA specials for UTF and UCP support"
title15="Test 15: Non-JIT limits and other non-JIT tests"
title16="Test 16: JIT-specific features when JIT is not available"
title17="Test 17: JIT-specific features when JIT is available"
title18="Test 18: Tests of the POSIX interface, excluding UTF/UCP"
title19="Test 19: Tests of the POSIX interface with UTF/UCP"
title20="Test 20: Serialization and code copy tests"
title21="Test 21: \C tests without UTF (supported for DFA matching)"
title22="Test 22: \C tests with UTF (not supported for DFA matching)"
title23="Test 23: \C disabled test"
title24="Test 24: Non-UTF pattern conversion tests"
title25="Test 25: UTF pattern conversion tests"
title26="Test 26: Unicode property tests (compatible with Perl >= 5.38)"
title27="Test 27: Auto-generated unicode property tests"
title28="Test 28: EBCDIC-specific tests"
title29="Test 29: EBCDIC-specific tests (for NL=0x25)"
maxtest=29
titleheap="Test 'heap': Environment-specific heap tests"

if [ $# -eq 1 -a "$1" = "list" ]; then
  echo $title0
  echo $title1
  echo $title2 "(not UTF or UCP)"
  echo $title3
  echo $title4A $title4B
  echo $title5A $title5B
  echo $title6
  echo $title7A $title7B
  echo $title8
  echo $title9
  echo $title10
  echo $title11
  echo $title12
  echo $title13
  echo $title14
  echo $title15
  echo $title16
  echo $title17
  echo $title18
  echo $title19
  echo $title20
  echo $title21
  echo $title22
  echo $title23
  echo $title24
  echo $title25
  echo $title26
  echo $title27
  echo $title28
  echo $title29
  echo ""
  echo $titleheap
  echo ""
  echo "Numbered tests are automatically run if nothing selected."
  echo "Named tests must be explicitly selected."
  exit 0
fi

# Set up a suitable "diff" command for comparison. Some systems
# have a diff that lacks a -u option. Try to deal with this.
# Use gdiff if available.

cf="diff"
gdiff /dev/null /dev/null 2>/dev/null && cf="gdiff"
$cf -u /dev/null /dev/null 2>/dev/null && cf="$cf -u"

# Find the test data

if [ -n "$srcdir" -a -d "$srcdir" ] ; then
  testdata="$srcdir/testdata"
elif [ -d "./testdata" ] ; then
  testdata=./testdata
elif [ -d "../testdata" ] ; then
  testdata=../testdata
else
  echo "Cannot find the testdata directory"
  exit 1
fi

yield=0


# ------ Function to check results of a test -------

# This function is called with three parameters:
#
#  $1 the value of $? after a call to pcre2test
#  $2 the suffix of the output file to compare with
#  $3 the $opt value (empty, -jit, or -dfa)
#
# Note: must define using name(), not "function name", for Solaris.

checkresult()
  {
  if [ $1 -ne 0 ] ; then
    echo "** pcre2test failed - check testoutput$bits$3/testoutput$2"
    yield=1
    return
  fi
  case "$3" in
    -jit) with=" with JIT";;
    -dfa) with=" with DFA";;
    *)    with="";;
  esac
  cf_out="$testdata/testoutput$2"
  if [ $ebcdic -eq 1 ] ; then
    # We currently only use the #if ... #endif support in pcre2test for EBCDIC
    # testing. Run in "preprocess-only" mode (-E) on the testoutput file to trim
    # the output lines matching the input lines which are discarded.
    $sim $pcre2test -q -E "$cf_out" >testoutput$bits$3/testoutput$2-expected
    cf_out=testoutput$bits$3/testoutput$2-expected
  fi
  $cf "$cf_out" testoutput$bits$3/testoutput$2
  if [ $? != 0 ] ; then
    echo ""
    echo "** Test $2 failed$with"
    yield=1
    return
  fi
  echo "  OK$with"
  }


# ------ Function to run and check a special pcre2test arguments test -------

checkspecial()
  {
  expect=${2:-0}
  $sim $valgrind $vjs $pcre2test $1 >>testSoutput 2>&1
  if [ $? -ne "$expect" ] ; then
    echo "** pcre2test $1 failed - check testSoutput"
    yield=1
    return 1
  fi
  return 0
  }


# ------ Test setup ------

# Default values

arg8=
arg16=
arg32=
nojit=
bigstack=
malloc=
sim=
skip=
valgrind=
vjs=
globalopts="-q"
: ${pcre2test:=./pcre2test}

# This is in case the caller has set aliases (as I do - PH)
unset cp ls mv rm

if [ ! -x $pcre2test ] ; then
  echo "** $pcre2test does not exist or is not executable."
  exit 1
fi

# Process options and select which tests to run; for those that are explicitly
# requested, check that the necessary optional facilities are available.

do0=no
do1=no
do2=no
do3=no
do4=no
do5=no
do6=no
do7=no
do8=no
do9=no
do10=no
do11=no
do12=no
do13=no
do14=no
do15=no
do16=no
do17=no
do18=no
do19=no
do20=no
do21=no
do22=no
do23=no
do24=no
do25=no
do26=no
do27=no
do28=no
do29=no
doheap=no

while [ $# -gt 0 ] ; do
  case $1 in
    0) do0=yes;;
    1) do1=yes;;
    2) do2=yes;;
    3) do3=yes;;
    4) do4=yes;;
    5) do5=yes;;
    6) do6=yes;;
    7) do7=yes;;
    8) do8=yes;;
    9) do9=yes;;
   10) do10=yes;;
   11) do11=yes;;
   12) do12=yes;;
   13) do13=yes;;
   14) do14=yes;;
   15) do15=yes;;
   16) do16=yes;;
   17) do17=yes;;
   18) do18=yes;;
   19) do19=yes;;
   20) do20=yes;;
   21) do21=yes;;
   22) do22=yes;;
   23) do23=yes;;
   24) do24=yes;;
   25) do25=yes;;
   26) do26=yes;;
   27) do27=yes;;
   28) do28=yes;;
   29) do29=yes;;
   heap) doheap=yes;;
  -8) arg8=yes;;
  -16) arg16=yes;;
  -32) arg32=yes;;
   bigstack|-bigstack) bigstack=yes;;
   malloc|-malloc) malloc=yes;;
   nojit|-nojit) nojit=yes;;
   sim|-sim) shift; sim=$1;;
   valgrind|-valgrind) valgrind="valgrind --tool=memcheck -q --leak-check=yes --errors-for-leak-kinds=all --smc-check=all-non-file --error-exitcode=70";;
   valgrind-log|-valgrind-log) valgrind="valgrind --tool=memcheck --num-callers=30 --leak-check=yes --errors-for-leak-kinds=all --error-limit=no --smc-check=all-non-file --log-file=report.%p ";;
   ~*)
     if expr "$1" : '~[0-9][0-9]*$' >/dev/null; then
       skip="$skip `expr "$1" : '~\([0-9]*\)*$'`"
     else
       echo "Unknown option or test selector '$1'"; exit 1
     fi
   ;;
   *-*)
     if expr "$1" : '[0-9][0-9]*-[0-9]*$' >/dev/null; then
       tf=`expr "$1" : '\([0-9]*\)'`
       tt=`expr "$1" : '.*-\([0-9]*\)'`
       if [ "$tt" = "" ] ; then tt=$maxtest; fi
       if expr \( "$tt" ">" "$maxtest" \) >/dev/null; then
         echo "Invalid test range '$1'"; exit 1
       fi
       while expr "$tf" "<=" "$tt" >/dev/null; do
         eval do${tf}=yes
         tf=`expr $tf + 1`
       done
     else
       echo "Invalid test range '$1'"; exit 1
     fi
   ;;
   *) echo "Unknown option or test selector '$1'"; exit 1;;
  esac
  shift
done

# If it is possible to set the system stack size and -bigstack was given,
# set up a large stack.

$sim $pcre2test -S 32 /dev/null /dev/null >/dev/null 2>&1
support_setstack=$?
if [ $support_setstack -eq 0 -a "$bigstack" != "" ] ; then
  globalopts="$globalopts -S 32"
fi

# If the malloc option is given, then call pcre2test with -malloc.

if [ "$malloc" != "" ] ; then
  globalopts="$globalopts -malloc"
fi

# All of 8-bit, 16-bit, and 32-bit character strings may be supported, but only
# one need be.

$sim $pcre2test -C pcre2-8 >/dev/null
support8=$?
$sim $pcre2test -C pcre2-16 >/dev/null
support16=$?
$sim $pcre2test -C pcre2-32 >/dev/null
support32=$?

# \C may be disabled

$sim $pcre2test -C backslash-C >/dev/null
supportBSC=$?

# Check if compiled in EBCDIC mode, and whether we have EBCDIC I/O and NL=0x25
$sim $pcre2test -C ebcdic >/dev/null
ebcdic=$?
$sim $pcre2test -C ebcdic-io >/dev/null
ebcdic_io=$?
$sim $pcre2test -C ebcdic-nl25 >/dev/null
ebcdic_nl25=$?

if [ $ebcdic -eq 1 ]; then
  if [ $ebcdic_io -eq 0 ]; then
    echo "Running tests in EBCDIC mode, and expecting ASCII test data"
  else
    echo "Running tests in EBCDIC mode, and expecting EBCDIC test data"
    echo "If you are on an EBCDIC machine, you will need to convert the PCRE2"
    echo "testdata/ directory from ISO8859-1, so the data match the EBCDIC"
    echo "codepage that your C compiler is using for C character literals."
    echo "For example:"
    echo "  iconv -f ISO8859-1 -t IBM-1047 ..."
  fi
fi

# Initialize all bitsizes skipped

test8=skip
test16=skip
test32=skip

# If no bitsize arguments, select all that are available

if [ "$arg8$arg16$arg32" = "" ] ; then
  if [ $support8 -ne 0 ] ; then
    test8=-8
  fi
  if [ $support16 -ne 0 ] ; then
    test16=-16
  fi
  if [ $support32 -ne 0 ] ; then
    test32=-32
  fi

# Otherwise, select requested bit sizes

else
  if [ "$arg8" = yes ] ; then
    if [ $support8 -eq 0 ] ; then
      echo "Cannot run 8-bit library tests: 8-bit library not compiled"
      exit 1
    fi
    test8=-8
  fi
  if [ "$arg16" = yes ] ; then
    if [ $support16 -eq 0 ] ; then
      echo "Cannot run 16-bit library tests: 16-bit library not compiled"
      exit 1
    fi
    test16=-16
  fi
  if [ "$arg32" = yes ] ; then
    if [ $support32 -eq 0 ] ; then
      echo "Cannot run 32-bit library tests: 32-bit library not compiled"
      exit 1
    fi
    test32=-32
  fi
fi

# UTF support is implied by Unicode support, and it always applies to all bit
# sizes if both are supported; we can't have UTF-8 support without UTF-16 or
# UTF-32 support.

$sim $pcre2test -C unicode >/dev/null
utf=$?

# When JIT is used with valgrind, we need to set up valgrind suppressions as
# otherwise there are a lot of false positive valgrind reports when the
# the hardware supports SSE2.

jitopt=
$sim $pcre2test -C jit >/dev/null
jit=$?
if [ $jit -ne 0 -a "$nojit" != "yes" ] ; then
  jitopt=-jit
  if [ "$valgrind" != "" ] ; then
    vjs="--suppressions=$testdata/valgrind-jit.supp"
  fi
fi

# If no specific tests were requested, select all the numbered tests. Those
# that are not relevant will be automatically skipped.

if [ $do0  = no -a $do1  = no -a $do2  = no -a $do3  = no -a \
     $do4  = no -a $do5  = no -a $do6  = no -a $do7  = no -a \
     $do8  = no -a $do9  = no -a $do10 = no -a $do11 = no -a \
     $do12 = no -a $do13 = no -a $do14 = no -a $do15 = no -a \
     $do16 = no -a $do17 = no -a $do18 = no -a $do19 = no -a \
     $do20 = no -a $do21 = no -a $do22 = no -a $do23 = no -a \
     $do24 = no -a $do25 = no -a $do26 = no -a $do27 = no -a \
     $do28 = no -a $do29 = no -a $doheap = no \
   ]; then
  do0=yes
  do1=yes
  do2=yes
  do3=yes
  do4=yes
  do5=yes
  do6=yes
  do7=yes
  do8=yes
  do9=yes
  do10=yes
  do11=yes
  do12=yes
  do13=yes
  do14=yes
  do15=yes
  do16=yes
  do17=yes
  do18=yes
  do19=yes
  do20=yes
  do21=yes
  do22=yes
  do23=yes
  do24=yes
  do25=yes
  do26=yes
  do27=yes
  do28=yes
  do29=yes
fi

# Handle any explicit skips at this stage, so that an argument list may consist
# only of explicit skips.

for i in $skip; do eval do$i=no; done

# Show which release and which test data

echo ""
echo PCRE2 C library tests using test data from $testdata
$sim $pcre2test /dev/null
echo ""


# ------ Normal Tests ------

for bmode in "$test8" "$test16" "$test32"; do
  case "$bmode" in
    skip) continue;;
    -16)  if [ "$test8$test32" != "skipskip" ] ; then echo ""; fi
          bits=16; echo "---- Testing 16-bit library ----"; echo "";;
    -32)  if [ "$test8$test16" != "skipskip" ] ; then echo ""; fi
          bits=32; echo "---- Testing 32-bit library ----"; echo "";;
    -8)   bits=8; echo "---- Testing 8-bit library ----"; echo "";;
  esac

  # Set up directories for test output.
  [ -d testoutput$bits ] || mkdir testoutput$bits
  [ -d testoutput$bits$jitopt ] || mkdir testoutput$bits$jitopt
  [ -d testoutput$bits-dfa ] || mkdir testoutput$bits-dfa

  # Test 0 is a special test. Its output is not checked, because it will
  # be different on different hardware and with different configurations.
  # Running this test just exercises the code.

  if [ $do0 = yes ] ; then
    echo $title0
    echo '/abc/jit,memory,framesize' >testSinput
    echo '   abc' >>testSinput
    echo '' >testSoutput
    saverc=0
    checkspecial "$bmode -C" || saverc=$?
    checkspecial '--help' || saverc=$?
    checkspecial "$bmode testSinput" || saverc=$?
    checkspecial "$bmode $testdata/testinputheap" || saverc=$?
    if [ $support_setstack -eq 0 ] ; then
      checkspecial "$bmode -S 1 -t 10 testSinput" || saverc=$?
    fi
    checkspecial "$bmode reallydoesnotexist" 1 || saverc=$?
    checkspecial "$bmode testSinput reallydoesnotexist/outfile" 1 || saverc=$?
    checkspecial "$bmode -pattern debug testSinput" || saverc=$?
    checkspecial "$bmode -pattern INVALID testSinput" 1 2>/dev/null || saverc=$?
    checkspecial "$bmode -subject notempty testSinput" || saverc=$?
    checkspecial "$bmode -subject INVALID testSinput" 1 2>/dev/null || saverc=$?
    checkspecial -LM || saverc=$?
    checkspecial -LP || saverc=$?
    checkspecial -LS || saverc=$?
    checkspecial "$bmode -unittest" || saverc=$?
    if [ $saverc -eq 0 ] ; then
      echo "  OK"
    fi
  fi

  # Primary non-UTF test, compatible with JIT and all versions of Perl >= 5.8

  if [ $do1 = yes ] ; then
    echo $title1
    for opt in "" $jitopt; do
      $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput1 testoutput$bits$opt/testoutput1
      checkresult $? 1 "$opt"
    done
  fi

  # PCRE2 tests that are not Perl-compatible: API, errors, internals. We copy
  # the testbtables file to the current directory for use by this test.

  if [ $do2 = yes ] ; then
    echo $title2 "(excluding UTF-$bits)"
    cp $testdata/testbtables .
    for opt in "" $jitopt; do
      $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput2 testoutput$bits$opt/testoutput2
      saverc=$?
      if [ $saverc = 0 ] ; then
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt -error -80,-62,-2,-1,0,100,101,191,300 >>testoutput$bits$opt/testoutput2
        checkresult $? 2 "$opt"
      else
        checkresult $saverc 2 "$opt"
      fi
    done
  fi

  # Locale-specific tests, provided that either the "fr_FR", "fr_CA", "french"
  # or "fr" locale is available. The first two are Unix-like standards; the
  # last two are for Windows. Unfortunately, different versions of the French
  # locale give different outputs for some items. This test passes if the
  # output matches any one of the alternative output files.

  if [ $do3 = yes ] ; then
    locale=

    # In some environments locales that are listed by the "locale -a"
    # command do not seem to work with setlocale(). Therefore, we do
    # a preliminary test to see if pcre2test can set one before going
    # on to use it.

    for loc in 'fr_FR' 'french' 'fr' 'fr_CA'; do
      locale -a | grep "^$loc\$" >/dev/null
      if [ $? -eq 0 ] ; then
        echo "/a/locale=$loc" | \
          $sim $valgrind $pcre2test -q $bmode | \
            grep "Failed to set locale" >/dev/null
        if [ $? -ne 0 ] ; then
          locale=$loc
          if [ "$locale" = "fr_FR" ] ; then
            infile=$testdata/testinput3
            outfile=$testdata/testoutput3
            outfile2=$testdata/testoutput3A
            outfile3=$testdata/testoutput3B
            outfile4=$testdata/testoutput3C
          else
            infile=test3input
            outfile=test3output
            outfile2=test3outputA
            outfile3=test3outputB
            outfile4=test3outputC
            sed "s/fr_FR/$loc/" $testdata/testinput3 >test3input
            sed "s/fr_FR/$loc/" $testdata/testoutput3 >test3output
            sed "s/fr_FR/$loc/" $testdata/testoutput3A >test3outputA
            sed "s/fr_FR/$loc/" $testdata/testoutput3B >test3outputB
            sed "s/fr_FR/$loc/" $testdata/testoutput3C >test3outputC
          fi
          break
        fi
      fi
    done

    if [ "$locale" != "" ] ; then
      echo $title3 "(using '$locale' locale)"
      for opt in "" $jitopt; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $infile testoutput$bits/testoutput3
        if [ $? = 0 ] ; then
          case "$opt" in
            -jit) with=" with JIT";;
            *)    with="";;
          esac
          if $cf $outfile testoutput$bits/testoutput3 >teststdout || \
             $cf $outfile2 testoutput$bits/testoutput3 >>teststdout || \
             $cf $outfile3 testoutput$bits/testoutput3 >>teststdout || \
             $cf $outfile4 testoutput$bits/testoutput3 >>teststdout
          then
            echo "  OK$with"
          else
            cat teststdout
            echo ""
            echo "** Locale test did not run successfully$with. The output did not match"
            echo "   $outfile, $outfile2, $outfile3 or $outfile4."
            echo "   This may mean that there is a problem with the locale settings rather"
            echo "   than a bug in PCRE2."
            yield=1
          fi
        else
          echo "** pcre2test failed - check testoutput$bits/testoutput3"
          yield=1
        fi
      done
    else
      echo "Cannot test locale-specific features - none of the 'fr_FR', 'fr_CA',"
      echo "'fr' or 'french' locales can be set, or the \"locale\" command is"
      echo "not available to check for them."
      echo " "
    fi
  fi

  # Tests for UTF and Unicode property support

  if [ $do4 = yes ] ; then
    echo ${title4A}-${bits}${title4B}
    if [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      for opt in "" $jitopt; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput4 testoutput$bits$opt/testoutput4
        checkresult $? 4 "$opt"
      done
    fi
  fi

  if [ $do5 = yes ] ; then
    echo ${title5A}-${bits}$title5B
    if [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      for opt in "" $jitopt; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput5 testoutput$bits$opt/testoutput5
        checkresult $? 5 "$opt"
      done
    fi
  fi

  # Tests for DFA matching support

  if [ $do6 = yes ] ; then
    echo $title6
    $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput6 testoutput$bits/testoutput6
    checkresult $? 6 ""
  fi

  if [ $do7 = yes ] ; then
    echo ${title7A}-${bits}$title7B
    if [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput7 testoutput$bits/testoutput7
      checkresult $? 7 ""
    fi
  fi

  # Test of internal offsets and code sizes. This test is run only when there
  # is UTF/UCP support. The actual tests are mostly the same as in some of the
  # above, but in this test we inspect some offsets and sizes. This is a
  # doublecheck for the maintainer, just in case something changes unexpectedly.
  # The output from this test is different in 8-bit, 16-bit, and 32-bit modes
  # and for different link sizes, so there are different output files for each
  # mode and link size.

  if [ $do8 = yes ] ; then
    echo $title8
    $sim $pcre2test -$bits -C linksize >/dev/null
    bits_link_size=$?
    if [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput8 testoutput$bits/testoutput8-$bits-$bits_link_size
      checkresult $? 8-$bits-$bits_link_size ""
    fi
  fi

  # Tests for 8-bit-specific features

  if [ "$do9" = yes ] ; then
    echo $title9
    if [ "$bits" = "16" -o "$bits" = "32" ] ; then
      echo "  Skipped when running 16/32-bit tests"
    else
      for opt in "" $jitopt; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput9 testoutput$bits$opt/testoutput9
        checkresult $? 9 "$opt"
      done
    fi
  fi

  # Tests for UTF-8 and UCP 8-bit-specific features

  if [ "$do10" = yes ] ; then
    echo $title10
    if [ "$bits" = "16" -o "$bits" = "32" ] ; then
      echo "  Skipped when running 16/32-bit tests"
    elif [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      for opt in "" $jitopt; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput10 testoutput$bits$opt/testoutput10
        checkresult $? 10 "$opt"
      done
    fi
  fi

  # Tests for 16-bit and 32-bit features. Output is different for the two widths.

  if [ $do11 = yes ] ; then
    echo $title11
    if [ "$bits" = "8" ] ; then
      echo "  Skipped when running 8-bit tests"
    else
      for opt in "" $jitopt; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput11 testoutput$bits$opt/testoutput11-$bits
        checkresult $? 11-$bits "$opt"
      done
    fi
  fi

  # Tests for 16-bit and 32-bit features with UTF-16/32 and UCP support. Output
  # is different for the two widths.

  if [ $do12 = yes ] ; then
    echo $title12
    if [ "$bits" = "8" ] ; then
      echo "  Skipped when running 8-bit tests"
    elif [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      for opt in "" $jitopt; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput12 testoutput$bits$opt/testoutput12-$bits
        checkresult $? 12-$bits "$opt"
      done
    fi
  fi

  # Tests for 16/32-bit-specific features in DFA non-UTF modes

  if [ $do13 = yes ] ; then
    echo $title13
    if [ "$bits" = "8" ] ; then
      echo "  Skipped when running 8-bit tests"
    else
      $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput13 testoutput$bits/testoutput13
      checkresult $? 13 ""
    fi
  fi

  # Tests for DFA UTF and UCP features. Output is different for the different widths.

  if [ $do14 = yes ] ; then
    echo $title14
    if [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput14 testoutput$bits/testoutput14-$bits
      checkresult $? 14-$bits ""
    fi
  fi

  # Test non-JIT match and recursion limits

  if [ $do15 = yes ] ; then
    echo $title15
    $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput15 testoutput$bits/testoutput15
    checkresult $? 15 ""
  fi

  # Test JIT-specific features when JIT is not available

  if [ $do16 = yes ] ; then
    echo $title16
    if [ $jit -ne 0 ] ; then
      echo "  Skipped because JIT is available"
    else
      $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput16 testoutput$bits/testoutput16
      checkresult $? 16 ""
    fi
  fi

  # Test JIT-specific features when JIT is available

  if [ $do17 = yes ] ; then
    echo $title17
    if [ $jit -eq 0 -o "$nojit" = "yes" ] ; then
      echo "  Skipped because JIT is not available or nojit was specified"
    else
      $sim $valgrind $vjs $pcre2test $globalopts $bmode $testdata/testinput17 testoutput$bits/testoutput17
      checkresult $? 17 ""
    fi
  fi

  # Tests for the POSIX interface without UTF/UCP (8-bit only)

  if [ $do18 = yes ] ; then
    echo $title18
    if [ "$bits" = "16" -o "$bits" = "32" ] ; then
      echo "  Skipped when running 16/32-bit tests"
    else
      $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput18 testoutput$bits/testoutput18
      checkresult $? 18 ""
    fi
  fi

  # Tests for the POSIX interface with UTF/UCP (8-bit only)

  if [ $do19 = yes ] ; then
    echo $title19
    if [ "$bits" = "16" -o "$bits" = "32" ] ; then
      echo "  Skipped when running 16/32-bit tests"
    elif [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput19 testoutput$bits/testoutput19
      checkresult $? 19 ""
    fi
  fi

  # Serialization tests

  if [ $do20 = yes ] ; then
    echo $title20
    $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput20 testoutput$bits/testoutput20
    checkresult $? 20 ""
  fi

  # \C tests without UTF - DFA matching is supported

  if [ "$do21" = yes ] ; then
    echo $title21
    if [ $supportBSC -eq 0 ] ; then
      echo "  Skipped because \C is disabled"
    else
      for opt in "" $jitopt -dfa; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput21 testoutput$bits$opt/testoutput21
        checkresult $? 21 "$opt"
      done
    fi
  fi

  # \C tests with UTF - DFA matching is not supported for \C in UTF mode

  if [ "$do22" = yes ] ; then
    echo $title22
    if [ $supportBSC -eq 0 ] ; then
      echo "  Skipped because \C is disabled"
    elif [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      for opt in "" $jitopt; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput22 testoutput$bits$opt/testoutput22-$bits
        checkresult $? 22-$bits "$opt"
      done
    fi
  fi

  # Test when \C is disabled

  if [ "$do23" = yes ] ; then
    echo $title23
    if [ $supportBSC -ne 0 ] ; then
      echo "  Skipped because \C is not disabled"
    else
      $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput23 testoutput$bits/testoutput23
      checkresult $? 23 ""
    fi
  fi

  # Non-UTF pattern conversion tests

  if [ "$do24" = yes ] ; then
    echo $title24
    $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput24 testoutput$bits/testoutput24
    checkresult $? 24 ""
  fi

  # UTF pattern conversion tests

  if [ "$do25" = yes ] ; then
    echo $title25
    if [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinput25 testoutput$bits/testoutput25
      checkresult $? 25 ""
    fi
  fi

  # Unicode property tests

  if [ $do26 = yes ] ; then
    echo $title26
    if [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      for opt in "" $jitopt; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput26 testoutput$bits$opt/testoutput26
        checkresult $? 26 "$opt"
      done
    fi
  fi

  # Auto-generated Unicode property tests

  if [ $do27 = yes ] ; then
    echo $title27
    if [ $utf -eq 0 ] ; then
      echo "  Skipped because UTF-$bits support is not available"
    else
      for opt in "" $jitopt; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput27 testoutput$bits$opt/testoutput27
        checkresult $? 27 "$opt"
      done
    fi
  fi

  # EBCDIC tests

  if [ $do28 = yes ] ; then
    echo $title28
    if [ $ebcdic -eq 0 ] ; then
      echo "  Skipped when not targetting EBCDIC"
    else
      for opt in "" $jitopt "-dfa"; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput28 testoutput$bits$opt/testoutput28
        checkresult $? 28 "$opt"
      done
    fi
  fi

  # EBCDIC tests (for NL=0x25)

  if [ $do29 = yes ] ; then
    echo $title29
    if [ $ebcdic -eq 0 ] ; then
      echo "  Skipped when not targetting EBCDIC"
    elif [ $ebcdic_nl25 -eq 0 ] ; then
      echo "  Skipped because EBCDIC newline is not 0x25"
    else
      for opt in "" $jitopt "-dfa"; do
        $sim $valgrind ${opt:+$vjs} $pcre2test $globalopts $bmode $opt $testdata/testinput29 testoutput$bits$opt/testoutput29
        checkresult $? 29 "$opt"
      done
    fi
  fi

  # Manually selected heap tests - output may vary in different environments,
  # which is why that are not automatically run.

  if [ $doheap = yes ] ; then
    echo $titleheap
    $sim $valgrind $pcre2test $globalopts $bmode $testdata/testinputheap testoutput$bits/testoutputheap-$bits
    checkresult $? heap-$bits ""
  fi

# End of loop for 8/16/32-bit tests
done


if [ $yield -eq 0 ] ; then
  echo ""
  echo "All tests passed."

  # Clean up local working files
  rm -f testbtables testSinput testSoutput test3input test3output test3outputA test3outputB testsaved1 testsaved2 teststdout teststderr
  rm -rf testoutput8 testoutput8-jit testoutput8-dfa \
         testoutput16 testoutput16-jit testoutput16-dfa \
         testoutput32 testoutput32-jit testoutput32-dfa
else
  echo ""
  echo "** Tests failed. See output above for details."
fi

exit $yield

# End
