comparison src/main.in.cc @ 29898:dffd1c943f1a stable

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. (grafted from bc19d9360bace492accb86414badda5ab9ba8cde)
author Markus Mützel <markus.muetzel@gmx.de>
date Sun, 18 Jul 2021 15:54:48 +0200
parents d13d090cb03a
children 853e4b7ae0d5 3583b11e151b
comparison
equal deleted inserted replaced
29883:0f6dc48a740e 29898:dffd1c943f1a
42 #include <algorithm> 42 #include <algorithm>
43 #include <iostream> 43 #include <iostream>
44 #include <string> 44 #include <string>
45 45
46 #include "fcntl-wrappers.h" 46 #include "fcntl-wrappers.h"
47 #include "getopt-wrapper.h"
47 #include "signal-wrappers.h" 48 #include "signal-wrappers.h"
48 #include "unistd-wrappers.h" 49 #include "unistd-wrappers.h"
49 #include "wait-wrappers.h" 50 #include "wait-wrappers.h"
50 51
51 #if ! defined (OCTAVE_VERSION) 52 #if ! defined (OCTAVE_VERSION)
67 #if ! defined (OCTAVE_EXEC_PREFIX) 68 #if ! defined (OCTAVE_EXEC_PREFIX)
68 # define OCTAVE_EXEC_PREFIX %OCTAVE_EXEC_PREFIX% 69 # define OCTAVE_EXEC_PREFIX %OCTAVE_EXEC_PREFIX%
69 #endif 70 #endif
70 71
71 #include "display-available.h" 72 #include "display-available.h"
73 #include "options.h"
72 #include "shared-fcns.h" 74 #include "shared-fcns.h"
73 75
74 #if defined (HAVE_OCTAVE_QT_GUI) && ! defined (OCTAVE_USE_WINDOWS_API) 76 #if defined (HAVE_OCTAVE_QT_GUI) && ! defined (OCTAVE_USE_WINDOWS_API)
75 77
76 // Forward signals to the GUI process. 78 // Forward signals to the GUI process.
235 237
236 // Declaring new_argv static avoids leak warnings when using GCC's 238 // Declaring new_argv static avoids leak warnings when using GCC's
237 // --address-sanitizer option. 239 // --address-sanitizer option.
238 static char **new_argv = new char * [argc + 2]; 240 static char **new_argv = new char * [argc + 2];
239 241
242 int next_optind = 1;
240 int k = 1; 243 int k = 1;
241 244
242 bool warn_display = true; 245 bool warn_display = true;
243 bool no_display = false; 246 bool no_display = false;
244 247
245 for (int i = 1; i < argc; i++) 248 while (true)
246 { 249 {
247 if (! strcmp (argv[i], "--no-gui-libs")) 250 int long_idx;
251
252 int optc = octave_getopt_long_wrapper (argc, argv, short_opts, long_opts,
253 &long_idx);
254 int old_optind = next_optind;
255 next_optind = octave_optind_wrapper ();
256
257 if (optc < 0)
258 break;
259
260 switch (optc)
248 { 261 {
249 // Run the version of Octave that is not linked with any GUI 262 case NO_GUI_LIBS_OPTION:
250 // libraries. It may not be possible to do plotting or any 263 // Run the version of Octave that is not linked with any GUI
251 // ui* calls, but it will be a little faster to start and 264 // libraries. It may not be possible to do plotting or any ui*
252 // require less memory. Don't pass the --no-gui-libs option 265 // calls, but it will be a little faster to start and require less
253 // on as that option is not recognized by Octave. 266 // memory. Don't pass the --no-gui-libs option on as that option
254 267 // is not recognized by Octave.
255 gui_libs = false; 268 gui_libs = false;
256 file = octave_cli; 269 file = octave_cli;
270 break;
271
272 case NO_GUI_OPTION:
273 // If we see this option, then we can just exec octave; we don't
274 // have to create a child process and wait for it to exit. But do
275 // exec "octave-gui", not "octave-cli", because even if the
276 // --no-gui option is given, we may be asked to do some plotting or
277 // ui* calls.
278 start_gui = false;
279 new_argv[k++] = argv[old_optind];
280 break;
281
282 case GUI_OPTION:
283 // If we see this option, then we fork and exec octave with the
284 // --gui option, while continuing to handle signals in the
285 // terminal.
286 // Do not copy the arg now, since we still not know if the gui
287 // should really be launched. Just store the index.
288 start_gui = true;
289 idx_gui = old_optind;
290 break;
291
292
293 case PERSIST_OPTION:
294 // FIXME: How can we reliably detect if this option appears after
295 // a FILE argument. In this case octave ignores the option,
296 // but the GUI might still be launched if --gui is also
297 // given.
298 persist_octave = true;
299 new_argv[k++] = argv[old_optind];
300 break;
301
302 case EVAL_OPTION:
303 case 0:
304 eval_code = true;
305 for (int i = old_optind; i < next_optind; i++)
306 new_argv[k++] = argv[i];
307 break;
308
309 case 'q':
310 // options "--silent" or "--quiet"
311 warn_display = false;
312 new_argv[k++] = argv[old_optind];
313 break;
314
315 case 'W':
316 // option "--no-window-system"
317 no_display = true;
318 new_argv[k++] = argv[old_optind];
319 break;
320
321 default:
322 for (int i = old_optind; i < next_optind; i++)
323 new_argv[k++] = argv[i];
324 break;
257 } 325 }
258 else if (! strcmp (argv[i], "--no-gui")) 326 }
259 { 327
260 // If we see this option, then we can just exec octave; we 328 // Tread trailing arguments as commands to be executed
261 // don't have to create a child process and wait for it to 329 if (next_optind < argc)
262 // exit. But do exec "octave-gui", not "octave-cli", because 330 {
263 // even if the --no-gui option is given, we may be asked to do 331 eval_code = true;
264 // some plotting or ui* calls. 332 for (int i = next_optind; i < argc; i++)
265
266 start_gui = false;
267 new_argv[k++] = argv[i];
268 }
269 else if (! strcmp (argv[i], "--gui") || ! strcmp (argv[i], "--force-gui"))
270 {
271 // If we see this option, then we fork and exec octave with
272 // the --gui option, while continuing to handle signals in the
273 // terminal.
274 // Do not copy the arg now, since we still not know if the
275 // gui should really be launched. Just store the index.
276
277 start_gui = true;
278 idx_gui = i;
279 }
280 else if (! strcmp (argv[i], "--persist"))
281 {
282 // FIXME: How can we reliably detect if this option appears
283 // after a FILE argument. In this case octave ignores
284 // the option, but the GUI might still be launched if
285 // --gui is also given.
286
287 persist_octave = true;
288 new_argv[k++] = argv[i];
289 }
290 else if (! strcmp (argv[i], "--eval") ||
291 (strlen (argv[i]) > 0 && argv[i][0] != '-'))
292 {
293 eval_code = true;
294 new_argv[k++] = argv[i];
295 }
296 else if (! strcmp (argv[i], "--silent") || ! strcmp (argv[i], "--quiet"))
297 {
298 warn_display = false;
299 new_argv[k++] = argv[i];
300 }
301 else if (! strcmp (argv[i], "--no-window-system"))
302 {
303 no_display = true;
304 new_argv[k++] = argv[i];
305 }
306 else if (strlen (argv[i]) > 1 && argv[i][0] == '-' && argv[i][1] != '-')
307 {
308 // Handle all single-letter command line options here; they may
309 // occur alone or may be aggregated into a single argument.
310
311 std::size_t len = strlen (argv[i]);
312
313 for (std::size_t j = 1; j < len; j++)
314 switch (argv[i][j])
315 {
316 case 'W':
317 no_display = true;
318 break;
319 case 'q':
320 warn_display = false;
321 break;
322 default:
323 break;
324 }
325
326 new_argv[k++] = argv[i];
327 }
328 else
329 new_argv[k++] = argv[i]; 333 new_argv[k++] = argv[i];
330 } 334 }
331 335
332 if (start_gui && eval_code && ! persist_octave) 336 if (start_gui && eval_code && ! persist_octave)
333 start_gui = false; 337 start_gui = false;