# -*- shell-script -*-
# debugger source-code listing routines
#
# Copyright (C) 2002-2004, 2006, 2008-2011, 2014
# Rocky Bernstein <rocky@gnu.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, 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; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place, Suite 330, Boston,
# MA 02111 USA.
# List search commands/routines
# Last search pattern used.
typeset _Dbg_last_search_pat
# The current line to be listed. A 0 value indicates we should set
# from _Dbg_frame_last_lineno
typeset -i _Dbg_listline=0
typeset _Dbg_source_line
# Print source line in standard format for line $1 of filename $2. If
# $2 is omitted, use _Dbg_frame_last_filename, if $1 is omitted use
# _Dbg_frame_last_lineno.
function _Dbg_print_location_and_command {
typeset line_number=${1:-$_Dbg_frame_last_lineno}
typeset filename=${2:-$_Dbg_frame_last_filename}
_Dbg_get_source_line $line_number "$filename"
filename=$(_Dbg_adjust_filename "$filename")
_Dbg_msg "(${filename}:${line_number}):
${line_number}:\t${_Dbg_source_line}"
# If we are at the same place in the file but the command has changed,
# then we have multiple commands on the line. So print which one we are
# currently at.
if [[ $_Dbg_set_show_command == "on" ]] ; then
_Dbg_msg "$_Dbg_bash_command"
elif [[ $_Dbg_last_lineno == $_Dbg_frame_last_lineno ]] \
&& [[ $_Dbg_last_source_file == $_Dbg_frame_last_filename ]] \
&& [[ $_Dbg_last_bash_command != $_Dbg_bash_command \
&& $_Dbg_set_show_command == "auto" ]] ; then
_Dbg_msg "$_Dbg_bash_command"
fi
}
# Print Linetrace output. We also handle output if linetrace expand
# is in effect.
_Dbg_print_linetrace() {
typeset line_number=${1:-$_Dbg_frame_last_lineno}
typeset filename=${2:-"$_Dbg_frame_last_filename"}
# Remove main + sig-handler + print_lintrace FUNCNAMES.
typeset -i depth=${#FUNCNAME[@]}-3
# If called from bashdb script rather than via "bash --debugger",
# we are artificially nested one deeper because of the bashdb call.
if [[ -n $_Dbg_script ]] ; then
((depth--))
fi
(( depth < 0 )) && return
_Dbg_get_source_line $line_number "$filename"
filename=$(_Dbg_adjust_filename "$filename")
_Dbg_msg "(${filename}:${line_number}):
level $_Dbg_DEBUGGER_LEVEL, subshell $BASH_SUBSHELL, depth $depth:\t${_Dbg_source_line}"
# if (( _Dbg_linetrace_expand )) ; then
# # typeset expanded_source_line
# # # Replace all double quotes (") with and an escape (\")
# # typeset esc_source_line="${_Dbg_source_line//\"/\\\"}"
# _Dbg_do_eval "expanded_source_line=\"$esc_source_line\"" 2>/dev/null
# _Dbg_do_eval "expanded_source_line=\"$_Dbg_bash_command\"" 2>/dev/null
# _Dbg_msg "+ ${expanded_source_line}"
# fi
# If we are at the same place in the file but the command has changed,
# then we have multiple commands on the line. So print which one we are
# currently at.
if [[ $_Dbg_set_show_command == "on" ]] ; then
_Dbg_msg "$_Dbg_bash_command"
elif (( _Dbg_last_lineno == _Dbg_frame_last_lineno )) \
&& [[ $_Dbg_last_source_file == $_Dbg_frame_last_filename ]] \
&& [[ $_Dbg_last_bash_command != $_Dbg_bash_command \
&& $_Dbg_set_show_command == "auto" ]] ; then
_Dbg_msg "$_Dbg_bash_command"
fi
}
# Parse $1 $2, $3, and optional $4 setting $filename, $_Dbg_start_line and
# $end_line. $2 is the maximimum number of lines. If $3 or $4 are
# less than 0, they are interpreted as line numbers counting from the
# end. If $3 is '.' use _Dbg_frame_last_lineno. If $4 is given and is
# greater than $3 then use that as an ending line. If $4 is less than
# $3, then it is a line count. And if $4 omitted, use the line count
# $_Dbg_set_listsize. if $2 is omitted, use global variable
# $_Dbg_frame_last_lineno.
_Dbg_parse_list_args() {
typeset -i max_line
(($# < 3 || $# > 5)) && return 1
typeset -i center_line
center_line=$2
max_line=$2
filename="$3"
# Parse start line $3 yielding _Dbg_listline
if [[ $4 == '.' ]]; then
((_Dbg_listline=_Dbg_frame_last_lineno))
elif [[ $4 == '-' ]]; then
((_Dbg_listline=_Dbg_listline-2*_Dbg_set_listsize))
elif [[ -n $4 ]] ; then
if (($4 < 0)) ; then
((_Dbg_listline=$2+$4+1))
else
((_Dbg_listline=$4))
fi
elif (( 0 == _Dbg_listline )) ; then
_Dbg_listline=$_Dbg_frame_last_lineno
fi
(( _Dbg_listline==0 && _Dbg_listline++ ))
typeset -i count
((count=${5:-_Dbg_set_listsize}))
((count < 0)) && ((count=$2+$5+1))
if [[ -z $5 ]] || ((count < _Dbg_listline)) ; then
((center_line)) && ((_Dbg_listline-=count/2))
((_Dbg_listline<=0)) && ((_Dbg_listline=1))
((end_line=_Dbg_listline+count-1))
else
((end_line=count))
fi
return 0
}
# list lines starting. See _Dbg_parse_list_args for how $2, $3, and $4
# are interpreted. Note though that they are called as $1, $2, $3 there.
_Dbg_list() {
(($# < 3 || $# > 5)) && return 1
typeset filename
filename=$2
typeset end_line
_Dbg_readin_if_new "$filename"
typeset -i max_line
max_line=$(_Dbg_get_maxline "$filename")
if (( $? != 0 )) ; then
_Dbg_errmsg "internal error getting number of lines in $filename"
return 1
fi
_Dbg_parse_list_args "$max_line" "$@"
if (( _Dbg_listline > max_line )) ; then
_Dbg_errmsg \
"Line number $_Dbg_listline out of range;" \
"$filename has $max_line lines."
return 1
fi
(( end_line > max_line )) && ((end_line=max_line))
typeset frame_fullfile
frame_fullfile=${_Dbg_file2canonic[$_Dbg_frame_last_filename]}
for (( ; _Dbg_listline <= end_line ; _Dbg_listline++ )) ; do
typeset prefix=' '
_Dbg_get_source_line $_Dbg_listline "$filename"
(( _Dbg_listline == _Dbg_frame_last_lineno )) \
&& [[ $fullname == $frame_fullfile ]] && prefix=' => '
_Dbg_printf "%3d:%s%s" $_Dbg_listline "$prefix" "$_Dbg_source_line"
done
return 0
}
_Dbg_list_columns() {
typeset colsep=' '
(($# > 0 )) && { colsep="$1"; shift; }
typeset -i linewidth
# 2 below is the initial prefix
if (($# > 0 )) ; then
((linewidth=$1-2));
shift
else
((linewidth=_Dbg_set_linewidth-2))
fi
(($# != 0)) && return 1
typeset -a columnized; columnize $linewidth "$colsep"
typeset -i i
for ((i=0; i<${#columnized[@]}; i++)) ; do
_Dbg_msg " ${columnized[i]}"
done
}