# -*- shell-script -*- # # Copyright (C) 2010-2011, 2015 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. #================ VARIABLE INITIALIZATIONS ====================# # Number of actions. typeset -i _Dbg_action_count = '0' # 1/0 if enabled or not typeset -a _Dbg_action_enable = ''; setglobal _Dbg_action_enable = ''() # filename of action $i typeset -a _Dbg_action_file = ''; setglobal _Dbg_action_file = ''() # Line number of action $i typeset -a _Dbg_action_line = ''; setglobal _Dbg_action_line = ''() # statement to run when line is hit typeset -a _Dbg_action_stmt = ''; setglobal _Dbg_action_stmt = ''() # Needed because we can't figure out what the max index is and arrays # can be sparse. typeset -i _Dbg_action_max = '0' # Maps a resolved filename to a list of action entries. typeset -A _Dbg_action_file2action = ''; setglobal _Dbg_action_file2action = ''() # Maps a resolved filename to a list of action line numbers in that file typeset -A _Dbg_action_file2linenos = ''; setglobal _Dbg_action_file2linenos = ''() # Note: we loop over possibly sparse arrays with _Dbg_brkpt_max by adding one # and testing for an entry. Could add yet another array to list only # used indices. Zsh is kind of primitive. #========================= FUNCTIONS ============================# proc _Dbg_save_actions { typeset -p _Dbg_action_line >> $_Dbg_statefile typeset -p _Dbg_action_file >> $_Dbg_statefile typeset -p _Dbg_action_enable >> $_Dbg_statefile typeset -p _Dbg_action_stmt >> $_Dbg_statefile typeset -p _Dbg_action_max >> $_Dbg_statefile typeset -p _Dbg_action_file2linenos >> $_Dbg_statefile typeset -p _Dbg_action_file2action >> $_Dbg_statefile } # list actions proc _Dbg_list_action { if test $(#_Dbg_action_line[@]) != 0 { _Dbg_msg "Actions at following places:" typeset -i i = '' _Dbg_section "Num Enb Stmt file:line" for (( i=1; (( i <= _Dbg_action_max )) ; i++ )) ; do if [[ -n ${_Dbg_action_line[$i]} ]] ; then typeset source_file=${_Dbg_action_file[$i]} source_file=$(_Dbg_adjust_filename "$source_file") _Dbg_printf "%-3d %3d %-18s %s:%s" $i ${_Dbg_action_enable[$i]} \ "${_Dbg_action_stmt[$i]}" \ $source_file ${_Dbg_action_line[$i]} fi done } else { _Dbg_msg "No actions have been set." } } # Internal routine to a set action unconditonally. proc _Dbg_set_action { sh-expr ' $# != 3 ' && return 1 typeset source_file = '' setglobal source_file = $[_Dbg_expand_filename $1] $[_Dbg_is_int $2] || return 1 typeset -ri lineno = $2 typeset -r stmt = $3 # Increment action_max here because we are 1-origin sh-expr '_Dbg_action_max++' sh-expr '_Dbg_action_count++' _Dbg_action_line[$_Dbg_action_max]=$lineno _Dbg_action_file[$_Dbg_action_max]="$source_file" _Dbg_action_stmt[$_Dbg_action_max]="$stmt" _Dbg_action_enable[$_Dbg_action_max]=1 typeset dq_source_file = '' typeset dq_source_file = $[_Dbg_esc_dq $source_file] typeset dq_stmt = $[_Dbg_esc_dq $stmt] _Dbg_write_journal "_Dbg_action_line[$_Dbg_action_max]=$lineno" _Dbg_write_journal "_Dbg_action_file[$_Dbg_action_max]=\"$dq_source_file\"" _Dbg_write_journal "_Dbg_action_stmt[$_Dbg_action_max]=\"$dq_stmt\"" _Dbg_write_journal "_Dbg_action_enable[$_Dbg_action_max]=1" # Add line number with a leading and trailing space. Delimiting the # number with space helps do a string search for the line number. _Dbg_action_file2linenos[$source_file]+=" $lineno " _Dbg_action_file2action[$source_file]+=" $_Dbg_action_max " setglobal source_file = $[_Dbg_adjust_filename $source_file] _Dbg_msg "Action $_Dbg_action_max set in file $(source_file), line $lineno." _Dbg_write_journal "_Dbg_action_max=$_Dbg_action_max" return 0 } # Internal routine to delete an action by file/line. # 0 is returned if we were able to unset the action. # Nonzero is returned otherwize. proc _Dbg_unset_action { sh-expr ' $# == 2 ' || return 1 typeset -r filename = $1 $[_Dbg_is_int $2] || return 1 typeset -i lineno = $2 typeset fullname = '' setglobal fullname = $[_Dbg_expand_filename $filename] # FIXME: combine with something? typeset -a linenos = '' eval "linenos=($(_Dbg_action_file2linenos[$fullname]))" typeset -a action_nos = '' eval "action_nos=($(_Dbg_action_file2action[$fullname]))" typeset -i i = '' for ((i=0; i < ${#linenos[@]}; i++)); do if (( linenos[i] == lineno )) ; then # Got a match, find action entry number typeset -i action_num (( action_num = action_nos[i] )) _Dbg_unset_action_arrays $action_num unset linenos[i] _Dbg_action_file2linenos[$fullname]=${linenos[@]} return 0 fi done _Dbg_errmsg "No action found in file $(filename), line $lineno." return 1 } # Internal routine to unset the actual action arrays # 0 is returned if successful proc _Dbg_unset_action_arrays { sh-expr ' $# != 1 ' && return 1 typeset -i del = $1 _Dbg_write_journal_eval "unset _Dbg_action_enable[$del]" _Dbg_write_journal_eval "unset _Dbg_action_file[$del]" _Dbg_write_journal_eval "unset _Dbg_action_line[$del]" _Dbg_write_journal_eval "unset _Dbg_action_stmt[$del]" sh-expr '_Dbg_action_count--' return 0 }