1 # Copyright 2019-2020 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 # Check that we have an entry in _entries matching FILENAME,
167 # LINENO, and TEXT. If LINENO is the empty string it is replaced
168 # with the string NONE in order to match a similarly missing line
169 # number in the output of the command.
171 # TESTNAME is the name of the test, or a default will be created
172 # based on the last command run and the arguments passed here.
174 # If a matching entry is found then it is removed from the
175 # _entries list, this allows us to check for duplicates using the
176 # check_no_entry call.
177 proc check_entry { filename lineno text { testname "" } } {
179 variable _last_command
181 if { $testname == "" } {
183 "$_last_command: check for entry '$filename', '$lineno', '$text'"
186 if { $lineno == "" } {
190 set new_entries [list]
193 foreach entry $_entries {
196 set f [lindex $entry 0]
197 set l [lindex $entry 1]
198 set t [lindex $entry 2]
199 if { [regexp -- $filename $f] \
200 && [regexp -- $lineno $l] \
201 && [regexp -- $text $t] } {
204 lappend new_entries $entry
207 lappend new_entries $entry
211 set _entries $new_entries
212 gdb_assert { $found_match } $testname
215 # Check that there is no entry in the _entries list matching
216 # FILENAME, LINENO, and TEXT. The LINENO and TEXT are optional,
217 # and will be replaced with '.*' if missing.
219 # If LINENO is the empty string then it will be replaced with the
220 # string NONE in order to match against missing line numbers in
221 # the output of the command.
223 # TESTNAME is the name of the test, or a default will be built
224 # from the last command run and the arguments passed here.
226 # This can be used after a call to check_entry to ensure that
227 # there are no further matches for a particular file in the
229 proc check_no_entry { filename { lineno ".*" } { text ".*" } \
232 variable _last_command
234 if { $testname == "" } {
236 "$_last_command: check no matches for '$filename', '$lineno', and '$text'"
239 if { $lineno == "" } {
243 foreach entry $_entries {
244 set f [lindex $entry 0]
245 set l [lindex $entry 1]
246 set t [lindex $entry 2]
247 if { [regexp -- $filename $f] \
248 && [regexp -- $lineno $l] \
249 && [regexp -- $text $t] } {
259 namespace eval GDBInfoModuleSymbols {
261 # A string that is the header printed by GDB immediately after the
262 # 'info modules (variables|functions)' command has been issued.
265 # A list of entries extracted from the output of the command.
266 # Each entry is a filename, a module name, a line number, and the
267 # rest of the text describing the entry. If an entry has no line
268 # number then it is replaced with the text NONE.
271 # The string that is the complete last command run.
272 variable _last_command
274 # Add a new entry to the _entries list.
275 proc _add_entry { filename module lineno text } {
278 set entry [list $filename $module $lineno $text]
279 lappend _entries $entry
282 # Run the 'info module ....' command, passing ARGS as extra
283 # arguments to the command. Process the output storing the
284 # results within the variables in this namespace.
286 # The results of any previous call to run_command are discarded
287 # when this is called.
288 proc run_command { cmd { testname "" } } {
293 variable _last_command
295 if {![regexp -- "^info module (variables|functions)" $cmd]} {
296 perror "invalid command: '$cmd'"
301 set _last_command $cmd
303 if { $testname == "" } {
310 # Match the original command echoed back to us.
313 fail "$testname (timeout)"
320 # Found the blank line after the header, we're done
321 # parsing the header now.
323 -re "^\[ \t\]*(\[^\r\n\]+)\r\n" {
324 set str $expect_out(1,string)
325 if { $_header == "" } {
328 set _header "$_header $str"
333 fail "$testname (timeout)"
338 set current_module ""
341 -re "^Module \"(\[^\"\]+)\":\r\n" {
342 set current_module $expect_out(1,string)
345 -re "^File (\[^\r\n\]+):\r\n" {
346 if { $current_module == "" } {
347 fail "$testname (missing module)"
350 set current_file $expect_out(1,string)
353 -re "^(\[0-9\]+):\[ \t\]+(\[^\r\n\]+)\r\n" {
354 set lineno $expect_out(1,string)
355 set text $expect_out(2,string)
356 if { $current_module == "" } {
357 fail "$testname (missing module)"
360 if { $current_file == "" } {
361 fail "$testname (missing filename)"
364 _add_entry $current_file $current_module \
368 -re "^\[ \t\]+(\[^\r\n\]+)\r\n" {
370 set text $expect_out(1,string)
371 if { $current_module == "" } {
372 fail "$testname (missing module)"
375 if { $current_file == "" } {
376 fail "$testname (missing filename)"
379 _add_entry $current_file $current_module \
386 -re "^$gdb_prompt $" {
390 fail "$testname (timeout)"
399 # Check that the header held in _header matches PATTERN. Use
400 # TESTNAME as the name of the test, or create a suitable default
401 # test name based on the last command.
402 proc check_header { pattern { testname "" } } {
404 variable _last_command
406 if { $testname == "" } {
407 set testname "$_last_command: check header"
410 gdb_assert {[regexp -- $pattern $_header]} $testname
413 # Check that we have an entry in _entries matching FILENAME,
414 # MODULE, LINENO, and TEXT. If LINENO is the empty string it is
415 # replaced with the string NONE in order to match a similarly
416 # missing line number in the output of the command.
418 # TESTNAME is the name of the test, or a default will be created
419 # based on the last command run and the arguments passed here.
421 # If a matching entry is found then it is removed from the
422 # _entries list, this allows us to check for duplicates using the
423 # check_no_entry call.
424 proc check_entry { filename module lineno text { testname "" } } {
426 variable _last_command
428 if { $testname == "" } {
430 "$_last_command: check for entry '$filename', '$lineno', '$text'"
433 if { $lineno == "" } {
437 set new_entries [list]
440 foreach entry $_entries {
443 set f [lindex $entry 0]
444 set m [lindex $entry 1]
445 set l [lindex $entry 2]
446 set t [lindex $entry 3]
447 if { [regexp -- $filename $f] \
448 && [regexp -- $module $m] \
449 && [regexp -- $lineno $l] \
450 && [regexp -- $text $t] } {
453 lappend new_entries $entry
456 lappend new_entries $entry
460 set _entries $new_entries
461 gdb_assert { $found_match } $testname
464 # Check that there is no entry in the _entries list matching
465 # FILENAME, MODULE, LINENO, and TEXT. The LINENO and TEXT are
466 # optional, and will be replaced with '.*' if missing.
468 # If LINENO is the empty string then it will be replaced with the
469 # string NONE in order to match against missing line numbers in
470 # the output of the command.
472 # TESTNAME is the name of the test, or a default will be built
473 # from the last command run and the arguments passed here.
475 # This can be used after a call to check_entry to ensure that
476 # there are no further matches for a particular file in the
478 proc check_no_entry { filename module { lineno ".*" } \
479 { text ".*" } { testname "" } } {
481 variable _last_command
483 if { $testname == "" } {
485 "$_last_command: check no matches for '$filename', '$lineno', and '$text'"
488 if { $lineno == "" } {
492 foreach entry $_entries {
493 set f [lindex $entry 0]
494 set m [lindex $entry 1]
495 set l [lindex $entry 2]
496 set t [lindex $entry 3]
497 if { [regexp -- $filename $f] \
498 && [regexp -- $module $m] \
499 && [regexp -- $lineno $l] \
500 && [regexp -- $text $t] } {