]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/maint-test-options.c
Add R_AARCH64_P32_MOVW_PREL_* ELF32 relocs
[thirdparty/binutils-gdb.git] / gdb / maint-test-options.c
CommitLineData
9d0faba9
PA
1/* Maintenance commands for testing the options framework.
2
3 Copyright (C) 2019 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#include "defs.h"
21#include "gdbcmd.h"
22#include "cli/cli-option.h"
23
24/* This file defines three "maintenance test-options" subcommands to
25 exercise TAB-completion and option processing:
26
27 (gdb) maint test-options require-delimiter
28 (gdb) maint test-options unknown-is-error
29 (gdb) maint test-options unknown-is-operand
30
31 And a fourth one to help with TAB-completion testing.
32
33 (gdb) maint show test-options-completion-result
34
35 Each of the test-options subcommands exercise
36 gdb::option::process_options with a different enum
37 process_options_mode value. Examples for commands they model:
38
39 - "print" and "compile print", are like "require-delimiter",
40 because they accept random expressions as argument.
41
42 - "backtrace" and "frame/thread apply" are like
43 "unknown-is-operand", because "-" is a valid command.
44
45 - "compile file" and "compile code" are like "unknown-is-error".
46
47 These commands allow exercising all aspects of option processing
48 without having to pick some existing command. That should be more
49 stable going forward than relying on an existing user command,
50 since if we picked say "print", that command or its options could
51 change in future, and then we'd be left with having to pick some
52 other command or option to exercise some non-command-specific
53 option processing detail. Also, actual user commands have side
54 effects that we're not interested in when we're focusing on unit
55 testing the options machinery. BTW, a maintenance command is used
56 as a sort of unit test driver instead of actual "maint selftest"
57 unit tests, since we need to go all the way via gdb including
58 readline, for proper testing of TAB completion.
59
60 These maintenance commands support options of all the different
61 available kinds of commands (boolean, enum, flag, uinteger):
62
63 (gdb) maint test-options require-delimiter -[TAB]
64 -bool -enum -flag -uinteger -xx1 -xx2
65
66 (gdb) maint test-options require-delimiter -bool o[TAB]
67 off on
68 (gdb) maint test-options require-delimiter -enum [TAB]
69 xxx yyy zzz
70 (gdb) maint test-options require-delimiter -uinteger [TAB]
71 NUMBER unlimited
72
73 '-xx1' and '-xx2' are flag options too. They exist in order to
74 test ambiguous option names, like '-xx'.
75
76 Invoking the commands makes them print out the options parsed:
77
78 (gdb) maint test-options unknown-is-error -flag -enum yyy cmdarg
79 -flag 1 -xx1 0 -xx2 0 -bool 0 -enum yyy -uint 0 -zuint-unl 0 -- cmdarg
80
81 (gdb) maint test-options require-delimiter -flag -enum yyy cmdarg
82 -flag 0 -xx1 0 -xx2 0 -bool 0 -enum xxx -uint 0 -zuint-unl 0 -- -flag -enum yyy cmdarg
83 (gdb) maint test-options require-delimiter -flag -enum yyy cmdarg --
84 Unrecognized option at: cmdarg --
85 (gdb) maint test-options require-delimiter -flag -enum yyy -- cmdarg
86 -flag 1 -xx1 0 -xx2 0 -bool 0 -enum yyy -uint 0 -zuint-unl 0 -- cmdarg
87
88 The "maint show test-options-completion-result" command exists in
89 order to do something similar for completion:
90
91 (gdb) maint test-options unknown-is-error -flag -b 0 -enum yyy OPERAND[TAB]
92 (gdb) maint show test-options-completion-result
93 0 OPERAND
94
95 (gdb) maint test-options unknown-is-error -flag -b 0 -enum yyy[TAB]
96 (gdb) maint show test-options-completion-result
97 1
98
99 (gdb) maint test-options require-dash -unknown[TAB]
100 (gdb) maint show test-options-completion-result
101 1
102
103 Here, "1" means the completion function processed the whole input
104 line, and that the command shouldn't do anything with the arguments,
105 since there are no operands. While "0" indicates that there are
106 operands after options. The text after "0" is the operands.
107
108 This level of detail is particularly important because getting the
109 completion function's entry point to return back to the caller the
110 right pointer into the operand is quite tricky in several
111 scenarios. */
112
113/* Enum values for the "maintenance test-options" commands. */
114const char test_options_enum_values_xxx[] = "xxx";
115const char test_options_enum_values_yyy[] = "yyy";
116const char test_options_enum_values_zzz[] = "zzz";
117static const char *const test_options_enum_values_choices[] =
118{
119 test_options_enum_values_xxx,
120 test_options_enum_values_yyy,
121 test_options_enum_values_zzz,
122 NULL
123};
124
125/* Option data for the "maintenance test-options" commands. */
126
127struct test_options_opts
128{
129 int flag_opt = 0;
130 int xx1_opt = 0;
131 int xx2_opt = 0;
132 int boolean_opt = 0;
133 const char *enum_opt = test_options_enum_values_xxx;
134 unsigned int uint_opt = 0;
135 int zuint_unl_opt = 0;
136};
137
138/* Option definitions for the "maintenance test-options" commands. */
139
140static const gdb::option::option_def test_options_option_defs[] = {
141
142 /* A flag option. */
143 gdb::option::flag_option_def<test_options_opts> {
144 "flag",
145 [] (test_options_opts *opts) { return &opts->flag_opt; },
146 N_("A flag option."),
147 },
148
149 /* A couple flags with similar names, for "ambiguous option names"
150 testing. */
151 gdb::option::flag_option_def<test_options_opts> {
152 "xx1",
153 [] (test_options_opts *opts) { return &opts->xx1_opt; },
154 N_("A flag option."),
155 },
156 gdb::option::flag_option_def<test_options_opts> {
157 "xx2",
158 [] (test_options_opts *opts) { return &opts->xx2_opt; },
159 N_("A flag option."),
160 },
161
162 /* A boolean option. */
163 gdb::option::boolean_option_def<test_options_opts> {
164 "bool",
165 [] (test_options_opts *opts) { return &opts->boolean_opt; },
166 nullptr, /* show_cmd_cb */
167 N_("A boolean option."),
168 },
169
170 /* An enum option. */
171 gdb::option::enum_option_def<test_options_opts> {
172 "enum",
173 test_options_enum_values_choices,
174 [] (test_options_opts *opts) { return &opts->enum_opt; },
175 nullptr, /* show_cmd_cb */
176 N_("An enum option."),
177 },
178
179 /* A uinteger option. */
180 gdb::option::uinteger_option_def<test_options_opts> {
181 "uinteger",
182 [] (test_options_opts *opts) { return &opts->uint_opt; },
183 nullptr, /* show_cmd_cb */
184 N_("A uinteger option."),
185 nullptr, /* show_doc */
186 N_("A help doc that spawns\nmultiple lines."),
187 },
188
189 /* A zuinteger_unlimited option. */
190 gdb::option::zuinteger_unlimited_option_def<test_options_opts> {
191 "zuinteger-unlimited",
192 [] (test_options_opts *opts) { return &opts->zuint_unl_opt; },
193 nullptr, /* show_cmd_cb */
194 N_("A zuinteger-unlimited option."),
195 nullptr, /* show_doc */
196 nullptr, /* help_doc */
197 },
198};
199
200/* Create an option_def_group for the test_options_opts options, with
201 OPTS as context. */
202
203static inline gdb::option::option_def_group
204make_test_options_options_def_group (test_options_opts *opts)
205{
206 return {{test_options_option_defs}, opts};
207}
208
209/* Implementation of the "maintenance test-options
210 require-delimiter/unknown-is-error/unknown-is-operand" commands.
211 Each of the commands maps to a different enum process_options_mode
212 enumerator. The test strategy is simply processing the options in
213 a number of scenarios, and printing back the parsed result. */
214
215static void
216maintenance_test_options_command_mode (const char *args,
217 gdb::option::process_options_mode mode)
218{
219 test_options_opts opts;
220
221 gdb::option::process_options (&args, mode,
222 make_test_options_options_def_group (&opts));
223
224 if (args == nullptr)
225 args = "";
226 else
227 args = skip_spaces (args);
228
229 printf_unfiltered (_("-flag %d -xx1 %d -xx2 %d -bool %d "
230 "-enum %s -uint %s -zuint-unl %s -- %s\n"),
231 opts.flag_opt,
232 opts.xx1_opt,
233 opts.xx2_opt,
234 opts.boolean_opt,
235 opts.enum_opt,
236 (opts.uint_opt == UINT_MAX
237 ? "unlimited"
238 : pulongest (opts.uint_opt)),
239 (opts.zuint_unl_opt == -1
240 ? "unlimited"
241 : plongest (opts.zuint_unl_opt)),
242 args);
243}
244
245/* Variables used by the "maintenance show
246 test-options-completion-result" command. These variables are
247 stored by the completer of the "maint test-options"
248 subcommands. */
249
250/* The result of gdb::option::complete_options. */
251static int maintenance_test_options_command_completion_result;
252/* The text at the word point after gdb::option::complete_options
253 returns. */
254static std::string maintenance_test_options_command_completion_text;
255
256/* The "maintenance show test-options-completion-result" command. */
257
258static void
259maintenance_show_test_options_completion_result
260 (struct ui_file *file, int from_tty,
261 struct cmd_list_element *c, const char *value)
262{
263 if (maintenance_test_options_command_completion_result)
264 fprintf_filtered (file, "1\n");
265 else
266 fprintf_filtered
267 (file, _("0 %s\n"),
268 maintenance_test_options_command_completion_text.c_str ());
269}
270
271/* Implementation of completer for the "maintenance test-options
272 require-delimiter/unknown-is-error/unknown-is-operand" commands.
273 Each of the commands maps to a different enum process_options_mode
274 enumerator. */
275
276static void
277maintenance_test_options_completer_mode (completion_tracker &tracker,
278 const char *text,
279 gdb::option::process_options_mode mode)
280{
281 try
282 {
283 maintenance_test_options_command_completion_result
284 = gdb::option::complete_options
285 (tracker, &text, mode,
286 make_test_options_options_def_group (nullptr));
287 maintenance_test_options_command_completion_text = text;
288 }
289 catch (const gdb_exception_error &ex)
290 {
291 maintenance_test_options_command_completion_result = 1;
292 throw;
293 }
294}
295
296/* Implementation of the "maintenance test-options require-delimiter"
297 command. */
298
299static void
300maintenance_test_options_require_delimiter_command (const char *args,
301 int from_tty)
302{
303 maintenance_test_options_command_mode
304 (args, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER);
305}
306
307/* Implementation of the "maintenance test-options
308 unknown-is-error" command. */
309
310static void
311maintenance_test_options_unknown_is_error_command (const char *args,
312 int from_tty)
313{
314 maintenance_test_options_command_mode
315 (args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR);
316}
317
318/* Implementation of the "maintenance test-options
319 unknown-is-operand" command. */
320
321static void
322maintenance_test_options_unknown_is_operand_command (const char *args,
323 int from_tty)
324{
325 maintenance_test_options_command_mode
326 (args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND);
327}
328
329/* Completer for the "maintenance test-options require-delimiter"
330 command. */
331
332static void
333maintenance_test_options_require_delimiter_command_completer
334 (cmd_list_element *ignore, completion_tracker &tracker,
335 const char *text, const char *word)
336{
337 maintenance_test_options_completer_mode
338 (tracker, text, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER);
339}
340
341/* Completer for the "maintenance test-options unknown-is-error"
342 command. */
343
344static void
345maintenance_test_options_unknown_is_error_command_completer
346 (cmd_list_element *ignore, completion_tracker &tracker,
347 const char *text, const char *word)
348{
349 maintenance_test_options_completer_mode
350 (tracker, text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR);
351}
352
353/* Completer for the "maintenance test-options unknown-is-operand"
354 command. */
355
356static void
357maintenance_test_options_unknown_is_operand_command_completer
358 (cmd_list_element *ignore, completion_tracker &tracker,
359 const char *text, const char *word)
360{
361 maintenance_test_options_completer_mode
362 (tracker, text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND);
363}
364
365/* Command list for maint test-options. */
366struct cmd_list_element *maintenance_test_options_list;
367
368/* The "maintenance test-options" prefix command. */
369
370static void
371maintenance_test_options_command (const char *arg, int from_tty)
372{
373 printf_unfiltered
374 (_("\"maintenance test-options\" must be followed "
375 "by the name of a subcommand.\n"));
376 help_list (maintenance_test_options_list, "maintenance test-options ",
377 all_commands, gdb_stdout);
378}
379
380\f
381void
382_initialize_maint_test_options ()
383{
384 cmd_list_element *cmd;
385
386 add_prefix_cmd ("test-options", no_class, maintenance_test_options_command,
387 _("\
388Generic command for testing the options infrastructure."),
389 &maintenance_test_options_list,
390 "maintenance test-options ", 0,
391 &maintenancelist);
392
393 const auto def_group = make_test_options_options_def_group (nullptr);
394
395 static const std::string help_require_delim_str
396 = gdb::option::build_help (_("\
397Command used for testing options processing.\n\
398Usage: maint test-options require-delimiter [[OPTION]... --] [OPERAND]...\n\
399\n\
400Options:\n\
401\n\
402%OPTIONS%\n\
403If you specify any command option, you must use a double dash (\"--\")\n\
404to mark the end of option processing."),
405 def_group);
406
407 static const std::string help_unknown_is_error_str
408 = gdb::option::build_help (_("\
409Command used for testing options processing.\n\
410Usage: maint test-options unknown-is-error [OPTION]... [OPERAND]...\n\
411\n\
412Options:\n\
413\n\
414%OPTIONS%"),
415 def_group);
416
417 static const std::string help_unknown_is_operand_str
418 = gdb::option::build_help (_("\
419Command used for testing options processing.\n\
420Usage: maint test-options unknown-is-operand [OPTION]... [OPERAND]...\n\
421\n\
422Options:\n\
423\n\
424%OPTIONS%"),
425 def_group);
426
427 cmd = add_cmd ("require-delimiter", class_maintenance,
428 maintenance_test_options_require_delimiter_command,
429 help_require_delim_str.c_str (),
430 &maintenance_test_options_list);
431 set_cmd_completer_handle_brkchars
432 (cmd, maintenance_test_options_require_delimiter_command_completer);
433
434 cmd = add_cmd ("unknown-is-error", class_maintenance,
435 maintenance_test_options_unknown_is_error_command,
436 help_unknown_is_error_str.c_str (),
437 &maintenance_test_options_list);
438 set_cmd_completer_handle_brkchars
439 (cmd, maintenance_test_options_unknown_is_error_command_completer);
440
441 cmd = add_cmd ("unknown-is-operand", class_maintenance,
442 maintenance_test_options_unknown_is_operand_command,
443 help_unknown_is_operand_str.c_str (),
444 &maintenance_test_options_list);
445 set_cmd_completer_handle_brkchars
446 (cmd, maintenance_test_options_unknown_is_operand_command_completer);
447
448 add_setshow_zinteger_cmd ("test-options-completion-result", class_maintenance,
449 &maintenance_test_options_command_completion_result,
450 _("\
451Set maintenance test-options completion result."), _("\
452Show maintenance test-options completion result."), _("\
453Show the results of completing\n\
454\"maint test-options require-delimiter\",\n\
455\"maint test-options unknown-is-error\", or\n\
456\"maint test-options unknown-is-operand\"."),
457 NULL,
458 maintenance_show_test_options_completion_result,
459 &maintenance_set_cmdlist,
460 &maintenance_show_cmdlist);
461}