24 #if defined (HAVE_CONFIG_H) 86 fail = (U.
numel () > 1);
92 else if (! W(0).iscell ())
96 Cell V = W(0).cell_value ();
97 for (
int i = 0;
i <
V.numel ();
i++)
105 error (
"dbstop: invalid 'errs' field");
112 fail = (U.
numel () > 1);
118 else if (! W(0).iscell ())
122 Cell V = W(0).cell_value ();
123 for (
int i = 0;
i <
V.numel ();
i++)
131 error (
"dbstop: invalid 'caught' field");
138 fail = (U.
numel () > 1);
144 else if (! W(0).iscell ())
148 Cell V = W(0).cell_value ();
149 for (
int i = 0;
i <
V.numel ();
i++)
157 error (
"dbstop: invalid 'warn' field");
184 for (
auto& idx_line_p :
retval)
186 if (idx_line_p.second != 0)
192 const char *
s = strchr (
fname.c_str (),
'>');
213 if (cond.length () > 0)
219 error (
"dbstop: Cannot parse condition '%s'", cond.c_str ());
225 "condition is not empty, but has nothing to evaluate");
234 error (
"dbstop: condition cannot be an assignment. " 235 "Did you mean '=='?");
238 error (
"dbstop: condition must be an expression");
271 if (
nargin == 0 || ! args(0).is_string ())
275 bool seen_in =
false, seen_at =
false, seen_if =
false;
281 if (args(pos).is_string ())
289 else if (
arg ==
"at")
294 else if (
arg ==
"if")
299 else if (atoi (args(pos).string_value ().c_str ()) > 0)
308 error (
"%s: '%s' missing argument", who,
310 ?
"in" : (tok ==
dbstop_at ?
"at" :
"if")));
316 symbol_name = args(pos).string_value ();
318 error (
"%s: Too many function names specified -- %s",
319 who, symbol_name.c_str ());
320 else if (seen_at || seen_if)
321 error (
"%s: function name must come before line number and 'if'",
329 error (
"%s: Only one 'at' clause is allowed -- %s",
330 who, args(pos).string_value ().c_str ());
332 error (
"%s: line number must come before 'if' clause\n");
341 error (
"%s: function name must come before line number " 346 error (
"%s: line number must come before 'if' clause\n");
349 for ( ; pos <
nargin; pos++)
351 if (args(pos).is_string ())
353 int line = atoi (args(pos).string_value ().c_str ());
356 lines[list_idx++] =
line;
365 lines[list_idx++] = static_cast<int> (
arg.elem (j));
368 error (
"%s: Invalid argument type %s",
369 args(pos).type_name ().c_str ());
377 for (; pos <
nargin; pos++)
379 if (args(pos).is_string ())
380 cond +=
' ' + args(pos).string_value ();
382 error (
"%s: arguments to 'if' must all be strings", who);
385 cond = cond.substr (1);
390 int on_off = !
strcmp(who,
"dbstop");
393 std::set<std::string> *id_list =
nullptr;
394 bool *stop_flag =
nullptr;
396 if (condition ==
"error")
401 else if (condition ==
"warning")
406 else if (condition ==
"caught" &&
nargin > pos+1
407 && args(pos+1).string_value () ==
"error")
413 else if (condition ==
"interrupt")
417 else if (condition ==
"naninf")
419 #if defined (DBSTOP_NANINF) 420 Vdebug_on_naninf = on_off;
423 warning (
"%s: condition '%s' not yet supported",
424 who, condition.c_str ());
428 error (
"%s: invalid condition %s",
429 who, condition.c_str ());
437 if (! args(pos).is_string () ||
nargin > pos+1)
438 error (
"%s: ID must be a single string", who);
439 else if (on_off == 1)
441 id_list->insert (args(pos).string_value ());
446 id_list->erase (args(pos).string_value ());
447 if (id_list->empty ())
494 int lineno,
int *end_line =
nullptr)
502 std::map<std::string, octave_value> subfcns = main_fcn->
subfunctions ();
503 for (
const auto& str_val_p : subfcns)
505 if (str_val_p.second.is_user_function ())
507 auto *dbg_subfcn = str_val_p.second.user_function_value ();
514 if (dbg_subfcn->ending_line () < earliest_end
515 && dbg_subfcn->ending_line () >= lineno
516 && dbg_subfcn->beginning_line () <= lineno)
518 earliest_end = dbg_subfcn->ending_line ();
524 if (dbg_subfcn->beginning_line () >= lineno && ! next_fcn)
525 next_fcn = dbg_subfcn;
534 if (
e >= lineno &&
e < earliest_end)
546 if (end_line && earliest_end < *end_line)
547 *end_line = earliest_end;
561 error (
"add_breakpoint: unable to find function '%s'\n",
fname.c_str ());
569 for (
int i = 0;
i < len;
i++)
573 if (m !=
line.end ())
575 int lineno = m->second;
585 retval.insert (std::pair<int,int> (
i, ret_one.find (
i)->second));
611 if (results.
length () > 0)
615 for (
int i = 0;
i < len;
i++)
619 if (
p !=
line.end ())
621 int lineno =
p->second;
660 error (
"remove_breakpoint: unable to find function %s\n",
667 const std::list<std::string> subfcn_names
670 std::map<std::string, octave_value> subfcns
673 for (
const auto& subf_nm : subfcn_names)
675 const auto q = subfcns.find (subf_nm);
677 if (q != subfcns.end ())
718 error (
"remove_all_breakpoint_in_file: " 719 "unable to find function %s\n",
fname.c_str ());
746 for (
int i = 0;
i < slist.
length ();
i++)
748 if (slist(
i).string_value () == match)
750 retval = slist(
i).string_value ();
764 std::set<std::string> tmp_bp_set =
m_bp_set;
766 for (
auto& bp_fname : tmp_bp_set)
768 if (fname_list.
empty ()
783 if (! bkpts.empty ())
788 const std::list<std::string> subf_nm
791 std::map<std::string, octave_value> subfcns
794 for (
const auto& subfcn_nm : subf_nm)
796 const auto q = subfcns.find (subfcn_nm);
798 if (q != subfcns.end ())
803 cmds = dbg_subfcn->
body ();
806 std::list<bp_type> bkpts
809 if (! bkpts.empty ())
812 = bp_fname +
'>' + dbg_subfcn->
name ();
952 auto beg =
name.begin () + 2;
953 auto end =
name.end () - 1;
957 size_t name_len =
name.length ();
959 if (name_len > 2 &&
name.substr (name_len-2) ==
".m")
virtual std::list< std::string > subfunction_names(void) const
virtual octave::tree_statement_list * body(void)=0
Cell index(const octave_value_list &idx, bool resize_ok=false) const
virtual std::map< std::string, octave_value > subfunctions(void) const
octave_value find_function(const std::string &name, const octave_value_list &args=octave_value_list(), bool local_funcs=true)
std::set< std::string > m_warnings_that_stop
F77_RET_T const F77_INT const F77_INT const F77_INT const F77_DBLE const F77_DBLE F77_INT F77_DBLE * V
virtual bool is_user_function(void) const
For example cd octave end example noindent changes the current working directory to file
is already an absolute the name is checked against the file system instead of Octave s loadpath In this if otherwise an empty string is returned If the first argument is a cell array of 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
octave_user_code * get_user_code(const std::string &fname)
bp_table::intmap remove_all_breakpoints(const std::string &file)
octave_user_code * debug_user_code(void) const
OCTINTERP_API void print_usage(void)
virtual bool is_user_code(void) const
tree_statement_list * m_stmt_list
size_t length(void) const
intmap::const_iterator const_intmap_iterator
void error(const char *fmt,...)
void delete_breakpoint(int line)
octave_value_list list_breakpoints(void)
static void update_breakpoint(bool insert, const std::string &file, int line, const std::string &cond="")
bool condition_valid(const std::string &cond)
std::map< std::string, std::list< bp_type > > fname_bp_map
intmap add_breakpoint(const std::string &fname="", const intmap &lines=intmap(), const std::string &condition="")
int remove_breakpoint(const std::string &fname="", const intmap &lines=intmap())
virtual std::string fcn_file_name(void) const
std::set< std::string >::iterator bp_set_iterator
OCTAVE_EXPORT octave_value_list isnumeric
std::set< std::string > m_caught_that_stop
bool is_defined(void) const
void dbclear_all_signals(void)
bool isfield(const std::string &name) const
symbol_table & __get_symbol_table__(const std::string &who)
nd deftypefn *std::string name
octave_value & assign(assign_op op, const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
std::list< bp_type > breakpoints_and_conds(void)
std::set< std::string > m_errors_that_stop
void parse_dbfunction_params(const char *, const octave_value_list &, std::string &, bp_table::intmap &, std::string &)
std::set< std::string > m_bp_set
octave_idx_type numel(const octave_value_list &idx)
std::string find_bkpt_list(octave_value_list slist, std::string match)
bool have_breakpoints(void)
intmap remove_all_breakpoints_in_file(const std::string &fname, bool silent=false)
std::complex< double > w(std::complex< double > z, double relerr=0)
bool strcmp(const T &str_a, const T &str_b)
True if strings are the same.
Array< octave_value > array_value(void) const
const Cell & contents(const_iterator p) const
std::map< int, int > intmap
virtual octave_user_code * user_code_value(bool silent=false)
octave_map stop_on_err_warn_status(bool to_screen)
int remove_breakpoint_1(octave_user_code *fcn, const std::string &, const intmap &lines)
void warning(const char *fmt,...)
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
void dbstop_process_map_args(const octave_map &mv)
charNDArray max(char d, const charNDArray &m)
fname_bp_map get_breakpoint_list(const octave_value_list &fname_list)
void remove_all_breakpoints(void)
call_stack & __get_call_stack__(const std::string &who)
bp_table::intmap add_breakpoint(const std::string &file, const bp_table::intmap &line, const std::string &condition)
octave_idx_type length(void) const
bool add_breakpoint_1(octave_user_code *fcn, const std::string &fname, const intmap &line, const std::string &condition, intmap &retval)
std::set< std::string >::const_iterator const_bp_set_iterator
virtual std::string profiler_name(void) const
bool is_expression(void) const
octave_idx_type numel(void) const
Number of elements in the array.
Vector representing the dimensions (size) of an Array.
std::string name(void) const
virtual bool is_assignment_expression(void) const
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_user_code * find_fcn_by_line(octave_user_code *main_fcn, int lineno, int *end_line=nullptr)
tree_expression * expression(void)