GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
interpreter.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2002-2024 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 (octave_interpreter_h)
27 #define octave_interpreter_h 1
28 
29 #include "octave-config.h"
30 
31 #include <atomic>
32 #include <map>
33 #include <set>
34 #include <stack>
35 #include <string>
36 
37 #include "child-list.h"
38 #include "oct-time.h"
39 #include "quit.h"
40 #include "str-vec.h"
41 
42 #include "cdef-manager.h"
43 #include "display.h"
44 #include "dynamic-ld.h"
45 #include "environment.h"
46 #include "error.h"
47 #include "event-manager.h"
48 #include "gh-manager.h"
49 #include "graphics.h"
50 #include "gtk-manager.h"
51 #include "help.h"
52 #include "input.h"
53 #include "load-path.h"
54 #include "load-save.h"
55 #include "oct-hist.h"
56 #include "oct-stream.h"
57 #include "ov-typeinfo.h"
58 #include "pager.h"
59 #include "pt-eval.h"
60 #include "settings.h"
61 #include "symtab.h"
62 #include "url-handle-manager.h"
63 
64 extern OCTINTERP_API bool quit_allowed;
65 
66 // TRUE means we are ready to interpret commands, but not everything
67 // is ready for interactive use.
68 extern OCTINTERP_API bool octave_interpreter_ready;
69 
70 // TRUE means we've processed all the init code and we are good to go.
71 extern OCTINTERP_API std::atomic<bool> octave_initialized;
72 
73 #include "oct-time.h"
74 
76 
77 class profiler;
78 class child_list;
79 class push_parser;
80 
81 // The time we last time we changed directories.
82 extern sys::time Vlast_chdir_time;
83 
84 // The application object contains a pointer to the current
85 // interpreter and the interpreter contains a pointer back to the
86 // application context so we need a forward declaration for one (or
87 // both) of them...
88 
89 class application;
90 
92 {
93 public:
94 
95  temporary_file_list () : m_files () { }
96 
97  OCTAVE_DISABLE_COPY_MOVE (temporary_file_list)
98 
100 
101  void insert (const std::string& file);
102 
103  void cleanup ();
104 
105 private:
106 
107  // List of temporary files to delete when we exit.
108  std::set<std::string> m_files;
109 
110 };
111 
112 class OCTINTERP_API interpreter
113 {
114 public:
115 
116  // Create an interpreter object and perform basic initialization.
117 
118  interpreter (application *app_context = nullptr);
119 
120  OCTAVE_DISABLE_COPY_MOVE (interpreter)
121 
122  // Clean up the interpreter object.
123 
124  ~interpreter ();
125 
126  void intern_nargin (octave_idx_type nargs);
127 
128  // If creating an embedded interpreter, you may inhibit reading
129  // the command history file by calling initialize_history with
130  // read_history_file = false prior to calling initialize.
131 
132  void initialize_history (bool read_history_file = false);
133 
134  // If creating an embedded interpreter, you may inhibit setting
135  // the default compiled-in path by calling initialize_load_path
136  // with set_initial_path = false prior calling initialize. After
137  // that, you can add directories to the load path to set up a
138  // custom path.
139 
140  void initialize_load_path (bool set_initial_path = true);
141 
142  // Load command line history, set the load path.
143 
144  void initialize ();
145 
146  // Note: GET_LINE_AND_EVAL is only used by new experimental terminal
147  // widget.
148 
149  void get_line_and_eval ();
150 
151  // Parse a line of input. If input ends at a complete statement
152  // boundary, execute the resulting parse tree. Useful to handle
153  // parsing user input when running in server mode.
154 
155  void parse_and_execute (const std::string& input, bool& incomplete_parse);
156 
157  // Initialize the interpreter (if not already done by an explicit
158  // call to initialize), execute startup files, --eval option code,
159  // script files, and/or interactive commands.
160 
161  int execute ();
162 
163  bool server_mode () const { return m_evaluator.server_mode (); }
164 
165  bool interactive () const
166  {
167  return m_interactive;
168  }
169 
170  void interactive (bool arg)
171  {
172  m_interactive = arg;
173  }
174 
175  void read_site_files (bool flag)
176  {
177  m_read_site_files = flag;
178  }
179 
180  void read_init_files (bool flag)
181  {
182  m_read_init_files = flag;
183  }
184 
185  void verbose (bool flag)
186  {
187  m_verbose = flag;
188  }
189 
190  void traditional (bool flag)
191  {
192  m_traditional = flag;
193  }
194 
195  bool traditional () const
196  {
197  return m_traditional;
198  }
199 
200  void inhibit_startup_message (bool flag)
201  {
202  m_inhibit_startup_message = flag;
203  }
204 
205  bool in_top_level_repl () const
206  {
207  return m_evaluator.in_top_level_repl ();
208  }
209 
210  bool is_initialized () const
211  {
212  return m_initialized;
213  }
214 
215  OCTAVE_DEPRECATED (9, "use octave::is_initialized instead")
216  bool initialized () const
217  {
218  return is_initialized ();
219  }
220 
222  {
223  m_interrupt_all_in_process_group = b;
224  }
225 
227  {
228  return m_interrupt_all_in_process_group;
229  }
230 
232  {
233  return m_app_context;
234  }
235 
237  {
238  return m_display_info;
239  }
240 
242  {
243  return m_environment;
244  }
245 
247  {
248  return m_settings;
249  }
250 
252  {
253  return m_error_system;
254  }
255 
256  tree_evaluator& get_evaluator ();
257 
259  {
260  return m_help_system;
261  }
262 
264  {
265  return m_input_system;
266  }
267 
269  {
270  return m_output_system;
271  }
272 
274  {
275  return m_history_system;
276  }
277 
279  {
280  return m_dynamic_loader;
281  }
282 
284  {
285  return m_load_path;
286  }
287 
289  {
290  return m_load_save_system;
291  }
292 
294  {
295  return m_type_info;
296  }
297 
299  {
300  return m_symbol_table;
301  }
302 
303  symbol_scope get_top_scope () const;
304  symbol_scope get_current_scope () const;
305  symbol_scope require_current_scope (const std::string& who) const;
306 
307  profiler& get_profiler ();
308 
309  stream_list& get_stream_list ();
310 
312  {
313  return m_child_list;
314  }
315 
316  url_handle_manager& get_url_handle_manager ();
317 
319  {
320  return m_cdef_manager;
321  }
322 
324  {
325  return m_gtk_manager;
326  }
327 
329  {
330  return m_event_manager;
331  }
332 
334  {
335  return *m_gh_manager;
336  }
337 
338  // Any Octave code that needs to change the current directory should
339  // call this function instead of calling the system chdir function
340  // directly so that the load-path and GUI may be notified of the
341  // change.
342 
343  int chdir (const std::string& dir);
344 
345  void mlock (bool skip_first = false) const;
346  void munlock (bool skip_first = false) const;
347  bool mislocked (bool skip_first = false) const;
348 
349  // NOTE: since we have a version that accepts a bool argument, we
350  // can't rely on automatic conversion from char* to std::string.
351  void munlock (const char *nm);
352  void munlock (const std::string& nm);
353 
354  bool mislocked (const char *nm);
355  bool mislocked (const std::string& nm);
356 
357  std::string mfilename (const std::string& opt = "") const;
358 
359  octave_value_list eval_string (const std::string& eval_str, bool silent,
360  int& parse_status, int nargout);
361 
362  octave_value eval_string (const std::string& eval_str, bool silent,
363  int& parse_status);
364 
365  octave_value_list eval_string (const octave_value& arg, bool silent,
366  int& parse_status, int nargout);
367 
368  octave_value_list eval (const std::string& try_code, int nargout);
369 
370  octave_value_list eval (const std::string& try_code,
371  const std::string& catch_code, int nargout);
372 
373  octave_value_list evalin (const std::string& context,
374  const std::string& try_code, int nargout);
375 
376  octave_value_list evalin (const std::string& context,
377  const std::string& try_code,
378  const std::string& catch_code, int nargout);
379 
381  feval (const char *name,
382  const octave_value_list& args = octave_value_list (),
383  int nargout = 0);
384 
386  feval (const std::string& name,
387  const octave_value_list& args = octave_value_list (),
388  int nargout = 0);
389 
391  feval (octave_function *fcn,
392  const octave_value_list& args = octave_value_list (),
393  int nargout = 0);
394 
396  feval (const octave_value& f_arg,
397  const octave_value_list& args = octave_value_list (),
398  int nargout = 0);
399 
400  octave_value_list feval (const octave_value_list& args, int nargout = 0);
401 
402  octave_value make_function_handle (const std::string& name);
403 
404  void install_variable (const std::string& name, const octave_value& value,
405  bool global);
406 
407  void set_global_value (const std::string& name, const octave_value& value);
408 
409  octave_value global_varval (const std::string& name) const;
410 
411  void global_assign (const std::string& name,
412  const octave_value& val = octave_value ());
413 
414  octave_value top_level_varval (const std::string& name) const;
415 
416  void top_level_assign (const std::string& name,
417  const octave_value& val = octave_value ());
418 
419  bool is_variable (const std::string& name) const;
420 
421  bool is_local_variable (const std::string& name) const;
422 
423  octave_value varval (const std::string& name) const;
424 
425  void assign (const std::string& name,
426  const octave_value& val = octave_value ());
427 
428  void assignin (const std::string& context, const std::string& varname,
429  const octave_value& val = octave_value ());
430 
431  void source_file (const std::string& file_name,
432  const std::string& context = "",
433  bool verbose = false, bool require_file = true);
434 
435  bool at_top_level () const;
436 
437  bool isglobal (const std::string& name) const;
438 
439  octave_value find (const std::string& name);
440 
441  void clear_all (bool force = false);
442 
443  void clear_objects ();
444 
445  void clear_variable (const std::string& name);
446 
447  void clear_variable_pattern (const std::string& pattern);
448 
449  void clear_variable_regexp (const std::string& pattern);
450 
451  void clear_variables ();
452 
453  void clear_global_variable (const std::string& name);
454 
455  void clear_global_variable_pattern (const std::string& pattern);
456 
457  void clear_global_variable_regexp (const std::string& pattern);
458 
459  void clear_global_variables ();
460 
461  void clear_functions (bool force = false);
462 
463  void clear_function (const std::string& name);
464 
465  void clear_symbol (const std::string& name);
466 
467  void clear_function_pattern (const std::string& pat);
468 
469  void clear_function_regexp (const std::string& pat);
470 
471  void clear_symbol_pattern (const std::string& pat);
472 
473  void clear_symbol_regexp (const std::string& pat);
474 
475  std::list<std::string> variable_names ();
476 
477  std::list<std::string> top_level_variable_names ();
478 
479  std::list<std::string> global_variable_names ();
480 
481  std::list<std::string> user_function_names ();
482 
483  std::list<std::string> autoloaded_functions () const;
484 
485  void interrupt ();
486 
487  // Pause interpreter execution at the next available statement and
488  // enter the debugger.
489  void pause ();
490 
491  // Exit debugger or stop execution and return to the top-level REPL
492  // or server loop.
493  void stop ();
494 
495  // Add EXPR to the set of expressions that may be evaluated when the
496  // debugger stops at a breakpoint.
497  void add_debug_watch_expression (const std::string& expr);
498 
499  // Remove EXPR from the set of expressions that may be evaluated
500  // when the debugger stops at a breakpoint.
501  void remove_debug_watch_expression (const std::string& expr);
502 
503  // Clear the set of expressions that may be evaluated when the
504  // debugger stops at a breakpoint.
505  void clear_debug_watch_expressions ();
506 
507  // Return the set of expressions that may be evaluated when the
508  // debugger stops at a breakpoint.
509  std::set<std::string> debug_watch_expressions () const;
510 
511  // Resume interpreter execution if paused.
512  void resume ();
513 
514  octave_value PS1 (const octave_value_list& args, int nargout);
515  std::string PS1 () const;
516  std::string PS1 (const std::string& s);
517  void set_PS1 (const std::string& s);
518 
519  octave_value PS2 (const octave_value_list& args, int nargout);
520  std::string PS2 () const;
521  std::string PS2 (const std::string& s);
522  void set_PS2 (const std::string& s);
523 
524  octave_value PS4 (const octave_value_list& args, int nargout);
525  std::string PS4 () const;
526  std::string PS4 (const std::string& s);
527  void set_PS4 (const std::string& s);
528 
529  // Provided for convenience. Will be removed once we eliminate the
530  // old terminal widget.
531  bool experimental_terminal_widget () const;
532 
533  void handle_exception (const execution_exception& ee);
534 
535  void recover_from_exception ();
536 
537  void mark_for_deletion (const std::string& file);
538 
539  void cleanup_tmp_files ();
540 
541  void quit (int exit_status, bool force = false, bool confirm = true);
542 
543  void cancel_quit (bool flag) { m_cancel_quit = flag; }
544 
546  {
547  return m_executing_finish_script;
548  }
549 
550  void add_atexit_fcn (const std::string& fname);
551 
552  bool remove_atexit_fcn (const std::string& fname);
553 
554  static interpreter * the_interpreter () { return s_instance; }
555 
556 private:
557 
558  void display_startup_message () const;
559 
560  int execute_startup_files ();
561 
562  int execute_eval_option_code ();
563 
564  int execute_command_line_file ();
565 
566  int main_loop ();
567 
568  int server_loop ();
569 
570  void shutdown ();
571 
572  void execute_atexit_fcns ();
573 
574  void maximum_braindamage ();
575 
576  void execute_pkg_add (const std::string& dir);
577 
578  int safe_source_file (const std::string& file_name,
579  const std::string& context = "",
580  bool verbose = false, bool require_file = true);
581 
582  //--------
583 
584  // The interpreter instance; Currently it is only possible to
585  // have one, so OCTAVE_THREAD_LOCAL will normally be defined to be
586  // empty. Eventually we would like to allow multiple interpreters
587  // to be active at once, but they will still be limited to one per
588  // thread. When that is possible, OCTAVE_THREAD_LOCAL can be
589  // replaced by the C++ thread_local keyword. For now, use a macro
590  // to allow experimenting with thread_local storage.
591 
592  OCTAVE_THREAD_LOCAL static interpreter *s_instance;
593 
594  application *m_app_context;
595 
596  temporary_file_list m_tmp_files;
597 
598  std::list<std::string> m_atexit_fcns;
599 
600  display_info m_display_info;
601 
602  environment m_environment;
603 
604  settings m_settings;
605 
606  error_system m_error_system;
607 
608  tree_evaluator m_evaluator;
609 
610  help_system m_help_system;
611 
612  input_system m_input_system;
613 
614  output_system m_output_system;
615 
616  history_system m_history_system;
617 
618  dynamic_loader m_dynamic_loader;
619 
620  load_path m_load_path;
621 
622  load_save_system m_load_save_system;
623 
624  type_info m_type_info;
625 
626  symbol_table m_symbol_table;
627 
628  stream_list m_stream_list;
629 
630  child_list m_child_list;
631 
632  url_handle_manager m_url_handle_manager;
633 
634  cdef_manager m_cdef_manager;
635 
636  gtk_manager m_gtk_manager;
637 
638  event_manager m_event_manager;
639 
640  gh_manager *m_gh_manager;
641 
642  // TRUE means this is an interactive interpreter (forced or not).
643  bool m_interactive;
644 
645  bool m_read_site_files;
646 
647  bool m_read_init_files;
648 
649  bool m_verbose;
650 
651  bool m_traditional;
652 
653  bool m_inhibit_startup_message;
654 
655  bool m_load_path_initialized;
656 
657  bool m_history_initialized;
658 
659  bool m_interrupt_all_in_process_group;
660 
661  bool m_cancel_quit;
662 
663  bool m_executing_finish_script;
664 
665  bool m_executing_atexit;
666 
667  bool m_initialized;
668 };
669 
670 OCTAVE_END_NAMESPACE(octave)
671 
672 #endif
Provides threadsafe access to octave.
void interrupt_all_in_process_group(bool b)
Definition: interpreter.h:221
void verbose(bool flag)
Definition: interpreter.h:185
void read_site_files(bool flag)
Definition: interpreter.h:175
gh_manager & get_gh_manager()
Definition: interpreter.h:333
bool in_top_level_repl() const
Definition: interpreter.h:205
cdef_manager & get_cdef_manager()
Definition: interpreter.h:318
bool traditional() const
Definition: interpreter.h:195
environment & get_environment()
Definition: interpreter.h:241
load_save_system & get_load_save_system()
Definition: interpreter.h:288
dynamic_loader & get_dynamic_loader()
Definition: interpreter.h:278
type_info & get_type_info()
Definition: interpreter.h:293
bool executing_finish_script() const
Definition: interpreter.h:545
event_manager & get_event_manager()
Definition: interpreter.h:328
symbol_table & get_symbol_table()
Definition: interpreter.h:298
input_system & get_input_system()
Definition: interpreter.h:263
void cancel_quit(bool flag)
Definition: interpreter.h:543
application * get_app_context()
Definition: interpreter.h:231
output_system & get_output_system()
Definition: interpreter.h:268
settings & get_settings()
Definition: interpreter.h:246
gtk_manager & get_gtk_manager()
Definition: interpreter.h:323
history_system & get_history_system()
Definition: interpreter.h:273
void traditional(bool flag)
Definition: interpreter.h:190
bool interactive() const
Definition: interpreter.h:165
void interactive(bool arg)
Definition: interpreter.h:170
void inhibit_startup_message(bool flag)
Definition: interpreter.h:200
display_info & get_display_info()
Definition: interpreter.h:236
load_path & get_load_path()
Definition: interpreter.h:283
void read_init_files(bool flag)
Definition: interpreter.h:180
bool is_initialized() const
Definition: interpreter.h:210
error_system & get_error_system()
Definition: interpreter.h:251
void set_global_value(const std::string &name, const octave_value &value)
child_list & get_child_list()
Definition: interpreter.h:311
bool server_mode() const
Definition: interpreter.h:163
help_system & get_help_system()
Definition: interpreter.h:258
bool interrupt_all_in_process_group() const
Definition: interpreter.h:226
static interpreter * the_interpreter()
Definition: interpreter.h:554
void insert(const std::string &file)
Definition: interpreter.cc:326
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
bool octave_interpreter_ready
Definition: interpreter.cc:92
sys::time Vlast_chdir_time
std::atomic< bool > octave_initialized
Definition: interpreter.cc:95
bool quit_allowed
Definition: interpreter.cc:88
int chdir(const std::string &path_arg)
Definition: lo-sysdep.cc:107
octave_value_list feval(const char *name, const octave_value_list &args, int nargout)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
Definition: oct-parse.cc:10413
void source_file(const std::string &file_name, const std::string &context="", bool verbose=false, bool require_file=true)