1# This testcase is part of GDB, the GNU debugger.
2
3# Copyright 2019-2023 Free Software Foundation, Inc.
4
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18# Test the gdb::option framework.
19
20# The test uses the "maintenance test-options" subcommands to exercise
21# TAB-completion and option processing.
22#
23# It also tests option integration in various commands, including:
24#
25#  - print
26#  - compile print
27#  - backtrace
28#  - frame apply
29#  - faas
30#  - tfaas
31#  - thread apply
32#  - taas
33
34load_lib compile-support.exp
35load_lib completion-support.exp
36
37standard_testfile .c
38
39if {[build_executable "failed to prepare" $testfile $srcfile debug]} {
40    return -1
41}
42
43clean_restart
44
45if { ![readline_is_used] } {
46    untested "no tab completion support without readline"
47    return -1
48}
49
50set tui_supported_p [expr ![skip_tui_tests]]
51
52# Check the completion result, as returned by the "maintenance show
53# test-options-completion-result" command.  TEST is used as test name.
54proc check_completion_result {expected test} {
55    gdb_test "maintenance show test-options-completion-result" \
56	"$expected" \
57	"$test: res=$expected"
58}
59
60# Like test_gdb_complete_unique, but the expected output is expected
61# to be the input line.  I.e., the line is already complete.  We're
62# just checking whether GDB recognizes the option and auto-appends a
63# space.
64proc test_completer_recognizes {res input_line} {
65    set expected_re [string_to_regexp $input_line]
66    test_gdb_complete_unique $input_line $expected_re
67    check_completion_result $res $input_line
68}
69
70# Wrapper around test_gdb_complete_multiple that also checks the
71# completion result is RES.
72proc res_test_gdb_complete_multiple {res cmd_prefix completion_word args} {
73    test_gdb_complete_multiple $cmd_prefix $completion_word {*}$args
74    check_completion_result $res "$cmd_prefix$completion_word"
75}
76
77# Wrapper around test_gdb_complete_none that also checks the
78# completion result is RES.
79proc res_test_gdb_complete_none { res input_line } {
80    test_gdb_complete_none $input_line
81    check_completion_result $res "$input_line"
82}
83
84# Wrapper around test_gdb_complete_unique that also checks the
85# completion result is RES.
86proc res_test_gdb_complete_unique { res input_line args} {
87    test_gdb_complete_unique $input_line {*}$args
88    check_completion_result $res "$input_line"
89}
90
91# Make a full command name from VARIANT.  VARIANT is either
92# "require-delimiter", "unknown-is-error" or "unknown-is-operand".
93proc make_cmd {variant} {
94    return "maint test-options $variant"
95}
96
97# Return a string for the expected result of running "maint
98# test-options xxx", with no flag/option set.  OPERAND is the expected
99# operand.
100proc expect_none {operand} {
101    return "-flag 0 -xx1 0 -xx2 0 -bool 0 -enum xxx -uint 0 -zuint-unl 0 -string '' -- $operand"
102}
103
104# Return a string for the expected result of running "maint
105# test-options xxx", with -flag set.  OPERAND is the expected operand.
106proc expect_flag {operand} {
107    return "-flag 1 -xx1 0 -xx2 0 -bool 0 -enum xxx -uint 0 -zuint-unl 0 -string '' -- $operand"
108}
109
110# Return a string for the expected result of running "maint
111# test-options xxx", with -bool set.  OPERAND is the expected operand.
112proc expect_bool {operand} {
113    return "-flag 0 -xx1 0 -xx2 0 -bool 1 -enum xxx -uint 0 -zuint-unl 0 -string '' -- $operand"
114}
115
116# Return a string for the expected result of running "maint
117# test-options xxx", with one of the integer options set to $VAL.
118# OPTION determines which option to expect set.  OPERAND is the
119# expected operand.
120proc expect_integer {option val operand} {
121    if {$option == "uinteger"} {
122	return "-flag 0 -xx1 0 -xx2 0 -bool 0 -enum xxx -uint $val -zuint-unl 0 -string '' -- $operand"
123    } elseif {$option == "zuinteger-unlimited"} {
124	return "-flag 0 -xx1 0 -xx2 0 -bool 0 -enum xxx -uint 0 -zuint-unl $val -string '' -- $operand"
125    } else {
126	error "unsupported option: $option"
127    }
128}
129
130# Return a string for the expected result of running "maint
131# test-options xxx", with -string set to $STR.  OPERAND is the
132# expected operand.
133proc expect_string {str operand} {
134    # Dequote the string in the expected output.
135    if { ( [string range $str 0 0] == "\""
136	   && [string range $str end end] == "\"")
137	 || ([string range $str 0 0] == "'"
138	     && [string range $str end end] == "'")} {
139	set str [string range $str 1 end-1]
140    }
141    return "-flag 0 -xx1 0 -xx2 0 -bool 0 -enum xxx -uint 0 -zuint-unl 0 -string '$str' -- $operand"
142}
143
144set all_options {
145    "-bool"
146    "-enum"
147    "-flag"
148    "-string"
149    "-uinteger"
150    "-xx1"
151    "-xx2"
152    "-zuinteger-unlimited"
153}
154
155# Basic option-machinery + "print" command integration tests.
156proc_with_prefix test-print {{prefix ""}} {
157    clean_restart
158
159    # Completing "print" with no argument completes on symbols only,
160    # no options are offered.  Since we haven't loaded any symbols,
161    # the match list should be empty.
162    test_gdb_complete_none "${prefix}print "
163
164    # OTOH, completing at "-" should list all options.
165    test_gdb_complete_multiple "${prefix}print " "-" "" {
166	"-address"
167	"-array"
168	"-array-indexes"
169	"-elements"
170	"-max-depth"
171	"-memory-tag-violations"
172	"-nibbles"
173	"-null-stop"
174	"-object"
175	"-pretty"
176	"-raw-values"
177	"-repeats"
178	"-static-members"
179	"-symbol"
180	"-union"
181	"-vtbl"
182    }
183
184    global binfile
185    clean_restart $binfile
186
187    if ![runto_main] {
188	return
189    }
190
191    # Mix options and format.
192    gdb_test "${prefix}print -pretty -- /x 1" " = 0x1"
193
194    # Smoke test that options actually work.
195    gdb_test "${prefix}print -pretty -- g_s" \
196	[multi_line  \
197	     " = {" \
198	     "  a = 1," \
199	     "  b = 2," \
200	     "  c = 3" \
201	     "}"]
202
203    test_gdb_complete_unique \
204	"${prefix}print xxx" \
205	"${prefix}print xxx1"
206    test_gdb_complete_unique \
207	"${prefix}print -- xxx" \
208	"${prefix}print -- xxx1"
209
210    # Error messages when testing with "compile" are different from
211    # the error messages gdb's internal parser throws.  This procedure
212    # hides the difference.  EXPECTED_RE is only considered when not
213    # testing with "compile".
214    proc test_invalid_expression {cmd expected_re} {
215	upvar prefix prefix
216
217	if {$prefix != "compile "} {
218	    gdb_test $cmd $expected_re
219	} else {
220	    # Error messages depend on compiler version, so we just
221	    # look for the last line indicating a failure.
222	    gdb_test $cmd "Compilation failed\\."
223	}
224    }
225
226    # Check that '-XXX' without a "--" is handled as an
227    # expression.
228    gdb_test "${prefix}print -1" " = -1"
229    test_invalid_expression \
230	"${prefix}print --1" \
231	"Left operand of assignment is not an lvalue\\."
232    test_invalid_expression \
233	"${prefix}print -object" \
234	"No symbol \"object\".*"
235
236    # Test printing with options and no expression.
237    set test "${prefix}print -object --"
238    if {$prefix != "compile "} {
239	# Regular "print" repeats the last history value.
240	gdb_test $test " = -1"
241    } else {
242	# "compile print" starts a multiline expression.
243	gdb_test_multiple $test $test {
244	    -re ">$" {
245		gdb_test "-1\nend" " = -1" \
246		    $test
247	    }
248	}
249    }
250
251    # Check that everything after "-- " is treated as an
252    # expression, not confused with an option.
253    test_invalid_expression \
254	"${prefix}print -- -address" \
255	"No symbol.*"
256    gdb_test "${prefix}print -- -1" " = -1"
257    test_invalid_expression \
258	"${prefix}print -- --1" \
259	"Left operand of assignment is not an lvalue\\."
260}
261
262# Basic option-machinery + "backtrace" command integration tests.
263proc_with_prefix test-backtrace {} {
264    clean_restart
265
266    test_gdb_complete_unique "backtrace" "backtrace"
267    test_gdb_complete_none "backtrace "
268
269    gdb_test "backtrace -" "Ambiguous option at: -"
270    gdb_test "backtrace --" "No stack\\."
271    gdb_test "backtrace -- -" "No stack\\."
272
273    test_gdb_complete_multiple "backtrace " "-" "" {
274	"-entry-values"
275	"-frame-arguments"
276	"-frame-info"
277	"-full"
278	"-hide"
279	"-no-filters"
280	"-past-entry"
281	"-past-main"
282	"-raw-frame-arguments"
283    }
284
285    # Test that we complete the qualifiers, if there's any.
286    test_gdb_complete_unique \
287	"backtrace ful" \
288	"backtrace full"
289    test_gdb_complete_unique \
290	"backtrace hid" \
291	"backtrace hide"
292    test_gdb_complete_unique \
293	"backtrace no-fil" \
294	"backtrace no-filters"
295
296    global binfile
297    clean_restart $binfile
298
299    if ![runto_main] {
300	return
301    }
302
303    # COUNT in "backtrace COUNT" is parsed as an expression.  Check
304    # that we complete expressions.
305
306    test_gdb_complete_unique \
307	"backtrace xxx" \
308	"backtrace xxx1"
309
310    test_gdb_complete_unique \
311	"backtrace -xxx" \
312	"backtrace -xxx1"
313
314    test_gdb_complete_unique \
315	"backtrace 1 + xxx" \
316	"backtrace 1 + xxx1"
317
318    test_gdb_complete_unique \
319	"backtrace (1 + xxx" \
320	"backtrace (1 + xxx1"
321}
322
323# Basic option-machinery + "frame apply" command integration tests.
324proc_with_prefix test-frame-apply {} {
325    global tui_supported_p
326
327    test_gdb_complete_unique "frame apply all" "frame apply all"
328
329    gdb_test "frame apply level 0-" \
330	"Please specify a command to apply on the selected frames"
331    test_gdb_complete_none "frame apply level 0-"
332
333    foreach cmd {
334	"frame apply all"
335	"frame apply 1"
336	"frame apply level 0"
337	"faas"
338	"tfaas"
339    } {
340	test_gdb_completion_offers_commands "$cmd "
341
342	# tfaas is silent on command error by design.  This procedure
343	# hides that aspect.  EXPECTED_RE is only considered when not
344	# testing with "faas"/"tfaas".
345	proc test_error_cmd {cmd arg expected_re} {
346	    if {$cmd == "tfaas"} {
347		gdb_test_no_output "$cmd$arg"
348	    } else {
349		gdb_test "$cmd$arg" $expected_re
350	    }
351	}
352	# Same, but for tests where both "faas" and "tfaas" are
353	# expected to be silent.
354	proc test_error_cmd2 {cmd arg expected_re} {
355	    if {$cmd == "tfaas" || $cmd == "faas"} {
356		gdb_test_no_output "$cmd$arg"
357	    } else {
358		gdb_test "$cmd$arg" $expected_re
359	    }
360	}
361
362	test_error_cmd $cmd " -" "Ambiguous option at: -"
363	test_gdb_complete_multiple "$cmd " "-" "" {
364	    "-c"
365	    "-past-entry"
366	    "-past-main"
367	    "-q"
368	    "-s"
369	}
370
371	with_test_prefix "no-trailing-space" {
372	    test_error_cmd $cmd " --" \
373		"Please specify a command to apply on the selected frames"
374	    test_gdb_complete_unique "$cmd --" "$cmd --"
375	}
376
377	with_test_prefix "trailing-space" {
378	    test_error_cmd $cmd " -- " \
379		"Please specify a command to apply on the selected frames"
380	    test_gdb_completion_offers_commands "$cmd -- "
381	}
382
383	if { $tui_supported_p } {
384	    # '-' is a valid TUI command.
385	    test_error_cmd2 $cmd " -- -" \
386		"Cannot enable the TUI when output is not a terminal"
387	    test_gdb_complete_unique \
388		"$cmd -- -" \
389		"$cmd -- -"
390	}
391
392	test_error_cmd2 $cmd " -foo" \
393	    "Undefined command: \"-foo\".  Try \"help\"\\."
394	test_gdb_complete_none "$cmd -foo"
395
396	test_gdb_completion_offers_commands "$cmd -s "
397    }
398}
399
400# Basic option-machinery + "thread apply" command integration tests.
401proc_with_prefix test-thread-apply {} {
402    global tui_supported_p
403
404    test_gdb_complete_unique "thread apply all" "thread apply all"
405    test_gdb_complete_unique "taas" "taas"
406
407    gdb_test "thread apply 1-" \
408	"inverted range"
409    test_gdb_complete_none "frame apply level 1-"
410
411    foreach cmd {
412	"thread apply all"
413	"thread apply 1"
414	"taas"
415    } {
416	test_gdb_completion_offers_commands "$cmd "
417
418	# taas is silent on command error by design.  This procedure
419	# hides the difference.  EXPECTED_RE is only considered when
420	# not testing with "taas".
421	proc test_invalid_cmd {cmd arg expected_re} {
422	    if {$cmd != "taas"} {
423		gdb_test "$cmd$arg" $expected_re
424	    } else {
425		gdb_test_no_output "$cmd$arg"
426	    }
427	}
428
429	gdb_test "$cmd -" "Ambiguous option at: -"
430
431	if {$cmd != "thread apply 1"} {
432	    test_gdb_complete_multiple "$cmd " "-" "" {
433		"-ascending"
434		"-c"
435		"-q"
436		"-s"
437	    }
438	} else {
439	    # "-ascending" only works with "all".
440	    test_gdb_complete_multiple "$cmd " "-" "" {
441		"-c"
442		"-q"
443		"-s"
444	    }
445	}
446
447	if {$cmd == "thread apply all" || $cmd == "taas"} {
448	    set errmsg \
449		"Please specify a command at the end of 'thread apply all'"
450	} elseif {$cmd == "thread apply 1"} {
451	    set errmsg \
452		"Please specify a command following the thread ID list"
453	} else {
454	    error "unexpected cmd: $cmd"
455	}
456
457	with_test_prefix "no-trailing-space" {
458	    gdb_test "$cmd --" $errmsg
459	    test_gdb_complete_unique "$cmd --" "$cmd --"
460	}
461
462	with_test_prefix "trailing-space" {
463	    gdb_test "$cmd -- " $errmsg
464	    test_gdb_completion_offers_commands "$cmd -- "
465	}
466
467	if { $tui_supported_p } {
468	    # '-' is a valid TUI command.
469	    test_invalid_cmd "$cmd" " -- -" \
470		"Cannot enable the TUI when output is not a terminal"
471	    test_gdb_complete_unique \
472		"$cmd -- -" \
473		"$cmd -- -"
474	}
475
476	test_invalid_cmd $cmd " -foo" \
477	    "Undefined command: \"-foo\".  Try \"help\"\\."
478	test_gdb_complete_none "$cmd -foo"
479
480	test_gdb_completion_offers_commands "$cmd -c "
481    }
482}
483
484# Basic option-machinery + "info threads" command integration tests.
485proc_with_prefix test-info-threads {} {
486    test_gdb_complete_multiple "info threads " "" "" {
487	"-gid"
488	"ID"
489    }
490
491    test_gdb_complete_unique \
492	"info threads -" \
493	"info threads -gid"
494
495    # "ID" isn't really something the user can type.
496    test_gdb_complete_none "info threads I"
497}
498
499# Miscellaneous tests.
500proc_with_prefix test-misc {variant} {
501    global all_options
502
503    set cmd [make_cmd $variant]
504
505    # Call test command with no arguments at all.
506    gdb_test "$cmd" [expect_none ""]
507
508    # Now with a single dash.
509    if {$variant == "require-delimiter"} {
510	gdb_test "$cmd -" [expect_none "-"]
511    } else {
512	gdb_test "$cmd -" "Ambiguous option at: -"
513    }
514
515    # Completing at "-" should list all options.
516    res_test_gdb_complete_multiple \
517	"1 [expect_none "-"]" \
518	"$cmd " "-" "" $all_options
519
520    # Now with a double dash.
521    gdb_test "$cmd --" [expect_none ""]
522
523    # "--" is recognized by options completer, gdb auto-appends a
524    # space.
525    test_completer_recognizes \
526	"1 [expect_none "--"]" \
527	"$cmd --"
528
529    # Now with a double dash, plus a dash as operand.
530    gdb_test "$cmd -- -" [expect_none "-"]
531    res_test_gdb_complete_none "0 -" "$cmd -- -"
532
533    # Completing an unambiguous option just appends an empty space.
534    test_completer_recognizes \
535	"1 [expect_none "-flag"]" \
536	"$cmd -flag"
537
538    # Try running an ambiguous option.
539    if {$variant == "require-delimiter"} {
540	gdb_test "$cmd -xx" [expect_none "-xx"]
541    } else {
542	gdb_test "$cmd -xx" "Ambiguous option at: -xx"
543    }
544
545    # Check that options are not case insensitive.
546    gdb_test "$cmd -flag --" [expect_flag ""]
547
548    # Check how the different modes behave on unknown option, with a
549    # delimiter.
550    gdb_test "$cmd -FLAG --" \
551	"Unrecognized option at: -FLAG --"
552
553    # Check how the different modes behave on unknown option, without
554    # a delimiter.
555    if {$variant == "unknown-is-error"} {
556	gdb_test "$cmd -FLAG" \
557	    "Unrecognized option at: -FLAG"
558    } else {
559	gdb_test "$cmd -FLAG" [expect_none "-FLAG"]
560    }
561
562    # Test parsing stops at a negative integer.
563    gdb_test "$cmd -1 --" \
564	"Unrecognized option at: -1 --"
565    gdb_test "$cmd -2 --" \
566	"Unrecognized option at: -2 --"
567}
568
569# Flag option tests.
570proc_with_prefix test-flag {variant} {
571    global all_options
572
573    set cmd [make_cmd $variant]
574
575    # Completing a flag just appends a space.
576    test_completer_recognizes \
577	"1 [expect_none "-flag"]" \
578	"$cmd -flag"
579
580    # Add a dash, and all options should be shown.
581    res_test_gdb_complete_multiple \
582	"1 [expect_flag "-"]" \
583	"$cmd  -flag " "-" "" $all_options
584
585    # Basic smoke tests of accepted / not accepted values.
586
587    # Check all the different variants a bool option may be specified.
588    if {$variant == "require-delimiter"} {
589	gdb_test "$cmd -flag 999" [expect_none "-flag 999"]
590    } else {
591	gdb_test "$cmd -flag 999" [expect_flag "999"]
592    }
593    gdb_test "$cmd -flag -- 999" [expect_flag "999"]
594
595    # If the "--" separator is present, then GDB errors out if the
596    # flag option is passed some value -- check that too.
597    gdb_test "$cmd -flag xxx 999 --" "Unrecognized option at: xxx 999 --"
598    gdb_test "$cmd -flag o 999 --" "Unrecognized option at: o 999 --"
599    gdb_test "$cmd -flag 1 999 --" "Unrecognized option at: 1 999 --"
600
601    # Extract twice the same flag, separated by one space.
602    gdb_test "$cmd -flag -flag -- non flags args" \
603	[expect_flag "non flags args"]
604
605    # Extract twice the same flag, separated by one space.
606    gdb_test "$cmd -xx1     -xx2 -xx1  -xx2 -xx1    -- non flags args" \
607	"-flag 0 -xx1 1 -xx2 1 -bool 0 -enum xxx -uint 0 -zuint-unl 0 -string '' -- non flags args"
608
609    # Extract 2 known flags in front of unknown flags.
610    gdb_test "$cmd -xx1 -xx2 -a -b -c -xx1 --" \
611	"Unrecognized option at: -a -b -c -xx1 --"
612
613    # Check that combined flags are not recognised.
614    gdb_test "$cmd -xx1 -xx1xx2 -xx1 --" \
615	"Unrecognized option at: -xx1xx2 -xx1 --"
616
617    # Make sure the completer don't confuse a flag option with a
618    # boolean option.  Specifically, "o" should not complete to
619    # "on/off".
620
621    if {$variant == "require-delimiter"} {
622	res_test_gdb_complete_none \
623	    "1 [expect_flag "o"]" \
624	    "$cmd -flag o"
625
626	gdb_test "$cmd -flag o" [expect_none "-flag o"]
627    } else {
628	res_test_gdb_complete_none "0 o" "$cmd -flag o"
629
630	gdb_test "$cmd -flag o" [expect_flag "o"]
631    }
632}
633
634# Boolean option tests.
635proc_with_prefix test-boolean {variant} {
636    global all_options
637
638    set cmd [make_cmd $variant]
639
640    # Boolean option's values are optional -- "on" is implied.  Check
641    # that:
642    #
643    # - For require-delimiter commands, completing after a boolean
644    #   option lists all other options, plus "on/off".  This is
645    #   because operands won't be processed until we see a "--"
646    #   delimiter.
647    #
648    # - For !require-delimiter commands, completing after a boolean
649    #   option completes as an operand, since that will tend to be
650    #   more common than typing "on/off".
651    #   E.g., "frame apply all -past-main COMMAND".
652
653    if {$variant == "require-delimiter"} {
654	set match_list $all_options
655	lappend match_list "off" "on"
656	res_test_gdb_complete_multiple \
657	    "1 [expect_none ""]" \
658	    "$cmd -bool " "" "" $match_list
659    } else {
660	res_test_gdb_complete_none "0 " "$cmd -bool "
661    }
662
663    # Add another dash, and "on/off" are no longer offered:
664    res_test_gdb_complete_multiple \
665	"1 [expect_bool "-"]" \
666	"$cmd -bool " "-" ""  $all_options
667
668    # Basic smoke tests of accepted / not accepted values.
669
670    # The command accepts all of "1/0/enable/disable/yes/no" too, even
671    # though like the "set" command, we don't offer those as
672    # completion candidates if you complete right after the boolean
673    # command's name, like:
674    #
675    #  (gdb) maint test-options require-delimiter -bool [TAB]
676    #  off        on
677    #
678    # However, the completer does recognize them if you start typing
679    # the boolean value.
680    foreach value {"0" "1"} {
681	test_completer_recognizes \
682	    "1 [expect_none ""]" \
683	    "$cmd -bool $value"
684    }
685    foreach value {"of" "off"} {
686	res_test_gdb_complete_unique \
687	    "1 [expect_none ""]" \
688	    "$cmd -bool $value" \
689	    "$cmd -bool off"
690    }
691    foreach value {"y" "ye" "yes"} {
692	res_test_gdb_complete_unique \
693	    "1 [expect_none ""]" \
694	    "$cmd -bool $value" \
695	    "$cmd -bool yes"
696    }
697    foreach value {"n" "no"} {
698	res_test_gdb_complete_unique \
699	    "1 [expect_none ""]" \
700	    "$cmd -bool $value" \
701	    "$cmd -bool no"
702    }
703    foreach value {
704	"e"
705	"en"
706	"ena"
707	"enab"
708	"enabl"
709	"enable"
710    } {
711	res_test_gdb_complete_unique \
712	    "1 [expect_none ""]" \
713	    "$cmd -bool $value" \
714	    "$cmd -bool enable"
715    }
716    foreach value {
717	"d"
718	"di"
719	"dis"
720	"disa"
721	"disab"
722	"disabl"
723	"disable"
724    } {
725	res_test_gdb_complete_unique \
726	    "1 [expect_none ""]" \
727	    "$cmd -bool $value" \
728	    "$cmd -bool disable"
729    }
730
731    if {$variant == "require-delimiter"} {
732	res_test_gdb_complete_none \
733	    "1 [expect_none "xxx"]" \
734	    "$cmd -bool xxx"
735    } else {
736	res_test_gdb_complete_none "0 xxx" "$cmd -bool xxx"
737    }
738
739    # The command accepts abbreviations of "enable/disable/yes/no",
740    # even though we don't offer those for completion.
741    foreach value {
742	"1"
743	"y" "ye" "yes"
744	"e"
745	"en"
746	"ena"
747	"enab"
748	"enabl"
749	"enable"} {
750	gdb_test "$cmd -bool $value --" [expect_bool ""]
751    }
752    foreach value {
753	"0"
754	"of" "off"
755	"n" "no"
756	"d"
757	"di"
758	"dis"
759	"disa"
760	"disab"
761	"disabl"
762	"disable"} {
763	gdb_test "$cmd -bool $value --" [expect_none ""]
764    }
765
766    if {$variant == "require-delimiter"} {
767	gdb_test "$cmd -bool 999" [expect_none "-bool 999"]
768    } else {
769	gdb_test "$cmd -bool 999" [expect_bool "999"]
770    }
771    gdb_test "$cmd -bool -- 999" [expect_bool "999"]
772
773    # Since "on" is implied after a boolean option, for
774    # !require-delimiter commands, anything that is not
775    # yes/no/1/0/on/off/enable/disable should be considered as the raw
776    # input after the last option.  Also check "o", which might look
777    # like "on" or "off", but it's treated the same.
778
779    foreach arg {"xxx" "o"} {
780	if {$variant == "require-delimiter"} {
781	    gdb_test "$cmd -bool $arg" [expect_none "-bool $arg"]
782	} else {
783	    gdb_test "$cmd -bool $arg" [expect_bool "$arg"]
784	}
785    }
786    # Also try -1.  "unknown-is-error" commands error out saying that
787    # that's not a valid option.
788    if {$variant == "require-delimiter"} {
789	gdb_test "$cmd -bool -1" \
790	     [expect_none "-bool -1"]
791    } elseif {$variant == "unknown-is-error"} {
792	gdb_test "$cmd -bool -1" \
793	    "Unrecognized option at: -1"
794    } else {
795	gdb_test "$cmd -bool -1" [expect_bool "-1"]
796    }
797
798    # OTOH, if the "--" separator is present, then GDB errors out if
799    # the boolean option is passed an invalid value -- check that too.
800    gdb_test "$cmd -bool -1 999 --" \
801	"Unrecognized option at: -1 999 --"
802    gdb_test "$cmd -bool xxx 999 --" \
803	"Value given for `-bool' is not a boolean: xxx"
804    gdb_test "$cmd -bool o 999 --" \
805	"Value given for `-bool' is not a boolean: o"
806
807    # Completing after a boolean option + "o" does list "on/off",
808    # though.
809    if {$variant == "require-delimiter"} {
810	res_test_gdb_complete_multiple \
811	    "1 [expect_none "o"]" \
812	    "$cmd -bool " "o" "" {
813	    "off"
814	    "on"
815	}
816    } else {
817	res_test_gdb_complete_multiple "0 o" "$cmd -bool " "o" "" {
818	    "off"
819	    "on"
820	}
821    }
822}
823
824# Uinteger option tests.  OPTION is which integer option we're
825# testing.  Can be "uinteger" or "zuinteger-unlimited".
826proc_with_prefix test-uinteger {variant option} {
827    global all_options
828
829    set cmd "[make_cmd $variant] -$option"
830
831    # Test completing a uinteger option:
832    res_test_gdb_complete_multiple \
833	"1 [expect_none ""]" \
834	"$cmd " "" "" {
835	"NUMBER"
836	"unlimited"
837    }
838
839    # NUMBER above is just a placeholder, make sure we don't complete
840    # it as a valid option.
841    res_test_gdb_complete_none \
842	"1 [expect_none "NU"]" \
843	"$cmd NU"
844
845    # "unlimited" is valid though.
846    res_test_gdb_complete_unique \
847	"1 [expect_none "u"]" \
848	"$cmd u" \
849	"$cmd unlimited"
850
851    # Basic smoke test of accepted / not accepted values.
852    gdb_test "$cmd 1 -- 999" [expect_integer $option "1" "999"]
853    gdb_test "$cmd unlimited -- 999" \
854	[expect_integer $option "unlimited" "999"]
855    if {$option == "zuinteger-unlimited"} {
856	gdb_test "$cmd -1 --" [expect_integer $option "unlimited" ""]
857	gdb_test "$cmd 0 --" [expect_integer $option "0" ""]
858    } else {
859	gdb_test "$cmd -1 --" "integer -1 out of range"
860	gdb_test "$cmd 0 --" [expect_integer $option "unlimited" ""]
861    }
862    gdb_test "$cmd xxx --" \
863	"Expected integer at: xxx --"
864    gdb_test "$cmd unlimitedx --" \
865	"Expected integer at: unlimitedx --"
866
867    # Don't offer completions until we're past the
868    # -uinteger/-zuinteger-unlimited argument.
869    res_test_gdb_complete_none \
870	"1 [expect_none ""]" \
871	"$cmd 1"
872
873    # A number of invalid values.
874    foreach value {"x" "x " "1a" "1a " "1-" "1- " "unlimitedx"} {
875	res_test_gdb_complete_none \
876	    "1 [expect_none $value]" \
877	    "$cmd $value"
878    }
879
880    # Try "-1".
881    if {$option == "uinteger"} {
882	# -1 is invalid uinteger.
883	foreach value {"-1" "-1 "} {
884	    res_test_gdb_complete_none \
885		"1 [expect_none ""]" \
886		"$cmd $value"
887	}
888    } else {
889	# -1 is valid for zuinteger-unlimited.
890	res_test_gdb_complete_none \
891	    "1 [expect_none ""]" \
892	    "$cmd -1"
893	if {$variant == "require-delimiter"} {
894	    res_test_gdb_complete_multiple \
895		"1 [expect_integer $option "unlimited" ""]" \
896		"$cmd -1 " "" "-" $all_options
897	} else {
898	    res_test_gdb_complete_none "0 " "$cmd -1 "
899	}
900    }
901
902    # Check that after a fully parsed option:
903    #
904    #  - for require-delimiter commands, completion offers all
905    #    options.
906    #
907    #  - for !require-delimiter commands, completion offers nothing
908    #    and returns false.
909    if {$variant == "require-delimiter"} {
910	res_test_gdb_complete_multiple \
911	    "1 [expect_integer $option 1 ""]" \
912	    "$cmd 1 " "" "-" $all_options
913    } else {
914	res_test_gdb_complete_none "0 " "$cmd 1 "
915    }
916
917    # Test completing non-option arguments after "-uinteger 1 ".
918    foreach operand {"x" "x " "1a" "1a " "1-" "1- "} {
919	if {$variant == "require-delimiter"} {
920	    res_test_gdb_complete_none \
921		"1 [expect_integer $option 1 $operand]" \
922		"$cmd 1 $operand"
923	} else {
924	    res_test_gdb_complete_none "0 $operand" "$cmd 1 $operand"
925	}
926    }
927    # These look like options, but they aren't.
928    foreach operand {"-1" "-1 "} {
929	if {$variant == "unknown-is-operand"} {
930	    res_test_gdb_complete_none "0 $operand" "$cmd 1 $operand"
931	} else {
932	    res_test_gdb_complete_none \
933		"1 [expect_integer $option 1 $operand]" \
934		"$cmd 1 $operand"
935	}
936    }
937}
938
939# Enum option tests.
940proc_with_prefix test-enum {variant} {
941    set cmd [make_cmd $variant]
942
943    res_test_gdb_complete_multiple \
944	"1 [expect_none ""]" \
945	"$cmd -enum " "" "" {
946	"xxx"
947	"yyy"
948	"zzz"
949    }
950
951    # Check that "-" where a value is expected does not show the
952    # command's options.  I.e., an enum's value is not optional.
953    # Check both completion and running the command.
954    res_test_gdb_complete_none \
955	"1 [expect_none "-"]" \
956	"$cmd -enum -"
957    gdb_test "$cmd -enum --"\
958	"Requires an argument. Valid arguments are xxx, yyy, zzz\\."
959
960    # Try passing an undefined item to an enum option.
961    gdb_test "$cmd -enum www --" "Undefined item: \"www\"."
962}
963
964# String option tests.
965proc_with_prefix test-string {variant} {
966    global all_options
967
968    set cmd [make_cmd $variant]
969
970    res_test_gdb_complete_none \
971	"1 [expect_none ""]" \
972	"$cmd -string "
973
974    # Check that "-" where a value is expected does not show the
975    # command's options.  I.e., a string's value is not optional.
976    # Check both completion and running the command.
977    res_test_gdb_complete_none \
978	"1 [expect_none ""]" \
979	"$cmd -string -"
980    gdb_test "$cmd -string --"\
981	"-string requires an argument"
982    if {$variant == "require-delimiter"} {
983	gdb_test "$cmd -string" [expect_none "-string"]
984    } else {
985	gdb_test "$cmd -string"\
986	    "-string requires an argument"
987    }
988
989    foreach_with_prefix str {
990	"STR"
991	"\"STR\""
992	"\\\"STR"
993	"'STR'"
994	"\\'STR"
995	"\"STR AAA\""
996	"'STR BBB'"
997	"\"STR 'CCC' DDD\""
998	"'STR \"EEE\" FFF'"
999	"\"STR \\\"GGG\\\" HHH\""
1000	"'STR \\\'III\\\' JJJ'"
1001    } {
1002	res_test_gdb_complete_none \
1003	    "1 [expect_none ""]" \
1004	    "$cmd -string ${str}"
1005	gdb_test "$cmd -string ${str} --" [expect_string "${str}" ""]
1006
1007	# Completing at "-" after parsing STR should list all options.
1008	res_test_gdb_complete_multiple \
1009	    "1 [expect_string "${str}" "-"]" \
1010	    "$cmd -string ${str} " "-" "" $all_options
1011
1012	# Check that only $STR is considered part of the string's value.
1013	# I.e., that we stop parsing the string at the first
1014	# whitespace or after the closing quote of $STR.
1015	if {$variant == "require-delimiter"} {
1016	    res_test_gdb_complete_none \
1017		"1 [expect_string "${str}" "BAR"]" \
1018		"$cmd -string ${str} BAR"
1019	} else {
1020	    res_test_gdb_complete_none "0 BAR" "$cmd -string ${str} BAR"
1021	}
1022	gdb_test "$cmd -string ${str} BAR --" "Unrecognized option at: BAR --"
1023    }
1024}
1025
1026# Run the options framework tests first.
1027foreach_with_prefix cmd {
1028    "require-delimiter"
1029    "unknown-is-error"
1030    "unknown-is-operand"
1031} {
1032    test-misc $cmd
1033    test-flag $cmd
1034    test-boolean $cmd
1035    foreach subcmd {"uinteger" "zuinteger-unlimited" } {
1036	test-uinteger $cmd $subcmd
1037    }
1038    test-enum $cmd
1039    test-string $cmd
1040}
1041
1042# Run the print integration tests, both as "standalone", and under
1043# "frame/thread apply".  The latter checks that the "frame/thread
1044# apply ... COMMAND" commands recurse the completion machinery for
1045# COMMAND completion correctly.
1046foreach prefix {
1047    ""
1048    "frame apply all "
1049    "frame apply 1 "
1050    "frame apply level 0 "
1051    "thread apply all "
1052    "thread apply 1 "
1053    "thread apply 1 frame apply 1 "
1054} {
1055    test-print $prefix
1056}
1057
1058# Same for "compile print".  Not really a wrapper prefix command like
1059# "frame apply", but similar enough that we test pretty much the same
1060# things.
1061if ![skip_compile_feature_tests] {
1062    test-print "compile "
1063}
1064
1065# Basic "backtrace" integration tests.
1066test-backtrace
1067
1068# Basic "frame apply" integration tests.
1069test-frame-apply
1070
1071# Basic "thread apply" integration tests.
1072test-thread-apply
1073
1074# Basic "info threads" integration tests.
1075test-info-threads
1076