changeset 29890:bc19d9360bac

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.
author Markus Mützel <markus.muetzel@gmx.de>
date Sun, 18 Jul 2021 15:54:48 +0200
parents 3ab696e02f55
children 7f22f024afdf
files libinterp/module.mk libinterp/octave.cc libinterp/octave.h libinterp/options-usage.h libinterp/options.h libinterp/usage.h src/main.in.cc
diffstat 7 files changed, 336 insertions(+), 294 deletions(-) [+]
line wrap: on
line diff
--- 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 += \
--- 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
 {
--- 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
   {
--- 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 <https://octave.org/copyright/>.
-//
-// 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
-// <https://www.gnu.org/licenses/>.
-//
-////////////////////////////////////////////////////////////////////////
-
-#if ! defined (octave_options_usage_h)
-#define octave_options_usage_h 1
-
-#include "octave-config.h"
-
-#include <iosfwd>
-
-#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
--- /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 <https://octave.org/copyright/>.
+//
+// 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
+// <https://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////
+
+#if ! defined (octave_options_h)
+#define octave_options_h 1
+
+#include "octave-config.h"
+
+#include <iosfwd>
+
+// #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
--- /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 <https://octave.org/copyright/>.
+//
+// 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
+// <https://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////
+
+#if ! defined (octave_usage_h)
+#define octave_usage_h 1
+
+#include "octave-config.h"
+
+#include <iosfwd>
+
+#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
--- 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];
     }