Imported from ../bash-2.05a.tar.gz.
[platform/upstream/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 }