GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
interpreter.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1993-2025 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include <cstdio>
31#include <clocale>
32
33#include <iostream>
34#include <set>
35#include <string>
36#include <thread>
37
38#include "cmd-edit.h"
39#include "cmd-hist.h"
40#include "file-ops.h"
41#include "file-stat.h"
42#include "file-ops.h"
43#include "fpucw-wrappers.h"
44#include "lo-blas-proto.h"
45#include "lo-error.h"
46#include "lo-sysdep.h"
47#include "oct-env.h"
48#include "quit.h"
49#include "str-vec.h"
50#include "signal-wrappers.h"
51#include "unistd-wrappers.h"
52
53#include "builtin-defun-decls.h"
54#include "defaults.h"
55#include "Cell.h"
56#include "defun.h"
57#include "display.h"
58#include "error.h"
59#include "event-manager.h"
60#include "graphics.h"
61#include "help.h"
62#include "input.h"
63#include "interpreter-private.h"
64#include "interpreter.h"
65#include "load-path.h"
66#include "load-save.h"
67#include "octave.h"
68#include "oct-hist.h"
69#include "oct-map.h"
70#include "oct-mutex.h"
71#include "ovl.h"
72#include "ov.h"
73#include "ov-classdef.h"
74#include "parse.h"
75#include "pt-classdef.h"
76#include "pt-eval.h"
77#include "pt-jump.h"
78#include "pt-stmt.h"
79#include "settings.h"
80#include "sighandlers.h"
81#include "sysdep.h"
82#include "unwind-prot.h"
83#include "utils.h"
84#include "variables.h"
85#include "version.h"
86
87// TRUE means the quit() call is allowed.
88bool quit_allowed = true;
89
90// TRUE means we are ready to interpret commands, but not everything
91// is ready for interactive use.
93
94// TRUE means we've processed all the init code and we are good to go.
95std::atomic<bool> octave_initialized{false};
96
98
99DEFUN (__version_info__, args, ,
100 doc: /* -*- texinfo -*-
101@deftypefn {} {retval =} __version_info__ (@var{name}, @var{version}, @var{release}, @var{date})
102Undocumented internal function.
103@end deftypefn */)
104{
105 static octave_map vinfo;
106
107 int nargin = args.length ();
108
109 if (nargin != 0 && nargin != 4)
110 print_usage ();
111
112 octave_value retval;
113
114 if (nargin == 0)
115 retval = vinfo;
116 else if (nargin == 4)
117 {
118 if (vinfo.nfields () == 0)
119 {
120 vinfo.assign ("Name", args(0));
121 vinfo.assign ("Version", args(1));
122 vinfo.assign ("Release", args(2));
123 vinfo.assign ("Date", args(3));
124 }
125 else
126 {
127 octave_idx_type n = vinfo.numel () + 1;
128
129 vinfo.resize (dim_vector (n, 1));
130
131 octave_value idx (n);
132
133 vinfo.assign (idx, "Name", Cell (octave_value (args(0))));
134 vinfo.assign (idx, "Version", Cell (octave_value (args(1))));
135 vinfo.assign (idx, "Release", Cell (octave_value (args(2))));
136 vinfo.assign (idx, "Date", Cell (octave_value (args(3))));
137 }
138 }
139
140 return retval;
141}
142
143DEFMETHOD (quit, interp, args, ,
144 doc: /* -*- texinfo -*-
145@deftypefn {} {} quit
146@deftypefnx {} {} quit cancel
147@deftypefnx {} {} quit force
148@deftypefnx {} {} quit ("cancel")
149@deftypefnx {} {} quit ("force")
150@deftypefnx {} {} quit (@var{status})
151@deftypefnx {} {} quit (@var{status}, "force")
152@deftypefnx {} {} exit (@dots{})
153Quit the current Octave session.
154
155If the optional integer value @var{status} is supplied, pass that value to
156the operating system as Octave's exit status. The default value is zero.
157
158When exiting, Octave will attempt to run the m-file @file{finish.m} if it
159exists. User commands to save the workspace or clean up temporary files
160may be placed in that file. Alternatively, another m-file may be scheduled
161to run using @code{atexit}. If an error occurs while executing the
162@file{finish.m} file, Octave does not exit and control is returned to
163the command prompt.
164
165If the optional argument @qcode{"cancel"} is provided, Octave does not
166exit and control is returned to the command prompt. This feature allows
167the @code{finish.m} file to cancel the quit process.
168
169If the user preference to request confirmation before exiting, Octave
170will display a dialog and give the user an option to cancel the exit
171process.
172
173If the optional argument @qcode{"force"} is provided, no confirmation is
174requested, and the execution of the @file{finish.m} file is skipped.
175
176Programming Note: @code{exit} is an alias for @code{quit} and can be used
177interchangeably.
178@seealso{atexit}
179@end deftypefn */)
180{
181 int numel = args.length ();
182
183 if (numel > 2)
184 print_usage ();
185
186 int exit_status = 0;
187
188 bool force = false;
189 bool cancel = false;
190
191 if (numel == 2)
192 {
193 exit_status = args(0).xnint_value ("quit: STATUS must be an integer");
194 std::string frc
195 = args(1).xstring_value ("quit: second argument must be a string");
196
197 if (frc == "force")
198 force = true;
199 else
200 error (R"(quit: second argument must be string "force")");
201 }
202 else if (numel == 1)
203 {
204 if (args(0).is_string ())
205 {
206 const char *msg
207 = R"(quit: option must be string "cancel" or "force")";
208
209 std::string opt = args(0).xstring_value (msg);
210
211 if (opt == "cancel")
212 cancel = true;
213 else if (opt == "force")
214 force = true;
215 else
216 error ("%s", msg);
217 }
218 else
219 exit_status = args(0).xnint_value ("quit: STATUS must be an integer");
220 }
221
222 if (cancel)
223 {
224 // No effect if "quit cancel" appears outside of finish script.
225
226 if (interp.executing_finish_script ())
227 interp.cancel_quit (true);
228
229 return ovl ();
230 }
231
232 interp.quit (exit_status, force);
233
234 return ovl ();
235}
236
237DEFALIAS (exit, quit);
238
239DEFMETHOD (atexit, interp, args, nargout,
240 doc: /* -*- texinfo -*-
241@deftypefn {} {} atexit (@var{fcn})
242@deftypefnx {} {} atexit (@var{fcn}, true)
243@deftypefnx {} {} atexit (@var{fcn}, false)
244@deftypefnx {} {@var{status} =} atexit (@var{fcn}, false)
245Register a function to be called when Octave exits.
246
247For example,
248
249@example
250@group
251function last_words ()
252 disp ("Bye bye");
253endfunction
254atexit ("last_words");
255@end group
256@end example
257
258@noindent
259will print the message @qcode{"Bye bye"} when Octave exits.
260
261The additional argument @var{flag} will register or unregister @var{fcn}
262from the list of functions to be called when Octave exits. If @var{flag} is
263true, the function is registered, and if @var{flag} is false, it is
264unregistered. For example, after registering the function @code{last_words}
265above,
266
267@example
268atexit ("last_words", false);
269@end example
270
271@noindent
272will remove the function from the list and Octave will not call
273@code{last_words} when it exits.
274
275The optional output @var{status} is only available when unregistering a
276function. The value is true if the unregistering was successful and false
277otherwise.
278
279Programming Note: @code{atexit} only removes the first occurrence of a function
280from the list; if a function was placed in the list multiple times with
281@code{atexit}, it must also be removed from the list multiple times.
282@seealso{quit}
283@end deftypefn */)
284{
285 int nargin = args.length ();
286
287 if (nargin < 1 || nargin > 2)
288 print_usage ();
289
290 std::string arg = args(0).xstring_value ("atexit: FCN argument must be a string");
291
292 bool add_mode = (nargin == 2)
293 ? args(1).strict_bool_value ("atexit: FLAG argument must be a logical value")
294 : true;
295
296 octave_value_list retval;
297
298 if (add_mode)
299 interp.add_atexit_fcn (arg);
300 else
301 {
302 bool found = interp.remove_atexit_fcn (arg);
303
304 if (nargout > 0)
305 retval = ovl (found);
306 }
307
308 return retval;
309}
310
311DEFMETHOD (__traditional__, interp, , ,
312 doc: /* -*- texinfo -*-
313@deftypefn {} {@var{tf} =} __traditional__ ()
314Return true if Octave was invoked with the @w{@env{--traditional}}@ option.
315@end deftypefn */)
316{
317 return ovl (interp.traditional ());
318}
319
324
325void
326temporary_file_list::insert (const std::string& file)
327{
328 m_files.insert (file);
329}
330
331void
333{
334 while (! m_files.empty ())
335 {
336 auto it = m_files.begin ();
337
338 octave_unlink_wrapper (it->c_str ());
339
340 m_files.erase (it);
341 }
342}
343
344// The time we last time we changed directories.
345sys::time Vlast_chdir_time = 0.0;
346
347static void
348initialize_version_info ()
349{
350 octave_value_list args (4);
351
352 args(0) = "GNU Octave";
353 args(1) = OCTAVE_VERSION;
354 args(2) = config::release ();
355 args(3) = OCTAVE_RELEASE_DATE;
356
357 F__version_info__ (args);
358}
359
360static void
361xerbla_abort ()
362{
363 error ("Fortran procedure terminated by call to XERBLA");
364}
365
366static void
367initialize_xerbla_error_handler ()
368{
369 // The idea here is to force xerbla to be referenced so that we will
370 // link to our own version instead of the one provided by the BLAS
371 // library. But numeric_limits<double>::NaN () should never be -1, so
372 // we should never actually call xerbla. FIXME (again!): If this
373 // becomes a constant expression the test might be optimized away and
374 // then the reference to the function might also disappear.
375
376 if (numeric_limits<double>::NaN () == -1)
377 F77_FUNC (xerbla, XERBLA) ("octave", 13 F77_CHAR_ARG_LEN (6));
378
379 typedef void (*xerbla_handler_ptr) ();
380
381 typedef void (*octave_set_xerbla_handler_ptr) (xerbla_handler_ptr);
382
383 dynamic_library libs ("");
384
385 if (libs)
386 {
387 octave_set_xerbla_handler_ptr octave_set_xerbla_handler
388 = reinterpret_cast<octave_set_xerbla_handler_ptr>
389 (libs.search ("octave_set_xerbla_handler"));
390
392 octave_set_xerbla_handler (xerbla_abort);
393 }
394}
395
396OCTAVE_NORETURN static void
397lo_error_handler (const char *fmt, ...)
398{
399 va_list args;
400 va_start (args, fmt);
401 verror_with_cfn (fmt, args);
402 va_end (args);
403
404 throw execution_exception ();
405}
406
407OCTAVE_NORETURN static void
408lo_error_with_id_handler (const char *id, const char *fmt, ...)
409{
410 va_list args;
411 va_start (args, fmt);
412 verror_with_id_cfn (id, fmt, args);
413 va_end (args);
414
415 throw execution_exception ();
416}
417
418static void
419initialize_error_handlers ()
420{
421 set_liboctave_error_handler (lo_error_handler);
422 set_liboctave_error_with_id_handler (lo_error_with_id_handler);
425}
426
427// Create an interpreter object and perform initialization up to the
428// point of setting reading command history and setting the load
429// path.
430
432 : m_app_context (app_context),
433 m_tmp_files (),
434 m_atexit_fcns (),
435 m_display_info (),
436 m_environment (),
437 m_settings (),
438 m_evaluator (*this),
439 m_error_system (*this),
440 m_help_system (*this),
441 m_input_system (*this),
442 m_output_system (*this),
443 m_history_system (*this),
444 m_dynamic_loader (*this),
445 m_load_path (*this),
446 m_load_save_system (*this),
447 m_type_info (),
448 m_symbol_table (*this),
449 m_stream_list (*this),
450 m_child_list (),
451 m_url_handle_manager (),
452 m_cdef_manager (*this),
453 m_gtk_manager (*this),
454 m_event_manager (*this),
455 m_gh_manager (nullptr),
456 m_interactive (false),
457 m_read_site_files (true),
458 m_read_user_files (m_app_context != nullptr),
459 m_init_trace (false),
460 m_traditional (false),
461 m_inhibit_startup_message (false),
462 m_load_path_initialized (false),
463 m_history_initialized (false),
464 m_interrupt_all_in_process_group (true),
465 m_cancel_quit (false),
466 m_executing_finish_script (false),
467 m_executing_atexit (false),
468 m_initialized (false)
469{
470 // FIXME: When thread_local storage is used by default, this message
471 // should change to say something like
472 //
473 // only one Octave interpreter may be active in any given thread
474
475 if (s_instance)
476 throw std::runtime_error
477 ("only one Octave interpreter may be active");
478
479 s_instance = this;
480
481#if defined (OCTAVE_HAVE_WINDOWS_UTF8_LOCALE)
482 // Force a UTF-8 locale on Windows if possible
483 std::setlocale (LC_ALL, ".UTF8");
484#else
485 std::setlocale (LC_ALL, "");
486#endif
487 // Matlab uses "C" locale for LC_NUMERIC class regardless of local setting
488 std::setlocale (LC_NUMERIC, "C");
489 std::setlocale (LC_TIME, "C");
490 sys::env::putenv ("LC_NUMERIC", "C");
491 sys::env::putenv ("LC_TIME", "C");
492
493 // Initialize the default floating point unit control state.
495
496 thread::init ();
497
499
500 initialize_xerbla_error_handler ();
501
502 initialize_error_handlers ();
503
504 if (m_app_context)
505 {
508 }
509 else
510 quit_allowed = false;
511
512 if (! m_app_context)
513 m_display_info.initialize ();
514
515 bool line_editing = false;
516
517 if (m_app_context)
518 {
519 // Embedded interpreters don't execute command line options.
520 const cmdline_options& options = m_app_context->options ();
521
522 // Make all command-line arguments available to startup files,
523 // including PKG_ADD files.
524
525 string_vector args = options.all_args ();
526
527 m_app_context->intern_argv (args);
528 intern_nargin (args.numel () - 1);
529
530 bool is_octave_program = m_app_context->is_octave_program ();
531
532 std::list<std::string> command_line_path = options.command_line_path ();
533
534 for (const auto& pth : command_line_path)
535 m_load_path.set_command_line_path (pth);
536
537 std::string exec_path = options.exec_path ();
538 if (! exec_path.empty ())
539 m_environment.exec_path (exec_path);
540
541 std::string image_path = options.image_path ();
542 if (! image_path.empty ())
543 m_environment.image_path (image_path);
544
545 if (! options.no_window_system ())
546 m_display_info.initialize ();
547
548 // Is input coming from a terminal? If so, we are probably
549 // interactive.
550
551 // If stdin is not a tty, then we are reading commands from a
552 // pipe or a redirected file.
553 bool stdin_is_tty = octave_isatty_wrapper (fileno (stdin));
554
555 m_interactive = (! is_octave_program && stdin_is_tty
556 && octave_isatty_wrapper (fileno (stdout)));
557
558 // Don't force interactive if we're already interactive (bug #60696).
559 bool forced_interactive = options.forced_interactive ();
560 if (m_interactive)
561 {
562 m_app_context->forced_interactive (false);
563 forced_interactive = false;
564 }
565
566 // Check if the user forced an interactive session.
567 if (forced_interactive)
568 m_interactive = true;
569
570 line_editing = options.line_editing ();
571 if ((! m_interactive || forced_interactive)
572 && ! options.forced_line_editing ())
573 line_editing = false;
574
575 m_traditional = options.traditional ();
576
577 // FIXME: if possible, perform the following actions directly
578 // instead of using the interpreter-level functions.
579
580 if (options.echo_commands ())
581 m_evaluator.echo
584
585 std::string docstrings_file = options.docstrings_file ();
586 if (! docstrings_file.empty ())
587 Fbuilt_in_docstrings_file (*this, ovl (docstrings_file));
588
589 std::string doc_cache_file = options.doc_cache_file ();
590 if (! doc_cache_file.empty ())
591 Fdoc_cache_file (*this, ovl (doc_cache_file));
592
593 std::string info_file = options.info_file ();
594 if (! info_file.empty ())
595 Finfo_file (*this, ovl (info_file));
596
597 std::string info_program = options.info_program ();
598 if (! info_program.empty ())
599 Finfo_program (*this, ovl (info_program));
600
601 std::string texi_macros_file = options.texi_macros_file ();
602 if (! texi_macros_file.empty ())
603 Ftexi_macros_file (*this, ovl (texi_macros_file));
604 }
605
606 // FIXME: we defer creation of the gh_manager object because it
607 // creates a root_figure object that requires the display_info
608 // object, but that is currently only accessible through the global
609 // interpreter object and that is not available until after the
610 // interpreter::instance pointer is set (above). It would be better
611 // if m_gh_manager could be an object value instead of a pointer and
612 // created as part of the interpreter initialization. To do that,
613 // we should either make the display_info object independent of the
614 // interpreter object (does it really need to cache any
615 // information?) or defer creation of the root_figure object until
616 // it is actually needed.
617 m_gh_manager = new gh_manager (*this);
618
619 m_input_system.initialize (line_editing);
620
621 // These can come after command line args since none of them set any
622 // defaults that might be changed by command line options.
623
624 initialize_version_info ();
625
626 // This should be done before initializing the load path because
627 // some PKG_ADD files might need --traditional behavior.
628
629 if (m_traditional)
630 maximum_braindamage ();
631
633}
634
635OCTAVE_THREAD_LOCAL interpreter *interpreter::s_instance = nullptr;
636
638{
639 if (! m_app_context)
640 shutdown ();
641
642 delete m_gh_manager;
643}
644
645void
650
651// Read the history file unless a command-line option inhibits that.
652
653void
654interpreter::initialize_history (bool read_history_file)
655{
656 if (! m_history_initialized)
657 {
658 // Allow command-line option to override.
659
660 if (m_app_context)
661 {
662 const cmdline_options& options = m_app_context->options ();
663
664 read_history_file = options.read_history_file ();
665
666 if (! read_history_file)
668 }
669
670 m_history_system.initialize (read_history_file);
671
672 if (! m_app_context)
674
675 m_history_initialized = true;
676 }
677}
678
679// Set the initial path to the system default unless command-line
680// option says to leave it empty.
681
682void
684{
685 if (! m_load_path_initialized)
686 {
687 // Allow command-line option to override.
688
689 if (m_app_context)
690 {
691 const cmdline_options& options = m_app_context->options ();
692
693 set_initial_path = options.set_initial_path ();
694 }
695
696 // Temporarily set the execute_pkg_add function to one that
697 // catches exceptions. This is better than wrapping
698 // load_path::initialize in a try-catch block because it will
699 // not stop executing PKG_ADD files at the first exception.
700 // It's also better than changing the default execute_pkg_add
701 // function to use safe_source file because that will normally
702 // be evaluated from the normal interpreter loop where exceptions
703 // are already handled.
704
705 unwind_action restore_add_hook (&load_path::set_add_hook, &m_load_path,
706 m_load_path.get_add_hook ());
707
708 m_load_path.set_add_hook ([this] (const std::string& dir) { this->execute_pkg_add (dir); });
709
710 m_load_path.initialize (set_initial_path);
711
712 m_load_path_initialized = true;
713 }
714}
715
716// This may be called separately from execute
717
718void
720{
721 if (m_initialized)
722 return;
723
724 if (m_app_context)
725 {
726 const cmdline_options& options = m_app_context->options ();
727
728 if (options.experimental_terminal_widget ())
729 {
730 if (! options.gui ())
731 display_startup_message ();
732 }
733 else
734 display_startup_message ();
735 }
736 else
737 display_startup_message ();
738
739 // Wait to read the history file until the interpreter reads input
740 // files and begins evaluating commands.
741
743
744 // Initializing the load path may execute PKG_ADD files, so can't be
745 // done until the interpreter is ready to execute commands.
746
747 // Deferring it to the execute step also allows the path to be
748 // initialized between creating and execute the interpreter, for
749 // example, to set a custom path for an embedded interpreter.
750
752
754
755 can_interrupt = true;
756
758 octave_interrupt_hook = nullptr;
759
761
762 // FIXME: could we eliminate this variable or make it not be global?
763 // Global used to communicate with signal handler.
764 octave_initialized = true;
765
766 m_initialized = true;
767}
768
769// Note: this function is currently only used with the new
770// experimental terminal widget.
771
772void
774{
775 m_evaluator.get_line_and_eval ();
776}
777
778// Note: the following class is currently only used with the new
779// experimental terminal widget.
780
781class cli_input_reader
782{
783public:
784
785 cli_input_reader (interpreter& interp)
786 : m_interpreter (interp), m_thread () { }
787
788 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (cli_input_reader)
789
790 ~cli_input_reader ()
791 {
792 // FIXME: Would it be better to ensure that
793 // interpreter::get_line_and_eval exits and then call
794 // m_thread.join () here?
795
796 m_thread.detach ();
797 }
798
799 void start ()
800 {
801 m_thread = std::thread (&interpreter::get_line_and_eval, &m_interpreter);
802 }
803
804private:
805
806 interpreter& m_interpreter;
807
808 std::thread m_thread;
809};
810
811void
812interpreter::parse_and_execute (const std::string& input,
813 bool& incomplete_parse)
814{
815 m_evaluator.parse_and_execute (input, incomplete_parse);
816}
817
818// FIXME: this function is intended to be executed only once. Should
819// we enforce that restriction?
820
821int
823{
824 int exit_status = 0;
825
826 try
827 {
828 initialize ();
829
830 execute_startup_files ();
831
832 if (m_app_context)
833 {
834 const cmdline_options& options = m_app_context->options ();
835
836 if (m_app_context->have_eval_option_code ())
837 {
838 int status = execute_eval_option_code ();
839
840 if (status )
841 exit_status = status;
842
843 if (! options.persist ())
844 {
845 shutdown ();
846
847 return exit_status;
848 }
849 }
850
851 // If there is an extra argument, see if it names a file to
852 // read. Additional arguments are taken as command line options
853 // for the script.
854
855 if (m_app_context->have_script_file ())
856 {
857 int status = execute_command_line_file ();
858
859 if (status)
860 exit_status = status;
861
862 if (! options.persist ())
863 {
864 shutdown ();
865
866 return exit_status;
867 }
868 }
869
870 if (options.forced_interactive ())
872
873 if (options.server ())
874 exit_status = server_loop ();
875 else if (options.experimental_terminal_widget ())
876 {
877 if (options.gui ())
878 {
879 m_event_manager.start_gui (true);
880
881 exit_status = server_loop ();
882 }
883 else
884 {
885 // Use an object so that the thread started for the
886 // reader will be cleaned up no matter how we exit
887 // this function.
888
889 cli_input_reader reader (*this);
890
891 reader.start ();
892
893 exit_status = server_loop ();
894 }
895 }
896 else
897 exit_status = main_loop ();
898
899 shutdown ();
900 }
901 }
902 catch (const exit_exception& xe)
903 {
904 exit_status = xe.exit_status ();
905
906 shutdown ();
907 }
908
909 return exit_status;
910}
911
912// Call a function with exceptions handled to avoid problems with
913// errors while shutting down.
914
915#define OCTAVE_IGNORE_EXCEPTION(E) \
916 catch (E) \
917 { \
918 recover_from_exception (); \
919 \
920 std::cerr << "error: ignoring " #E " while preparing to exit" \
921 << std::endl; \
922 }
923
924#define OCTAVE_SAFE_CALL(F, ARGS) \
925 do \
926 { \
927 try \
928 { \
929 unwind_action restore_debug_on_error \
930 (&error_system::set_debug_on_error, &m_error_system, \
931 m_error_system.debug_on_error ()); \
932 \
933 unwind_action restore_debug_on_warning \
934 (&error_system::set_debug_on_warning, &m_error_system, \
935 m_error_system.debug_on_warning ()); \
936 \
937 m_error_system.debug_on_error (false); \
938 m_error_system.debug_on_warning (false); \
939 \
940 F ARGS; \
941 } \
942 OCTAVE_IGNORE_EXCEPTION (const exit_exception&) \
943 OCTAVE_IGNORE_EXCEPTION (const interrupt_exception&) \
944 OCTAVE_IGNORE_EXCEPTION (const execution_exception&) \
945 OCTAVE_IGNORE_EXCEPTION (const std::bad_alloc&) \
946 } \
947 while (0)
948
949void
950interpreter::shutdown ()
951{
952 // Attempt to prevent more than one call to shutdown.
953
954 if (! m_initialized)
955 return;
956
957 m_initialized = false;
958
959 OCTAVE_SAFE_CALL (feval, ("close", ovl ("all"), 0));
960
961 // Any atexit functions added after this function call won't be
962 // executed. Each atexit function is executed with
963 // OCTAVE_SAFE_CALL, so we don't need that here.
964
965 execute_atexit_fcns ();
966
967 // Clear all functions and variables while the event manager is
968 // still processing events and notify the event manager. This way,
969 // the workspace model will be cleared before the GUI exits.
970
971 // FIXME: This approach seems a bit fragile since there could be
972 // other places in the GUI that have references to interpreter
973 // objects. How can we reliably ensure that they are all removed
974 // before the interpreter exits? Maybe the best solution is to
975 // always start the GUI from the interpreter and close it when the
976 // interpreter exits? However, the workspace model is owned by the
977 // base_qobject object not the workspace viewer or the main window,
978 // so simply closing the GUI window(s) is not sufficient. See also
979 // bug #61994.
980
981 // Note that we don't force symbols to be cleared, so we will
982 // respect mlock at this point. Later, we'll force all variables
983 // and functions to be cleared.
984
986 OCTAVE_SAFE_CALL (m_event_manager.clear_workspace, ());
987
988 // If we are attached to a GUI, queue and event to close it (only
989 // works with the new terminal widget), process pending events and
990 // disable the link.
991
992 OCTAVE_SAFE_CALL (m_event_manager.close_gui, ());
993 OCTAVE_SAFE_CALL (m_event_manager.process_events, (true));
994 OCTAVE_SAFE_CALL (m_event_manager.disable, ());
995
996 OCTAVE_SAFE_CALL (m_input_system.clear_input_event_hooks, ());
997
998 // We may still have some figures. Close them.
999
1000 OCTAVE_SAFE_CALL (feval, ("close", ovl ("all"), 0));
1001
1002 // What is supposed to happen if a figure has a closerequestfcn or
1003 // deletefcn callback registered that creates other figures or
1004 // variables? What if those variables are classdef objects with
1005 // destructors that can create figures? The possibilities are
1006 // endless. At some point, we have to give up and force execution
1007 // to end.
1008
1009 // Note that we again don't force symbols to be cleared, so we
1010 // continue to respect mlock here. Later, we'll force all variables
1011 // and functions to be cleared.
1012
1014
1015 // Do this explicitly so that destructors for mex file objects
1016 // are called, so that functions registered with mexAtExit are
1017 // called.
1018
1019 OCTAVE_SAFE_CALL (m_symbol_table.clear_mex_functions, ());
1020
1022
1023 OCTAVE_SAFE_CALL (m_history_system.write_timestamp, ());
1024
1027
1028 OCTAVE_SAFE_CALL (m_gtk_manager.unload_all_toolkits, ());
1029
1030 // Now that the graphics toolkits have been unloaded, force all
1031 // symbols to be cleared.
1032
1033 OCTAVE_SAFE_CALL (clear_all, (true));
1034
1035 // FIXME: May still need something like this to ensure that
1036 // destructors for class objects will run properly. Should that be
1037 // done earlier? Before or after atexit functions are executed?
1038 // What will happen if the destructor for an obect attempts to
1039 // display a figure?
1040
1041 OCTAVE_SAFE_CALL (m_symbol_table.cleanup, ());
1042
1044
1046
1047 // Don't call singleton_cleanup_list::cleanup until we have the
1048 // problems with registering/unregistering types worked out. For
1049 // example, uncomment the following line, then use the make_int
1050 // function from the examples directory to create an integer
1051 // object and then exit Octave. Octave should crash with a
1052 // segfault when cleaning up the typinfo singleton. We need some
1053 // way to force new octave_value_X types that are created in
1054 // .oct files to be unregistered when the .oct file shared library
1055 // is unloaded.
1056 //
1057 // OCTAVE_SAFE_CALL (singleton_cleanup_list::cleanup, ());
1058}
1059
1060void
1061interpreter::execute_atexit_fcns ()
1062{
1063 // Prevent atexit functions from adding new functions to the list.
1064 m_executing_atexit = true;
1065
1066 while (! m_atexit_fcns.empty ())
1067 {
1068 std::string fcn = m_atexit_fcns.front ();
1069
1070 m_atexit_fcns.pop_front ();
1071
1073
1075 }
1076}
1077
1078void
1079interpreter::display_startup_message () const
1080{
1081 bool inhibit_startup_message = false;
1082
1083 if (m_app_context)
1084 {
1085 const cmdline_options& options = m_app_context->options ();
1086
1088 }
1089
1090 if (m_interactive && ! inhibit_startup_message)
1091 std::cout << octave_startup_message () << "\n" << std::endl;
1092}
1093
1094// Initialize by reading startup files. Return nonzero if an exception
1095// occurs when reading any of them, but don't exit early because of an
1096// exception.
1097
1098int
1099interpreter::execute_startup_files ()
1100{
1101 bool read_site_files = m_read_site_files;
1102 bool read_user_files = m_read_user_files;
1103 bool trace = m_init_trace;
1104 bool inhibit_startup_message = m_inhibit_startup_message;
1105
1106 if (m_app_context)
1107 {
1108 const cmdline_options& options = m_app_context->options ();
1109
1110 read_site_files = options.read_site_files ();
1111 read_user_files = options.read_user_files ();
1112 trace = options.init_trace ();
1114 }
1115
1116 trace = (trace && ! inhibit_startup_message);
1117
1118 bool require_file = false;
1119
1120 std::string context;
1121
1122 int exit_status = 0;
1123
1124 if (read_site_files)
1125 {
1126 // Execute commands from the site-wide configuration file.
1127 // First from the file $(prefix)/lib/octave/site/m/octaverc
1128 // (if it exists), then from the file
1129 // $(prefix)/share/octave/$(version)/m/octaverc (if it exists).
1130
1131 int status = safe_source_file (config::local_site_defaults_file (),
1132 context, trace, require_file);
1133
1134 if (status)
1135 exit_status = status;
1136
1137 status = safe_source_file (config::site_defaults_file (),
1138 context, trace, require_file);
1139
1140 if (status)
1141 exit_status = status;
1142 }
1143
1144 if (read_user_files)
1145 {
1146 // Try to execute commands from the Matlab compatible startup.m file
1147 // if it exists anywhere in the load path when starting Octave.
1148 std::string ff_startup_m = file_in_path ("startup.m", "");
1149
1150 if (! ff_startup_m.empty ())
1151 {
1152 int parse_status = 0;
1153
1154 try
1155 {
1156 eval_string (std::string ("startup"), false, parse_status, 0);
1157 }
1158 catch (const interrupt_exception&)
1159 {
1161 }
1162 catch (const execution_exception& ee)
1163 {
1164 handle_exception (ee);
1165 }
1166 }
1167
1168 // Try to execute commands from $CONFIG/octave/octaverc, where
1169 // $CONFIG is the platform-dependent location for user local
1170 // configuration files.
1171
1172 std::string user_config_dir = sys::env::get_user_config_directory ();
1173
1174 std::string cfg_dir = user_config_dir + sys::file_ops::dir_sep_str ()
1175 + "octave";
1176
1177 std::string cfg_rc = sys::env::make_absolute ("octaverc", cfg_dir);
1178
1179 if (! cfg_rc.empty ())
1180 {
1181 int status = safe_source_file (cfg_rc, context, trace,
1182 require_file);
1183
1184 if (status)
1185 exit_status = status;
1186 }
1187
1188 // Try to execute commands from $HOME/$OCTAVE_INITFILE and
1189 // $OCTAVE_INITFILE. If $OCTAVE_INITFILE is not set,
1190 // .octaverc is assumed.
1191
1192 bool home_rc_already_executed = false;
1193
1194 std::string initfile = sys::env::getenv ("OCTAVE_INITFILE");
1195
1196 if (initfile.empty ())
1197 initfile = ".octaverc";
1198
1199 std::string home_dir = sys::env::get_home_directory ();
1200
1201 std::string home_rc = sys::env::make_absolute (initfile, home_dir);
1202
1203 std::string local_rc;
1204
1205 if (! home_rc.empty ())
1206 {
1207 int status = safe_source_file (home_rc, context, trace,
1208 require_file);
1209
1210 if (status)
1211 exit_status = status;
1212
1213 // Names alone are not enough.
1214
1215 if (sys::file_exists (home_rc))
1216 {
1217 // We want to check for curr_dir after executing home_rc
1218 // because doing that may change the working directory.
1219
1220 local_rc = sys::env::make_absolute (initfile);
1221
1222 home_rc_already_executed = sys::same_file (home_rc, local_rc);
1223 }
1224 }
1225
1226 if (! home_rc_already_executed)
1227 {
1228 if (local_rc.empty ())
1229 local_rc = sys::env::make_absolute (initfile);
1230
1231 int status = safe_source_file (local_rc, context, trace,
1232 require_file);
1233
1234 if (status)
1235 exit_status = status;
1236 }
1237 }
1238
1239 if (m_interactive && trace)
1240 octave_stdout << std::endl;
1241
1242 return exit_status;
1243}
1244
1245// Execute any code specified with --eval 'CODE'
1246
1247int
1248interpreter::execute_eval_option_code ()
1249{
1250 if (! m_app_context)
1251 return 0;
1252
1253 const cmdline_options& options = m_app_context->options ();
1254
1255 std::string code_to_eval = options.code_to_eval ();
1256
1257 unwind_protect_var<bool> upv (m_interactive, false);
1258
1259 int parse_status = 0;
1260
1261 try
1262 {
1263 eval_string (code_to_eval, false, parse_status, 0);
1264 }
1265 catch (const interrupt_exception&)
1266 {
1268
1269 return 1;
1270 }
1271 catch (const execution_exception& ee)
1272 {
1273 handle_exception (ee);
1274
1275 return 1;
1276 }
1277
1278 return parse_status;
1279}
1280
1281int
1282interpreter::execute_command_line_file ()
1283{
1284 if (! m_app_context)
1285 return 0;
1286
1287 const cmdline_options& options = m_app_context->options ();
1288
1289 string_vector args = options.all_args ();
1290
1291 void (interpreter::*interactive_fptr) (bool) = &interpreter::interactive;
1292 unwind_action restore_interactive (interactive_fptr, this, m_interactive);
1293
1294 unwind_action restore_argv (&application::intern_argv, m_app_context, args);
1295
1296 unwind_action restore_nargin (&interpreter::intern_nargin, this,
1297 args.numel () - 1);
1298
1299 void (application::*program_invocation_name_fptr) (const std::string&)
1300 = &application::program_invocation_name;
1301 unwind_action restore_program_invocation_name
1302 (program_invocation_name_fptr, m_app_context,
1304
1305 void (application::*program_name_fptr) (const std::string&)
1306 = &application::program_name;
1307 unwind_action restore_program_name
1308 (program_name_fptr, m_app_context, application::program_name ());
1309
1310 m_interactive = false;
1311
1312 // If we are running an executable script (#! /bin/octave) then
1313 // we should only see the args passed to the script.
1314
1315 string_vector script_args = options.remaining_args ();
1316
1317 m_app_context->intern_argv (script_args);
1318 intern_nargin (script_args.numel () - 1);
1319
1320 std::string fname = script_args[0];
1321
1322 m_app_context->set_program_names (fname);
1323
1324 std::string context;
1325 bool verbose = false;
1326 bool require_file = true;
1327
1328 return safe_source_file (fname, context, verbose, require_file);
1329}
1330
1331int
1332interpreter::main_loop ()
1333{
1335
1336 return m_evaluator.repl ();
1337}
1338
1339int
1340interpreter::server_loop ()
1341{
1342 return m_evaluator.server_loop ();
1343}
1344
1347{
1348 return m_evaluator;
1349}
1350
1353{
1354 return m_stream_list;
1355}
1356
1359{
1360 return m_url_handle_manager;
1361}
1362
1365{
1366 return m_evaluator.get_top_scope ();
1367}
1368
1371{
1372 return m_evaluator.get_current_scope ();
1373}
1374
1376interpreter::require_current_scope (const std::string& who) const
1377{
1379
1380 if (! scope)
1381 error ("%s: symbol table scope missing", who.c_str ());
1382
1383 return scope;
1384}
1385
1386profiler&
1388{
1389 return m_evaluator.get_profiler ();
1390}
1391
1392int
1393interpreter::chdir (const std::string& dir)
1394{
1395 std::string xdir = sys::file_ops::tilde_expand (dir);
1396
1397 int cd_ok = sys::env::chdir (xdir);
1398
1399 if (! cd_ok)
1400 error ("%s: %s", dir.c_str (), std::strerror (errno));
1401
1402 Vlast_chdir_time.stamp ();
1403
1404 // FIXME: should these actions be handled as a list of functions
1405 // to call so users can add their own chdir handlers?
1406
1407 m_load_path.read_dir_config (".");
1408 m_load_path.update ();
1409 // Updating the last prompt time stamp avoids skipping a fcn-info refresh
1410 // so that functions in the new current directory can shadow functions
1411 // further back in the load path order.
1412 Vlast_prompt_time.stamp ();
1413
1414 m_event_manager.directory_changed (sys::env::get_current_directory ());
1415
1416 return cd_ok;
1417}
1418
1419void
1420interpreter::mlock (bool skip_first) const
1421{
1422 m_evaluator.mlock (skip_first);
1423}
1424
1425void
1426interpreter::munlock (bool skip_first) const
1427{
1428 m_evaluator.munlock (skip_first);
1429}
1430
1431bool
1432interpreter::mislocked (bool skip_first) const
1433{
1434 return m_evaluator.mislocked (skip_first);
1435}
1436
1437void
1438interpreter::munlock (const char *nm)
1439{
1440 if (! nm)
1441 error ("munlock: invalid value for NAME");
1442
1443 munlock (std::string (nm));
1444}
1445
1446void
1447interpreter::munlock (const std::string& nm)
1448{
1449 octave_value val = m_symbol_table.find_function (nm);
1450
1451 if (val.is_defined ())
1452 {
1453 octave_function *fcn = val.function_value ();
1454
1455 if (fcn)
1456 fcn->unlock ();
1457 }
1458}
1459
1460bool
1462{
1463 if (! nm)
1464 error ("mislocked: invalid value for NAME");
1465
1466 return mislocked (std::string (nm));
1467}
1468
1469bool
1470interpreter::mislocked (const std::string& nm)
1471{
1472 bool retval = false;
1473
1474 octave_value val = m_symbol_table.find_function (nm);
1475
1476 if (val.is_defined ())
1477 {
1478 octave_function *fcn = val.function_value ();
1479
1480 if (fcn)
1481 retval = fcn->islocked ();
1482 }
1483
1484 return retval;
1485}
1486
1487std::string
1488interpreter::mfilename (const std::string& opt) const
1489{
1490 return m_evaluator.mfilename (opt);
1491}
1492
1494interpreter::eval_string (const std::string& eval_str,
1495 bool silent, int& parse_status,
1496 int nargout)
1497{
1498 return m_evaluator.eval_string (eval_str, silent, parse_status, nargout);
1499}
1500
1502interpreter::eval_string (const std::string& eval_str,
1503 bool silent, int& parse_status)
1504{
1505 return m_evaluator.eval_string (eval_str, silent, parse_status);
1506}
1507
1510 bool silent, int& parse_status,
1511 int nargout)
1512{
1513 return m_evaluator.eval_string (arg, silent, parse_status, nargout);
1514}
1515
1517interpreter::eval (const std::string& try_code,
1518 int nargout)
1519{
1520 return m_evaluator.eval (try_code, nargout);
1521}
1522
1524interpreter::eval (const std::string& try_code,
1525 const std::string& catch_code,
1526 int nargout)
1527{
1528 return m_evaluator.eval (try_code, catch_code, nargout);
1529}
1530
1532interpreter::evalin (const std::string& context,
1533 const std::string& try_code,
1534 int nargout)
1535{
1536 return m_evaluator.evalin (context, try_code, nargout);
1537}
1538
1540interpreter::evalin (const std::string& context,
1541 const std::string& try_code,
1542 const std::string& catch_code,
1543 int nargout)
1544{
1545 return m_evaluator.evalin (context, try_code, catch_code, nargout);
1546}
1547
1548//! Evaluate an Octave function (built-in or interpreted) and return
1549//! the list of result values.
1550//!
1551//! @param name The name of the function to call.
1552//! @param args The arguments to the function.
1553//! @param nargout The number of output arguments expected.
1554//! @return A list of output values. The length of the list is not
1555//! necessarily the same as @c nargout.
1556
1558interpreter::feval (const char *name,
1559 const octave_value_list& args,
1560 int nargout)
1561{
1562 return feval (std::string (name), args, nargout);
1563}
1564
1566interpreter::feval (const std::string& name,
1567 const octave_value_list& args,
1568 int nargout)
1569{
1570 octave_value fcn = m_symbol_table.find_function (name, args);
1571
1572 if (fcn.is_undefined ())
1573 error ("feval: function '%s' not found", name.c_str ());
1574
1575 octave_function *of = fcn.function_value ();
1576
1577 return of->call (m_evaluator, nargout, args);
1578}
1579
1582 const octave_value_list& args,
1583 int nargout)
1584{
1585 if (fcn)
1586 return fcn->call (m_evaluator, nargout, args);
1587
1588 return octave_value_list ();
1589}
1590
1593 const octave_value_list& args,
1594 int nargout)
1595{
1596 // FIXME: do we really want to silently return an empty ovl if
1597 // the function object is undefined? It's essentially what the
1598 // version above that accepts a pointer to an octave_function
1599 // object does and some code was apparently written to rely on it
1600 // (for example, __ode15__).
1601
1602 if (val.is_undefined ())
1603 return ovl ();
1604
1605 if (val.is_function ())
1606 {
1607 return feval (val.function_value (), args, nargout);
1608 }
1609 else if (val.is_function_handle () || val.is_inline_function ())
1610 {
1611 // This covers function handles, inline functions, and anonymous
1612 // functions.
1613
1614 std::list<octave_value_list> arg_list;
1615 arg_list.push_back (args);
1616
1617 // FIXME: could we make octave_value::subsref a const method?
1618 // It would be difficult because there are instances of
1619 // incrementing the reference count inside subsref methods,
1620 // which means they can't be const with the current way of
1621 // handling reference counting.
1622
1623 octave_value xval = val;
1624 return xval.subsref ("(", arg_list, nargout);
1625 }
1626 else if (val.is_string ())
1627 {
1628 return feval (val.string_value (), args, nargout);
1629 }
1630 else
1631 error ("feval: first argument must be a string, inline function, or a function handle");
1632
1633 return ovl ();
1634}
1635
1636//! Evaluate an Octave function (built-in or interpreted) and return
1637//! the list of result values.
1638//!
1639//! @param args The first element of @c args is the function to call.
1640//! It may be the name of the function as a string, a function
1641//! handle, or an inline function. The remaining arguments are
1642//! passed to the function.
1643//! @param nargout The number of output arguments expected.
1644//! @return A list of output values. The length of the list is not
1645//! necessarily the same as @c nargout.
1646
1649 int nargout)
1650{
1651 if (args.length () == 0)
1652 error ("feval: first argument must be a string, inline function, or a function handle");
1653
1654 octave_value f_arg = args(0);
1655
1656 octave_value_list tmp_args = args.slice (1, args.length () - 1, true);
1657
1658 return feval (f_arg, tmp_args, nargout);
1659}
1660
1661std::string
1662interpreter::inputname (int n, bool ids_only) const
1663{
1664 return m_evaluator.inputname (n, ids_only);
1665}
1666
1668interpreter::make_function_handle (const std::string& name)
1669{
1670 return m_evaluator.make_fcn_handle (name);
1671}
1672
1673void
1674interpreter::install_variable (const std::string& name,
1675 const octave_value& value, bool global)
1676{
1677 m_evaluator.install_variable (name, value, global);
1678}
1679
1681interpreter::global_varval (const std::string& name) const
1682{
1683 return m_evaluator.global_varval (name);
1684}
1685
1686void
1687interpreter::global_assign (const std::string& name,
1688 const octave_value& val)
1689{
1690 m_evaluator.global_assign (name, val);
1691}
1692
1694interpreter::top_level_varval (const std::string& name) const
1695{
1696 return m_evaluator.top_level_varval (name);
1697}
1698
1699void
1700interpreter::top_level_assign (const std::string& name,
1701 const octave_value& val)
1702{
1703 m_evaluator.top_level_assign (name, val);
1704}
1705
1706bool
1707interpreter::is_variable (const std::string& name) const
1708{
1709 return m_evaluator.is_variable (name);
1710}
1711
1712bool
1713interpreter::is_local_variable (const std::string& name) const
1714{
1715 return m_evaluator.is_local_variable (name);
1716}
1717
1719interpreter::varval (const std::string& name) const
1720{
1721 return m_evaluator.varval (name);
1722}
1723
1724void
1725interpreter::assign (const std::string& name,
1726 const octave_value& val)
1727{
1728 m_evaluator.assign (name, val);
1729}
1730
1731void
1732interpreter::assignin (const std::string& context,
1733 const std::string& name,
1734 const octave_value& val)
1735{
1736 m_evaluator.assignin (context, name, val);
1737}
1738
1739void
1740interpreter::source_file (const std::string& file_name,
1741 const std::string& context, bool verbose,
1742 bool require_file)
1743{
1744 m_evaluator.source_file (file_name, context, verbose, require_file);
1745}
1746
1747bool
1749{
1750 return m_evaluator.at_top_level ();
1751}
1752
1753bool
1754interpreter::isglobal (const std::string& name) const
1755{
1756 return m_evaluator.is_global (name);
1757}
1758
1760interpreter::find (const std::string& name)
1761{
1762 return m_evaluator.find (name);
1763}
1764
1765void
1767{
1768 m_evaluator.clear_all (force);
1769}
1770
1771void
1773{
1774 m_evaluator.clear_objects ();
1775}
1776
1777void
1778interpreter::clear_variable (const std::string& name)
1779{
1780 m_evaluator.clear_variable (name);
1781}
1782
1783void
1784interpreter::clear_variable_pattern (const std::string& pattern)
1785{
1786 m_evaluator.clear_variable_pattern (pattern);
1787}
1788
1789void
1790interpreter::clear_variable_regexp (const std::string& pattern)
1791{
1792 m_evaluator.clear_variable_regexp (pattern);
1793}
1794
1795void
1797{
1798 m_evaluator.clear_variables ();
1799}
1800
1801void
1802interpreter::clear_global_variable (const std::string& name)
1803{
1804 m_evaluator.clear_global_variable (name);
1805}
1806
1807void
1809{
1810 m_evaluator.clear_global_variable_pattern (pattern);
1811}
1812
1813void
1815{
1816 m_evaluator.clear_global_variable_regexp (pattern);
1817}
1818
1819void
1824
1825void
1827{
1828 m_symbol_table.clear_functions (force);
1829}
1830
1831void
1832interpreter::clear_function (const std::string& name)
1833{
1834 m_symbol_table.clear_function (name);
1835}
1836
1837void
1838interpreter::clear_symbol (const std::string& name)
1839{
1840 m_evaluator.clear_symbol (name);
1841}
1842
1843void
1845{
1846 m_symbol_table.clear_function_pattern (pat);
1847}
1848
1849void
1851{
1852 m_symbol_table.clear_function_regexp (pat);
1853}
1854
1855void
1857{
1858 return m_evaluator.clear_symbol_pattern (pat);
1859}
1860
1861void
1862interpreter::clear_symbol_regexp (const std::string& pat)
1863{
1864 return m_evaluator.clear_symbol_regexp (pat);
1865}
1866
1867std::list<std::string>
1869{
1870 return m_evaluator.global_variable_names ();
1871}
1872
1873std::list<std::string>
1875{
1876 return m_evaluator.top_level_variable_names ();
1877}
1878
1879std::list<std::string>
1881{
1882 return m_evaluator.variable_names ();
1883}
1884
1885std::list<std::string>
1887{
1888 return m_symbol_table.user_function_names ();
1889}
1890
1891std::list<std::string>
1893{
1894 return m_evaluator.autoloaded_functions ();
1895}
1896
1897// May be used to send an interrupt signal to the the interpreter from
1898// another thread (for example, the GUI).
1899
1900void
1902{
1903 static int sigint = 0;
1904 static bool first = true;
1905
1906 if (first)
1907 {
1908 octave_get_sig_number ("SIGINT", &sigint);
1909 first = false;
1910 }
1911
1912 // Send SIGINT to Octave and (optionally) all other processes in its
1913 // process group. The signal handler for SIGINT will set a global
1914 // variable indicating an interrupt has happened. That variable is
1915 // checked in many places in the Octave interpreter and eventually
1916 // results in an interrupt_exception being thrown. Finally, that
1917 // exception is caught and returns control to one of the
1918 // read-eval-print loops or to the server loop. We use a signal
1919 // instead of just setting the global variables here so that we will
1920 // probably send interrupt signals to any subprocesses as well as
1921 // interrupt execution of the interpreter.
1922
1923 pid_t pid
1924 = m_interrupt_all_in_process_group ? 0 : octave_getpid_wrapper ();
1925
1926 octave_kill_wrapper (pid, sigint);
1927}
1928
1929void
1931{
1932 // FIXME: To be reliable, these tree_evaluator functions must be
1933 // made thread safe.
1934
1935 m_evaluator.break_on_next_statement (true);
1936 m_evaluator.reset_debug_state ();
1937}
1938
1939void
1941{
1942 // FIXME: To be reliable, these tree_evaluator functions must be
1943 // made thread safe.
1944
1945 if (m_evaluator.in_debug_repl ())
1946 m_evaluator.dbquit (true);
1947 else
1948 interrupt ();
1949}
1950
1951void
1953{
1954 // FIXME: To be reliable, these tree_evaluator functions must be
1955 // made thread safe.
1956
1957 // FIXME: Should there be any feeback about not doing anything if
1958 // not in debug mode?
1959
1960 if (m_evaluator.in_debug_repl ())
1961 m_evaluator.dbcont ();
1962}
1963
1965interpreter::PS1 (const octave_value_list& args, int nargout)
1966{
1967 return m_input_system.PS1 (args, nargout);
1968}
1969
1970std::string
1972{
1973 return m_input_system.PS1 ();
1974}
1975
1976std::string
1977interpreter::PS1 (const std::string& s)
1978{
1979 return m_input_system.PS1 (s);
1980}
1981
1982void
1983interpreter::set_PS1 (const std::string& s)
1984{
1985 m_input_system.set_PS1 (s);
1986}
1987
1989interpreter::PS2 (const octave_value_list& args, int nargout)
1990{
1991 return m_input_system.PS2 (args, nargout);
1992}
1993
1994std::string
1996{
1997 return m_input_system.PS2 ();
1998}
1999
2000std::string
2001interpreter::PS2 (const std::string& s)
2002{
2003 return m_input_system.PS2 (s);
2004}
2005
2006void
2007interpreter::set_PS2 (const std::string& s)
2008{
2009 m_input_system.set_PS2 (s);
2010}
2011
2013interpreter::PS4 (const octave_value_list& args, int nargout)
2014{
2015 return m_evaluator.PS4 (args, nargout);
2016}
2017
2018std::string
2020{
2021 return m_evaluator.PS4 ();
2022}
2023
2024std::string
2025interpreter::PS4 (const std::string& s)
2026{
2027 return m_evaluator.PS4 (s);
2028}
2029
2030void
2031interpreter::set_PS4 (const std::string& s)
2032{
2033 m_evaluator.set_PS4 (s);
2034}
2035
2036// Provided for convenience. Will be removed once we eliminate the
2037// old terminal widget.
2038bool
2040{
2041 if (! m_app_context)
2042 return false;
2043
2044 // Embedded interpreters don't execute command line options.
2045 const cmdline_options& options = m_app_context->options ();
2046
2047 return options.experimental_terminal_widget ();
2048}
2049
2050void
2052{
2053 m_evaluator.add_debug_watch_expression (expr);
2054}
2055
2056void
2058{
2059 m_evaluator.remove_debug_watch_expression (expr);
2060}
2061
2062void
2067
2068std::set<std::string>
2070{
2071 return m_evaluator.debug_watch_expressions ();
2072}
2073
2074void
2076{
2077 m_error_system.save_exception (ee);
2078
2079 // FIXME: use a separate stream instead of std::cerr directly so that
2080 // error messages can be redirected more easily? Pass the message
2081 // to an event manager function?
2082 m_error_system.display_exception (ee);
2083
2085}
2086
2087void
2099
2100void
2101interpreter::mark_for_deletion (const std::string& file)
2102{
2103 m_tmp_files.insert (file);
2104}
2105
2106void
2108{
2109 m_tmp_files.cleanup ();
2110}
2111
2112void
2113interpreter::quit (int exit_status, bool force, bool confirm)
2114{
2115 if (! force)
2116 {
2117 try
2118 {
2119 bool cancel = false;
2120
2121 if (symbol_exist ("finish.m", "file"))
2122 {
2123 unwind_protect_var<bool> upv1 (m_executing_finish_script, true);
2124 unwind_protect_var<bool> upv2 (m_cancel_quit);
2125
2126 evalin ("base", "finish", 0);
2127
2128 cancel = m_cancel_quit;
2129 }
2130
2131 if (cancel)
2132 return;
2133
2134 // Check for confirmation.
2135
2136 if (confirm && ! m_event_manager.confirm_shutdown ())
2137 return;
2138 }
2139 catch (const execution_exception&)
2140 {
2141 // Catch execution_exceptions so we don't throw an
2142 // exit_exception if there is an in finish.m. But throw it
2143 // again so that will be handled as any other
2144 // execution_exception by the evaluator. This way, errors
2145 // will be ignored properly and we won't exit if quit is
2146 // called recursively from finish.m.
2147
2148 throw;
2149 }
2150 }
2151
2152 throw exit_exception (exit_status);
2153}
2154
2155void
2156interpreter::add_atexit_fcn (const std::string& fname)
2157{
2158 if (m_executing_atexit)
2159 return;
2160
2161 m_atexit_fcns.push_front (fname);
2162}
2163
2164bool
2165interpreter::remove_atexit_fcn (const std::string& fname)
2166{
2167 bool found = false;
2168
2169 for (auto it = m_atexit_fcns.begin ();
2170 it != m_atexit_fcns.end (); it++)
2171 {
2172 if (*it == fname)
2173 {
2174 m_atexit_fcns.erase (it);
2175 found = true;
2176 break;
2177 }
2178 }
2179
2180 return found;
2181}
2182
2183// What internal options get configured by --traditional.
2184
2185void
2186interpreter::maximum_braindamage ()
2187{
2188 PS1 (">> ");
2189 PS2 ("");
2190 PS4 ("");
2191
2192 m_load_save_system.crash_dumps_octave_core (false);
2193 m_load_save_system.save_default_options ("-mat-binary");
2194
2195 m_history_system.timestamp_format_string ("%%-- %D %I:%M %p --%%");
2196
2197 m_error_system.beep_on_error (true);
2198
2199 Fconfirm_recursive_rmdir (ovl (false));
2200 Foptimize_diagonal_matrix (ovl (false));
2201 Foptimize_permutation_matrix (ovl (false));
2202 Foptimize_range (ovl (false));
2203 Ffixed_point_format (ovl (true));
2204 Fprint_empty_dimensions (ovl (false));
2207
2208 m_error_system.disable_warning ("Octave:abbreviated-property-match");
2209 m_error_system.disable_warning ("Octave:colon-nonscalar-argument");
2210 m_error_system.disable_warning ("Octave:data-file-in-path");
2211 m_error_system.disable_warning ("Octave:empty-index");
2212 m_error_system.disable_warning ("Octave:function-name-clash");
2213 m_error_system.disable_warning ("Octave:possible-matlab-short-circuit-operator");
2214}
2215
2216void
2217interpreter::execute_pkg_add (const std::string& dir)
2218{
2219 try
2220 {
2221 m_load_path.execute_pkg_add (dir);
2222 }
2223 catch (const interrupt_exception&)
2224 {
2226 }
2227 catch (const execution_exception& ee)
2228 {
2229 handle_exception (ee);
2230 }
2231}
2232
2233// Execute commands from a file and catch potential exceptions in a consistent
2234// way. This function should be called anywhere we might parse and execute
2235// commands from a file before we have entered the main loop in
2236// toplev.cc.
2237
2238int
2239interpreter::safe_source_file (const std::string& file_name,
2240 const std::string& context,
2241 bool verbose, bool require_file)
2242{
2243 try
2244 {
2245 source_file (file_name, context, verbose, require_file);
2246 }
2247 catch (const interrupt_exception&)
2248 {
2250
2251 return 1;
2252 }
2253 catch (const execution_exception& ee)
2254 {
2255 handle_exception (ee);
2256
2257 return 1;
2258 }
2259
2260 return 0;
2261}
2262
2263OCTAVE_END_NAMESPACE(octave)
Definition Cell.h:41
void set_program_names(const std::string &pname)
Definition octave.cc:308
void forced_interactive(bool arg)
Definition octave.h:310
void intern_argv(const string_vector &args)
Definition octave.cc:318
bool have_eval_option_code() const
Definition octave.h:275
cmdline_options options() const
Definition octave.h:273
static std::string program_name()
Definition octave.h:323
bool is_octave_program() const
Definition octave.h:279
bool have_script_file() const
Definition octave.h:277
static std::string program_invocation_name()
Definition octave.h:318
bool line_editing() const
Definition octave.h:65
bool forced_interactive() const
Definition octave.h:60
bool experimental_terminal_widget() const
Definition octave.h:58
std::string texi_macros_file() const
Definition octave.h:90
bool inhibit_startup_message() const
Definition octave.h:63
std::string doc_cache_file() const
Definition octave.h:85
bool init_trace() const
Definition octave.h:80
std::string image_path() const
Definition octave.h:87
bool read_site_files() const
Definition octave.h:70
string_vector remaining_args() const
Definition octave.h:92
bool persist() const
Definition octave.h:68
bool read_user_files() const
Definition octave.h:71
std::string info_program() const
Definition octave.h:89
bool server() const
Definition octave.h:74
bool read_history_file() const
Definition octave.h:69
std::string exec_path() const
Definition octave.h:86
bool no_window_system() const
Definition octave.h:67
std::string code_to_eval() const
Definition octave.h:81
string_vector all_args() const
Definition octave.h:91
std::string info_file() const
Definition octave.h:88
std::string docstrings_file() const
Definition octave.h:84
bool echo_commands() const
Definition octave.h:56
bool gui() const
Definition octave.h:62
bool traditional() const
Definition octave.h:76
bool set_initial_path() const
Definition octave.h:75
bool forced_line_editing() const
Definition octave.h:61
std::list< std::string > command_line_path() const
Definition octave.h:82
static void blink_matching_paren(bool flag)
Definition cmd-edit.cc:1306
static void restore_terminal_state()
Definition cmd-edit.cc:1299
static void add_event_hook(event_hook_fcn f)
Definition cmd-edit.cc:1556
static bool ignoring_entries()
Definition cmd-hist.cc:610
static void clean_up_and_save(const std::string &="", int=-1)
Definition cmd-hist.cc:768
static void ignore_entries(bool=true)
Definition cmd-hist.cc:603
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:90
void initialize()
Definition display.cc:42
octave_value image_path(const octave_value_list &args, int nargout)
octave_value exec_path(const octave_value_list &args, int nargout)
octave_value beep_on_error(const octave_value_list &args, int nargout)
Definition error.cc:307
void disable_warning(const std::string &id)
Definition error.cc:856
void save_exception(const execution_exception &ee)
Definition error.cc:927
void display_exception(const execution_exception &ee) const
Definition error.cc:939
bool confirm_shutdown()
void process_events(bool disable=false)
void interpreter_interrupted()
void directory_changed(const std::string &dir)
void start_gui(bool gui_app=false)
void clear_workspace()
void unload_all_toolkits()
void write_timestamp()
Definition oct-hist.cc:281
octave_value timestamp_format_string(const octave_value_list &args, int nargout)
Definition oct-hist.cc:307
void initialize(bool read_history_file=false)
Definition oct-hist.cc:269
void initialize(bool line_editing)
Definition input.cc:412
void clear_input_event_hooks()
void set_PS2(const std::string &s)
Definition input.h:91
void set_PS1(const std::string &s)
Definition input.h:78
octave_value PS2(const octave_value_list &args, int nargout)
octave_value PS1(const octave_value_list &args, int nargout)
octave_value global_varval(const std::string &name) const
octave_value varval(const std::string &name) const
void clear_variable(const std::string &name)
octave_value make_function_handle(const std::string &name)
void assignin(const std::string &context, const std::string &varname, const octave_value &val=octave_value())
bool isglobal(const std::string &name) const
void quit(int exit_status, bool force=false, bool confirm=true)
void clear_global_variables()
std::list< std::string > autoloaded_functions() const
void global_assign(const std::string &name, const octave_value &val=octave_value())
void install_variable(const std::string &name, const octave_value &value, bool global)
void verbose(bool flag)
void add_debug_watch_expression(const std::string &expr)
bool at_top_level() const
void read_site_files(bool flag)
void add_atexit_fcn(const std::string &fname)
bool remove_atexit_fcn(const std::string &fname)
void initialize()
void clear_objects()
octave_value find(const std::string &name)
void mlock(bool skip_first=false) const
profiler & get_profiler()
void source_file(const std::string &file_name, const std::string &context="", bool verbose=false, bool require_file=true)
std::list< std::string > variable_names()
void top_level_assign(const std::string &name, const octave_value &val=octave_value())
std::set< std::string > debug_watch_expressions() const
octave_value_list eval(const std::string &try_code, int nargout)
std::string PS2() const
octave_value_list eval_string(const std::string &eval_str, bool silent, int &parse_status, int nargout)
std::string PS1() const
void clear_symbol_regexp(const std::string &pat)
void handle_exception(const execution_exception &ee)
bool experimental_terminal_widget() const
symbol_scope get_current_scope() const
void clear_symbol_pattern(const std::string &pat)
void clear_global_variable_regexp(const std::string &pattern)
void clear_global_variable(const std::string &name)
void set_PS1(const std::string &s)
int chdir(const std::string &dir)
std::list< std::string > user_function_names()
void clear_global_variable_pattern(const std::string &pattern)
void clear_function_regexp(const std::string &pat)
octave_value top_level_varval(const std::string &name) const
symbol_scope get_top_scope() const
void intern_nargin(octave_idx_type nargs)
void clear_variables()
void parse_and_execute(const std::string &input, bool &incomplete_parse)
bool is_variable(const std::string &name) const
interpreter(application *app_context=nullptr)
void clear_variable_regexp(const std::string &pattern)
bool interactive() const
std::string PS4() const
bool mislocked(bool skip_first=false) const
tree_evaluator & get_evaluator()
void assign(const std::string &name, const octave_value &val=octave_value())
void initialize_history(bool read_history_file=false)
void clear_symbol(const std::string &name)
std::list< std::string > global_variable_names()
octave_value_list evalin(const std::string &context, const std::string &try_code, int nargout)
void read_user_files(bool flag)
void cleanup_tmp_files()
std::string mfilename(const std::string &opt="") const
void initialize_load_path(bool set_initial_path=true)
void clear_debug_watch_expressions()
void inhibit_startup_message(bool flag)
void clear_variable_pattern(const std::string &pattern)
void clear_function_pattern(const std::string &pat)
bool is_local_variable(const std::string &name) const
std::list< std::string > top_level_variable_names()
void munlock(bool skip_first=false) const
octave_value_list feval(const char *name, const octave_value_list &args=octave_value_list(), int nargout=0)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
void get_line_and_eval()
url_handle_manager & get_url_handle_manager()
symbol_scope require_current_scope(const std::string &who) const
std::string inputname(int n, bool ids_only=true) const
void clear_function(const std::string &name)
void remove_debug_watch_expression(const std::string &expr)
void recover_from_exception()
void clear_all(bool force=false)
void mark_for_deletion(const std::string &file)
void set_PS2(const std::string &s)
stream_list & get_stream_list()
void set_PS4(const std::string &s)
void clear_functions(bool force=false)
void set_add_hook(const std::function< void(const std::string &)> &f)
Definition load-path.h:180
void initialize(bool set_initial_path=false)
Definition load-path.cc:260
void read_dir_config(const std::string &dir) const
std::function< void(const std::string &)> get_add_hook()
Definition load-path.h:170
void execute_pkg_add(const std::string &dir)
Definition load-path.cc:968
void update()
Definition load-path.cc:425
void set_command_line_path(const std::string &p)
Definition load-path.h:195
octave_value save_default_options(const octave_value_list &args, int nargout)
Definition load-save.cc:300
octave_value crash_dumps_octave_core(const octave_value_list &args, int nargout)
Definition load-save.cc:276
bool islocked() const
Definition ov-fcn.h:188
void unlock()
Definition ov-fcn.h:182
virtual octave_value_list call(octave::tree_evaluator &tw, int nargout=0, const octave_value_list &args=octave_value_list())
Definition ov-fcn.cc:67
void resize(const dim_vector &dv, bool fill=false)
Definition oct-map.cc:574
octave_idx_type nfields() const
Definition oct-map.h:323
octave_idx_type length() const
Definition oct-map.h:369
octave_idx_type numel() const
Definition oct-map.h:368
void assign(const std::string &k, const Cell &val)
Definition oct-map.h:344
octave_value_list slice(octave_idx_type offset, octave_idx_type len, bool tags=false) const
Definition ovl.h:129
octave_idx_type length() const
Definition ovl.h:111
bool is_function_handle() const
Definition ov.h:768
bool is_undefined() const
Definition ov.h:595
bool is_inline_function() const
Definition ov.h:774
octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition ov.h:476
octave_function * function_value(bool silent=false) const
bool is_string() const
Definition ov.h:637
bool is_defined() const
Definition ov.h:592
bool is_function() const
Definition ov.h:777
std::string string_value(bool force=false) const
Definition ov.h:983
octave_idx_type length() const
octave_idx_type numel() const
Definition str-vec.h:98
void clear_function(const std::string &name)
Definition symtab.cc:446
void clear_function_pattern(const std::string &pat)
Definition symtab.cc:452
void clear_functions(bool force=false)
Definition symtab.cc:437
octave_value find_function(const std::string &name, const symbol_scope &search_scope=symbol_scope::invalid())
Definition symtab.cc:254
void clear_mex_functions()
Definition symtab.cc:515
void cleanup()
Definition symtab.cc:722
std::list< std::string > user_function_names()
Definition symtab.cc:603
void clear_function_regexp(const std::string &pat)
Definition symtab.cc:468
void insert(const std::string &file)
static void init()
octave_value_list eval_string(const std::string &eval_str, bool silent, int &parse_status, int nargout)
Definition pt-eval.cc:1028
bool is_global(const std::string &name) const
Definition pt-eval.cc:1948
bool mislocked(bool skip_first=false) const
Definition pt-eval.cc:2806
void clear_all(bool force=false)
Definition pt-eval.cc:2923
void reset_debug_state()
Definition pt-eval.cc:1384
void source_file(const std::string &file_name, const std::string &context="", bool verbose=false, bool require_file=true)
Definition pt-eval.cc:2063
symbol_scope get_current_scope() const
Definition pt-eval.cc:2766
octave_value echo(const octave_value_list &args, int nargout)
Definition pt-eval.cc:5017
void set_PS4(const std::string &s)
Definition pt-eval.h:715
void clear_global_variables()
Definition pt-eval.cc:2917
void clear_global_variable(const std::string &name)
Definition pt-eval.cc:2899
bool break_on_next_statement() const
Definition pt-eval.h:810
std::string inputname(int n, bool ids_only=true) const
Definition pt-eval.cc:1468
void munlock(bool skip_first=false) const
Definition pt-eval.cc:2789
bool at_top_level() const
Definition pt-eval.cc:544
octave_value find(const std::string &name)
Definition pt-eval.cc:2829
std::list< std::string > variable_names() const
Definition pt-eval.cc:2984
bool is_local_variable(const std::string &name) const
Definition pt-eval.cc:1890
bool in_debug_repl() const
Definition pt-eval.cc:5145
profiler & get_profiler()
Definition pt-eval.h:426
symbol_scope get_top_scope() const
Definition pt-eval.cc:2760
void clear_symbol_pattern(const std::string &pattern)
Definition pt-eval.cc:2948
void clear_symbol(const std::string &name)
Definition pt-eval.cc:2936
void remove_debug_watch_expression(const std::string &expr)
Definition pt-eval.h:685
void dbquit(bool all=false)
Definition pt-eval.cc:5159
void clear_objects()
Definition pt-eval.cc:2854
int server_loop()
Definition pt-eval.cc:886
void clear_variable(const std::string &name)
Definition pt-eval.cc:2863
bool is_variable(const std::string &name) const
Definition pt-eval.cc:1881
void add_debug_watch_expression(const std::string &expr)
Definition pt-eval.h:678
std::list< std::string > global_variable_names() const
Definition pt-eval.cc:2972
void clear_global_variable_pattern(const std::string &pattern)
Definition pt-eval.cc:2905
void assign(const std::string &name, const octave_value &val=octave_value())
Definition pt-eval.cc:2018
void assignin(const std::string &context, const std::string &name, const octave_value &val=octave_value())
Definition pt-eval.cc:2027
octave_value top_level_varval(const std::string &name) const
Definition pt-eval.cc:2005
void clear_symbol_regexp(const std::string &pattern)
Definition pt-eval.cc:2960
void get_line_and_eval()
Definition pt-eval.cc:651
std::list< std::string > autoloaded_functions() const
Definition pt-eval.cc:4757
void eval(std::shared_ptr< tree_statement_list > &stmt_list, bool interactive)
Definition pt-eval.cc:995
octave_value_list evalin(const std::string &context, const std::string &try_code, int nargout)
Definition pt-eval.cc:1182
octave_value global_varval(const std::string &name) const
Definition pt-eval.cc:1986
void top_level_assign(const std::string &name, const octave_value &val=octave_value())
Definition pt-eval.cc:2011
void install_variable(const std::string &name, const octave_value &value, bool global)
Definition pt-eval.cc:1975
void set_auto_fcn_var(stack_frame::auto_var_type avt, const octave_value &val=octave_value())
Definition pt-eval.cc:2222
std::set< std::string > debug_watch_expressions() const
Definition pt-eval.h:699
void clear_global_variable_regexp(const std::string &pattern)
Definition pt-eval.cc:2911
void parse_and_execute(const std::string &input, bool &incomplete_parse)
Definition pt-eval.cc:586
void clear_debug_watch_expressions()
Definition pt-eval.h:692
std::list< std::string > top_level_variable_names() const
Definition pt-eval.cc:2978
void global_assign(const std::string &name, const octave_value &val=octave_value())
Definition pt-eval.cc:1998
octave_value make_fcn_handle(const std::string &nm)
Definition pt-eval.cc:1624
void mlock(bool skip_first=false) const
Definition pt-eval.cc:2772
octave_value varval(const symbol_record &sym) const
Definition pt-eval.cc:1957
octave_value PS4(const octave_value_list &args, int nargout)
Definition pt-eval.cc:5263
std::string mfilename(const std::string &opt="") const
Definition pt-eval.cc:550
void clear_variable_regexp(const std::string &pattern)
Definition pt-eval.cc:2881
void clear_variable_pattern(const std::string &pattern)
Definition pt-eval.cc:2872
void clear_variables()
Definition pt-eval.cc:2890
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void print_usage()
Definition defun-int.h:72
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition defun.h:111
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition defun.h:56
#define DEFALIAS(alias, name)
Macro to define an alias for another existing function name.
Definition defun.h:160
octave_value_list Fconfirm_recursive_rmdir(const octave_value_list &args, int nargout)
Definition dirfns.cc:779
void warning(const char *fmt,...)
Definition error.cc:1078
void warning_with_id(const char *id, const char *fmt,...)
Definition error.cc:1093
void verror_with_id_cfn(const char *id, const char *fmt, va_list args)
Definition error.cc:1057
void verror_with_cfn(const char *fmt, va_list args)
Definition error.cc:1027
void error(const char *fmt,...)
Definition error.cc:1003
void octave_set_default_fpucw(void)
octave::sys::time Vlast_prompt_time
Definition input.cc:82
#define OCTAVE_SAFE_CALL(F, ARGS)
octave_value_list F__version_info__(const octave_value_list &args, int)
bool octave_interpreter_ready
sys::time Vlast_chdir_time
std::atomic< bool > octave_initialized
bool quit_allowed
bool octave_interpreter_ready
sys::time Vlast_chdir_time
std::atomic< bool > octave_initialized
bool quit_allowed
void set_liboctave_error_handler(OCTAVE_NORETURN liboctave_error_handler f)
Definition lo-error.c:67
void set_liboctave_warning_handler(liboctave_warning_handler f)
Definition lo-error.c:86
void set_liboctave_error_with_id_handler(OCTAVE_NORETURN liboctave_error_with_id_handler f)
Definition lo-error.c:76
void set_liboctave_warning_with_id_handler(liboctave_warning_with_id_handler f)
Definition lo-error.c:95
void octave_ieee_init()
Definition lo-ieee.cc:124
#define OCTAVE_VERSION
Definition main.in.cc:63
int release_unreferenced_dynamic_libraries()
Definition oct-shlib.cc:72
T::size_type numel(const T &str)
Definition oct-string.cc:74
octave_value_list Fprint_struct_array_contents(const octave_value_list &args, int nargout)
octave_value_list Fstruct_levels_to_print(const octave_value_list &args, int nargout)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition ovl.h:217
void flush_stdout()
Definition pager.cc:268
#define octave_stdout
Definition pager.h:301
octave_value_list Ffixed_point_format(const octave_value_list &args, int nargout)
octave_value_list Fprint_empty_dimensions(const octave_value_list &args, int nargout)
std::atomic< bool > octave_signal_caught
Definition quit.cc:41
std::atomic< sig_atomic_t > octave_interrupt_state
Definition quit.cc:39
void(* octave_interrupt_hook)()
Definition quit.cc:44
void(* octave_signal_hook)()
Definition quit.cc:43
void respond_to_pending_signals()
std::atomic< bool > can_interrupt
interrupt_handler catch_interrupts()
void install_signal_handlers()
void octave_save_signal_mask(void)
void octave_unblock_signal_by_name(const char *signame)
bool octave_get_sig_number(const char *signame, int *signum)
int octave_kill_wrapper(pid_t pid, int signum)
void octave_restore_signal_mask(void)
void sysdep_cleanup()
Definition sysdep.cc:456
pid_t octave_getpid_wrapper(void)
int octave_unlink_wrapper(const char *nm)
int octave_isatty_wrapper(int fd)
std::string file_in_path(const std::string &name, const std::string &suffix)
Definition utils.cc:698
int symbol_exist(const std::string &name, const std::string &type)
Definition variables.cc:327
std::string octave_startup_message(bool html)
Definition version.cc:118
F77_RET_T F77_FUNC(xerbla, XERBLA)(F77_CONST_CHAR_ARG_DEF(s_arg
void octave_set_xerbla_handler(xerbla_handler_fptr fcn)
Definition xerbla.cc:52