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