# -*- shell-script -*- # debugger source-code listing routines # # Copyright (C) 2002-2004, 2006, 2008-2011, 2014 # Rocky Bernstein # # 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. proc _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 setglobal 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" ]] { _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" ]] { _Dbg_msg $_Dbg_bash_command } } # Print Linetrace output. We also handle output if linetrace expand # is in effect. proc _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 ]] { sh-expr 'depth--' } sh-expr ' depth < 0 )'&& return _Dbg_get_source_line $line_number $filename setglobal 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" ]] { _Dbg_msg $_Dbg_bash_command } elif sh-expr ' _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" ]] { _Dbg_msg $_Dbg_bash_command } } # 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. proc _Dbg_parse_list_args { typeset -i max_line sh-expr '$# < 3 || $# > 5)'&& return 1 typeset -i center_line setglobal center_line = $2 setglobal max_line = $2 setglobal filename = $3 # Parse start line $3 yielding _Dbg_listline if [[ $4 == '.' ]] { sh-expr '_Dbg_listline=_Dbg_frame_last_lineno' } elif [[ $4 == '-' ]] { sh-expr '_Dbg_listline=_Dbg_listline-2*_Dbg_set_listsize' } elif [[ -n $4 ]] { if sh-expr '$4 < 0)' { sh-expr '_Dbg_listline=$2+$4+1' } else { sh-expr '_Dbg_listline=$4' } } elif sh-expr ' 0 == _Dbg_listline )' { setglobal _Dbg_listline = $_Dbg_frame_last_lineno } sh-expr ' _Dbg_listline==0 && _Dbg_listline++ ' typeset -i count sh-expr 'count=${5:-_Dbg_set_listsize}' sh-expr 'count < 0)'&& sh-expr 'count=$2+$5+1' if [[ -z $5 ]] || sh-expr 'count < _Dbg_listline)' { sh-expr 'center_line)'&& sh-expr '_Dbg_listline-=count/2' sh-expr '_Dbg_listline<=0)'&& sh-expr '_Dbg_listline=1' sh-expr 'end_line=_Dbg_listline+count-1' } else { sh-expr 'end_line=count' } 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. proc _Dbg_list { sh-expr '$# < 3 || $# > 5)'&& return 1 typeset filename setglobal filename = $2 typeset end_line _Dbg_readin_if_new $filename typeset -i max_line setglobal max_line = $[_Dbg_get_maxline $filename] if sh-expr ' $? != 0 )' { _Dbg_errmsg "internal error getting number of lines in $filename" return 1 } _Dbg_parse_list_args $max_line @Argv if sh-expr ' _Dbg_listline > max_line )' { _Dbg_errmsg \ "Line number $_Dbg_listline out of range;" \ "$filename has $max_line lines." return 1 } sh-expr ' end_line > max_line )'&& sh-expr 'end_line=max_line' typeset frame_fullfile setglobal 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 } proc _Dbg_list_columns { typeset colsep=' ' sh-expr '$# > 0 )'&& do { setglobal colsep = $1; shift; } typeset -i linewidth # 2 below is the initial prefix if sh-expr '$# > 0 )' { sh-expr 'linewidth=$1-2'; shift } else { sh-expr 'linewidth=_Dbg_set_linewidth-2' } sh-expr '$# != 0)'&& return 1 typeset -a columnized; columnize $linewidth $colsep typeset -i i for ((i=0; i<${#columnized[@]}; i++)) ; do _Dbg_msg " ${columnized[i]}" done }