mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 23:53:18 +02:00
commit bash-20070712 snapshot
This commit is contained in:
@@ -14759,3 +14759,28 @@ lib/readline/display.c
|
||||
second line and the redisplay draws the invisible character. Fixes
|
||||
redisplay bug reported by Andreas Schwab <schwab@suse.de>
|
||||
|
||||
|
||||
7/11
|
||||
----
|
||||
|
||||
lib/readline/rltty.c
|
||||
- enable flush-output code for systems other than AIX 4.1. Problem
|
||||
reported by Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
7/12
|
||||
----
|
||||
lib/readline/display.c
|
||||
- set prompt_invis_chars_first_line from the portion of the prompt
|
||||
following the final newline, instead of from the prefix. Fixes
|
||||
bug reported on the Ubuntu bug list by dAniel hAhler
|
||||
<ubuntu@thequod.de>
|
||||
|
||||
7/13
|
||||
----
|
||||
variables.c
|
||||
- use native __QNX__ and __QNXNTO__ cpp defines instead of qnx and
|
||||
qnx6, respectively. Patch from Sean Boudreau <seanb@qnx.com>
|
||||
|
||||
lib/sh/getcwd.c
|
||||
- #undef HAVE_LSTAT on qnx, so it uses stat instead. Patch from
|
||||
Sean Boudreau <seanb@qnx.com>
|
||||
|
||||
+22
-1
@@ -14757,5 +14757,26 @@ lib/readline/display.c
|
||||
- change _rl_move_cursor_relative to adjust _rl_last_c_pos in a
|
||||
multibyte environment when the prompt has invisible chars on the
|
||||
second line and the redisplay draws the invisible character. Fixes
|
||||
bug reported by Andreas Schwab <schwab@suse.de>
|
||||
redisplay bug reported by Andreas Schwab <schwab@suse.de>
|
||||
|
||||
|
||||
7/11
|
||||
----
|
||||
|
||||
lib/readline/rltty.c
|
||||
- enable flush-output code for systems other than AIX 4.1. Problem
|
||||
reported by Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
7/12
|
||||
----
|
||||
lib/readline/display.c
|
||||
- set prompt_invis_chars_first_line from the portion of the prompt
|
||||
following the final newline, instead of from the prefix. Fixes
|
||||
bug reported on the Ubuntu bug list by dAniel hAhler
|
||||
<ubuntu@thequod.de>
|
||||
|
||||
7/13
|
||||
----
|
||||
variables.c
|
||||
- use native __QNX__ and __QNXNTO__ cpp defines instead of qnx and
|
||||
qnx6, respectively. Patch from Sean Boudreau <seanb@qnx.com>
|
||||
|
||||
@@ -10,7 +10,6 @@ builtins d
|
||||
cross-build d
|
||||
doc d
|
||||
examples d
|
||||
examples/bashdb d
|
||||
examples/obashdb d
|
||||
examples/complete d
|
||||
examples/functions d
|
||||
@@ -535,15 +534,10 @@ support/shobj-conf f 755
|
||||
support/rlvers.sh f 755
|
||||
examples/INDEX.txt f
|
||||
examples/INDEX.html f
|
||||
examples/bashdb/PERMISSION f
|
||||
examples/bashdb/README f
|
||||
examples/bashdb/bashdb f
|
||||
examples/bashdb/bashdb.el f
|
||||
examples/obashdb/PERMISSION f
|
||||
examples/obashdb/README f
|
||||
examples/obashdb/bashdb f
|
||||
examples/obashdb/bashdb.fns f
|
||||
examples/obashdb/bashdb.pre f
|
||||
examples/obashdb/bashdb f
|
||||
examples/obashdb/bashdb.el f
|
||||
examples/complete/complete-examples f
|
||||
examples/complete/complete.ianmac f
|
||||
examples/complete/complete2.ianmac f
|
||||
|
||||
+1
-7
@@ -5,7 +5,7 @@
|
||||
<th>X-Ref</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>./bashdb</td>
|
||||
<td>./obashdb</td>
|
||||
<td>Deprecated sample implementation of a bash debugger</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -436,12 +436,6 @@
|
||||
</tr>
|
||||
<tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>./obashdb</td>
|
||||
<td>Modified version of the Korn Shell debugger from Bill Rosenblatt's 'Learning the Korn Shell'.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>./scripts.noah</td>
|
||||
<td>Noah Friedman's collection of scripts (updated to bash v2 syntax by Chet Ramey)</td>
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
Path Description X-Ref
|
||||
./bashdb Deprecated sample implementation of a bash debugger
|
||||
./obashdb Deprecated sample implementation of a bash debugger
|
||||
|
||||
./complete Shell completion code
|
||||
|
||||
@@ -103,8 +103,6 @@ Path Description X-Ref
|
||||
./misc/README README
|
||||
./misc/suncmd.termcap SunView TERMCAP string.
|
||||
|
||||
./obashdb Modified version of the Korn Shell debugger from Bill Rosenblatt's 'Learning the Korn Shell'.
|
||||
|
||||
./scripts.noah Noah Friedman's collection of scripts (updated to bash v2 syntax by Chet Ramey)
|
||||
./scripts.noah/aref.bash Pseudo-arrays and substring indexing examples.
|
||||
./scripts.noah/bash.sub.bash Library functions used by require.bash.
|
||||
|
||||
+3
-12
@@ -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.
|
||||
|
||||
Regular → Executable
+572
-24
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,561 @@
|
||||
#! /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.
|
||||
|
||||
# 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
|
||||
|
||||
# TODO:
|
||||
#
|
||||
# break [regexp]
|
||||
# cond [break] [condition]
|
||||
# tbreak [regexp|+lines]
|
||||
# restart
|
||||
# Variable watchpoints
|
||||
# Output colourization
|
||||
# History with csh ^ substitution? Or write a readline frontend?
|
||||
# Instrument shell functions with the _steptrap in $_potbelliedpig
|
||||
# Instrument `source' and `.' files in $_potbelliedpig
|
||||
# be cleverer about lines we allow breakpoints to be set on
|
||||
# break [function_name]
|
||||
|
||||
|
||||
echo 'Bash Debugger version 1.2.4'
|
||||
|
||||
export _dbname=$(echo "X$0"|sed -e 's,^X,,' -e 's,^.*/,,')
|
||||
|
||||
if test $# -lt 1; then
|
||||
echo "$_dbname: Usage: $_dbname <filename>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_guineapig=$1
|
||||
|
||||
if test ! -r $1; then
|
||||
echo "$_dbname: Cannot read file '$_guineapig'." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shift
|
||||
|
||||
__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 "$@"
|
||||
|
||||
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
|
||||
|
||||
shift
|
||||
|
||||
function _steptrap
|
||||
{
|
||||
local i=0
|
||||
|
||||
_curline=$1
|
||||
|
||||
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 && $_curline > 1)); 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
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
_listbp
|
||||
elif [ $(echo $1 | grep '^\+*[1-9][0-9]*') ]
|
||||
then
|
||||
case $1 in
|
||||
+*)
|
||||
let f="$1 + `expr $1 : '+*\([1-9][0-9]*\)'`"
|
||||
;;
|
||||
*)
|
||||
let f=$1
|
||||
;;
|
||||
esac
|
||||
|
||||
# find the next valid line
|
||||
line="${_lines[$f]}"
|
||||
while _invalidbreakp $f
|
||||
do
|
||||
let f="$f + 1"
|
||||
line="${_lines[$f]}"
|
||||
done
|
||||
|
||||
if (( $f != $1 ))
|
||||
then
|
||||
_msg "Line $1 is not a valid breakpoint"
|
||||
fi
|
||||
|
||||
if [ -n "${_lines[$f]}" ]
|
||||
then
|
||||
_linebp=($(echo $( (for i in ${_linebp[*]} $1; do
|
||||
echo $i; done) | sort -n) ))
|
||||
_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
|
||||
}
|
||||
|
||||
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
|
||||
y*)
|
||||
unset _linebp[*]
|
||||
_msg "All breakpoints have been cleared"
|
||||
;;
|
||||
esac
|
||||
elif [ $(echo $1 | grep '^[0-9]*') ]; then
|
||||
_linebp=($(echo $(for i in ${_linebp[*]}; do
|
||||
if (( $1 != $i )); then echo $1; fi; done) ))
|
||||
_msg "Breakpoint cleared at line $1"
|
||||
else
|
||||
_msg "Please specify a numeric line number"
|
||||
fi
|
||||
}
|
||||
|
||||
function _setbc
|
||||
{
|
||||
if [ -n "$*" ]
|
||||
then
|
||||
_brcond=$args
|
||||
_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
|
||||
y*)
|
||||
unset _disps[*]
|
||||
_msg "All breakpoints have been cleared"
|
||||
;;
|
||||
esac
|
||||
elif [ $(echo $1 | grep '^[0-9]*') ]
|
||||
then
|
||||
unset _disps[$1]
|
||||
_msg "Display $i has been cleared"
|
||||
else
|
||||
_listdisp
|
||||
_msg "Please specify a numeric display number"
|
||||
fi
|
||||
}
|
||||
|
||||
function _cmdloop
|
||||
{
|
||||
local cmd args
|
||||
|
||||
while read -e -p "bashdb> " cmd args; do
|
||||
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"
|
||||
;;
|
||||
\?|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
|
||||
{
|
||||
local i=0
|
||||
|
||||
if [ "$_linebp" ]
|
||||
then
|
||||
while (( $i < ${#_linebp[@]} )); do
|
||||
if (( ${_linebp[$i]} == $_curline )); then
|
||||
return 0
|
||||
fi
|
||||
let i=$i+1
|
||||
done
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function _invalidbreakp
|
||||
{
|
||||
local line=${_lines[$1]}
|
||||
|
||||
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
|
||||
if test $1 = "%"
|
||||
then
|
||||
let start=1
|
||||
let end=${#_lines[@]}
|
||||
else
|
||||
let start=$1-5
|
||||
let end=$1+5
|
||||
fi
|
||||
elif (( $# > 1 ))
|
||||
then
|
||||
if test $1 = "^"
|
||||
then
|
||||
let start=1
|
||||
else
|
||||
let start=$1
|
||||
fi
|
||||
|
||||
if test $2 = "\$"
|
||||
then
|
||||
let end=${#_lines[@]}
|
||||
else
|
||||
let end=$2
|
||||
fi
|
||||
else
|
||||
let start=$_curline-5
|
||||
let end=$_curline+5
|
||||
fi
|
||||
|
||||
if (( $start < 1 ))
|
||||
then
|
||||
start=1
|
||||
fi
|
||||
if (( $end > ${#_lines[@]} ))
|
||||
then
|
||||
end=${#_lines[@]}
|
||||
fi
|
||||
|
||||
let 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
|
||||
let start=$end+1
|
||||
let 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
|
||||
|
||||
while (( $i < ${#_linebp[@]} ))
|
||||
do
|
||||
if [ ${_linebp[$i]} ] && (( ${_linebp[$i]} == $line ))
|
||||
then
|
||||
bp='*'
|
||||
fi
|
||||
let i=$i+1
|
||||
done
|
||||
|
||||
if (( $_curline == $line )); then
|
||||
cl=">"
|
||||
else
|
||||
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
|
||||
help print this menu
|
||||
! string passes string to a shell
|
||||
quit quit'
|
||||
}
|
||||
|
||||
|
||||
_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=2
|
||||
LINENO=-2
|
||||
trap '_steptrap $LINENO' DEBUG
|
||||
:
|
||||
@@ -419,14 +419,14 @@ rl_expand_prompt (prompt)
|
||||
t = ++p;
|
||||
local_prompt = expand_prompt (p, &prompt_visible_length,
|
||||
&prompt_last_invisible,
|
||||
(int *)NULL,
|
||||
&prompt_invis_chars_first_line,
|
||||
&prompt_physical_chars);
|
||||
c = *t; *t = '\0';
|
||||
/* The portion of the prompt string up to and including the
|
||||
final newline is now null-terminated. */
|
||||
local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
|
||||
(int *)NULL,
|
||||
&prompt_invis_chars_first_line,
|
||||
(int *)NULL,
|
||||
(int *)NULL);
|
||||
*t = c;
|
||||
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
|
||||
|
||||
@@ -419,14 +419,14 @@ rl_expand_prompt (prompt)
|
||||
t = ++p;
|
||||
local_prompt = expand_prompt (p, &prompt_visible_length,
|
||||
&prompt_last_invisible,
|
||||
(int *)NULL,
|
||||
&prompt_invis_chars_first_line,
|
||||
&prompt_physical_chars);
|
||||
c = *t; *t = '\0';
|
||||
/* The portion of the prompt string up to and including the
|
||||
final newline is now null-terminated. */
|
||||
local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
|
||||
(int *)NULL,
|
||||
&prompt_invis_chars_first_line,
|
||||
(int *)NULL,
|
||||
(int *)NULL);
|
||||
*t = c;
|
||||
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
|
||||
@@ -938,7 +938,7 @@ rl_redisplay ()
|
||||
second and subsequent lines start at inv_lbreaks[N], offset by
|
||||
OFFSET (which has already been calculated above). */
|
||||
|
||||
#define WRAP_OFFSET(line, offset) ((line == 0) \
|
||||
#define WRAP_OFFSET<(line, offset) ((line == 0) \
|
||||
? (offset ? prompt_invis_chars_first_line : 0) \
|
||||
: ((line == prompt_last_screen_line) ? wrap_offset-prompt_invis_chars_first_line : 0))
|
||||
#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
|
||||
@@ -1009,7 +1009,8 @@ rl_redisplay ()
|
||||
out (e.g., when printing the i-search prompt). In general,
|
||||
the case of the new line being shorter than the old.
|
||||
Incomplete */
|
||||
else if (linenum == 1 && prompt_physical_chars > _rl_screenwidth &&
|
||||
else if (linenum == prompt_last_screen_line &&
|
||||
prompt_physical_chars > _rl_screenwidth &&
|
||||
wrap_offset != prompt_invis_chars_first_line &&
|
||||
_rl_last_c_pos == out &&
|
||||
#endif
|
||||
@@ -1842,7 +1843,8 @@ _rl_move_cursor_relative (new, data)
|
||||
prompt string, since they're both buffer indices and DPOS is a
|
||||
desired display position. */
|
||||
if ((new > prompt_last_invisible) || /* XXX - don't use woff here */
|
||||
(prompt_physical_chars > _rl_screenwidth && _rl_last_v_pos == 1 &&
|
||||
(prompt_physical_chars > _rl_screenwidth &&
|
||||
_rl_last_v_pos == prompt_last_screen_line &&
|
||||
wrap_offset != woff &&
|
||||
new > (prompt_last_invisible-_rl_screenwidth-wrap_offset)))
|
||||
{
|
||||
|
||||
@@ -500,7 +500,7 @@ _get_tty_settings (tty, tiop)
|
||||
}
|
||||
if (OUTPUT_BEING_FLUSHED (tiop))
|
||||
{
|
||||
#if defined (FLUSHO) && defined (_AIX41)
|
||||
#if defined (FLUSHO)
|
||||
_rl_errmsg ("warning: turning off output flushing");
|
||||
tiop->c_lflag &= ~FLUSHO;
|
||||
break;
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#pragma alloca
|
||||
#endif /* _AIX && RISC6000 && !__GNUC__ */
|
||||
|
||||
#if defined (__QNX__)
|
||||
# undef HAVE_LSTAT
|
||||
#endif
|
||||
|
||||
#include <bashtypes.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
/* getcwd.c -- stolen from the GNU C library and modified to work with bash. */
|
||||
|
||||
/* Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if !defined (HAVE_GETCWD)
|
||||
|
||||
#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
|
||||
#pragma alloca
|
||||
#endif /* _AIX && RISC6000 && !__GNUC__ */
|
||||
|
||||
#include <bashtypes.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined (HAVE_LIMITS_H)
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <posixdir.h>
|
||||
#include <posixstat.h>
|
||||
#include <maxpath.h>
|
||||
#include <memalloc.h>
|
||||
|
||||
#include <bashansi.h>
|
||||
|
||||
#include <xmalloc.h>
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
#if !defined (HAVE_LSTAT)
|
||||
# define lstat stat
|
||||
#endif
|
||||
|
||||
#if !defined (NULL)
|
||||
# define NULL 0
|
||||
#endif
|
||||
|
||||
/* Get the pathname of the current working directory,
|
||||
and put it in SIZE bytes of BUF. Returns NULL if the
|
||||
directory couldn't be determined or SIZE was too small.
|
||||
If successful, returns BUF. In GNU, if BUF is NULL,
|
||||
an array is allocated with `malloc'; the array is SIZE
|
||||
bytes long, unless SIZE <= 0, in which case it is as
|
||||
big as necessary. */
|
||||
#if defined (__STDC__)
|
||||
char *
|
||||
getcwd (char *buf, size_t size)
|
||||
#else /* !__STDC__ */
|
||||
char *
|
||||
getcwd (buf, size)
|
||||
char *buf;
|
||||
size_t size;
|
||||
#endif /* !__STDC__ */
|
||||
{
|
||||
static const char dots[]
|
||||
= "../../../../../../../../../../../../../../../../../../../../../../../\
|
||||
../../../../../../../../../../../../../../../../../../../../../../../../../../\
|
||||
../../../../../../../../../../../../../../../../../../../../../../../../../..";
|
||||
const char *dotp, *dotlist;
|
||||
size_t dotsize;
|
||||
dev_t rootdev, thisdev;
|
||||
ino_t rootino, thisino;
|
||||
char path[PATH_MAX + 1];
|
||||
register char *pathp;
|
||||
char *pathbuf;
|
||||
size_t pathsize;
|
||||
struct stat st;
|
||||
int saved_errno;
|
||||
|
||||
if (buf != NULL && size == 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
pathsize = sizeof (path);
|
||||
pathp = &path[pathsize];
|
||||
*--pathp = '\0';
|
||||
pathbuf = path;
|
||||
|
||||
if (stat (".", &st) < 0)
|
||||
return ((char *)NULL);
|
||||
thisdev = st.st_dev;
|
||||
thisino = st.st_ino;
|
||||
|
||||
if (stat ("/", &st) < 0)
|
||||
return ((char *)NULL);
|
||||
rootdev = st.st_dev;
|
||||
rootino = st.st_ino;
|
||||
|
||||
saved_errno = 0;
|
||||
|
||||
dotsize = sizeof (dots) - 1;
|
||||
dotp = &dots[sizeof (dots)];
|
||||
dotlist = dots;
|
||||
while (!(thisdev == rootdev && thisino == rootino))
|
||||
{
|
||||
register DIR *dirstream;
|
||||
register struct dirent *d;
|
||||
dev_t dotdev;
|
||||
ino_t dotino;
|
||||
char mount_point;
|
||||
int namlen;
|
||||
|
||||
/* Look at the parent directory. */
|
||||
if (dotp == dotlist)
|
||||
{
|
||||
/* My, what a deep directory tree you have, Grandma. */
|
||||
char *new;
|
||||
if (dotlist == dots)
|
||||
{
|
||||
new = (char *)malloc (dotsize * 2 + 1);
|
||||
if (new == NULL)
|
||||
goto lose;
|
||||
memcpy (new, dots, dotsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
new = (char *)realloc ((PTR_T) dotlist, dotsize * 2 + 1);
|
||||
if (new == NULL)
|
||||
goto lose;
|
||||
}
|
||||
memcpy (&new[dotsize], new, dotsize);
|
||||
dotp = &new[dotsize];
|
||||
dotsize *= 2;
|
||||
new[dotsize] = '\0';
|
||||
dotlist = new;
|
||||
}
|
||||
|
||||
dotp -= 3;
|
||||
|
||||
/* Figure out if this directory is a mount point. */
|
||||
if (stat (dotp, &st) < 0)
|
||||
goto lose;
|
||||
dotdev = st.st_dev;
|
||||
dotino = st.st_ino;
|
||||
mount_point = dotdev != thisdev;
|
||||
|
||||
/* Search for the last directory. */
|
||||
dirstream = opendir (dotp);
|
||||
if (dirstream == NULL)
|
||||
goto lose;
|
||||
while ((d = readdir (dirstream)) != NULL)
|
||||
{
|
||||
if (d->d_name[0] == '.' &&
|
||||
(d->d_name[1] == '\0' ||
|
||||
(d->d_name[1] == '.' && d->d_name[2] == '\0')))
|
||||
continue;
|
||||
if (mount_point || d->d_fileno == thisino)
|
||||
{
|
||||
char *name;
|
||||
|
||||
namlen = D_NAMLEN(d);
|
||||
name = (char *)
|
||||
alloca (dotlist + dotsize - dotp + 1 + namlen + 1);
|
||||
memcpy (name, dotp, dotlist + dotsize - dotp);
|
||||
name[dotlist + dotsize - dotp] = '/';
|
||||
memcpy (&name[dotlist + dotsize - dotp + 1],
|
||||
d->d_name, namlen + 1);
|
||||
if (lstat (name, &st) < 0)
|
||||
{
|
||||
#if 0
|
||||
int save = errno;
|
||||
(void) closedir (dirstream);
|
||||
errno = save;
|
||||
goto lose;
|
||||
#else
|
||||
saved_errno = errno;
|
||||
#endif
|
||||
}
|
||||
if (st.st_dev == thisdev && st.st_ino == thisino)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d == NULL)
|
||||
{
|
||||
#if 0
|
||||
int save = errno;
|
||||
#else
|
||||
int save = errno ? errno : saved_errno;
|
||||
#endif
|
||||
(void) closedir (dirstream);
|
||||
errno = save;
|
||||
goto lose;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t space;
|
||||
|
||||
while ((space = pathp - pathbuf) <= namlen)
|
||||
{
|
||||
char *new;
|
||||
|
||||
if (pathbuf == path)
|
||||
{
|
||||
new = (char *)malloc (pathsize * 2);
|
||||
if (!new)
|
||||
goto lose;
|
||||
}
|
||||
else
|
||||
{
|
||||
new = (char *)realloc ((PTR_T) pathbuf, (pathsize * 2));
|
||||
if (!new)
|
||||
goto lose;
|
||||
pathp = new + space;
|
||||
}
|
||||
(void) memcpy (new + pathsize + space, pathp, pathsize - space);
|
||||
pathp = new + pathsize + space;
|
||||
pathbuf = new;
|
||||
pathsize *= 2;
|
||||
}
|
||||
|
||||
pathp -= namlen;
|
||||
(void) memcpy (pathp, d->d_name, namlen);
|
||||
*--pathp = '/';
|
||||
(void) closedir (dirstream);
|
||||
}
|
||||
|
||||
thisdev = dotdev;
|
||||
thisino = dotino;
|
||||
}
|
||||
|
||||
if (pathp == &path[sizeof(path) - 1])
|
||||
*--pathp = '/';
|
||||
|
||||
if (dotlist != dots)
|
||||
free ((PTR_T) dotlist);
|
||||
|
||||
{
|
||||
size_t len = pathbuf + pathsize - pathp;
|
||||
if (buf == NULL)
|
||||
{
|
||||
if (len < (size_t) size)
|
||||
len = size;
|
||||
buf = (char *) malloc (len);
|
||||
if (buf == NULL)
|
||||
goto lose2;
|
||||
}
|
||||
else if ((size_t) size < len)
|
||||
{
|
||||
errno = ERANGE;
|
||||
goto lose2;
|
||||
}
|
||||
(void) memcpy((PTR_T) buf, (PTR_T) pathp, len);
|
||||
}
|
||||
|
||||
if (pathbuf != path)
|
||||
free (pathbuf);
|
||||
|
||||
return (buf);
|
||||
|
||||
lose:
|
||||
if ((dotlist != dots) && dotlist)
|
||||
{
|
||||
int e = errno;
|
||||
free ((PTR_T) dotlist);
|
||||
errno = e;
|
||||
}
|
||||
|
||||
lose2:
|
||||
if ((pathbuf != path) && pathbuf)
|
||||
{
|
||||
int e = errno;
|
||||
free ((PTR_T) pathbuf);
|
||||
errno = e;
|
||||
}
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
#if defined (TEST)
|
||||
# include <stdio.h>
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char b[PATH_MAX];
|
||||
|
||||
if (getcwd(b, sizeof(b)))
|
||||
{
|
||||
printf ("%s\n", b);
|
||||
exit (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
perror ("cwd: getcwd");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
#endif /* TEST */
|
||||
#endif /* !HAVE_GETCWD */
|
||||
+6
-6
@@ -24,13 +24,13 @@
|
||||
#include "posixstat.h"
|
||||
#include "posixtime.h"
|
||||
|
||||
#if defined (qnx)
|
||||
# if defined (qnx6)
|
||||
#if defined (__QNX__)
|
||||
# if defined (__QNXNTO__)
|
||||
# include <sys/netmgr.h>
|
||||
# else
|
||||
# include <sys/vc.h>
|
||||
# endif /* !qnx6 */
|
||||
#endif /* qnx */
|
||||
# endif /* !__QNXNTO__ */
|
||||
#endif /* __QNX__ */
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
@@ -391,11 +391,11 @@ initialize_shell_variables (env, privmode)
|
||||
set_auto_export (temp_var); /* XXX */
|
||||
#endif
|
||||
|
||||
#if defined (qnx)
|
||||
#if defined (__QNX__)
|
||||
/* set node id -- don't import it from the environment */
|
||||
{
|
||||
char node_name[22];
|
||||
# if defined (qnx6)
|
||||
# if defined (__QNXNTO__)
|
||||
netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name));
|
||||
# else
|
||||
qnx_nidtostr (getnid (), node_name, sizeof (node_name));
|
||||
|
||||
@@ -1604,7 +1604,11 @@ FUNCTION_DEF *
|
||||
find_function_def (name)
|
||||
const char *name;
|
||||
{
|
||||
#if defined (DEBUGGER)
|
||||
return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
|
||||
#else
|
||||
return ((FUNCTION_DEF *)0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the value of VAR. VAR is assumed to have been the result of a
|
||||
@@ -2147,6 +2151,7 @@ bind_function (name, value)
|
||||
return (entry);
|
||||
}
|
||||
|
||||
#if defined (DEBUGGER)
|
||||
/* Bind a function definition, which includes source file and line number
|
||||
information in addition to the command, into the FUNCTION_DEF hash table.*/
|
||||
void
|
||||
@@ -2175,6 +2180,7 @@ bind_function_def (name, value)
|
||||
elt->data = (PTR_T *)entry;
|
||||
}
|
||||
}
|
||||
#endif /* DEBUGGER */
|
||||
|
||||
/* Add STRING, which is of the form foo=bar, to the temporary environment
|
||||
HASH_TABLE (temporary_env). The functions in execute_cmd.c are
|
||||
@@ -2367,6 +2373,7 @@ unbind_func (name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined (DEBUGGER)
|
||||
int
|
||||
unbind_function_def (name)
|
||||
const char *name;
|
||||
@@ -2388,6 +2395,7 @@ unbind_function_def (name)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* DEBUGGER */
|
||||
|
||||
/* Make the variable associated with NAME go away. HASH_LIST is the
|
||||
hash table from which this variable should be deleted (either
|
||||
|
||||
Reference in New Issue
Block a user