GNU Octave  4.0.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
debug.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2001-2015 Ben Sapp
4 Copyright (C) 2007-2009 John Swensen
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
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
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
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <deque>
28 #include <fstream>
29 #include <iomanip>
30 #include <iostream>
31 #include <set>
32 #include <string>
33 
34 #include "file-stat.h"
35 #include "singleton-cleanup.h"
36 
37 #include "defun.h"
38 #include "error.h"
39 #include "help.h"
40 #include "input.h"
41 #include "pager.h"
42 #include "octave-link.h"
43 #include "oct-obj.h"
44 #include "utils.h"
45 #include "parse.h"
46 #include "symtab.h"
47 #include "gripes.h"
48 #include "ov.h"
49 #include "ov-usr-fcn.h"
50 #include "ov-fcn.h"
51 #include "ov-struct.h"
52 #include "pt-pr-code.h"
53 #include "pt-bp.h"
54 #include "pt-eval.h"
55 #include "pt-stmt.h"
56 #include "toplev.h"
57 #include "unwind-prot.h"
58 #include "utils.h"
59 #include "variables.h"
60 
61 #include "debug.h"
62 
63 // Initialize the singleton object
65 
66 static std::string
67 snarf_file (const std::string& fname)
68 {
69  std::string retval;
70 
71  file_stat fs (fname);
72 
73  if (fs)
74  {
75  size_t sz = fs.size ();
76 
77  std::ifstream file (fname.c_str (), std::ios::in|std::ios::binary);
78 
79  if (file)
80  {
81  std::string buf (sz+1, 0);
82 
83  file.read (&buf[0], sz+1);
84 
85  if (file.eof ())
86  {
87  // Expected to read the entire file.
88  retval = buf;
89  }
90  else
91  error ("error reading file %s", fname.c_str ());
92  }
93  }
94 
95  return retval;
96 }
97 
98 static std::deque<size_t>
99 get_line_offsets (const std::string& buf)
100 {
101  // This could maybe be smarter. Is deque the right thing to use here?
102 
103  std::deque<size_t> offsets;
104 
105  offsets.push_back (0);
106 
107  size_t len = buf.length ();
108 
109  for (size_t i = 0; i < len; i++)
110  {
111  char c = buf[i];
112 
113  if (c == '\r' && ++i < len)
114  {
115  c = buf[i];
116 
117  if (c == '\n')
118  offsets.push_back (i+1);
119  else
120  offsets.push_back (i);
121  }
122  else if (c == '\n')
123  offsets.push_back (i+1);
124  }
125 
126  offsets.push_back (len);
127 
128  return offsets;
129 }
130 
131 std::string
132 get_file_line (const std::string& fname, size_t line)
133 {
134  std::string retval;
135 
136  static std::string last_fname;
137 
138  static std::string buf;
139 
140  static std::deque<size_t> offsets;
141 
142  if (fname != last_fname)
143  {
144  buf = snarf_file (fname);
145 
146  offsets = get_line_offsets (buf);
147  }
148 
149  if (line > 0)
150  line--;
151 
152  if (line < offsets.size () - 1)
153  {
154  size_t bol = offsets[line];
155  size_t eol = offsets[line+1];
156 
157  while (eol > 0 && eol > bol && (buf[eol-1] == '\n' || buf[eol-1] == '\r'))
158  eol--;
159 
160  retval = buf.substr (bol, eol - bol);
161  }
162 
163  return retval;
164 }
165 
166 // Return a pointer to the user-defined function FNAME. If FNAME is
167 // empty, search backward for the first user-defined function in the
168 // current call stack.
169 
170 static octave_user_code *
171 get_user_code (const std::string& fname = std::string ())
172 {
173  octave_user_code *dbg_fcn = 0;
174 
175  if (fname.empty ())
177  else
178  {
179  std::string name = fname;
180 
181  size_t name_len = name.length ();
182 
183  if (! name.empty () && name_len > 2 && name.substr (name_len-2) == ".m")
184  name = name.substr (0, name_len-2);
185 
187 
188  if (fcn.is_defined () && fcn.is_user_code ())
189  dbg_fcn = fcn.user_code_value ();
190  }
191 
192  return dbg_fcn;
193 }
194 
195 static void
196 parse_dbfunction_params (const char *who, const octave_value_list& args,
197  std::string& symbol_name, bp_table::intmap& lines)
198 {
199  int nargin = args.length ();
200  int idx = 0;
201  int list_idx = 0;
202  symbol_name = std::string ();
203  lines = bp_table::intmap ();
204 
205  if (args.length () == 0)
206  return;
207 
208  if (args(0).is_string ())
209  {
210  // string could be function name or line number
211  int isint = atoi (args(0).string_value ().c_str ());
212 
213  if (error_state)
214  return;
215 
216  if (isint == 0)
217  {
218  // It was a function name
219  symbol_name = args(0).string_value ();
220  if (error_state)
221  return;
222  idx = 1;
223  }
224  else
225  {
226  // It was a line number. Need to get function name from debugger.
227  if (Vdebugging)
228  {
229  symbol_name = get_user_code ()->name ();
230  idx = 0;
231  }
232  else
233  {
234  error ("%s: no function specified", who);
235  }
236  }
237  }
238  else if (args(0).is_map ())
239  {
240  // This is a problem because parse_dbfunction_params()
241  // can only pass out a single function.
242  error ("%s: struct input not implemented", who);
243  return;
244  }
245  else
246  error ("%s: invalid parameter specified", who);
247 
248  for (int i = idx; i < nargin; i++)
249  {
250  if (args(i).is_string ())
251  {
252  int line = atoi (args(i).string_value ().c_str ());
253  if (error_state)
254  break;
255  lines[list_idx++] = line;
256  }
257  else if (args(i).is_map ())
258  octave_stdout << who << ": skipping struct input" << std::endl;
259  else
260  {
261  const NDArray arg = args(i).array_value ();
262 
263  if (error_state)
264  break;
265 
266  for (octave_idx_type j = 0; j < arg.nelem (); j++)
267  {
268  int line = static_cast<int> (arg.elem (j));
269  if (error_state)
270  break;
271  lines[list_idx++] = line;
272  }
273 
274  if (error_state)
275  break;
276  }
277  }
278 }
279 
280 bool
282 {
283  bool retval = true;
284 
285  if (! instance)
286  {
287  instance = new bp_table ();
288 
289  if (instance)
291  }
292 
293  if (! instance)
294  {
295  ::error ("unable to create breakpoint table!");
296  retval = false;
297  }
298 
299  return retval;
300 }
301 
302 bool
304  const std::string& fname,
305  const bp_table::intmap& line,
306  bp_table::intmap& retval)
307 {
308  bool found = false;
309 
310  tree_statement_list *cmds = fcn->body ();
311 
312  std::string file = fcn->fcn_file_name ();
313 
314  if (cmds)
315  {
316  retval = cmds->add_breakpoint (file, line);
317 
318  for (intmap_iterator p = retval.begin (); p != retval.end (); p++)
319  {
320  if (p->second != 0)
321  {
322  bp_set.insert (fname);
323  found = true;
324  break;
325  }
326  }
327  }
328 
329  return found;
330 }
331 
333 bp_table::do_add_breakpoint (const std::string& fname,
334  const bp_table::intmap& line)
335 {
336  intmap retval;
337 
338  octave_user_code *dbg_fcn = get_user_code (fname);
339 
340  if (dbg_fcn)
341  {
342  if (! do_add_breakpoint_1 (dbg_fcn, fname, line, retval))
343  {
344  // Search subfunctions in the order they appear in the file.
345 
346  const std::list<std::string> subfcn_names
347  = dbg_fcn->subfunction_names ();
348 
349  std::map<std::string, octave_value> subfcns
350  = dbg_fcn->subfunctions ();
351 
352  for (std::list<std::string>::const_iterator p = subfcn_names.begin ();
353  p != subfcn_names.end (); p++)
354  {
355  std::map<std::string, octave_value>::const_iterator
356  q = subfcns.find (*p);
357 
358  if (q != subfcns.end ())
359  {
360  octave_user_code *dbg_subfcn = q->second.user_code_value ();
361 
362  if (do_add_breakpoint_1 (dbg_subfcn, fname, line, retval))
363  break;
364  }
365  }
366  }
367  }
368  else
369  error ("add_breakpoint: unable to find the requested function\n");
370 
372 
373  return retval;
374 }
375 
376 int
378  const std::string& fname,
379  const bp_table::intmap& line)
380 {
381  int retval = 0;
382 
383  std::string file = fcn->fcn_file_name ();
384 
385  tree_statement_list *cmds = fcn->body ();
386 
387  // FIXME: move the operation on cmds to the tree_statement_list class?
388 
389  if (cmds)
390  {
391  octave_value_list results = cmds->list_breakpoints ();
392 
393  if (results.length () > 0)
394  {
395  octave_idx_type len = line.size ();
396 
397  for (int i = 0; i < len; i++)
398  {
399  const_intmap_iterator p = line.find (i);
400 
401  if (p != line.end ())
402  {
403  int lineno = p->second;
404 
405  cmds->delete_breakpoint (lineno);
406 
407  if (! file.empty ())
408  octave_link::update_breakpoint (false, file, lineno);
409  }
410  }
411 
412  results = cmds->list_breakpoints ();
413 
414  bp_set_iterator it = bp_set.find (fname);
415  if (results.length () == 0 && it != bp_set.end ())
416  bp_set.erase (it);
417  }
418 
419  retval = results.length ();
420  }
421 
422  return retval;
423 }
424 
425 int
426 bp_table::do_remove_breakpoint (const std::string& fname,
427  const bp_table::intmap& line)
428 {
429  int retval = 0;
430 
431  octave_idx_type len = line.size ();
432 
433  if (len == 0)
434  {
435  intmap results = remove_all_breakpoints_in_file (fname);
436  retval = results.size ();
437  }
438  else
439  {
440  octave_user_code *dbg_fcn = get_user_code (fname);
441 
442  if (dbg_fcn)
443  {
444  retval = do_remove_breakpoint_1 (dbg_fcn, fname, line);
445 
446  // Search subfunctions in the order they appear in the file.
447 
448  const std::list<std::string> subfcn_names
449  = dbg_fcn->subfunction_names ();
450 
451  std::map<std::string, octave_value> subfcns
452  = dbg_fcn->subfunctions ();
453 
454  for (std::list<std::string>::const_iterator p = subfcn_names.begin ();
455  p != subfcn_names.end (); p++)
456  {
457  std::map<std::string, octave_value>::const_iterator
458  q = subfcns.find (*p);
459 
460  if (q != subfcns.end ())
461  {
462  octave_user_code *dbg_subfcn = q->second.user_code_value ();
463 
464  retval += do_remove_breakpoint_1 (dbg_subfcn, fname, line);
465  }
466  }
467  }
468  else
469  error ("remove_breakpoint: unable to find the requested function\n");
470  }
471 
473 
474  return retval;
475 }
476 
479  const std::string& fname)
480 {
481  intmap retval;
482 
483  std::string file = fcn->fcn_file_name ();
484 
485  tree_statement_list *cmds = fcn->body ();
486 
487  if (cmds)
488  {
489  retval = cmds->remove_all_breakpoints (file);
490 
491  bp_set_iterator it = bp_set.find (fname);
492  if (it != bp_set.end ())
493  bp_set.erase (it);
494  }
495 
496  return retval;
497 }
498 
501  bool silent)
502 {
503  intmap retval;
504 
505  octave_user_code *dbg_fcn = get_user_code (fname);
506 
507  if (dbg_fcn)
508  {
509  retval = do_remove_all_breakpoints_in_file_1 (dbg_fcn, fname);
510 
511  // Order is not important here.
512 
513  typedef std::map<std::string, octave_value>::const_iterator
514  subfcns_const_iterator;
515 
516  std::map<std::string, octave_value> subfcns = dbg_fcn->subfunctions ();
517 
518  for (subfcns_const_iterator p = subfcns.begin ();
519  p != subfcns.end (); p++)
520  {
521  octave_user_code *dbg_subfcn = p->second.user_code_value ();
522 
523  intmap tmp = do_remove_all_breakpoints_in_file_1 (dbg_subfcn, fname);
524 
525  // Merge new list with retval.
526  retval.insert (tmp.begin (), tmp.end ());
527  }
528  }
529  else if (! silent)
530  error ("remove_all_breakpoint_in_file: "
531  "unable to find the requested function\n");
532 
534 
535  return retval;
536 }
537 
538 void
540 {
541  // Odd loop structure required because delete will invalidate bp_set iterators
542  for (const_bp_set_iterator it=bp_set.begin (), it_next=it;
543  it != bp_set.end ();
544  it=it_next)
545  {
546  ++it_next;
548  }
549 
551 }
552 
553 std::string
555  std::string match)
556 {
557  std::string retval;
558 
559  for (int i = 0; i < slist.length (); i++)
560  {
561  if (slist(i).string_value () == match)
562  {
563  retval = slist(i).string_value ();
564  break;
565  }
566  }
567 
568  return retval;
569 }
570 
573 {
574  fname_line_map retval;
575 
576  for (bp_set_iterator it = bp_set.begin (); it != bp_set.end (); it++)
577  {
578  if (fname_list.length () == 0
579  || do_find_bkpt_list (fname_list, *it) != "")
580  {
582 
583  if (f)
584  {
585  tree_statement_list *cmds = f->body ();
586 
587  // FIXME: move the operation on cmds to the
588  // tree_statement_list class?
589  if (cmds)
590  {
591  octave_value_list bkpts = cmds->list_breakpoints ();
592  octave_idx_type len = bkpts.length ();
593 
594  if (len > 0)
595  {
596  bp_table::intmap bkpts_vec;
597 
598  for (int i = 0; i < len; i++)
599  bkpts_vec[i] = bkpts(i).double_value ();
600 
601  std::string symbol_name = f->name ();
602 
603  retval[symbol_name] = bkpts_vec;
604  }
605  }
606  }
607  }
608  }
609 
610  return retval;
611 }
612 
613 static octave_value
615 {
616  int idx = 0;
617 
618  NDArray retval (dim_vector (1, line.size ()));
619 
620  for (size_t i = 0; i < line.size (); i++)
621  {
622  bp_table::const_intmap_iterator p = line.find (i);
623 
624  if (p != line.end ())
625  {
626  int lineno = p->second;
627  retval(idx++) = lineno;
628  }
629  }
630 
631  retval.resize (dim_vector (1, idx));
632 
633  return retval;
634 }
635 
636 DEFUN (dbstop, args, ,
637  "-*- texinfo -*-\n\
638 @deftypefn {Command} {} dbstop @var{func}\n\
639 @deftypefnx {Command} {} dbstop @var{func} @var{line}\n\
640 @deftypefnx {Command} {} dbstop @var{func} @var{line1} @var{line2} @dots{}\n\
641 @deftypefnx {Command} {} dbstop @var{line} @dots{}\n\
642 @deftypefnx {Built-in Function} {@var{rline} =} dbstop (\"@var{func}\")\n\
643 @deftypefnx {Built-in Function} {@var{rline} =} dbstop (\"@var{func}\", @var{line})\n\
644 @deftypefnx {Built-in Function} {@var{rline} =} dbstop (\"@var{func}\", @var{line1}, @var{line2}, @dots{})\n\
645 @deftypefnx {Built-in Function} {} dbstop (\"@var{func}\", [@var{line1}, @dots{}])\n\
646 @deftypefnx {Built-in Function} {} dbstop (@var{line}, @dots{})\n\
647 Set a breakpoint at line number @var{line} in function @var{func}.\n\
648 \n\
649 Arguments are\n\
650 \n\
651 @table @var\n\
652 @item func\n\
653 Function name as a string variable. When already in debug mode this argument\n\
654 can be omitted and the current function will be used.\n\
655 \n\
656 @item line\n\
657 Line number where the breakpoint should be set. Multiple lines may be given\n\
658 as separate arguments or as a vector.\n\
659 @end table\n\
660 \n\
661 When called with a single argument @var{func}, the breakpoint is set at the\n\
662 first executable line in the named function.\n\
663 \n\
664 The optional output @var{rline} is the real line number where the breakpoint\n\
665 was set. This can differ from the specified line if the line is not\n\
666 executable. For example, if a breakpoint attempted on a blank line then\n\
667 Octave will set the real breakpoint at the next executable line.\n\
668 @seealso{dbclear, dbstatus, dbstep, debug_on_error, debug_on_warning, debug_on_interrupt}\n\
669 @end deftypefn")
670 {
671  bp_table::intmap retval;
672  std::string symbol_name;
673  bp_table::intmap lines;
674 
675  parse_dbfunction_params ("dbstop", args, symbol_name, lines);
676 
677  if (lines.size () == 0)
678  lines[0] = 1;
679 
680  if (! error_state)
681  retval = bp_table::add_breakpoint (symbol_name, lines);
682 
683  return intmap_to_ov (retval);
684 }
685 
686 DEFUN (dbclear, args, ,
687  "-*- texinfo -*-\n\
688 @deftypefn {Command} {} dbclear @var{func}\n\
689 @deftypefnx {Command} {} dbclear @var{func} @var{line}\n\
690 @deftypefnx {Command} {} dbclear @var{func} @var{line1} @var{line2} @dots{}\n\
691 @deftypefnx {Command} {} dbclear @var{line} @dots{}\n\
692 @deftypefnx {Command} {} dbclear all\n\
693 @deftypefnx {Built-in Function} {} dbclear (\"@var{func}\")\n\
694 @deftypefnx {Built-in Function} {} dbclear (\"@var{func}\", @var{line})\n\
695 @deftypefnx {Built-in Function} {} dbclear (\"@var{func}\", @var{line1}, @var{line2}, @dots{})\n\
696 @deftypefnx {Built-in Function} {} dbclear (\"@var{func}\", [@var{line1}, @dots{}])\n\
697 @deftypefnx {Built-in Function} {} dbclear (@var{line}, @dots{})\n\
698 @deftypefnx {Built-in Function} {} dbclear (\"all\")\n\
699 Delete a breakpoint at line number @var{line} in the function @var{func}.\n\
700 \n\
701 Arguments are\n\
702 \n\
703 @table @var\n\
704 @item func\n\
705 Function name as a string variable. When already in debug mode this argument\n\
706 can be omitted and the current function will be used.\n\
707 \n\
708 @item line\n\
709 Line number from which to remove a breakpoint. Multiple lines may be given\n\
710 as separate arguments or as a vector.\n\
711 @end table\n\
712 \n\
713 When called without a line number specification all breakpoints in the named\n\
714 function are cleared.\n\
715 \n\
716 If the requested line is not a breakpoint no action is performed.\n\
717 \n\
718 The special keyword @qcode{\"all\"} will clear all breakpoints from all\n\
719 files.\n\
720 @seealso{dbstop, dbstatus, dbwhere}\n\
721 @end deftypefn")
722 {
723  octave_value retval;
724  std::string symbol_name = "";
725  bp_table::intmap lines;
726 
727  int nargin = args.length ();
728 
729  parse_dbfunction_params ("dbclear", args, symbol_name, lines);
730 
731  if (nargin == 1 && symbol_name == "all")
733  else
734  {
735  if (! error_state)
736  bp_table::remove_breakpoint (symbol_name, lines);
737  }
738 
739  return retval;
740 }
741 
742 DEFUN (dbstatus, args, nargout,
743  "-*- texinfo -*-\n\
744 @deftypefn {Built-in Function} {} dbstatus ()\n\
745 @deftypefnx {Built-in Function} {@var{brk_list} =} dbstatus ()\n\
746 @deftypefnx {Built-in Function} {@var{brk_list} =} dbstatus (\"@var{func}\")\n\
747 Report the location of active breakpoints.\n\
748 \n\
749 When called with no input or output arguments, print the list of all\n\
750 functions with breakpoints and the line numbers where those breakpoints are\n\
751 set.\n\
752 \n\
753 If a function name @var{func} is specified then only report breakpoints\n\
754 for the named function.\n\
755 \n\
756 The optional return argument @var{brk_list} is a struct array with the\n\
757 following fields.\n\
758 \n\
759 @table @asis\n\
760 @item name\n\
761 The name of the function with a breakpoint.\n\
762 \n\
763 @item file\n\
764 The name of the m-file where the function code is located.\n\
765 \n\
766 @item line\n\
767 A line number, or vector of line numbers, with a breakpoint.\n\
768 @end table\n\
769 \n\
770 Note: When @code{dbstatus} is called from the debug prompt within a function,\n\
771 the list of breakpoints is automatically trimmed to the breakpoints in the\n\
772 current function.\n\
773 @seealso{dbclear, dbwhere}\n\
774 @end deftypefn")
775 {
776  octave_map retval;
777  int nargin = args.length ();
778  octave_value_list fcn_list;
779  bp_table::fname_line_map bp_list;
780  std::string symbol_name;
781 
782  if (nargin != 0 && nargin != 1)
783  {
784  error ("dbstatus: only zero or one arguments accepted\n");
785  return octave_value ();
786  }
787 
788  if (nargin == 1)
789  {
790  if (args(0).is_string ())
791  {
792  symbol_name = args(0).string_value ();
793  fcn_list(0) = symbol_name;
794  bp_list = bp_table::get_breakpoint_list (fcn_list);
795  }
796  else
797  gripe_wrong_type_arg ("dbstatus", args(0));
798  }
799  else
800  {
801  if (Vdebugging)
802  {
803  octave_user_code *dbg_fcn = get_user_code ();
804  if (dbg_fcn)
805  {
806  symbol_name = dbg_fcn->name ();
807  fcn_list(0) = symbol_name;
808  }
809  }
810 
811  bp_list = bp_table::get_breakpoint_list (fcn_list);
812  }
813 
814  if (nargout == 0)
815  {
816  // Print out the breakpoint information.
817 
818  for (bp_table::fname_line_map_iterator it = bp_list.begin ();
819  it != bp_list.end (); it++)
820  {
821  bp_table::intmap m = it->second;
822 
823  size_t nel = m.size ();
824 
825  octave_stdout << "breakpoint in " << it->first;
826  if (nel > 1)
827  octave_stdout << " at lines ";
828  else
829  octave_stdout << " at line ";
830 
831  for (size_t j = 0; j < nel; j++)
832  octave_stdout << m[j] << ((j < nel - 1) ? ", " : ".");
833 
834  if (nel > 0)
835  octave_stdout << std::endl;
836  }
837  return octave_value ();
838  }
839  else
840  {
841  // Fill in an array for return.
842 
843  int i = 0;
844  Cell names (dim_vector (bp_list.size (), 1));
845  Cell file (dim_vector (bp_list.size (), 1));
846  Cell line (dim_vector (bp_list.size (), 1));
847 
848  for (bp_table::const_fname_line_map_iterator it = bp_list.begin ();
849  it != bp_list.end (); it++)
850  {
851  names(i) = it->first;
852  line(i) = intmap_to_ov (it->second);
853  file(i) = do_which (it->first);
854  i++;
855  }
856 
857  retval.assign ("name", names);
858  retval.assign ("file", file);
859  retval.assign ("line", line);
860 
861  return octave_value (retval);
862  }
863 }
864 
865 DEFUN (dbwhere, , ,
866  "-*- texinfo -*-\n\
867 @deftypefn {Command} {} dbwhere\n\
868 In debugging mode, report the current file and line number where execution\n\
869 is stopped.\n\
870 @seealso{dbstatus, dbcont, dbstep, dbup}\n\
871 @end deftypefn")
872 {
873  octave_value retval;
874 
875  octave_user_code *dbg_fcn = get_user_code ();
876 
877  if (dbg_fcn)
878  {
879  bool have_file = true;
880 
881  std::string name = dbg_fcn->fcn_file_name ();
882 
883  if (name.empty ())
884  {
885  have_file = false;
886 
887  name = dbg_fcn->name ();
888  }
889 
890  octave_stdout << "stopped in " << name << " at ";
891 
893 
894  if (l > 0)
895  {
896  octave_stdout << "line " << l << std::endl;
897 
898  if (have_file)
899  {
900  std::string line = get_file_line (name, l);
901 
902  if (! line.empty ())
903  octave_stdout << l << ": " << line << std::endl;
904  }
905  }
906  else
907  octave_stdout << "<unknown line>" << std::endl;
908  }
909  else
910  error ("dbwhere: must be inside a user function to use dbwhere\n");
911 
912  return retval;
913 }
914 
915 void
916 do_dbtype (std::ostream& os, const std::string& name, int start, int end)
917 {
918  std::string ff = fcn_file_in_path (name);
919 
920  if (! ff.empty ())
921  {
922  std::ifstream fs (ff.c_str (), std::ios::in);
923 
924  if (fs)
925  {
926  int line = 1;
927  std::string text;
928 
929  while (std::getline (fs, text) && line <= end)
930  {
931  if (line >= start)
932  os << line << "\t" << text << "\n";
933 
934  line++;
935  }
936  }
937  else
938  os << "dbtype: unable to open '" << ff << "' for reading!\n";
939  }
940  else
941  os << "dbtype: unknown function " << name << "\n";
942 
943  os.flush ();
944 }
945 
946 DEFUN (dbtype, args, ,
947  "-*- texinfo -*-\n\
948 @deftypefn {Command} {} dbtype\n\
949 @deftypefnx {Command} {} dbtype @var{lineno}\n\
950 @deftypefnx {Command} {} dbtype @var{startl:endl}\n\
951 @deftypefnx {Command} {} dbtype @var{startl:end}\n\
952 @deftypefnx {Command} {} dbtype @var{func}\n\
953 @deftypefnx {Command} {} dbtype @var{func} @var{lineno}\n\
954 @deftypefnx {Command} {} dbtype @var{func} @var{startl:endl}\n\
955 @deftypefnx {Command} {} dbtype @var{func} @var{startl:end}\n\
956 Display a script file with line numbers.\n\
957 \n\
958 When called with no arguments in debugging mode, display the script file\n\
959 currently being debugged.\n\
960 \n\
961 An optional range specification can be used to list only a portion of the\n\
962 file. The special keyword @qcode{\"end\"} is a valid line number\n\
963 specification for the last line of the file.\n\
964 \n\
965 When called with the name of a function, list that script file with line\n\
966 numbers.\n\
967 @seealso{dbwhere, dbstatus, dbstop}\n\
968 @end deftypefn")
969 {
970  octave_value retval;
971  octave_user_code *dbg_fcn;
972 
973  int nargin = args.length ();
974  string_vector argv = args.make_argv ("dbtype");
975 
976  if (! error_state)
977  {
978  switch (nargin)
979  {
980  case 0: // dbtype
981  dbg_fcn = get_user_code ();
982 
983  if (dbg_fcn)
984  do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (),
986  else
987  error ("dbtype: must be inside a user function to give no arguments to dbtype\n");
988 
989  break;
990 
991  case 1: // (dbtype start:end) || (dbtype func) || (dbtype lineno)
992  {
993  std::string arg = argv[1];
994 
995  size_t ind = arg.find (':');
996 
997  if (ind != std::string::npos) // (dbtype start:end)
998  {
999  dbg_fcn = get_user_code ();
1000 
1001  if (dbg_fcn)
1002  {
1003  std::string start_str = arg.substr (0, ind);
1004  std::string end_str = arg.substr (ind + 1);
1005 
1006  int start, end;
1007  start = atoi (start_str.c_str ());
1008  if (end_str == "end")
1010  else
1011  end = atoi (end_str.c_str ());
1012 
1013  if (std::min (start, end) <= 0)
1014  {
1015  error ("dbtype: start and end lines must be >= 1\n");
1016  break;
1017  }
1018 
1019  if (start <= end)
1020  do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (),
1021  start, end);
1022  else
1023  error ("dbtype: start line must be less than end line\n");
1024  }
1025  }
1026  else // (dbtype func) || (dbtype lineno)
1027  {
1028  int line = atoi (arg.c_str ());
1029 
1030  if (line == 0) // (dbtype func)
1031  {
1032  dbg_fcn = get_user_code (arg);
1033 
1034  if (dbg_fcn)
1035  do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (),
1037  else
1038  error ("dbtype: function <%s> not found\n", arg.c_str ());
1039  }
1040  else // (dbtype lineno)
1041  {
1042  if (line <= 0)
1043  {
1044  error ("dbtype: start and end lines must be >= 1\n");
1045  break;
1046  }
1047 
1048  dbg_fcn = get_user_code ();
1049 
1050  if (dbg_fcn)
1051  do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (),
1052  line, line);
1053  }
1054  }
1055  }
1056  break;
1057 
1058  case 2: // (dbtype func start:end) || (dbtype func start)
1059  dbg_fcn = get_user_code (argv[1]);
1060 
1061  if (dbg_fcn)
1062  {
1063  std::string arg = argv[2];
1064  int start, end;
1065  size_t ind = arg.find (':');
1066 
1067  if (ind != std::string::npos)
1068  {
1069  std::string start_str = arg.substr (0, ind);
1070  std::string end_str = arg.substr (ind + 1);
1071 
1072  start = atoi (start_str.c_str ());
1073  if (end_str == "end")
1075  else
1076  end = atoi (end_str.c_str ());
1077  }
1078  else
1079  {
1080  start = atoi (arg.c_str ());
1081  end = start;
1082  }
1083 
1084  if (std::min (start, end) <= 0)
1085  {
1086  error ("dbtype: start and end lines must be >= 1\n");
1087  break;
1088  }
1089 
1090  if (start <= end)
1091  do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (),
1092  start, end);
1093  else
1094  error ("dbtype: start line must be less than end line\n");
1095  }
1096  else
1097  error ("dbtype: function <%s> not found\n", argv[1].c_str ());
1098 
1099  break;
1100 
1101  default:
1102  error ("dbtype: expecting zero, one, or two arguments\n");
1103  }
1104  }
1105 
1106  return retval;
1107 }
1108 
1109 DEFUN (dblist, args, ,
1110  "-*- texinfo -*-\n\
1111 @deftypefn {Command} {} dblist\n\
1112 @deftypefnx {Command} {} dblist @var{n}\n\
1113 In debugging mode, list @var{n} lines of the function being debugged\n\
1114 centered around the current line to be executed.\n\
1115 \n\
1116 If unspecified @var{n} defaults to 10 (+/- 5 lines)\n\
1117 @seealso{dbwhere, dbtype}\n\
1118 @end deftypefn")
1119 {
1120  octave_value retval;
1121 
1122  int n = 10;
1123 
1124  if (args.length () == 1)
1125  {
1126  octave_value arg = args(0);
1127 
1128  if (arg.is_string ())
1129  {
1130  std::string s_arg = arg.string_value ();
1131 
1132  n = atoi (s_arg.c_str ());
1133  }
1134  else
1135  n = args(0).int_value ();
1136 
1137  if (n < 0)
1138  error ("dblist: N must be a non-negative integer");
1139  }
1140 
1141  octave_user_code *dbg_fcn = get_user_code ();
1142 
1143  if (dbg_fcn)
1144  {
1145  bool have_file = true;
1146 
1147  std::string name = dbg_fcn->fcn_file_name ();
1148 
1149  if (name.empty ())
1150  {
1151  have_file = false;
1152  name = dbg_fcn->name ();
1153  }
1154 
1156 
1157  if (l > 0)
1158  {
1159  if (have_file)
1160  {
1161  int l_min = std::max (l - n/2, 0);
1162  int l_max = l + n/2;
1163  do_dbtype (octave_stdout, name, l_min, l-1);
1164 
1165  std::string line = get_file_line (name, l);
1166  if (! line.empty ())
1167  octave_stdout << l << "-->\t" << line << std::endl;
1168 
1169  do_dbtype (octave_stdout, name, l+1, l_max);
1170  }
1171  }
1172  else
1173  {
1174  octave_stdout << "dblist: unable to determine source code line"
1175  << std::endl;
1176  }
1177  }
1178  else
1179  error ("dblist: must be inside a user function to use dblist\n");
1180 
1181  return retval;
1182 }
1183 
1184 static octave_value_list
1185 do_dbstack (const octave_value_list& args, int nargout, std::ostream& os)
1186 {
1187  octave_value_list retval;
1188 
1189  unwind_protect frame;
1190 
1191  octave_idx_type curr_frame = -1;
1192 
1193  size_t nskip = 0;
1194 
1195  octave_idx_type len = args.length ();
1196 
1197  // dbstack accepts up to 2 arguments.
1198 
1199  if (len == 1 || len == 2)
1200  {
1201  int n = 0;
1202 
1203  for (octave_idx_type i = 0; i < len && ! error_state; i++)
1204  {
1205  octave_value arg = args(i);
1206 
1207  if (arg.is_string ())
1208  {
1209  std::string s_arg = arg.string_value ();
1210 
1211  // Skip "-completenames", octave returns full names anyway.
1212 
1213  if (s_arg == "-completenames")
1214  continue;
1215 
1216  n = atoi (s_arg.c_str ());
1217  }
1218  else
1219  n = arg.int_value ();
1220 
1221  if (! error_state && n <= 0)
1222  error ("dbstack: N must be a non-negative integer");
1223  }
1224 
1225  if (n > 0)
1226  nskip = n;
1227  }
1228  else if (len)
1229  print_usage ();
1230 
1231  if (! error_state)
1232  {
1233  if (nargout == 0)
1234  {
1235  octave_map stk = octave_call_stack::backtrace (nskip, curr_frame);
1236  octave_idx_type nframes_to_display = stk.numel ();
1237 
1238  if (nframes_to_display > 0)
1239  {
1240  octave_preserve_stream_state stream_state (os);
1241 
1242  os << "stopped in:\n\n";
1243 
1244  Cell names = stk.contents ("name");
1245  Cell files = stk.contents ("file");
1246  Cell lines = stk.contents ("line");
1247 
1248  bool show_top_level = true;
1249 
1250  size_t max_name_len = 0;
1251 
1252  for (octave_idx_type i = 0; i < nframes_to_display; i++)
1253  {
1254  std::string name = names(i).string_value ();
1255 
1256  max_name_len = std::max (name.length (), max_name_len);
1257  }
1258 
1259  for (octave_idx_type i = 0; i < nframes_to_display; i++)
1260  {
1261  std::string name = names(i).string_value ();
1262  std::string file = files(i).string_value ();
1263  int line = lines(i).int_value ();
1264 
1265  if (show_top_level && i == curr_frame)
1266  show_top_level = false;
1267 
1268  os << (i == curr_frame ? " --> " : " ")
1269  << std::setw (max_name_len) << name
1270  << " at line " << line
1271  << " [" << file << "]"
1272  << std::endl;
1273  }
1274 
1275  if (show_top_level)
1276  os << " --> top level" << std::endl;
1277  }
1278  }
1279  else
1280  {
1282  curr_frame,
1283  false);
1284 
1285  retval(1) = curr_frame < 0 ? 1 : curr_frame + 1;
1286  retval(0) = stk;
1287  }
1288  }
1289 
1290  return retval;
1291 }
1292 
1293 // A function that can be easily called from a debugger print the Octave
1294 // stack. This can be useful for finding what line of code the
1295 // interpreter is currently executing when the debugger is stopped in
1296 // some C++ function, for example.
1297 
1298 void
1300 {
1301  do_dbstack (octave_value_list (), 0, std::cerr);
1302 }
1303 
1304 DEFUN (dbstack, args, nargout,
1305  "-*- texinfo -*-\n\
1306 @deftypefn {Command} {} dbstack\n\
1307 @deftypefnx {Command} {} dbstack @var{n}\n\
1308 @deftypefnx {Command} {} dbstack @var{-completenames}\n\
1309 @deftypefnx {Built-in Function} {[@var{stack}, @var{idx}] =} dbstack (@dots{})\n\
1310 Display or return current debugging function stack information.\n\
1311 \n\
1312 With optional argument @var{n}, omit the @var{n} innermost stack frames.\n\
1313 \n\
1314 Although accepted, the argument @var{-completenames} is silently ignored.\n\
1315 Octave always returns absolute file names.\n\
1316 \n\
1317 The arguments @var{n} and @var{-completenames} can be both specified in any\n\
1318 order.\n\
1319 \n\
1320 The optional return argument @var{stack} is a struct array with the\n\
1321 following fields:\n\
1322 \n\
1323 @table @asis\n\
1324 @item file\n\
1325 The name of the m-file where the function code is located.\n\
1326 \n\
1327 @item name\n\
1328 The name of the function with a breakpoint.\n\
1329 \n\
1330 @item line\n\
1331 The line number of an active breakpoint.\n\
1332 \n\
1333 @item column\n\
1334 The column number of the line where the breakpoint begins.\n\
1335 \n\
1336 @item scope\n\
1337 Undocumented.\n\
1338 \n\
1339 @item context\n\
1340 Undocumented.\n\
1341 @end table\n\
1342 \n\
1343 The return argument @var{idx} specifies which element of the @var{stack}\n\
1344 struct array is currently active.\n\
1345 @seealso{dbup, dbdown, dbwhere, dbstatus}\n\
1346 @end deftypefn")
1347 {
1348  return do_dbstack (args, nargout, octave_stdout);
1349 }
1350 
1351 static void
1352 do_dbupdown (const octave_value_list& args, const std::string& who)
1353 {
1354  int n = 1;
1355 
1356  if (args.length () == 1)
1357  {
1358  octave_value arg = args(0);
1359 
1360  if (arg.is_string ())
1361  {
1362  std::string s_arg = arg.string_value ();
1363 
1364  n = atoi (s_arg.c_str ());
1365  }
1366  else
1367  n = args(0).int_value ();
1368  }
1369 
1370  if (! error_state)
1371  {
1372  if (who == "dbup")
1373  n = -n;
1374 
1376  error ("%s: invalid stack frame", who.c_str ());
1377  }
1378 }
1379 
1380 DEFUN (dbup, args, ,
1381  "-*- texinfo -*-\n\
1382 @deftypefn {Command} {} dbup\n\
1383 @deftypefnx {Command} {} dbup @var{n}\n\
1384 In debugging mode, move up the execution stack @var{n} frames.\n\
1385 \n\
1386 If @var{n} is omitted, move up one frame.\n\
1387 @seealso{dbstack, dbdown}\n\
1388 @end deftypefn")
1389 {
1390  octave_value retval;
1391 
1392  do_dbupdown (args, "dbup");
1393 
1394  return retval;
1395 }
1396 
1397 DEFUN (dbdown, args, ,
1398  "-*- texinfo -*-\n\
1399 @deftypefn {Command} {} dbdown\n\
1400 @deftypefnx {Command} {} dbdown @var{n}\n\
1401 In debugging mode, move down the execution stack @var{n} frames.\n\
1402 \n\
1403 If @var{n} is omitted, move down one frame.\n\
1404 @seealso{dbstack, dbup}\n\
1405 @end deftypefn")
1406 {
1407  octave_value retval;
1408 
1409  do_dbupdown (args, "dbdown");
1410 
1411  return retval;
1412 }
1413 
1414 DEFUN (dbstep, args, ,
1415  "-*- texinfo -*-\n\
1416 @deftypefn {Command} {} dbstep\n\
1417 @deftypefnx {Command} {} dbstep @var{n}\n\
1418 @deftypefnx {Command} {} dbstep in\n\
1419 @deftypefnx {Command} {} dbstep out\n\
1420 @deftypefnx {Command} {} dbnext @dots{}\n\
1421 In debugging mode, execute the next @var{n} lines of code.\n\
1422 \n\
1423 If @var{n} is omitted, execute the next single line of code. If the next\n\
1424 line of code is itself defined in terms of an m-file remain in the existing\n\
1425 function.\n\
1426 \n\
1427 Using @code{dbstep in} will cause execution of the next line to step into\n\
1428 any m-files defined on the next line.\n\
1429 \n\
1430 Using @code{dbstep out} will cause execution to continue until the current\n\
1431 function returns.\n\
1432 \n\
1433 @code{dbnext} is an alias for @code{dbstep}.\n\
1434 @seealso{dbcont, dbquit}\n\
1435 @end deftypefn")
1436 {
1437  if (Vdebugging)
1438  {
1439  int nargin = args.length ();
1440 
1441  if (nargin > 1)
1442  print_usage ();
1443  else if (nargin == 1)
1444  {
1445  if (args(0).is_string ())
1446  {
1447  std::string arg = args(0).string_value ();
1448 
1449  if (arg == "in")
1450  {
1451  Vdebugging = false;
1452 
1454  }
1455  else if (arg == "out")
1456  {
1457  Vdebugging = false;
1458 
1460  }
1461  else
1462  {
1463  int n = atoi (arg.c_str ());
1464 
1465  if (n > 0)
1466  {
1467  Vdebugging = false;
1468 
1470  }
1471  else
1472  error ("dbstep: invalid argument");
1473  }
1474  }
1475  else
1476  error ("dbstep: input argument must be a string");
1477  }
1478  else
1479  {
1480  Vdebugging = false;
1481 
1483  }
1484  }
1485  else
1486  error ("dbstep: can only be called in debug mode");
1487 
1488  return octave_value_list ();
1489 }
1490 
1491 DEFALIAS (dbnext, dbstep);
1492 
1493 DEFUN (dbcont, args, ,
1494  "-*- texinfo -*-\n\
1495 @deftypefn {Command} {} dbcont\n\
1496 Leave command-line debugging mode and continue code execution normally.\n\
1497 @seealso{dbstep, dbquit}\n\
1498 @end deftypefn")
1499 {
1500  if (Vdebugging)
1501  {
1502  if (args.length () == 0)
1503  {
1504  Vdebugging = false;
1505 
1507  }
1508  else
1509  print_usage ();
1510  }
1511  else
1512  error ("dbcont: can only be called in debug mode");
1513 
1514  return octave_value_list ();
1515 }
1516 
1517 DEFUN (dbquit, args, ,
1518  "-*- texinfo -*-\n\
1519 @deftypefn {Command} {} dbquit\n\
1520 Quit debugging mode immediately without further code execution and return to\n\
1521 the Octave prompt.\n\
1522 @seealso{dbcont, dbstep}\n\
1523 @end deftypefn")
1524 {
1525  if (Vdebugging)
1526  {
1527  if (args.length () == 0)
1528  {
1529  Vdebugging = false;
1530 
1532 
1534  }
1535  else
1536  print_usage ();
1537  }
1538  else
1539  error ("dbquit: can only be called in debug mode");
1540 
1541  return octave_value_list ();
1542 }
1543 
1544 DEFUN (isdebugmode, args, ,
1545  "-*- texinfo -*-\n\
1546 @deftypefn {Built-in Function} {} isdebugmode ()\n\
1547 Return true if in debugging mode, otherwise false.\n\
1548 @seealso{dbwhere, dbstack, dbstatus}\n\
1549 @end deftypefn")
1550 {
1551  octave_value retval;
1552 
1553  if (args.length () == 0)
1554  retval = Vdebugging;
1555  else
1556  print_usage ();
1557 
1558  return retval;
1559 }
1560 
1561 DEFUN (__db_next_breakpoint_quiet__, args, ,
1562  "-*- texinfo -*-\n\
1563 @deftypefn {Built-in Function} {} __db_next_breakpoint_quiet__ ()\n\
1564 @deftypefnx {Built-in Function} {} __db_next_breakpoint_quiet__ (@var{flag})\n\
1565 Disable line info printing at the next breakpoint.\n\
1566 \n\
1567 With a logical argument @var{flag}, set the state on or off.\n\
1568 @end deftypefn")
1569 {
1570  octave_value retval;
1571 
1572  int nargin = args.length ();
1573 
1574  if (nargin == 0 || nargin == 1)
1575  {
1576  bool state = true;
1577 
1578  if (nargin == 1)
1579  {
1580  state = args(0).bool_value ();
1581 
1582  if (error_state)
1583  {
1584  gripe_wrong_type_arg ("db_next_breakpoint", args(0), true);
1585  return retval;
1586  }
1587  }
1588 
1590  }
1591  else
1592  print_usage ();
1593 
1594  return retval;
1595 }
static void cleanup_instance(void)
Definition: debug.h:117
static std::deque< size_t > get_line_offsets(const std::string &buf)
Definition: debug.cc:99
static std::string do_which(const std::string &name, std::string &type)
Definition: help.cc:1225
virtual std::map< std::string, octave_value > subfunctions(void) const
Definition: ov-usr-fcn.cc:65
const Cell & contents(const_iterator p) const
Definition: oct-map.h:314
intmap do_remove_all_breakpoints_in_file(const std::string &fname, bool silent)
Definition: debug.cc:500
Definition: Cell.h:35
static bool debug_mode
Definition: pt-eval.h:152
void gripe_wrong_type_arg(const char *name, const char *s, bool is_error)
Definition: gripes.cc:135
void do_dbtype(std::ostream &os, const std::string &name, int start, int end)
Definition: debug.cc:916
void assign(const std::string &k, const Cell &val)
Definition: oct-map.h:348
static uint32_t state[624]
Definition: randmtzig.c:188
intmap::const_iterator const_intmap_iterator
Definition: debug.h:50
std::map< std::string, intmap > fname_line_map
Definition: debug.h:53
OCTINTERP_API void print_usage(void)
Definition: defun.cc:51
bool is_user_code(void) const
Definition: ov.h:704
octave_idx_type length(void) const
Definition: oct-obj.h:89
static bool have_breakpoints(void)
Definition: debug.h:102
octave_user_code * user_code_value(bool silent=false) const
Definition: ov.cc:1615
int do_remove_breakpoint(const std::string &, const intmap &lines)
Definition: debug.cc:426
bool is_defined(void) const
Definition: ov.h:520
void delete_breakpoint(int line)
Definition: pt-stmt.cc:191
static void do_dbupdown(const octave_value_list &args, const std::string &who)
Definition: debug.cc:1352
void octave_throw_interrupt_exception(void)
Definition: quit.cc:52
int int_value(bool req_int=false, bool frc_str_conv=false) const
Definition: ov.h:730
intmap do_add_breakpoint(const std::string &fname, const intmap &lines)
Definition: debug.cc:333
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:44
void error(const char *fmt,...)
Definition: error.cc:476
std::set< std::string >::iterator bp_set_iterator
Definition: debug.h:110
std::string name(void) const
Definition: ov-fcn.h:161
static string_vector names(const map_type &lst)
Definition: help.cc:782
std::set< std::string > bp_set
Definition: debug.h:113
T & elem(octave_idx_type n)
Definition: Array.h:380
octave_idx_type numel(void) const
Definition: oct-map.h:372
static octave_value_list do_dbstack(const octave_value_list &args, int nargout, std::ostream &os)
Definition: debug.cc:1185
std::string fcn_file_in_path(const std::string &name)
Definition: utils.cc:504
static octave_value find_function(const std::string &name, const octave_value_list &args=octave_value_list(), bool local_funcs=true)
Definition: symtab.cc:1271
static bool quiet_breakpoint_flag
Definition: pt-eval.h:154
std::string do_find_bkpt_list(octave_value_list slist, std::string match)
Definition: debug.cc:554
octave_idx_type nelem(void) const
Number of elements in the array.
Definition: Array.h:271
bp_table::intmap add_breakpoint(const std::string &file, const bp_table::intmap &line)
Definition: pt-stmt.cc:222
#define DEFALIAS(alias, name)
Definition: defun.h:63
virtual tree_statement_list * body(void)=0
intmap::iterator intmap_iterator
Definition: debug.h:51
static int dbstep_flag
Definition: pt-eval.h:147
static std::string snarf_file(const std::string &fname)
Definition: debug.cc:67
std::set< std::string >::const_iterator const_bp_set_iterator
Definition: debug.h:109
static octave_user_code * caller_user_code(size_t nskip=0)
Definition: toplev.h:221
void do_remove_all_breakpoints(void)
Definition: debug.cc:539
F77_RET_T const double const double * f
Definition: debug.h:36
std::string string_value(bool force=false) const
Definition: ov.h:897
static void add(fptr f)
std::map< int, int > intmap
Definition: debug.h:48
bool is_string(void) const
Definition: ov.h:562
int error_state
Definition: error.cc:101
fname_line_map::iterator fname_line_map_iterator
Definition: debug.h:56
void resize(const dim_vector &dv, const T &rfv)
Definition: Array.cc:1033
octave_value_list(void)
Definition: oct-obj.h:42
virtual std::list< std::string > subfunction_names(void) const
Definition: ov-fcn.h:152
static void parse_dbfunction_params(const char *who, const octave_value_list &args, std::string &symbol_name, bp_table::intmap &lines)
Definition: debug.cc:196
static void reset_debug_state(void)
Definition: pt-eval.cc:130
octave_idx_type length(void) const
Definition: ov.cc:1525
static intmap remove_all_breakpoints_in_file(const std::string &fname, bool silent=false)
Definition: debug.h:77
virtual octave_user_code * user_code_value(bool silent=false)
Definition: ov-base.cc:1025
int do_remove_breakpoint_1(octave_user_code *fcn, const std::string &, const intmap &lines)
Definition: debug.cc:377
fname_line_map do_get_breakpoint_list(const octave_value_list &fname_list)
Definition: debug.cc:572
double arg(double x)
Definition: lo-mappers.h:37
static int caller_user_code_line(void)
Definition: toplev.h:164
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:233
virtual std::string fcn_file_name(void) const
Definition: ov-fcn.h:62
fname_line_map::const_iterator const_fname_line_map_iterator
Definition: debug.h:55
#define octave_stdout
Definition: pager.h:144
static bp_table * instance
Definition: debug.h:115
static void remove_all_breakpoints(void)
Definition: debug.h:86
Array< octave_value > array_value(void) const
Definition: oct-obj.h:79
octave_value_list list_breakpoints(void)
Definition: pt-stmt.cc:213
static bool instance_ok(void)
Definition: debug.cc:281
bool do_add_breakpoint_1(octave_user_code *fcn, const std::string &fname, const intmap &line, intmap &retval)
Definition: debug.cc:303
intmap do_remove_all_breakpoints_in_file_1(octave_user_code *fcn, const std::string &fname)
Definition: debug.cc:478
bp_table(void)
Definition: debug.h:42
static int remove_breakpoint(const std::string &fname="", const intmap &lines=intmap())
Definition: debug.h:69
Array< octave_idx_type > find(octave_idx_type n=-1, bool backward=false) const
Find indices of (at most n) nonzero elements.
Definition: Array.cc:2246
octave_idx_type length(void) const
Definition: oct-map.h:373
static intmap add_breakpoint(const std::string &fname="", const intmap &lines=intmap())
Definition: debug.h:61
static bool match(const std::string &filename_arg, const std::string &path_elt_arg)
Definition: kpse.cc:1738
std::string get_file_line(const std::string &fname, size_t line)
Definition: debug.cc:132
void show_octave_dbstack(void)
Definition: debug.cc:1299
static octave_user_code * get_user_code(const std::string &fname=std::string())
Definition: debug.cc:171
bp_table::intmap remove_all_breakpoints(const std::string &file)
Definition: pt-stmt.cc:248
off_t size(void) const
Definition: file-stat.h:115
bool Vdebugging
Definition: input.cc:117
static bool goto_frame_relative(int n, bool verbose=false)
Definition: toplev.h:277
static octave_value intmap_to_ov(const bp_table::intmap &line)
Definition: debug.cc:614
static fname_line_map get_breakpoint_list(const octave_value_list &fname_list)
Definition: debug.h:95
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:210
static octave_map backtrace(size_t nskip=0)
Definition: toplev.h:295