75 size_t sz = fs.
size ();
77 std::ifstream file (fname.c_str (), std::ios::in|std::ios::binary);
81 std::string buf (sz+1, 0);
83 file.read (&buf[0], sz+1);
91 error (
"error reading file %s", fname.c_str ());
98 static std::deque<size_t>
103 std::deque<size_t> offsets;
105 offsets.push_back (0);
107 size_t len = buf.length ();
109 for (
size_t i = 0; i < len; i++)
113 if (c ==
'\r' && ++i < len)
118 offsets.push_back (i+1);
120 offsets.push_back (i);
123 offsets.push_back (i+1);
126 offsets.push_back (len);
136 static std::string last_fname;
138 static std::string buf;
140 static std::deque<size_t> offsets;
142 if (fname != last_fname)
152 if (line < offsets.size () - 1)
154 size_t bol = offsets[line];
155 size_t eol = offsets[line+1];
157 while (eol > 0 && eol > bol && (buf[eol-1] ==
'\n' || buf[eol-1] ==
'\r'))
160 retval = buf.substr (bol, eol - bol);
179 std::string name = fname;
181 size_t name_len = name.length ();
183 if (! name.empty () && name_len > 2 && name.substr (name_len-2) ==
".m")
184 name = name.substr (0, name_len-2);
199 int nargin = args.
length ();
202 symbol_name = std::string ();
208 if (args(0).is_string ())
211 int isint = atoi (args(0).string_value ().c_str ());
219 symbol_name = args(0).string_value ();
234 error (
"%s: no function specified", who);
238 else if (args(0).is_map ())
242 error (
"%s: struct input not implemented", who);
246 error (
"%s: invalid parameter specified", who);
248 for (
int i = idx; i < nargin; i++)
250 if (args(i).is_string ())
252 int line = atoi (args(i).string_value ().c_str ());
255 lines[list_idx++] = line;
257 else if (args(i).is_map ())
258 octave_stdout << who <<
": skipping struct input" << std::endl;
268 int line =
static_cast<int> (arg.
elem (j));
271 lines[list_idx++] = line;
295 ::error (
"unable to create breakpoint table!");
304 const std::string& fname,
346 const std::list<std::string> subfcn_names
349 std::map<std::string, octave_value> subfcns
352 for (std::list<std::string>::const_iterator p = subfcn_names.begin ();
353 p != subfcn_names.end (); p++)
355 std::map<std::string, octave_value>::const_iterator
356 q = subfcns.find (*p);
358 if (q != subfcns.end ())
369 error (
"add_breakpoint: unable to find the requested function\n");
378 const std::string& fname,
393 if (results.
length () > 0)
397 for (
int i = 0; i < len; i++)
401 if (p != line.end ())
403 int lineno = p->second;
419 retval = results.
length ();
436 retval = results.size ();
448 const std::list<std::string> subfcn_names
451 std::map<std::string, octave_value> subfcns
454 for (std::list<std::string>::const_iterator p = subfcn_names.begin ();
455 p != subfcn_names.end (); p++)
457 std::map<std::string, octave_value>::const_iterator
458 q = subfcns.find (*p);
460 if (q != subfcns.end ())
469 error (
"remove_breakpoint: unable to find the requested function\n");
479 const std::string& fname)
513 typedef std::map<std::string, octave_value>::const_iterator
514 subfcns_const_iterator;
516 std::map<std::string, octave_value> subfcns = dbg_fcn->
subfunctions ();
518 for (subfcns_const_iterator p = subfcns.begin ();
519 p != subfcns.end (); p++)
526 retval.insert (tmp.begin (), tmp.end ());
530 error (
"remove_all_breakpoint_in_file: "
531 "unable to find the requested function\n");
559 for (
int i = 0; i < slist.
length (); i++)
561 if (slist(i).string_value () ==
match)
563 retval = slist(i).string_value ();
578 if (fname_list.
length () == 0
598 for (
int i = 0; i < len; i++)
599 bkpts_vec[i] = bkpts(i).double_value ();
601 std::string symbol_name = f->
name ();
603 retval[symbol_name] = bkpts_vec;
620 for (
size_t i = 0; i < line.size (); i++)
624 if (p != line.end ())
626 int lineno = p->second;
627 retval(idx++) = lineno;
636 DEFUN (dbstop, args, ,
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\
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\
657 Line number where the breakpoint should be set. Multiple lines may be given\n\
658 as separate arguments or as a vector.\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\
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\
672 std::string symbol_name;
677 if (lines.size () == 0)
686 DEFUN (dbclear, args, ,
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\
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\
709 Line number from which to remove a breakpoint. Multiple lines may be given\n\
710 as separate arguments or as a vector.\n\
713 When called without a line number specification all breakpoints in the named\n\
714 function are cleared.\n\
716 If the requested line is not a breakpoint no action is performed.\n\
718 The special keyword @qcode{\"all\"} will clear all breakpoints from all\n\
720 @seealso{dbstop, dbstatus, dbwhere}\n\
724 std::string symbol_name =
"";
727 int nargin = args.
length ();
731 if (nargin == 1 && symbol_name ==
"all")
742 DEFUN (dbstatus, args, nargout,
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\
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\
753 If a function name @var{func} is specified then only report breakpoints\n\
754 for the named function.\n\
756 The optional return argument @var{brk_list} is a struct array with the\n\
761 The name of the function with a breakpoint.\n\
764 The name of the m-file where the function code is located.\n\
767 A line number, or vector of line numbers, with a breakpoint.\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\
773 @seealso{dbclear, dbwhere}\n\
777 int nargin = args.
length ();
780 std::string symbol_name;
782 if (nargin != 0 && nargin != 1)
784 error (
"dbstatus: only zero or one arguments accepted\n");
790 if (args(0).is_string ())
792 symbol_name = args(0).string_value ();
793 fcn_list(0) = symbol_name;
806 symbol_name = dbg_fcn->
name ();
807 fcn_list(0) = symbol_name;
819 it != bp_list.end (); it++)
823 size_t nel = m.size ();
831 for (
size_t j = 0; j < nel; j++)
849 it != bp_list.end (); it++)
851 names(i) = it->first;
857 retval.
assign (
"name", names);
858 retval.
assign (
"file", file);
859 retval.
assign (
"line", line);
867 @deftypefn {Command} {} dbwhere\n\
868 In debugging mode, report the current file and line number where execution\n\
870 @seealso{dbstatus, dbcont, dbstep, dbup}\n\
879 bool have_file =
true;
887 name = dbg_fcn->
name ();
910 error (
"dbwhere: must be inside a user function to use dbwhere\n");
916 do_dbtype (std::ostream& os,
const std::string& name,
int start,
int end)
922 std::ifstream fs (ff.c_str (), std::ios::in);
929 while (std::getline (fs, text) && line <= end)
932 os << line <<
"\t" << text <<
"\n";
938 os <<
"dbtype: unable to open '" << ff <<
"' for reading!\n";
941 os <<
"dbtype: unknown function " << name <<
"\n";
946 DEFUN (dbtype, args, ,
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\
958 When called with no arguments in debugging mode, display the script file\n\
959 currently being debugged.\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\
965 When called with the name of a function, list that script file with line\n\
967 @seealso{dbwhere, dbstatus, dbstop}\n\
973 int nargin = args.length ();
987 error (
"dbtype: must be inside a user function to give no arguments to dbtype\n");
993 std::string
arg = argv[1];
995 size_t ind = arg.
find (
':');
997 if (ind != std::string::npos)
1003 std::string start_str = arg.substr (0, ind);
1004 std::string end_str = arg.substr (ind + 1);
1007 start = atoi (start_str.c_str ());
1008 if (end_str ==
"end")
1011 end = atoi (end_str.c_str ());
1015 error (
"dbtype: start and end lines must be >= 1\n");
1023 error (
"dbtype: start line must be less than end line\n");
1028 int line = atoi (arg.c_str ());
1038 error (
"dbtype: function <%s> not found\n", arg.c_str ());
1044 error (
"dbtype: start and end lines must be >= 1\n");
1063 std::string
arg = argv[2];
1065 size_t ind = arg.
find (
':');
1067 if (ind != std::string::npos)
1069 std::string start_str = arg.substr (0, ind);
1070 std::string end_str = arg.substr (ind + 1);
1072 start = atoi (start_str.c_str ());
1073 if (end_str ==
"end")
1076 end = atoi (end_str.c_str ());
1080 start = atoi (arg.c_str ());
1086 error (
"dbtype: start and end lines must be >= 1\n");
1094 error (
"dbtype: start line must be less than end line\n");
1097 error (
"dbtype: function <%s> not found\n", argv[1].c_str ());
1102 error (
"dbtype: expecting zero, one, or two arguments\n");
1109 DEFUN (dblist, args, ,
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\
1116 If unspecified @var{n} defaults to 10 (+/- 5 lines)\n\
1117 @seealso{dbwhere, dbtype}\n\
1124 if (args.length () == 1)
1132 n = atoi (s_arg.c_str ());
1135 n = args(0).int_value ();
1138 error (
"dblist: N must be a non-negative integer");
1145 bool have_file =
true;
1152 name = dbg_fcn->
name ();
1162 int l_max = l + n/2;
1166 if (! line.empty ())
1174 octave_stdout <<
"dblist: unable to determine source code line"
1179 error (
"dblist: must be inside a user function to use dblist\n");
1199 if (len == 1 || len == 2)
1213 if (s_arg ==
"-completenames")
1216 n = atoi (s_arg.c_str ());
1222 error (
"dbstack: N must be a non-negative integer");
1238 if (nframes_to_display > 0)
1242 os <<
"stopped in:\n\n";
1248 bool show_top_level =
true;
1250 size_t max_name_len = 0;
1254 std::string name =
names(i).string_value ();
1256 max_name_len =
std::max (name.length (), max_name_len);
1261 std::string name =
names(i).string_value ();
1262 std::string file = files(i).string_value ();
1263 int line = lines(i).int_value ();
1265 if (show_top_level && i == curr_frame)
1266 show_top_level =
false;
1268 os << (i == curr_frame ?
" --> " :
" ")
1269 << std::setw (max_name_len) << name
1270 <<
" at line " << line
1271 <<
" [" << file <<
"]"
1276 os <<
" --> top level" << std::endl;
1285 retval(1) = curr_frame < 0 ? 1 : curr_frame + 1;
1304 DEFUN (dbstack, args, nargout,
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\
1312 With optional argument @var{n}, omit the @var{n} innermost stack frames.\n\
1314 Although accepted, the argument @var{-completenames} is silently ignored.\n\
1315 Octave always returns absolute file names.\n\
1317 The arguments @var{n} and @var{-completenames} can be both specified in any\n\
1320 The optional return argument @var{stack} is a struct array with the\n\
1321 following fields:\n\
1325 The name of the m-file where the function code is located.\n\
1328 The name of the function with a breakpoint.\n\
1331 The line number of an active breakpoint.\n\
1334 The column number of the line where the breakpoint begins.\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\
1364 n = atoi (s_arg.c_str ());
1367 n = args(0).int_value ();
1376 error (
"%s: invalid stack frame", who.c_str ());
1380 DEFUN (dbup, args, ,
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\
1386 If @var{n} is omitted, move up one frame.\n\
1387 @seealso{dbstack, dbdown}\n\
1397 DEFUN (dbdown, args, ,
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\
1403 If @var{n} is omitted, move down one frame.\n\
1404 @seealso{dbstack, dbup}\n\
1414 DEFUN (dbstep, args, ,
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\
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\
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\
1430 Using @code{dbstep out} will cause execution to continue until the current\n\
1431 function returns.\n\
1433 @code{dbnext} is an alias for @code{dbstep}.\n\
1434 @seealso{dbcont, dbquit}\n\
1439 int nargin = args.length ();
1443 else if (nargin == 1)
1445 if (args(0).is_string ())
1447 std::string
arg = args(0).string_value ();
1455 else if (arg ==
"out")
1463 int n = atoi (arg.c_str ());
1472 error (
"dbstep: invalid argument");
1476 error (
"dbstep: input argument must be a string");
1486 error (
"dbstep: can only be called in debug mode");
1493 DEFUN (dbcont, args, ,
1495 @deftypefn {Command} {} dbcont\n\
1496 Leave command-line debugging mode and continue code execution normally.\n\
1497 @seealso{dbstep, dbquit}\n\
1502 if (args.length () == 0)
1512 error (
"dbcont: can only be called in debug mode");
1517 DEFUN (dbquit, args, ,
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\
1527 if (args.length () == 0)
1539 error (
"dbquit: can only be called in debug mode");
1544 DEFUN (isdebugmode, args, ,
1546 @deftypefn {Built-in Function} {} isdebugmode ()\n\
1547 Return true if in debugging mode, otherwise false.\n\
1548 @seealso{dbwhere, dbstack, dbstatus}\n\
1553 if (args.length () == 0)
1561 DEFUN (__db_next_breakpoint_quiet__, args, ,
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\
1567 With a logical argument @var{flag}, set the state on or off.\n\
1572 int nargin = args.
length ();
1574 if (nargin == 0 || nargin == 1)
1580 state = args(0).bool_value ();
static void cleanup_instance(void)
static std::deque< size_t > get_line_offsets(const std::string &buf)
static std::string do_which(const std::string &name, std::string &type)
virtual std::map< std::string, octave_value > subfunctions(void) const
const Cell & contents(const_iterator p) const
intmap do_remove_all_breakpoints_in_file(const std::string &fname, bool silent)
void gripe_wrong_type_arg(const char *name, const char *s, bool is_error)
void do_dbtype(std::ostream &os, const std::string &name, int start, int end)
void assign(const std::string &k, const Cell &val)
static uint32_t state[624]
intmap::const_iterator const_intmap_iterator
std::map< std::string, intmap > fname_line_map
OCTINTERP_API void print_usage(void)
bool is_user_code(void) const
octave_idx_type length(void) const
static bool have_breakpoints(void)
octave_user_code * user_code_value(bool silent=false) const
int do_remove_breakpoint(const std::string &, const intmap &lines)
bool is_defined(void) const
void delete_breakpoint(int line)
static void do_dbupdown(const octave_value_list &args, const std::string &who)
void octave_throw_interrupt_exception(void)
int int_value(bool req_int=false, bool frc_str_conv=false) const
intmap do_add_breakpoint(const std::string &fname, const intmap &lines)
#define DEFUN(name, args_name, nargout_name, doc)
void error(const char *fmt,...)
std::set< std::string >::iterator bp_set_iterator
std::string name(void) const
static string_vector names(const map_type &lst)
std::set< std::string > bp_set
static void update_breakpoint(bool insert, const std::string &file, int line)
T & elem(octave_idx_type n)
octave_idx_type numel(void) const
static octave_value_list do_dbstack(const octave_value_list &args, int nargout, std::ostream &os)
std::string fcn_file_in_path(const std::string &name)
static octave_value find_function(const std::string &name, const octave_value_list &args=octave_value_list(), bool local_funcs=true)
static bool quiet_breakpoint_flag
std::string do_find_bkpt_list(octave_value_list slist, std::string match)
octave_idx_type nelem(void) const
Number of elements in the array.
bp_table::intmap add_breakpoint(const std::string &file, const bp_table::intmap &line)
#define DEFALIAS(alias, name)
virtual tree_statement_list * body(void)=0
intmap::iterator intmap_iterator
static std::string snarf_file(const std::string &fname)
std::set< std::string >::const_iterator const_bp_set_iterator
static octave_user_code * caller_user_code(size_t nskip=0)
void do_remove_all_breakpoints(void)
F77_RET_T const double const double * f
std::string string_value(bool force=false) const
std::map< int, int > intmap
bool is_string(void) const
fname_line_map::iterator fname_line_map_iterator
void resize(const dim_vector &dv, const T &rfv)
virtual std::list< std::string > subfunction_names(void) const
static void parse_dbfunction_params(const char *who, const octave_value_list &args, std::string &symbol_name, bp_table::intmap &lines)
static void reset_debug_state(void)
octave_idx_type length(void) const
static intmap remove_all_breakpoints_in_file(const std::string &fname, bool silent=false)
virtual octave_user_code * user_code_value(bool silent=false)
int do_remove_breakpoint_1(octave_user_code *fcn, const std::string &, const intmap &lines)
fname_line_map do_get_breakpoint_list(const octave_value_list &fname_list)
static int caller_user_code_line(void)
charNDArray max(char d, const charNDArray &m)
virtual std::string fcn_file_name(void) const
fname_line_map::const_iterator const_fname_line_map_iterator
static bp_table * instance
static void remove_all_breakpoints(void)
Array< octave_value > array_value(void) const
octave_value_list list_breakpoints(void)
static bool instance_ok(void)
bool do_add_breakpoint_1(octave_user_code *fcn, const std::string &fname, const intmap &line, intmap &retval)
intmap do_remove_all_breakpoints_in_file_1(octave_user_code *fcn, const std::string &fname)
static int remove_breakpoint(const std::string &fname="", const intmap &lines=intmap())
Array< octave_idx_type > find(octave_idx_type n=-1, bool backward=false) const
Find indices of (at most n) nonzero elements.
octave_idx_type length(void) const
static intmap add_breakpoint(const std::string &fname="", const intmap &lines=intmap())
static bool match(const std::string &filename_arg, const std::string &path_elt_arg)
std::string get_file_line(const std::string &fname, size_t line)
void show_octave_dbstack(void)
static octave_user_code * get_user_code(const std::string &fname=std::string())
bp_table::intmap remove_all_breakpoints(const std::string &file)
static bool goto_frame_relative(int n, bool verbose=false)
static octave_value intmap_to_ov(const bp_table::intmap &line)
static fname_line_map get_breakpoint_list(const octave_value_list &fname_list)
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)
static octave_map backtrace(size_t nskip=0)