GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
error.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2018 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software: you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <cstdarg>
28 #include <cstdlib>
29 #include <cstring>
30 
31 #include <iomanip>
32 #include <iostream>
33 #include <sstream>
34 #include <string>
35 
36 #include "bp-table.h"
37 #include "builtin-defun-decls.h"
38 #include "call-stack.h"
39 #include "defun.h"
40 #include "error.h"
41 #include "input.h"
42 #include "interpreter-private.h"
43 #include "interpreter.h"
44 #include "oct-map.h"
45 #include "octave.h"
46 #include "ov-usr-fcn.h"
47 #include "ov.h"
48 #include "ovl.h"
49 #include "pager.h"
50 #include "pt-eval.h"
51 #include "unwind-prot.h"
52 #include "utils.h"
53 #include "variables.h"
54 
55 // TRUE means that Octave will try to beep obnoxiously before printing
56 // error messages.
57 static bool Vbeep_on_error = false;
58 
59 // TRUE means that Octave will try to enter the debugger when an error
60 // is encountered. This will also inhibit printing of the normal
61 // traceback message (you will only see the top-level error message).
62 bool Vdebug_on_error = false;
63 
64 // TRUE means that Octave will try to enter the debugger when an error
65 // is encountered within the 'try' section of a 'try' / 'catch' block.
66 bool Vdebug_on_caught = false;
67 
68 // TRUE means that Octave will try to enter the debugger when a warning
69 // is encountered.
70 bool Vdebug_on_warning = false;
71 
72 // TRUE means that Octave will try to display a stack trace when a
73 // warning is encountered.
74 static bool Vbacktrace_on_warning = true;
75 
76 // TRUE means that Octave will print a verbose warning. Currently unused.
77 static bool Vverbose_warning;
78 
79 // TRUE means that Octave will print no warnings, but lastwarn will be updated
80 static bool Vquiet_warning = false;
81 
82 // A structure containing (most of) the current state of warnings.
84 
85 // The text of the last error message.
87 
88 // The text of the last warning message.
90 
91 // The last warning message id.
93 
94 // The last error message id.
96 
97 // The last file in which an error occurred
99 
100 // Current error state.
101 //
102 // Valid values:
103 //
104 // 0: no error
105 // 1: an error has occurred
106 //
107 int error_state = 0;
108 
109 // Tell the error handler whether to print messages, or just store
110 // them for later. Used for handling errors in eval() and
111 // the 'unwind_protect' statement.
113 
114 // The number of layers of try / catch blocks we're in. Used to print
115 // "caught error" instead of error when "dbstop if caught error" is on.
116 int in_try_catch = 0;
117 
118 // TRUE means error messages are turned off.
120 
121 // TRUE means warning messages are turned off.
123 
124 void
126 {
128  in_try_catch = 0;
129  discard_error_messages = false;
130 }
131 
132 static void
134 {
135  octave_scalar_map initw;
136 
137  initw.setfield ("identifier", "all");
138  initw.setfield ("state", state);
139 
140  warning_options = initw;
141 }
142 
143 static octave_map
145 {
147  = octave::__get_call_stack__ ("initialize_last_error_stack");
148 
149  return cs.empty_backtrace ();
150 }
151 
152 static void
153 verror (bool save_last_error, std::ostream& os,
154  const char *name, const char *id, const char *fmt, va_list args,
155  bool with_cfn = false)
156 {
158  return;
159 
162 
163  // FIXME: we really want to capture the message before it has all the
164  // formatting goop attached to it. We probably also want just the
165  // message, not the traceback information.
166 
167  std::ostringstream output_buf;
168 
169  octave_vformat (output_buf, fmt, args);
170 
171  std::string base_msg = output_buf.str ();
172 
173  bool to_beep_or_not_to_beep_p = Vbeep_on_error;
174 
175  std::string msg_string;
176 
177  if (to_beep_or_not_to_beep_p)
178  msg_string = "\a";
179 
180  if (name)
181  {
182  if (in_try_catch && ! strcmp (name, "error"))
183  msg_string += "caught error: ";
184  else
185  msg_string += std::string (name) + ": ";
186  }
187 
189 
190  // If with_fcn is specified, we'll attempt to prefix the message with the name
191  // of the current executing function. But we'll do so only if:
192  // 1. the name is not empty (anonymous function)
193  // 2. it is not already there (including the following colon)
194  if (with_cfn)
195  {
196  octave_function *curfcn = cs.current ();
197  if (curfcn)
198  {
199  std::string cfn = curfcn->name ();
200  if (! cfn.empty ())
201  {
202  cfn += ':';
203  if (cfn.length () > base_msg.length ()
204  || base_msg.compare (0, cfn.length (), cfn) != 0)
205  {
206  msg_string += cfn + ' ';
207  }
208  }
209  }
210  }
211 
212  msg_string += base_msg + '\n';
213 
214  if (save_last_error)
215  {
216  // This is the first error in a possible series.
217 
218  Vlast_error_id = id;
219  Vlast_error_message = base_msg;
220 
222 
223  if (fcn)
224  {
225  octave_idx_type curr_frame = -1;
226 
227  Vlast_error_stack = cs.backtrace (0, curr_frame);
228  }
229  else
231  }
232 
234  {
235  octave_diary << msg_string;
236  os << msg_string;
237  }
238 }
239 
240 static void
241 pr_where_2 (std::ostream& os, const char *fmt, va_list args)
242 {
243  if (fmt)
244  {
245  if (*fmt)
246  {
247  size_t len = strlen (fmt);
248 
249  if (len > 0)
250  {
251  if (fmt[len - 1] == '\n')
252  {
253  if (len > 1)
254  {
255  std::string tmp_fmt (fmt, len - 1);
256  verror (false, os, nullptr, "", tmp_fmt.c_str (), args);
257  }
258  }
259  else
260  verror (false, os, nullptr, "", fmt, args);
261  }
262  }
263  }
264  else
265  panic ("pr_where_2: invalid format");
266 }
267 
268 static void
269 pr_where_1 (std::ostream& os, const char *fmt, ...)
270 {
271  va_list args;
272  va_start (args, fmt);
273  pr_where_2 (os, fmt, args);
274  va_end (args);
275 }
276 
277 struct
279 {
281  int line;
282  int column;
283 };
284 
285 static void
286 pr_where (std::ostream& os, const char *who,
287  const std::list<error_stack_frame>& frames)
288 {
289  size_t nframes = frames.size ();
290 
291  if (nframes > 0)
292  pr_where_1 (os, "%s: called from\n", who);
293 
294  for (const auto& frm : frames)
295  {
296  std::string fcn_name = frm.name;
297  int line = frm.line;
298  int column = frm.column;
299 
300  if (line > 0)
301  {
302  if (column > 0)
303  pr_where_1 (os, " %s at line %d column %d\n",
304  fcn_name.c_str (), line, column);
305  else
306  pr_where_1 (os, " %s at line %d\n", fcn_name.c_str (), line);
307  }
308  else
309  pr_where_1 (os, " %s\n", fcn_name.c_str ());
310  }
311 }
312 
313 static void
314 pr_where (std::ostream& os, const char *who)
315 {
317 
318  std::list<octave::call_stack::stack_frame> call_stack_frames
319  = cs.backtrace_frames ();
320 
321  // Print the error message only if it is different from the previous one;
322  // Makes the output more concise and readable.
323  call_stack_frames.unique ();
324 
325  std::list<error_stack_frame> frames;
326  for (const auto& frm : call_stack_frames)
327  {
329 
330  frame.name = frm.fcn_name ();
331  frame.line = frm.line ();
332  frame.column = frm.column ();
333 
334  frames.push_back (frame);
335  }
336 
337  pr_where (os, who, frames);
338 }
339 
340 octave::execution_exception
341 make_execution_exception (const char *who)
342 {
343  std::ostringstream buf;
344 
345  pr_where (buf, who);
346 
347  octave::execution_exception retval;
348 
349  retval.set_stack_trace (buf.str ());
350 
351  return retval;
352 }
353 
354 static void
355 maybe_enter_debugger (octave::execution_exception& e,
356  bool show_stack_trace = false)
357 {
358  octave::call_stack& cs = octave::__get_call_stack__ ("maybe_enter_debugger");
359  octave::bp_table& bptab = octave::__get_bp_table__ ("maybe_enter_debugger");
360 
361  if ((octave::application::interactive ()
362  || octave::application::forced_interactive ())
363  && ((Vdebug_on_error && bptab.debug_on_err (last_error_id ()))
365  && cs.caller_user_code ())
366  {
369  Vdebug_on_error = false;
370 
372 
374 
375  if (show_stack_trace)
376  {
377  std::string stack_trace = e.info ();
378 
379  if (! stack_trace.empty ())
380  {
381  std::cerr << stack_trace;
382 
383  e.set_stack_trace ();
384  }
385  }
386 
388  }
389 }
390 
391 // Warning messages are never buffered.
392 
393 static void
394 vwarning (const char *name, const char *id, const char *fmt, va_list args)
395 {
397  return;
398 
400 
401  std::ostringstream output_buf;
402 
403  octave_vformat (output_buf, fmt, args);
404 
405  // FIXME: we really want to capture the message before it has all the
406  // formatting goop attached to it. We probably also want just the
407  // message, not the traceback information.
408 
409  std::string base_msg = output_buf.str ();
410  std::string msg_string;
411 
412  if (name)
413  msg_string = std::string (name) + ": ";
414 
415  msg_string += base_msg + '\n';
416 
418  Vlast_warning_message = base_msg;
419 
420  if (! Vquiet_warning)
421  {
422  octave_diary << msg_string;
423 
424  std::cerr << msg_string;
425  }
426 }
427 
428 void
429 vmessage (const char *name, const char *fmt, va_list args)
430 {
431  verror (false, std::cerr, name, "", fmt, args);
432 }
433 
434 void
435 message (const char *name, const char *fmt, ...)
436 {
437  va_list args;
438  va_start (args, fmt);
439  vmessage (name, fmt, args);
440  va_end (args);
441 }
442 
443 void
444 vmessage_with_id (const char *name, const char *id, const char *fmt,
445  va_list args)
446 {
447  verror (false, std::cerr, name, id, fmt, args);
448 }
449 
450 void
451 message_with_id (const char *name, const char *id, const char *fmt, ...)
452 {
453  va_list args;
454  va_start (args, fmt);
455  vmessage_with_id (name, id, fmt, args);
456  va_end (args);
457 }
458 
459 OCTAVE_NORETURN static
460 void
461 usage_1 (octave::execution_exception& e, const char *id,
462  const char *fmt, va_list args)
463 {
464  verror (true, std::cerr, "usage", id, fmt, args);
465 
467 
468  throw e;
469 }
470 
471 OCTAVE_NORETURN static
472 void
473 usage_1 (const char *id, const char *fmt, va_list args)
474 {
475  octave::execution_exception e = make_execution_exception ("usage");
476 
477  usage_1 (e, id, fmt, args);
478 }
479 
480 void
481 vusage (const char *fmt, va_list args)
482 {
483  usage_1 ("", fmt, args);
484 }
485 
486 void
487 usage (const char *fmt, ...)
488 {
489  va_list args;
490  va_start (args, fmt);
491  usage_1 ("", fmt, args);
492  va_end (args);
493 }
494 
495 void
496 vusage_with_id (const char *id, const char *fmt, va_list args)
497 {
498  usage_1 (id, fmt, args);
499 }
500 
501 void
502 usage_with_id (const char *id, const char *fmt, ...)
503 {
504  va_list args;
505  va_start (args, fmt);
506  vusage_with_id (id, fmt, args);
507  va_end (args);
508 }
509 
510 OCTAVE_NORETURN static
511 void
512 error_1 (octave::execution_exception& e, std::ostream& os,
513  const char *name, const char *id, const char *fmt,
514  va_list args, bool with_cfn = false)
515 {
516  bool show_stack_trace = false;
517 
518  if (fmt)
519  {
520  if (*fmt)
521  {
522  size_t len = strlen (fmt);
523 
524  if (len > 0)
525  {
526  if (fmt[len - 1] == '\n')
527  {
528  if (len > 1)
529  {
530  std::string tmp_fmt (fmt, len - 1);
531  verror (true, os, name, id, tmp_fmt.c_str (),
532  args, with_cfn);
533  }
534 
535  // If format ends with newline, suppress stack trace.
536  e.set_stack_trace ();
537  }
538  else
539  {
540  verror (true, os, name, id, fmt, args, with_cfn);
541 
543  = octave::__get_call_stack__ ("error_1");
544 
545  bool in_user_code = cs.caller_user_code () != nullptr;
546 
547  if (in_user_code && ! discard_error_messages)
548  show_stack_trace = true;
549  }
550  }
551  }
552  }
553  else
554  panic ("error_1: invalid format");
555 
556  maybe_enter_debugger (e, show_stack_trace);
557 
558  throw e;
559 }
560 
561 OCTAVE_NORETURN static
562 void
563 error_1 (std::ostream& os, const char *name, const char *id,
564  const char *fmt, va_list args, bool with_cfn = false)
565 {
566  octave::execution_exception e = make_execution_exception ("error");
567 
568  error_1 (e, os, name, id, fmt, args, with_cfn);
569 }
570 
571 void
572 verror (const char *fmt, va_list args)
573 {
574  error_1 (std::cerr, "error", "", fmt, args);
575 }
576 
577 void
578 error (const char *fmt, ...)
579 {
580  va_list args;
581  va_start (args, fmt);
582  verror (fmt, args);
583  va_end (args);
584 }
585 
586 void
587 verror (octave::execution_exception& e, const char *fmt, va_list args)
588 {
589  error_1 (e, std::cerr, "error", "", fmt, args);
590 }
591 
592 void
593 error (octave::execution_exception& e, const char *fmt, ...)
594 {
595  va_list args;
596  va_start (args, fmt);
597  verror (e, fmt, args);
598  va_end (args);
599 }
600 
601 void
602 verror_with_cfn (const char *fmt, va_list args)
603 {
604  error_1 (std::cerr, "error", "", fmt, args, true);
605 }
606 
607 void
608 error_with_cfn (const char *fmt, ...)
609 {
610  va_list args;
611  va_start (args, fmt);
612  verror_with_cfn (fmt, args);
613  va_end (args);
614 }
615 
616 void
617 verror_with_id (const char *id, const char *fmt, va_list args)
618 {
619  error_1 (std::cerr, "error", id, fmt, args);
620 }
621 
622 void
623 error_with_id (const char *id, const char *fmt, ...)
624 {
625  va_list args;
626  va_start (args, fmt);
627  verror_with_id (id, fmt, args);
628  va_end (args);
629 }
630 
631 void
632 verror_with_id_cfn (const char *id, const char *fmt, va_list args)
633 {
634  error_1 (std::cerr, "error", id, fmt, args, true);
635 }
636 
637 void
638 error_with_id_cfn (const char *id, const char *fmt, ...)
639 {
640  va_list args;
641  va_start (args, fmt);
642  verror_with_id_cfn (id, fmt, args);
643  va_end (args);
644 }
645 
646 static int
648 {
649  // -1: not found
650  // 0: found, "off"
651  // 1: found, "on"
652  // 2: found, "error"
653 
654  if (state == "off")
655  return 0;
656  else if (state == "on")
657  return 1;
658  else if (state == "error")
659  return 2;
660  else
661  return -1;
662 }
663 
664 // For given warning ID, return 0 if warnings are disabled, 1 if
665 // enabled, and 2 if the given ID should be an error instead of a
666 // warning.
667 
668 int
670 {
671  int retval = 0;
672 
673  int all_state = -1;
674  int id_state = -1;
675 
677 
678  if (nel > 0)
679  {
680  Cell identifier = warning_options.contents ("identifier");
681  Cell state = warning_options.contents ("state");
682 
683  bool all_found = false;
684  bool id_found = false;
685 
686  for (octave_idx_type i = 0; i < nel; i++)
687  {
688  octave_value ov = identifier(i);
689  std::string ovs = ov.string_value ();
690 
691  if (! all_found && ovs == "all")
692  {
693  all_state = check_state (state(i).string_value ());
694 
695  if (all_state >= 0)
696  all_found = true;
697  }
698 
699  if (! id_found && ovs == id)
700  {
701  id_state = check_state (state(i).string_value ());
702 
703  if (id_state >= 0)
704  id_found = true;
705  }
706 
707  if (all_found && id_found)
708  break;
709  }
710  }
711 
712  // If "all" is not present, assume warnings are enabled.
713  if (all_state == -1)
714  all_state = 1;
715 
716  if (all_state == 0)
717  {
718  if (id_state >= 0)
719  retval = id_state;
720  }
721  else if (all_state == 1)
722  {
723  if (id_state == 0 || id_state == 2)
724  retval = id_state;
725  else
726  retval = all_state;
727  }
728  else if (all_state == 2)
729  {
730  if (id_state == 0)
731  retval= id_state;
732  else
733  retval = all_state;
734  }
735 
736  return retval;
737 }
738 
739 static void
740 warning_1 (const char *id, const char *fmt, va_list args)
741 {
742  int warn_opt = warning_enabled (id);
743 
744  if (warn_opt == 2)
745  {
746  // Handle this warning as an error.
747 
748  error_1 (std::cerr, "error", id, fmt, args);
749  }
750  else if (warn_opt == 1)
751  {
752  bool fmt_suppresses_backtrace = false;
753  size_t fmt_len = (fmt ? strlen (fmt) : 0);
754  fmt_suppresses_backtrace = (fmt_len > 0 && fmt[fmt_len-1] == '\n');
755 
756  if (fmt_suppresses_backtrace && fmt_len > 1)
757  {
758  // Strip newline before issuing warning
759  std::string tmp_fmt (fmt, fmt_len - 1);
760  vwarning ("warning", id, tmp_fmt.c_str (), args);
761  }
762  else
763  vwarning ("warning", id, fmt, args);
764 
766 
767  bool in_user_code = cs.caller_user_code () != nullptr;
768 
769  if (! fmt_suppresses_backtrace && in_user_code
772  pr_where (std::cerr, "warning");
773 
774  octave::bp_table& bptab
775  = octave::__get_bp_table__ ("warning_1");
776 
777  if ((octave::application::interactive ()
778  || octave::application::forced_interactive ())
779  && Vdebug_on_warning && in_user_code && bptab.debug_on_warn (id))
780  {
783  Vdebug_on_warning = false;
784 
786 
788 
790  }
791  }
792 }
793 
794 void
795 vwarning (const char *fmt, va_list args)
796 {
797  warning_1 ("", fmt, args);
798 }
799 
800 void
801 warning (const char *fmt, ...)
802 {
803  va_list args;
804  va_start (args, fmt);
805  vwarning (fmt, args);
806  va_end (args);
807 }
808 
809 void
810 vwarning_with_id (const char *id, const char *fmt, va_list args)
811 {
812  warning_1 (id, fmt, args);
813 }
814 
815 void
816 warning_with_id (const char *id, const char *fmt, ...)
817 {
818  va_list args;
819  va_start (args, fmt);
820  vwarning_with_id (id, fmt, args);
821  va_end (args);
822 }
823 
824 void
825 vparse_error (const char *fmt, va_list args)
826 {
827  error_1 (std::cerr, nullptr, "", fmt, args);
828 }
829 
830 void
831 parse_error (const char *fmt, ...)
832 {
833  va_list args;
834  va_start (args, fmt);
835  vparse_error (fmt, args);
836  va_end (args);
837 }
838 
839 void
840 vparse_error_with_id (const char *id, const char *fmt, va_list args)
841 {
842  error_1 (std::cerr, nullptr, id, fmt, args);
843 }
844 
845 void
846 parse_error_with_id (const char *id, const char *fmt, ...)
847 {
848  va_list args;
849  va_start (args, fmt);
850  vparse_error_with_id (id, fmt, args);
851  va_end (args);
852 }
853 
854 void
855 rethrow_error (const char *id, const char *fmt, ...)
856 {
857  va_list args;
858  va_start (args, fmt);
859  error_1 (std::cerr, nullptr, id, fmt, args);
860  va_end (args);
861 }
862 
863 static std::list<error_stack_frame>
865 {
866  std::list<error_stack_frame> frames;
867 
868  Cell name = stack.contents ("name");
869  Cell line = stack.contents ("line");
870  Cell column;
871  bool have_column = false;
872  if (stack.contains ("column"))
873  {
874  have_column = true;
875  column = stack.contents ("column");
876  }
877 
878  octave_idx_type nel = name.numel ();
879 
880  for (octave_idx_type i = 0; i < nel; i++)
881  {
883 
884  frame.name = name(i).string_value ();
885  frame.line = line(i).int_value ();
886  frame.column = (have_column ? column(i).int_value () : -1);
887 
888  frames.push_back (frame);
889  }
890 
891  return frames;
892 }
893 
894 static void
895 rethrow_error_1 (const char *id, const char *fmt, ...)
896 {
897  va_list args;
898  va_start (args, fmt);
899  verror (false, std::cerr, nullptr, id, fmt, args);
900  va_end (args);
901 }
902 
903 OCTAVE_NORETURN static
904 void
905 rethrow_error (const std::string& id, const std::string& msg,
906  const octave_map& stack)
907 {
908  octave::execution_exception e = make_execution_exception ("error");
909 
910  if (! stack.isempty ()
911  && ! (stack.contains ("file") && stack.contains ("name")
912  && stack.contains ("line")))
913  error ("rethrow: STACK struct must contain the fields 'file', 'name', and 'line'");
914 
915  Vlast_error_id = id;
916  Vlast_error_message = msg;
917  Vlast_error_stack = stack;
918 
919  size_t len = msg.length ();
920 
921  std::string tmp_msg (msg);
922  if (len > 1 && tmp_msg[len-1] == '\n')
923  {
924  tmp_msg.erase (len - 1);
925 
926  rethrow_error_1 (id.c_str (), "%s\n", tmp_msg.c_str ());
927  }
928  else
929  rethrow_error_1 (id.c_str (), "%s", tmp_msg.c_str ());
930 
931  if (! stack.isempty ())
932  {
933  std::ostringstream buf;
934 
935  pr_where (buf, "error", make_stack_frame_list (stack));
936 
937  e.set_stack_trace (buf.str ());
938  }
939 
940  throw e;
941 }
942 
943 void
944 panic (const char *fmt, ...)
945 {
946  va_list args;
947  va_start (args, fmt);
949  discard_error_messages = false;
950  verror (false, std::cerr, "panic", "", fmt, args);
951  va_end (args);
952  abort ();
953 }
954 
955 static void
956 defun_usage_message_1 (const char *fmt, ...)
957 {
958  va_list args;
959  va_start (args, fmt);
960  error_1 (octave_stdout, nullptr, "", fmt, args);
961  va_end (args);
962 }
963 
964 void
966 {
967  defun_usage_message_1 ("%s", msg.c_str ());
968 }
969 
970 typedef void (*error_fun)(const char *, const char *, ...);
971 
972 extern octave_value_list Fsprintf (const octave_value_list&, int);
973 
974 static std::string
975 handle_message (error_fun f, const char *id, const char *msg,
976  const octave_value_list& args, bool have_fmt)
977 {
979 
980  std::string tstr;
981 
982  if (args.length () > 0)
983  {
985 
986  if (have_fmt)
987  {
988  octave_value_list tmp = Fsprintf (args, 1);
989  arg = tmp(0);
990  }
991  else
992  arg = args(0);
993 
994  if (arg.is_defined ())
995  {
996  if (arg.is_string ())
997  {
998  tstr = arg.string_value ();
999  msg = tstr.c_str ();
1000 
1001  if (! msg)
1002  return retval;
1003  }
1004  else if (arg.isempty ())
1005  return retval;
1006  }
1007  }
1008 
1009 // Ugh.
1010 
1011  size_t len = strlen (msg);
1012 
1013  if (len > 0)
1014  {
1015  if (msg[len - 1] == '\n')
1016  {
1017  if (len > 1)
1018  {
1019  std::string tmp_msg (msg, len - 1);
1020  f (id, "%s\n", tmp_msg.c_str ());
1021  retval = tmp_msg;
1022  }
1023  }
1024  else
1025  {
1026  f (id, "%s", msg);
1027  retval = msg;
1028  }
1029  }
1030 
1031  return retval;
1032 }
1033 
1034 DEFUN (rethrow, args, ,
1035  doc: /* -*- texinfo -*-
1036 @deftypefn {} {} rethrow (@var{err})
1037 Reissue a previous error as defined by @var{err}.
1038 
1039 @var{err} is a structure that must contain at least the @qcode{"message"}
1040 and @qcode{"identifier"} fields. @var{err} can also contain a field
1041 @qcode{"stack"} that gives information on the assumed location of the
1042 error. Typically @var{err} is returned from @code{lasterror}.
1043 @seealso{lasterror, lasterr, error}
1044 @end deftypefn */)
1045 {
1046  if (args.length () != 1)
1047  print_usage ();
1048 
1049  const octave_scalar_map err = args(0).scalar_map_value ();
1050 
1051  if (! (err.contains ("message") && err.contains ("identifier")))
1052  error ("rethrow: ERR struct must contain the fields 'message' and 'identifier'");
1053 
1054  std::string msg = err.contents ("message").string_value ();
1055  std::string id = err.contents ("identifier").string_value ();
1056 
1057  octave_map err_stack = initialize_last_error_stack ();
1058 
1059  if (err.contains ("stack"))
1060  err_stack = err.contents ("stack").xmap_value ("ERR.STACK must be a struct");
1061 
1062  rethrow_error (id, msg, err_stack);
1063 
1064  return ovl ();
1065 }
1066 
1067 // Determine whether the first argument to error or warning function
1068 // should be handled as the message identifier or as the format string.
1069 
1070 static bool
1071 maybe_extract_message_id (const std::string& caller,
1072  const octave_value_list& args,
1073  octave_value_list& nargs,
1074  std::string& id)
1075 {
1076  nargs = args;
1077  id = "";
1078 
1079  int nargin = args.length ();
1080 
1081  bool have_fmt = nargin > 1;
1082 
1083  if (nargin > 0)
1084  {
1085  std::string arg1 = args(0).string_value ();
1086 
1087  // For compatibility with Matlab, an identifier must contain ':',
1088  // but not at the beginning or the end, and it must not contain '%'
1089  // (even if it is not a valid conversion operator) or whitespace.
1090 
1091  if (arg1.find_first_of ("% \f\n\r\t\v") == std::string::npos
1092  && arg1.find (':') != std::string::npos
1093  && arg1[0] != ':'
1094  && arg1.back () != ':')
1095  {
1096  if (nargin > 1)
1097  {
1098  id = arg1;
1099 
1100  nargs.resize (nargin-1);
1101 
1102  for (int i = 1; i < nargin; i++)
1103  nargs(i-1) = args(i);
1104  }
1105  else
1106  nargs(0) = "call to " + caller
1107  + " with message identifier '" + arg1
1108  + "' requires message";
1109  }
1110  }
1111 
1112  return have_fmt;
1113 }
1114 
1115 DEFUN (error, args, ,
1116  doc: /* -*- texinfo -*-
1117 @deftypefn {} {} error (@var{template}, @dots{})
1118 @deftypefnx {} {} error (@var{id}, @var{template}, @dots{})
1119 Display an error message and stop m-file execution.
1120 
1121 Format the optional arguments under the control of the template string
1122 @var{template} using the same rules as the @code{printf} family of
1123 functions (@pxref{Formatted Output}) and print the resulting message
1124 on the @code{stderr} stream. The message is prefixed by the character
1125 string @samp{error: }.
1126 
1127 Calling @code{error} also sets Octave's internal error state such that
1128 control will return to the top level without evaluating any further
1129 commands. This is useful for aborting from functions or scripts.
1130 
1131 If the error message does not end with a newline character, Octave will
1132 print a traceback of all the function calls leading to the error. For
1133 example, given the following function definitions:
1134 
1135 @example
1136 @group
1137 function f () g (); end
1138 function g () h (); end
1139 function h () nargin == 1 || error ("nargin != 1"); end
1140 @end group
1141 @end example
1142 
1143 @noindent
1144 calling the function @code{f} will result in a list of messages that
1145 can help you to quickly find the exact location of the error:
1146 
1147 @example
1148 @group
1149 f ()
1150 error: nargin != 1
1151 error: called from:
1152 error: h at line 1, column 27
1153 error: g at line 1, column 15
1154 error: f at line 1, column 15
1155 @end group
1156 @end example
1157 
1158 If the error message ends in a newline character, Octave will print the
1159 message but will not display any traceback messages as it returns
1160 control to the top level. For example, modifying the error message
1161 in the previous example to end in a newline causes Octave to only print
1162 a single message:
1163 
1164 @example
1165 @group
1166 function h () nargin == 1 || error ("nargin != 1\n"); end
1167 f ()
1168 error: nargin != 1
1169 @end group
1170 @end example
1171 
1172 A null string ("") input to @code{error} will be ignored and the code
1173 will continue running as if the statement were a NOP@. This is for
1174 compatibility with @sc{matlab}. It also makes it possible to write code
1175 such as
1176 
1177 @example
1178 @group
1179 err_msg = "";
1180 if (CONDITION 1)
1181  err_msg = "CONDITION 1 found";
1182 elseif (CONDITION2)
1183  err_msg = "CONDITION 2 found";
1184 @dots{}
1185 endif
1186 error (err_msg);
1187 @end group
1188 @end example
1189 
1190 @noindent
1191 which will only stop execution if an error has been found.
1192 
1193 Implementation Note: For compatibility with @sc{matlab}, escape
1194 sequences in @var{template} (e.g., @qcode{"@xbackslashchar{}n"} =>
1195 newline) are processed regardless of whether @var{template} has been defined
1196 with single quotes, as long as there are two or more input arguments. To
1197 disable escape sequence expansion use a second backslash before the sequence
1198 (e.g., @qcode{"@xbackslashchar{}@xbackslashchar{}n"}) or use the
1199 @code{regexptranslate} function.
1200 @seealso{warning, lasterror}
1201 @end deftypefn */)
1202 {
1203 
1204  int nargin = args.length ();
1205 
1206  if (nargin == 0)
1207  print_usage ();
1208 
1210 
1211  octave_value_list nargs = args;
1212 
1213  std::string id;
1214 
1215  bool have_fmt = false;
1216 
1217  if (nargin == 1 && args(0).isstruct ())
1218  {
1219  // empty struct is not an error. return and resume calling function.
1220  if (args(0).isempty ())
1221  return retval;
1222 
1223  octave_scalar_map m = args(0).scalar_map_value ();
1224 
1225  // empty struct is not an error. return and resume calling function.
1226  if (m.nfields () == 0)
1227  return retval;
1228 
1229  if (m.contains ("message"))
1230  {
1231  octave_value c = m.getfield ("message");
1232 
1233  if (c.is_string ())
1234  nargs(0) = c.string_value ();
1235  }
1236 
1237  if (m.contains ("identifier"))
1238  {
1239  octave_value c = m.getfield ("identifier");
1240 
1241  if (c.is_string ())
1242  id = c.string_value ();
1243  }
1244 
1245  // FIXME: also need to handle "stack" field in error structure,
1246  // but that will require some more significant surgery on
1247  // handle_message, error_with_id, etc.
1248  }
1249  else
1250  have_fmt = maybe_extract_message_id ("error", args, nargs, id);
1251 
1252  handle_message (error_with_id, id.c_str (), "unspecified error",
1253  nargs, have_fmt);
1254 
1255  return retval;
1256 }
1257 
1258 static octave_scalar_map
1259 warning_query (const std::string& id_arg)
1260 {
1262 
1263  std::string id = id_arg;
1264 
1265  if (id == "last")
1266  id = Vlast_warning_id;
1267 
1268  Cell ident = warning_options.contents ("identifier");
1269  Cell state = warning_options.contents ("state");
1270 
1271  octave_idx_type nel = ident.numel ();
1272 
1273  assert (nel != 0);
1274 
1275  bool found = false;
1276 
1277  std::string val;
1278 
1279  for (octave_idx_type i = 0; i < nel; i++)
1280  {
1281  if (ident(i).string_value () == id)
1282  {
1283  val = state(i).string_value ();
1284  found = true;
1285  break;
1286  }
1287  }
1288 
1289  if (! found)
1290  {
1291  for (octave_idx_type i = 0; i < nel; i++)
1292  {
1293  if (ident(i).string_value () == "all")
1294  {
1295  val = state(i).string_value ();
1296  found = true;
1297  break;
1298  }
1299  }
1300  }
1301 
1302  // The warning state "all" is always supposed to remain in the list,
1303  // so we should always find a state, either explicitly or by using the
1304  // state for "all".
1305 
1306  assert (found);
1307 
1308  retval.assign ("identifier", id);
1309  retval.assign ("state", val);
1310 
1311  return retval;
1312 }
1313 
1314 static std::string
1315 default_warning_state (void)
1316 {
1317  std::string retval = "on";
1318 
1319  Cell ident = warning_options.contents ("identifier");
1320  Cell state = warning_options.contents ("state");
1321 
1322  octave_idx_type nel = ident.numel ();
1323 
1324  for (octave_idx_type i = 0; i < nel; i++)
1325  {
1326  if (ident(i).string_value () == "all")
1327  {
1328  retval = state(i).string_value ();
1329  break;
1330  }
1331  }
1332 
1333  return retval;
1334 }
1335 
1336 static void
1337 display_warning_options (std::ostream& os)
1338 {
1339  Cell ident = warning_options.contents ("identifier");
1340  Cell state = warning_options.contents ("state");
1341 
1342  octave_idx_type nel = ident.numel ();
1343 
1344  std::string all_state = default_warning_state ();
1345 
1346  if (all_state == "on")
1347  os << "By default, warnings are enabled.";
1348  else if (all_state == "off")
1349  os << "By default, warnings are disabled.";
1350  else if (all_state == "error")
1351  os << "By default, warnings are treated as errors.";
1352  else
1353  panic_impossible ();
1354 
1355  if (nel > 1)
1356  os << "\n\n";
1357 
1358  // The state for all is always supposed to be first in the list.
1359 
1360  for (octave_idx_type i = 1; i < nel; i++)
1361  {
1362  std::string tid = ident(i).string_value ();
1363  std::string tst = state(i).string_value ();
1364 
1365  os << std::setw (7) << tst << " " << tid << "\n";
1366  }
1367 
1368  os << std::endl;
1369 }
1370 
1371 static void
1372 set_warning_option (const std::string& state, const std::string& ident)
1373 {
1374  std::string all_state = default_warning_state ();
1375 
1376  if (state != "on" && state != "off" && state != "error")
1377  error ("invalid warning state: %s", state.c_str ());
1378 
1379  Cell tid = warning_options.contents ("identifier");
1380  Cell tst = warning_options.contents ("state");
1381 
1382  octave_idx_type nel = tid.numel ();
1383 
1384  for (octave_idx_type i = 0; i < nel; i++)
1385  {
1386  if (tid(i).string_value () == ident)
1387  {
1388  // We found it in the current list of options. If the state
1389  // for "all" is same as arg1, we can simply remove the item
1390  // from the list.
1391 
1392  if (state == all_state && ident != "all")
1393  {
1394  for (i = i + 1; i < nel; i++)
1395  {
1396  tid(i-1) = tid(i);
1397  tst(i-1) = tst(i);
1398  }
1399 
1400  tid.resize (dim_vector (1, nel-1));
1401  tst.resize (dim_vector (1, nel-1));
1402  }
1403  else
1404  tst(i) = state;
1405 
1407 
1408  warning_options.assign ("identifier", tid);
1409  warning_options.assign ("state", tst);
1410 
1411  return;
1412  }
1413  }
1414 
1415  // The option wasn't already in the list. Append it.
1416 
1417  tid.resize (dim_vector (1, nel+1));
1418  tst.resize (dim_vector (1, nel+1));
1419 
1420  tid(nel) = ident;
1421  tst(nel) = state;
1422 
1424 
1425  warning_options.assign ("identifier", tid);
1426  warning_options.assign ("state", tst);
1427 }
1428 
1429 DEFMETHOD (warning, interp, args, nargout,
1430  doc: /* -*- texinfo -*-
1431 @deftypefn {} {} warning (@var{template}, @dots{})
1432 @deftypefnx {} {} warning (@var{id}, @var{template}, @dots{})
1433 @deftypefnx {} {} warning ("on", @var{id})
1434 @deftypefnx {} {} warning ("off", @var{id})
1435 @deftypefnx {} {} warning ("error", @var{id})
1436 @deftypefnx {} {} warning ("query", @var{id})
1437 @deftypefnx {} {} warning (@var{state}, @var{id}, "local")
1438 @deftypefnx {} {} warning (@var{warning_struct})
1439 @deftypefnx {} {@var{warning_struct} =} warning (@dots{})
1440 @deftypefnx {} {} warning (@var{state}, @var{mode})
1441 
1442 Display a warning message or control the behavior of Octave's warning system.
1443 
1444 The first call form uses a template @var{template} and optional additional
1445 arguments to display a message on the @code{stderr} stream. The message is
1446 formatted using the same rules as the @code{printf} family of functions
1447 (@pxref{Formatted Output}) and prefixed by the character string
1448 @w{@samp{warning: }}. You should use this function when you want to notify the
1449 user of an unusual condition, but only when it makes sense for your program to
1450 go on. For example:
1451 
1452 @example
1453 @group
1454 warning ("foo: maybe something wrong here");
1455 @end group
1456 @end example
1457 
1458 The optional warning identifier @var{id} allows users to enable or disable
1459 warnings tagged by this identifier. A message identifier is a string of the
1460 form @qcode{"NAMESPACE:WARNING-NAME"}. Octave's own warnings use the
1461 @qcode{"Octave"} namespace (@pxref{XREFwarning_ids,,warning_ids}). For
1462 example:
1463 
1464 @example
1465 @group
1466 warning ("MyNameSpace:check-something",
1467  "foo: maybe something wrong here");
1468 @end group
1469 @end example
1470 
1471 The second call form is meant to change and/or query the state of warnings.
1472 The first input argument must be a string @var{state} (@qcode{"on"},
1473 @qcode{"off"}, @qcode{"error"}, or @qcode{"query"}) followed by an optional
1474 warning identifier @var{id} or @qcode{"all"} (default).
1475 
1476 The optional output argument @var{warning_struct} is a structure or structure
1477 array with fields @qcode{"state"} and @qcode{"identifier"}. The @var{state}
1478 argument may have the following values:
1479 
1480 @table @asis
1481 @item @qcode{"on"}|@qcode{"off"}:
1482 Enable or disable the display of warnings identified by @var{id} and optionally
1483 return their previous state @var{stout}.
1484 
1485 @item @qcode{"error"}:
1486 Turn warnings identified by @var{id} into errors and optionally return their
1487 previous state @var{stout}.
1488 
1489 @item @qcode{"query"}:
1490 Return the current state of warnings identified by @var{id}.
1491 @end table
1492 
1493 A structure or structure array @var{warning_struct}, with fields
1494 @qcode{"state"} and @qcode{"identifier"}, may be given as an input to achieve
1495 equivalent results. The following example shows how to temporarily disable a
1496 warning and then restore its original state:
1497 
1498 @example
1499 @group
1500 loglog (-1:10);
1501 ## Disable the previous warning and save its original state
1502 [~, id] = lastwarn ();
1503 warnstate = warning ("off", id);
1504 loglog (-1:10);
1505 ## Restore its original state
1506 warning (warnstate);
1507 @end group
1508 @end example
1509 
1510 If a final argument @qcode{"local"} is provided then the warning state will be
1511 set temporarily until the end of the current function. Changes to warning
1512 states that are set locally affect the current function and all functions
1513 called from the current scope. The previous warning state is restored on
1514 return from the current function. The @qcode{"local"} option is ignored if
1515 used in the top-level workspace.
1516 
1517 With no input argument @code{warning ()} is equivalent to
1518 @code{warning ("query", "all")} except that in the absence of an output
1519 argument, the state of warnings is displayed on @code{stderr}.
1520 
1521 The level of verbosity of the warning system may also be controlled by two
1522 modes @var{mode}:
1523 
1524 @table @asis
1525 @item @qcode{"backtrace"}:
1526 enable/disable the display of the stack trace after the warning message
1527 
1528 @item @qcode{"verbose"}:
1529 enable/disable the display of additional information after the warning message
1530 @end table
1531 
1532 In this case the @var{state} argument may only be @qcode{"on"} or
1533 @qcode{"off"}.
1534 
1535 Implementation Note: For compatibility with @sc{matlab}, escape sequences in
1536 @var{template} (e.g., @qcode{"@xbackslashchar{}n"} => newline) are processed
1537 regardless of whether @var{template} has been defined with single quotes, as
1538 long as there are two or more input arguments. To disable escape sequence
1539 expansion use a second backslash before the sequence (e.g.,
1540 @qcode{"@xbackslashchar{}@xbackslashchar{}n"}) or use the
1541 @code{regexptranslate} function.
1542 @seealso{warning_ids, lastwarn, error}
1543 @end deftypefn */)
1544 {
1546 
1547  int nargin = args.length ();
1548  bool done = false;
1549 
1550  if (nargin > 0 && args.all_strings_p ())
1551  {
1552  string_vector argv = args.make_argv ("warning");
1553 
1554  std::string arg1 = argv[1];
1555  std::string arg2 = "all";
1556 
1557  if (nargin >= 2)
1558  arg2 = argv[2];
1559 
1560  if (arg1 == "on" || arg1 == "off" || arg1 == "error")
1561  {
1562  // Prepare output structure
1563  octave_map old_warning_options;
1564  if (arg2 == "all")
1565  old_warning_options = warning_options;
1566  else
1567  old_warning_options = octave_map (warning_query (arg2));
1568 
1569  octave::symbol_table& symtab = interp.get_symbol_table ();
1570 
1571  if (nargin == 3 && argv[3] == "local"
1572  && ! symtab.at_top_level ())
1573  {
1574  octave::symbol_scope scope
1575  = symtab.require_current_scope ("warning");
1576 
1577  octave_scalar_map val = warning_query (arg2);
1578 
1579  octave_value curr_state = val.contents ("state");
1580 
1581  // FIXME: this might be better with a dictionary object.
1582 
1583  octave_value curr_warning_states
1584  = scope.varval (".saved_warning_states.");
1585 
1586  octave_map m;
1587 
1588  if (curr_warning_states.is_defined ())
1589  m = curr_warning_states.map_value ();
1590  else
1591  {
1592  string_vector fields (2);
1593 
1594  fields(0) = "identifier";
1595  fields(1) = "state";
1596 
1597  m = octave_map (dim_vector (0, 1), fields);
1598  }
1599 
1600  Cell ids = m.contents ("identifier");
1601  Cell states = m.contents ("state");
1602 
1603  octave_idx_type nel = states.numel ();
1604  bool found = false;
1606  for (i = 0; i < nel; i++)
1607  {
1608  std::string id = ids(i).string_value ();
1609 
1610  if (id == arg2)
1611  {
1612  states(i) = curr_state;
1613  found = true;
1614  break;
1615  }
1616  }
1617 
1618  if (! found)
1619  {
1620  m.resize (dim_vector (nel+1, 1));
1621 
1622  ids.resize (dim_vector (nel+1, 1));
1623  states.resize (dim_vector (nel+1, 1));
1624 
1625  ids(nel) = arg2;
1626  states(nel) = curr_state;
1627  }
1628 
1629  m.contents ("identifier") = ids;
1630  m.contents ("state") = states;
1631 
1632  scope.force_assign (".saved_warning_states.", m);
1633 
1634  // Now ignore the "local" argument and continue to
1635  // handle the current setting.
1636  nargin--;
1637  }
1638 
1639  if (nargin >= 2 && arg2 == "all")
1640  {
1641  // If "all" is explicitly given as ID.
1642 
1643  octave_map tmp;
1644  int is_error = (arg1 == "error");
1645 
1646  Cell id (1, 1 + 2*is_error);
1647  Cell st (1, 1 + 2*is_error);
1648 
1649  id(0) = arg2;
1650  st(0) = arg1;
1651 
1652  // Since internal Octave functions are not compatible,
1653  // and "all"=="error" causes any "on" to throw an error,
1654  // turning all warnings into errors should disable
1655  // Octave:language-extension.
1656 
1657  if (is_error)
1658  {
1659  id(1) = "Octave:language-extension";
1660  st(1) = "off";
1661 
1662  id(2) = "Octave:single-quote-string";
1663  st(2) = "off";
1664  }
1665 
1666  tmp.assign ("identifier", id);
1667  tmp.assign ("state", st);
1668 
1669  warning_options = tmp;
1670 
1671  done = true;
1672  }
1673  else if (arg2 == "backtrace")
1674  {
1675  if (arg1 != "error")
1676  {
1677  Vbacktrace_on_warning = (arg1 == "on");
1678  done = true;
1679  }
1680  }
1681  else if (arg2 == "debug")
1682  {
1683  if (arg1 != "error")
1684  {
1685  Vdebug_on_warning = (arg1 == "on");
1686  done = true;
1687  }
1688  }
1689  else if (arg2 == "verbose")
1690  {
1691  if (arg1 != "error")
1692  {
1693  Vverbose_warning = (arg1 == "on");
1694  done = true;
1695  }
1696  }
1697  else if (arg2 == "quiet")
1698  {
1699  if (arg1 != "error")
1700  {
1701  Vquiet_warning = (arg1 == "on");
1702  done = true;
1703  }
1704  }
1705  else
1706  {
1707  if (arg2 == "last")
1708  arg2 = Vlast_warning_id;
1709 
1710  set_warning_option (arg1, arg2);
1711 
1712  done = true;
1713  }
1714 
1715  if (done && nargout > 0)
1716  retval = old_warning_options;
1717  }
1718  else if (arg1 == "query")
1719  {
1720  if (arg2 == "all")
1722  else if (arg2 == "backtrace" || arg2 == "debug"
1723  || arg2 == "verbose" || arg2 == "quiet")
1724  {
1726  tmp.assign ("identifier", arg2);
1727  if (arg2 == "backtrace")
1728  tmp.assign ("state", Vbacktrace_on_warning ? "on" : "off");
1729  else if (arg2 == "debug")
1730  tmp.assign ("state", Vdebug_on_warning ? "on" : "off");
1731  else if (arg2 == "verbose")
1732  tmp.assign ("state", Vverbose_warning ? "on" : "off");
1733  else
1734  tmp.assign ("state", Vquiet_warning ? "on" : "off");
1735 
1736  retval = tmp;
1737  }
1738  else
1739  retval = warning_query (arg2);
1740 
1741  done = true;
1742  }
1743  }
1744  else if (nargin == 0)
1745  {
1746  if (nargout > 0)
1748  else
1749  display_warning_options (octave_stdout);
1750 
1751  done = true;
1752  }
1753  else if (nargin == 1)
1754  {
1755  octave_value arg = args(0);
1756 
1757  octave_map old_warning_options;
1758 
1759  if (arg.isstruct ())
1760  {
1761  octave_map m = arg.map_value ();
1762 
1763  if (! m.contains ("identifier") || ! m.contains ("state"))
1764  error ("warning: STATE structure must have fields 'identifier' and 'state'");
1765 
1766  // Simply step through the struct elements one at a time.
1767 
1768  Cell ident = m.contents ("identifier");
1769  Cell state = m.contents ("state");
1770 
1771  octave_idx_type nel = ident.numel ();
1772 
1773  // Prepare output structure
1774  old_warning_options = octave_map (m);
1775  Cell oldstate (state);
1776 
1777  for (octave_idx_type i = 0; i < nel; i++)
1778  {
1779  std::string tid = ident(i).string_value ();
1780  oldstate(i) = warning_query (tid).getfield ("state");
1781  }
1782  old_warning_options.setfield ("state", oldstate);
1783 
1784  // Set new values
1785  for (octave_idx_type i = 0; i < nel; i++)
1786  {
1787  std::string tst = state(i).string_value ();
1788  std::string tid = ident(i).string_value ();
1789 
1790  set_warning_option (tst, tid);
1791  }
1792 
1793  done = true;
1794 
1795  if (nargout > 0)
1796  retval = old_warning_options;
1797  }
1798  }
1799 
1800  if (! done)
1801  {
1802  octave_value_list nargs = args;
1803 
1804  std::string id;
1805 
1806  bool have_fmt = maybe_extract_message_id ("warning", args, nargs, id);
1807 
1809 
1810  std::string curr_msg = handle_message (warning_with_id, id.c_str (),
1811  "unspecified warning", nargs,
1812  have_fmt);
1813 
1814  if (nargout > 0)
1815  retval = prev_msg;
1816  }
1817 
1818  return retval;
1819 }
1820 
1821 /*
1822 %!test <*45753>
1823 %! warning ("error");
1824 %! assert (! isempty (help ("warning")));
1825 */
1826 
1827 /*
1828 %!test <*51997>
1829 %! id = "Octave:divide-by-zero";
1830 %! current = warning ("query", id);
1831 %! current_all = warning ();
1832 %! previous = warning (current_all);
1833 %! assert (previous, current_all);
1834 %! previous = warning (current);
1835 %! assert (previous, current);
1836 %! previous = warning (current.state, id);
1837 %! assert (previous, current);
1838 */
1839 
1841 set_warning_state (const std::string& id, const std::string& state)
1842 {
1843  octave_value_list args;
1844 
1845  args(1) = id;
1846  args(0) = state;
1847 
1848  octave::interpreter& interp
1849  = octave::__get_interpreter__ ("set_warning_state");
1850 
1851  return Fwarning (interp, args, 1);
1852 }
1853 
1856 {
1857  octave::interpreter& interp
1858  = octave::__get_interpreter__ ("set_warning_state");
1859 
1860  return Fwarning (interp, args, 1);
1861 }
1862 
1863 void
1864 disable_warning (const std::string& id)
1865 {
1866  set_warning_option ("off", id);
1867 }
1868 
1869 void
1871 {
1873 
1874  // Most people will want to have the following disabled.
1875 
1876  disable_warning ("Octave:array-as-logical");
1877  disable_warning ("Octave:array-to-scalar");
1878  disable_warning ("Octave:array-to-vector");
1879  disable_warning ("Octave:imag-to-real");
1880  disable_warning ("Octave:language-extension");
1881  disable_warning ("Octave:missing-semicolon");
1882  disable_warning ("Octave:neg-dim-as-zero");
1883  disable_warning ("Octave:resize-on-range-error");
1884  disable_warning ("Octave:separator-insert");
1885  disable_warning ("Octave:single-quote-string");
1886  disable_warning ("Octave:str-to-num");
1887  disable_warning ("Octave:mixed-string-concat");
1888  disable_warning ("Octave:variable-switch-label");
1889 }
1890 
1891 DEFMETHOD (lasterror, interp, args, ,
1892  doc: /* -*- texinfo -*-
1893 @deftypefn {} {@var{lasterr} =} lasterror ()
1894 @deftypefnx {} {} lasterror (@var{err})
1895 @deftypefnx {} {} lasterror ("reset")
1896 Query or set the last error message structure.
1897 
1898 When called without arguments, return a structure containing the last error
1899 message and other information related to this error. The elements of the
1900 structure are:
1901 
1902 @table @code
1903 @item message
1904 The text of the last error message
1905 
1906 @item identifier
1907 The message identifier of this error message
1908 
1909 @item stack
1910 A structure containing information on where the message occurred. This may
1911 be an empty structure if the information cannot be obtained. The fields of
1912 the structure are:
1913 
1914 @table @code
1915 @item file
1916 The name of the file where the error occurred
1917 
1918 @item name
1919 The name of function in which the error occurred
1920 
1921 @item line
1922 The line number at which the error occurred
1923 
1924 @item column
1925 An optional field with the column number at which the error occurred
1926 @end table
1927 @end table
1928 
1929 The last error structure may be set by passing a scalar structure,
1930 @var{err}, as input. Any fields of @var{err} that match those above are
1931 set while any unspecified fields are initialized with default values.
1932 
1933 If @code{lasterror} is called with the argument @qcode{"reset"}, all
1934 fields are set to their default values.
1935 @seealso{lasterr, error, lastwarn}
1936 @end deftypefn */)
1937 {
1938  int nargin = args.length ();
1939 
1940  if (nargin > 1)
1941  print_usage ();
1942 
1944 
1945  err.assign ("message", Vlast_error_message);
1946  err.assign ("identifier", Vlast_error_id);
1947 
1948  err.assign ("stack", octave_value (Vlast_error_stack));
1949 
1950  if (nargin == 1)
1951  {
1952  if (args(0).is_string ())
1953  {
1954  if (args(0).string_value () != "reset")
1955  error ("lasterror: unrecognized string argument");
1956 
1957  Vlast_error_message = "";
1958  Vlast_error_id = "";
1959 
1961  }
1962  else if (args(0).isstruct ())
1963  {
1964  octave_scalar_map new_err = args(0).scalar_map_value ();
1965  octave_scalar_map new_err_stack;
1966  std::string new_error_message;
1967  std::string new_error_id;
1968  std::string new_error_file;
1969  std::string new_error_name;
1970  int new_error_line = -1;
1971  int new_error_column = -1;
1972  bool initialize_stack = false;
1973 
1974  if (new_err.contains ("message"))
1975  {
1976  const std::string tmp =
1977  new_err.getfield ("message").string_value ();
1978  new_error_message = tmp;
1979  }
1980 
1981  if (new_err.contains ("identifier"))
1982  {
1983  const std::string tmp =
1984  new_err.getfield ("identifier").string_value ();
1985  new_error_id = tmp;
1986  }
1987 
1988  if (new_err.contains ("stack"))
1989  {
1990  if (new_err.getfield ("stack").isempty ())
1991  initialize_stack = true;
1992  else
1993  {
1994  new_err_stack =
1995  new_err.getfield ("stack").scalar_map_value ();
1996 
1997  if (new_err_stack.contains ("file"))
1998  {
1999  const std::string tmp =
2000  new_err_stack.getfield ("file").string_value ();
2001  new_error_file = tmp;
2002  }
2003 
2004  if (new_err_stack.contains ("name"))
2005  {
2006  const std::string tmp =
2007  new_err_stack.getfield ("name").string_value ();
2008  new_error_name = tmp;
2009  }
2010 
2011  if (new_err_stack.contains ("line"))
2012  {
2013  const int tmp =
2014  new_err_stack.getfield ("line").nint_value ();
2015  new_error_line = tmp;
2016  }
2017 
2018  if (new_err_stack.contains ("column"))
2019  {
2020  const int tmp =
2021  new_err_stack.getfield ("column").nint_value ();
2022  new_error_column = tmp;
2023  }
2024  }
2025  }
2026 
2027  Vlast_error_message = new_error_message;
2028  Vlast_error_id = new_error_id;
2029 
2030  if (initialize_stack)
2032  else if (new_err.contains ("stack"))
2033  {
2034  new_err_stack.setfield ("file", new_error_file);
2035  new_err_stack.setfield ("name", new_error_name);
2036  new_err_stack.setfield ("line", new_error_line);
2037  new_err_stack.setfield ("column", new_error_column);
2038  Vlast_error_stack = new_err_stack;
2039  }
2040  else
2041  {
2042  // No stack field. Fill it in with backtrace info.
2043  octave_idx_type curr_frame = -1;
2044 
2045  octave::call_stack& cs = interp.get_call_stack ();
2046 
2047  Vlast_error_stack = cs.backtrace (0, curr_frame);
2048  }
2049  }
2050  else
2051  error ("lasterror: argument must be a structure or a string");
2052  }
2053 
2054  return ovl (err);
2055 }
2056 
2057 /*
2058 ## Test lasterror with empty error state
2059 %!test
2060 %! lasterror ("reset");
2061 %! x = lasterror ();
2062 %! assert (x.identifier, "")
2063 %! assert (x.message, "")
2064 %! assert (isempty (x.stack))
2065 %! lasterror (x);
2066 %! y = lasterror ();
2067 %! assert (y, x);
2068 */
2069 
2070 DEFUN (lasterr, args, nargout,
2071  doc: /* -*- texinfo -*-
2072 @deftypefn {} {[@var{msg}, @var{msgid}] =} lasterr ()
2073 @deftypefnx {} {} lasterr (@var{msg})
2074 @deftypefnx {} {} lasterr (@var{msg}, @var{msgid})
2075 Query or set the last error message.
2076 
2077 When called without input arguments, return the last error message and
2078 message identifier.
2079 
2080 With one argument, set the last error message to @var{msg}.
2081 
2082 With two arguments, also set the last message identifier.
2083 @seealso{lasterror, error, lastwarn}
2084 @end deftypefn */)
2085 {
2086  int nargin = args.length ();
2087 
2088  if (nargin > 2)
2089  print_usage ();
2090 
2091  string_vector argv = args.make_argv ("lasterr");
2092 
2093  std::string prev_error_id = Vlast_error_id;
2094  std::string prev_error_message = Vlast_error_message;
2095 
2096  if (nargin == 2)
2097  {
2098  Vlast_error_id = argv[2];
2100  }
2101  else if (nargin == 1)
2102  {
2103  Vlast_error_id = "";
2105  }
2106 
2107  if (nargin == 0 || nargout > 0)
2108  return ovl (prev_error_message, prev_error_id);
2109  else
2110  return ovl ();
2111 }
2112 
2113 DEFUN (lastwarn, args, nargout,
2114  doc: /* -*- texinfo -*-
2115 @deftypefn {} {[@var{msg}, @var{msgid}] =} lastwarn ()
2116 @deftypefnx {} {} lastwarn (@var{msg})
2117 @deftypefnx {} {} lastwarn (@var{msg}, @var{msgid})
2118 Query or set the last warning message.
2119 
2120 When called without input arguments, return the last warning message and
2121 message identifier.
2122 
2123 With one argument, set the last warning message to @var{msg}.
2124 
2125 With two arguments, also set the last message identifier.
2126 @seealso{warning, lasterror, lasterr}
2127 @end deftypefn */)
2128 {
2129  int nargin = args.length ();
2130 
2131  if (nargin > 2)
2132  print_usage ();
2133 
2134  string_vector argv = args.make_argv ("lastwarn");
2135 
2136  std::string prev_warning_id = Vlast_warning_id;
2137  std::string prev_warning_message = Vlast_warning_message;
2138 
2139  if (nargin == 2)
2140  {
2141  Vlast_warning_id = argv[2];
2143  }
2144  else if (nargin == 1)
2145  {
2146  Vlast_warning_id = "";
2148  }
2149 
2150  if (nargin == 0 || nargout > 0)
2151  return ovl (prev_warning_message, prev_warning_id);
2152  else
2153  return ovl ();
2154 }
2155 
2156 DEFUN (beep_on_error, args, nargout,
2157  doc: /* -*- texinfo -*-
2158 @deftypefn {} {@var{val} =} beep_on_error ()
2159 @deftypefnx {} {@var{old_val} =} beep_on_error (@var{new_val})
2160 @deftypefnx {} {} beep_on_error (@var{new_val}, "local")
2161 Query or set the internal variable that controls whether Octave will try
2162 to ring the terminal bell before printing an error message.
2163 
2164 When called from inside a function with the @qcode{"local"} option, the
2165 variable is changed locally for the function and any subroutines it calls.
2166 The original variable value is restored when exiting the function.
2167 @end deftypefn */)
2168 {
2169  return SET_INTERNAL_VARIABLE (beep_on_error);
2170 }
2171 
2172 DEFUN (debug_on_error, args, nargout,
2173  doc: /* -*- texinfo -*-
2174 @deftypefn {} {@var{val} =} debug_on_error ()
2175 @deftypefnx {} {@var{old_val} =} debug_on_error (@var{new_val})
2176 @deftypefnx {} {} debug_on_error (@var{new_val}, "local")
2177 Query or set the internal variable that controls whether Octave will try
2178 to enter the debugger when an error is encountered.
2179 
2180 This will also inhibit printing of the normal traceback message (you will
2181 only see the top-level error message).
2182 
2183 When called from inside a function with the @qcode{"local"} option, the
2184 variable is changed locally for the function and any subroutines it calls.
2185 The original variable value is restored when exiting the function.
2186 @seealso{debug_on_warning, debug_on_interrupt}
2187 @end deftypefn */)
2188 {
2189  return SET_INTERNAL_VARIABLE (debug_on_error);
2190 }
2191 
2192 DEFUN (debug_on_warning, args, nargout,
2193  doc: /* -*- texinfo -*-
2194 @deftypefn {} {@var{val} =} debug_on_warning ()
2195 @deftypefnx {} {@var{old_val} =} debug_on_warning (@var{new_val})
2196 @deftypefnx {} {} debug_on_warning (@var{new_val}, "local")
2197 Query or set the internal variable that controls whether Octave will try
2198 to enter the debugger when a warning is encountered.
2199 
2200 When called from inside a function with the @qcode{"local"} option, the
2201 variable is changed locally for the function and any subroutines it calls.
2202 The original variable value is restored when exiting the function.
2203 @seealso{debug_on_error, debug_on_interrupt}
2204 @end deftypefn */)
2205 {
2206  return SET_INTERNAL_VARIABLE (debug_on_warning);
2207 }
2208 
2210 last_error_message (void)
2211 {
2212  return Vlast_error_message;
2213 }
2214 
2216 last_error_id (void)
2217 {
2218  return Vlast_error_id;
2219 }
2220 
2221 octave_map
2222 last_error_stack (void)
2223 {
2224  return Vlast_error_stack;
2225 }
2226 
2228 last_warning_message (void)
2229 {
2230  return Vlast_warning_message;
2231 }
2232 
2234 last_warning_id (void)
2235 {
2236  return Vlast_warning_id;
2237 }
2238 
2239 void
2241 {
2245 
2247  Vdebug_on_error = false;
2248  Vdebug_on_warning = false;
2249  // leave Vdebug_on_caught as it was, so errors in try/catch are still caught
2250 }
uint32_t id
Definition: graphics.cc:12193
bool Vdebug_on_error
Definition: error.cc:62
int warning_enabled(const std::string &id)
Definition: error.cc:669
void panic(const char *fmt,...)
Definition: error.cc:944
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:816
scalar structure containing the one value The second produces an empty struct array with one field and no values since being passed an empty cell array of struct array values When the value is a cell array containing a single entry this becomes a scalar struct with that single entry as the value of the field That single entry happens to be an empty cell array Finally if the value is a non scalar cell array then ode isstruct
scalar structure containing the fields
Definition: ov-struct.cc:1736
Definition: Cell.h:37
OCTAVE_EXPORT octave_value_list column
Definition: sparse.cc:123
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
Definition: utils.cc:305
bool contains(const std::string &name) const
Definition: oct-map.h:336
bool Vdebug_on_caught
Definition: error.cc:66
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition: defun.h:135
bool Vdebug_on_warning
Definition: error.cc:70
interpreter & __get_interpreter__(const std::string &who)
static bool Vbeep_on_error
Definition: error.cc:57
std::string string_value(bool force=false) const
Definition: ov.h:955
bool isempty(void) const
Definition: ov.h:529
void vparse_error(const char *fmt, va_list args)
Definition: error.cc:825
void assign(const std::string &k, const Cell &val)
Definition: oct-map.h:351
OCTINTERP_API void initialize_default_warning_state(void)
octave_map map_value(void) const
bool debug_on_warn(const std::string &id)
Definition: bp-table.h:109
OCTINTERP_API void print_usage(void)
Definition: defun.cc:54
OCTINTERP_API size_t octave_vformat(std::ostream &os, const char *fmt, va_list args)
void verror_with_id(const char *id, const char *fmt, va_list args)
Definition: error.cc:617
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
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 const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE * f
void rethrow_error(const char *id, const char *fmt,...)
Definition: error.cc:855
int nint_value(bool frc_str_conv=false) const
Definition: ov.h:800
static void vwarning(const char *name, const char *id, const char *fmt, va_list args)
Definition: error.cc:394
void vmessage(const char *name, const char *fmt, va_list args)
Definition: error.cc:429
static OCTAVE_NORETURN void error_1(octave::execution_exception &e, std::ostream &os, const char *name, const char *id, const char *fmt, va_list args, bool with_cfn=false)
Definition: error.cc:512
octave_map backtrace(size_t nskip, octave_idx_type &curr_user_frame, bool print_subfn=true) const
Definition: call-stack.cc:573
octave_map empty_backtrace(void) const
Definition: call-stack.cc:614
void flush_stdout(void)
Definition: pager.cc:464
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:53
void error(const char *fmt,...)
Definition: error.cc:578
#define SET_INTERNAL_VARIABLE(NM)
Definition: variables.h:109
OCTINTERP_API octave_value_list set_warning_state(const std::string &id, const std::string &state)
octave_user_code * caller_user_code(size_t nskip=0) const
Definition: call-stack.cc:164
void setfield(const std::string &key, const octave_value &val)
Definition: oct-map.cc:191
bool is_defined(void) const
Definition: ov.h:523
static octave_map initialize_last_error_stack(void)
Definition: error.cc:144
static std::string Vlast_error_message
Definition: error.cc:86
void message_with_id(const char *name, const char *id, const char *fmt,...)
Definition: error.cc:451
#define octave_diary
Definition: pager.h:176
bool at_top_level(void)
Definition: symtab.h:140
static bool Vverbose_warning
Definition: error.cc:77
static OCTAVE_NORETURN void usage_1(octave::execution_exception &e, const char *id, const char *fmt, va_list args)
Definition: error.cc:461
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
Definition: file-io.cc:587
i e
Definition: data.cc:2591
static std::string Vlast_warning_id
Definition: error.cc:92
void usage(const char *fmt,...)
Definition: error.cc:487
void usage_with_id(const char *id, const char *fmt,...)
Definition: error.cc:502
void(* error_fun)(const char *, const char *,...)
Definition: error.cc:970
octave_value arg
Definition: pr-output.cc:3244
octave_function * fcn
Definition: ov-class.cc:1754
string_vector argv
Definition: load-save.cc:648
static std::string Vlast_warning_message
Definition: error.cc:89
octave::call_stack & cs
Definition: ov-class.cc:1752
static bool Vquiet_warning
Definition: error.cc:80
static std::string handle_message(error_fun f, const char *id, const char *msg, const octave_value_list &args, bool have_fmt)
Definition: error.cc:975
static void maybe_enter_debugger(octave::execution_exception &e, bool show_stack_trace=false)
Definition: error.cc:355
static bool Vbacktrace_on_warning
Definition: error.cc:74
void message(const char *name, const char *fmt,...)
Definition: error.cc:435
bool contains(const std::string &name) const
Definition: oct-map.h:213
void verror_with_cfn(const char *fmt, va_list args)
Definition: error.cc:602
done
Definition: syscalls.cc:251
static void pr_where(std::ostream &os, const char *who, const std::list< error_stack_frame > &frames)
Definition: error.cc:286
int buffer_error_messages
Definition: error.cc:112
nd deftypefn *std::string name
Definition: sysdep.cc:647
octave_value & assign(assign_op op, const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
void verror_with_id_cfn(const char *id, const char *fmt, va_list args)
Definition: error.cc:632
OCTINTERP_API void disable_warning(const std::string &id)
void clear(void)
Definition: oct-map.h:368
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)
Definition: ov-usr-fcn.cc:997
OCTINTERP_API std::string last_warning_id(void)
void defun_usage_message(const std::string &msg)
Definition: error.cc:965
static octave_map Vlast_error_stack
Definition: error.cc:98
void error_with_cfn(const char *fmt,...)
Definition: error.cc:608
void error_with_id(const char *id, const char *fmt,...)
Definition: error.cc:623
static size_t current_frame
Definition: pt-eval.h:250
void vusage_with_id(const char *id, const char *fmt, va_list args)
Definition: error.cc:496
bool strcmp(const T &str_a, const T &str_b)
True if strings are the same.
Definition: oct-string.cc:112
void vparse_error_with_id(const char *id, const char *fmt, va_list args)
Definition: error.cc:840
int in_try_catch
Definition: error.cc:116
OCTINTERP_API std::string last_error_id(void)
string_vector make_argv(const std::string &="") const
Definition: ovl.cc:212
int error_state
Definition: error.cc:107
void resize(const dim_vector &dv, const T &rfv)
Resizing (with fill).
Definition: Array.cc:1010
double tmp
Definition: data.cc:6252
bool debug_on_err(const std::string &id)
Definition: bp-table.h:97
std::string name
Definition: error.cc:280
static void rethrow_error_1(const char *id, const char *fmt,...)
Definition: error.cc:895
void vmessage_with_id(const char *name, const char *id, const char *fmt, va_list args)
Definition: error.cc:444
octave_value retval
Definition: data.cc:6246
#define panic_impossible()
Definition: error.h:40
bool debug_on_caught(const std::string &id)
Definition: bp-table.h:103
void reset_error_handler(void)
Definition: error.cc:125
const Cell & contents(const_iterator p) const
Definition: oct-map.h:317
symbol_scope require_current_scope(const std::string &who)
Definition: symtab.h:79
static void warning_1(const char *id, const char *fmt, va_list args)
Definition: error.cc:740
octave_value getfield(const std::string &key) const
Definition: oct-map.cc:184
bool isstruct(void) const
Definition: ov.h:589
static bool debug_mode
Definition: pt-eval.h:252
T::size_type strlen(const typename T::value_type *str)
Definition: oct-string.cc:75
void parse_error(const char *fmt,...)
Definition: error.cc:831
octave_idx_type numel(void) const
Definition: oct-map.h:375
octave_value varval(const std::string &name) const
Definition: symscope.h:727
void vusage(const char *fmt, va_list args)
Definition: error.cc:481
static uint32_t state[624]
Definition: randmtzig.cc:183
void setfield(const std::string &key, const Cell &val)
Definition: oct-map.cc:283
octave_function * current(void) const
Definition: call-stack.h:97
void warning(const char *fmt,...)
Definition: error.cc:801
octave::unwind_protect frame
Definition: graphics.cc:12190
OCTINTERP_API std::string last_error_message(void)
octave_scalar_map scalar_map_value(void) const
OCTINTERP_API octave_map last_error_stack(void)
static void defun_usage_message_1(const char *fmt,...)
Definition: error.cc:956
#define octave_stdout
Definition: pager.h:174
static std::string Vlast_error_id
Definition: error.cc:95
octave_value do_keyboard(const octave_value_list &args=octave_value_list())
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
octave::execution_exception make_execution_exception(const char *who)
Definition: error.cc:341
static octave_map warning_options
Definition: error.cc:83
bp_table & __get_bp_table__(const std::string &who)
static void verror(bool save_last_error, std::ostream &os, const char *name, const char *id, const char *fmt, va_list args, bool with_cfn=false)
Definition: error.cc:153
std::list< call_stack::stack_frame > backtrace_frames(size_t nskip, octave_idx_type &curr_user_frame) const
Definition: call-stack.cc:539
void force_assign(const std::string &name, const octave_value &value)
Definition: symscope.h:721
void error_with_id_cfn(const char *id, const char *fmt,...)
Definition: error.cc:638
call_stack & __get_call_stack__(const std::string &who)
octave_idx_type length(void) const
Definition: ovl.h:96
bool isempty(void) const
Definition: oct-map.h:377
static void initialize_warning_options(const std::string &state)
Definition: error.cc:133
bool all_strings_p(void) const
Definition: ovl.cc:161
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Definition: ovl.h:100
args.length() nargin
Definition: file-io.cc:589
void parse_error_with_id(const char *id, const char *fmt,...)
Definition: error.cc:846
for i
Definition: data.cc:5264
bool is_string(void) const
Definition: ov.h:577
OCTAVE_EXPORT octave_value_list error nd deftypefn *const octave_scalar_map err
Definition: error.cc:1049
void resize(const dim_vector &dv, bool fill=false)
Definition: oct-map.cc:577
OCTINTERP_API std::string last_warning_message(void)
void vwarning_with_id(const char *id, const char *fmt, va_list args)
Definition: error.cc:810
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
octave_idx_type length(void) const
Definition: oct-map.h:376
octave_idx_type nfields(void) const
Definition: oct-map.h:207
bool discard_warning_messages
Definition: error.cc:122
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
bool discard_error_messages
Definition: error.cc:119
std::string name(void) const
Definition: ov-fcn.h:182
static int check_state(const std::string &state)
Definition: error.cc:647
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
Definition: utils.cc:888
static std::list< error_stack_frame > make_stack_frame_list(const octave_map &stack)
Definition: error.cc:864
octave::stream os
Definition: file-io.cc:627
size_t current_frame(void) const
Definition: call-stack.h:123
line(const graphics_handle &mh, const graphics_handle &p)
Definition: graphics.in.h:4357
OCTINTERP_API void interpreter_try(octave::unwind_protect &)
octave_value_list Fsprintf(const octave_value_list &, int)
static void pr_where_1(std::ostream &os, const char *fmt,...)
Definition: error.cc:269
static void pr_where_2(std::ostream &os, const char *fmt, va_list args)
Definition: error.cc:241