1 # Copyright 2019-2023 Free Software Foundation, Inc.
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.
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.
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/>.
16 # Make it easier to run the 'info modules' command (using
17 # GDBInfoModules), and the 'info module ...' commands (using
18 # GDBInfoModuleContents) and process the output.
20 # The difficulty we run into is that different versions of gFortran
21 # include different helper modules which show up in the results. The
22 # procedures in this library help process those parts of the output we
23 # actually want to check, while ignoring those parts that we don't
26 # For each namespace GDBInfoModules and GDBInfoModuleContents, there's
27 # a run_command proc, use this to run a command and capture the
28 # output. Then make calls to check_header, check_entry, and
29 # check_no_entry to ensure the output was as expected.
31 namespace eval GDBInfoSymbols {
33 # A string that is the header printed by GDB immediately after the
34 # 'info [modules|types|functions|variables]' command has been issued.
37 # A list of entries extracted from the output of the command.
38 # Each entry is a filename, a line number, and the rest of the
39 # text describing the entry. If an entry has no line number then
40 # it is replaced with the text NONE.
43 # The string that is the complete last command run.
44 variable _last_command
46 # Add a new entry to the _entries list.
47 proc _add_entry { filename lineno text } {
50 set entry [list $filename $lineno $text]
51 lappend _entries $entry
54 # Run the 'info modules' command, passing ARGS as extra arguments
55 # to the command. Process the output storing the results within
56 # the variables in this namespace.
58 # The results of any previous call to run_command are discarded
59 # when this is called.
60 proc run_command { cmd { testname "" } } {
65 variable _last_command
67 if {![regexp -- "^info (modules|types|variables|functions)" $cmd]} {
68 perror "invalid command"
73 set _last_command $cmd
75 if { $testname == "" } {
82 # Match the original command echoed back to us.
85 fail "$testname (timeout)"
92 # Found the blank line after the header, we're done
93 # parsing the header now.
95 -re "^\[ \t]*(\[^\r\n\]+)\r\n" {
96 set str $expect_out(1,string)
97 if { $_header == "" } {
100 set _header "$_header $str"
105 fail "$testname (timeout)"
112 -re "^File (\[^\r\n\]+):\r\n" {
113 set current_file $expect_out(1,string)
116 -re "^(\[0-9\]+):\[ \t\]+(\[^\r\n\]+)\r\n" {
117 set lineno $expect_out(1,string)
118 set text $expect_out(2,string)
119 if { $current_file == "" } {
120 fail "$testname (missing filename)"
123 _add_entry $current_file $lineno $text
126 -re "^\[ \t\]+(\[^\r\n\]+)\r\n" {
128 set text $expect_out(1,string)
129 if { $current_file == "" } {
130 fail "$testname (missing filename)"
133 _add_entry $current_file $lineno $text
139 -re "^$gdb_prompt $" {
143 fail "$testname (timeout)"
152 # Check that the header held in _header matches PATTERN. Use
153 # TESTNAME as the name of the test, or create a suitable default
154 # test name based on the last command.
155 proc check_header { pattern { testname "" } } {
157 variable _last_command
159 if { $testname == "" } {
160 set testname "$_last_command: check header"
163 gdb_assert {[regexp -- $pattern $_header]} $testname
166 # Call check_entry_1 with OPTIONAL == 0.
167 proc check_entry { filename lineno text { testname "" } } {
168 check_entry_1 $filename $lineno $text 0 $testname
171 # Call check_entry_1 with OPTIONAL == 1.
172 proc check_optional_entry { filename lineno text { testname "" } } {
173 check_entry_1 $filename $lineno $text 1 $testname
176 # Check that we have an entry in _entries matching FILENAME,
177 # LINENO, and TEXT. If LINENO is the empty string it is replaced
178 # with the string NONE in order to match a similarly missing line
179 # number in the output of the command.
181 # TESTNAME is the name of the test, or a default will be created
182 # based on the last command run and the arguments passed here.
184 # If a matching entry is found then it is removed from the
185 # _entries list, this allows us to check for duplicates using the
186 # check_no_entry call.
187 proc check_entry_1 { filename lineno text optional testname } {
189 variable _last_command
191 if { $testname == "" } {
193 "$_last_command: check for entry '$filename', '$lineno', '$text'"
196 if { $lineno == "" } {
200 set new_entries [list]
203 foreach entry $_entries {
206 set f [lindex $entry 0]
207 set l [lindex $entry 1]
208 set t [lindex $entry 2]
209 if { [regexp -- $filename $f] \
210 && [regexp -- $lineno $l] \
211 && [regexp -- $text $t] } {
214 lappend new_entries $entry
217 lappend new_entries $entry
221 set _entries $new_entries
222 if { $optional && ! $found_match } {
223 unsupported $testname
225 gdb_assert { $found_match } $testname
229 # Check that there is no entry in the _entries list matching
230 # FILENAME, LINENO, and TEXT. The LINENO and TEXT are optional,
231 # and will be replaced with '.*' if missing.
233 # If LINENO is the empty string then it will be replaced with the
234 # string NONE in order to match against missing line numbers in
235 # the output of the command.
237 # TESTNAME is the name of the test, or a default will be built
238 # from the last command run and the arguments passed here.
240 # This can be used after a call to check_entry to ensure that
241 # there are no further matches for a particular file in the
243 proc check_no_entry { filename { lineno ".*" } { text ".*" } \
246 variable _last_command
248 if { $testname == "" } {
250 "$_last_command: check no matches for '$filename', '$lineno', and '$text'"
253 if { $lineno == "" } {
257 foreach entry $_entries {
258 set f [lindex $entry 0]
259 set l [lindex $entry 1]
260 set t [lindex $entry 2]
261 if { [regexp -- $filename $f] \
262 && [regexp -- $lineno $l] \
263 && [regexp -- $text $t] } {
273 namespace eval GDBInfoModuleSymbols {
275 # A string that is the header printed by GDB immediately after the
276 # 'info modules (variables|functions)' command has been issued.
279 # A list of entries extracted from the output of the command.
280 # Each entry is a filename, a module name, a line number, and the
281 # rest of the text describing the entry. If an entry has no line
282 # number then it is replaced with the text NONE.
285 # The string that is the complete last command run.
286 variable _last_command
288 # Add a new entry to the _entries list.
289 proc _add_entry { filename module lineno text } {
292 set entry [list $filename $module $lineno $text]
293 lappend _entries $entry
296 # Run the 'info module ....' command, passing ARGS as extra
297 # arguments to the command. Process the output storing the
298 # results within the variables in this namespace.
300 # The results of any previous call to run_command are discarded
301 # when this is called.
302 proc run_command { cmd { testname "" } } {
307 variable _last_command
309 if {![regexp -- "^info module (variables|functions)" $cmd]} {
310 perror "invalid command: '$cmd'"
315 set _last_command $cmd
317 if { $testname == "" } {
324 # Match the original command echoed back to us.
327 fail "$testname (timeout)"
334 # Found the blank line after the header, we're done
335 # parsing the header now.
337 -re "^\[ \t\]*(\[^\r\n\]+)\r\n" {
338 set str $expect_out(1,string)
339 if { $_header == "" } {
342 set _header "$_header $str"
347 fail "$testname (timeout)"
352 set current_module ""
355 -re "^Module \"(\[^\"\]+)\":\r\n" {
356 set current_module $expect_out(1,string)
359 -re "^File (\[^\r\n\]+):\r\n" {
360 if { $current_module == "" } {
361 fail "$testname (missing module)"
364 set current_file $expect_out(1,string)
367 -re "^(\[0-9\]+):\[ \t\]+(\[^\r\n\]+)\r\n" {
368 set lineno $expect_out(1,string)
369 set text $expect_out(2,string)
370 if { $current_module == "" } {
371 fail "$testname (missing module)"
374 if { $current_file == "" } {
375 fail "$testname (missing filename)"
378 _add_entry $current_file $current_module \
382 -re "^\[ \t\]+(\[^\r\n\]+)\r\n" {
384 set text $expect_out(1,string)
385 if { $current_module == "" } {
386 fail "$testname (missing module)"
389 if { $current_file == "" } {
390 fail "$testname (missing filename)"
393 _add_entry $current_file $current_module \
400 -re "^$gdb_prompt $" {
404 fail "$testname (timeout)"
413 # Check that the header held in _header matches PATTERN. Use
414 # TESTNAME as the name of the test, or create a suitable default
415 # test name based on the last command.
416 proc check_header { pattern { testname "" } } {
418 variable _last_command
420 if { $testname == "" } {
421 set testname "$_last_command: check header"
424 gdb_assert {[regexp -- $pattern $_header]} $testname
427 # Check that we have an entry in _entries matching FILENAME,
428 # MODULE, LINENO, and TEXT. If LINENO is the empty string it is
429 # replaced with the string NONE in order to match a similarly
430 # missing line number in the output of the command.
432 # TESTNAME is the name of the test, or a default will be created
433 # based on the last command run and the arguments passed here.
435 # If a matching entry is found then it is removed from the
436 # _entries list, this allows us to check for duplicates using the
437 # check_no_entry call.
439 # If OPTIONAL, don't generate a FAIL for a mismatch, but use UNSUPPORTED
441 proc check_entry_1 { filename module lineno text optional testname } {
443 variable _last_command
445 if { $testname == "" } {
447 "$_last_command: check for entry '$filename', '$lineno', '$text'"
450 if { $lineno == "" } {
454 set new_entries [list]
457 foreach entry $_entries {
460 set f [lindex $entry 0]
461 set m [lindex $entry 1]
462 set l [lindex $entry 2]
463 set t [lindex $entry 3]
464 if { [regexp -- $filename $f] \
465 && [regexp -- $module $m] \
466 && [regexp -- $lineno $l] \
467 && [regexp -- $text $t] } {
470 lappend new_entries $entry
473 lappend new_entries $entry
477 set _entries $new_entries
478 if { $optional && ! $found_match } {
479 unsupported $testname
481 gdb_assert { $found_match } $testname
485 # Call check_entry_1 with OPTIONAL == 0.
486 proc check_entry { filename module lineno text { testname "" } } {
487 check_entry_1 $filename $module $lineno $text 0 $testname
490 # Call check_entry_1 with OPTIONAL == 1.
491 proc check_optional_entry { filename module lineno text { testname "" } } {
492 check_entry_1 $filename $module $lineno $text 1 $testname
495 # Check that there is no entry in the _entries list matching
496 # FILENAME, MODULE, LINENO, and TEXT. The LINENO and TEXT are
497 # optional, and will be replaced with '.*' if missing.
499 # If LINENO is the empty string then it will be replaced with the
500 # string NONE in order to match against missing line numbers in
501 # the output of the command.
503 # TESTNAME is the name of the test, or a default will be built
504 # from the last command run and the arguments passed here.
506 # This can be used after a call to check_entry to ensure that
507 # there are no further matches for a particular file in the
509 proc check_no_entry { filename module { lineno ".*" } \
510 { text ".*" } { testname "" } } {
512 variable _last_command
514 if { $testname == "" } {
516 "$_last_command: check no matches for '$filename', '$lineno', and '$text'"
519 if { $lineno == "" } {
523 foreach entry $_entries {
524 set f [lindex $entry 0]
525 set m [lindex $entry 1]
526 set l [lindex $entry 2]
527 set t [lindex $entry 3]
528 if { [regexp -- $filename $f] \
529 && [regexp -- $module $m] \
530 && [regexp -- $lineno $l] \
531 && [regexp -- $text $t] } {