23 #if defined (HAVE_CONFIG_H)
88 std::ifstream
file (fname.c_str (), std::ios::in | std::ios::binary);
94 file.read (&buf[0], sz+1);
97 error (
"error reading file %s", fname.c_str ());
107 static std::deque<size_t>
112 std::deque<size_t> offsets;
114 offsets.push_back (0);
116 size_t len = buf.length ();
118 for (
size_t i = 0;
i < len;
i++)
122 if (c ==
'\r' && ++
i < len)
127 offsets.push_back (
i+1);
129 offsets.push_back (
i);
132 offsets.push_back (
i+1);
135 offsets.push_back (len);
149 static std::deque<size_t> offsets;
151 if (fname != last_fname)
161 if (line < offsets.size () - 1)
163 size_t bol = offsets[line];
164 size_t eol = offsets[line+1];
166 while (eol > 0 && eol > bol && (buf[eol-1] ==
'\n' || buf[eol-1] ==
'\r'))
169 retval = buf.substr (bol, eol - bol);
192 int len = name.length () - 1;
193 for (
int i = 2;
i < len;
i++)
198 size_t name_len = name.length ();
200 if (! name.empty () && name_len > 2 && name.substr (name_len-2) ==
".m")
201 name = name.substr (0, name_len-2);
212 #if defined (DBSTOP_NANINF)
213 # include "sigfpe.cc"
235 if (nargin == 0 || !
args(0).is_string ())
239 bool seen_in =
false, seen_at =
false, seen_if =
false;
245 if (
args(pos).is_string ())
253 else if (arg ==
"at")
258 else if (arg ==
"if")
263 else if (atoi (
args(pos).string_value ().c_str ()) > 0)
272 error (
"%s: '%s' missing argument", who,
280 symbol_name =
args(pos).string_value ();
282 error (
"%s: Too many function names specified -- %s",
283 who, symbol_name.c_str ());
284 else if (seen_at || seen_if)
285 error (
"%s: function name must come before line number and 'if'",
293 error (
"%s: Only one 'at' clause is allowed -- %s",
294 who,
args(pos).string_value ().c_str ());
296 error (
"%s: line number must come before 'if' clause\n");
305 error (
"%s: function name must come before line number "
310 error (
"%s: line number must come before 'if' clause\n");
313 for ( ; pos <
nargin; pos++)
315 if (
args(pos).is_string ())
317 int line = atoi (
args(pos).string_value ().c_str ());
320 lines[list_idx++] = line;
324 else if (
args(pos).is_numeric_type ())
329 lines[list_idx++] = static_cast<int> (arg.
elem (j));
332 error (
"%s: Invalid argument type %s",
333 args(pos).type_name ().c_str ());
341 for (; pos <
nargin; pos++)
343 if (
args(pos).is_string ())
344 cond = cond +
" " +
args(pos).string_value ();
346 error (
"%s: arguments to 'if' must all be strings", who);
349 cond = cond.substr (1);
354 int on_off = !
strcmp(who,
"dbstop");
357 std::set<std::string> *id_list = NULL;
358 bool *stop_flag = NULL;
360 if (condition ==
"error")
365 else if (condition ==
"warning")
370 else if (condition ==
"caught" && nargin > pos+1
371 &&
args(pos+1).string_value () ==
"error")
377 else if (condition ==
"interrupt")
381 else if (condition ==
"naninf")
382 #if defined (DBSTOP_NANINF)
384 Vdebug_on_naninf = on_off;
388 warning (
"%s: condition '%s' not yet supported",
389 who, condition.c_str ());
392 error (
"%s: invalid condition %s",
393 who, condition.c_str ());
401 if (!
args(pos).is_string () || nargin > pos+1)
402 error (
"%s: ID must be a single string", who);
403 else if (on_off == 1)
405 id_list->insert (
args(pos).string_value ());
410 id_list->erase (
args(pos).string_value ());
411 if (id_list->empty ())
467 error (
"unable to create breakpoint table!");
477 bp_table::errors_that_stop.clear ();
480 bp_table::caught_that_stop.clear ();
483 bp_table::warnings_that_stop.clear ();
498 fail = (U.
numel () > 1);
502 if (W.
is_empty () ||
W(0).is_empty () == 0)
504 else if (!
W(0).is_cell ())
509 for (
int i = 0;
i < V.
numel ();
i++)
517 error (
"dbstop: invalid 'errs' field");
524 fail = (U.
numel () > 1);
530 else if (!
W(0).is_cell ())
535 for (
int i = 0;
i < V.
numel ();
i++)
543 error (
"dbstop: invalid 'caught' field");
550 fail = (U.
numel () > 1);
556 else if (!
W(0).is_cell ())
561 for (
int i = 0;
i < V.
numel ();
i++)
569 error (
"dbstop: invalid 'warn' field");
596 for (
auto& idx_line_p : retval)
598 if (idx_line_p.second != 0)
605 bp_set.insert (fname.substr (0, s - fname.c_str ()));
624 if (cond.length () > 0)
628 int parse_status = parser.
run ();
630 error (
"dbstop: Cannot parse condition '%s'", cond.c_str ());
636 "condition is not empty, but has nothing to evaluate");
645 error (
"dbstop: condition cannot be an assignment. "
646 "Did you mean '=='?");
649 error (
"dbstop: condition must be an expression");
668 std::map<std::string, octave_value> subfcns = main_fcn->
subfunctions ();
669 for (
const auto& str_val_p : subfcns)
671 if (str_val_p.second.is_user_function ())
673 auto *dbg_subfcn = str_val_p.second.user_function_value ();
680 if (dbg_subfcn->ending_line () < earliest_end
681 && dbg_subfcn->ending_line () >= lineno
682 && dbg_subfcn->beginning_line () <= lineno)
684 earliest_end = dbg_subfcn->ending_line ();
690 if (dbg_subfcn->beginning_line () >= lineno && ! next_fcn)
691 next_fcn = dbg_subfcn;
700 if (e >= lineno && e < earliest_end)
712 if (end_line != 0 && earliest_end < *end_line)
713 *end_line = earliest_end;
728 error (
"add_breakpoint: unable to find function '%s'\n", fname.c_str ());
736 for (
int i = 0;
i < len;
i++)
740 if (m != line.end ())
742 int lineno = m->second;
752 retval.insert (std::pair<int,int> (
i, ret_one.find (
i)->second));
779 if (results.
length () > 0)
783 for (
int i = 0;
i < len;
i++)
787 if (p != line.end ())
789 int lineno = p->second;
805 retval = results.
length ();
822 retval = results.size ();
829 error (
"remove_breakpoint: unable to find function %s\n",
836 const std::list<std::string> subfcn_names
839 std::map<std::string, octave_value> subfcns
842 for (
const auto& subf_nm : subfcn_names)
844 const auto q = subfcns.find (subf_nm);
846 if (q != subfcns.end ())
886 error (
"remove_all_breakpoint_in_file: "
887 "unable to find function %s\n", fname.c_str ());
916 for (
int i = 0;
i < slist.
length ();
i++)
918 if (slist(
i).string_value () == match)
920 retval = slist(
i).string_value ();
934 std::set<std::string> tmp_bp_set =
bp_set;
936 for (
auto& bp_fname : tmp_bp_set)
938 if (fname_list.
empty ()
953 if (! bkpts.empty ())
954 retval[bp_fname] = bkpts;
960 std::map<std::string, octave_value> subf = f->
subfunctions ();
962 for (
const auto& subfcn_nm : subf_nm)
964 const auto q = subf.find (subfcn_nm);
966 if (q != subf.end ())
973 std::list<bp_type> bkpts
976 if (! bkpts.empty ())
995 for (
size_t i = 0;
i < line.size ();
i++)
999 if (p != line.end ())
1001 int lineno = p->second;
1107 if (
args.length() >= 1 && !
args(0).is_map ())
1112 if (lines.size () == 0)
1115 if (symbol_name !=
"")
1121 else if (
args.length () != 1)
1144 error (
"dbstop: invalid 'bkpt' field");
1155 error (
"dbstop: Cell array must contain fields 'name' and 'line'");
1160 bool use_cond = mv.
isfield (
"cond");
1167 lines [0] = line(
i).double_value ();
1169 use_cond ? cond(
i).string_value ()
1231 if (nargin == 1 && symbol_name ==
"all")
1238 if (symbol_name !=
"")
1395 int nargin =
args.length ();
1397 if (nargin != 0 && nargin != 1)
1398 error (
"dbstatus: only zero or one arguments accepted\n");
1406 if (!
args(0).is_string ())
1409 symbol_name =
args(0).string_value ();
1410 fcn_list(0) = symbol_name;
1434 for (
auto& fnm_bp_p: bp_list)
1436 std::list<bp_type>
m = fnm_bp_p.second;
1441 int have_unconditional = 0;
1442 for (
const auto& bp : m)
1446 if (have_unconditional++)
1451 if (have_unconditional)
1453 const char *_s_ = (have_unconditional > 1) ?
"s" :
"";
1454 octave_stdout <<
"breakpoint" << _s_ <<
" in " << fnm_bp_p.first
1455 <<
" at line" << _s_ <<
" ";
1457 for (
const auto& bp : m)
1466 for (
const auto& bp : m)
1470 <<
" at line " << bp.line
1471 <<
" if " << bp.cond <<
"\n";
1488 for (
const auto& fnm_bp_p : bp_list)
1489 count += fnm_bp_p.second.size ();
1496 for (
const auto& fnm_bp_p : bp_list)
1499 const char *sub_fun = strchr (filename.c_str (),
Vfilemarker);
1501 filename = filename.substr(0, sub_fun - filename.c_str ());
1505 for (
const auto& bp : fnm_bp_p.second)
1507 names(i) = fnm_bp_p.first;
1508 file(i) = path_name;
1518 retmap.
assign (
"cond", cond);
1528 outer.assign (
"bkpt",
Cell (retmap));
1581 if (! file_name.empty ())
1587 if (! line.empty ())
1605 os <<
"dbtype: unknown function " << name <<
"\n";
1608 std::ifstream
fs (ff.c_str (), std::ios::in);
1611 os <<
"dbtype: unable to open '" << ff <<
"' for reading!\n";
1617 while (std::getline (
fs, text) && line <= end)
1620 os << line <<
"\t" << text <<
"\n";
1658 switch (
args.length ())
1664 error (
"dbtype: must be inside a user function to give no arguments to dbtype\n");
1675 size_t ind = arg.find (
':');
1677 if (ind != std::string::npos)
1687 start = atoi (start_str.c_str ());
1688 if (end_str ==
"end")
1691 end = atoi (end_str.c_str ());
1694 error (
"dbtype: start and end lines must be >= 1\n");
1697 error (
"dbtype: start line must be less than end line\n");
1705 int line = atoi (arg.c_str ());
1712 error (
"dbtype: function <%s> not found\n", arg.c_str ());
1720 error (
"dbtype: start and end lines must be >= 1\n");
1737 error (
"dbtype: function <%s> not found\n", argv[1].c_str ());
1741 size_t ind = arg.find (
':');
1743 if (ind != std::string::npos)
1748 start = atoi (start_str.c_str ());
1749 if (end_str ==
"end")
1752 end = atoi (end_str.c_str ());
1756 start = atoi (arg.c_str ());
1761 error (
"dbtype: start and end lines must be >= 1\n");
1764 error (
"dbtype: start line must be less than end line\n");
1771 error (
"dbtype: expecting zero, one, or two arguments\n");
1790 if (
args.length () == 1)
1798 n = atoi (s_arg.c_str ());
1801 n =
args(0).int_value ();
1804 error (
"dblist: N must be a non-negative integer");
1810 error (
"dblist: must be inside a user function to use dblist\n");
1812 bool have_file =
true;
1819 name = dbg_fcn->
name ();
1829 int l_max = l + n/2;
1833 if (! line.empty ())
1841 octave_stdout <<
"dblist: unable to determine source code line"
1851 int nargin = args.
length ();
1864 if (nargin == 1 || nargin == 2)
1877 if (s_arg ==
"-completenames")
1880 n = atoi (s_arg.c_str ());
1886 error (
"dbstack: N must be a non-negative integer");
1898 if (nframes_to_display > 0)
1902 os <<
"stopped in:\n\n";
1908 bool show_top_level =
true;
1910 size_t max_name_len = 0;
1916 max_name_len =
std::max (name.length (), max_name_len);
1923 int line = lines(i).int_value ();
1925 if (show_top_level && i == curr_frame)
1926 show_top_level =
false;
1928 os << (i == curr_frame ?
" --> " :
" ")
1929 << std::setw (max_name_len) << name
1930 <<
" at line " << line
1931 <<
" [" << file <<
"]"
1936 os <<
" --> top level" << std::endl;
1943 retval =
ovl (stk, curr_frame < 0 ? 1 : curr_frame + 1);
1955 show_octave_dbstack (
void)
1960 DEFUN (dbstack, args, nargout,
2020 n = atoi (s_arg.c_str ());
2023 n =
args(0).int_value ();
2030 error (
"%s: invalid stack frame", who.c_str ());
2033 DEFUN (dbup, args, ,
2043 do_dbupdown (args,
"dbup");
2048 DEFUN (dbdown, args, ,
2058 do_dbupdown (args,
"dbdown");
2063 DEFUN (dbstep, args, ,
2087 error (
"dbstep: can only be called in debug mode");
2089 int nargin = args.
length ();
2096 std::string arg =
args(0).xstring_value (
"dbstep: input argument must be a string");
2105 else if (arg ==
"out")
2114 int n = atoi (arg.c_str ());
2117 error (
"dbstep: invalid argument");
2138 DEFUN (dbcont, args, ,
2146 error (
"dbcont: can only be called in debug mode");
2159 DEFUN (dbquit, args, ,
2168 error (
"dbquit: can only be called in debug mode");
2182 DEFUN (isdebugmode, args, ,
2195 DEFUN (__db_next_breakpoint_quiet__, args, ,
2204 int nargin = args.
length ();
2212 state =
args(0).bool_value ();
static void cleanup_instance(void)
static std::deque< size_t > get_line_offsets(const std::string &buf)
virtual std::map< std::string, octave_value > subfunctions(void) const
const Cell & contents(const_iterator p) const
bool is_empty(void) const
intmap do_remove_all_breakpoints_in_file(const std::string &fname, bool silent)
F77_RET_T const F77_INT const F77_INT const F77_INT const F77_DBLE const F77_DBLE F77_INT F77_DBLE * V
For example cd octave end example noindent changes the current working directory to file
static void dbstop_process_map_args(const octave_map &mv)
static fname_bp_map get_breakpoint_list(const octave_value_list &fname_list)
std::string canonicalize_file_name(const std::string &name)
static intmap add_breakpoint(const std::string &fname="", const intmap &lines=intmap(), const std::string &condition=bp_empty_string)
std::list< bp_type > breakpoints_and_conds(void)
void assign(const std::string &k, const Cell &val)
static octave_user_code * find_fcn_by_line(octave_user_code *main_fcn, int lineno, int *end_line=0)
intmap::const_iterator const_intmap_iterator
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
OCTINTERP_API void print_usage(void)
bool is_user_code(void) const
octave_idx_type numel(void) const
Number of elements in the array.
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE * f
octave_idx_type length(void) const
static bool have_breakpoints(void)
OCTINTERP_API std::string fcn_file_in_path(const std::string &)
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)
void octave_throw_interrupt_exception(void)
int int_value(bool req_int=false, bool frc_str_conv=false) const
#define DEFUN(name, args_name, nargout_name, doc)
void error(const char *fmt,...)
static void reset_debug_state(void)
std::set< std::string >::iterator bp_set_iterator
fname_bp_map do_get_breakpoint_list(const octave_value_list &fname_list)
std::string name(void) const
std::set< std::string > bp_set
static void dbclear_all_signals(void)
static octave_map stop_on_err_warn_status(bool toScreen)
T & elem(octave_idx_type n)
octave_idx_type numel(void) const
static void update_breakpoint(bool insert, const std::string &file, int line, const std::string &cond="")
Cell getfield(const std::string &key) const
static octave_user_code * get_user_code(const std::string &fname="")
static octave_value find_function(const std::string &name, const octave_value_list &args=octave_value_list(), bool local_funcs=true)
const_iterator end(void) const
void parse_dbfunction_params(const char *who, const octave_value_list &args, std::string &symbol_name, bp_table::intmap &lines, std::string &cond)
static bool quiet_breakpoint_flag
std::string do_find_bkpt_list(octave_value_list slist, std::string match)
This class gets nodes and searchs inside of 'info files'.
OCTAVE_EXPORT octave_value_list search each directory of the loadpath for element of the cell array and return the first that matches If the second optional argument return a cell array containing the list of all files that have the same name in the path If no files are found
static std::set< std::string > caught_that_stop
Cell cell_value(void) const
Cell cell_value(void) const
#define DEFALIAS(alias, name)
virtual tree_statement_list * body(void)=0
static int debug_user_code_line(void)
static std::string snarf_file(const std::string &fname)
std::set< std::string >::const_iterator const_bp_set_iterator
static std::set< std::string > warnings_that_stop
void do_remove_all_breakpoints(void)
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
bool isfield(const std::string &name) const
std::string string_value(bool force=false) const
static octave_user_code * debug_user_code(void)
nd deftypefn *octave_map m
std::complex< double > w(std::complex< double > z, double relerr=0)
std::map< int, int > intmap
bool is_string(void) const
bool strcmp(const T &str_a, const T &str_b)
True if strings are the same.
static char dir_sep_char(void)
bool do_add_breakpoint_1(octave_user_code *fcn, const std::string &fname, const intmap &line, const std::string &condition, intmap &retval)
OCTINTERP_API std::string do_which(const std::string &name)
void resize(const dim_vector &dv, const T &rfv)
OCTAVE_EXPORT octave_value_list W
std::map< std::string, std::list< bp_type > > fname_bp_map
virtual std::list< std::string > subfunction_names(void) const
static intmap remove_all_breakpoints_in_file(const std::string &fname, bool silent=false)
virtual bool is_user_function(void) const
the sparsity preserving column transformation such that that defines the pivoting threshold can be given in which case it defines the c
const_iterator begin(void) const
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)
void err_wrong_type_arg(const char *name, const char *s)
static uint32_t state[624]
static std::set< std::string > errors_that_stop
void warning(const char *fmt,...)
virtual std::string profiler_name(void) const
octave::unwind_protect frame
charNDArray max(char d, const charNDArray &m)
virtual std::string fcn_file_name(void) const
bool is_empty(void) const
OCTAVE_EXPORT octave_value_list the first data row corresponds to an index of zero The a spreadsheet style form such as the file is read until end of file is reached The such as text
static bp_table * instance
static bool condition_valid(const std::string &cond)
otherwise an error message is printed The permission mask is a UNIX concept used when creating new objects on a file system such as files
static void remove_all_breakpoints(void)
=val(i)}if ode{val(i)}occurs in table i
octave_value_list list_breakpoints(void)
static bool instance_ok(void)
tree_expression * expression(void)
size_t length(void) const
static int remove_breakpoint(const std::string &fname="", const intmap &lines=intmap())
bp_table::intmap add_breakpoint(const std::string &file, const bp_table::intmap &line, const std::string &condition)
Cell index(const octave_value_list &idx, bool resize_ok=false) const
octave::sys::file_stat fs(filename)
virtual bool is_assignment_expression(void) const
intmap do_add_breakpoint(const std::string &fname, const intmap &lines, const std::string &condition)
bool is_empty(void) const
tree_statement_list * stmt_list
bool is_expression(void) const
std::string get_file_line(const std::string &fname, size_t line)
octave_fields::const_iterator const_iterator
bp_table::intmap remove_all_breakpoints(const std::string &file)
Vector representing the dimensions (size) of an Array.
static bool goto_frame_relative(int n, bool verbose=false)
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
static octave_value intmap_to_ov(const bp_table::intmap &line)
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)