# HG changeset patch # User Markus Mützel # Date 1626616488 -7200 # Node ID bc19d9360bace492accb86414badda5ab9ba8cde # Parent 3ab696e02f55bdbe95ade0e872d65981198bb2df main.cc: Use getopt to parse command line arguments (bug #60886). * src/main.in.cc (main): Use getopt to parse command line arguments. * libinterp/options-usage.h: Split into options.h and usage.h. * libinterp/options.h (octave_getopt_options long_opts): Add command line options "force-gui" and "no-gui-libs" to struct. diff -r 3ab696e02f55 -r bc19d9360bac libinterp/module.mk --- a/libinterp/module.mk Fri Jul 16 16:20:23 2021 -0400 +++ b/libinterp/module.mk Sun Jul 18 15:54:48 2021 +0200 @@ -92,7 +92,8 @@ $(PARSER_INC) noinst_HEADERS += \ - %reldir%/options-usage.h \ + %reldir%/options.h \ + %reldir%/usage.h \ $(NOINSTALL_LIBINTERP_OPERATORS_INC) nodist_octinclude_HEADERS += \ diff -r 3ab696e02f55 -r bc19d9360bac libinterp/octave.cc --- a/libinterp/octave.cc Fri Jul 16 16:20:23 2021 -0400 +++ b/libinterp/octave.cc Sun Jul 18 15:54:48 2021 +0200 @@ -48,10 +48,11 @@ #include "oct-hist.h" #include "oct-map.h" #include "ovl.h" -#include "options-usage.h" +#include "options.h" #include "ov.h" #include "parse.h" #include "sysdep.h" +#include "usage.h" namespace octave { diff -r 3ab696e02f55 -r bc19d9360bac libinterp/octave.h --- a/libinterp/octave.h Fri Jul 16 16:20:23 2021 -0400 +++ b/libinterp/octave.h Sun Jul 18 15:54:48 2021 +0200 @@ -38,7 +38,7 @@ namespace octave { - // Command line arguments. See also options-usage.h. + // Command line arguments. See also options.h. class OCTINTERP_API cmdline_options { diff -r 3ab696e02f55 -r bc19d9360bac libinterp/options-usage.h --- a/libinterp/options-usage.h Fri Jul 16 16:20:23 2021 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,203 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 1993-2021 The Octave Project Developers -// -// See the file COPYRIGHT.md in the top-level directory of this -// distribution or . -// -// This file is part of Octave. -// -// Octave is free software: you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Octave is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Octave; see the file COPYING. If not, see -// . -// -//////////////////////////////////////////////////////////////////////// - -#if ! defined (octave_options_usage_h) -#define octave_options_usage_h 1 - -#include "octave-config.h" - -#include - -#include "version.h" - -// Usage message -static const char *usage_string = - "octave [-HVWdfhiqvx] [--debug] [--debug-jit] [--doc-cache-file file]\n\ - [--echo-commands] [--eval CODE] [--exec-path path]\n\ - [--experimental-terminal-widget] [--gui] [--help] [--image-path path]\n\ - [--info-file file] [--info-program prog] [--interactive]\n\ - [--jit-compiler] [--line-editing] [--no-gui] [--no-history]\n\ - [--no-init-file] [--no-init-path] [--no-line-editing]\n\ - [--no-site-file] [--no-window-system] [--norc] [-p path]\n\ - [--path path] [--persist] [--server] [--silent] [--traditional]\n\ - [--verbose] [--version] [file]"; - -// This is here so that it's more likely that the usage message and -// the real set of options will agree. Note: the '+' must come first -// to prevent getopt from permuting arguments! -static const char *short_opts = "+HWVdfhip:qvx"; - - -#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC) - // Disable warning temporarily. -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#endif - -// Long options. See the comments in getopt.h for the meanings of the -// fields in this structure. -#define BUILT_IN_DOCSTRINGS_FILE_OPTION 1 -#define DOC_CACHE_FILE_OPTION 2 -#define EVAL_OPTION 3 -#define EXEC_PATH_OPTION 4 -#define GUI_OPTION 5 -#define IMAGE_PATH_OPTION 6 -#define INFO_FILE_OPTION 7 -#define INFO_PROG_OPTION 8 -#define DEBUG_JIT_OPTION 9 -#define JIT_COMPILER_OPTION 10 -#define LINE_EDITING_OPTION 11 -#define NO_GUI_OPTION 12 -#define NO_INIT_FILE_OPTION 13 -#define NO_INIT_PATH_OPTION 14 -#define NO_LINE_EDITING_OPTION 15 -#define NO_SITE_FILE_OPTION 16 -#define PERSIST_OPTION 17 -#define SERVER_OPTION 18 -#define TEXI_MACROS_FILE_OPTION 19 -#define TRADITIONAL_OPTION 20 -#define EXPERIMENTAL_TERMINAL_WIDGET_OPTION 21 -struct octave_getopt_options long_opts[] = -{ - { "braindead", octave_no_arg, 0, TRADITIONAL_OPTION }, - { "built-in-docstrings-file", octave_required_arg, 0, BUILT_IN_DOCSTRINGS_FILE_OPTION }, - { "debug", octave_no_arg, 0, 'd' }, - { "debug-jit", octave_no_arg, 0, DEBUG_JIT_OPTION }, - { "doc-cache-file", octave_required_arg, 0, DOC_CACHE_FILE_OPTION }, - { "echo-commands", octave_no_arg, 0, 'x' }, - { "eval", octave_required_arg, 0, EVAL_OPTION }, - { "exec-path", octave_required_arg, 0, EXEC_PATH_OPTION }, - { "experimental-terminal-widget", octave_no_arg, 0, EXPERIMENTAL_TERMINAL_WIDGET_OPTION }, - { "gui", octave_no_arg, 0, GUI_OPTION }, - { "help", octave_no_arg, 0, 'h' }, - { "image-path", octave_required_arg, 0, IMAGE_PATH_OPTION }, - { "info-file", octave_required_arg, 0, INFO_FILE_OPTION }, - { "info-program", octave_required_arg, 0, INFO_PROG_OPTION }, - { "interactive", octave_no_arg, 0, 'i' }, - { "jit-compiler", octave_no_arg, 0, JIT_COMPILER_OPTION }, - { "line-editing", octave_no_arg, 0, LINE_EDITING_OPTION }, - { "no-gui", octave_no_arg, 0, NO_GUI_OPTION }, - { "no-history", octave_no_arg, 0, 'H' }, - { "no-init-file", octave_no_arg, 0, NO_INIT_FILE_OPTION }, - { "no-init-path", octave_no_arg, 0, NO_INIT_PATH_OPTION }, - { "no-line-editing", octave_no_arg, 0, NO_LINE_EDITING_OPTION }, - { "no-site-file", octave_no_arg, 0, NO_SITE_FILE_OPTION }, - { "no-window-system", octave_no_arg, 0, 'W' }, - { "norc", octave_no_arg, 0, 'f' }, - { "path", octave_required_arg, 0, 'p' }, - { "persist", octave_no_arg, 0, PERSIST_OPTION }, - { "quiet", octave_no_arg, 0, 'q' }, - { "server", octave_no_arg, 0, SERVER_OPTION }, - { "silent", octave_no_arg, 0, 'q' }, - { "texi-macros-file", octave_required_arg, 0, TEXI_MACROS_FILE_OPTION }, - { "traditional", octave_no_arg, 0, TRADITIONAL_OPTION }, - { "verbose", octave_no_arg, 0, 'V' }, - { "version", octave_no_arg, 0, 'v' }, - { 0, 0, 0, 0 } -}; - -#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC) - // Restore prevailing warning state for remainder of the file. -# pragma GCC diagnostic pop -#endif - -// Usage message with extra help. - -static void -octave_print_verbose_usage_and_exit (void) -{ - std::cout << octave_name_version_copyright_copying_and_warranty () - << "\n\ -\n\ -Usage: octave [options] [FILE]\n\ -\n\ -Options:\n\ -\n\ - --built-in-docstrings-file FILE Use docs for built-ins from FILE.\n\ - --debug, -d Enter parser debugging mode.\n\ - --debug-jit Enable JIT compiler debugging/tracing.\n\ - --doc-cache-file FILE Use doc cache file FILE.\n\ - --echo-commands, -x Echo commands as they are executed.\n\ - --eval CODE Evaluate CODE. Exit when done unless --persist.\n\ - --exec-path PATH Set path for executing subprograms.\n\ - --experimental-terminal-widget\n\ - Use new experimental terminal widget in the GUI.\n\ - --gui Start the graphical user interface.\n\ - --help, -h, Print short help message and exit.\n\ - --image-path PATH Add PATH to head of image search path.\n\ - --info-file FILE Use top-level info file FILE.\n\ - --info-program PROGRAM Use PROGRAM for reading info files.\n\ - --interactive, -i Force interactive behavior.\n\ - --jit-compiler Enable the JIT compiler.\n\ - --line-editing Force readline use for command-line editing.\n\ - --no-gui Disable the graphical user interface.\n\ - --no-history, -H Don't save commands to the history list\n\ - --no-init-file Don't read the ~/.octaverc or .octaverc files.\n\ - --no-init-path Don't initialize function search path.\n\ - --no-line-editing Don't use readline for command-line editing.\n\ - --no-site-file Don't read the site-wide octaverc file.\n\ - --no-window-system, -W Disable window system, including graphics.\n\ - --norc, -f Don't read any initialization files.\n\ - --path PATH, -p PATH Add PATH to head of function search path.\n\ - --persist Go interactive after --eval or reading from FILE.\n\ - --server Enter server mode at startup.\n\ - --silent, --quiet, -q Don't print message at startup.\n\ - --texi-macros-file FILE Use Texinfo macros in FILE for makeinfo command.\n\ - --traditional Set variables for closer MATLAB compatibility.\n\ - --verbose, -V Enable verbose output in some cases.\n\ - --version, -v Print version number and exit.\n\ -\n\ - FILE Execute commands from FILE. Exit when done\n\ - unless --persist is also specified.\n\ -\n" - << octave_www_statement () - << "\n\n" - << octave_contrib_statement () - << "\n\n" - << octave_bugs_statement () - << "\n"; - - exit (0); -} - -// Terse usage message. - -static void -octave_print_terse_usage_and_exit (void) -{ - std::cerr << "\nusage: " << usage_string << "\n\n"; - - exit (1); -} - -static void -octave_print_version_and_exit (void) -{ - std::cout << octave_name_version_copyright_copying_warranty_and_bugs () - << "\n"; - exit (0); -} - -#endif diff -r 3ab696e02f55 -r bc19d9360bac libinterp/options.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/options.h Sun Jul 18 15:54:48 2021 +0200 @@ -0,0 +1,117 @@ +//////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 1993-2021 The Octave Project Developers +// +// See the file COPYRIGHT.md in the top-level directory of this +// distribution or . +// +// This file is part of Octave. +// +// Octave is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Octave is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Octave; see the file COPYING. If not, see +// . +// +//////////////////////////////////////////////////////////////////////// + +#if ! defined (octave_options_h) +#define octave_options_h 1 + +#include "octave-config.h" + +#include + +// #include "version.h" + +// This is here so that it's more likely that the usage message and +// the real set of options will agree. Note: the '+' must come first +// to prevent getopt from permuting arguments! +static const char *short_opts = "+HWVdfhip:qvx"; + + +#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC) + // Disable warning temporarily. +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif + +// Long options. See the comments in getopt.h for the meanings of the +// fields in this structure. +#define BUILT_IN_DOCSTRINGS_FILE_OPTION 1 +#define DOC_CACHE_FILE_OPTION 2 +#define EVAL_OPTION 3 +#define EXEC_PATH_OPTION 4 +#define EXPERIMENTAL_TERMINAL_WIDGET_OPTION 5 +#define GUI_OPTION 6 +#define IMAGE_PATH_OPTION 7 +#define INFO_FILE_OPTION 8 +#define INFO_PROG_OPTION 9 +#define DEBUG_JIT_OPTION 10 +#define JIT_COMPILER_OPTION 11 +#define LINE_EDITING_OPTION 12 +#define NO_GUI_OPTION 13 +#define NO_GUI_LIBS_OPTION 14 +#define NO_INIT_FILE_OPTION 15 +#define NO_INIT_PATH_OPTION 16 +#define NO_LINE_EDITING_OPTION 17 +#define NO_SITE_FILE_OPTION 18 +#define PERSIST_OPTION 19 +#define SERVER_OPTION 20 +#define TEXI_MACROS_FILE_OPTION 21 +#define TRADITIONAL_OPTION 22 +struct octave_getopt_options long_opts[] = +{ + { "braindead", octave_no_arg, 0, TRADITIONAL_OPTION }, + { "built-in-docstrings-file", octave_required_arg, 0, BUILT_IN_DOCSTRINGS_FILE_OPTION }, + { "debug", octave_no_arg, 0, 'd' }, + { "debug-jit", octave_no_arg, 0, DEBUG_JIT_OPTION }, + { "doc-cache-file", octave_required_arg, 0, DOC_CACHE_FILE_OPTION }, + { "echo-commands", octave_no_arg, 0, 'x' }, + { "eval", octave_required_arg, 0, EVAL_OPTION }, + { "exec-path", octave_required_arg, 0, EXEC_PATH_OPTION }, + { "experimental-terminal-widget", octave_no_arg, 0, EXPERIMENTAL_TERMINAL_WIDGET_OPTION }, + { "force-gui", octave_no_arg, 0, GUI_OPTION }, + { "gui", octave_no_arg, 0, GUI_OPTION }, + { "help", octave_no_arg, 0, 'h' }, + { "image-path", octave_required_arg, 0, IMAGE_PATH_OPTION }, + { "info-file", octave_required_arg, 0, INFO_FILE_OPTION }, + { "info-program", octave_required_arg, 0, INFO_PROG_OPTION }, + { "interactive", octave_no_arg, 0, 'i' }, + { "jit-compiler", octave_no_arg, 0, JIT_COMPILER_OPTION }, + { "line-editing", octave_no_arg, 0, LINE_EDITING_OPTION }, + { "no-gui", octave_no_arg, 0, NO_GUI_OPTION }, + { "no-gui-libs", octave_no_arg, 0, NO_GUI_LIBS_OPTION }, + { "no-history", octave_no_arg, 0, 'H' }, + { "no-init-file", octave_no_arg, 0, NO_INIT_FILE_OPTION }, + { "no-init-path", octave_no_arg, 0, NO_INIT_PATH_OPTION }, + { "no-line-editing", octave_no_arg, 0, NO_LINE_EDITING_OPTION }, + { "no-site-file", octave_no_arg, 0, NO_SITE_FILE_OPTION }, + { "no-window-system", octave_no_arg, 0, 'W' }, + { "norc", octave_no_arg, 0, 'f' }, + { "path", octave_required_arg, 0, 'p' }, + { "persist", octave_no_arg, 0, PERSIST_OPTION }, + { "quiet", octave_no_arg, 0, 'q' }, + { "server", octave_no_arg, 0, SERVER_OPTION }, + { "silent", octave_no_arg, 0, 'q' }, + { "texi-macros-file", octave_required_arg, 0, TEXI_MACROS_FILE_OPTION }, + { "traditional", octave_no_arg, 0, TRADITIONAL_OPTION }, + { "verbose", octave_no_arg, 0, 'V' }, + { "version", octave_no_arg, 0, 'v' }, + { 0, 0, 0, 0 } +}; + +#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC) + // Restore prevailing warning state for remainder of the file. +# pragma GCC diagnostic pop +#endif + +#endif diff -r 3ab696e02f55 -r bc19d9360bac libinterp/usage.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/usage.h Sun Jul 18 15:54:48 2021 +0200 @@ -0,0 +1,124 @@ +//////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 1993-2021 The Octave Project Developers +// +// See the file COPYRIGHT.md in the top-level directory of this +// distribution or . +// +// This file is part of Octave. +// +// Octave is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Octave is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Octave; see the file COPYING. If not, see +// . +// +//////////////////////////////////////////////////////////////////////// + +#if ! defined (octave_usage_h) +#define octave_usage_h 1 + +#include "octave-config.h" + +#include + +#include "version.h" + +// Usage message +static const char *usage_string = + "octave [-HVWdfhiqvx] [--debug] [--debug-jit] [--doc-cache-file file]\n\ + [--echo-commands] [--eval CODE] [--exec-path path]\n\ + [--experimental-terminal-widget] [--gui] [--help] [--image-path path]\n\ + [--info-file file] [--info-program prog] [--interactive]\n\ + [--jit-compiler] [--line-editing] [--no-gui] [--no-history]\n\ + [--no-init-file] [--no-init-path] [--no-line-editing]\n\ + [--no-site-file] [--no-window-system] [--norc] [-p path]\n\ + [--path path] [--persist] [--server] [--silent] [--traditional]\n\ + [--verbose] [--version] [file]"; + +// Usage message with extra help. + +static void +octave_print_verbose_usage_and_exit (void) +{ + std::cout << octave_name_version_copyright_copying_and_warranty () + << "\n\ +\n\ +Usage: octave [options] [FILE]\n\ +\n\ +Options:\n\ +\n\ + --built-in-docstrings-file FILE Use docs for built-ins from FILE.\n\ + --debug, -d Enter parser debugging mode.\n\ + --debug-jit Enable JIT compiler debugging/tracing.\n\ + --doc-cache-file FILE Use doc cache file FILE.\n\ + --echo-commands, -x Echo commands as they are executed.\n\ + --eval CODE Evaluate CODE. Exit when done unless --persist.\n\ + --exec-path PATH Set path for executing subprograms.\n\ + --experimental-terminal-widget\n\ + Use new experimental terminal widget in the GUI.\n\ + --gui Start the graphical user interface.\n\ + --help, -h, Print short help message and exit.\n\ + --image-path PATH Add PATH to head of image search path.\n\ + --info-file FILE Use top-level info file FILE.\n\ + --info-program PROGRAM Use PROGRAM for reading info files.\n\ + --interactive, -i Force interactive behavior.\n\ + --jit-compiler Enable the JIT compiler.\n\ + --line-editing Force readline use for command-line editing.\n\ + --no-gui Disable the graphical user interface.\n\ + --no-history, -H Don't save commands to the history list\n\ + --no-init-file Don't read the ~/.octaverc or .octaverc files.\n\ + --no-init-path Don't initialize function search path.\n\ + --no-line-editing Don't use readline for command-line editing.\n\ + --no-site-file Don't read the site-wide octaverc file.\n\ + --no-window-system, -W Disable window system, including graphics.\n\ + --norc, -f Don't read any initialization files.\n\ + --path PATH, -p PATH Add PATH to head of function search path.\n\ + --persist Go interactive after --eval or reading from FILE.\n\ + --server Enter server mode at startup.\n\ + --silent, --quiet, -q Don't print message at startup.\n\ + --texi-macros-file FILE Use Texinfo macros in FILE for makeinfo command.\n\ + --traditional Set variables for closer MATLAB compatibility.\n\ + --verbose, -V Enable verbose output in some cases.\n\ + --version, -v Print version number and exit.\n\ +\n\ + FILE Execute commands from FILE. Exit when done\n\ + unless --persist is also specified.\n\ +\n" + << octave_www_statement () + << "\n\n" + << octave_contrib_statement () + << "\n\n" + << octave_bugs_statement () + << "\n"; + + exit (0); +} + +// Terse usage message. + +static void +octave_print_terse_usage_and_exit (void) +{ + std::cerr << "\nusage: " << usage_string << "\n\n"; + + exit (1); +} + +static void +octave_print_version_and_exit (void) +{ + std::cout << octave_name_version_copyright_copying_warranty_and_bugs () + << "\n"; + exit (0); +} + +#endif diff -r 3ab696e02f55 -r bc19d9360bac src/main.in.cc --- a/src/main.in.cc Fri Jul 16 16:20:23 2021 -0400 +++ b/src/main.in.cc Sun Jul 18 15:54:48 2021 +0200 @@ -54,6 +54,7 @@ #undef OCTAVE_API #define OCTAVE_API #include "fcntl-wrappers.h" +#include "getopt-wrapper.h" #include "signal-wrappers.h" #include "unistd-wrappers.h" #include "wait-wrappers.h" @@ -79,6 +80,7 @@ #endif #include "display-available.h" +#include "options.h" #include "shared-fcns.h" #if defined (HAVE_OCTAVE_QT_GUI) && ! defined (OCTAVE_USE_WINDOWS_API) @@ -270,107 +272,107 @@ // --address-sanitizer option. static char **new_argv = new char * [argc + 2]; + int next_optind = 1; int k = 1; bool warn_display = true; bool no_display = false; - for (int i = 1; i < argc; i++) + while (true) { - if (! strcmp (argv[i], "--no-gui-libs")) - { - // Run the version of Octave that is not linked with any GUI - // libraries. It may not be possible to do plotting or any - // ui* calls, but it will be a little faster to start and - // require less memory. Don't pass the --no-gui-libs option - // on as that option is not recognized by Octave. - - gui_libs = false; - file = octave_cli; - } - else if (! strcmp (argv[i], "--no-gui")) - { - // If we see this option, then we can just exec octave; we - // don't have to create a child process and wait for it to - // exit. But do exec "octave-gui", not "octave-cli", because - // even if the --no-gui option is given, we may be asked to do - // some plotting or ui* calls. + int long_idx; - start_gui = false; - new_argv[k++] = argv[i]; - } - else if (! strcmp (argv[i], "--gui") || ! strcmp (argv[i], "--force-gui")) - { - // If we see this option, then we fork and exec octave with - // the --gui option, while continuing to handle signals in the - // terminal. - // Do not copy the arg now, since we still not know if the - // gui should really be launched. Just store the index. + int optc = octave_getopt_long_wrapper (argc, argv, short_opts, long_opts, + &long_idx); + int old_optind = next_optind; + next_optind = octave_optind_wrapper (); - start_gui = true; - idx_gui = i; - } - else if (! strcmp (argv[i], "--experimental-terminal-widget")) - { - // If we see this option, then we don't fork and exec. + if (optc < 0) + break; - fork_and_exec = false; - new_argv[k++] = argv[i]; - } - else if (! strcmp (argv[i], "--persist")) + switch (optc) { - // FIXME: How can we reliably detect if this option appears - // after a FILE argument. In this case octave ignores - // the option, but the GUI might still be launched if - // --gui is also given. + case NO_GUI_LIBS_OPTION: + // Run the version of Octave that is not linked with any GUI + // libraries. It may not be possible to do plotting or any ui* + // calls, but it will be a little faster to start and require less + // memory. Don't pass the --no-gui-libs option on as that option + // is not recognized by Octave. + gui_libs = false; + file = octave_cli; + break; + + case NO_GUI_OPTION: + // If we see this option, then we can just exec octave; we don't + // have to create a child process and wait for it to exit. But do + // exec "octave-gui", not "octave-cli", because even if the + // --no-gui option is given, we may be asked to do some plotting or + // ui* calls. + start_gui = false; + new_argv[k++] = argv[old_optind]; + break; + + case GUI_OPTION: + // If we see this option, then we fork and exec octave with the + // --gui option, while continuing to handle signals in the + // terminal. + // Do not copy the arg now, since we still not know if the gui + // should really be launched. Just store the index. + start_gui = true; + idx_gui = old_optind; + break; + + case EXPERIMENTAL_TERMINAL_WIDGET_OPTION: + // If we see this option, then we don't fork and exec. + fork_and_exec = false; + new_argv[k++] = argv[old_optind]; + break; - persist_octave = true; - new_argv[k++] = argv[i]; - } - else if (! strcmp (argv[i], "--server")) - { - server = true; - new_argv[k++] = argv[i]; - } - else if (! strcmp (argv[i], "--eval") || - (strlen (argv[i]) > 0 && argv[i][0] != '-')) - { - eval_code = true; - new_argv[k++] = argv[i]; - } - else if (! strcmp (argv[i], "--silent") || ! strcmp (argv[i], "--quiet")) - { - warn_display = false; - new_argv[k++] = argv[i]; + case PERSIST_OPTION: + // FIXME: How can we reliably detect if this option appears after + // a FILE argument. In this case octave ignores the option, + // but the GUI might still be launched if --gui is also + // given. + persist_octave = true; + new_argv[k++] = argv[old_optind]; + break; + + case SERVER_OPTION: + server = true; + new_argv[k++] = argv[old_optind]; + break; + + case EVAL_OPTION: + case 0: + eval_code = true; + for (int i = old_optind; i < next_optind; i++) + new_argv[k++] = argv[i]; + break; + + case 'q': + // options "--silent" or "--quiet" + warn_display = false; + new_argv[k++] = argv[old_optind]; + break; + + case 'W': + // option "--no-window-system" + no_display = true; + new_argv[k++] = argv[old_optind]; + break; + + default: + for (int i = old_optind; i < next_optind; i++) + new_argv[k++] = argv[i]; + break; } - else if (! strcmp (argv[i], "--no-window-system")) - { - no_display = true; - new_argv[k++] = argv[i]; - } - else if (strlen (argv[i]) > 1 && argv[i][0] == '-' && argv[i][1] != '-') - { - // Handle all single-letter command line options here; they may - // occur alone or may be aggregated into a single argument. - - std::size_t len = strlen (argv[i]); + } - for (std::size_t j = 1; j < len; j++) - switch (argv[i][j]) - { - case 'W': - no_display = true; - break; - case 'q': - warn_display = false; - break; - default: - break; - } - - new_argv[k++] = argv[i]; - } - else + // Tread trailing arguments as commands to be executed + if (next_optind < argc) + { + eval_code = true; + for (int i = next_optind; i < argc; i++) new_argv[k++] = argv[i]; }