GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
octave.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-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 // Born February 20, 1992.
27 
28 #if defined (HAVE_CONFIG_H)
29 # include "config.h"
30 #endif
31 
32 #include <iostream>
33 #include <string>
34 
35 #include "file-ops.h"
36 #include "getopt-wrapper.h"
37 #include "lo-error.h"
38 #include "oct-env.h"
39 #include "str-vec.h"
40 
41 #include "Cell.h"
42 #include "defun.h"
43 #include "display.h"
44 #include "error.h"
45 #include "input.h"
46 #include "interpreter.h"
47 #include "octave.h"
48 #include "oct-hist.h"
49 #include "oct-map.h"
50 #include "ovl.h"
51 #include "options.h"
52 #include "ov.h"
53 #include "parse.h"
54 #include "sysdep.h"
55 #include "usage.h"
56 
58 
60 {
61  m_all_args.resize (1);
62  m_all_args[0] = "";
63 }
64 
65 cmdline_options::cmdline_options (int argc, char **argv)
66 {
67  // Save raw program arguments.
68  m_all_args = string_vector (argv, argc);
69 
70  while (true)
71  {
72  int long_idx;
73 
74  int optc = octave_getopt_long_wrapper (argc, argv, short_opts,
75  long_opts, &long_idx);
76 
77  if (optc < 0)
78  break;
79 
80  switch (optc)
81  {
82  case '?':
83  // Unrecognized option. getopt_long already printed a message about
84  // it, so we will just print the usage string and exit.
85  octave_print_terse_usage_and_exit ();
86  break;
87 
88  case 'H':
89  m_read_history_file = false;
90  break;
91 
92  case 'W':
93  m_no_window_system = true;
94  break;
95 
96  case 'V':
97  m_verbose_flag = true;
98  break;
99 
100  case 'd':
101  // This is the same as yydebug in parse.y.
102  octave_debug++;
103  break;
104 
105  case 'f':
106  m_read_init_files = false;
107  m_read_site_files = false;
108  break;
109 
110  case 'h':
111  octave_print_verbose_usage_and_exit ();
112  break;
113 
114  case 'i':
115  m_forced_interactive = true;
116  break;
117 
118  case 'p':
119  if (octave_optarg_wrapper ())
120  m_command_line_path.push_back (octave_optarg_wrapper ());
121  break;
122 
123  case 'q':
124  m_inhibit_startup_message = true;
125  break;
126 
127  case 'x':
128  m_echo_commands = true;
129  break;
130 
131  case 'v':
132  octave_print_version_and_exit ();
133  break;
134 
136  if (octave_optarg_wrapper ())
137  m_docstrings_file = octave_optarg_wrapper ();
138  break;
139 
141  if (octave_optarg_wrapper ())
142  m_doc_cache_file = octave_optarg_wrapper ();
143  break;
144 
145  case EVAL_OPTION:
146  if (octave_optarg_wrapper ())
147  {
148  if (m_code_to_eval.empty ())
149  m_code_to_eval = octave_optarg_wrapper ();
150  else
151  m_code_to_eval += (std::string (" ")
152  + octave_optarg_wrapper ());
153  }
154  break;
155 
156  case EXEC_PATH_OPTION:
157  if (octave_optarg_wrapper ())
158  m_exec_path = octave_optarg_wrapper ();
159  break;
160 
162 #if defined (HAVE_QSCINTILLA)
163  m_experimental_terminal_widget = true;
164 #endif
165  break;
166 
167  case GUI_OPTION:
168  m_gui = true;
169  break;
170 
171  case IMAGE_PATH_OPTION:
172  if (octave_optarg_wrapper ())
173  m_image_path = octave_optarg_wrapper ();
174  break;
175 
176  case INFO_FILE_OPTION:
177  if (octave_optarg_wrapper ())
178  m_info_file = octave_optarg_wrapper ();
179  break;
180 
181  case INFO_PROG_OPTION:
182  if (octave_optarg_wrapper ())
183  m_info_program = octave_optarg_wrapper ();
184  break;
185 
186  case LINE_EDITING_OPTION:
187  m_forced_line_editing = m_line_editing = true;
188  break;
189 
190  case NO_GUI_OPTION:
191  m_gui = false;
192  break;
193 
194  case NO_INIT_FILE_OPTION:
195  m_read_init_files = false;
196  break;
197 
198  case NO_INIT_PATH_OPTION:
199  m_set_initial_path = false;
200  break;
201 
203  m_line_editing = false;
204  break;
205 
206  case NO_SITE_FILE_OPTION:
207  m_read_site_files = false;
208  break;
209 
210  case PERSIST_OPTION:
211  m_persist = true;
212  break;
213 
214  case SERVER_OPTION:
215  m_server = true;
216  break;
217 
219  if (octave_optarg_wrapper ())
220  m_texi_macros_file = octave_optarg_wrapper ();
221  break;
222 
223  case TRADITIONAL_OPTION:
224  m_traditional = true;
225  m_persist = true;
226  break;
227 
228  default:
229  // getopt_long should print a message about unrecognized options and
230  // return '?', which is handled above. If we end up here, it is
231  // because there was an option but we forgot to handle it.
232  // That should be fatal.
233  panic_impossible ();
234  break;
235  }
236  }
237 
238  m_remaining_args = string_vector (argv+octave_optind_wrapper (),
239  argc-octave_optind_wrapper ());
240 }
241 
244 {
246 
247  m.assign ("sys_argc", sys_argc ());
248  m.assign ("sys_argv", Cell (all_args ()));
249  m.assign ("echo_commands", echo_commands ());
250  m.assign ("forced_interactive", forced_interactive ());
251  m.assign ("forced_line_editing", forced_line_editing ());
252  m.assign ("gui", gui ());
253  m.assign ("inhibit_startup_message", inhibit_startup_message ());
254  m.assign ("line_editing", line_editing ());
255  m.assign ("no_window_system", no_window_system ());
256  m.assign ("persist", persist ());
257  m.assign ("read_history_file", read_history_file ());
258  m.assign ("read_init_files", read_init_files ());
259  m.assign ("read_site_files", read_site_files ());
260  m.assign ("server", server ());
261  m.assign ("set_initial_path", set_initial_path ());
262  m.assign ("traditional", traditional ());
263  m.assign ("verbose_flag", verbose_flag ());
264  m.assign ("code_to_eval", code_to_eval ());
265  m.assign ("command_line_path", string_vector (command_line_path ()));
266  m.assign ("docstrings_file", docstrings_file ());
267  m.assign ("doc_cache_file", doc_cache_file ());
268  m.assign ("exec_path", exec_path ());
269  m.assign ("image_path", image_path ());
270  m.assign ("info_file", info_file ());
271  m.assign ("info_program", info_program ());
272  m.assign ("texi_macros_file", texi_macros_file ());
273  m.assign ("all_args", Cell (all_args ()));
274  m.assign ("remaining_args", Cell (remaining_args ()));
275 
276  return m;
277 }
278 
279 application *application::s_instance = nullptr;
280 
281 application::application (int argc, char **argv)
282  : m_options (argc, argv)
283 {
284  init ();
285 }
286 
288  : m_options (opts)
289 {
290  init ();
291 }
292 
293 // Note: Although the application destructor doesn't explicitly
294 // perform any actions, it can't be declared "default" in the header
295 // file if the interpreter is an incomplete type. Providing
296 // an explicit definition of the destructor here is much simpler than
297 // including the full declaration of interpreter in the
298 // octave.h header file.
300 
301 void
302 application::set_program_names (const std::string& pname)
303 {
305 
306  std::size_t pos = pname.find_last_of (sys::file_ops::dir_sep_chars ());
307 
308  m_program_name = (pos != std::string::npos) ? pname.substr (pos+1) : pname;
309 }
310 
311 void
313 {
314  octave_idx_type nargs = args.numel ();
315 
316  if (nargs > 0)
317  {
318  // Skip first argument (program name).
319  nargs--;
320 
321  m_argv.resize (nargs);
322 
323  for (octave_idx_type i = 0; i < nargs; i++)
324  m_argv[i] = args[i+1];
325  }
326 }
327 
328 bool
330 {
331  return s_instance ? s_instance->m_options.forced_interactive () : false;
332 }
333 
334 // Provided for convenience. Will be removed once we eliminate the
335 // old terminal widget.
336 bool
338 {
339  return (s_instance
340  ? s_instance->m_options.experimental_terminal_widget () : false);
341 }
342 
343 bool
345 {
346  return m_interpreter ? m_interpreter->is_initialized () : false;
347 }
348 
351 {
352  if (! m_interpreter)
353  m_interpreter = std::unique_ptr<interpreter> (new interpreter (this));
354 
355  return *m_interpreter;
356 }
357 
358 void
360 {
361  if (m_interpreter)
362  m_interpreter->initialize ();
363 }
364 
365 int
367 {
368  return m_interpreter ? m_interpreter->execute () : -1;
369 }
370 
371 void
373 {
374  m_interpreter.reset ();
375 }
376 
377 void
378 application::init ()
379 {
380  if (s_instance)
381  throw std::runtime_error
382  ("only one Octave application object may be active");
383 
384  s_instance = this;
385 
386  string_vector all_args = m_options.all_args ();
387 
388  set_program_names (all_args[0]);
389 
390  string_vector remaining_args = m_options.remaining_args ();
391 
392  std::string code_to_eval = m_options.code_to_eval ();
393 
394  m_have_script_file = ! remaining_args.empty ();
395 
396  m_have_eval_option_code = ! code_to_eval.empty ();
397 
399  {
400  std::cerr << R"(error: --eval "CODE" and script file are mutually exclusive options)" << std::endl;
401 
402  octave_print_terse_usage_and_exit ();
403  }
404 
405  if (m_options.gui ())
406  {
408  {
409  std::cerr << "error: --gui and --no-window-system are mutually exclusive options" << std::endl;
410  octave_print_terse_usage_and_exit ();
411  }
412  if (! m_options.line_editing ())
413  {
414  std::cerr << "error: --gui and --no-line-editing are mutually exclusive options" << std::endl;
415  octave_print_terse_usage_and_exit ();
416  }
417  if (m_options.server ())
418  {
419  std::cerr << "error: --gui and --server are mutually exclusive options" << std::endl;
420  octave_print_terse_usage_and_exit ();
421  }
422  }
423 
425  && ! m_options.persist ()
426  && ! m_options.traditional ());
427 
428  // This should probably happen early.
429  sysdep_init ();
430 }
431 
432 int
434 {
435  interpreter& interp = create_interpreter ();
436 
437  int status = interp.execute ();
438 
439  return status;
440 }
441 
442 DEFUN (isguirunning, args, ,
443  doc: /* -*- texinfo -*-
444 @deftypefn {} {@var{tf} =} isguirunning ()
445 Return true if Octave is running in GUI mode and false otherwise.
446 @seealso{have_window_system}
447 @end deftypefn */)
448 {
449  if (args.length () != 0)
450  print_usage ();
451 
452  // FIXME: This isn't quite right, it just says that we intended to
453  // start the GUI, not that it is actually running.
454 
455  return ovl (application::is_gui_running ());
456 }
457 
458 /*
459 %!assert (islogical (isguirunning ()))
460 %!error <Invalid call> isguirunning (1)
461 */
462 
463 DEFUN (argv, args, ,
464  doc: /* -*- texinfo -*-
465 @deftypefn {} {@var{args} =} argv ()
466 Return the command line arguments passed to Octave.
467 
468 For example, if you invoked Octave using the command
469 
470 @example
471 octave --no-line-editing --silent
472 @end example
473 
474 @noindent
475 @code{argv} would return a cell array of strings with the elements
476 @option{--no-line-editing} and @option{--silent}.
477 
478 If you write an executable Octave script, @code{argv} will return the list
479 of arguments passed to the script. @xref{Executable Octave Programs}, for
480 an example of how to create an executable Octave script.
481 @seealso{program_name, cmdline_options}
482 @end deftypefn */)
483 {
484  if (args.length () != 0)
485  print_usage ();
486 
487  return ovl (Cell (application::argv ()));
488 }
489 
490 /*
491 %!assert (iscellstr (argv ()))
492 %!error <Invalid call> argv (1)
493 */
494 
495 DEFUN (cmdline_options, args, ,
496  doc: /* -*- texinfo -*-
497 @deftypefn {} {@var{opt_struct} =} cmdline_options ()
498 Return a structure containing detailed information about the command line
499 arguments passed to Octave.
500 
501 Programming Note: This function provides copious amounts of information about
502 Octave's parsing of command line options and may be more useful for debugging
503 Octave rather than for general use.
504 @seealso{argv, program_name}
505 @end deftypefn */)
506 {
507  if (args.length () != 0)
508  print_usage ();
509 
510  application *app = application::app ();
511 
512  if (! app)
513  error ("invalid application context!");
514 
515  cmdline_options opts = app->options ();
516 
517  return ovl (opts.as_octave_value ());
518 }
519 
520 /*
521 %!assert (isstruct (cmdline_options ()))
522 %!error <Invalid call> cmdline_options (1)
523 */
524 
525 DEFUN (program_invocation_name, args, ,
526  doc: /* -*- texinfo -*-
527 @deftypefn {} {@var{name} =} program_invocation_name ()
528 Return the string that was typed at the shell prompt to run Octave.
529 
530 The string may include path components as well as the program filename.
531 
532 If executing a script from the command line (e.g., @code{octave foo.m}) or
533 using an executable Octave script, the program name is set to the name of the
534 script. @xref{Executable Octave Programs}, for an example of how to create an
535 executable Octave script.
536 @seealso{program_name, argv}
537 @end deftypefn */)
538 {
539  if (args.length () != 0)
540  print_usage ();
541 
543 }
544 
545 /*
546 %!assert (ischar (program_invocation_name ()))
547 %!error <Invalid call> program_invocation_name (1)
548 */
549 
550 DEFUN (program_name, args, ,
551  doc: /* -*- texinfo -*-
552 @deftypefn {} {@var{name} =} program_name ()
553 Return the filename component of the value returned by
554 @code{program_invocation_name}.
555 
556 @seealso{program_invocation_name, argv}
557 @end deftypefn */)
558 {
559  if (args.length () != 0)
560  print_usage ();
561 
562  return ovl (application::program_name ());
563 }
564 
565 /*
566 %!assert (ischar (program_name ()))
567 %!error <Invalid call> program_name (1)
568 */
569 
570 OCTAVE_END_NAMESPACE(octave)
Definition: Cell.h:43
application(const cmdline_options &opts=cmdline_options())
Definition: octave.cc:287
virtual int execute_interpreter()
Definition: octave.cc:366
void set_program_names(const std::string &pname)
Definition: octave.cc:302
static bool forced_interactive()
Definition: octave.cc:329
void intern_argv(const string_vector &args)
Definition: octave.cc:312
virtual ~application()
Definition: octave.cc:299
string_vector m_argv
Definition: octave.h:346
static application * app()
Definition: octave.h:301
cmdline_options options() const
Definition: octave.h:261
bool m_have_script_file
Definition: octave.h:355
static std::string program_name()
Definition: octave.h:308
bool m_is_octave_program
Definition: octave.h:360
static string_vector argv()
Definition: octave.h:313
bool interpreter_is_initialized() const
Definition: octave.cc:344
bool m_have_eval_option_code
Definition: octave.h:351
std::string m_program_name
Definition: octave.h:340
static bool is_gui_running()
Definition: octave.h:318
virtual void initialize_interpreter()
Definition: octave.cc:359
virtual interpreter & create_interpreter()
Definition: octave.cc:350
bool experimental_terminal_widget() const
Definition: octave.cc:337
std::unique_ptr< interpreter > m_interpreter
Definition: octave.h:362
static std::string program_invocation_name()
Definition: octave.h:303
cmdline_options m_options
Definition: octave.h:348
std::string m_program_invocation_name
Definition: octave.h:337
virtual void delete_interpreter()
Definition: octave.cc:372
int execute()
Definition: octave.cc:433
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
int sys_argc() const
Definition: octave.h:53
std::string texi_macros_file() const
Definition: octave.h:85
bool inhibit_startup_message() const
Definition: octave.h:63
std::string doc_cache_file() const
Definition: octave.h:80
std::string image_path() const
Definition: octave.h:82
bool read_site_files() const
Definition: octave.h:71
string_vector remaining_args() const
Definition: octave.h:87
bool persist() const
Definition: octave.h:68
std::string info_program() const
Definition: octave.h:84
bool server() const
Definition: octave.h:72
bool read_history_file() const
Definition: octave.h:69
std::string exec_path() const
Definition: octave.h:81
bool no_window_system() const
Definition: octave.h:67
std::list< std::string > command_line_path() const
Definition: octave.h:77
std::string code_to_eval() const
Definition: octave.h:76
string_vector all_args() const
Definition: octave.h:86
std::string info_file() const
Definition: octave.h:83
bool verbose_flag() const
Definition: octave.h:75
std::string docstrings_file() const
Definition: octave.h:79
bool echo_commands() const
Definition: octave.h:56
bool gui() const
Definition: octave.h:62
bool traditional() const
Definition: octave.h:74
bool read_init_files() const
Definition: octave.h:70
bool set_initial_path() const
Definition: octave.h:73
bool forced_line_editing() const
Definition: octave.h:61
octave_value as_octave_value() const
Definition: octave.cc:243
void resize(octave_idx_type n, const std::string &rfv="")
Definition: str-vec.h:95
bool empty() const
Definition: str-vec.h:77
octave_idx_type numel() const
Definition: str-vec.h:100
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void print_usage(void)
Definition: defun-int.h:72
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
void() error(const char *fmt,...)
Definition: error.cc:988
#define panic_impossible()
Definition: error.h:503
std::string dir_sep_chars()
char * octave_optarg_wrapper(void)
int octave_getopt_long_wrapper(int argc, char **argv, const char *shortopts, const struct octave_getopt_options *longopts, int *longind)
int octave_optind_wrapper(void)
T octave_idx_type m
Definition: mx-inlines.cc:781
#define INFO_FILE_OPTION
Definition: options.h:47
#define NO_INIT_PATH_OPTION
Definition: options.h:53
#define NO_GUI_OPTION
Definition: options.h:50
#define LINE_EDITING_OPTION
Definition: options.h:49
#define TRADITIONAL_OPTION
Definition: options.h:59
#define INFO_PROG_OPTION
Definition: options.h:48
#define BUILT_IN_DOCSTRINGS_FILE_OPTION
Definition: options.h:40
#define SERVER_OPTION
Definition: options.h:57
#define DOC_CACHE_FILE_OPTION
Definition: options.h:41
#define GUI_OPTION
Definition: options.h:45
#define EXPERIMENTAL_TERMINAL_WIDGET_OPTION
Definition: options.h:44
#define NO_SITE_FILE_OPTION
Definition: options.h:55
#define NO_LINE_EDITING_OPTION
Definition: options.h:54
#define TEXI_MACROS_FILE_OPTION
Definition: options.h:58
struct octave_getopt_options long_opts[]
Definition: options.h:60
#define EXEC_PATH_OPTION
Definition: options.h:43
#define IMAGE_PATH_OPTION
Definition: options.h:46
#define PERSIST_OPTION
Definition: options.h:56
#define EVAL_OPTION
Definition: options.h:42
#define NO_INIT_FILE_OPTION
Definition: options.h:52
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219
int octave_debug
void sysdep_init()