1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 2002-2021 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 <map> 32 #include <stack> 33 #include <string> 34 35 #include "child-list.h" 36 #include "oct-time.h" 37 #include "quit.h" 38 #include "str-vec.h" 39 40 #include "cdef-manager.h" 41 #include "display.h" 42 #include "dynamic-ld.h" 43 #include "environment.h" 44 #include "error.h" 45 #include "event-manager.h" 46 #include "graphics.h" 47 #include "gtk-manager.h" 48 #include "help.h" 49 #include "input.h" 50 #include "load-path.h" 51 #include "load-save.h" 52 #include "oct-hist.h" 53 #include "oct-stream.h" 54 #include "ov-typeinfo.h" 55 #include "pager.h" 56 #include "pt-eval.h" 57 #include "settings.h" 58 #include "symtab.h" 59 #include "url-handle-manager.h" 60 61 extern OCTINTERP_API bool quit_allowed; 62 63 // TRUE means we are ready to interpret commands, but not everything 64 // is ready for interactive use. 65 extern OCTINTERP_API bool octave_interpreter_ready; 66 67 // TRUE means we've processed all the init code and we are good to go. 68 extern OCTINTERP_API bool octave_initialized; 69 70 #include "oct-time.h" 71 72 namespace octave 73 { 74 class profiler; 75 class child_list; 76 77 // The time we last time we changed directories. 78 extern sys::time Vlast_chdir_time; 79 80 // The application object contains a pointer to the current 81 // interpreter and the interpreter contains a pointer back to the 82 // application context so we need a forward declaration for one (or 83 // both) of them... 84 85 class application; 86 87 class temporary_file_list 88 { 89 public: 90 temporary_file_list(void)91 temporary_file_list (void) : m_files () { } 92 93 // No copying! 94 95 temporary_file_list (const temporary_file_list&) = delete; 96 97 temporary_file_list& operator = (const temporary_file_list&) = delete; 98 99 ~temporary_file_list (void); 100 101 void insert (const std::string& file); 102 103 void cleanup (void); 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 // No copying, at least not yet... 121 122 interpreter (const interpreter&) = delete; 123 124 interpreter& operator = (const interpreter&) = delete; 125 126 // Clean up the interpreter object. 127 128 ~interpreter (void); 129 130 void intern_nargin (octave_idx_type nargs); 131 132 // If creating an embedded interpreter, you may inhibit reading 133 // the command history file by calling initialize_history with 134 // read_history_file = false prior to calling initialize. 135 136 void initialize_history (bool read_history_file = false); 137 138 // If creating an embedded interpreter, you may inhibit setting 139 // the default compiled-in path by calling initialize_load_path 140 // with set_initial_path = false prior calling initialize. After 141 // that, you can add directories to the load path to set up a 142 // custom path. 143 144 void initialize_load_path (bool set_initial_path = true); 145 146 // Load command line history, set the load path. 147 148 void initialize (void); 149 150 // Initialize the interpreter (if not already done by an explicit 151 // call to initialize), execute startup files, --eval option code, 152 // script files, and/or interactive commands. 153 154 int execute (void); 155 156 void shutdown (void); 157 interactive(void)158 bool interactive (void) const 159 { 160 return m_interactive; 161 } 162 interactive(bool arg)163 void interactive (bool arg) 164 { 165 m_interactive = arg; 166 } 167 read_site_files(bool flag)168 void read_site_files (bool flag) 169 { 170 m_read_site_files = flag; 171 } 172 read_init_files(bool flag)173 void read_init_files (bool flag) 174 { 175 m_read_init_files = flag; 176 } 177 verbose(bool flag)178 void verbose (bool flag) 179 { 180 m_verbose = flag; 181 } 182 inhibit_startup_message(bool flag)183 void inhibit_startup_message (bool flag) 184 { 185 m_inhibit_startup_message = flag; 186 } 187 in_top_level_repl(void)188 bool in_top_level_repl (void) const 189 { 190 return m_evaluator.in_top_level_repl (); 191 } 192 initialized(void)193 bool initialized (void) const 194 { 195 return m_initialized; 196 } 197 get_display_info(void)198 display_info& get_display_info (void) 199 { 200 return m_display_info; 201 } 202 get_environment(void)203 environment& get_environment (void) 204 { 205 return m_environment; 206 } 207 get_settings(void)208 settings& get_settings (void) 209 { 210 return m_settings; 211 } 212 get_error_system(void)213 error_system& get_error_system (void) 214 { 215 return m_error_system; 216 } 217 get_help_system(void)218 help_system& get_help_system (void) 219 { 220 return m_help_system; 221 } 222 get_input_system(void)223 input_system& get_input_system (void) 224 { 225 return m_input_system; 226 } 227 get_output_system(void)228 output_system& get_output_system (void) 229 { 230 return m_output_system; 231 } 232 get_history_system(void)233 history_system& get_history_system (void) 234 { 235 return m_history_system; 236 } 237 get_dynamic_loader(void)238 dynamic_loader& get_dynamic_loader (void) 239 { 240 return m_dynamic_loader; 241 } 242 get_load_path(void)243 load_path& get_load_path (void) 244 { 245 return m_load_path; 246 } 247 get_load_save_system(void)248 load_save_system& get_load_save_system (void) 249 { 250 return m_load_save_system; 251 } 252 get_type_info(void)253 type_info& get_type_info (void) 254 { 255 return m_type_info; 256 } 257 get_symbol_table(void)258 symbol_table& get_symbol_table (void) 259 { 260 return m_symbol_table; 261 } 262 263 tree_evaluator& get_evaluator (void); 264 265 symbol_scope get_top_scope (void) const; 266 symbol_scope get_current_scope (void) const; 267 symbol_scope require_current_scope (const std::string& who) const; 268 269 profiler& get_profiler (void); 270 271 stream_list& get_stream_list (void); 272 get_child_list(void)273 child_list& get_child_list (void) 274 { 275 return m_child_list; 276 } 277 278 url_handle_manager& get_url_handle_manager (void); 279 get_cdef_manager(void)280 cdef_manager& get_cdef_manager (void) 281 { 282 return m_cdef_manager; 283 } 284 get_gtk_manager(void)285 gtk_manager& get_gtk_manager (void) 286 { 287 return m_gtk_manager; 288 } 289 get_event_manager(void)290 event_manager& get_event_manager (void) 291 { 292 return m_event_manager; 293 } 294 get_gh_manager(void)295 gh_manager& get_gh_manager (void) 296 { 297 return *m_gh_manager; 298 } 299 300 // Any Octave code that needs to change the current directory should 301 // call this function instead of calling the system chdir function 302 // directly so that the load-path and GUI may be notified of the 303 // change. 304 305 int chdir (const std::string& dir); 306 307 void mlock (bool skip_first = false) const; 308 void munlock (bool skip_first = false) const; 309 bool mislocked (bool skip_first = false) const; 310 311 // NOTE: since we have a version that accepts a bool argument, we 312 // can't rely on automatic conversion from char* to std::string. 313 void munlock (const char *nm); 314 void munlock (const std::string& nm); 315 316 bool mislocked (const char *nm); 317 bool mislocked (const std::string& nm); 318 319 std::string mfilename (const std::string& opt = "") const; 320 321 octave_value_list eval_string (const std::string& eval_str, bool silent, 322 int& parse_status, int nargout); 323 324 octave_value eval_string (const std::string& eval_str, bool silent, 325 int& parse_status); 326 327 octave_value_list eval_string (const octave_value& arg, bool silent, 328 int& parse_status, int nargout); 329 330 octave_value_list eval (const std::string& try_code, int nargout); 331 332 octave_value_list eval (const std::string& try_code, 333 const std::string& catch_code, int nargout); 334 335 octave_value_list evalin (const std::string& context, 336 const std::string& try_code, int nargout); 337 338 octave_value_list evalin (const std::string& context, 339 const std::string& try_code, 340 const std::string& catch_code, int nargout); 341 342 octave_value_list 343 feval (const char *name, 344 const octave_value_list& args = octave_value_list (), 345 int nargout = 0); 346 347 octave_value_list 348 feval (const std::string& name, 349 const octave_value_list& args = octave_value_list (), 350 int nargout = 0); 351 352 octave_value_list 353 feval (octave_function *fcn, 354 const octave_value_list& args = octave_value_list (), 355 int nargout = 0); 356 357 octave_value_list 358 feval (const octave_value& f_arg, 359 const octave_value_list& args = octave_value_list (), 360 int nargout = 0); 361 362 octave_value_list feval (const octave_value_list& args, int nargout = 0); 363 364 octave_value make_function_handle (const std::string& name); 365 366 void install_variable (const std::string& name, const octave_value& value, 367 bool global); 368 369 void set_global_value (const std::string& name, const octave_value& value); 370 371 octave_value global_varval (const std::string& name) const; 372 373 void global_assign (const std::string& name, 374 const octave_value& val = octave_value ()); 375 376 octave_value top_level_varval (const std::string& name) const; 377 378 void top_level_assign (const std::string& name, 379 const octave_value& val = octave_value ()); 380 381 bool is_variable (const std::string& name) const; 382 383 bool is_local_variable (const std::string& name) const; 384 385 octave_value varval (const std::string& name) const; 386 387 void assign (const std::string& name, 388 const octave_value& val = octave_value ()); 389 390 void assignin (const std::string& context, const std::string& varname, 391 const octave_value& val = octave_value ()); 392 393 void source_file (const std::string& file_name, 394 const std::string& context = "", 395 bool verbose = false, bool require_file = true); 396 397 bool at_top_level (void) const; 398 399 bool isglobal (const std::string& name) const; 400 401 octave_value find (const std::string& name); 402 403 void clear_all (bool force = false); 404 405 void clear_objects (void); 406 407 void clear_variable (const std::string& name); 408 409 void clear_variable_pattern (const std::string& pattern); 410 411 void clear_variable_regexp (const std::string& pattern); 412 413 void clear_variables (void); 414 415 void clear_global_variable (const std::string& name); 416 417 void clear_global_variable_pattern (const std::string& pattern); 418 419 void clear_global_variable_regexp (const std::string& pattern); 420 421 void clear_global_variables (void); 422 423 void clear_functions (bool force = false); 424 425 void clear_function (const std::string& name); 426 427 void clear_symbol (const std::string& name); 428 429 void clear_function_pattern (const std::string& pat); 430 431 void clear_function_regexp (const std::string& pat); 432 433 void clear_symbol_pattern (const std::string& pat); 434 435 void clear_symbol_regexp (const std::string& pat); 436 437 std::list<std::string> variable_names (void); 438 439 std::list<std::string> top_level_variable_names (void); 440 441 std::list<std::string> global_variable_names (void); 442 443 std::list<std::string> user_function_names (void); 444 445 std::list<std::string> autoloaded_functions (void) const; 446 447 void handle_exception (const execution_exception& e); 448 449 void recover_from_exception (void); 450 451 void mark_for_deletion (const std::string& file); 452 453 void cleanup_tmp_files (void); 454 455 void quit (int exit_status, bool force = false, bool confirm = true); 456 cancel_quit(bool flag)457 void cancel_quit (bool flag) { m_cancel_quit = flag; } 458 executing_finish_script(void)459 bool executing_finish_script (void) const 460 { 461 return m_executing_finish_script; 462 } 463 464 void add_atexit_fcn (const std::string& fname); 465 466 bool remove_atexit_fcn (const std::string& fname); 467 468 OCTAVE_DEPRECATED (6, "use interpreter::add_atexit_fcn member function instead") 469 static void add_atexit_function (const std::string& fname); 470 471 OCTAVE_DEPRECATED (6, "use interpreter::remove_atexit_fcn member function instead") 472 static bool remove_atexit_function (const std::string& fname); 473 the_interpreter(void)474 static interpreter * the_interpreter (void) { return instance; } 475 476 private: 477 478 // The interpreter instance; Currently it is only possible to 479 // have one, so OCTAVE_THREAD_LOCAL will normally be defined to be 480 // empty. Eventually we would like to allow multiple interpreters 481 // to be active at once, but they will still be limited to one per 482 // thread. When that is possible, OCTAVE_THREAD_LOCAL can be 483 // replaced by the C++ thread_local keyword. For now, use a macro 484 // to allow experimenting with thread_local storage. 485 486 OCTAVE_THREAD_LOCAL static interpreter *instance; 487 488 void display_startup_message (void) const; 489 490 int execute_startup_files (void); 491 492 int execute_eval_option_code (void); 493 494 int execute_command_line_file (void); 495 496 int main_loop (void); 497 498 void execute_atexit_fcns (void); 499 500 application *m_app_context; 501 502 temporary_file_list m_tmp_files; 503 504 std::list<std::string> m_atexit_fcns; 505 506 display_info m_display_info; 507 508 environment m_environment; 509 510 settings m_settings; 511 512 error_system m_error_system; 513 514 help_system m_help_system; 515 516 input_system m_input_system; 517 518 output_system m_output_system; 519 520 history_system m_history_system; 521 522 dynamic_loader m_dynamic_loader; 523 524 load_path m_load_path; 525 526 load_save_system m_load_save_system; 527 528 type_info m_type_info; 529 530 symbol_table m_symbol_table; 531 532 tree_evaluator m_evaluator; 533 534 stream_list m_stream_list; 535 536 child_list m_child_list; 537 538 url_handle_manager m_url_handle_manager; 539 540 cdef_manager m_cdef_manager; 541 542 gtk_manager m_gtk_manager; 543 544 event_manager m_event_manager; 545 546 gh_manager *m_gh_manager; 547 548 // TRUE means this is an interactive interpreter (forced or not). 549 bool m_interactive; 550 551 bool m_read_site_files; 552 553 bool m_read_init_files; 554 555 bool m_verbose; 556 557 bool m_inhibit_startup_message; 558 559 bool m_load_path_initialized; 560 561 bool m_history_initialized; 562 563 bool m_cancel_quit; 564 565 bool m_executing_finish_script; 566 567 bool m_executing_atexit; 568 569 bool m_initialized; 570 571 void maximum_braindamage (void); 572 573 void execute_pkg_add (const std::string& dir); 574 }; 575 } 576 577 #endif 578