#!/bin/sh

TMP=${MPRTMP-/tmp}
MPRAWK=${MPRAWK-awk}

pcfile=$TMP/mpr.pc.$$
gdbfile=$TMP/mpr.gdb.$$
gdbcmdfile=$TMP/mpr.gdbcmd.$$
fofiles=

for arg in "$@"; do
	case "$1" in
	-F )	fofiles="$2"; shift;;
	-F*)	fofiles=`echo "$1" | sed 's/-F//'`;;
	--)	shift; break;;
	-*)	echo "mprfl: warning: ignoring unknown option $1" >&2;;
	*)	break;;
	esac
	shift
done

case "$#" in
1|2)	;;
*)	echo "usage: mprfl [-F foo.c,bar.c,..] a.out [log]" >&2
	exit 1;;
esac

aout=`mprwhich "$1"` || exit 1; shift
MPRFILTER=`mprfilter mprfl "$@"` || exit 1

status=1
set -e
trap 'set +e; rm -f $pcfile $gdbfile $gdbcmdfile; trap 0; exit $status' 0 1 2 13 15

$MPRFILTER |

$MPRAWK -F: '
	function savepc(n, i) { for (i=2; i<=n; i++) pc[$i]=1 }
	/^m/ { savepc(NF-2) }
	/^r/ { savepc(NF-3) }
	/^f/ { savepc(NF-1) }
	END  { for (i in pc) print i }
' |

sort -n | tee $pcfile |

(
	echo set prompt
	echo set width 0
	echo set print demangle off
	echo set print asm-demangle off
	$MPRAWK '{ printf "info line *%s\n", $1 }'
	echo quit
) >$gdbcmdfile

(gdb -nx -q --command=$gdbcmdfile "$aout" 2>/dev/null; echo) |

$MPRAWK '
	{
		gsub(/\(gdb\) /, "")
	}
	/^$/ {
		next
	}
	/^Line/ {
		gsub("\"", "", $4)
		if ($4 ~ /^\.\//)	# delete leading ./
			$4 = substr($4, 3)
		printf "%s\t%s\n", $4, $2
		next
	}
	/No line number/ {
		print "xxx"	# needed for paste
		next
	}
	/^(Current language|\(no debugging|\[New|\[Switching)/ {
		next
	}
	# unexpected output from gdb -> print a warning
	{
		printf "*** mprfl: warning: unexpected output from gdb\n" |"cat 1>&2"
		printf "*** mprfl: [%s]\n", $0 |"cat 1>&2"
	}

' >$gdbfile

paste $pcfile $gdbfile |

$MPRAWK -F"	" -v fofiles="$fofiles" '
	BEGIN {
		if (fofiles != "") {
			gsub(",", "|", fofiles)
			gsub(" ", "|", fofiles)
			gsub("/", "\\/", fofiles)
			gsub("\\.", "\\.", fofiles)
		}
	}
	/xxx$/ {
		next
	}
	{
		if (fofiles == "" || $2 ~ "^("fofiles")$")
			print
	}
'

status=0
