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