comparison libinterp/corefcn/error.cc @ 31607:aac27ad79be6 stable

maint: Re-indent code after switch to using namespace macros. * build-env.h, build-env.in.cc, Cell.h, __betainc__.cc, __eigs__.cc, __ftp__.cc, __ichol__.cc, __ilu__.cc, __isprimelarge__.cc, __magick_read__.cc, __pchip_deriv__.cc, amd.cc, base-text-renderer.cc, base-text-renderer.h, besselj.cc, bitfcns.cc, bsxfun.cc, c-file-ptr-stream.h, call-stack.cc, call-stack.h, ccolamd.cc, cellfun.cc, chol.cc, colamd.cc, dasrt.cc, data.cc, debug.cc, defaults.cc, defaults.h, det.cc, display.cc, display.h, dlmread.cc, dynamic-ld.cc, dynamic-ld.h, ellipj.cc, environment.cc, environment.h, error.cc, error.h, errwarn.h, event-manager.cc, event-manager.h, event-queue.cc, event-queue.h, fcn-info.cc, fcn-info.h, fft.cc, fft2.cc, file-io.cc, filter.cc, find.cc, ft-text-renderer.cc, ft-text-renderer.h, gcd.cc, gl-render.cc, gl-render.h, gl2ps-print.cc, gl2ps-print.h, graphics-toolkit.cc, graphics-toolkit.h, graphics.cc, gsvd.cc, gtk-manager.cc, gtk-manager.h, help.cc, help.h, hook-fcn.cc, hook-fcn.h, input.cc, input.h, interpreter-private.cc, interpreter-private.h, interpreter.cc, interpreter.h, inv.cc, jsondecode.cc, jsonencode.cc, latex-text-renderer.cc, latex-text-renderer.h, load-path.cc, load-path.h, load-save.cc, load-save.h, lookup.cc, ls-hdf5.cc, ls-mat4.cc, ls-mat5.cc, lsode.cc, lu.cc, mappers.cc, matrix_type.cc, max.cc, mex.cc, mexproto.h, mxarray.h, mxtypes.in.h, oct-errno.in.cc, oct-hdf5-types.cc, oct-hist.cc, oct-hist.h, oct-map.cc, oct-map.h, oct-opengl.h, oct-prcstrm.h, oct-process.cc, oct-process.h, oct-stdstrm.h, oct-stream.cc, oct-stream.h, oct-strstrm.h, octave-default-image.h, ordqz.cc, ordschur.cc, pager.cc, pager.h, pinv.cc, pow2.cc, pr-output.cc, psi.cc, qr.cc, quadcc.cc, rand.cc, regexp.cc, settings.cc, settings.h, sighandlers.cc, sighandlers.h, sparse-xpow.cc, sqrtm.cc, stack-frame.cc, stack-frame.h, stream-euler.cc, strfns.cc, svd.cc, syminfo.cc, syminfo.h, symrcm.cc, symrec.cc, symrec.h, symscope.cc, symscope.h, symtab.cc, symtab.h, sysdep.cc, sysdep.h, text-engine.cc, text-engine.h, text-renderer.cc, text-renderer.h, time.cc, toplev.cc, typecast.cc, url-handle-manager.cc, url-handle-manager.h, urlwrite.cc, utils.cc, utils.h, variables.cc, variables.h, xdiv.cc, __delaunayn__.cc, __init_fltk__.cc, __init_gnuplot__.cc, __ode15__.cc, __voronoi__.cc, audioread.cc, convhulln.cc, gzip.cc, cdef-class.cc, cdef-class.h, cdef-fwd.h, cdef-manager.cc, cdef-manager.h, cdef-method.cc, cdef-method.h, cdef-object.cc, cdef-object.h, cdef-package.cc, cdef-package.h, cdef-property.cc, cdef-property.h, cdef-utils.cc, cdef-utils.h, ov-base-diag.cc, ov-base-int.cc, ov-base-mat.cc, ov-base-mat.h, ov-base-scalar.cc, ov-base.cc, ov-base.h, ov-bool-mat.cc, ov-bool-mat.h, ov-bool-sparse.cc, ov-bool.cc, ov-builtin.h, ov-cell.cc, ov-ch-mat.cc, ov-class.cc, ov-class.h, ov-classdef.cc, ov-classdef.h, ov-complex.cc, ov-cx-diag.cc, ov-cx-mat.cc, ov-cx-sparse.cc, ov-dld-fcn.cc, ov-dld-fcn.h, ov-fcn-handle.cc, ov-fcn-handle.h, ov-fcn.h, ov-float.cc, ov-flt-complex.cc, ov-flt-cx-diag.cc, ov-flt-cx-mat.cc, ov-flt-re-diag.cc, ov-flt-re-mat.cc, ov-flt-re-mat.h, ov-intx.h, ov-java.cc, ov-lazy-idx.cc, ov-legacy-range.cc, ov-magic-int.cc, ov-mex-fcn.cc, ov-mex-fcn.h, ov-null-mat.cc, ov-perm.cc, ov-range.cc, ov-re-diag.cc, ov-re-mat.cc, ov-re-mat.h, ov-re-sparse.cc, ov-scalar.cc, ov-str-mat.cc, ov-struct.cc, ov-typeinfo.cc, ov-typeinfo.h, ov-usr-fcn.cc, ov-usr-fcn.h, ov.cc, ov.h, ovl.h, octave.cc, octave.h, op-b-sbm.cc, op-bm-sbm.cc, op-cs-scm.cc, op-fm-fcm.cc, op-fs-fcm.cc, op-s-scm.cc, op-scm-cs.cc, op-scm-s.cc, op-sm-cs.cc, ops.h, anon-fcn-validator.cc, anon-fcn-validator.h, bp-table.cc, bp-table.h, comment-list.cc, comment-list.h, filepos.h, lex.h, oct-lvalue.cc, oct-lvalue.h, parse.h, profiler.cc, profiler.h, pt-anon-scopes.cc, pt-anon-scopes.h, pt-arg-list.cc, pt-arg-list.h, pt-args-block.cc, pt-args-block.h, pt-array-list.cc, pt-array-list.h, pt-assign.cc, pt-assign.h, pt-binop.cc, pt-binop.h, pt-bp.cc, pt-bp.h, pt-cbinop.cc, pt-cbinop.h, pt-cell.cc, pt-cell.h, pt-check.cc, pt-check.h, pt-classdef.cc, pt-classdef.h, pt-cmd.h, pt-colon.cc, pt-colon.h, pt-const.cc, pt-const.h, pt-decl.cc, pt-decl.h, pt-eval.cc, pt-eval.h, pt-except.cc, pt-except.h, pt-exp.cc, pt-exp.h, pt-fcn-handle.cc, pt-fcn-handle.h, pt-id.cc, pt-id.h, pt-idx.cc, pt-idx.h, pt-jump.h, pt-loop.cc, pt-loop.h, pt-mat.cc, pt-mat.h, pt-misc.cc, pt-misc.h, pt-pr-code.cc, pt-pr-code.h, pt-select.cc, pt-select.h, pt-spmd.cc, pt-spmd.h, pt-stmt.cc, pt-stmt.h, pt-tm-const.cc, pt-tm-const.h, pt-unop.cc, pt-unop.h, pt-walk.cc, pt-walk.h, pt.cc, pt.h, token.cc, token.h, Range.cc, Range.h, idx-vector.cc, idx-vector.h, range-fwd.h, CollocWt.cc, CollocWt.h, aepbalance.cc, aepbalance.h, chol.cc, chol.h, gepbalance.cc, gepbalance.h, gsvd.cc, gsvd.h, hess.cc, hess.h, lo-mappers.cc, lo-mappers.h, lo-specfun.cc, lo-specfun.h, lu.cc, lu.h, oct-convn.cc, oct-convn.h, oct-fftw.cc, oct-fftw.h, oct-norm.cc, oct-norm.h, oct-rand.cc, oct-rand.h, oct-spparms.cc, oct-spparms.h, qr.cc, qr.h, qrp.cc, qrp.h, randgamma.cc, randgamma.h, randmtzig.cc, randmtzig.h, randpoisson.cc, randpoisson.h, schur.cc, schur.h, sparse-chol.cc, sparse-chol.h, sparse-lu.cc, sparse-lu.h, sparse-qr.cc, sparse-qr.h, svd.cc, svd.h, child-list.cc, child-list.h, dir-ops.cc, dir-ops.h, file-ops.cc, file-ops.h, file-stat.cc, file-stat.h, lo-sysdep.cc, lo-sysdep.h, lo-sysinfo.cc, lo-sysinfo.h, mach-info.cc, mach-info.h, oct-env.cc, oct-env.h, oct-group.cc, oct-group.h, oct-password.cc, oct-password.h, oct-syscalls.cc, oct-syscalls.h, oct-time.cc, oct-time.h, oct-uname.cc, oct-uname.h, action-container.cc, action-container.h, base-list.h, cmd-edit.cc, cmd-edit.h, cmd-hist.cc, cmd-hist.h, f77-fcn.h, file-info.cc, file-info.h, lo-array-errwarn.cc, lo-array-errwarn.h, lo-hash.cc, lo-hash.h, lo-ieee.h, lo-regexp.cc, lo-regexp.h, lo-utils.cc, lo-utils.h, oct-base64.cc, oct-base64.h, oct-glob.cc, oct-glob.h, oct-inttypes.h, oct-mutex.cc, oct-mutex.h, oct-refcount.h, oct-shlib.cc, oct-shlib.h, oct-sparse.cc, oct-sparse.h, oct-string.h, octave-preserve-stream-state.h, pathsearch.cc, pathsearch.h, quit.cc, quit.h, unwind-prot.cc, unwind-prot.h, url-transfer.cc, url-transfer.h: Re-indent code after switch to using namespace macros.
author Rik <rik@octave.org>
date Thu, 01 Dec 2022 18:02:15 -0800
parents e88a07dec498
children 23664317f0d3 96d321d59ee3
comparison
equal deleted inserted replaced
31605:e88a07dec498 31607:aac27ad79be6
233 return have_fmt; 233 return have_fmt;
234 } 234 }
235 235
236 OCTAVE_BEGIN_NAMESPACE(octave) 236 OCTAVE_BEGIN_NAMESPACE(octave)
237 237
238 static octave_scalar_map 238 static octave_scalar_map
239 init_warning_options (const std::string& state) 239 init_warning_options (const std::string& state)
240 { 240 {
241 octave_scalar_map initw; 241 octave_scalar_map initw;
242 242
243 initw.setfield ("identifier", "all"); 243 initw.setfield ("identifier", "all");
244 initw.setfield ("state", state); 244 initw.setfield ("state", state);
245 245
246 return initw; 246 return initw;
247 } 247 }
248 248
249 static octave_map 249 static octave_map
250 init_error_stack (interpreter& interp) 250 init_error_stack (interpreter& interp)
251 { 251 {
252 tree_evaluator& tw = interp.get_evaluator (); 252 tree_evaluator& tw = interp.get_evaluator ();
253 253
254 return tw.empty_backtrace (); 254 return tw.empty_backtrace ();
255 } 255 }
256 256
257 error_system::error_system (interpreter& interp) 257 error_system::error_system (interpreter& interp)
258 : m_interpreter (interp), 258 : m_interpreter (interp),
259 m_debug_on_error (false), 259 m_debug_on_error (false),
260 m_debug_on_caught (false), 260 m_debug_on_caught (false),
261 m_debug_on_warning (false), 261 m_debug_on_warning (false),
262 m_discard_warning_messages (false), 262 m_discard_warning_messages (false),
263 m_beep_on_error (false), 263 m_beep_on_error (false),
264 m_backtrace_on_warning (true), 264 m_backtrace_on_warning (true),
265 m_verbose_warning (false), 265 m_verbose_warning (false),
266 m_quiet_warning (false), 266 m_quiet_warning (false),
267 m_warning_options (init_warning_options ("on")), 267 m_warning_options (init_warning_options ("on")),
268 m_last_error_message (), 268 m_last_error_message (),
269 m_last_warning_message (), 269 m_last_warning_message (),
270 m_last_warning_id (), 270 m_last_warning_id (),
271 m_last_error_id (), 271 m_last_error_id (),
272 m_last_error_stack (init_error_stack (interp)) 272 m_last_error_stack (init_error_stack (interp))
273 { 273 {
274 initialize_default_warning_state (); 274 initialize_default_warning_state ();
275 } 275 }
276 276
277 octave_value 277 octave_value
278 error_system::debug_on_error (const octave_value_list& args, int nargout) 278 error_system::debug_on_error (const octave_value_list& args, int nargout)
279 { 279 {
280 return set_internal_variable (m_debug_on_error, args, nargout, 280 return set_internal_variable (m_debug_on_error, args, nargout,
281 "debug_on_error"); 281 "debug_on_error");
282 } 282 }
283 283
284 octave_value 284 octave_value
285 error_system::debug_on_caught (const octave_value_list& args, int nargout) 285 error_system::debug_on_caught (const octave_value_list& args, int nargout)
286 { 286 {
287 return set_internal_variable (m_debug_on_caught, args, nargout, 287 return set_internal_variable (m_debug_on_caught, args, nargout,
288 "debug_on_caught"); 288 "debug_on_caught");
289 } 289 }
290 290
291 octave_value 291 octave_value
292 error_system::debug_on_warning (const octave_value_list& args, int nargout) 292 error_system::debug_on_warning (const octave_value_list& args, int nargout)
293 { 293 {
294 return set_internal_variable (m_debug_on_warning, args, nargout, 294 return set_internal_variable (m_debug_on_warning, args, nargout,
295 "debug_on_warning"); 295 "debug_on_warning");
296 } 296 }
297 297
298 octave_value 298 octave_value
299 error_system::discard_warning_messages (const octave_value_list& args, 299 error_system::discard_warning_messages (const octave_value_list& args,
300 int nargout) 300 int nargout)
301 { 301 {
302 return set_internal_variable (m_discard_warning_messages, args, nargout, 302 return set_internal_variable (m_discard_warning_messages, args, nargout,
303 "discard_warning_messages"); 303 "discard_warning_messages");
304 } 304 }
305 305
306 octave_value 306 octave_value
307 error_system::beep_on_error (const octave_value_list& args, int nargout) 307 error_system::beep_on_error (const octave_value_list& args, int nargout)
308 { 308 {
309 return set_internal_variable (m_beep_on_error, args, nargout, 309 return set_internal_variable (m_beep_on_error, args, nargout,
310 "beep_on_error"); 310 "beep_on_error");
311 } 311 }
312 312
313 octave_value 313 octave_value
314 error_system::backtrace_on_warning (const octave_value_list& args, 314 error_system::backtrace_on_warning (const octave_value_list& args,
315 int nargout) 315 int nargout)
316 { 316 {
317 return set_internal_variable (m_backtrace_on_warning, args, nargout, 317 return set_internal_variable (m_backtrace_on_warning, args, nargout,
318 "backtrace_on_warning"); 318 "backtrace_on_warning");
319 } 319 }
320 320
321 octave_value 321 octave_value
322 error_system::verbose_warning (const octave_value_list& args, int nargout) 322 error_system::verbose_warning (const octave_value_list& args, int nargout)
323 { 323 {
324 return set_internal_variable (m_verbose_warning, args, nargout, 324 return set_internal_variable (m_verbose_warning, args, nargout,
325 "verbose_warning"); 325 "verbose_warning");
326 } 326 }
327 327
328 octave_value 328 octave_value
329 error_system::quiet_warning (const octave_value_list& args, int nargout) 329 error_system::quiet_warning (const octave_value_list& args, int nargout)
330 { 330 {
331 return set_internal_variable (m_quiet_warning, args, nargout, 331 return set_internal_variable (m_quiet_warning, args, nargout,
332 "quiet_warning"); 332 "quiet_warning");
333 } 333 }
334 334
335 octave_value 335 octave_value
336 error_system::last_error_message (const octave_value_list& args, int nargout) 336 error_system::last_error_message (const octave_value_list& args, int nargout)
337 { 337 {
338 return set_internal_variable (m_last_error_message, args, nargout, 338 return set_internal_variable (m_last_error_message, args, nargout,
339 "last_error_message"); 339 "last_error_message");
340 } 340 }
341 341
342 octave_value 342 octave_value
343 error_system::last_warning_message (const octave_value_list& args, 343 error_system::last_warning_message (const octave_value_list& args,
344 int nargout) 344 int nargout)
345 { 345 {
346 return set_internal_variable (m_last_warning_message, args, nargout, 346 return set_internal_variable (m_last_warning_message, args, nargout,
347 "last_warning_message"); 347 "last_warning_message");
348 } 348 }
349 349
350 octave_value 350 octave_value
351 error_system::last_warning_id (const octave_value_list& args, int nargout) 351 error_system::last_warning_id (const octave_value_list& args, int nargout)
352 { 352 {
353 return set_internal_variable (m_last_warning_id, args, nargout, 353 return set_internal_variable (m_last_warning_id, args, nargout,
354 "last_warning_id"); 354 "last_warning_id");
355 } 355 }
356 356
357 octave_value 357 octave_value
358 error_system::last_error_id (const octave_value_list& args, int nargout) 358 error_system::last_error_id (const octave_value_list& args, int nargout)
359 { 359 {
360 return set_internal_variable (m_last_error_id, args, nargout, 360 return set_internal_variable (m_last_error_id, args, nargout,
361 "last_error_id"); 361 "last_error_id");
362 } 362 }
363 363
364 // Use static fields for the best efficiency. 364 // Use static fields for the best efficiency.
365 // NOTE: C++0x will allow these two to be merged into one. 365 // NOTE: C++0x will allow these two to be merged into one.
366 static const char *bt_fieldnames[] = 366 static const char *bt_fieldnames[] =
367 { "file", "name", "line", "column", nullptr }; 367 { "file", "name", "line", "column", nullptr };
368 368
369 static const octave_fields bt_fields (bt_fieldnames); 369 static const octave_fields bt_fields (bt_fieldnames);
370 370
371 octave_map 371 octave_map
372 error_system::make_stack_map (const std::list<frame_info>& frames) 372 error_system::make_stack_map (const std::list<frame_info>& frames)
373 { 373 {
374 std::size_t nframes = frames.size (); 374 std::size_t nframes = frames.size ();
375 375
376 octave_map retval (dim_vector (nframes, 1), bt_fields); 376 octave_map retval (dim_vector (nframes, 1), bt_fields);
377 377
378 Cell& file = retval.contents (0); 378 Cell& file = retval.contents (0);
379 Cell& name = retval.contents (1); 379 Cell& name = retval.contents (1);
380 Cell& line = retval.contents (2); 380 Cell& line = retval.contents (2);
381 Cell& column = retval.contents (3); 381 Cell& column = retval.contents (3);
382 382
383 octave_idx_type k = 0; 383 octave_idx_type k = 0;
384 384
385 for (const auto& frm : frames) 385 for (const auto& frm : frames)
386 { 386 {
387 file(k) = frm.file_name (); 387 file(k) = frm.file_name ();
388 name(k) = frm.fcn_name (); 388 name(k) = frm.fcn_name ();
389 line(k) = frm.line (); 389 line(k) = frm.line ();
390 column(k) = frm.column (); 390 column(k) = frm.column ();
391 391
392 k++; 392 k++;
393 } 393 }
394 394
395 return retval; 395 return retval;
396 } 396 }
397 397
398 std::list<frame_info> 398 std::list<frame_info>
399 error_system::make_stack_frame_list (const octave_map& stack) 399 error_system::make_stack_frame_list (const octave_map& stack)
400 { 400 {
401 std::list<frame_info> frames; 401 std::list<frame_info> frames;
402 402
403 Cell file = stack.contents ("file"); 403 Cell file = stack.contents ("file");
404 Cell name = stack.contents ("name"); 404 Cell name = stack.contents ("name");
405 Cell line = stack.contents ("line"); 405 Cell line = stack.contents ("line");
406 Cell column = stack.contents ("column"); 406 Cell column = stack.contents ("column");
407 407
408 octave_idx_type nel = name.numel (); 408 octave_idx_type nel = name.numel ();
409 409
410 for (octave_idx_type i = 0; i < nel; i++) 410 for (octave_idx_type i = 0; i < nel; i++)
411 frames.push_back (frame_info (file(i).string_value (), 411 frames.push_back (frame_info (file(i).string_value (),
412 name(i).string_value (), 412 name(i).string_value (),
413 line(i).int_value (), 413 line(i).int_value (),
414 column(i).int_value ())); 414 column(i).int_value ()));
415 415
416 return frames; 416 return frames;
417 } 417 }
418 418
419 // For given warning ID, return 0 if warnings are disabled, 1 if 419 // For given warning ID, return 0 if warnings are disabled, 1 if
420 // enabled, and 2 if the given ID should be an error instead of a 420 // enabled, and 2 if the given ID should be an error instead of a
421 // warning. 421 // warning.
422 422
423 int error_system::warning_enabled (const std::string& id) 423 int error_system::warning_enabled (const std::string& id)
424 { 424 {
425 int retval = 0; 425 int retval = 0;
426 426
427 int all_state = -1; 427 int all_state = -1;
428 int id_state = -1; 428 int id_state = -1;
429 429
430 octave_map opts = warning_options (); 430 octave_map opts = warning_options ();
431 431
432 octave_idx_type nel = opts.numel (); 432 octave_idx_type nel = opts.numel ();
433 433
434 if (nel > 0) 434 if (nel > 0)
435 { 435 {
436 Cell identifier = opts.contents ("identifier"); 436 Cell identifier = opts.contents ("identifier");
437 Cell state = opts.contents ("state"); 437 Cell state = opts.contents ("state");
438 438
439 bool all_found = false; 439 bool all_found = false;
440 bool id_found = false; 440 bool id_found = false;
441 441
442 for (octave_idx_type i = 0; i < nel; i++) 442 for (octave_idx_type i = 0; i < nel; i++)
443 { 443 {
444 octave_value ov = identifier(i); 444 octave_value ov = identifier(i);
445 std::string ovs = ov.string_value (); 445 std::string ovs = ov.string_value ();
446 446
447 if (! all_found && ovs == "all") 447 if (! all_found && ovs == "all")
448 { 448 {
449 all_state = check_state (state(i).string_value ()); 449 all_state = check_state (state(i).string_value ());
450 450
451 if (all_state >= 0) 451 if (all_state >= 0)
452 all_found = true; 452 all_found = true;
453 } 453 }
454 454
455 if (! id_found && ovs == id) 455 if (! id_found && ovs == id)
456 { 456 {
457 id_state = check_state (state(i).string_value ()); 457 id_state = check_state (state(i).string_value ());
458 458
459 if (id_state >= 0) 459 if (id_state >= 0)
460 id_found = true; 460 id_found = true;
461 } 461 }
462 462
463 if (all_found && id_found) 463 if (all_found && id_found)
464 break;
465 }
466 }
467
468 // If "all" is not present, assume warnings are enabled.
469 if (all_state == -1)
470 all_state = 1;
471
472 if (all_state == 0)
473 {
474 if (id_state >= 0)
475 retval = id_state;
476 }
477 else if (all_state == 1)
478 {
479 if (id_state == 0 || id_state == 2)
480 retval = id_state;
481 else
482 retval = all_state;
483 }
484 else if (all_state == 2)
485 {
486 if (id_state == 0)
487 retval= id_state;
488 else
489 retval = all_state;
490 }
491
492 return retval;
493 }
494
495 void error_system::vusage (const char *id, const char *fmt, va_list args)
496 {
497 std::string str_id = id ? id : "";
498 std::string message = format_message (fmt, args);
499
500 throw_error ("usage", str_id, message);
501 }
502
503 void error_system::vwarning (const char *name, const char *id,
504 const char *fmt, va_list args)
505 {
506 flush_stdout ();
507
508 std::string base_msg = format_message (fmt, args);
509 std::string msg_string;
510
511 if (name)
512 msg_string = std::string (name) + ": ";
513
514 msg_string += base_msg;
515
516 bool fmt_suppresses_backtrace = false;
517 std::size_t fmt_len = (fmt ? strlen (fmt) : 0);
518 fmt_suppresses_backtrace = (fmt_len > 0 && fmt[fmt_len-1] == '\n');
519
520 if (! fmt_suppresses_backtrace)
521 msg_string += '\n';
522
523 last_warning_id (id);
524 last_warning_message (base_msg);
525
526 if (discard_warning_messages ())
527 return;
528
529 tree_evaluator& tw = m_interpreter.get_evaluator ();
530
531 bool in_user_code = tw.in_user_code ();
532
533 if (! quiet_warning ())
534 {
535 octave_diary << msg_string;
536 std::cerr << msg_string;
537
538 if (! fmt_suppresses_backtrace && in_user_code
539 && backtrace_on_warning ()
540 && ! discard_warning_messages ())
541 {
542 std::string bt_msg = tw.backtrace_message ();
543
544 if (! bt_msg.empty ())
545 bt_msg = "warning: called from\n" + bt_msg;
546
547 octave_diary << bt_msg << std::endl;
548 std::cerr << bt_msg << std::endl;
549 }
550 }
551
552 bp_table& bptab = tw.get_bp_table ();
553
554 if ((m_interpreter.interactive ()
555 || application::forced_interactive ())
556 && debug_on_warning () && in_user_code && bptab.debug_on_warn (id))
557 {
558 unwind_protect_var<bool> restore_var (m_debug_on_warning, false);
559
560 tw.enter_debugger ();
561 }
562 }
563
564 void error_system::error_1 (execution_exception& ee, const char *id,
565 const char *fmt, va_list args)
566 {
567 ee.set_identifier (id);
568 ee.set_message (format_message (fmt, args));
569
570 throw_error (ee);
571 }
572
573 void error_system::error_1 (const char *id, const char *fmt,
574 va_list args)
575 {
576 std::string message = format_message (fmt, args);
577
578 std::list<frame_info> stack_info;
579
580 throw_error ("error", id, message);
581 }
582
583 void error_system::vwarning (const char *id, const char *fmt, va_list args)
584 {
585 int warn_opt = warning_enabled (id);
586
587 if (warn_opt == 2)
588 {
589 // Handle this warning as an error.
590
591 error_1 (id, fmt, args);
592 }
593 else if (warn_opt == 1)
594 vwarning ("warning", id, fmt, args);
595 }
596
597 void error_system::rethrow_error (const std::string& id,
598 const std::string& msg,
599 const octave_map& stack)
600 {
601 std::list<frame_info> stack_info;
602
603 execution_exception ee ("error", id, msg, stack_info);
604
605 if (! stack.isempty ())
606 {
607 if (! (stack.contains ("file") && stack.contains ("name")
608 && stack.contains ("line")))
609 error ("rethrow: STACK struct must contain the fields 'file', 'name', and 'line'");
610
611 if (! stack.contains ("column"))
612 {
613 octave_map new_stack = stack;
614
615 new_stack.setfield ("column", Cell (octave_value (-1)));
616
617 ee.set_stack_info (make_stack_frame_list (new_stack));
618 }
619 else
620 ee.set_stack_info (make_stack_frame_list (stack));
621 }
622
623 throw_error (ee);
624 }
625
626 void error_system::vpanic (const char *fmt, va_list args)
627 {
628 // Is there any point in trying to write the panic message to the
629 // diary?
630
631 std::cerr << "panic: " << format_message (fmt, args) << std::endl;
632
633 abort ();
634 }
635
636 void error_system::panic (const char *fmt, ...)
637 {
638 va_list args;
639 va_start (args, fmt);
640 vpanic (fmt, args);
641 va_end (args);
642 }
643
644 octave_scalar_map error_system::warning_query (const std::string& id_arg)
645 {
646 octave_scalar_map retval;
647
648 std::string id = id_arg;
649
650 if (id == "last")
651 id = last_warning_id ();
652
653 octave_map opts = warning_options ();
654
655 Cell ident = opts.contents ("identifier");
656 Cell state = opts.contents ("state");
657
658 octave_idx_type nel = ident.numel ();
659
660 panic_if (nel == 0);
661
662 bool found = false;
663
664 std::string val;
665
666 for (octave_idx_type i = 0; i < nel; i++)
667 {
668 if (ident(i).string_value () == id)
669 {
670 val = state(i).string_value ();
671 found = true;
672 break;
673 }
674 }
675
676 if (! found)
677 {
678 for (octave_idx_type i = 0; i < nel; i++)
679 {
680 if (ident(i).string_value () == "all")
681 {
682 val = state(i).string_value ();
683 found = true;
464 break; 684 break;
465 } 685 }
466 } 686 }
467 687 }
468 // If "all" is not present, assume warnings are enabled. 688
469 if (all_state == -1) 689 // The warning state "all" is always supposed to remain in the list,
470 all_state = 1; 690 // so we should always find a state, either explicitly or by using the
471 691 // state for "all".
472 if (all_state == 0) 692 panic_unless (found);
473 { 693
474 if (id_state >= 0) 694 retval.assign ("identifier", id);
475 retval = id_state; 695 retval.assign ("state", val);
476 } 696
477 else if (all_state == 1) 697 return retval;
478 { 698 }
479 if (id_state == 0 || id_state == 2) 699
480 retval = id_state; 700 std::string error_system::default_warning_state (void)
481 else 701 {
482 retval = all_state; 702 std::string retval = "on";
483 } 703
484 else if (all_state == 2) 704 octave_map opts = warning_options ();
485 { 705
486 if (id_state == 0) 706 Cell ident = opts.contents ("identifier");
487 retval= id_state; 707 Cell state = opts.contents ("state");
488 else 708
489 retval = all_state; 709 octave_idx_type nel = ident.numel ();
490 } 710
491 711 for (octave_idx_type i = 0; i < nel; i++)
492 return retval; 712 {
493 } 713 if (ident(i).string_value () == "all")
494 714 {
495 void error_system::vusage (const char *id, const char *fmt, va_list args) 715 retval = state(i).string_value ();
496 { 716 break;
497 std::string str_id = id ? id : ""; 717 }
498 std::string message = format_message (fmt, args); 718 }
499 719
500 throw_error ("usage", str_id, message); 720 return retval;
501 } 721 }
502 722
503 void error_system::vwarning (const char *name, const char *id, 723 void error_system::display_warning_options (std::ostream& os)
504 const char *fmt, va_list args) 724 {
505 { 725 octave_map opts = warning_options ();
506 flush_stdout (); 726
507 727 Cell ident = opts.contents ("identifier");
508 std::string base_msg = format_message (fmt, args); 728 Cell state = opts.contents ("state");
509 std::string msg_string; 729
510 730 octave_idx_type nel = ident.numel ();
511 if (name) 731
512 msg_string = std::string (name) + ": "; 732 std::string all_state = default_warning_state ();
513 733
514 msg_string += base_msg; 734 if (all_state == "on")
515 735 os << "By default, warnings are enabled.";
516 bool fmt_suppresses_backtrace = false; 736 else if (all_state == "off")
517 std::size_t fmt_len = (fmt ? strlen (fmt) : 0); 737 os << "By default, warnings are disabled.";
518 fmt_suppresses_backtrace = (fmt_len > 0 && fmt[fmt_len-1] == '\n'); 738 else if (all_state == "error")
519 739 os << "By default, warnings are treated as errors.";
520 if (! fmt_suppresses_backtrace) 740 else
521 msg_string += '\n'; 741 panic_impossible ();
522 742
523 last_warning_id (id); 743 if (nel > 1)
524 last_warning_message (base_msg); 744 {
525 745 os << "\n";
526 if (discard_warning_messages ()) 746 os << "Non-default warning states are:\n\n";
527 return; 747 os << " State Warning ID\n";
528 748 }
529 tree_evaluator& tw = m_interpreter.get_evaluator (); 749
530 750 // The state for "all" is always supposed to be first in the list.
531 bool in_user_code = tw.in_user_code (); 751
532 752 for (octave_idx_type i = 1; i < nel; i++)
533 if (! quiet_warning ()) 753 {
534 { 754 std::string tid = ident(i).string_value ();
535 octave_diary << msg_string; 755 std::string tst = state(i).string_value ();
536 std::cerr << msg_string; 756
537 757 os << std::setw (7) << tst << " " << tid << "\n";
538 if (! fmt_suppresses_backtrace && in_user_code 758 }
539 && backtrace_on_warning () 759
540 && ! discard_warning_messages ()) 760 os << std::endl;
541 { 761 }
542 std::string bt_msg = tw.backtrace_message (); 762
543 763 void error_system::set_warning_option (const std::string& state,
544 if (! bt_msg.empty ()) 764 const std::string& ident)
545 bt_msg = "warning: called from\n" + bt_msg; 765 {
546 766 std::string all_state = default_warning_state ();
547 octave_diary << bt_msg << std::endl; 767
548 std::cerr << bt_msg << std::endl; 768 if (state != "on" && state != "off" && state != "error")
549 } 769 error ("invalid warning state: %s", state.c_str ());
550 } 770
551 771 octave_map opts = warning_options ();
552 bp_table& bptab = tw.get_bp_table (); 772
553 773 Cell tid = opts.contents ("identifier");
554 if ((m_interpreter.interactive () 774 Cell tst = opts.contents ("state");
555 || application::forced_interactive ()) 775
556 && debug_on_warning () && in_user_code && bptab.debug_on_warn (id)) 776 octave_idx_type nel = tid.numel ();
557 { 777
558 unwind_protect_var<bool> restore_var (m_debug_on_warning, false); 778 for (octave_idx_type i = 0; i < nel; i++)
559 779 {
560 tw.enter_debugger (); 780 if (tid(i).string_value () == ident)
561 } 781 {
562 } 782 // We found it in the current list of options. If the state
563 783 // for "all" is same as arg1, we can simply remove the item
564 void error_system::error_1 (execution_exception& ee, const char *id, 784 // from the list.
565 const char *fmt, va_list args) 785
566 { 786 if (state == all_state && ident != "all")
567 ee.set_identifier (id); 787 {
568 ee.set_message (format_message (fmt, args)); 788 for (i = i + 1; i < nel; i++)
569 789 {
570 throw_error (ee); 790 tid(i-1) = tid(i);
571 } 791 tst(i-1) = tst(i);
572 792 }
573 void error_system::error_1 (const char *id, const char *fmt, 793
574 va_list args) 794 tid.resize (dim_vector (1, nel-1));
575 { 795 tst.resize (dim_vector (1, nel-1));
576 std::string message = format_message (fmt, args); 796 }
577 797 else
578 std::list<frame_info> stack_info; 798 tst(i) = state;
579 799
580 throw_error ("error", id, message); 800 opts.clear ();
581 } 801
582 802 opts.assign ("identifier", tid);
583 void error_system::vwarning (const char *id, const char *fmt, va_list args) 803 opts.assign ("state", tst);
584 { 804
585 int warn_opt = warning_enabled (id); 805 warning_options (opts);
586 806
587 if (warn_opt == 2) 807 return;
588 { 808 }
589 // Handle this warning as an error. 809 }
590 810
591 error_1 (id, fmt, args); 811 // The option wasn't already in the list. Append it.
592 } 812
593 else if (warn_opt == 1) 813 tid.resize (dim_vector (1, nel+1));
594 vwarning ("warning", id, fmt, args); 814 tst.resize (dim_vector (1, nel+1));
595 } 815
596 816 tid(nel) = ident;
597 void error_system::rethrow_error (const std::string& id, 817 tst(nel) = state;
598 const std::string& msg, 818
599 const octave_map& stack) 819 opts.clear ();
600 { 820
601 std::list<frame_info> stack_info; 821 opts.assign ("identifier", tid);
602 822 opts.assign ("state", tst);
603 execution_exception ee ("error", id, msg, stack_info); 823
604 824 warning_options (opts);
605 if (! stack.isempty ()) 825 }
606 { 826
607 if (! (stack.contains ("file") && stack.contains ("name") 827 void error_system::disable_warning (const std::string& id)
608 && stack.contains ("line"))) 828 {
609 error ("rethrow: STACK struct must contain the fields 'file', 'name', and 'line'"); 829 set_warning_option ("off", id);
610 830 }
611 if (! stack.contains ("column")) 831
612 { 832 void error_system::initialize_default_warning_state (void)
613 octave_map new_stack = stack; 833 {
614 834 warning_options (init_warning_options ("on"));
615 new_stack.setfield ("column", Cell (octave_value (-1))); 835
616 836 // Most people will want to have the following disabled.
617 ee.set_stack_info (make_stack_frame_list (new_stack)); 837
618 } 838 disable_warning ("Octave:array-as-logical");
619 else 839 disable_warning ("Octave:array-to-scalar");
620 ee.set_stack_info (make_stack_frame_list (stack)); 840 disable_warning ("Octave:array-to-vector");
621 } 841 disable_warning ("Octave:imag-to-real");
622 842 disable_warning ("Octave:language-extension");
623 throw_error (ee); 843 disable_warning ("Octave:missing-semicolon");
624 } 844 disable_warning ("Octave:neg-dim-as-zero");
625 845 disable_warning ("Octave:separator-insert");
626 void error_system::vpanic (const char *fmt, va_list args) 846 disable_warning ("Octave:single-quote-string");
627 { 847 disable_warning ("Octave:str-to-num");
628 // Is there any point in trying to write the panic message to the 848 disable_warning ("Octave:mixed-string-concat");
629 // diary? 849 disable_warning ("Octave:variable-switch-label");
630 850 }
631 std::cerr << "panic: " << format_message (fmt, args) << std::endl; 851
632 852 void error_system::interpreter_try (unwind_protect& frame)
633 abort (); 853 {
634 } 854 frame.protect_var (m_debug_on_error);
635 855 m_debug_on_error = false;
636 void error_system::panic (const char *fmt, ...) 856
637 { 857 frame.protect_var (m_debug_on_warning);
638 va_list args; 858 m_debug_on_warning = false;
639 va_start (args, fmt); 859
640 vpanic (fmt, args); 860 // Leave debug_on_caught as it was, so errors in try/catch are still
641 va_end (args); 861 // caught.
642 } 862 }
643 863
644 octave_scalar_map error_system::warning_query (const std::string& id_arg) 864 void error_system::throw_error (const std::string& err_type,
645 { 865 const std::string& id,
646 octave_scalar_map retval; 866 const std::string& message,
647 867 const std::list<frame_info>& stack_info_arg)
648 std::string id = id_arg; 868 {
649 869 std::list<frame_info> stack_info = stack_info_arg;
650 if (id == "last") 870
651 id = last_warning_id (); 871 if (stack_info.empty ())
652 872 {
653 octave_map opts = warning_options (); 873 tree_evaluator& tw = m_interpreter.get_evaluator ();
654 874
655 Cell ident = opts.contents ("identifier"); 875 stack_info = tw.backtrace_info ();
656 Cell state = opts.contents ("state"); 876
657 877 // Print the error message only if it is different from the
658 octave_idx_type nel = ident.numel (); 878 // previous one; makes the output more concise and readable.
659 879
660 panic_if (nel == 0); 880 stack_info.unique ();
661 881 }
662 bool found = false; 882
663 883 execution_exception ex (err_type, id, message, stack_info);
664 std::string val; 884
665 885 throw_error (ex);
666 for (octave_idx_type i = 0; i < nel; i++) 886 }
667 { 887
668 if (ident(i).string_value () == id) 888 void error_system::throw_error (execution_exception& ex)
669 { 889 {
670 val = state(i).string_value (); 890 throw ex;
671 found = true; 891 }
672 break; 892
673 } 893 void error_system::save_exception (const execution_exception& ee)
674 } 894 {
675 895 last_error_id (ee.identifier ());
676 if (! found) 896 std::string message = ee.message ();
677 { 897 std::string xmsg
678 for (octave_idx_type i = 0; i < nel; i++) 898 = (message.size () > 0 && message.back () == '\n'
679 { 899 ? message.substr (0, message.size () - 1) : message);
680 if (ident(i).string_value () == "all") 900 last_error_message (xmsg);
681 { 901 last_error_stack (make_stack_map (ee.stack_info ()));
682 val = state(i).string_value (); 902 }
683 found = true; 903
684 break; 904 // DEPRECATED in Octave 7.
685 } 905 void error_system::display_exception (const execution_exception& ee,
686 } 906 std::ostream& os) const
687 } 907 {
688 908 if (m_beep_on_error)
689 // The warning state "all" is always supposed to remain in the list, 909 os << "\a";
690 // so we should always find a state, either explicitly or by using the 910
691 // state for "all". 911 ee.display (octave_diary);
692 panic_unless (found); 912 ee.display (os);
693 913 }
694 retval.assign ("identifier", id); 914
695 retval.assign ("state", val); 915 void error_system::display_exception (const execution_exception& ee) const
696 916 {
697 return retval; 917 // FIXME: How should we handle beep_on_error?
698 } 918
699 919 ee.display (octave_diary);
700 std::string error_system::default_warning_state (void) 920
701 { 921 // FIXME: Handle display using an event manager message so that the
702 std::string retval = "on"; 922 // GUI or other client can receive error messages without needing to
703 923 // capture them from std::cerr or some other stream.
704 octave_map opts = warning_options (); 924
705 925 event_manager& evmgr = m_interpreter.get_event_manager ();
706 Cell ident = opts.contents ("identifier"); 926
707 Cell state = opts.contents ("state"); 927 evmgr.display_exception (ee, m_beep_on_error);
708 928 }
709 octave_idx_type nel = ident.numel ();
710
711 for (octave_idx_type i = 0; i < nel; i++)
712 {
713 if (ident(i).string_value () == "all")
714 {
715 retval = state(i).string_value ();
716 break;
717 }
718 }
719
720 return retval;
721 }
722
723 void error_system::display_warning_options (std::ostream& os)
724 {
725 octave_map opts = warning_options ();
726
727 Cell ident = opts.contents ("identifier");
728 Cell state = opts.contents ("state");
729
730 octave_idx_type nel = ident.numel ();
731
732 std::string all_state = default_warning_state ();
733
734 if (all_state == "on")
735 os << "By default, warnings are enabled.";
736 else if (all_state == "off")
737 os << "By default, warnings are disabled.";
738 else if (all_state == "error")
739 os << "By default, warnings are treated as errors.";
740 else
741 panic_impossible ();
742
743 if (nel > 1)
744 {
745 os << "\n";
746 os << "Non-default warning states are:\n\n";
747 os << " State Warning ID\n";
748 }
749
750 // The state for "all" is always supposed to be first in the list.
751
752 for (octave_idx_type i = 1; i < nel; i++)
753 {
754 std::string tid = ident(i).string_value ();
755 std::string tst = state(i).string_value ();
756
757 os << std::setw (7) << tst << " " << tid << "\n";
758 }
759
760 os << std::endl;
761 }
762
763 void error_system::set_warning_option (const std::string& state,
764 const std::string& ident)
765 {
766 std::string all_state = default_warning_state ();
767
768 if (state != "on" && state != "off" && state != "error")
769 error ("invalid warning state: %s", state.c_str ());
770
771 octave_map opts = warning_options ();
772
773 Cell tid = opts.contents ("identifier");
774 Cell tst = opts.contents ("state");
775
776 octave_idx_type nel = tid.numel ();
777
778 for (octave_idx_type i = 0; i < nel; i++)
779 {
780 if (tid(i).string_value () == ident)
781 {
782 // We found it in the current list of options. If the state
783 // for "all" is same as arg1, we can simply remove the item
784 // from the list.
785
786 if (state == all_state && ident != "all")
787 {
788 for (i = i + 1; i < nel; i++)
789 {
790 tid(i-1) = tid(i);
791 tst(i-1) = tst(i);
792 }
793
794 tid.resize (dim_vector (1, nel-1));
795 tst.resize (dim_vector (1, nel-1));
796 }
797 else
798 tst(i) = state;
799
800 opts.clear ();
801
802 opts.assign ("identifier", tid);
803 opts.assign ("state", tst);
804
805 warning_options (opts);
806
807 return;
808 }
809 }
810
811 // The option wasn't already in the list. Append it.
812
813 tid.resize (dim_vector (1, nel+1));
814 tst.resize (dim_vector (1, nel+1));
815
816 tid(nel) = ident;
817 tst(nel) = state;
818
819 opts.clear ();
820
821 opts.assign ("identifier", tid);
822 opts.assign ("state", tst);
823
824 warning_options (opts);
825 }
826
827 void error_system::disable_warning (const std::string& id)
828 {
829 set_warning_option ("off", id);
830 }
831
832 void error_system::initialize_default_warning_state (void)
833 {
834 warning_options (init_warning_options ("on"));
835
836 // Most people will want to have the following disabled.
837
838 disable_warning ("Octave:array-as-logical");
839 disable_warning ("Octave:array-to-scalar");
840 disable_warning ("Octave:array-to-vector");
841 disable_warning ("Octave:imag-to-real");
842 disable_warning ("Octave:language-extension");
843 disable_warning ("Octave:missing-semicolon");
844 disable_warning ("Octave:neg-dim-as-zero");
845 disable_warning ("Octave:separator-insert");
846 disable_warning ("Octave:single-quote-string");
847 disable_warning ("Octave:str-to-num");
848 disable_warning ("Octave:mixed-string-concat");
849 disable_warning ("Octave:variable-switch-label");
850 }
851
852 void error_system::interpreter_try (unwind_protect& frame)
853 {
854 frame.protect_var (m_debug_on_error);
855 m_debug_on_error = false;
856
857 frame.protect_var (m_debug_on_warning);
858 m_debug_on_warning = false;
859
860 // Leave debug_on_caught as it was, so errors in try/catch are still
861 // caught.
862 }
863
864 void error_system::throw_error (const std::string& err_type,
865 const std::string& id,
866 const std::string& message,
867 const std::list<frame_info>& stack_info_arg)
868 {
869 std::list<frame_info> stack_info = stack_info_arg;
870
871 if (stack_info.empty ())
872 {
873 tree_evaluator& tw = m_interpreter.get_evaluator ();
874
875 stack_info = tw.backtrace_info ();
876
877 // Print the error message only if it is different from the
878 // previous one; makes the output more concise and readable.
879
880 stack_info.unique ();
881 }
882
883 execution_exception ex (err_type, id, message, stack_info);
884
885 throw_error (ex);
886 }
887
888 void error_system::throw_error (execution_exception& ex)
889 {
890 throw ex;
891 }
892
893 void error_system::save_exception (const execution_exception& ee)
894 {
895 last_error_id (ee.identifier ());
896 std::string message = ee.message ();
897 std::string xmsg
898 = (message.size () > 0 && message.back () == '\n'
899 ? message.substr (0, message.size () - 1) : message);
900 last_error_message (xmsg);
901 last_error_stack (make_stack_map (ee.stack_info ()));
902 }
903
904 // DEPRECATED in Octave 7.
905 void error_system::display_exception (const execution_exception& ee,
906 std::ostream& os) const
907 {
908 if (m_beep_on_error)
909 os << "\a";
910
911 ee.display (octave_diary);
912 ee.display (os);
913 }
914
915 void error_system::display_exception (const execution_exception& ee) const
916 {
917 // FIXME: How should we handle beep_on_error?
918
919 ee.display (octave_diary);
920
921 // FIXME: Handle display using an event manager message so that the
922 // GUI or other client can receive error messages without needing to
923 // capture them from std::cerr or some other stream.
924
925 event_manager& evmgr = m_interpreter.get_event_manager ();
926
927 evmgr.display_exception (ee, m_beep_on_error);
928 }
929 929
930 OCTAVE_END_NAMESPACE(octave) 930 OCTAVE_END_NAMESPACE(octave)
931 931
932 void 932 void
933 vmessage (const char *name, const char *fmt, va_list args) 933 vmessage (const char *name, const char *fmt, va_list args)
1692 else 1692 else
1693 { 1693 {
1694 octave_scalar_map tmp = es.warning_query (arg2); 1694 octave_scalar_map tmp = es.warning_query (arg2);
1695 1695
1696 octave_stdout << '"' << arg2 << R"(" warning state is ")" << 1696 octave_stdout << '"' << arg2 << R"(" warning state is ")" <<
1697 tmp.getfield ("state").string_value () << 1697 tmp.getfield ("state").string_value () <<
1698 "\"\n"; 1698 "\"\n";
1699 } 1699 }
1700 } 1700 }
1701 1701
1702 done = true; 1702 done = true;
1703 } 1703 }