xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/maint-test-options.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
17d62b00eSchristos /* Maintenance commands for testing the options framework.
27d62b00eSchristos 
3*6881a400Schristos    Copyright (C) 2019-2023 Free Software Foundation, Inc.
47d62b00eSchristos 
57d62b00eSchristos    This file is part of GDB.
67d62b00eSchristos 
77d62b00eSchristos    This program is free software; you can redistribute it and/or modify
87d62b00eSchristos    it under the terms of the GNU General Public License as published by
97d62b00eSchristos    the Free Software Foundation; either version 3 of the License, or
107d62b00eSchristos    (at your option) any later version.
117d62b00eSchristos 
127d62b00eSchristos    This program is distributed in the hope that it will be useful,
137d62b00eSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
147d62b00eSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
157d62b00eSchristos    GNU General Public License for more details.
167d62b00eSchristos 
177d62b00eSchristos    You should have received a copy of the GNU General Public License
187d62b00eSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
197d62b00eSchristos 
207d62b00eSchristos #include "defs.h"
217d62b00eSchristos #include "gdbcmd.h"
227d62b00eSchristos #include "cli/cli-option.h"
237d62b00eSchristos 
247d62b00eSchristos /* This file defines three "maintenance test-options" subcommands to
257d62b00eSchristos    exercise TAB-completion and option processing:
267d62b00eSchristos 
277d62b00eSchristos     (gdb) maint test-options require-delimiter
287d62b00eSchristos     (gdb) maint test-options unknown-is-error
297d62b00eSchristos     (gdb) maint test-options unknown-is-operand
307d62b00eSchristos 
317d62b00eSchristos    And a fourth one to help with TAB-completion testing.
327d62b00eSchristos 
337d62b00eSchristos     (gdb) maint show test-options-completion-result
347d62b00eSchristos 
357d62b00eSchristos    Each of the test-options subcommands exercise
367d62b00eSchristos    gdb::option::process_options with a different enum
377d62b00eSchristos    process_options_mode value.  Examples for commands they model:
387d62b00eSchristos 
397d62b00eSchristos    - "print" and "compile print", are like "require-delimiter",
407d62b00eSchristos       because they accept random expressions as argument.
417d62b00eSchristos 
427d62b00eSchristos    - "backtrace" and "frame/thread apply" are like
437d62b00eSchristos      "unknown-is-operand", because "-" is a valid command.
447d62b00eSchristos 
457d62b00eSchristos    - "compile file" and "compile code" are like "unknown-is-error".
467d62b00eSchristos 
477d62b00eSchristos    These commands allow exercising all aspects of option processing
487d62b00eSchristos    without having to pick some existing command.  That should be more
497d62b00eSchristos    stable going forward than relying on an existing user command,
507d62b00eSchristos    since if we picked say "print", that command or its options could
517d62b00eSchristos    change in future, and then we'd be left with having to pick some
527d62b00eSchristos    other command or option to exercise some non-command-specific
537d62b00eSchristos    option processing detail.  Also, actual user commands have side
547d62b00eSchristos    effects that we're not interested in when we're focusing on unit
557d62b00eSchristos    testing the options machinery.  BTW, a maintenance command is used
567d62b00eSchristos    as a sort of unit test driver instead of actual "maint selftest"
577d62b00eSchristos    unit tests, since we need to go all the way via gdb including
587d62b00eSchristos    readline, for proper testing of TAB completion.
597d62b00eSchristos 
607d62b00eSchristos    These maintenance commands support options of all the different
617d62b00eSchristos    available kinds of commands (boolean, enum, flag, string, uinteger):
627d62b00eSchristos 
637d62b00eSchristos     (gdb) maint test-options require-delimiter -[TAB]
647d62b00eSchristos     -bool      -enum      -flag      -string     -uinteger   -xx1       -xx2
657d62b00eSchristos 
667d62b00eSchristos     (gdb) maint test-options require-delimiter -bool o[TAB]
677d62b00eSchristos     off  on
687d62b00eSchristos     (gdb) maint test-options require-delimiter -enum [TAB]
697d62b00eSchristos     xxx  yyy  zzz
707d62b00eSchristos     (gdb) maint test-options require-delimiter -uinteger [TAB]
717d62b00eSchristos     NUMBER     unlimited
727d62b00eSchristos 
737d62b00eSchristos    '-xx1' and '-xx2' are flag options too.  They exist in order to
747d62b00eSchristos    test ambiguous option names, like '-xx'.
757d62b00eSchristos 
767d62b00eSchristos   Invoking the commands makes them print out the options parsed:
777d62b00eSchristos 
787d62b00eSchristos    (gdb) maint test-options unknown-is-error -flag -enum yyy cmdarg
797d62b00eSchristos    -flag 1 -xx1 0 -xx2 0 -bool 0 -enum yyy -uint 0 -zuint-unl 0 -- cmdarg
807d62b00eSchristos 
817d62b00eSchristos    (gdb) maint test-options require-delimiter -flag -enum yyy cmdarg
827d62b00eSchristos    -flag 0 -xx1 0 -xx2 0 -bool 0 -enum xxx -uint 0  -zuint-unl 0 -- -flag -enum yyy cmdarg
837d62b00eSchristos    (gdb) maint test-options require-delimiter -flag -enum yyy cmdarg --
847d62b00eSchristos    Unrecognized option at: cmdarg --
857d62b00eSchristos    (gdb) maint test-options require-delimiter -flag -enum yyy -- cmdarg
867d62b00eSchristos    -flag 1 -xx1 0 -xx2 0 -bool 0 -enum yyy -uint 0 -zuint-unl 0 -- cmdarg
877d62b00eSchristos 
887d62b00eSchristos   The "maint show test-options-completion-result" command exists in
897d62b00eSchristos   order to do something similar for completion:
907d62b00eSchristos 
917d62b00eSchristos    (gdb) maint test-options unknown-is-error -flag -b 0 -enum yyy OPERAND[TAB]
927d62b00eSchristos    (gdb) maint show test-options-completion-result
937d62b00eSchristos    0 OPERAND
947d62b00eSchristos 
957d62b00eSchristos    (gdb) maint test-options unknown-is-error -flag -b 0 -enum yyy[TAB]
967d62b00eSchristos    (gdb) maint show test-options-completion-result
977d62b00eSchristos    1
987d62b00eSchristos 
997d62b00eSchristos    (gdb) maint test-options require-dash -unknown[TAB]
1007d62b00eSchristos    (gdb) maint show test-options-completion-result
1017d62b00eSchristos    1
1027d62b00eSchristos 
1037d62b00eSchristos   Here, "1" means the completion function processed the whole input
1047d62b00eSchristos   line, and that the command shouldn't do anything with the arguments,
1057d62b00eSchristos   since there are no operands.  While "0" indicates that there are
1067d62b00eSchristos   operands after options.  The text after "0" is the operands.
1077d62b00eSchristos 
1087d62b00eSchristos   This level of detail is particularly important because getting the
1097d62b00eSchristos   completion function's entry point to return back to the caller the
1107d62b00eSchristos   right pointer into the operand is quite tricky in several
1117d62b00eSchristos   scenarios.  */
1127d62b00eSchristos 
1137d62b00eSchristos /* Enum values for the "maintenance test-options" commands.  */
1147d62b00eSchristos const char test_options_enum_values_xxx[] = "xxx";
1157d62b00eSchristos const char test_options_enum_values_yyy[] = "yyy";
1167d62b00eSchristos const char test_options_enum_values_zzz[] = "zzz";
1177d62b00eSchristos static const char *const test_options_enum_values_choices[] =
1187d62b00eSchristos {
1197d62b00eSchristos   test_options_enum_values_xxx,
1207d62b00eSchristos   test_options_enum_values_yyy,
1217d62b00eSchristos   test_options_enum_values_zzz,
1227d62b00eSchristos   NULL
1237d62b00eSchristos };
1247d62b00eSchristos 
1257d62b00eSchristos /* Option data for the "maintenance test-options" commands.  */
1267d62b00eSchristos 
1277d62b00eSchristos struct test_options_opts
1287d62b00eSchristos {
1297d62b00eSchristos   bool flag_opt = false;
1307d62b00eSchristos   bool xx1_opt = false;
1317d62b00eSchristos   bool xx2_opt = false;
1327d62b00eSchristos   bool boolean_opt = false;
1337d62b00eSchristos   const char *enum_opt = test_options_enum_values_xxx;
1347d62b00eSchristos   unsigned int uint_opt = 0;
1357d62b00eSchristos   int zuint_unl_opt = 0;
136*6881a400Schristos   std::string string_opt;
1377d62b00eSchristos 
1387d62b00eSchristos   test_options_opts () = default;
1397d62b00eSchristos 
1407d62b00eSchristos   DISABLE_COPY_AND_ASSIGN (test_options_opts);
1417d62b00eSchristos 
1427d62b00eSchristos   /* Dump the options to FILE.  ARGS is the remainder unprocessed
1437d62b00eSchristos      arguments.  */
1447d62b00eSchristos   void dump (ui_file *file, const char *args) const
1457d62b00eSchristos   {
146*6881a400Schristos     gdb_printf (file,
1477d62b00eSchristos 		_("-flag %d -xx1 %d -xx2 %d -bool %d "
1487d62b00eSchristos 		  "-enum %s -uint %s -zuint-unl %s -string '%s' -- %s\n"),
1497d62b00eSchristos 		flag_opt,
1507d62b00eSchristos 		xx1_opt,
1517d62b00eSchristos 		xx2_opt,
1527d62b00eSchristos 		boolean_opt,
1537d62b00eSchristos 		enum_opt,
1547d62b00eSchristos 		(uint_opt == UINT_MAX
1557d62b00eSchristos 		 ? "unlimited"
1567d62b00eSchristos 		 : pulongest (uint_opt)),
1577d62b00eSchristos 		(zuint_unl_opt == -1
1587d62b00eSchristos 		 ? "unlimited"
1597d62b00eSchristos 		 : plongest (zuint_unl_opt)),
160*6881a400Schristos 		string_opt.c_str (),
1617d62b00eSchristos 		args);
1627d62b00eSchristos   }
1637d62b00eSchristos };
1647d62b00eSchristos 
1657d62b00eSchristos /* Option definitions for the "maintenance test-options" commands.  */
1667d62b00eSchristos 
1677d62b00eSchristos static const gdb::option::option_def test_options_option_defs[] = {
1687d62b00eSchristos 
1697d62b00eSchristos   /* A flag option.  */
1707d62b00eSchristos   gdb::option::flag_option_def<test_options_opts> {
1717d62b00eSchristos     "flag",
1727d62b00eSchristos     [] (test_options_opts *opts) { return &opts->flag_opt; },
1737d62b00eSchristos     N_("A flag option."),
1747d62b00eSchristos   },
1757d62b00eSchristos 
1767d62b00eSchristos   /* A couple flags with similar names, for "ambiguous option names"
1777d62b00eSchristos      testing.  */
1787d62b00eSchristos   gdb::option::flag_option_def<test_options_opts> {
1797d62b00eSchristos     "xx1",
1807d62b00eSchristos     [] (test_options_opts *opts) { return &opts->xx1_opt; },
1817d62b00eSchristos     N_("A flag option."),
1827d62b00eSchristos   },
1837d62b00eSchristos   gdb::option::flag_option_def<test_options_opts> {
1847d62b00eSchristos     "xx2",
1857d62b00eSchristos     [] (test_options_opts *opts) { return &opts->xx2_opt; },
1867d62b00eSchristos     N_("A flag option."),
1877d62b00eSchristos   },
1887d62b00eSchristos 
1897d62b00eSchristos   /* A boolean option.  */
1907d62b00eSchristos   gdb::option::boolean_option_def<test_options_opts> {
1917d62b00eSchristos     "bool",
1927d62b00eSchristos     [] (test_options_opts *opts) { return &opts->boolean_opt; },
1937d62b00eSchristos     nullptr, /* show_cmd_cb */
1947d62b00eSchristos     N_("A boolean option."),
1957d62b00eSchristos   },
1967d62b00eSchristos 
1977d62b00eSchristos   /* An enum option.  */
1987d62b00eSchristos   gdb::option::enum_option_def<test_options_opts> {
1997d62b00eSchristos     "enum",
2007d62b00eSchristos     test_options_enum_values_choices,
2017d62b00eSchristos     [] (test_options_opts *opts) { return &opts->enum_opt; },
2027d62b00eSchristos     nullptr, /* show_cmd_cb */
2037d62b00eSchristos     N_("An enum option."),
2047d62b00eSchristos   },
2057d62b00eSchristos 
2067d62b00eSchristos   /* A uinteger option.  */
2077d62b00eSchristos   gdb::option::uinteger_option_def<test_options_opts> {
2087d62b00eSchristos     "uinteger",
2097d62b00eSchristos     [] (test_options_opts *opts) { return &opts->uint_opt; },
2107d62b00eSchristos     nullptr, /* show_cmd_cb */
2117d62b00eSchristos     N_("A uinteger option."),
2127d62b00eSchristos     nullptr, /* show_doc */
2137d62b00eSchristos     N_("A help doc that spawns\nmultiple lines."),
2147d62b00eSchristos   },
2157d62b00eSchristos 
2167d62b00eSchristos   /* A zuinteger_unlimited option.  */
2177d62b00eSchristos   gdb::option::zuinteger_unlimited_option_def<test_options_opts> {
2187d62b00eSchristos     "zuinteger-unlimited",
2197d62b00eSchristos     [] (test_options_opts *opts) { return &opts->zuint_unl_opt; },
2207d62b00eSchristos     nullptr, /* show_cmd_cb */
2217d62b00eSchristos     N_("A zuinteger-unlimited option."),
2227d62b00eSchristos     nullptr, /* show_doc */
2237d62b00eSchristos     nullptr, /* help_doc */
2247d62b00eSchristos   },
2257d62b00eSchristos 
2267d62b00eSchristos   /* A string option.  */
2277d62b00eSchristos   gdb::option::string_option_def<test_options_opts> {
2287d62b00eSchristos     "string",
2297d62b00eSchristos     [] (test_options_opts *opts) { return &opts->string_opt; },
2307d62b00eSchristos     nullptr, /* show_cmd_cb */
2317d62b00eSchristos     N_("A string option."),
2327d62b00eSchristos   },
2337d62b00eSchristos };
2347d62b00eSchristos 
2357d62b00eSchristos /* Create an option_def_group for the test_options_opts options, with
2367d62b00eSchristos    OPTS as context.  */
2377d62b00eSchristos 
2387d62b00eSchristos static inline gdb::option::option_def_group
2397d62b00eSchristos make_test_options_options_def_group (test_options_opts *opts)
2407d62b00eSchristos {
2417d62b00eSchristos   return {{test_options_option_defs}, opts};
2427d62b00eSchristos }
2437d62b00eSchristos 
2447d62b00eSchristos /* Implementation of the "maintenance test-options
2457d62b00eSchristos    require-delimiter/unknown-is-error/unknown-is-operand" commands.
2467d62b00eSchristos    Each of the commands maps to a different enum process_options_mode
2477d62b00eSchristos    enumerator.  The test strategy is simply processing the options in
2487d62b00eSchristos    a number of scenarios, and printing back the parsed result.  */
2497d62b00eSchristos 
2507d62b00eSchristos static void
2517d62b00eSchristos maintenance_test_options_command_mode (const char *args,
2527d62b00eSchristos 				       gdb::option::process_options_mode mode)
2537d62b00eSchristos {
2547d62b00eSchristos   test_options_opts opts;
2557d62b00eSchristos 
2567d62b00eSchristos   gdb::option::process_options (&args, mode,
2577d62b00eSchristos 				make_test_options_options_def_group (&opts));
2587d62b00eSchristos 
2597d62b00eSchristos   if (args == nullptr)
2607d62b00eSchristos     args = "";
2617d62b00eSchristos   else
2627d62b00eSchristos     args = skip_spaces (args);
2637d62b00eSchristos 
2647d62b00eSchristos   opts.dump (gdb_stdout, args);
2657d62b00eSchristos }
2667d62b00eSchristos 
2677d62b00eSchristos /* Variable used by the "maintenance show
2687d62b00eSchristos    test-options-completion-result" command.  This variable is stored
2697d62b00eSchristos    by the completer of the "maint test-options" subcommands.
2707d62b00eSchristos 
2717d62b00eSchristos    If the completer returned false, this includes the text at the word
2727d62b00eSchristos    point after gdb::option::complete_options returns.  If true, then
2737d62b00eSchristos    this includes a dump of the processed options.  */
2747d62b00eSchristos static std::string maintenance_test_options_command_completion_text;
2757d62b00eSchristos 
2767d62b00eSchristos /* The "maintenance show test-options-completion-result" command.  */
2777d62b00eSchristos 
2787d62b00eSchristos static void
2797d62b00eSchristos maintenance_show_test_options_completion_result (const char *args,
2807d62b00eSchristos 						 int from_tty)
2817d62b00eSchristos {
282*6881a400Schristos   gdb_puts (maintenance_test_options_command_completion_text.c_str ());
2837d62b00eSchristos }
2847d62b00eSchristos 
2857d62b00eSchristos /* Save the completion result in the global variables read by the
2867d62b00eSchristos    "maintenance test-options require-delimiter" command.  */
2877d62b00eSchristos 
2887d62b00eSchristos static void
2897d62b00eSchristos save_completion_result (const test_options_opts &opts, bool res,
2907d62b00eSchristos 			const char *text)
2917d62b00eSchristos {
2927d62b00eSchristos   if (res)
2937d62b00eSchristos     {
2947d62b00eSchristos       string_file stream;
2957d62b00eSchristos 
2967d62b00eSchristos       stream.puts ("1 ");
2977d62b00eSchristos       opts.dump (&stream, text);
298*6881a400Schristos       maintenance_test_options_command_completion_text = stream.release ();
2997d62b00eSchristos     }
3007d62b00eSchristos   else
3017d62b00eSchristos     {
3027d62b00eSchristos       maintenance_test_options_command_completion_text
3037d62b00eSchristos 	= string_printf ("0 %s\n", text);
3047d62b00eSchristos     }
3057d62b00eSchristos }
3067d62b00eSchristos 
3077d62b00eSchristos /* Implementation of completer for the "maintenance test-options
3087d62b00eSchristos    require-delimiter/unknown-is-error/unknown-is-operand" commands.
3097d62b00eSchristos    Each of the commands maps to a different enum process_options_mode
3107d62b00eSchristos    enumerator.  */
3117d62b00eSchristos 
3127d62b00eSchristos static void
3137d62b00eSchristos maintenance_test_options_completer_mode (completion_tracker &tracker,
3147d62b00eSchristos 					 const char *text,
3157d62b00eSchristos 					 gdb::option::process_options_mode mode)
3167d62b00eSchristos {
3177d62b00eSchristos   test_options_opts opts;
3187d62b00eSchristos 
3197d62b00eSchristos   try
3207d62b00eSchristos     {
3217d62b00eSchristos       bool res = (gdb::option::complete_options
3227d62b00eSchristos 		  (tracker, &text, mode,
3237d62b00eSchristos 		   make_test_options_options_def_group (&opts)));
3247d62b00eSchristos 
3257d62b00eSchristos       save_completion_result (opts, res, text);
3267d62b00eSchristos     }
3277d62b00eSchristos   catch (const gdb_exception_error &ex)
3287d62b00eSchristos     {
3297d62b00eSchristos       save_completion_result (opts, true, text);
3307d62b00eSchristos       throw;
3317d62b00eSchristos     }
3327d62b00eSchristos }
3337d62b00eSchristos 
3347d62b00eSchristos /* Implementation of the "maintenance test-options require-delimiter"
3357d62b00eSchristos    command.  */
3367d62b00eSchristos 
3377d62b00eSchristos static void
3387d62b00eSchristos maintenance_test_options_require_delimiter_command (const char *args,
3397d62b00eSchristos 						    int from_tty)
3407d62b00eSchristos {
3417d62b00eSchristos   maintenance_test_options_command_mode
3427d62b00eSchristos     (args, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER);
3437d62b00eSchristos }
3447d62b00eSchristos 
3457d62b00eSchristos /* Implementation of the "maintenance test-options
3467d62b00eSchristos    unknown-is-error" command.  */
3477d62b00eSchristos 
3487d62b00eSchristos static void
3497d62b00eSchristos maintenance_test_options_unknown_is_error_command (const char *args,
3507d62b00eSchristos 						   int from_tty)
3517d62b00eSchristos {
3527d62b00eSchristos   maintenance_test_options_command_mode
3537d62b00eSchristos     (args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR);
3547d62b00eSchristos }
3557d62b00eSchristos 
3567d62b00eSchristos /* Implementation of the "maintenance test-options
3577d62b00eSchristos    unknown-is-operand" command.  */
3587d62b00eSchristos 
3597d62b00eSchristos static void
3607d62b00eSchristos maintenance_test_options_unknown_is_operand_command (const char *args,
3617d62b00eSchristos 						     int from_tty)
3627d62b00eSchristos {
3637d62b00eSchristos   maintenance_test_options_command_mode
3647d62b00eSchristos     (args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND);
3657d62b00eSchristos }
3667d62b00eSchristos 
3677d62b00eSchristos /* Completer for the "maintenance test-options require-delimiter"
3687d62b00eSchristos    command.  */
3697d62b00eSchristos 
3707d62b00eSchristos static void
3717d62b00eSchristos maintenance_test_options_require_delimiter_command_completer
3727d62b00eSchristos   (cmd_list_element *ignore, completion_tracker &tracker,
3737d62b00eSchristos    const char *text, const char *word)
3747d62b00eSchristos {
3757d62b00eSchristos   maintenance_test_options_completer_mode
3767d62b00eSchristos     (tracker, text, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER);
3777d62b00eSchristos }
3787d62b00eSchristos 
3797d62b00eSchristos /* Completer for the "maintenance test-options unknown-is-error"
3807d62b00eSchristos    command.  */
3817d62b00eSchristos 
3827d62b00eSchristos static void
3837d62b00eSchristos maintenance_test_options_unknown_is_error_command_completer
3847d62b00eSchristos   (cmd_list_element *ignore, completion_tracker &tracker,
3857d62b00eSchristos    const char *text, const char *word)
3867d62b00eSchristos {
3877d62b00eSchristos   maintenance_test_options_completer_mode
3887d62b00eSchristos     (tracker, text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR);
3897d62b00eSchristos }
3907d62b00eSchristos 
3917d62b00eSchristos /* Completer for the "maintenance test-options unknown-is-operand"
3927d62b00eSchristos    command.  */
3937d62b00eSchristos 
3947d62b00eSchristos static void
3957d62b00eSchristos maintenance_test_options_unknown_is_operand_command_completer
3967d62b00eSchristos   (cmd_list_element *ignore, completion_tracker &tracker,
3977d62b00eSchristos    const char *text, const char *word)
3987d62b00eSchristos {
3997d62b00eSchristos   maintenance_test_options_completer_mode
4007d62b00eSchristos     (tracker, text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND);
4017d62b00eSchristos }
4027d62b00eSchristos 
4037d62b00eSchristos /* Command list for maint test-options.  */
404*6881a400Schristos static cmd_list_element *maintenance_test_options_list;
4057d62b00eSchristos 
4067d62b00eSchristos 
4077d62b00eSchristos void _initialize_maint_test_options ();
4087d62b00eSchristos void
4097d62b00eSchristos _initialize_maint_test_options ()
4107d62b00eSchristos {
4117d62b00eSchristos   cmd_list_element *cmd;
4127d62b00eSchristos 
4137d62b00eSchristos   add_basic_prefix_cmd ("test-options", no_class,
4147d62b00eSchristos 			_("\
4157d62b00eSchristos Generic command for testing the options infrastructure."),
4167d62b00eSchristos 			&maintenance_test_options_list,
417*6881a400Schristos 			0, &maintenancelist);
4187d62b00eSchristos 
4197d62b00eSchristos   const auto def_group = make_test_options_options_def_group (nullptr);
4207d62b00eSchristos 
4217d62b00eSchristos   static const std::string help_require_delim_str
4227d62b00eSchristos     = gdb::option::build_help (_("\
4237d62b00eSchristos Command used for testing options processing.\n\
4247d62b00eSchristos Usage: maint test-options require-delimiter [[OPTION]... --] [OPERAND]...\n\
4257d62b00eSchristos \n\
4267d62b00eSchristos Options:\n\
4277d62b00eSchristos %OPTIONS%\n\
4287d62b00eSchristos \n\
4297d62b00eSchristos If you specify any command option, you must use a double dash (\"--\")\n\
4307d62b00eSchristos to mark the end of option processing."),
4317d62b00eSchristos 			       def_group);
4327d62b00eSchristos 
4337d62b00eSchristos   static const std::string help_unknown_is_error_str
4347d62b00eSchristos     = gdb::option::build_help (_("\
4357d62b00eSchristos Command used for testing options processing.\n\
4367d62b00eSchristos Usage: maint test-options unknown-is-error [OPTION]... [OPERAND]...\n\
4377d62b00eSchristos \n\
4387d62b00eSchristos Options:\n\
4397d62b00eSchristos %OPTIONS%"),
4407d62b00eSchristos 			       def_group);
4417d62b00eSchristos 
4427d62b00eSchristos   static const std::string help_unknown_is_operand_str
4437d62b00eSchristos     = gdb::option::build_help (_("\
4447d62b00eSchristos Command used for testing options processing.\n\
4457d62b00eSchristos Usage: maint test-options unknown-is-operand [OPTION]... [OPERAND]...\n\
4467d62b00eSchristos \n\
4477d62b00eSchristos Options:\n\
4487d62b00eSchristos %OPTIONS%"),
4497d62b00eSchristos 			       def_group);
4507d62b00eSchristos 
4517d62b00eSchristos   cmd = add_cmd ("require-delimiter", class_maintenance,
4527d62b00eSchristos 		 maintenance_test_options_require_delimiter_command,
4537d62b00eSchristos 		 help_require_delim_str.c_str (),
4547d62b00eSchristos 		 &maintenance_test_options_list);
4557d62b00eSchristos   set_cmd_completer_handle_brkchars
4567d62b00eSchristos     (cmd, maintenance_test_options_require_delimiter_command_completer);
4577d62b00eSchristos 
4587d62b00eSchristos   cmd = add_cmd ("unknown-is-error", class_maintenance,
4597d62b00eSchristos 		 maintenance_test_options_unknown_is_error_command,
4607d62b00eSchristos 		 help_unknown_is_error_str.c_str (),
4617d62b00eSchristos 		 &maintenance_test_options_list);
4627d62b00eSchristos   set_cmd_completer_handle_brkchars
4637d62b00eSchristos     (cmd, maintenance_test_options_unknown_is_error_command_completer);
4647d62b00eSchristos 
4657d62b00eSchristos   cmd = add_cmd ("unknown-is-operand", class_maintenance,
4667d62b00eSchristos 		 maintenance_test_options_unknown_is_operand_command,
4677d62b00eSchristos 		 help_unknown_is_operand_str.c_str (),
4687d62b00eSchristos 		 &maintenance_test_options_list);
4697d62b00eSchristos   set_cmd_completer_handle_brkchars
4707d62b00eSchristos     (cmd, maintenance_test_options_unknown_is_operand_command_completer);
4717d62b00eSchristos 
4727d62b00eSchristos   add_cmd ("test-options-completion-result", class_maintenance,
4737d62b00eSchristos 	   maintenance_show_test_options_completion_result,
4747d62b00eSchristos 	   _("\
4757d62b00eSchristos Show maintenance test-options completion result.\n\
4767d62b00eSchristos Shows the results of completing\n\
4777d62b00eSchristos \"maint test-options require-delimiter\",\n\
4787d62b00eSchristos \"maint test-options unknown-is-error\", or\n\
4797d62b00eSchristos \"maint test-options unknown-is-operand\"."),
4807d62b00eSchristos 	   &maintenance_show_cmdlist);
4817d62b00eSchristos }
482