#!/bin/sh
# refdbg.  Generated from refdbg.in by configure.
#
# -----------------------------------------------------------------
# refdbg - Shell script to do the LD_PRELOAD magic.
#
# refdbg - GObject refcount debugger
# Copyright (C) 2004-2005 Josh Green <jgreen@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA or point your web browser to http://www.gnu.org.
# -----------------------------------------------------------------

usage() {
   echo "GObject refcount debugger"
   echo "(C) 2004 Josh Green <jgreen@users.sourceforge.net>"
   echo "Distributed under the GPL license"
   echo
   echo "Usage: refdbg [options] <program> [program arguments..]"
   echo "  -c \"cmd1;cmd2;...\"    Execute refdbg init commands"
   echo "  -h, --help            Display detailed help"
   echo
   echo "Commands (-c, use 'help' in RefDbg shell for more info):"
   echo "help [topic]          Get help"
   echo "exit/quit/q           Quit the RefDbg shell (ignored if not in the shell)"
   echo "display [DispRule]    Display event log with optional criteria"
   echo "object [ObjRule]      Display object information with optional criteria"
   echo "clear                 Clear event log and refcount timer"
   echo "stats                 Get RefDbg statistics (event log size, mem usage, etc)"
   echo "time                  Get current time (offset from RefDbg start time)"
   echo "timer=<MSEC>          Refcount timer expire in milliseconds (0 = disable)"
   echo "rules                 Display current rule stack"
   echo "addrule <Rule>        Add an event rule to the event stack"
   echo "insrule <POS> <Rule>  Insert a rule at the given position (POS >= 0)"
   echo "delrule <N>           Delete a rule by rule number"
   echo "r0=<Rule>             Set the default event rule"
   echo "r<N>=<Rule>           Set a specific rule"
   echo "savelog=0|1           Enable or disable saving of event log on exit"
   echo "btnum=<N>             Set max callers in stack backtraces to N (init only)"
   echo "notimer               Disable glib timer callback (init only)"
   echo "dispmax=<N>           Set max items/events to display for display commands"
   echo
   if [ $# -eq 1 ]; then  # Function argument is set to display detailed help
   echo "<Rule> format:"
   echo "<GType> <!GType> 0x76543210 !0xFEDCBA98 D:<Flags> B:<Flags> L:<Flags>"
   echo "  '<GType>'             Specifies a GObject type to match"
   echo "  '<!GType>'            Specifies a GObject type to NOT match"
   echo "  '0x76543210'          Address of an object to match"
   echo "  '!0xFEDCBA98'         Address of an object to NOT match"
   echo "  'D:<Flags>'           Events that cause event to be displayed"
   echo "  'B:<Flags>'           Events that cause a break point to be executed"
   echo "  'L:<Flags>'           Events that are logged to event log"
   echo
   echo "<Flags> consists of a pipe '|' separated list of:"
   echo "--- Event flags ---"
   echo "  PreNew                A pre new object event (pre object creation)"
   echo "  New                   New object event (after object created)"
   echo "  Ref                   Object reference event"
   echo "  Unref                 Object un-reference event"
   echo "  PreFinalize           Object pre finalize event"
   echo "  Finalize              Object finalize event"
   echo "--- Error flags ---"
   echo "  EUnknownObj           Address is not known (never was created)"
   echo "  EDestroyedObj         Address points to a destroyed object"
   echo "  ENotObj               Address points to a non GObject"
   echo "  EInitCount            Initial object reference count not 1"
   echo "  EBadCount             Unexpected reference count during ref/unref"
   echo "--- Special flags ---"
   echo "  Paranoid              Process EUnknownObj errors immediately (D:/B:)"
   echo "  Timer                 Enable refcount timer (D: only)"
   echo "--- Group flags ---"
   echo "  All                   All flags from above (Event and Error flags)"
   echo "  None                  No flags"
   echo "  Event                 All Event flags from above"
   echo "  Error                 All Error flags from above"
   echo
   echo "Rule examples:"
   echo "addrule <GtkObject> <!GtkAdjustment> D:Error B:None L:All"
   echo "  Add a rule to match GtkObject derived types except GtkAdjustment"
   echo "  and display errors, no break points are set and log all events."
   echo "r0=<GtkWindow> D:All B:All L:All"
   echo "  Set the default rule to match only GtkWindow derived types and"
   echo "  display, break and log all events."
   echo "addrule 0x12345678 D:Ref|Unref|Error B:Ref|Unref|Error L:All"
   echo "  Add a rule to match a specific object instance and display and set"
   echo "  break points for Ref, Unref and Error events and log all events."
   echo
   fi

   echo "Separate commands with semi-colons and surround in double quotes \"\""
   echo "Example: refdbg -c \"btnum=8;timer=500\" myprog --myprog-arg=blah"
   echo
   echo "NOTE: Run with -h or --help switch for detailed help"
   exit 1
}

if [ $# -lt 1 ]; then
    usage
fi

for (( ndx=1; ndx <= $#; ndx++ )) ; do
    arg=${@:ndx:1}

    if [ ${arg:0:1} != "-" ]; then  # Break on first non option (program name)
	break
    fi

    case "$arg" in
	-c)
	    ndx=$((ndx+1))
	    arg=${@:ndx:1}

	    if [ "x$arg" == "x" ]; then
		echo "Expected refdbg commands following -c switch"
		exit 1
	    fi

	    if [ "x${REFDBG_OPTIONS}" != "x" ]; then
		REFDBG_OPTIONS="${REFDBG_OPTIONS} $arg"
	    else
		REFDBG_OPTIONS="$arg"
	    fi
	    ;;
	-h | --help)
	    usage 1
	    ;;
	*)
	    echo "Invalid option '$arg'"
	    usage
	    ;;
    esac
done

if [ $ndx -gt $# ] ; then
    echo "Program to run is a required parameter"
    exit 1
fi

if [ "x${REFDBG_OPTIONS}" == "x" ] ; then
    LD_PRELOAD=/usr/lib64/librefdbg.so "${@:ndx}"
else
    REFDBG_OPTIONS="${REFDBG_OPTIONS}" LD_PRELOAD=/usr/lib64/librefdbg.so \
	"${@:ndx}"
fi
