#!/bin/sh

# Copyright (c) 2003-2013 Aleksey Cheusov <vle@gmx.net>
# 
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# 
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

set -e

version (){
cat <<EOF
lmdbg-run 1.3.0
EOF
}

usage (){
    cat <<'EOF'
lmdbg is a tiny program for detecting memory leaks in C programs

usage: lmdbg [OPTIONS] <prog> [args...]
OPTIONS:
  -h                display this screen
  -V                display version

  -M <mode>
     l or leaks     program is analysed for memory leaks (the default)
     p or peak      statistical information about peak memory usage
                    per stacktrace is output
     a or allocs    statistical information about a number of allocations
                    per stacktrace is output
     m or max       statistical information about maximum number of bytes
                    allocated per stacktrace is output

  -o <filename>     set a filename for logging
  -v                verbose loggin

  -c <config_file>  configuration file for lmdbg-leaks

  -T <num>          pass -T<num> to lmdbg-run
  -B <num>          pass -B<num> to lmdbg-run
  -n                pass -n to lmdbg-run

  -a                pass -a to lmdbg-sym
  -g                pass -g to lmdbg-sym (default)
EOF
}

lmdbg_sym_opts=''
lmdbg_run_opts=''

mode=default

while getopts hVvo:c:gaT:B:nM: f; do
    case $f in
	h)
	    usage
	    exit 0;;
	V)
	    version
	    exit 0;;
	v)
	    verbose=--verbose;;
	o)
	    log_file="$OPTARG";;
        c)
	    conf_opts="-c $OPTARG";;
	g)
	    lmdbg_sym_opts="$lmdbg_sym_opts -g";;
	a)
	    lmdbg_sym_opts="$lmdbg_sym_opts -a";;
	T)
	    lmdbg_run_opts="$lmdbg_run_opts -T$OPTARG";;
	B)
	    lmdbg_run_opts="$lmdbg_run_opts -B$OPTARG";;
	n)
	    lmdbg_run_opts="$lmdbg_run_opts -n";;
	M)
	    mode="$OPTARG";;
	'?')
	    usage 1>&2
	    exit 1;;
    esac
done
shift $(expr $OPTIND - 1)

if test $# = 0; then
    echo "<prog> is missing. Run lmdbg -h for more information" 1>&2
    exit 1
fi

if test "_$log_file" = "_"; then
    echo "log file is not specified. Run lmdbg -h for more information" 1>&2
    exit 1
fi

if test -d /usr/lib/debug; then
    LD_LIBRARY_PATH=/usr/lib/debug:$LD_LIBRARY_PATH
fi

type lmdbg-run   > /dev/null || exit 1
type lmdbg-sym   > /dev/null || exit 2
type lmdbg-leaks > /dev/null || exit 3
type lmdbg-sysleaks > /dev/null || exit 3

case "$mode" in
    l|leaks)
	pipe="lmdbg-leaks | lmdbg-stat | lmdbg-sort -fleaks | lmdbg-sym $lmdbg_sym_opts | lmdbg-sysleaks $conf_opts -s | lmdbg-strip -a";;
    p|peak)
	pipe="lmdbg-stat | lmdbg-sort -fpeak | lmdbg-sym $lmdbg_sym_opts | lmdbg-strip -a";;
    a|allocs)
	pipe="lmdbg-stat | lmdbg-sort -fallocs | lmdbg-sym $lmdbg_sym_opts | lmdbg-strip -a";;
    m|max)
	pipe="lmdbg-stat | lmdbg-sort -fmax | lmdbg-sym $lmdbg_sym_opts | lmdbg-strip -a";;
    d|default)
	pipe="lmdbg-leaks | lmdbg-sym $lmdbg_sym_opts | lmdbg-sysleaks $conf_opts -s | grep -v '^info '";;
    *)
	echo "bad argument for -M" 1>&2
	exit 1;;
esac

lmdbg-run $lmdbg_run_opts -p "$pipe" -o "$log_file" "$@"
if test -s "$log_file"; then
    if test "$verbose"; then
	echo "Log file was saved to '$log_file'" 1>&2
    fi

    exit 10
else
    rm "$log_file"

    if test $verbose; then
	echo "No memory leaks detected" 1>&2
    fi
fi
