#!/bin/sh
#
# Make a new PCP QA test that runs an existing test under valgrind
#
# Copyright (c) 1997-2002 Silicon Graphics, Inc.  All Rights Reserved.
# Copyright (c) 2021 Ken McDonell.  All Rights Reserved.
#
# Usage: new-grind [-n|-v] seq-no
#
#

# generic initialization
. ./common.rc

min=1600
max=1999
max_probes=200

_usage()
{
    echo >&2 "Usage: new-grind [options] seq-no"
    echo >&2
    echo >&2 "Options:"
    echo >&2 "-n   show-me, change nothing"
    echo >&2 "-v   verbose"

    exit 1
}

showme=false
verbose=false
while getopts 'nrsv?' p
do
    case "$p"
    in
	n)	showme=true
		;;
	v)	verbose=true
		;;
	?)	echo "bad arg: $p"; _usage
		# NOTREACHED
    esac
done
shift `expr $OPTIND - 1`

if [ $# -ne 1 ]
then
    _usage
    # NOTREACHED
fi

oldseq=$1

if [ ! -f "$oldseq" ]
then
    echo "Error: test \"$oldseq\" does not exist"
    exit 1
fi

if grep "^do_valgrind=false" $oldseq >/dev/null
then
    :
else
    echo "Error: test \"$oldseq\" does look like it was created recently with ./new"
    echo "... no \"do_valgrind=false\" line"
    exit 1
fi

if egrep "_run_(valgrind|helgrind) " $oldseq >/dev/null
then
    if grep "_run_valgrind \.\.\.your test goes here\.\.\." $oldseq >/dev/null
    then
	echo "Error: test \"$oldseq\" still contains the dummy \"_run_valgrind\" line"
	exit 1
    fi
else
    echo "Error: test \"$oldseq\" does not contain a \"_run_valgrind\" or"
    echo "\"_run_helgrind\" line"
    exit 1
fi

if [ ! -f group ]
then
    echo "Error: no \"group\" file"
    exit 1
fi

oldgroup=`grep "^$oldseq[ :]" <group`
if [ -z "$oldgroup" ]
then
    echo "Error: test \"$oldseq\" not found in \"group\" file"
    exit 1
fi

if [ ! -w group ]
then
    echo "Error: cannot write index file \"group\""
    exit 1
fi

tmp=/tmp/new-grind-$$
sts=1
trap "rm -f $tmp.*; exit \$sts" 0 1 2 3 15

try=`expr $oldseq + 1`
try=`printf "%03d\n" $try`
# first $oldseq+1, then keep serially probing
#
$verbose && echo >&2 "Info: start probing at $try"
probe=0
while [ $probe -lt $max_probes ]
do
    if grep "^$try[ :]" <group >/dev/null
    then
	# already allocated ... try again
	#
	seed=$try
	try=`expr $try + 1`
	try=`printf "%03d\n" $try`
	$verbose && echo >&2 "Info: try $try"
    else
	newseq=$try
	break
    fi
done

if [ $probe -eq $max_probes ]
then
    echo >&2 "Error: after $max_probes attempts, no unassigned tests in the range $oldseq ...  Time to increase \$max_probes"
    exit 1
fi

if [ -f $newseq ]
then
    echo >&2 "Error: test $newseq already exists, but not in group file!"
    exit
fi

if $showme
then
    echo $newseq
    exit
fi

echo "Allocated test number $newseq"
newgroup=`echo $oldgroup | sed -e "s/^$oldseq\([: ]\)/$newseq\1/" -e 's/$/ valgrind/'`

if grep 'non-valgrind' $oldseq >/dev/null
then
    : annotation already added
else
    $PCP_AWK_PROG <$oldseq >$oldseq.new-grind '
BEGIN			{ done = 0 }
NF == 1 && $1 == "#" && done == 0	{
			  print "# non-valgrind variant, see qa/'$newseq' for the valgrind variant"
			  done = 1
			}
			{ print }'
    mv $oldseq.new-grind $oldseq
    chmod 755 $oldseq
fi

$PCP_AWK_PROG <$oldseq >$newseq '
BEGIN			{ done = 0 }
NF == 0			{ exit }
/non-valgrind variant/	{ next }
/PCP QA Test No/	{ sub(/'$oldseq'$/, "'$newseq'") }
NF == 1 && $1 == "#" && done == 0	{
			  print "# valgrind variant, see qa/'$oldseq' for the non-valgrind variant"
			  done = 1
			}
			{ print }'
			
cat <<End-of-File >>$newseq

seq=\`basename \$0\`
echo "QA output created by \$seq"

# get standard environment, filters and checks
. ./common.product
. ./common.filter
. ./common.check

_check_valgrind

_cleanup()
{
    cd \$here
    \$sudo rm -rf \$tmp \$tmp.*
}

status=0	# success is the default!
\$sudo rm -rf \$tmp \$tmp.* \$seq.full
trap "_cleanup; exit \\\$status" 0 1 2 3 15

# real QA test starts here
export seq
./$oldseq --valgrind \
| \$PCP_AWK_PROG '
skip == 1 && \$1 == "==="       { skip = 0 }
/^=== std err ===/             { skip = 1 }
skip == 0              { print }
skip == 1              { print >>"'\$here/\$seq.full'" }'

# success, all done
exit
End-of-File
chmod 755 $newseq

echo "Creating $newseq script"
echo "Adding $newseq to group index"
echo "$newgroup" >>group

# sort the tests numerically
#
$PCP_AWK_PROG <group '
BEGIN				{ state = "head" }
state == "head" && /^[0-9]/	{ state = "list" }
				{ print >"'$tmp'." state }'
sort -n $tmp.list >>$tmp.head
cp $tmp.head group

# make a $newseq.out placeholder if not already done
#
if [ ! -f $newseq.out ]
then
    echo "Creating output $newseq.out"
    echo "QA output created by $newseq" >$newseq.out
    if [ -f $oldseq.out ]
    then
	sed -e '1s/$/ --valgrind/' <$oldseq.out >>$newseq.out
    else
	echo "[skeleton from qa/new, replace me]" >>$newseq.out
    fi
fi

# and finally, don't forget the git work ...
#
git add $newseq $newseq.out

sts=0
exit
