Mercurial > hg > octave-nkf
annotate src/debug.cc @ 7736:a059b5679fbb
implement dbstack
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 25 Apr 2008 15:11:03 -0400 |
parents | 87eda1f8faaa |
children | 40c428ea3408 |
rev | line source |
---|---|
3805 | 1 /* |
2 | |
7348 | 3 Copyright (C) 2007, 2008 John Swensen |
4 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Ben Sapp | |
3805 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
3805 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
3805 | 21 |
22 */ | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
3895 | 27 #include <iostream> |
28 #include <fstream> | |
3948 | 29 #include <string> |
7082 | 30 #include <set> |
31 | |
3805 | 32 #include "defun.h" |
33 #include "error.h" | |
7082 | 34 #include "help.h" |
3805 | 35 #include "input.h" |
36 #include "pager.h" | |
37 #include "oct-obj.h" | |
38 #include "utils.h" | |
39 #include "parse.h" | |
40 #include "symtab.h" | |
41 #include "gripes.h" | |
42 #include "ov.h" | |
43 #include "ov-usr-fcn.h" | |
44 #include "ov-fcn.h" | |
7082 | 45 #include "ov-list.h" |
46 #include "ov-struct.h" | |
3805 | 47 #include "pt-pr-code.h" |
48 #include "pt.h" | |
49 #include "pt-bp.h" | |
50 #include "pt-stmt.h" | |
51 #include "toplev.h" | |
52 #include "unwind-prot.h" | |
53 #include "variables.h" | |
54 | |
7082 | 55 #include "debug.h" |
56 | |
57 // Initialize the singleton object | |
7083 | 58 bp_table *bp_table::instance = 0; |
7082 | 59 |
7736 | 60 // FIXME -- dbup and dbdown will need to modify this variable. |
61 static int current_stack_frame = 1; | |
62 | |
5743 | 63 // Return a pointer to the user-defined function FNAME. If FNAME is |
64 // empty, search backward for the first user-defined function in the | |
65 // current call stack. | |
7083 | 66 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
67 static octave_user_code * |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
68 get_user_code (const std::string& fname = std::string ()) |
3805 | 69 { |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
70 octave_user_code *dbg_fcn = 0; |
3805 | 71 |
7083 | 72 if (fname.empty ()) |
5744 | 73 dbg_fcn = octave_call_stack::caller_user_function (); |
5743 | 74 else |
3805 | 75 { |
7539
3e107d73aeb4
debug.cc: use find_function instead of find_user_function
John Swensen
parents:
7348
diff
changeset
|
76 octave_value fcn = symbol_table::find_function (fname); |
3946 | 77 |
7539
3e107d73aeb4
debug.cc: use find_function instead of find_user_function
John Swensen
parents:
7348
diff
changeset
|
78 if (fcn.is_defined ()) |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
79 dbg_fcn = fcn.user_code_value (); |
3805 | 80 } |
81 | |
82 return dbg_fcn; | |
83 } | |
84 | |
7082 | 85 static void |
7348 | 86 parse_dbfunction_params (const char *who, const octave_value_list& args, |
87 std::string& symbol_name, bp_table::intmap& lines) | |
7082 | 88 { |
89 int nargin = args.length (); | |
90 int idx = 0; | |
91 int list_idx = 0; | |
92 symbol_name = std::string (); | |
7348 | 93 lines = bp_table::intmap (); |
94 | |
95 if (args.length () == 0) | |
96 return; | |
7082 | 97 |
7083 | 98 // If we are already in a debugging function. |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
99 if (octave_call_stack::caller_user_code ()) |
7348 | 100 { |
101 idx = 0; | |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
102 symbol_name = get_user_code ()->name (); |
7348 | 103 } |
104 else if (args(0).is_map ()) | |
7082 | 105 { |
7348 | 106 // Problem because parse_dbfunction_params() can only pass out a |
107 // single function | |
108 } | |
109 else if (args(0).is_string()) | |
110 { | |
111 symbol_name = args(0).string_value (); | |
7082 | 112 if (error_state) |
113 return; | |
114 idx = 1; | |
115 } | |
7348 | 116 else |
117 error ("%s: invalid parameter specified", who); | |
7082 | 118 |
119 for (int i = idx; i < nargin; i++ ) | |
120 { | |
7348 | 121 if (args(i).is_string ()) |
7082 | 122 { |
7083 | 123 int line = atoi (args(i).string_value().c_str ()); |
7082 | 124 if (error_state) |
7083 | 125 break; |
7082 | 126 lines[list_idx++] = line; |
127 } | |
7348 | 128 else if (args(i).is_map ()) |
129 octave_stdout << who << ": accepting a struct" << std::endl; | |
7082 | 130 else |
131 { | |
7083 | 132 const NDArray arg = args(i).array_value (); |
7082 | 133 |
134 if (error_state) | |
135 break; | |
136 | |
7083 | 137 for (octave_idx_type j = 0; j < arg.nelem (); j++) |
7082 | 138 { |
139 int line = static_cast<int> (arg.elem (j)); | |
140 if (error_state) | |
141 break; | |
142 lines[list_idx++] = line; | |
143 } | |
144 | |
145 if (error_state) | |
146 break; | |
147 } | |
148 } | |
149 } | |
150 | |
7083 | 151 bp_table::intmap |
152 bp_table::do_add_breakpoint (const std::string& fname, | |
153 const bp_table::intmap& line) | |
7082 | 154 { |
7083 | 155 intmap retval; |
7082 | 156 |
157 octave_idx_type len = line.size (); | |
7083 | 158 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
159 octave_user_code *dbg_fcn = get_user_code (fname); |
7082 | 160 |
161 if (dbg_fcn) | |
162 { | |
163 tree_statement_list *cmds = dbg_fcn->body (); | |
7083 | 164 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
165 if (cmds) |
7082 | 166 { |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
167 for (int i = 0; i < len; i++) |
7082 | 168 { |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
169 const_intmap_iterator p = line.find (i); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
170 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
171 if (p != line.end ()) |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
172 { |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
173 int lineno = p->second; |
7083 | 174 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
175 retval[i] = cmds->set_breakpoint (lineno); |
7083 | 176 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
177 if (retval[i] != 0) |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
178 bp_map[fname] = dbg_fcn; |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
179 } |
7082 | 180 } |
181 } | |
182 } | |
183 else | |
184 error ("add_breakpoint: unable to find the function requested\n"); | |
185 | |
186 return retval; | |
187 } | |
188 | |
189 | |
190 int | |
7083 | 191 bp_table::do_remove_breakpoint (const std::string& fname, |
192 const bp_table::intmap& line) | |
7082 | 193 { |
7083 | 194 int retval = 0; |
7082 | 195 |
196 octave_idx_type len = line.size (); | |
197 | |
198 if (len == 0) | |
199 { | |
200 intmap results = remove_all_breakpoints_in_file (fname); | |
201 retval = results.size (); | |
202 } | |
203 else | |
204 { | |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
205 octave_user_code *dbg_fcn = get_user_code (fname); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
206 |
7082 | 207 if (dbg_fcn) |
208 { | |
209 tree_statement_list *cmds = dbg_fcn->body (); | |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
210 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
211 if (cmds) |
7082 | 212 { |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
213 octave_value_list results = cmds->list_breakpoints (); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
214 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
215 if (results.length () > 0) |
7348 | 216 { |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
217 for (int i = 0; i < len; i++) |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
218 { |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
219 const_intmap_iterator p = line.find (i); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
220 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
221 if (p != line.end ()) |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
222 cmds->delete_breakpoint (p->second); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
223 } |
7083 | 224 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
225 results = cmds->list_breakpoints (); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
226 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
227 breakpoint_map_iterator it = bp_map.find (fname); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
228 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
229 if (results.length () == 0 && it != bp_map.end ()) |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
230 bp_map.erase (it); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
231 } |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
232 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
233 retval = results.length (); |
7082 | 234 } |
235 } | |
236 else | |
237 error ("remove_breakpoint: unable to find the function requested\n"); | |
238 } | |
239 return retval; | |
240 } | |
241 | |
242 | |
7083 | 243 bp_table::intmap |
244 bp_table::do_remove_all_breakpoints_in_file (const std::string& fname) | |
7082 | 245 { |
7083 | 246 intmap retval; |
7082 | 247 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
248 octave_user_code *dbg_fcn = get_user_code (fname); |
7082 | 249 |
250 if (dbg_fcn) | |
251 { | |
252 tree_statement_list *cmds = dbg_fcn->body (); | |
7083 | 253 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
254 if (cmds) |
7082 | 255 { |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
256 octave_value_list bkpts = cmds->list_breakpoints (); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
257 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
258 for (int i = 0; i < bkpts.length (); i++) |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
259 { |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
260 int lineno = static_cast<int> (bkpts(i).int_value ()); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
261 cmds->delete_breakpoint (lineno); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
262 retval[i] = lineno; |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
263 } |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
264 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
265 breakpoint_map_iterator it = bp_map.find (fname); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
266 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
267 if (it != bp_map.end ()) |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
268 bp_map.erase (it); |
7082 | 269 } |
270 } | |
271 else | |
272 error ("remove_all_breakpoint_in_file: " | |
273 "unable to find the function requested\n"); | |
274 | |
275 return retval; | |
276 } | |
277 | |
278 void | |
7083 | 279 bp_table::do_remove_all_breakpoints (void) |
7082 | 280 { |
7083 | 281 for (const_breakpoint_map_iterator it = bp_map.begin (); |
282 it != bp_map.end (); it++) | |
283 remove_all_breakpoints_in_file (it->first); | |
7082 | 284 } |
285 | |
286 std::string | |
287 do_find_bkpt_list (octave_value_list slist, | |
288 std::string match) | |
289 { | |
290 std::string retval; | |
7083 | 291 |
7082 | 292 for (int i = 0; i < slist.length (); i++) |
293 { | |
294 if (slist (i).string_value () == match) | |
295 { | |
7083 | 296 retval = slist(i).string_value (); |
7082 | 297 break; |
298 } | |
299 } | |
300 return retval; | |
301 } | |
302 | |
303 | |
7083 | 304 bp_table::fname_line_map |
305 bp_table::do_get_breakpoint_list (const octave_value_list& fname_list) | |
7082 | 306 { |
7083 | 307 fname_line_map retval; |
7082 | 308 |
309 // Iterate through each of the files in the map and get the | |
7083 | 310 // name and list of breakpoints. |
311 | |
312 for (breakpoint_map_iterator it = bp_map.begin (); it != bp_map.end (); it++) | |
7082 | 313 { |
7083 | 314 if (fname_list.length () == 0 |
315 || do_find_bkpt_list (fname_list, it->first) != "") | |
7082 | 316 { |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
317 octave_user_code *f = it->second; |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
318 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
319 tree_statement_list *cmds = f->body (); |
7083 | 320 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
321 if (cmds) |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
322 { |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
323 octave_value_list bkpts = cmds->list_breakpoints (); |
7083 | 324 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
325 octave_idx_type len = bkpts.length (); |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
326 |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
327 bp_table::intmap bkpts_vec; |
7083 | 328 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
329 for (int i = 0; i < len; i++) |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
330 bkpts_vec[i] = bkpts (i).double_value (); |
7083 | 331 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
332 retval[it->first] = bkpts_vec; |
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
333 } |
7082 | 334 } |
335 } | |
7083 | 336 |
7082 | 337 return retval; |
338 } | |
339 | |
340 static octave_value | |
7083 | 341 intmap_to_ov (const bp_table::intmap& line) |
7082 | 342 { |
343 int idx = 0; | |
7083 | 344 |
345 NDArray retval (dim_vector (1, line.size ())); | |
346 | |
347 for (size_t i = 0; i < line.size (); i++) | |
7082 | 348 { |
7083 | 349 bp_table::const_intmap_iterator p = line.find (i); |
350 | |
7082 | 351 if (p != line.end ()) |
352 { | |
353 int lineno = p->second; | |
7083 | 354 retval(idx++) = lineno; |
7082 | 355 } |
356 } | |
7083 | 357 |
7082 | 358 retval.resize (dim_vector (1, idx)); |
7083 | 359 |
7082 | 360 return retval; |
361 } | |
3895 | 362 |
4208 | 363 DEFCMD (dbstop, args, , |
3805 | 364 "-*- texinfo -*-\n\ |
7083 | 365 @deftypefn {Loadable Function} {rline =} dbstop (@var{func}, @var{line}, @dots{})\n\ |
3805 | 366 Set a breakpoint in a function\n\ |
367 @table @code\n\ | |
368 @item func\n\ | |
369 String representing the function name. When already in debug\n\ | |
370 mode this should be left out and only the line should be given.\n\ | |
371 @item line\n\ | |
6646 | 372 Line you would like the breakpoint to be set on. Multiple\n\ |
7001 | 373 lines might be given as separate arguments or as a vector.\n\ |
3805 | 374 @end table\n\ |
375 \n\ | |
376 The rline returned is the real line that the breakpoint was set at.\n\ | |
5642 | 377 @seealso{dbclear, dbstatus, dbnext}\n\ |
378 @end deftypefn") | |
3805 | 379 { |
7083 | 380 bp_table::intmap retval; |
381 std::string symbol_name; | |
382 bp_table::intmap lines; | |
383 | |
7348 | 384 parse_dbfunction_params ("dbstop", args, symbol_name, lines); |
6646 | 385 |
7083 | 386 if (! error_state) |
7082 | 387 retval = bp_table::add_breakpoint (symbol_name, lines); |
3805 | 388 |
7083 | 389 return intmap_to_ov (retval); |
3805 | 390 } |
391 | |
4208 | 392 DEFCMD (dbclear, args, , |
3805 | 393 "-*- texinfo -*-\n\ |
7083 | 394 @deftypefn {Loadable Function} {} dbclear (@var{func}, @var{line}, @dots{})\n\ |
3805 | 395 Delete a breakpoint in a function\n\ |
396 @table @code\n\ | |
397 @item func\n\ | |
398 String representing the function name. When already in debug\n\ | |
399 mode this should be left out and only the line should be given.\n\ | |
400 @item line\n\ | |
6653 | 401 Line where you would like to remove the breakpoint. Multiple\n\ |
7001 | 402 lines might be given as separate arguments or as a vector.\n\ |
3805 | 403 @end table\n\ |
404 No checking is done to make sure that the line you requested is really\n\ | |
6646 | 405 a breakpoint. If you get the wrong line nothing will happen.\n\ |
5642 | 406 @seealso{dbstop, dbstatus, dbwhere}\n\ |
407 @end deftypefn") | |
3805 | 408 { |
409 octave_value retval; | |
410 std::string symbol_name = ""; | |
7083 | 411 bp_table::intmap lines; |
412 | |
7348 | 413 parse_dbfunction_params ("dbclear", args, symbol_name, lines); |
7082 | 414 |
7083 | 415 if (! error_state) |
7082 | 416 bp_table::remove_breakpoint (symbol_name, lines); |
3805 | 417 |
418 return retval; | |
419 } | |
420 | |
7082 | 421 DEFCMD (dbstatus, args, nargout, |
3805 | 422 "-*- texinfo -*-\n\ |
7083 | 423 @deftypefn {Loadable Function} {lst =} dbstatus (@var{func})\n\ |
3805 | 424 Return a vector containing the lines on which a function has \n\ |
425 breakpoints set.\n\ | |
426 @table @code\n\ | |
427 @item func\n\ | |
428 String representing the function name. When already in debug\n\ | |
429 mode this should be left out.\n\ | |
430 @end table\n\ | |
5642 | 431 @seealso{dbclear, dbwhere}\n\ |
432 @end deftypefn") | |
3805 | 433 { |
7082 | 434 Octave_map retval; |
3805 | 435 int nargin = args.length (); |
7082 | 436 octave_value_list fcn_list; |
7083 | 437 bp_table::fname_line_map bp_list; |
438 std::string symbol_name; | |
3805 | 439 |
440 if (nargin != 0 && nargin != 1) | |
441 { | |
3948 | 442 error ("dbstatus: only zero or one arguements accepted\n"); |
7082 | 443 return octave_value (); |
3805 | 444 } |
445 | |
446 if (nargin == 1) | |
447 { | |
448 if (args(0).is_string ()) | |
7082 | 449 { |
7083 | 450 symbol_name = args(0).string_value (); |
451 fcn_list(0) = symbol_name; | |
7082 | 452 bp_list = bp_table::get_breakpoint_list (fcn_list); |
453 } | |
3805 | 454 else |
7083 | 455 gripe_wrong_type_arg ("dbstatus", args(0)); |
7082 | 456 } |
457 else | |
458 { | |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
459 octave_user_code *dbg_fcn = get_user_code (); |
7082 | 460 if (dbg_fcn) |
461 { | |
462 symbol_name = dbg_fcn->name (); | |
7083 | 463 fcn_list(0) = symbol_name; |
7082 | 464 } |
7083 | 465 |
7082 | 466 bp_list = bp_table::get_breakpoint_list (fcn_list); |
3805 | 467 } |
468 | |
7083 | 469 if (nargout == 0) |
3805 | 470 { |
7083 | 471 // Print out the breakpoint information. |
472 | |
473 for (bp_table::fname_line_map_iterator it = bp_list.begin (); | |
474 it != bp_list.end (); it++) | |
475 { | |
476 octave_stdout << "Breakpoint in " << it->first << " at line(s) "; | |
477 | |
478 bp_table::intmap m = it->second; | |
479 | |
480 size_t nel = m.size (); | |
481 | |
482 for (size_t j = 0; j < nel; j++) | |
483 octave_stdout << m[j] << ((j < nel - 1) ? ", " : "."); | |
484 | |
485 if (nel > 0) | |
486 octave_stdout << std::endl; | |
487 } | |
488 return octave_value (); | |
489 } | |
490 else | |
491 { | |
492 // Fill in an array for return. | |
493 | |
7082 | 494 int i = 0; |
495 Cell names (dim_vector (bp_list.size (), 1)); | |
496 Cell file (dim_vector (bp_list.size (), 1)); | |
497 Cell line (dim_vector (bp_list.size (), 1)); | |
7083 | 498 |
499 for (bp_table::const_fname_line_map_iterator it = bp_list.begin (); | |
500 it != bp_list.end (); it++) | |
3946 | 501 { |
7083 | 502 names(i) = it->first; |
503 line(i) = intmap_to_ov (it->second); | |
504 file(i) = do_which (it->first); | |
7082 | 505 i++; |
3805 | 506 } |
7083 | 507 |
7082 | 508 retval.assign ("name", names); |
509 retval.assign ("file", file); | |
510 retval.assign ("line", line); | |
7083 | 511 |
7082 | 512 return octave_value (retval); |
3805 | 513 } |
514 } | |
515 | |
4208 | 516 DEFCMD (dbwhere, , , |
3805 | 517 "-*- texinfo -*-\n\ |
3895 | 518 @deftypefn {Loadable Function} {} dbwhere ()\n\ |
3805 | 519 Show where we are in the code\n\ |
5642 | 520 @seealso{dbclear, dbstatus, dbstop}\n\ |
5645 | 521 @end deftypefn") |
3805 | 522 { |
523 octave_value retval; | |
3946 | 524 |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
525 octave_user_code *dbg_fcn = get_user_code (); |
3805 | 526 |
527 if (dbg_fcn) | |
528 { | |
4748 | 529 std::string name = dbg_fcn->name (); |
3805 | 530 |
531 octave_stdout << name << ":"; | |
532 | |
533 const tree *dbg_stmt = tree::break_statement; | |
534 | |
535 if (dbg_stmt) | |
536 { | |
7083 | 537 octave_stdout << " line " << dbg_stmt->line () << ", "; |
3805 | 538 octave_stdout << "column " << dbg_stmt->column () << std::endl; |
539 } | |
540 else | |
7083 | 541 octave_stdout << " (unknown line)\n"; |
3805 | 542 } |
543 else | |
3948 | 544 error ("dbwhere: must be inside of a user function to use dbwhere\n"); |
3895 | 545 |
546 return retval; | |
547 } | |
548 | |
549 // Copied and modified from the do_type command in help.cc | |
3946 | 550 // Maybe we could share some code? |
551 void | |
3949 | 552 do_dbtype (std::ostream& os, const std::string& name, int start, int end) |
3895 | 553 { |
554 std::string ff = fcn_file_in_path (name); | |
555 | |
556 if (! ff.empty ()) | |
557 { | |
558 std::ifstream fs (ff.c_str (), std::ios::in); | |
3946 | 559 |
3895 | 560 if (fs) |
3946 | 561 { |
3895 | 562 char ch; |
563 int line = 1; | |
3946 | 564 |
3895 | 565 if (line >= start && line <= end) |
566 os << line << "\t"; | |
3946 | 567 |
3895 | 568 while (fs.get (ch)) |
569 { | |
570 if (line >= start && line <= end) | |
571 { | |
572 os << ch; | |
573 } | |
574 | |
575 if (ch == '\n') | |
576 { | |
577 line++; | |
578 if (line >= start && line <= end) | |
3946 | 579 os << line << "\t"; |
3895 | 580 } |
581 } | |
582 } | |
3946 | 583 else |
3949 | 584 os << "dbtype: unable to open `" << ff << "' for reading!\n"; |
3895 | 585 } |
586 else | |
6317 | 587 os << "dbtype: unknown function " << name << "\n"; |
3895 | 588 |
6646 | 589 os.flush (); |
3895 | 590 } |
591 | |
4208 | 592 DEFCMD (dbtype, args, , |
3895 | 593 "-*- texinfo -*-\n\ |
594 @deftypefn {Loadable Function} {} dbtype ()\n\ | |
595 List script file with line numbers.\n\ | |
5642 | 596 @seealso{dbclear, dbstatus, dbstop}\n\ |
597 @end deftypefn") | |
3895 | 598 { |
599 octave_value retval; | |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
600 octave_user_code *dbg_fcn; |
3946 | 601 |
3895 | 602 int nargin = args.length (); |
603 string_vector argv = args.make_argv ("dbtype"); | |
3946 | 604 |
3895 | 605 if (! error_state) |
606 { | |
607 switch (nargin) | |
608 { | |
609 case 0: // dbtype | |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
610 dbg_fcn = get_user_code (); |
3895 | 611 |
612 if (dbg_fcn) | |
4748 | 613 do_dbtype (octave_stdout, dbg_fcn->name (), 0, INT_MAX); |
3895 | 614 else |
3948 | 615 error ("dbtype: must be in a user function to give no arguments to dbtype\n"); |
3946 | 616 break; |
3895 | 617 |
3946 | 618 case 1: // (dbtype func) || (dbtype start:end) |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
619 dbg_fcn = get_user_code (argv[1]); |
3895 | 620 |
621 if (dbg_fcn) | |
4748 | 622 do_dbtype (octave_stdout, dbg_fcn->name (), 0, INT_MAX); |
3895 | 623 else |
624 { | |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
625 dbg_fcn = get_user_code (); |
3895 | 626 |
627 if (dbg_fcn) | |
628 { | |
3948 | 629 std::string arg = argv[1]; |
630 | |
631 size_t ind = arg.find (':'); | |
3895 | 632 |
3948 | 633 if (ind != NPOS) |
634 { | |
635 std::string start_str = arg.substr (0, ind); | |
636 std::string end_str = arg.substr (ind + 1); | |
637 | |
638 int start = atoi (start_str.c_str ()); | |
639 int end = atoi (end_str.c_str ()); | |
3946 | 640 |
6317 | 641 if (std::min (start, end) <= 0) |
642 error ("dbtype: start and end lines must be >= 1\n"); | |
643 | |
644 if (start <= end) | |
645 do_dbtype (octave_stdout, dbg_fcn->name (), start, end); | |
3948 | 646 else |
6317 | 647 error ("dbtype: start line must be less than end line\n"); |
3895 | 648 } |
3948 | 649 else |
6317 | 650 error ("dbtype: line specification must be `start:end'"); |
3895 | 651 } |
652 } | |
653 break; | |
3946 | 654 |
6317 | 655 case 2: // (dbtype func start:end) , (dbtype func start) |
7719
87eda1f8faaa
octave_user_code: new base class for octave_user_script and octave_user_function
John W. Eaton <jwe@octave.org>
parents:
7539
diff
changeset
|
656 dbg_fcn = get_user_code (argv[1]); |
3895 | 657 |
658 if (dbg_fcn) | |
659 { | |
3948 | 660 std::string arg = argv[2]; |
6317 | 661 int start = 0; |
662 int end = 0; | |
3948 | 663 size_t ind = arg.find (':'); |
3895 | 664 |
3948 | 665 if (ind != NPOS) |
3895 | 666 { |
3948 | 667 std::string start_str = arg.substr (0, ind); |
668 std::string end_str = arg.substr (ind + 1); | |
3895 | 669 |
6317 | 670 start = atoi (start_str.c_str ()); |
671 end = atoi (end_str.c_str ()); | |
672 | |
3948 | 673 } |
674 else | |
6317 | 675 { |
676 start = atoi (arg.c_str ()); | |
677 end = start; | |
678 } | |
679 | |
680 if (std::min (start, end) <= 0) | |
681 error ("dbtype: start and end lines must be >= 1\n"); | |
682 | |
683 if (start <= end) | |
684 do_dbtype (octave_stdout, dbg_fcn->name (), start, end); | |
685 else | |
686 error ("dbtype: start line must be less than end line\n"); | |
3895 | 687 } |
3946 | 688 break; |
3895 | 689 |
690 default: | |
3948 | 691 error ("dbtype: expecting zero, one, or two arguments\n"); |
3895 | 692 } |
693 } | |
3805 | 694 |
695 return retval; | |
696 } | |
697 | |
7736 | 698 DEFUN (__dbstack__, args, , |
699 "-*- texinfo -*-\n\ | |
700 @deftypefn {Loadable Function} {[@var{stack}, @var{idx}]} __dbstack__ (@var{n})\n\ | |
701 Undocumented internal function.\n\ | |
702 @end deftypefn") | |
703 { | |
704 octave_value_list retval; | |
705 | |
706 int n = 0; | |
707 | |
708 if (args.length () == 1) | |
709 n = args(0).int_value (); | |
710 | |
711 if (! error_state) | |
712 { | |
713 retval(1) = current_stack_frame; | |
714 | |
715 // Add one here to skip the __dbstack__ stack frame. | |
716 retval(0) = octave_call_stack::backtrace (n+1); | |
717 } | |
718 | |
719 return retval; | |
720 } | |
721 | |
3805 | 722 /* |
723 ;;; Local Variables: *** | |
724 ;;; mode: C++ *** | |
725 ;;; End: *** | |
726 */ |