xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/lib/completion-support.exp (revision c9055873d0546e63388f027d3d7f85381cde0545)
1# Copyright 2017-2023 Free Software Foundation, Inc.
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16# This file is part of the gdb testsuite.
17
18# Any variable or procedure in the namespace whose name starts with
19# "_" is private to the module.  Do not use these.
20
21namespace eval completion {
22    variable bell_re "\\\x07"
23
24    # List of all quote chars.
25    variable all_quotes_list {"'" "\""}
26
27    # List of all quote chars, including no-quote at all.
28    variable maybe_quoted_list {"" "'" "\""}
29
30    variable keyword_list {"-force-condition" "if" "task" "thread"}
31
32    variable explicit_opts_list \
33	{"-function" "-label" "-line" "-qualified" "-source"}
34}
35
36# Make a regular expression that matches a TAB completion list.
37
38proc make_tab_completion_list_re { completion_list } {
39    # readline separates the completion columns that fit on the same
40    # line with whitespace.  Since we're testing under "set width
41    # unlimited", all completions will be printed on the same line.
42    # The amount of whitespace depends on the length of the widest
43    # completion.  We could compute that here and expect the exact
44    # number of ws characters between each completion match, but to
45    # keep it simple, we accept any number of characters.
46    set ws " +"
47
48    set completion_list_re ""
49    foreach c $completion_list {
50	append completion_list_re [string_to_regexp $c]
51	append completion_list_re $ws
52    }
53    append completion_list_re $ws
54
55    return $completion_list_re
56}
57
58# Make a regular expression that matches a "complete" command
59# completion list.  CMD_PREFIX is the command prefix added to each
60# completion match.
61
62proc make_cmd_completion_list_re { cmd_prefix completion_list start_quote_char end_quote_char } {
63
64    set completion_list_re ""
65    foreach c $completion_list {
66	# The command prefix is included in all completion matches.
67	append completion_list_re [string_to_regexp $cmd_prefix$start_quote_char$c$end_quote_char]
68	append completion_list_re "\r\n"
69    }
70
71    return $completion_list_re
72}
73
74# Clear the input line.
75
76proc clear_input_line { test } {
77    global gdb_prompt
78
79    send_gdb "\003"
80    gdb_test_multiple "" "$test (clearing input line)" {
81	-re "Quit\r\n$gdb_prompt $" {
82	}
83    }
84}
85
86# Test that completing LINE with TAB completes to nothing.
87
88proc test_gdb_complete_tab_none { line } {
89    set line_re [string_to_regexp $line]
90
91    set test "tab complete \"$line\""
92    send_gdb "$line\t"
93    gdb_test_multiple "" "$test" {
94	-re "^$line_re$completion::bell_re$" {
95	    pass "$test"
96	}
97    }
98
99    clear_input_line $test
100}
101
102# Test that completing INPUT_LINE with TAB completes to
103# COMPLETE_LINE_RE.  APPEND_CHAR_RE is the character expected to be
104# appended after EXPECTED_OUTPUT.  Normally that's a whitespace, but
105# in some cases it's some other character, like a colon.
106
107proc test_gdb_complete_tab_unique { input_line complete_line_re append_char_re } {
108
109    set test "tab complete \"$input_line\""
110    send_gdb "$input_line\t"
111    set res 1
112    gdb_test_multiple "" "$test" {
113	-re "^$complete_line_re$append_char_re$" {
114	    pass "$test"
115	}
116	timeout {
117	    fail "$test (timeout)"
118	    set res -1
119	}
120    }
121
122    clear_input_line $test
123    return $res
124}
125
126# Test that completing INPUT_LINE with TAB completes to "INPUT_LINE +
127# ADD_COMPLETED_LINE" and that it displays the completion matches in
128# COMPLETION_LIST.  If MAX_COMPLETIONS then we expect the completion
129# to hit the max-completions limit.
130
131proc test_gdb_complete_tab_multiple { input_line add_completed_line \
132					  completion_list {max_completions 0}} {
133    global gdb_prompt
134
135    set input_line_re [string_to_regexp $input_line]
136    set add_completed_line_re [string_to_regexp $add_completed_line]
137
138    set expected_re [make_tab_completion_list_re $completion_list]
139
140    if {$max_completions} {
141	append expected_re "\r\n"
142	append expected_re \
143	    "\\*\\*\\* List may be truncated, max-completions reached\\. \\*\\*\\*"
144    }
145
146    set test "tab complete \"$input_line\""
147    send_gdb "$input_line\t"
148    gdb_test_multiple "" "$test (first tab)" {
149	-re "^${input_line_re}${completion::bell_re}$add_completed_line_re$" {
150	    send_gdb "\t"
151	    # If we auto-completed to an ambiguous prefix, we need an
152	    # extra tab to show the matches list.
153	    if {$add_completed_line != ""} {
154		send_gdb "\t"
155		set maybe_bell ${completion::bell_re}
156	    } else {
157		set maybe_bell ""
158	    }
159	    gdb_test_multiple "" "$test (second tab)" {
160		-re "^${maybe_bell}\r\n$expected_re\r\n$gdb_prompt " {
161		    gdb_test_multiple "" "$test (second tab)" {
162			-re "^$input_line_re$add_completed_line_re$" {
163			    pass "$test"
164			}
165		    }
166		}
167	    }
168	}
169    }
170
171    clear_input_line $test
172}
173
174# Test that completing LINE with the complete command completes to
175# nothing.
176
177proc test_gdb_complete_cmd_none { line } {
178    gdb_test_no_output "complete $line" "cmd complete \"$line\""
179}
180
181# Test that completing LINE with the complete command completes to
182# COMPLETE_LINE_RE.
183
184proc test_gdb_complete_cmd_unique { input_line complete_line_re } {
185    global gdb_prompt
186
187    set cmd "complete $input_line"
188    set cmd_re [string_to_regexp $cmd]
189    set test "cmd complete \"$input_line\""
190    gdb_test_multiple $cmd $test {
191	-re "^$cmd_re\r\n$complete_line_re\r\n$gdb_prompt $" {
192	    pass $test
193	}
194    }
195}
196
197# Test that completing "CMD_PREFIX + COMPLETION_WORD" with the
198# complete command displays the COMPLETION_LIST completion list.  Each
199# entry in the list should be prefixed by CMD_PREFIX.  If
200# MAX_COMPLETIONS then we expect the completion to hit the
201# max-completions limit.
202
203proc test_gdb_complete_cmd_multiple { cmd_prefix completion_word completion_list {start_quote_char ""} {end_quote_char ""} {max_completions 0}} {
204    global gdb_prompt
205
206    set expected_re [make_cmd_completion_list_re $cmd_prefix $completion_list $start_quote_char $end_quote_char]
207
208    if {$max_completions} {
209	set cmd_prefix_re [string_to_regexp $cmd_prefix]
210	append expected_re \
211	    "$cmd_prefix_re \\*\\*\\* List may be truncated, max-completions reached\\. \\*\\*\\*.*\r\n"
212    }
213
214    set cmd_re [string_to_regexp "complete $cmd_prefix$completion_word"]
215    set test "cmd complete \"$cmd_prefix$completion_word\""
216    gdb_test_multiple "complete $cmd_prefix$completion_word" $test {
217	-re "^$cmd_re\r\n$expected_re$gdb_prompt $" {
218	    pass $test
219	}
220    }
221}
222
223# Test that completing LINE completes to nothing.
224
225proc test_gdb_complete_none { input_line } {
226    if { [readline_is_used] } {
227	test_gdb_complete_tab_none $input_line
228    }
229    test_gdb_complete_cmd_none $input_line
230}
231
232# Test that completing INPUT_LINE completes to COMPLETE_LINE_RE.
233#
234# APPEND_CHAR is the character expected to be appended after
235# EXPECTED_OUTPUT when TAB completing.  Normally that's a whitespace,
236# but in some cases it's some other character, like a colon.
237#
238# If MAX_COMPLETIONS is true, then we expect the completion to hit the
239# max-completions limit.  Since we're expecting a unique completion
240# match, this will only be visible in the "complete" command output.
241# Tab completion will just auto-complete the only match and won't
242# display a match list.
243#
244# Note: usually it's more convenient to pass a literal string instead
245# of a regular expression (as COMPLETE_LINE_RE).  See
246# test_gdb_complete_unique below.
247
248proc test_gdb_complete_unique_re { input_line complete_line_re {append_char " "} {max_completions 0}} {
249    set append_char_re [string_to_regexp $append_char]
250    if { [readline_is_used] } {
251	if { [test_gdb_complete_tab_unique $input_line $complete_line_re \
252		  $append_char_re] == -1 } {
253	    return -1
254	}
255    }
256
257    # Trim COMPLETE LINE, for the case we're completing a command with leading
258    # whitespace.  Leading command whitespace is discarded by GDB.
259    set expected_output_re [string trimleft $complete_line_re]
260    if {$append_char_re != " "} {
261	append expected_output_re $append_char_re
262    }
263    if {$max_completions} {
264	set max_completion_reached_msg \
265	    "*** List may be truncated, max-completions reached. ***"
266	set input_line_re \
267	    [string_to_regexp [string trimleft $input_line]]
268	set max_completion_reached_msg_re \
269	    [string_to_regexp $max_completion_reached_msg]
270
271	append expected_output_re \
272	    "\r\n$input_line_re $max_completion_reached_msg_re"
273    }
274
275    test_gdb_complete_cmd_unique $input_line $expected_output_re
276    return 1
277}
278
279# Like TEST_GDB_COMPLETE_UNIQUE_RE, but COMPLETE_LINE is a string, not
280# a regular expression.
281
282proc test_gdb_complete_unique { input_line complete_line {append_char " "} {max_completions 0}} {
283    set complete_line_re [string_to_regexp $complete_line]
284    test_gdb_complete_unique_re $input_line $complete_line_re $append_char $max_completions
285}
286
287# Test that completing "CMD_PREFIX + COMPLETION_WORD" adds
288# ADD_COMPLETED_LINE to the input line, and that it displays
289# COMPLETION_LIST as completion match list.  COMPLETION_WORD is the
290# completion word.  If MAX_COMPLETIONS then we expect the completion
291# to hit the max-completions limit.
292
293proc test_gdb_complete_multiple {
294  cmd_prefix completion_word add_completed_line completion_list
295  {start_quote_char ""} {end_quote_char ""} {max_completions 0}
296} {
297    if { [readline_is_used] } {
298      test_gdb_complete_tab_multiple "$cmd_prefix$completion_word" $add_completed_line $completion_list $max_completions
299    }
300    test_gdb_complete_cmd_multiple $cmd_prefix $completion_word $completion_list $start_quote_char $end_quote_char $max_completions
301}
302
303# Test that all the substring prefixes of INPUT from [0..START) to
304# [0..END) complete to COMPLETION_RE (a regular expression).  If END
305# is ommitted, default to the length of INPUT.
306
307proc test_complete_prefix_range_re {input completion_re start {end -1}} {
308    if {$end == -1} {
309	set end [string length $input]
310    }
311
312    set timeouts 0
313    set max_timeouts 3
314    for {set i $start} {$i < $end} {incr i} {
315	set line [string range $input 0 $i]
316	set res [test_gdb_complete_unique_re "$line" $completion_re]
317	if { $res == -1 } {
318	    incr timeouts
319	} else {
320	    if { $timeouts > 0 } {
321		set timeouts 0
322	    }
323	}
324	if { $timeouts == $max_timeouts } {
325	    verbose -log "Consecutive timeouts in test_complete_prefix_range_re, giving up"
326	    break
327	}
328    }
329}
330
331# Test that all the substring prefixes of COMPLETION from [0..START)
332# to [0..END) complete to COMPLETION.  If END is ommitted, default to
333# the length of COMPLETION.
334
335proc test_complete_prefix_range {completion start {end -1}} {
336    set completion_re [string_to_regexp $completion]
337    test_complete_prefix_range_re $completion $completion_re $start $end
338}
339
340# Find NEEDLE in HAYSTACK and return the index _after_ NEEDLE.  E.g.,
341# searching for "(" in "foo(int)" returns 4, which would be useful if
342# you want to find the "(" to try completing "foo(".
343
344proc index_after {needle haystack} {
345    set start [string first $needle $haystack]
346    if {$start == -1} {
347	error "could not find \"$needle\" in \"$haystack\""
348    }
349    return [expr $start + [string length $needle]]
350}
351
352# Create a breakpoint using BREAK_COMMAND, and return the number
353# of locations found.
354
355proc completion::_create_bp {break_command} {
356    global gdb_prompt
357    global decimal hex
358
359    set found_locations -1
360
361    set test "set breakpoint"
362    gdb_test_multiple "$break_command" $test {
363	-re "\\\(\($decimal\) locations\\\)\r\n$gdb_prompt $" {
364	    set found_locations "$expect_out(1,string)"
365	}
366	-re "Breakpoint $decimal at $hex: file .*, line .*$gdb_prompt $" {
367	    set found_locations 1
368	}
369	-re "Make breakpoint pending on future shared library load.*y or .n.. $" {
370	    send_gdb "n\n"
371	    gdb_test_multiple "" "$test (prompt)" {
372		-re "$gdb_prompt $" {
373		}
374	    }
375	    set found_locations 0
376	}
377	-re "invalid explicit location argument, \[^\r\n\]*\r\n$gdb_prompt $" {
378	    set found_locations 0
379	}
380	-re "Function \[^\r\n\]* not defined in \[^\r\n\]*\r\n$gdb_prompt $" {
381	    set found_locations 0
382	}
383    }
384    return $found_locations
385}
386
387# Return true if lists A and B have the same elements.  Order of
388# elements does not matter.
389
390proc completion::_leq {a b} {
391    return [expr {[lsort $a] eq [lsort $b]}]
392}
393
394# Check that trying to create a breakpoint using BREAK_COMMAND fails.
395
396proc check_setting_bp_fails {break_command} {
397    with_test_prefix "\"$break_command\" creates no bp locations" {
398	set found_locations [completion::_create_bp $break_command]
399	gdb_assert {$found_locations == 0} "matches"
400	if {$found_locations != 0} {
401	    delete_breakpoints
402	}
403    }
404}
405
406# Check that creating the breakpoint using BREAK_COMMAND finds the
407# same breakpoint locations as completing BREAK_COMMAND.
408# COMPLETION_LIST is the expected completion match list.
409
410proc check_bp_locations_match_list {break_command completion_list} {
411    global gdb_prompt
412    global hex
413
414    with_test_prefix "compare \"$break_command\" completion list with bp location list" {
415	set num_locations [completion::_create_bp $break_command]
416
417	set found_list ""
418
419	set any "\[^\r\n\]*"
420
421	gdb_test_multiple "info breakpoint \$bpnum" "info breakpoint" {
422	    -re "in \(\[^\r\n\]*\) at " {
423		# A function location.
424		set found_location "$expect_out(1,string)"
425		lappend found_list $found_location
426		exp_continue
427	    }
428	    -re "breakpoint${any}keep${any}y${any}$hex\[ \t]*\(${any}\)\r\n" {
429		# A label location.
430		set found_location "$expect_out(1,string)"
431		lappend found_list $found_location
432		exp_continue
433	    }
434	    -re "$gdb_prompt $" {
435	    }
436	}
437
438	gdb_assert {[completion::_leq $found_list $completion_list]} "matches"
439
440	delete_breakpoints
441    }
442}
443
444# Build linespec and explicit locations out of all the combinations of
445# SOURCES, FUNCTIONS and LABELS, with all combinations of possible
446# quoting and whitespace around separators, and run BODY_LINESPEC and
447# BODY_EXPLICIT in the context of the caller for each combination.  A
448# variable named "location" is set in the callers context with the
449# currently iterated location.
450
451proc foreach_location_functions { sources functions body_linespec body_explicit } {
452    upvar source source
453    upvar function function
454    upvar source_sep source_sep
455    upvar location location
456
457    foreach source $sources {
458	# Test with and without source quoting.
459	foreach sqc $completion::maybe_quoted_list {
460	    if {$source == "" && $sqc != ""} {
461		# Invalid combination.
462		continue
463	    }
464
465	    # Test with and without function quoting.
466	    foreach fqc $completion::maybe_quoted_list {
467		# Test known and unknown functions.
468		foreach function $functions {
469		    # Linespec version.  Test with and without spacing
470		    # after the source/colon colon separator.
471		    foreach source_sep {"" ":" ": "} {
472			# Skip invalid combinations.
473			if {$source == "" && $source_sep != ""} {
474			    continue
475			}
476			if {$source != "" && $source_sep == ""} {
477			    continue
478			}
479
480			set location "${sqc}${source}${sqc}${source_sep}${fqc}$function${fqc}"
481			uplevel 1 $body_linespec
482		    }
483
484		    # Explicit locations version.
485		    if {$source != ""} {
486			set loc_src "-source ${sqc}${source}${sqc} "
487		    } else {
488			set loc_src ""
489		    }
490
491		    set location "${loc_src}-function ${fqc}$function${fqc}"
492		    uplevel 1 $body_explicit
493		}
494	    }
495	}
496    }
497}
498
499# Same as foreach_locations_functions, but also iterate over
500# combinations of labels.
501proc foreach_location_labels { sources functions labels body_linespec body_explicit } {
502    upvar source source
503    upvar function function
504    upvar label label
505    upvar source_sep source_sep
506    upvar label_sep label_sep
507    upvar location location
508
509    # Test both with a known source file and without a source file
510    # component.
511    foreach_location_functions \
512	$sources \
513	$functions \
514	{
515	    # Linespec version.  Test various spacing around the label
516	    # colon separator.
517	    set saved_location ${location}
518	    foreach label_sep {":" " :" ": " " : "} {
519		# Test both known and unknown label.
520		foreach label $labels {
521		    set location "${saved_location}${label_sep}$label"
522		    uplevel 1 $body_linespec
523		}
524	    }
525	} \
526	{
527	    # Explicit locations version.
528	    set saved_location ${location}
529	    foreach label $labels {
530		set location "${saved_location} -label $label"
531		uplevel 1 $body_explicit
532	    }
533	}
534}
535
536# Check that completion of INPUT_LINE results in GDB completing on all
537# command names.
538proc test_gdb_completion_offers_commands {input_line} {
539    global gdb_prompt
540
541    # There are two many commands to usefully check here.  So we force
542    # max-completions to 2, and check if those 2 come out.
543
544    # Save current max-completions.
545    set max_completions 0
546    set test "show max-completions"
547    gdb_test_multiple $test $test {
548	-re "Maximum number of completion candidates is (.*)\\.\r\n$gdb_prompt $" {
549	    set max_completions $expect_out(1,string)
550	}
551    }
552
553    # Force showing two commands.
554    gdb_test_no_output -nopass "set max-completions 2"
555
556    # TUI adds additional commands to the possible completions, so we
557    # need different patterns depending on whether or not it is enabled.
558    if { [skip_tui_tests] } {
559	test_gdb_complete_multiple $input_line "" "" {
560	    "!"
561	    "actions"
562	} "" "" 1
563    } else {
564	test_gdb_complete_multiple $input_line "" "" {
565	    "!"
566	    "+"
567	} "" "" 1
568    }
569
570    # Restore.
571    gdb_test_no_output -nopass "set max-completions $max_completions"
572}
573