Imported from ../bash-4.0-rc1.tar.gz.

This commit is contained in:
Jari Aalto 2009-01-12 13:36:28 +00:00
commit 3185942a52
666 changed files with 188710 additions and 54674 deletions

View file

@ -1,12 +1,3 @@
This is a modified version of the Korn Shell debugger from Bill
Rosenblatt's `Learning the Korn Shell', published by O'Reilly
and Associates (ISBN 1-56592-054-6).
The original `kshdb' is available for anonymous FTP with the URL
http://examples.oreilly.com/korn/ksh.tar.Z
A revised edition is available at:
http://examples.oreilly.com/korn2/korn2_examples.tar.gz
This is a sample implementation of a bash debugger. It is not the same
as the project available from http://bashdb.sourceforge.net, and has been
deprecated in favor of that implementation.

596
examples/obashdb/bashdb Normal file → Executable file
View file

@ -1,33 +1,581 @@
# kshdb - Korn Shell Debugger main file
# adapted from 'Learning the Korn Shell' by Bill Rosenblatt (O'Reilly)
# by Cigy Cyriac (cigy@felix.tulblr.unisys.com)
# Main driver: constructs full script (with preamble) and runs it
#! /bin/bash
# bashdb - Bash shell debugger
#
# Adapted from an idea in O'Reilly's `Learning the Korn Shell'
# Copyright (C) 1993-1994 O'Reilly and Associates, Inc.
# Copyright (C) 1998, 1999, 2001 Gary V. Vaughan <gvv@techie.com>>
#
# 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.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
echo 'Bourne-Again Shell Debugger version 0.1'
# NOTE:
#
# This program requires bash 2.x.
# If bash 2.x is installed as "bash2", you can invoke bashdb like this:
#
# DEBUG_SHELL=/bin/bash2 /bin/bash2 bashdb script.sh
_pname=${0##*/}
# TODO:
#
# break [regexp]
# cond [break] [condition]
# tbreak [regexp|+lines]
# restart
# Variable watchpoints
# Instrument `source' and `.' files in $_potbelliedpig
# be cleverer about lines we allow breakpoints to be set on
# break [function_name]
[ $# -eq 0 ] && {
echo "${_pname}: usage: ${_pname} <script_file>"
exit 1
}
echo 'Bash Debugger version 1.2.4'
export _dbname=${0##*/}
if test $# -lt 1; then
echo "$_dbname: Usage: $_dbname filename" >&2
exit 1
fi
_guineapig=$1
[ -r $_guineapig ] || {
echo "${_pname}: cannot read $_guineapig." >&2
exit 1
}
if test ! -r $1; then
echo "$_dbname: Cannot read file '$_guineapig'." >&2
exit 1
fi
shift
_tmpdir=/tmp
_libdir=.
_dbgfile=$_tmpdir/bashdb$$ #temp file for script being debugged
__debug=${TMPDIR-/tmp}/bashdb.$$
sed -e '/^# bashdb - Bash shell debugger/,/^# -- DO NOT DELETE THIS LINE -- /d' "$0" > $__debug
cat $_guineapig >> $__debug
exec ${DEBUG_SHELL-bash} $__debug $_guineapig "$@"
cat $_libdir/bashdb.pre $_guineapig > $_dbgfile
if [ -f "$BASH" ]; then
exec $BASH $_dbgfile $_guineapig $_tmpdir $_libdir "$@"
else
exec bash $_dbgfile $_guineapig $_tmpdir $_libdir "$@"
fi
# end of bashdb
exit 1
# -- DO NOT DELETE THIS LINE -- The program depends on it
#bashdb preamble
# $1 name of the original guinea pig script
__debug=$0
_guineapig=$1
__steptrap_calls=0
shift
shopt -s extglob # turn on extglob so we can parse the debugger funcs
function _steptrap
{
local i=0
_curline=$1
if (( ++__steptrap_calls > 1 && $_curline == 1 )); then
return
fi
if [ -n "$_disps" ]; then
while (( $i < ${#_disps[@]} ))
do
if [ -n "${_disps[$i]}" ]; then
_msg "${_disps[$i]}: \c"
eval _msg ${_disps[$i]}
fi
let i=$i+1
done
fi
if (( $_trace )); then
_showline $_curline
fi
if (( $_steps >= 0 )); then
let _steps="$_steps - 1"
fi
if _at_linenumbp ; then
_msg "Reached breakpoint at line $_curline"
_showline $_curline
_cmdloop
elif [ -n "$_brcond" ] && eval $_brcond; then
_msg "Break condition $_brcond true at line $_curline"
_showline $_curline
_cmdloop
elif (( $_steps == 0 )); then
# Assuming a real script will have the "#! /bin/sh" at line 1,
# assume that when $_curline == 1 we are inside backticks.
if (( ! $_trace )); then
_msg "Stopped at line $_curline"
_showline $_curline
fi
_cmdloop
fi
}
function _setbp
{
local i f line _x
if [ -z "$1" ]; then
_listbp
return
fi
eval "$_seteglob"
if [[ $1 == *(\+)[1-9]*([0-9]) ]]; then
case $1 in
+*)
# normalize argument, then double it (+2 -> +2 + 2 = 4)
_x=${1##*([!1-9])} # cut off non-numeric prefix
_x=${x%%*([!0-9])} # cut off non-numeric suffix
f=$(( $1 + $_x ))
;;
*)
f=$(( $1 ))
;;
esac
# find the next valid line
line="${_lines[$f]}"
while _invalidbreakp $f
do
(( f++ ))
line="${_lines[$f]}"
done
if (( $f != $1 ))
then
_msg "Line $1 is not a valid breakpoint"
fi
if [ -n "${_lines[$f]}" ]; then
_linebp[$1]=$1;
_msg "Breakpoint set at line $f"
else
_msg "Breakpoints can only be set on executable lines"
fi
else
_msg "Please specify a numeric line number"
fi
eval "$_resteglob"
}
function _listbp
{
local i
if [ -n "$_linebp" ]; then
_msg "Breakpoints:"
for i in ${_linebp[*]}; do
_showline $i
done
else
_msg "No breakpoints have been set"
fi
}
function _clearbp
{
local i
if [ -z "$1" ]; then
read -e -p "Delete all breakpoints? "
case $REPLY in
[yY]*)
unset _linebp[*]
_msg "All breakpoints have been cleared"
;;
esac
return 0
fi
eval "$_seteglob"
if [[ $1 == [1-9]*([0-9]) ]]; then
unset _linebp[$1]
_msg "Breakpoint cleared at line $1"
else
_msg "Please specify a numeric line number"
fi
eval "$_resteglob"
}
function _setbc
{
if (( $# > 0 )); then
_brcond=$@
_msg "Break when true: $_brcond"
else
_brcond=
_msg "Break condition cleared"
fi
}
function _setdisp
{
if [ -z "$1" ]; then
_listdisp
else
_disps[${#_disps[@]}]="$1"
if (( ${#_disps[@]} < 10 ))
then
_msg " ${#_disps[@]}: $1"
else
_msg "${#_disps[@]}: $1"
fi
fi
}
function _listdisp
{
local i=0 j
if [ -n "$_disps" ]; then
while (( $i < ${#_disps[@]} ))
do
let j=$i+1
if (( ${#_disps[@]} < 10 ))
then
_msg " $j: ${_disps[$i]}"
else
_msg "$j: ${_disps[$i]}"
fi
let i=$j
done
else
_msg "No displays have been set"
fi
}
function _cleardisp
{
if (( $# < 1 )) ; then
read -e -p "Delete all display expressions? "
case $REPLY in
[Yy]*)
unset _disps[*]
_msg "All breakpoints have been cleared"
;;
esac
return 0
fi
eval "$_seteglob"
if [[ $1 == [1-9]*([0-9]) ]]; then
unset _disps[$1]
_msg "Display $i has been cleared"
else
_listdisp
_msg "Please specify a numeric display number"
fi
eval "$_resteglob"
}
# usage _ftrace -u funcname [funcname...]
function _ftrace
{
local _opt=-t _tmsg="enabled" _func
if [[ $1 == -u ]]; then
_opt=+t
_tmsg="disabled"
shift
fi
for _func; do
declare -f $_opt $_func
_msg "Tracing $_tmsg for function $_func"
done
}
function _cmdloop
{
local cmd args
while read -e -p "bashdb> " cmd args; do
test -n "$cmd" && history -s "$cmd $args" # save on history list
test -n "$cmd" || { set $_lastcmd; cmd=$1; shift; args=$*; }
if [ -n "$cmd" ]
then
case $cmd in
b|br|bre|brea|break)
_setbp $args
_lastcmd="break $args"
;;
co|con)
_msg "ambiguous command: '$cmd', condition, continue?"
;;
cond|condi|condit|conditi|conditio|condition)
_setbc $args
_lastcmd="condition $args"
;;
c|cont|conti|contin|continu|continue)
_lastcmd="continue"
return
;;
d)
_msg "ambiguous command: '$cmd', delete, display?"
;;
de|del|dele|delet|delete)
_clearbp $args
_lastcmd="delete $args"
;;
di|dis|disp|displ|displa|display)
_setdisp $args
_lastcmd="display $args"
;;
f|ft|ftr|ftra|ftrace)
_ftrace $args
_lastcmd="ftrace $args"
;;
\?|h|he|hel|help)
_menu
_lastcmd="help"
;;
l|li|lis|list)
_displayscript $args
# _lastcmd is set in the _displayscript function
;;
p|pr|pri|prin|print)
_examine $args
_lastcmd="print $args"
;;
q|qu|qui|quit)
exit
;;
s|st|ste|step|n|ne|nex|next)
let _steps=${args:-1}
_lastcmd="next $args"
return
;;
t|tr|tra|trac|trace)
_xtrace
;;
u|un|und|undi|undis|undisp|undispl|undispla|undisplay)
_cleardisp $args
_lastcmd="undisplay $args"
;;
!*)
eval ${cmd#!} $args
_lastcmd="$cmd $args"
;;
*)
_msg "Invalid command: '$cmd'"
;;
esac
fi
done
}
function _at_linenumbp
{
[[ -n ${_linebp[$_curline]} ]]
}
function _invalidbreakp
{
local line=${_lines[$1]}
# XXX - should use shell patterns
if test -z "$line" \
|| expr "$line" : '[ \t]*#.*' > /dev/null \
|| expr "$line" : '[ \t]*;;[ \t]*$' > /dev/null \
|| expr "$line" : '[ \t]*[^)]*)[ \t]*$' > /dev/null \
|| expr "$line" : '[ \t]*;;[ \t]*#.**$' > /dev/null \
|| expr "$line" : '[ \t]*[^)]*)[ \t]*;;[ \t]*$' > /dev/null \
|| expr "$line" : '[ \t]*[^)]*)[ \t]*;;*[ \t]*#.*$' > /dev/null
then
return 0
fi
return 1
}
function _examine
{
if [ -n "$*" ]; then
_msg "$args: \c"
eval _msg $args
else
_msg "Nothing to print"
fi
}
function _displayscript
{
local i j start end bp cl
if (( $# == 1 )); then # list 5 lines on either side of $1
if [ $1 = "%" ]; then
let start=1
let end=${#_lines[@]}
else
let start=$1-5
let end=$1+5
fi
elif (( $# > 1 )); then # list between start and end
if [ $1 = "^" ]; then
let start=1
else
let start=$1
fi
if [ $2 = "\$" ]; then
let end=${#_lines[@]}
else
let end=$2
fi
else # list 5 lines on either side of current line
let start=$_curline-5
let end=$_curline+5
fi
# normalize start and end
if (( $start < 1 )); then
start=1
fi
if (( $end > ${#_lines[@]} )); then
end=${#_lines[@]}
fi
cl=$(( $end - $start ))
if (( $cl > ${LINES-24} )); then
pager=${PAGER-more}
else
pager=cat
fi
i=$start
( while (( $i <= $end )); do
_showline $i
let i=$i+1
done ) 2>&1 | $pager
# calculate the next block of lines
start=$(( $end + 1 ))
end=$(( $start + 11 ))
if (( $end > ${#_lines[@]} ))
then
end=${#_lines[@]}
fi
_lastcmd="list $start $end"
}
function _xtrace
{
let _trace="! $_trace"
if (( $_trace )); then
_msg "Execution trace on"
else
_msg "Execution trace off"
fi
}
function _msg
{
echo -e "$@" >&2
}
function _showline
{
local i=0 bp=' ' line=$1 cl=' '
if [[ -n ${_linebp[$line]} ]]; then
bp='*'
fi
if (( $_curline == $line )); then
cl=">"
fi
if (( $line < 100 )); then
_msg "${_guineapig/*\//}:$line $bp $cl${_lines[$line]}"
elif (( $line < 10 )); then
_msg "${_guineapig/*\//}:$line $bp $cl${_lines[$line]}"
elif (( $line > 0 )); then
_msg "${_guineapig/*\//}:$line $bp $cl${_lines[$line]}"
fi
}
function _cleanup
{
rm -f $__debug $_potbelliedpig 2> /dev/null
}
function _menu
{
_msg 'bashdb commands:
break N set breakpoint at line N
break list breakpoints & break condition
condition foo set break condition to foo
condition clear break condition
delete N clear breakpoint at line N
delete clear all breakpoints
display EXP evaluate and display EXP for each debug step
display show a list of display expressions
undisplay N remove display expression N
list N M display all lines of script between N and M
list N display 5 lines of script either side of line N
list display 5 lines if script either side of current line
continue continue execution upto next breakpoint
next [N] execute [N] statements (default 1)
print expr prints the value of an expression
trace toggle execution trace on/off
ftrace [-u] func make the debugger step into function FUNC
(-u turns off tracing FUNC)
help print this menu
! string passes string to a shell
quit quit'
}
shopt -u extglob
HISTFILE=~/.bashdb_history
set -o history
set +H
# strings to save and restore the setting of `extglob' in debugger functions
# that need it
_seteglob='local __eopt=-u ; shopt -q extglob && __eopt=-s ; shopt -s extglob'
_resteglob='shopt $__eopt extglob'
_linebp=()
let _trace=0
let _i=1
# Be careful about quoted newlines
_potbelliedpig=${TMPDIR-/tmp}/${_guineapig/*\//}.$$
sed 's,\\$,\\\\,' $_guineapig > $_potbelliedpig
_msg "Reading source from file: $_guineapig"
while read; do
_lines[$_i]=$REPLY
let _i=$_i+1
done < $_potbelliedpig
trap _cleanup EXIT
# Assuming a real script will have the "#! /bin/sh" at line 1,
# don't stop at line 1 on the first run
let _steps=1
LINENO=-1
trap '_steptrap $LINENO' DEBUG

177
examples/obashdb/bashdb.el Normal file
View file

@ -0,0 +1,177 @@
;;; bashdb.el --- Grand Unified Debugger mode for running bashdb
;; Copyright (C) 2000, 2001 Masatake YAMATO
;; Author: Masatake YAMATO <jet@gyve.org>
;; 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
;; Commentary:
;; This program may run on Emacs 21.0.91 and XEmacs 21.1.
;;
;; Put
;; (autoload 'bashdb "bashdb" "Run bashdb" t nil)
;; to your .emacs.
;; M-x bashdb
;; Run bashdb (like this): bashdb target.sh
;;
;; About bashdb:
;; You can get bashdb from
;; http://www.oranda.demon.co.uk/development.html
;;
;; bashdb.el is based on perldb in gud.el in XEmacs 21.1.
;; Revision:
;; $Revision: 1.6 $
;; $Log: bashdb.el,v $
;; Revision 1.6 2001/01/06 12:18:06 masata-y
;; Write note about XEmacs.
;;
;;
;;; Code:
(require 'gud)
;; User customizable variable
(defcustom gud-bashdb-command-name "bashdb"
"File name for executing Bashdb."
:type 'string
:group 'gud)
;; History of argument lists passed to bashdb.
(defvar gud-bashdb-history nil)
(defun gud-bashdb-massage-args (file args)
(if xemacsp
(cons (file-name-nondirectory file) args)
args))
;; There's no guarantee that Emacs will hand the filter the entire
;; marker at once; it could be broken up across several strings. We
;; might even receive a big chunk with several markers in it. If we
;; receive a chunk of text which looks like it might contain the
;; beginning of a marker, we save it here between calls to the
;; filter.
(if xemacsp
(defvar gud-bashdb-marker-acc ""))
(defun gud-bashdb-marker-acc ()
(if xemacsp
gud-bashdb-marker-acc
gud-marker-acc))
(defun gud-bashdb-marker-acc-quote ()
(if xemacsp
'gud-bashdb-marker-acc
'gud-marker-acc))
(defun gud-bashdb-marker-filter (string)
(save-match-data
(set (gud-bashdb-marker-acc-quote)
(concat (gud-bashdb-marker-acc) string))
(let ((output ""))
;; Process all the complete markers in this chunk.
(while (string-match "^\\([^:\n]+\\):\\([0-9]+\\)[ *]*>.*\n"
(gud-bashdb-marker-acc))
(setq
;; Extract the frame position from the marker.
gud-last-frame (cons
(substring (gud-bashdb-marker-acc)
(match-beginning 1)
(match-end 1))
(string-to-int
(substring (gud-bashdb-marker-acc)
(match-beginning 2)
(match-end 2))))
;; Append any text before the marker to the output we're going
;; to return - we don't include the marker in this text.
output (concat output
(substring (gud-bashdb-marker-acc) 0 (match-beginning 0))))
;; Set the accumulator to the remaining text.
(set
(gud-bashdb-marker-acc-quote) (substring
(gud-bashdb-marker-acc) (match-end 0))))
;; Does the remaining text look like it might end with the
;; beginning of another marker? If it does, then keep it in
;; (gud-bashdb-marker-acc) until we receive the rest of it. Since we
;; know the full marker regexp above failed, it's pretty simple to
;; test for marker starts.
(if (string-match "^\\([^:\n]+\\):\\([0-9]+\\)[ *]*>" (gud-bashdb-marker-acc))
(progn
;; Everything before the potential marker start can be output.
(setq output (concat output (substring (gud-bashdb-marker-acc)
0 (match-beginning 0))))
;; Everything after, we save, to combine with later input.
(set (gud-bashdb-marker-acc-quote)
(substring (gud-bashdb-marker-acc) (match-beginning 0))))
(setq output (concat output (gud-bashdb-marker-acc)))
(set (gud-bashdb-marker-acc-quote) ""))
output)))
(defun gud-bashdb-find-file (f)
(find-file-noselect f))
;;;###autoload
(defun bashdb (command-line)
"Run bashdb on program FILE in buffer *gud-FILE*.
The directory containing FILE becomes the initial working directory
and source-file directory for your debugger."
(interactive
(if xemacsp
(list (read-from-minibuffer "Run bashdb (like this): "
(if (consp gud-bashdb-history)
(car gud-bashdb-history)
(format "%s " gud-bashdb-command-name))
nil nil
'(gud-bashdb-history . 1)))
(list (gud-query-cmdline 'bashdb))
))
(if xemacsp
(progn
(gud-overload-functions '((gud-massage-args . gud-bashdb-massage-args)
(gud-marker-filter . gud-bashdb-marker-filter)
(gud-find-file . gud-bashdb-find-file)))
(gud-common-init command-line gud-bashdb-command-name))
(gud-common-init command-line 'gud-bashdb-massage-args
'gud-bashdb-marker-filter 'gud-bashdb-find-file)
(set (make-local-variable 'gud-minor-mode) 'bashdb))
;; Unsupported commands
;; condition foo set break condition to foo
;; condition clear break condition
;; display EXP evaluate and display EXP for each debug step
;; display show a list of display expressions
;; undisplay N remove display expression N
;; ! string passes string to a shell
;; quit quit
(gud-def gud-break "break %l" "\C-b" "Set breakpoint at current line.")
(gud-def gud-list-break "break" "b" "List breakpoints & break condition.")
(gud-def gud-remove "delete %l" "\C-d" "Remove breakpoint at current line")
(gud-def gud-remove-all "delete" "d" "Clear all breakpoints")
(gud-def gud-cont "continue" "\C-r" "Continue with display.")
(gud-def gud-next "next" "\C-n" "Step one line (skip functions).")
(gud-def gud-print "print %e" "\C-p" "Evaluate bash expression at point.")
(gud-def gud-help "help" "h" "Show all commands.")
(gud-def gud-trace "trace" "t" "Toggle execution trace on/off")
(setq comint-prompt-regexp "^bashdb> ")
(setq paragraph-start comint-prompt-regexp)
(run-hooks 'bashdb-mode-hook))
(provide 'bashdb)
;; bashdb.el ends here

View file

@ -1,237 +0,0 @@
# bashdb.fns - Bourne-Again Shell Debugger functions
_BUFSIZ=100
# Here after each statement in script being debugged.
# Handle single-step and breakpoints.
_steptrap() {
let _curline=$1-1 # no. of line that just ran
let "$_curline < 1" && let _curline=1
let "$_curline > $_firstline+$_BUFSIZ" && _readin $_curline
let " $_trace" &&
_msg "$PS4, line $_curline: ${_lines[$(($_curline-$_firstline+1))]}"
# if in step mode, decrement counter
let " $_steps >= 0" && let _steps="$_steps - 1"
# first check if line num or string brkpt. reached
if _at_linenumbp || _at_stringbp; then
_msg "Reached breakpoint at line $_curline"
_cmdloop # enter debugger
# if not, check whether break condition exists and is true
elif [ -n "$_brcond" ] && eval $_brcond; then
_msg "Break condition $_brcond true at line $_curline"
_cmdloop # enter debugger
# next, check if step mode and no. of steps is up
elif let "$_steps == 0"; then
_msg "Stopped at line $_curline"
_cmdloop # enter debugger
fi
}
# Debugger command loop.
# Here at start of debugger session, when brkpt. reached, or after single-step.
_cmdloop() {
local cmd args
# added support for default command (last one entered)
while read -e -p "bashdb> [$lastcmd $lastargs] " cmd args; do
if [ -z "$cmd" ]; then
cmd=$lastcmd
args=$lastargs
fi
lastcmd="$cmd"
lastargs=$args
# made commands to be debugger commands by default, no need for '*' prefix
case $cmd in
bp ) _setbp $args ;; #set brkpt at line num or string
bc ) _setbc $args ;; # set break condition
cb ) _clearbp ;; # clear all brkpts.
g ) return ;; # start/resume execution
s ) let _steps=${args:-1}
return ;; # single-step N times(default 1)
x ) _xtrace ;; # toggle execution trace
pr ) _print $args ;; # print lines in file
\? | h | help ) _menu ;; # print command menu
hi ) history ;; # show command history
q ) _cleanup; exit ;; # quit
\! ) eval $args ;; # run shell command
* ) _msg "Invalid command: $cmd" ; _menu ;;
esac
done
}
# see if next line no. is a brkpt.
_at_linenumbp() {
if [ -z "${_linebp}" ]; then
return 1
fi
echo "${_curline}" | grep -E "(${_linebp%\|})" >/dev/null 2>&1
return $?
}
# search string brkpts to see if next line in script matches.
_at_stringbp() {
local l;
if [ -z "$_stringbp" ]; then
return 1;
fi
l=${_lines[$_curline-$_firstline+1]}
echo "${l}" | grep -E "\\*(${_stringbp%\|})\\*" >/dev/null 2>&1
return $?
}
# print message to stderr
_msg() {
echo -e "$@" >&2
}
# set brkpt(s) at given line numbers and/or strings
# by appending lines to brkpt file
_setbp() {
declare -i n
case "$1" in
"") _listbp ;;
[0-9]*) #number, set brkpt at that line
n=$1
_linebp="${_linebp}$n|"
_msg "Breakpoint at line " $1
;;
*) #string, set brkpt at next line w/string
_stringbp="${_stringbp}$@|"
_msg "Breakpoint at next line containing $@."
;;
esac
}
# list brkpts and break condition.
_listbp() {
_msg "Breakpoints at lines:"
_msg "${_linebp//\|/ }"
_msg "Breakpoints at strings:"
_msg "${_stringbp//\|/ }"
_msg "Break on condition:"
_msg "$_brcond"
}
# set or clear break condition
_setbc() {
if [ -n "$@" ] ; then
_brcond=$args
_msg "Break when true: $_brcond"
else
_brcond=
_msg "Break condition cleared"
fi
}
# clear all brkpts
_clearbp() {
_linebp=
_stringbp=
_msg "All breakpoints cleared"
}
# toggle execution trace feature
_xtrace() {
let _trace="! $_trace"
_msg "Execution trace \c"
let " $_trace" && _msg "on." || _msg "off."
}
# print command menu
_menu() {
# made commands to be debugger commands by default, no need for '*' prefix
_msg 'bashdb commands:
bp N set breakpoint at line N
bp string set breakpoint at next line containing "string"
bp list breakpoints and break condition
bc string set break condition to "string"
bc clear break condition
cb clear all breakpoints
g start/resume execution
s [N] execute N statements (default 1)
x toggle execution trace on/off (default on)
pr [start|.] [cnt] print "cnt" lines from line no. "start"
?, h, help print this menu
hi show command history
q quit
! cmd [args] execute command "cmd" with "args"
default: last command (in "[ ]" at the prompt)
Readline command line editing (emacs/vi mode) is available'
}
# erase temp files before exiting
_cleanup() {
rm $_dbgfile 2>/dev/null
}
# read $_BUFSIZ lines from $_guineapig into _lines array, starting from line $1
# save number of first line read in _firstline
_readin() {
declare -i _i=1
let _firstline=$1
SEDCMD="$_firstline,$(($_firstline+$_BUFSIZ))p"
sed -n "$SEDCMD" $_guineapig > /tmp/_script.$$
while read -r _lines[$_i]; do
_i=_i+1
done < /tmp/_script.$$
rm -f /tmp/_script.$$ 2>/dev/null
}
_print() {
typeset _start _cnt
if [ -z "$1" ] || [ "$1" = . ]; then
_start=$_curline
else
_start=$1
fi
_cnt=${2:-9}
SEDCMD="$_start,$(($_start+$_cnt))p"
pr -tn $_guineapig | sed -n "$SEDCMD"
}

View file

@ -1,37 +0,0 @@
# bashdb.pre - Bourne-Again Shell Debugger preamble file
# prepended to script being ddebugged
#arguments:
# $1 = name of original guineapig script
# $2 = dir where temp files are stored
# $3 = dir where bashdb.pre and bashdb.fns are stored
# separate history file for bashdb
HISTFILE=~/.bashdb_history
set -o history
set +H
# prompt for trace line
PS4="${1}"
_dbgfile=$0
_guineapig=$1
_tmpdir=$2
_libdir=$3
shift 3 #move user's args into place
. $_libdir/bashdb.fns #read in the debugger functions
_linebp=
_stringbp=
let _trace=1 #init execution trace flag to on
#read guineapig file into _lines array
_readin 1
trap _cleanup EXIT #erase files before exiting
let _steps=1 #no. of statements to run after setting trap
#set LINENO, gets incremented to 1
LINENO=0
trap '_steptrap $LINENO' DEBUG
: