Mercurial > hg > octave-lyh
comparison src/debug.cc @ 3895:d38c7538b954
[project @ 2002-04-10 19:18:39 by jwe]
author | jwe |
---|---|
date | Wed, 10 Apr 2002 19:18:39 +0000 |
parents | 44386b0e53da |
children | eab957395758 |
comparison
equal
deleted
inserted
replaced
3894:d71f92546e45 | 3895:d38c7538b954 |
---|---|
21 */ | 21 */ |
22 | 22 |
23 #ifdef HAVE_CONFIG_H | 23 #ifdef HAVE_CONFIG_H |
24 #include <config.h> | 24 #include <config.h> |
25 #endif | 25 #endif |
26 | |
27 #include <iostream> | |
28 #include <fstream> | |
29 #include <strstream> | |
30 #include <string> | |
31 #include <stdlib.h> | |
26 | 32 |
27 #include "defun.h" | 33 #include "defun.h" |
28 #include "error.h" | 34 #include "error.h" |
29 #include "input.h" | 35 #include "input.h" |
30 #include "pager.h" | 36 #include "pager.h" |
47 octave_user_function * | 53 octave_user_function * |
48 get_user_function (std::string str = "") | 54 get_user_function (std::string str = "") |
49 { | 55 { |
50 octave_user_function *dbg_fcn = NULL; | 56 octave_user_function *dbg_fcn = NULL; |
51 | 57 |
52 if (curr_function) | 58 if (str.compare ("")) |
53 { | |
54 dbg_fcn = curr_function; | |
55 } | |
56 else if (str.compare ("")) | |
57 { | 59 { |
58 symbol_record *ptr = curr_sym_tab->lookup (str); | 60 symbol_record *ptr = curr_sym_tab->lookup (str); |
59 | 61 |
60 if (ptr && ptr->is_user_function ()) | 62 if (ptr && ptr->is_user_function ()) |
61 { | 63 { |
71 octave_value tmp = ptr->def (); | 73 octave_value tmp = ptr->def (); |
72 dbg_fcn = static_cast<octave_user_function *> (tmp.function_value ()); | 74 dbg_fcn = static_cast<octave_user_function *> (tmp.function_value ()); |
73 } | 75 } |
74 } | 76 } |
75 } | 77 } |
78 else if (curr_function) | |
79 { | |
80 dbg_fcn = curr_function; | |
81 } | |
76 | 82 |
77 return dbg_fcn; | 83 return dbg_fcn; |
78 } | 84 } |
79 | 85 |
80 DEFUN_TEXT (dbg_set, args, , | 86 |
87 DEFUN_TEXT (dbstop, args, , | |
81 "-*- texinfo -*-\n\ | 88 "-*- texinfo -*-\n\ |
82 @deftypefn {Loadable Function} {rline =} dbg_set (func, line)\n\ | 89 @deftypefn {Loadable Function} {rline =} dbstop (func, line)\n\ |
83 Set a breakpoint in a function\n\ | 90 Set a breakpoint in a function\n\ |
84 @table @code\n\ | 91 @table @code\n\ |
85 @item func\n\ | 92 @item func\n\ |
86 String representing the function name. When already in debug\n\ | 93 String representing the function name. When already in debug\n\ |
87 mode this should be left out and only the line should be given.\n\ | 94 mode this should be left out and only the line should be given.\n\ |
90 @end table\n\ | 97 @end table\n\ |
91 \n\ | 98 \n\ |
92 The rline returned is the real line that the breakpoint was set at.\n\ | 99 The rline returned is the real line that the breakpoint was set at.\n\ |
93 \n\ | 100 \n\ |
94 @end deftypefn\n\ | 101 @end deftypefn\n\ |
95 @seealso{dbg_delete, dbg_list, dbg_where}") | 102 @seealso{dbclear, dbtatus, dbnext}") |
96 { | 103 { |
97 octave_value retval; | 104 octave_value retval; |
98 | 105 |
99 int result = -1; | 106 int result = -1; |
100 int nargin = args.length (); | 107 int nargin = args.length (); |
101 | 108 |
102 string_vector argv = args.make_argv ("dbg_set"); | 109 string_vector argv = args.make_argv ("dbstop"); |
103 | 110 |
104 if (error_state) | 111 if (error_state) |
105 return retval; | 112 return retval; |
106 | 113 |
107 if (nargin == 2) | 114 if (nargin == 2) |
144 retval = static_cast<double> (result); | 151 retval = static_cast<double> (result); |
145 | 152 |
146 return retval; | 153 return retval; |
147 } | 154 } |
148 | 155 |
149 DEFUN_TEXT (dbg_delete, args, , | 156 DEFUN_TEXT (dbclear, args, , |
150 "-*- texinfo -*-\n\ | 157 "-*- texinfo -*-\n\ |
151 @deftypefn {Loadable Function} {} dbg_delete (func, line)\n\ | 158 @deftypefn {Loadable Function} {} dbclear (func, line)\n\ |
152 Delete a breakpoint in a function\n\ | 159 Delete a breakpoint in a function\n\ |
153 @table @code\n\ | 160 @table @code\n\ |
154 @item func\n\ | 161 @item func\n\ |
155 String representing the function name. When already in debug\n\ | 162 String representing the function name. When already in debug\n\ |
156 mode this should be left out and only the line should be given.\n\ | 163 mode this should be left out and only the line should be given.\n\ |
158 Line where you would like to remove the the breakpoint\n\ | 165 Line where you would like to remove the the breakpoint\n\ |
159 @end table\n\ | 166 @end table\n\ |
160 No checking is done to make sure that the line you requested is really\n\ | 167 No checking is done to make sure that the line you requested is really\n\ |
161 a breakpoint. If you get the wrong line nothing will happen.\n\ | 168 a breakpoint. If you get the wrong line nothing will happen.\n\ |
162 @end deftypefn\n\ | 169 @end deftypefn\n\ |
163 @seealso{dbg_set, dbg_list, dbg_where}") | 170 @seealso{dbstop, dbstatus, dbwhere}") |
164 { | 171 { |
165 octave_value retval; | 172 octave_value retval; |
166 | 173 |
167 std::string symbol_name = ""; | 174 std::string symbol_name = ""; |
168 | 175 std::string line_number; |
169 int line = -1; | 176 int line = -1; |
170 int nargin = args.length (); | 177 int nargin = args.length (); |
171 | 178 |
172 if (nargin != 1 && nargin != 2) | 179 if (nargin != 1 && nargin != 2) |
173 { | 180 { |
174 error ("need one or two arguements\n"); | 181 error ("need one or two arguements\n"); |
175 return retval; | 182 return retval; |
176 } | 183 } |
177 | 184 |
178 string_vector argv = args.make_argv ("dbg_delete"); | 185 string_vector argv = args.make_argv ("dbclear"); |
179 | 186 |
180 if (error_state) | 187 if (error_state) |
181 return retval; | 188 return retval; |
182 | 189 |
183 if (nargin == 2) | 190 if (nargin == 2) |
184 { | 191 { |
185 octave_stdout << "2 input arguments\n"; | 192 octave_stdout << "2 input arguments\n"; |
186 symbol_name = argv[1]; | 193 symbol_name = argv[1]; |
187 | 194 |
188 octave_stdout << argv[1] << std::endl; | 195 octave_stdout << argv[1] << std::endl; |
189 std::string line_number = argv[2]; | 196 line_number = argv[2]; |
190 | 197 |
191 line = atoi (line_number.c_str ()); | |
192 } | 198 } |
193 else if (nargin == 1) | 199 else if (nargin == 1) |
194 { | 200 { |
195 octave_stdout << "1 input argument\n"; | 201 octave_stdout << "1 input argument\n"; |
196 std::string line_number = argv[1]; | 202 line_number = argv[1]; |
197 | |
198 line = atoi (line_number.c_str ()); | |
199 } | 203 } |
200 else | 204 else |
201 { | 205 { |
202 error ("need one or two arguements\n"); | 206 error ("need one or two arguements\n"); |
203 return retval; | 207 return retval; |
204 } | 208 } |
205 | 209 |
210 | |
211 if (line_number.compare("all") && line_number.compare("ALL")) | |
212 line = atoi (line_number.c_str ()); | |
213 else | |
214 line = -1; | |
215 | |
206 octave_stdout << "symbol_name = " << symbol_name << std::endl; | 216 octave_stdout << "symbol_name = " << symbol_name << std::endl; |
207 octave_user_function *dbg_fcn = get_user_function (symbol_name); | 217 octave_user_function *dbg_fcn = get_user_function (symbol_name); |
208 | 218 |
209 if (dbg_fcn) | 219 if (dbg_fcn) |
210 { | 220 { |
215 error ("unable to find the function requested\n"); | 225 error ("unable to find the function requested\n"); |
216 | 226 |
217 return retval; | 227 return retval; |
218 } | 228 } |
219 | 229 |
220 DEFUN_TEXT (dbg_list, args, , | 230 DEFUN_TEXT (dbstatus, args, , |
221 "-*- texinfo -*-\n\ | 231 "-*- texinfo -*-\n\ |
222 @deftypefn {Loadable Function} {lst =} dbg_list ([func])\n\ | 232 @deftypefn {Loadable Function} {lst =} dbstatus ([func])\n\ |
223 Return a vector containing the lines on which a function has \n\ | 233 Return a vector containing the lines on which a function has \n\ |
224 breakpoints set.\n\ | 234 breakpoints set.\n\ |
225 @table @code\n\ | 235 @table @code\n\ |
226 @item func\n\ | 236 @item func\n\ |
227 String representing the function name. When already in debug\n\ | 237 String representing the function name. When already in debug\n\ |
228 mode this should be left out.\n\ | 238 mode this should be left out.\n\ |
229 @end table\n\ | 239 @end table\n\ |
230 @end deftypefn\n\ | 240 @end deftypefn\n\ |
231 @seealso{dbg_delete, dbg_set, dbg_where}") | 241 @seealso{dbclear, dbwhere}") |
232 { | 242 { |
233 octave_value retval; | 243 octave_value retval; |
234 | 244 |
235 int nargin = args.length (); | 245 int nargin = args.length (); |
236 | 246 |
245 if (nargin == 1) | 255 if (nargin == 1) |
246 { | 256 { |
247 if (args(0).is_string ()) | 257 if (args(0).is_string ()) |
248 symbol_name = args(0).string_value (); | 258 symbol_name = args(0).string_value (); |
249 else | 259 else |
250 gripe_wrong_type_arg ("dbg_list", args(0)); | 260 gripe_wrong_type_arg ("dbstatus", args(0)); |
251 } | 261 } |
252 | 262 |
253 octave_user_function *dbg_fcn = get_user_function (symbol_name); | 263 octave_user_function *dbg_fcn = get_user_function (symbol_name); |
254 | 264 |
255 if (dbg_fcn) | 265 if (dbg_fcn) |
274 error ("unable to find the function you requested\n"); | 284 error ("unable to find the function you requested\n"); |
275 | 285 |
276 return retval; | 286 return retval; |
277 } | 287 } |
278 | 288 |
279 | 289 DEFUN_TEXT (dbwhere, , , |
280 DEFUN_TEXT (dbg_where, , , | |
281 "-*- texinfo -*-\n\ | 290 "-*- texinfo -*-\n\ |
282 @deftypefn {Loadable Function} {} dbg_where ()\n\ | 291 @deftypefn {Loadable Function} {} dbwhere ()\n\ |
283 Show where we are in the code\n\ | 292 Show where we are in the code\n\ |
284 @end deftypefn\n\ | 293 @end deftypefn\n\ |
285 @seealso{dbg_delete, dbg_list, dbg_set}") | 294 @seealso{dbclear, dbstatus, dbstop}") |
286 { | 295 { |
287 octave_value retval; | 296 octave_value retval; |
288 | 297 |
289 octave_user_function *dbg_fcn = curr_function; | 298 octave_user_function *dbg_fcn = curr_function; |
290 | 299 |
303 } | 312 } |
304 else | 313 else |
305 octave_stdout << "-1\n"; | 314 octave_stdout << "-1\n"; |
306 } | 315 } |
307 else | 316 else |
308 error ("must be inside of a user function to use dbg_where\n"); | 317 error ("must be inside of a user function to use dbwhere\n"); |
318 | |
319 return retval; | |
320 } | |
321 | |
322 // Copied and modified from the do_type command in help.cc | |
323 // Maybe we could share some code? | |
324 void | |
325 do_dbtype(std::ostream& os, const std::string& name, int start, int end) | |
326 { | |
327 std::string ff = fcn_file_in_path (name); | |
328 | |
329 if (! ff.empty ()) | |
330 { | |
331 std::ifstream fs (ff.c_str (), std::ios::in); | |
332 | |
333 if (fs) | |
334 { | |
335 char ch; | |
336 int line = 1; | |
337 | |
338 if (line >= start && line <= end) | |
339 os << line << "\t"; | |
340 | |
341 while (fs.get (ch)) | |
342 { | |
343 if (line >= start && line <= end) | |
344 { | |
345 os << ch; | |
346 } | |
347 | |
348 if (ch == '\n') | |
349 { | |
350 line++; | |
351 if (line >= start && line <= end) | |
352 os << line << "\t"; | |
353 } | |
354 } | |
355 } | |
356 else | |
357 os << "unable to open `" << ff << "' for reading!\n"; | |
358 } | |
359 else | |
360 os << "unkown function"; | |
361 | |
362 } | |
363 | |
364 DEFUN_TEXT (dbtype, args, , | |
365 "-*- texinfo -*-\n\ | |
366 @deftypefn {Loadable Function} {} dbtype ()\n\ | |
367 List script file with line numbers.\n\ | |
368 @end deftypefn\n\ | |
369 @seealso{dbclear, dbstatus, dbstop}") | |
370 { | |
371 octave_value retval; | |
372 octave_user_function *dbg_fcn; | |
373 | |
374 int nargin = args.length (); | |
375 string_vector argv = args.make_argv ("dbtype"); | |
376 | |
377 if (! error_state) | |
378 { | |
379 switch (nargin) | |
380 { | |
381 case 0: // dbtype | |
382 dbg_fcn = get_user_function (); | |
383 | |
384 if (dbg_fcn) | |
385 do_dbtype(octave_stdout,dbg_fcn->function_name (), 0, INT_MAX); | |
386 else | |
387 error("must be in a user function to give no arguments to dbtype\n"); | |
388 | |
389 break; | |
390 case 1: // (dbtype func) || (dbtype start:end) | |
391 dbg_fcn = get_user_function (argv[1].c_str ()); | |
392 | |
393 if (dbg_fcn) | |
394 do_dbtype(octave_stdout,dbg_fcn->function_name (), 0, INT_MAX); | |
395 else | |
396 { | |
397 dbg_fcn = get_user_function (""); | |
398 | |
399 if (dbg_fcn) | |
400 { | |
401 char *str = (char *)malloc(strlen(argv[1].c_str ()) + 1); | |
402 | |
403 if (str) | |
404 memcpy(str, argv[1].c_str (), strlen(argv[1].c_str ()) + 1); | |
405 else | |
406 error("croaked\n"); | |
407 | |
408 char *ind = index(str,':'); | |
409 | |
410 if (ind) | |
411 *ind = '\0'; | |
412 else | |
413 { | |
414 free(str); | |
415 error("if you specify lines it must be like `start:end`"); | |
416 } | |
417 ind++; | |
418 | |
419 int start = atoi(str); | |
420 int end = atoi(ind); | |
421 | |
422 free(str); | |
423 str = NULL; | |
424 ind = NULL; | |
425 | |
426 octave_stdout << "got start and end\n"; | |
427 | |
428 if (start > end) | |
429 error("the start line must be less than the end line\n"); | |
430 | |
431 octave_stdout << "doing dbtype\n"; | |
432 do_dbtype(octave_stdout, dbg_fcn->function_name (), start, end); | |
433 octave_stdout << "did dbtype\n"; | |
434 } | |
435 } | |
436 break; | |
437 case 2: // (dbtype func start:end) | |
438 dbg_fcn = get_user_function (argv[1].c_str ()); | |
439 | |
440 if (dbg_fcn) | |
441 { | |
442 | |
443 char *str = (char *)malloc(strlen(argv[2].c_str ()) + 1); | |
444 | |
445 if (str) | |
446 memcpy(str, argv[2].c_str (), strlen(argv[2].c_str ()) + 1); | |
447 else | |
448 error("not enough memory\n"); | |
449 | |
450 | |
451 char *ind = index(str,':'); | |
452 | |
453 if (ind) | |
454 *ind = '\0'; | |
455 else | |
456 { | |
457 free(str); | |
458 error("if you specify lines it must be like `start:end`"); | |
459 } | |
460 ind++; | |
461 | |
462 int start = atoi(str); | |
463 int end = atoi(ind); | |
464 | |
465 free(str); | |
466 ind = NULL; | |
467 str = NULL; | |
468 | |
469 if (start > end) | |
470 error("the start line must be less than the end line\n"); | |
471 | |
472 do_dbtype(octave_stdout, dbg_fcn->function_name (), start, end); | |
473 } | |
474 | |
475 break; | |
476 default: | |
477 error("unacceptable number of arguments\n"); | |
478 } | |
479 } | |
309 | 480 |
310 return retval; | 481 return retval; |
311 } | 482 } |
312 | 483 |
313 /* | 484 /* |