]> git.ipfire.org Git - thirdparty/bash.git/blob - examples/bashdb/bashdb.fns
Imported from ../bash-2.05a.tar.gz.
[thirdparty/bash.git] / examples / bashdb / bashdb.fns
1 # bashdb.fns - Bourne-Again Shell Debugger functions
2
3 _BUFSIZ=100
4
5 # Here after each statement in script being debugged.
6 # Handle single-step and breakpoints.
7 _steptrap() {
8 let _curline=$1-1 # no. of line that just ran
9 let "$_curline < 1" && let _curline=1
10
11 let "$_curline > $_firstline+$_BUFSIZ" && _readin $_curline
12
13 let " $_trace" &&
14 _msg "$PS4, line $_curline: ${_lines[$(($_curline-$_firstline+1))]}"
15
16
17 # if in step mode, decrement counter
18 let " $_steps >= 0" && let _steps="$_steps - 1"
19
20 # first check if line num or string brkpt. reached
21 if _at_linenumbp || _at_stringbp; then
22 _msg "Reached breakpoint at line $_curline"
23 _cmdloop # enter debugger
24
25 # if not, check whether break condition exists and is true
26 elif [ -n "$_brcond" ] && eval $_brcond; then
27 _msg "Break condition $_brcond true at line $_curline"
28 _cmdloop # enter debugger
29
30 # next, check if step mode and no. of steps is up
31 elif let "$_steps == 0"; then
32 _msg "Stopped at line $_curline"
33 _cmdloop # enter debugger
34 fi
35 }
36
37
38 # Debugger command loop.
39 # Here at start of debugger session, when brkpt. reached, or after single-step.
40 _cmdloop() {
41 local cmd args
42
43 # added support for default command (last one entered)
44
45 while read -e -p "bashdb> [$lastcmd $lastargs] " cmd args; do
46 if [ -z "$cmd" ]; then
47 cmd=$lastcmd
48 args=$lastargs
49 fi
50
51 lastcmd="$cmd"
52 lastargs=$args
53
54 # made commands to be debugger commands by default, no need for '*' prefix
55
56 case $cmd in
57 bp ) _setbp $args ;; #set brkpt at line num or string
58
59 bc ) _setbc $args ;; # set break condition
60
61 cb ) _clearbp ;; # clear all brkpts.
62
63 g ) return ;; # start/resume execution
64
65 s ) let _steps=${args:-1}
66 return ;; # single-step N times(default 1)
67
68 x ) _xtrace ;; # toggle execution trace
69
70 pr ) _print $args ;; # print lines in file
71
72 \? | h | help ) _menu ;; # print command menu
73
74 hi ) history ;; # show command history
75
76 q ) _cleanup; exit ;; # quit
77
78 \! ) eval $args ;; # run shell command
79
80 * ) _msg "\aInvalid command: $cmd" ; _menu ;;
81 esac
82 done
83 }
84
85
86 # see if next line no. is a brkpt.
87 _at_linenumbp() {
88 if [ -z "${_linebp}" ]; then
89 return 1
90 fi
91 echo "${_curline}" | egrep "(${_linebp%\|})" >/dev/null 2>&1
92 return $?
93 }
94
95
96 # search string brkpts to see if next line in script matches.
97 _at_stringbp() {
98 local l;
99
100 if [ -z "$_stringbp" ]; then
101 return 1;
102 fi
103 l=${_lines[$_curline-$_firstline+1]}
104 echo "${l}" | egrep "*(${_stringbp%\|})*" >/dev/null 2>&1
105 return $?
106 }
107
108
109 # print message to stderr
110 _msg() {
111 echo -e "$@" >&2
112 }
113
114
115 # set brkpt(s) at given line numbers and/or strings
116 # by appending lines to brkpt file
117 _setbp() {
118 declare -i n
119 case "$1" in
120 "") _listbp ;;
121 [0-9]*) #number, set brkpt at that line
122 n=$1
123 _linebp="${_linebp}$n|"
124 _msg "Breakpoint at line " $1
125 ;;
126 *) #string, set brkpt at next line w/string
127 _stringbp="${_stringbp}$@|"
128 _msg "Breakpoint at next line containing $@."
129 ;;
130 esac
131 }
132
133
134 # list brkpts and break condition.
135 _listbp() {
136 _msg "Breakpoints at lines:"
137 _msg "${_linebp//\|/ }"
138 _msg "Breakpoints at strings:"
139 _msg "${_stringbp//\|/ }"
140 _msg "Break on condition:"
141 _msg "$_brcond"
142 }
143
144
145 # set or clear break condition
146 _setbc() {
147 if [ -n "$@" ] ; then
148 _brcond=$args
149 _msg "Break when true: $_brcond"
150 else
151 _brcond=
152 _msg "Break condition cleared"
153 fi
154 }
155
156
157 # clear all brkpts
158 _clearbp() {
159 _linebp=
160 _stringbp=
161 _msg "All breakpoints cleared"
162 }
163
164
165 # toggle execution trace feature
166 _xtrace() {
167 let _trace="! $_trace"
168
169 _msg "Execution trace \c"
170 let " $_trace" && _msg "on." || _msg "off."
171 }
172
173
174 # print command menu
175 _menu() {
176
177 # made commands to be debugger commands by default, no need for '*' prefix
178
179 _msg 'bashdb commands:
180 bp N set breakpoint at line N
181 bp string set breakpoint at next line containing "string"
182 bp list breakpoints and break condition
183 bc string set break condition to "string"
184 bc clear break condition
185 cb clear all breakpoints
186 g start/resume execution
187 s [N] execute N statements (default 1)
188 x toggle execution trace on/off (default on)
189 pr [start|.] [cnt] print "cnt" lines from line no. "start"
190 ?, h, help print this menu
191 hi show command history
192 q quit
193
194 ! cmd [args] execute command "cmd" with "args"
195
196 default: last command (in "[ ]" at the prompt)
197
198 Readline command line editing (emacs/vi mode) is available'
199 }
200
201
202 # erase temp files before exiting
203 _cleanup() {
204 rm $_dbgfile 2>/dev/null
205 }
206
207
208 # read $_BUFSIZ lines from $_guineapig into _lines array, starting from line $1
209 # save number of first line read in _firstline
210 _readin() {
211 declare -i _i=1
212 let _firstline=$1
213
214 SEDCMD="$_firstline,$(($_firstline+$_BUFSIZ))p"
215
216 sed -n "$SEDCMD" $_guineapig > /tmp/_script.$$
217 while read -r _lines[$_i]; do
218 _i=_i+1
219 done < /tmp/_script.$$
220 rm -f /tmp/_script.$$ 2>/dev/null
221 }
222
223 _print() {
224 typeset _start _cnt
225
226 if [ -z "$1" ] || [ "$1" = . ]; then
227 _start=$_curline
228 else
229 _start=$1
230 fi
231
232 _cnt=${2:-9}
233
234 SEDCMD="$_start,$(($_start+$_cnt))p"
235
236 pr -tn $_guineapig | sed -n "$SEDCMD"
237 }