This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RFC: Support for conditional regexps in dumps
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: binutils at sourceware dot org
- Date: Sat, 20 Nov 2010 15:41:18 +0000
- Subject: RFC: Support for conditional regexps in dumps
I was looking at cleaning up the testsuite results for mips-sgi-irix6.5,
given David Cross's recent post that it's still working pretty well.
A lot of the gas testsuite failures are due to R_MIPS_JALR relocation
hints that aren't present for IRIX o32. (Using them for o32 is a GNU
extension that the SGI tools don't understand.)
It seems a shame to add whole new dumps just for that. What do you
think about adding support for conditional regexp matching?
As a Tcl fan, I wondered about making the conditions normal Tcl
expressions. That seemed like a bad idea for several reasons:
- Some people want the tests to be as declarative as possible,
so that it's possible to use them with harnesses other than dejagnu.
- It would have led to the temptation to use chains of [istarget ...]
tests instead of feature tests. That is, if a new target is added
that has the same quirk as some existing target, the tendancy is to
go through all the [istarget old_target] tests and add
"|| [istarget new_target]", rather than turning the test into
a feature test.
- It would probably have led to the need for multi-line conditions,
which would have made the whole thing more complicated.
So how about the attached version? I've included a specimen testsuite
change to show how it would be used.
Richard
binutils/testsuite/
* lib/binutils-common.exp (regexp_diff): Add support for #if,
#elseif, #else and #endif.
* lib/target-conditions.exp: New file.
gas/testsuite/
* gas/mips/jal-svr4pic.d: Don't expect R_MIPS_JALRs on IRIX.
Index: binutils/testsuite/lib/binutils-common.exp
===================================================================
--- binutils/testsuite/lib/binutils-common.exp 2010-11-20 15:10:38.000000000 +0000
+++ binutils/testsuite/lib/binutils-common.exp 2010-11-20 15:10:51.000000000 +0000
@@ -18,6 +18,8 @@
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
+load_common_lib target-conditions.exp
+
# True if the object format is known to be ELF.
#
proc is_elf_format {} {
@@ -163,6 +165,18 @@ proc is_elf64 { binary_file } {
# #failif
# Reverse the sense of the test: expect differences to exist.
#
+# #if COND
+# ...REGEXPS...
+# #elseif COND
+# ...REGEXPS...
+# #else
+# ...REGEXPS...
+# #endif
+# Conditionally select regexps based on target conditions
+# (see target-conditions.exp). Conditional blocks can be
+# nested in the normal way. There can zero of more #elseifs
+# and the #else is optional.
+#
# #...
# REGEXP
# Skip all lines in FILE_1 until the first that matches REGEXP.
@@ -210,6 +224,12 @@ proc regexp_diff { file_1 file_2 args }
verbose " Regexp-diff'ing: $file_1 $file_2" 2
+ # a list of if-then-else conditions, with the innermost last. bit 0
+ # is set if the current "if" is true, bit 1 is set if a previous "if"
+ # was true, and bit 2 is set if an "else" was found.
+ set conditions {}
+ set skip 0
+ set error 0
while { 1 } {
set line_a ""
set line_b ""
@@ -220,8 +240,46 @@ proc regexp_diff { file_1 file_2 args }
break
}
}
- while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
- if { [string match "#pass" $line_b] } {
+ while { [string length $line_b] == 0
+ || [string match "#*" $line_b]
+ || $skip } {
+ if { [string match "#if *" $line_b] } {
+ set error [catch {
+ lappend conditions [target_condition [lindex $line_b 1]]
+ } msg]
+ } elseif { [string match "#elseif *" $line_b] } {
+ set error [catch {
+ if { [llength $conditions] < 1 } {
+ error "misplaced #elseif"
+ }
+ if { [lindex $conditions end] & 4 } {
+ error "#elseif after #else"
+ }
+ lset conditions end \
+ [expr {(([lindex $conditions end] & 1) << 1)
+ | [target_condition [lindex $line_b 1]]}]
+ } msg]
+ } elseif { [string match "#else" $line_b] } {
+ set error [catch {
+ if { [llength $conditions] < 1 } {
+ error "misplaced #else"
+ }
+ if { [lindex $conditions end] & 4 } {
+ error "#else after #else"
+ }
+ lset conditions end \
+ [expr {(([lindex $conditions end] & 1) << 1) | 5}]
+ } msg]
+ } elseif { [string match "#endif" $line_b] } {
+ set error [catch {
+ if { [llength $conditions] < 1 } {
+ error "misplaced #endif"
+ }
+ set conditions [lreplace $conditions end end]
+ } msg]
+ } elseif { $skip } {
+ # Ignore any other directives.
+ } elseif { [string match "#pass" $line_b] } {
set end_2 1
set diff_pass 1
break
@@ -249,13 +307,27 @@ proc regexp_diff { file_1 file_2 args }
}
break
}
+ if { $error } {
+ break
+ }
if { [gets $file_b line_b] == $eof } {
set end_2 1
+ set error [catch {
+ if { [llength $conditions] > 0 } {
+ error "unclosed #if"
+ }
+ } msg]
break
}
+ set skip [expr {[llength $conditions] > 0
+ && ([lindex $conditions end] & 3) != 1}]
}
- if { $diff_pass } {
+ if { $error } {
+ perror "$file_2: $msg"
+ set differences 1
+ break
+ } elseif { $diff_pass } {
break
} elseif { $end_1 && $end_2 } {
break
Index: binutils/testsuite/lib/target-conditions.exp
===================================================================
--- /dev/null 2010-11-20 09:08:08.118111512 +0000
+++ binutils/testsuite/lib/target-conditions.exp 2010-11-20 15:10:51.000000000 +0000
@@ -0,0 +1,43 @@
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# Set a target condition that can be tested by target_condition.
+# NAME is the name of the condition and VALUE is the boolean value.
+proc set_target_condition { name value } {
+ global targetcond
+ set targetcond($name) [uplevel expr $value]
+}
+
+# Return the boolean value of target condition NAME. A leading
+# "!" inverts the condition.
+proc target_condition { name } {
+ global targetcond
+
+ if { ![regexp -- "(!?)(.*)" $name dummy prefix name]
+ || ![info exists targetcond($name)] } {
+ error "undefined target condition: $name"
+ }
+ return [expr $prefix$targetcond($name)]
+}
+
+# Put target conditions here, so that they can be used by both
+# target-independent and target-dependent tests.
+
+# Target tests
+set_target_condition irix [istarget "mips*-*-irix*"]
Index: gas/testsuite/gas/mips/jal-svr4pic.d
===================================================================
--- gas/testsuite/gas/mips/jal-svr4pic.d 2010-11-20 15:10:38.000000000 +0000
+++ gas/testsuite/gas/mips/jal-svr4pic.d 2010-11-20 15:10:51.000000000 +0000
@@ -24,19 +24,25 @@ Disassembly of section \.text:
[0-9a-f]+ <[^>]*> 27390000 addiu t9,t9,0
[ ]*28: R_MIPS_LO16 .text
[0-9a-f]+ <[^>]*> 0320f809 jalr t9
+#if !irix
[ ]*2c: R_MIPS_JALR text_label
+#endif
[0-9a-f]+ <[^>]*> 00000000 nop
[0-9a-f]+ <[^>]*> 8fbc0000 lw gp,0\(sp\)
[0-9a-f]+ <[^>]*> 8f990000 lw t9,0\(gp\)
[ ]*38: R_MIPS_CALL16 weak_text_label
[0-9a-f]+ <[^>]*> 0320f809 jalr t9
+#if !irix
[ ]*3c: R_MIPS_JALR weak_text_label
+#endif
[0-9a-f]+ <[^>]*> 00000000 nop
[0-9a-f]+ <[^>]*> 8fbc0000 lw gp,0\(sp\)
[0-9a-f]+ <[^>]*> 8f990000 lw t9,0\(gp\)
[ ]*48: R_MIPS_CALL16 external_text_label
[0-9a-f]+ <[^>]*> 0320f809 jalr t9
+#if !irix
[ ]*4c: R_MIPS_JALR external_text_label
+#endif
[0-9a-f]+ <[^>]*> 00000000 nop
[0-9a-f]+ <[^>]*> 1000ffea b 0+0000 <text_label>
[0-9a-f]+ <[^>]*> 8fbc0000 lw gp,0\(sp\)