1# Copyright 2017-2019 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 {"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 gdb_test_multiple "" "$test" { 112 -re "^$complete_line_re$append_char_re$" { 113 pass "$test" 114 } 115 } 116 117 clear_input_line $test 118} 119 120# Test that completing INPUT_LINE with TAB completes to "INPUT_LINE + 121# ADD_COMPLETED_LINE" and that it displays the completion matches in 122# COMPLETION_LIST. 123 124proc test_gdb_complete_tab_multiple { input_line add_completed_line \ 125 completion_list } { 126 global gdb_prompt 127 128 set input_line_re [string_to_regexp $input_line] 129 set add_completed_line_re [string_to_regexp $add_completed_line] 130 131 set expected_re [make_tab_completion_list_re $completion_list] 132 133 set test "tab complete \"$input_line\"" 134 send_gdb "$input_line\t" 135 gdb_test_multiple "" "$test (first tab)" { 136 -re "^${input_line_re}${completion::bell_re}$add_completed_line_re$" { 137 send_gdb "\t" 138 # If we auto-completed to an ambiguous prefix, we need an 139 # extra tab to show the matches list. 140 if {$add_completed_line != ""} { 141 send_gdb "\t" 142 set maybe_bell ${completion::bell_re} 143 } else { 144 set maybe_bell "" 145 } 146 gdb_test_multiple "" "$test (second tab)" { 147 -re "^${maybe_bell}\r\n$expected_re\r\n$gdb_prompt $input_line_re$add_completed_line_re$" { 148 pass "$test" 149 } 150 } 151 } 152 } 153 154 clear_input_line $test 155} 156 157# Test that completing LINE with the complete command completes to 158# nothing. 159 160proc test_gdb_complete_cmd_none { line } { 161 gdb_test_no_output "complete $line" "cmd complete \"$line\"" 162} 163 164# Test that completing LINE with the complete command completes to 165# COMPLETE_LINE_RE. 166 167proc test_gdb_complete_cmd_unique { input_line complete_line_re } { 168 global gdb_prompt 169 170 set cmd "complete $input_line" 171 set cmd_re [string_to_regexp $cmd] 172 set test "cmd complete \"$input_line\"" 173 gdb_test_multiple $cmd $test { 174 -re "^$cmd_re\r\n$complete_line_re\r\n$gdb_prompt $" { 175 pass $test 176 } 177 } 178} 179 180# Test that completing "CMD_PREFIX + COMPLETION_WORD" with the 181# complete command displays the COMPLETION_LIST completion list. Each 182# entry in the list should be prefixed by CMD_PREFIX. 183 184proc test_gdb_complete_cmd_multiple { cmd_prefix completion_word completion_list {start_quote_char ""} {end_quote_char ""} } { 185 global gdb_prompt 186 187 set expected_re [make_cmd_completion_list_re $cmd_prefix $completion_list $start_quote_char $end_quote_char] 188 set cmd_re [string_to_regexp "complete $cmd_prefix$completion_word"] 189 set test "cmd complete \"$cmd_prefix$completion_word\"" 190 gdb_test_multiple "complete $cmd_prefix$completion_word" $test { 191 -re "^$cmd_re\r\n$expected_re$gdb_prompt $" { 192 pass $test 193 } 194 } 195} 196 197# Test that completing LINE completes to nothing. 198 199proc test_gdb_complete_none { input_line } { 200 test_gdb_complete_tab_none $input_line 201 test_gdb_complete_cmd_none $input_line 202} 203 204# Test that completing INPUT_LINE completes to COMPLETE_LINE_RE. 205# 206# APPEND_CHAR is the character expected to be appended after 207# EXPECTED_OUTPUT when TAB completing. Normally that's a whitespace, 208# but in some cases it's some other character, like a colon. 209# 210# If MAX_COMPLETIONS is true, then we expect the completion to hit the 211# max-completions limit. Since we're expecting a unique completion 212# match, this will only be visible in the "complete" command output. 213# Tab completion will just auto-complete the only match and won't 214# display a match list. 215# 216# Note: usually it's more convenient to pass a literal string instead 217# of a regular expression (as COMPLETE_LINE_RE). See 218# test_gdb_complete_unique below. 219 220proc test_gdb_complete_unique_re { input_line complete_line_re {append_char " "} {max_completions 0}} { 221 set append_char_re [string_to_regexp $append_char] 222 test_gdb_complete_tab_unique $input_line $complete_line_re $append_char_re 223 224 # Trim INPUT_LINE and COMPLETE LINE, for the case we're completing 225 # a command with leading whitespace. Leading command whitespace 226 # is discarded by GDB. 227 set input_line [string trimleft $input_line] 228 set expected_output_re [string trimleft $complete_line_re] 229 if {$append_char_re != " "} { 230 append expected_output_re $append_char_re 231 } 232 if {$max_completions} { 233 set max_completion_reached_msg \ 234 "*** List may be truncated, max-completions reached. ***" 235 set input_line_re \ 236 [string_to_regexp $input_line] 237 set max_completion_reached_msg_re \ 238 [string_to_regexp $max_completion_reached_msg] 239 240 append expected_output_re \ 241 "\r\n$input_line_re $max_completion_reached_msg_re" 242 } 243 244 test_gdb_complete_cmd_unique $input_line $expected_output_re 245} 246 247# Like TEST_GDB_COMPLETE_UNIQUE_RE, but COMPLETE_LINE is a string, not 248# a regular expression. 249 250proc test_gdb_complete_unique { input_line complete_line {append_char " "} {max_completions 0}} { 251 set complete_line_re [string_to_regexp $complete_line] 252 test_gdb_complete_unique_re $input_line $complete_line_re $append_char $max_completions 253} 254 255# Test that completing "CMD_PREFIX + COMPLETION_WORD" adds 256# ADD_COMPLETED_LINE to the input line, and that it displays 257# COMPLETION_LIST as completion match list. COMPLETION_WORD is the 258# completion word. 259 260proc test_gdb_complete_multiple { cmd_prefix completion_word add_completed_line completion_list {start_quote_char ""} {end_quote_char ""}} { 261 test_gdb_complete_tab_multiple "$cmd_prefix$completion_word" $add_completed_line $completion_list 262 test_gdb_complete_cmd_multiple $cmd_prefix $completion_word $completion_list $start_quote_char $end_quote_char 263} 264 265# Test that all the substring prefixes of INPUT from [0..START) to 266# [0..END) complete to COMPLETION_RE (a regular expression). If END 267# is ommitted, default to the length of INPUT. 268 269proc test_complete_prefix_range_re {input completion_re start {end -1}} { 270 if {$end == -1} { 271 set end [string length $input] 272 } 273 274 for {set i $start} {$i < $end} {incr i} { 275 set line [string range $input 0 $i] 276 test_gdb_complete_unique_re "$line" $completion_re 277 } 278} 279 280# Test that all the substring prefixes of COMPLETION from [0..START) 281# to [0..END) complete to COMPLETION. If END is ommitted, default to 282# the length of COMPLETION. 283 284proc test_complete_prefix_range {completion start {end -1}} { 285 set completion_re [string_to_regexp $completion] 286 test_complete_prefix_range_re $completion $completion_re $start $end 287} 288 289# Find NEEDLE in HAYSTACK and return the index _after_ NEEDLE. E.g., 290# searching for "(" in "foo(int)" returns 4, which would be useful if 291# you want to find the "(" to try completing "foo(". 292 293proc index_after {needle haystack} { 294 set start [string first $needle $haystack] 295 if {$start == -1} { 296 error "could not find \"$needle\" in \"$haystack\"" 297 } 298 return [expr $start + [string length $needle]] 299} 300 301# Create a breakpoint using BREAK_COMMAND, and return the number 302# of locations found. 303 304proc completion::_create_bp {break_command} { 305 global gdb_prompt 306 global decimal hex 307 308 set found_locations -1 309 310 set test "set breakpoint" 311 gdb_test_multiple "$break_command" $test { 312 -re "\\\(\($decimal\) locations\\\)\r\n$gdb_prompt $" { 313 set found_locations "$expect_out(1,string)" 314 } 315 -re "Breakpoint $decimal at $hex: file .*, line .*$gdb_prompt $" { 316 set found_locations 1 317 } 318 -re "Make breakpoint pending on future shared library load.*y or .n.. $" { 319 send_gdb "n\n" 320 gdb_test_multiple "" "$test (prompt)" { 321 -re "$gdb_prompt $" { 322 } 323 } 324 set found_locations 0 325 } 326 -re "invalid explicit location argument, \[^\r\n\]*\r\n$gdb_prompt $" { 327 set found_locations 0 328 } 329 -re "Function \[^\r\n\]* not defined in \[^\r\n\]*\r\n$gdb_prompt $" { 330 set found_locations 0 331 } 332 } 333 return $found_locations 334} 335 336# Return true if lists A and B have the same elements. Order of 337# elements does not matter. 338 339proc completion::_leq {a b} { 340 return [expr {[lsort $a] eq [lsort $b]}] 341} 342 343# Check that trying to create a breakpoint using BREAK_COMMAND fails. 344 345proc check_setting_bp_fails {break_command} { 346 with_test_prefix "\"$break_command\" creates no bp locations" { 347 set found_locations [completion::_create_bp $break_command] 348 gdb_assert {$found_locations == 0} "matches" 349 if {$found_locations != 0} { 350 delete_breakpoints 351 } 352 } 353} 354 355# Check that creating the breakpoint using BREAK_COMMAND finds the 356# same breakpoint locations as completing BREAK_COMMAND. 357# COMPLETION_LIST is the expected completion match list. 358 359proc check_bp_locations_match_list {break_command completion_list} { 360 global gdb_prompt 361 global hex 362 363 with_test_prefix "compare \"$break_command\" completion list with bp location list" { 364 set num_locations [completion::_create_bp $break_command] 365 366 set found_list "" 367 368 set any "\[^\r\n\]*" 369 370 gdb_test_multiple "info breakpoint \$bpnum" "info breakpoint" { 371 -re "in \(\[^\r\n\]*\) at " { 372 # A function location. 373 set found_location "$expect_out(1,string)" 374 lappend found_list $found_location 375 exp_continue 376 } 377 -re "breakpoint${any}keep${any}y${any}$hex\[ \t]*\(${any}\)\r\n" { 378 # A label location. 379 set found_location "$expect_out(1,string)" 380 lappend found_list $found_location 381 exp_continue 382 } 383 -re "$gdb_prompt $" { 384 } 385 } 386 387 gdb_assert {[completion::_leq $found_list $completion_list]} "matches" 388 389 delete_breakpoints 390 } 391} 392 393# Build linespec and explicit locations out of all the combinations of 394# SOURCES, FUNCTIONS and LABELS, with all combinations of possible 395# quoting and whitespace around separators, and run BODY_LINESPEC and 396# BODY_EXPLICIT in the context of the caller for each combination. A 397# variable named "location" is set in the callers context with the 398# currently iterated location. 399 400proc foreach_location_functions { sources functions body_linespec body_explicit } { 401 upvar source source 402 upvar function function 403 upvar source_sep source_sep 404 upvar location location 405 406 foreach source $sources { 407 # Test with and without source quoting. 408 foreach sqc $completion::maybe_quoted_list { 409 if {$source == "" && $sqc != ""} { 410 # Invalid combination. 411 continue 412 } 413 414 # Test with and without function quoting. 415 foreach fqc $completion::maybe_quoted_list { 416 # Test known and unknown functions. 417 foreach function $functions { 418 # Linespec version. Test with and without spacing 419 # after the source/colon colon separator. 420 foreach source_sep {"" ":" ": "} { 421 # Skip invalid combinations. 422 if {$source == "" && $source_sep != ""} { 423 continue 424 } 425 if {$source != "" && $source_sep == ""} { 426 continue 427 } 428 429 set location "${sqc}${source}${sqc}${source_sep}${fqc}$function${fqc}" 430 uplevel 1 $body_linespec 431 } 432 433 # Explicit locations version. 434 if {$source != ""} { 435 set loc_src "-source ${sqc}${source}${sqc} " 436 } else { 437 set loc_src "" 438 } 439 440 set location "${loc_src}-function ${fqc}$function${fqc}" 441 uplevel 1 $body_explicit 442 } 443 } 444 } 445 } 446} 447 448# Same as foreach_locations_functions, but also iterate over 449# combinations of labels. 450proc foreach_location_labels { sources functions labels body_linespec body_explicit } { 451 upvar source source 452 upvar function function 453 upvar label label 454 upvar source_sep source_sep 455 upvar label_sep label_sep 456 upvar location location 457 458 # Test both with a known source file and without a source file 459 # component. 460 foreach_location_functions \ 461 $sources \ 462 $functions \ 463 { 464 # Linespec version. Test various spacing around the label 465 # colon separator. 466 set saved_location ${location} 467 foreach label_sep {":" " :" ": " " : "} { 468 # Test both known and unknown label. 469 foreach label $labels { 470 set location "${saved_location}${label_sep}$label" 471 uplevel 1 $body_linespec 472 } 473 } 474 } \ 475 { 476 # Explicit locations version. 477 set saved_location ${location} 478 foreach label $labels { 479 set location "${saved_location} -label $label" 480 uplevel 1 $body_explicit 481 } 482 } 483} 484