#!/bin/sh
#
# vitrace is a script to invoke valgrind-itrace and convert the results to
# qtrace format
#
# Copyright (c) International Business Machines Corp., 2008 - 2013

#
# Authors: Dave Nomura, Maynard Johnson
#
declare -a PROG
VAL_ARGS=""
OUTPUT=""
READABLE_OUTPUT="no"


# print help message
do_help()
{ 
	# --output is used to name output files
	echo "usage: vitrace [options] <program>"
	echo "     [--output-file=<output>] (The '.vgi' extension will be added automatically.)"
	echo "     [--fnname=<func>]"
	echo "     [--readable=no|yes] [--trace-instrs=yes|no] [--trace-mem=yes|no]"
	echo "     [--num-insns-before-start=<val>]"
	echo "     [--num-func-calls-before-start=<val>]"
	echo "     [--num-K-insns-to-collect=<val>]"
	echo "See 'valgrind --tool=itrace --help' for more details"
}

# check value is set
check_value()
{
	if test -z "$2"; then
		echo "vitrace: value missing for $1 option"
		do_help 
		exit 1
	fi
}

check_yes_no()
{
	check_value $1 $2
	if test "$2" != "yes" -a "$2" != "no"; then
		echo "vitrace: yes or no value expected for $1 option"
		exit 1
	fi
}

check_if_integer()
{
	check_value $1 $2
	if ! [ `expr $2 + 1 2> /dev/null` ] ; then
		echo "Bad option value: $2"
		exit 1
	fi ;
}

do_options()
{
	# default settings


	while [ "$#" -ne 0 ]
	do
		arg=`printf %s $1 | awk -F= '{print $1}'`
		val=`printf %s $1 | awk -F= '{print $2}'`
 
		case "$arg" in
			--help)
				do_help
				exit 0
				;;
			--output-file)
				check_value $arg $val
				OUTPUT=$val
				;;
			--fnname)
				check_value $arg $val
				VAL_ARGS="$VAL_ARGS $arg=$val"
				;;

			--trace-mem | --trace-instrs)
				check_yes_no $arg $val
				VAL_ARGS="$VAL_ARGS $arg=$val"
				;;

			--readable)
				check_yes_no $arg $val
				VAL_ARGS="$VAL_ARGS $arg=$val"
				if test "$val" == "yes"; then
					READABLE_OUTPUT="yes"
				fi
				;;

			--num-insns-before-start | --num-func-calls-before-start | --num-K-insns-to-collect)
				check_if_integer $arg $val
				VAL_ARGS="$VAL_ARGS $arg=$val"
				;;

			--*)
				VAL_ARGS="$VAL_ARGS $1"
				;;
			-*)
				unexpected arg: $1, ignored
				;;
			*)
				PROG=(${PROG[@]} $1)
				;; 
		esac
		shift
	done
}

do_options $@
trap "rm -f /tmp/vitrace$$" EXIT

if test "${#PROG[@]}" = 0; then
	echo vitrace: program to be traced must be specified
	exit 1
fi

if test -z "$OUTPUT"; then
	OUTPUT=`basename ${PROG[0]}`
fi

if test "$READABLE_OUTPUT" == "yes"; then
	valgrind --tool=itrace $VAL_ARGS ${PROG[@]}  > /tmp/vitrace$$ 2>&1
	status="$?"
	if test "$status" != "0"; then
		grep -v '^==' /tmp/vitrace$$
		exit 1
	else
		grep -v '^==' /tmp/vitrace$$ > $OUTPUT.vgi
	fi
else
	valgrind --tool=itrace $VAL_ARGS --binary-outfile=$OUTPUT.vgi ${PROG[@]}
fi

vgi2qt -f $OUTPUT.vgi -o $OUTPUT.qt
status="$?"

rm -f /tmp/vitrace$$
exit $status

