File: dbg-io.inc

package info (click to toggle)
bashdb 3.1.0.9-1
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 3,252 kB
  • ctags: 117
  • sloc: sh: 4,880; pascal: 3,186; lisp: 484; makefile: 315; ansic: 294
file content (287 lines) | stat: -rw-r--r-- 8,283 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# dbg-io.inc - Bourne Again Shell Debugger Input/Output routines
#
#   Copyright (C) 2002, 2003, 2004, 2006 Rocky Bernstein 
#   rockyb@users.sourceforge.net
#
#   Bash 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.
#
#   Bash 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 Bash; see the file COPYING.  If not, write to the Free Software
#   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.

# ==================== VARIABLES =======================================

# _Dbg_source_mungedfilename is an array which contains source_lines for
#  filename
# _Dbg_read_mungedfilename is array which contains the value '1' if the
#  filename has been read in.

# Filename that's used when no source file is around. In particular
# if bash --debugger -c 'string' was used to invoke us.
typeset -r _Dbg_bogus_file='*BOGUS*'

typeset -a _Dbg_filenames          # names of all source files read
typeset -a _Dbg_override_filenames # name translations given via the debugger
                                   # "file" command.
typeset _cur_source_file  # current source file of debugged program
typeset _cur_filevar      # source file mangled so it can be used in a variable
typeset -i _curline       # current line number of debugged program

# See if we have compiled the readarray builtin. This speeds up reading
# files into a bash array.
typeset -i _Dbg_have_readarray=0

if [[ -r $_Dbg_libdir/readarray ]] ; then
  if enable -f $_Dbg_libdir/readarray  readarray >/dev/null 2>&1 ; then
    _Dbg_have_readarray=1
  fi
fi

# ===================== FUNCTIONS =======================================

# print message to output device
_Dbg_msg() {
  if (( $_Dbg_logging != 0 )) ; then
    builtin echo -e "$@" >>$_Dbg_logfid
  fi
  if (( $_Dbg_logging_redirect == 0 )) ; then
    if [[ -n $_Dbg_tty  ]] ; then
      builtin echo -e "$@" >>$_Dbg_tty
    else
      builtin echo -e "$@"
    fi
  fi
}

# print message to output device without a carriage return at the end
_Dbg_msg_nocr() {
  if (( $_Dbg_logging != 0 )) ; then
    builtin echo -n -e "$@" >>$_Dbg_logfid
  fi
  if (( $_Dbg_logging_redirect == 0 )) ; then
    if [[ -n $_Dbg_tty  ]] ; then
      builtin echo -n -e "$@" >>$_Dbg_tty
    else
      builtin echo -n -e "$@"
    fi
  fi
}

# print message to output device
_Dbg_printf() {
  local format=$1
  shift
  if (( $_Dbg_logging != 0 )) ; then
    builtin printf "$format" "$@" >>$_Dbg_logfid
  fi
  if (( $_Dbg_logging_redirect == 0 )) ; then
    if [[ -n $_Dbg_tty ]] ; then
      builtin printf "$format" "$@" >>$_Dbg_tty
    else
      builtin printf "$format" "$@"
    fi
  fi
  _Dbg_msg ""
}

# print message to output device without a carriage return at the end
_Dbg_printf_nocr() {
  local format=$1
  shift 
  if (( $_Dbg_logging != 0 )) ; then
    builtin printf "$format" "$@" >>$_Dbg_logfid
  fi
  if (( $_Dbg_logging_redirect == 0 )) ; then
    if [[ -n $_Dbg_tty ]] ; then 
      builtin printf "$format" "$@" >>$_Dbg_tty
    else
      builtin printf "$format" "$@"
    fi
  fi
}

# Common funnel for "Undefined command" message
_Dbg_undefined_cmd() {
  _Dbg_msg "Undefined $1 command \"$2\""
}

# _Dbg_progess_show --- print the progress bar
# $1: prefix string
# $2: max value
# $3: current value
_Dbg_progess_show() {
    local title=$1
    local -i max_value=$2
    local -i current_value=$3
    local -i max_length=40
    local -i current_length

    
    if (( max_value == 0 )) ; then
	# Avoid dividing by 0.
	current_length=${max_length}
    else
	current_length=$(( ${max_length} * ${current_value} / ${max_value} ))
    fi
    
    _Dbg_progess_show_internal "$1" ${max_length} ${current_length}
    _Dbg_printf_nocr " %3d%%" "$(( 100 * ${current_value} / ${max_value} ))"
}
# _Dbg_progess_show_internal --- internal function for _Dbg_progess_show
# $1: prefix string
# $2: max length
# $3: current length
_Dbg_progess_show_internal() {
    local -i i=0

    # Erase line
    if test "x$EMACS" = xt; then
	_Dbg_msg_nocr "\r\b\n"	
    else
	_Dbg_msg_nocr "\r\b"
    fi
    
    _Dbg_msg_nocr "$1: ["
    for (( i=0; i < $3 ; i++ )); do
	_Dbg_msg_nocr "="
    done
    _Dbg_msg_nocr ">"

    for (( i=0; i < $2 - $3 ; i++ )); do
	_Dbg_msg_nocr " "
    done
    _Dbg_msg_nocr "]"
}

# clean up progress bar
_Dbg_progess_done() {
    # Erase line
    if test "x$EMACS" = xt; then
	_Dbg_msg_nocr "\r\b\n"	
    else
	_Dbg_msg_nocr "\r\b"
    fi
    _Dbg_msg $1
}


# Return text for source line for line $1 of filename $2 in variable
# $source_line. The hope is that this has been declared "local" in the 
# caller.

# If $2 is omitted, # use _cur_source_file, if $1 is omitted use _curline.
_Dbg_get_source_line() {
  local lineno=${1:-$_curline}
  local filename=${2:-$_cur_source_file}
  local filevar=`_Dbg_file2var $filename`
  local is_read=`_Dbg_get_assoc_scalar_entry "_Dbg_read_" $filevar`
  [ $is_read ] || _Dbg_readin $filename 
  
  source_line=`_Dbg_get_assoc_array_entry _Dbg_source_${filevar} $lineno`
}

# Read $1 into _source_$1 array.  Variable _Dbg_read_$1 will be set
# to 1 to note that the file has been read and the filename will be saved
# in array _Dbg_filenames

_Dbg_readin() {
  # set -xv
  local filename=${1:-$_cur_source_file}

  local -i line_count=0
  local filevar
  local source_array
  local -ir NOT_SMALLFILE=1000

  if [[ -z $filename ]] || [[ $filename == $_Dbg_bogus_file ]] ; then 
    filevar='ABOGUSA'
    source_array="_Dbg_source_${filevar}"
    local cmd="${source_array}[0]=\"$BASH_EXECUTION_STRING\""
    eval $cmd

  else 
    local fullname=$(_Dbg_resolve_expand_filename $filename)
    filevar=`_Dbg_file2var $filename`
    if [[ -r $fullname ]] ; then
      local -r progress_prefix="Reading $filename"
      source_array="_Dbg_source_${filevar}"
      if (( 0 != $_Dbg_have_readarray )); then
	# If we have readarray that speeds up reading greatly. Use it.
	local -ir BIGFILE=30000
	if wc -l < /dev/null >/dev/null 2>&1 ; then 
	  line_count=`wc -l < "${fullname}"`
	  if (( $line_count >= $NOT_SMALLFILE )) ; then 
	    _Dbg_msg_nocr "${progress_prefix} "
	  fi
	fi
	readarray -t -O 1 -c $BIGFILE \
	  -C "_Dbg_progess_show \"${progress_prefix}\" ${line_count}" \
	  $source_array < $fullname 
	(( line_count > BIGFILE)) && _Dbg_progess_done
	
      else
	# No readarray. Do things the long way.
	local -i i
	for (( i=1; 1 ; i++ )) ; do 
	  local source_entry="${source_array}[$i]"
	  local readline_cmd="read -r $source_entry; rc=\$?";
	  local -i rc=1
	  if (( i % 1000 == 0 )) ; then
	    if (( i==NOT_SMALLFILE )) ; then
	      if wc -l < /dev/null >/dev/null 2>&1 ; then 
		line_count=`wc -l < "${fullname}"`
	      else
		_Dbg_msg_nocr "${progress_prefix} "
	      fi
	    fi
	    if (( line_count == 0 )) ; then
	      _Dbg_msg_nocr "${i}... "
	    else
	      _Dbg_progess_show "${progress_prefix}" ${line_count} ${i}
	    fi
	  fi
	  eval $readline_cmd
	  if [[ $rc != 0 ]]  ; then 
	    break;
	  fi
	done  < $fullname
	# The last read in the loop above failed. So we've actually 
	# read one more than the number of lines.
	local -r remove_last_index_cmd="unset $source_array[$i]"
	eval $remove_last_index_cmd
	(( line_count != 0 )) && _Dbg_progess_done
      fi
    else
	return
    fi
  fi

  local -r line_count_cmd="line_count=\${#$source_array[@]}"
  eval $line_count_cmd

  (( line_count >= NOT_SMALLFILE )) && _Dbg_msg "done."

  _Dbg_set_assoc_scalar_entry "_Dbg_read_" $filevar 1
  _Dbg_set_assoc_scalar_entry "_Dbg_maxline_" $filevar $line_count
  
  # Add $filename to list of all filenames
  _Dbg_filenames[${#_Dbg_filenames[@]}]=$fullname;
  # set +xv
}

# This is put at the so we have something at the end when we debug this.
typeset -r _Dbg_io_ver=\
'$Id: dbg-io.inc,v 1.12 2006/12/19 04:41:05 rockyb Exp $'

#;;; Local Variables: ***
#;;; mode:shell-script ***
#;;; eval: (sh-set-shell "bash") ***
#;;; End: ***