Commit generated files for 2.12.1.
[binutils.git] / gas / testsuite / lib / gas-defs.exp
blobe695abf7cb63f2c732759efa0490d39b63d735a3
1 # Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001 Free Software
2 # Foundation, Inc.
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
8
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
18 # Please email any bugs, comments, and/or additions to this file to:
19 # DejaGnu@cygnus.com
21 # This file was written by Ken Raeburn (raeburn@cygnus.com).
23 proc gas_version {} {
24     global AS
25     catch "exec $AS -version < /dev/null" tmp
26     # Should find a way to discard constant parts, keep whatever's
27     # left, so the version string could be almost anything at all...
28     regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
29     if ![info exists number] then {
30         return "[which $AS] (no version number)\n"
31     }
32     clone_output "[which $AS] $number\n"
33     unset version
36 proc gas_run { prog as_opts redir } {
37     global AS
38     global ASFLAGS
39     global comp_output
40     global srcdir
41     global subdir
42     global host_triplet
44     verbose "Executing $srcdir/lib/run $AS $ASFLAGS $as_opts $srcdir/$subdir/$prog $redir"
45     catch "exec $srcdir/lib/run $AS $ASFLAGS $as_opts $srcdir/$subdir/$prog $redir" comp_output
46     set comp_output [prune_warnings $comp_output]
47     verbose "output was $comp_output"
48     return [list $comp_output ""];
51 proc all_ones { args } {
52     foreach x $args { if [expr $x!=1] { return 0 } }
53     return 1
56 proc gas_start { prog as_opts } {
57     global AS
58     global ASFLAGS
59     global srcdir
60     global subdir
61     global spawn_id
63     verbose "Starting $AS $ASFLAGS $as_opts $prog" 2
64     catch {
65         spawn -noecho -nottycopy $srcdir/lib/run $AS $ASFLAGS $as_opts $srcdir/$subdir/$prog
66     } foo
67     if ![regexp {^[0-9]+} $foo] then {
68         perror "Can't run $subdir/$prog: $foo"
69     }
72 proc gas_finish { } {
73     global spawn_id
75     catch "close"
76     catch "wait"
79 proc want_no_output { testname } {
80     global comp_output
82     if ![string match "" $comp_output] then {
83         send_log "$comp_output\n"
84         verbose "$comp_output" 3
85     }
86     if [string match "" $comp_output] then {
87         pass "$testname"
88         return 1
89     } else {
90         fail "$testname"
91         return 0
92     }
95 proc gas_test_old { file as_opts testname } {
96     gas_run $file $as_opts ""
97     return [want_no_output $testname]
100 proc gas_test { file as_opts var_opts testname } {
101     global comp_output
103     set i 0
104     foreach word $var_opts {
105         set ignore_stdout($i) [string match "*>" $word]
106         set opt($i) [string trim $word {>}]
107         incr i
108     }
109     set max [expr 1<<$i]
110     for {set i 0} {[expr $i<$max]} {incr i} {
111         set maybe_ignore_stdout ""
112         set extra_opts ""
113         for {set bit 0} {(1<<$bit)<$max} {incr bit} {
114             set num [expr 1<<$bit]
115             if [expr $i&$num] then {
116                 set extra_opts "$extra_opts $opt($bit)"
117                 if $ignore_stdout($bit) then {
118                     set maybe_ignore_stdout ">/dev/null"
119                 }
120             }
121         }
122         set extra_opts [string trim $extra_opts]
123         gas_run $file "$as_opts $extra_opts" $maybe_ignore_stdout
125         # Should I be able to use a conditional expression here?
126         if [string match "" $extra_opts] then {
127             want_no_output $testname
128         } else {
129             want_no_output "$testname ($extra_opts)"
130         }
131     }
132     if [info exists errorInfo] then {
133         unset errorInfo
134     }
137 proc gas_test_ignore_stdout { file as_opts testname } {
138     global comp_output
140     gas_run $file $as_opts ">/dev/null"
141     want_no_output $testname
144 proc gas_test_error { file as_opts testname } {
145     global comp_output
147     gas_run $file $as_opts ">/dev/null"
148     if ![string match "" $comp_output] then {
149         send_log "$comp_output\n"
150         verbose "$comp_output" 3
151     }
152     if [string match "" $comp_output] then {
153         fail "$testname"
154     } else {
155         pass "$testname"
156     }
159 proc gas_exit {} {}
161 proc gas_init { args } {
162     global target_cpu
163     global target_cpu_family
164     global target_family
165     global target_vendor
166     global target_os
167     global stdoptlist
169     case "$target_cpu" in {
170         "m68???"                { set target_cpu_family m68k }
171         "i[34]86"               { set target_cpu_family i386 }
172         default                 { set target_cpu_family $target_cpu }
173     }
175     set target_family "$target_cpu_family-$target_vendor-$target_os"
176     set stdoptlist "-a>"
178     if ![istarget "*-*-*"] {
179         perror "Target name [istarget] is not a triple."
180     }
181     # Need to return an empty string.
182     return
186 # run_dump_test FILE 
188 # Assemble a .s file, then run some utility on it and check the output.
190 # There should be an assembly language file named FILE.s in the test
191 # suite directory, and a pattern file called FILE.d.  `run_dump_test'
192 # will assemble FILE.s, run some tool like `objdump', `objcopy', or
193 # `nm' on the .o file to produce textual output, and then analyze that
194 # with regexps.  The FILE.d file specifies what program to run, and
195 # what to expect in its output.
197 # The FILE.d file begins with zero or more option lines, which specify
198 # flags to pass to the assembler, the program to run to dump the
199 # assembler's output, and the options it wants.  The option lines have
200 # the syntax:
202 #         # OPTION: VALUE
204 # OPTION is the name of some option, like "name" or "objdump", and
205 # VALUE is OPTION's value.  The valid options are described below.
206 # Whitespace is ignored everywhere, except within VALUE.  The option
207 # list ends with the first line that doesn't match the above syntax
208 # (hmm, not great for error detection).
210 # The interesting options are:
212 #   name: TEST-NAME
213 #       The name of this test, passed to DejaGNU's `pass' and `fail'
214 #       commands.  If omitted, this defaults to FILE, the root of the
215 #       .s and .d files' names.
217 #   as: FLAGS
218 #       When assembling FILE.s, pass FLAGS to the assembler.
220 #   PROG: PROGRAM-NAME
221 #       The name of the program to run to analyze the .o file produced
222 #       by the assembler.  This can be omitted; run_dump_test will guess
223 #       which program to run by seeing which of the flags options below
224 #       is present.
226 #   objdump: FLAGS
227 #   nm: FLAGS
228 #   objcopy: FLAGS
229 #       Use the specified program to analyze the .o file, and pass it
230 #       FLAGS, in addition to the .o file name.
232 #   source: SOURCE
233 #       Assemble the file SOURCE.s.  If omitted, this defaults to FILE.s.
234 #       This is useful if several .d files want to share a .s file.
236 # Each option may occur at most once.
238 # After the option lines come regexp lines.  `run_dump_test' calls
239 # `regexp_diff' to compare the output of the dumping tool against the
240 # regexps in FILE.d.  `regexp_diff' is defined later in this file; see
241 # further comments there.
243 proc run_dump_test { name } {
244     global subdir srcdir
245     global OBJDUMP NM AS OBJCOPY READELF
246     global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS
247     global host_triplet
249     if [string match "*/*" $name] {
250         set file $name
251         set name [file tail $name]
252     } else {
253         set file "$srcdir/$subdir/$name"
254     }
255     set opt_array [slurp_options "${file}.d"]
256     if { $opt_array == -1 } {
257         perror "error reading options from $file.d"
258         unresolved $subdir/$name
259         return
260     }
261     set opts(as) {}
262     set opts(objdump) {}
263     set opts(nm) {}
264     set opts(objcopy) {}
265     set opts(readelf) {}
266     set opts(name) {}
267     set opts(PROG) {}
268     set opts(source) {}
270     foreach i $opt_array {
271         set opt_name [lindex $i 0]
272         set opt_val [lindex $i 1]
273         if ![info exists opts($opt_name)] {
274             perror "unknown option $opt_name in file $file.d"
275             unresolved $subdir/$name
276             return
277         }
278         if [string length $opts($opt_name)] {
279             perror "option $opt_name multiply set in $file.d"
280             unresolved $subdir/$name
281             return
282         }
283         set opts($opt_name) $opt_val
284     }
286     if {$opts(PROG) != ""} {
287         switch -- $opts(PROG) {
288             objdump
289                 { set program objdump }
290             nm
291                 { set program nm }
292             objcopy
293                 { set program objcopy }
294             readelf
295                 { set program readelf }
296             default
297                 { perror "unrecognized program option $opts(PROG) in $file.d"
298                   unresolved $subdir/$name
299                   return }
300         }
301     } else {
302         # Guess which program to run, by seeing which option was specified.
303         set program ""
304         foreach p {objdump objcopy nm readelf} {
305             if {$opts($p) != ""} {
306                 if {$program != ""} {
307                     perror "ambiguous dump program in $file.d"
308                     unresolved $subdir/$name
309                     return
310                 } else {
311                     set program $p
312                 }
313             }
314         }
315         if {$program == ""} {
316             perror "dump program unspecified in $file.d"
317             unresolved $subdir/$name
318             return
319         }
320     }
322     set progopts1 $opts($program)
323     eval set progopts \$[string toupper $program]FLAGS
324     eval set binary \$[string toupper $program]
325     if { $opts(name) == "" } {
326         set testname "$subdir/$name"
327     } else {
328         set testname $opts(name)
329     }
331     if { $opts(source) == "" } {
332         set sourcefile ${file}.s
333     } else {
334         set sourcefile $srcdir/$subdir/$opts(source)
335     }
337     send_log "$AS $ASFLAGS $opts(as) -o dump.o $sourcefile\n"
338     catch "exec $srcdir/lib/run $AS $ASFLAGS $opts(as) -o dump.o $sourcefile" comp_output
339     set comp_output [prune_warnings $comp_output]
341     if ![string match "" $comp_output] then {
342         send_log "$comp_output\n"
343         verbose "$comp_output" 3
344         fail $testname
345         return
346     }
348     if { [which $binary] == 0 } {
349         untested $testname
350         return
351     }
353     if { $progopts1 == "" } { set $progopts1 "-r" }
354     verbose "running $binary $progopts $progopts1" 3
356     # Objcopy, unlike the other two, won't send its output to stdout,
357     # so we have to run it specially.
358     if { $program == "objcopy" } {
359         send_log "$binary $progopts $progopts1 dump.o dump.out\n"
360         catch "exec $binary $progopts $progopts1 dump.o dump.out" comp_output
361         set comp_output [prune_warnings $comp_output]
362         if ![string match "" $comp_output] then {
363             send_log "$comp_output\n"
364             fail $testname
365             return
366         }
367     } else {
368         send_log "$binary $progopts $progopts1 dump.o > dump.out\n"
369         catch "exec $binary $progopts $progopts1 dump.o > dump.out" comp_output
370         set comp_output [prune_warnings $comp_output]
371         if ![string match "" $comp_output] then {
372             send_log "$comp_output\n"
373             fail $testname
374             return
375         }
376     }
378     verbose_eval {[file_contents "dump.out"]} 3
379     if { [regexp_diff "dump.out" "${file}.d"] } then {
380         fail $testname
381         verbose "output is [file_contents "dump.out"]" 2
382         return
383     }
385     pass $testname
388 proc slurp_options { file } {
389     if [catch { set f [open $file r] } x] {
390         #perror "couldn't open `$file': $x"
391         perror "$x"
392         return -1
393     }
394     set opt_array {}
395     # whitespace expression
396     set ws  {[  ]*}
397     set nws {[^         ]*}
398     # whitespace is ignored anywhere except within the options list;
399     # option names are alphabetic only
400     set pat "^#${ws}(\[a-zA-Z\]*)$ws:${ws}(.*)$ws\$"
401     while { [gets $f line] != -1 } {
402         set line [string trim $line]
403         # Whitespace here is space-tab.
404         if [regexp $pat $line xxx opt_name opt_val] {
405             # match!
406             lappend opt_array [list $opt_name $opt_val]
407         } else {
408             break
409         }
410     }
411     close $f
412     return $opt_array
415 proc objdump { opts } {
416     global OBJDUMP
417     global comp_output
418     global host_triplet
420     catch "exec $OBJDUMP $opts" comp_output
421     set comp_output [prune_warnings $comp_output]
422     verbose "objdump output=$comp_output\n" 3
425 proc objdump_start_no_subdir { prog opts } {
426     global OBJDUMP
427     global srcdir
428     global spawn_id
430     verbose "Starting $OBJDUMP $opts $prog" 2
431     catch {
432         spawn -noecho -nottyinit $srcdir/lib/run $OBJDUMP $opts $prog
433     } foo
434     if ![regexp {^[0-9]+} $foo] then {
435         perror "Can't run $prog: $foo"
436     }
439 proc objdump_finish { } {
440     global spawn_id
442     catch "close"
443     catch "wait"
446 # Default timeout is 10 seconds, loses on a slow machine.  But some
447 # configurations of dejagnu may override it.
448 if {$timeout<120} then { set timeout 120 }
450 expect_after -i {
451     timeout                     { perror "timeout" }
452     "virtual memory exhausted"  { perror "virtual memory exhausted" }
453     buffer_full                 { perror "buffer full" }
454     eof                         { perror "eof" }
457 # regexp_diff, based on simple_diff taken from ld test suite
458 #       compares two files line-by-line
459 #       file1 contains strings, file2 contains regexps and #-comments
460 #       blank lines are ignored in either file
461 #       returns non-zero if differences exist
463 proc regexp_diff { file_1 file_2 } {
465     set eof -1
466     set end_1 0
467     set end_2 0
468     set differences 0
469     set diff_pass 0
471     if [file exists $file_1] then {
472         set file_a [open $file_1 r]
473     } else {
474         warning "$file_1 doesn't exist"
475         return 1
476     }
478     if [file exists $file_2] then {
479         set file_b [open $file_2 r]
480     } else {
481         fail "$file_2 doesn't exist"
482         close $file_a
483         return 1
484     }
486     verbose " Regexp-diff'ing: $file_1 $file_2" 2
488     while { 1 } {
489         set line_a ""
490         set line_b ""
491         while { [string length $line_a] == 0 } {
492             if { [gets $file_a line_a] == $eof } {
493                 set end_1 1
494                 break
495             }
496         }
497         while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
498             if [ string match "#pass" $line_b ] {
499                 set end_2 1
500                 set diff_pass 1
501                 break
502             } elseif [ string match "#..." $line_b ] {
503                 if { [gets $file_b line_b] == $eof } {
504                     set end_2 1
505                     break
506                 }
507                 verbose "looking for \"^$line_b$\"" 3
508                 while { ![regexp "^$line_b$" "$line_a"] } {
509                     verbose "skipping    \"$line_a\"" 3
510                     if { [gets $file_a line_a] == $eof } {
511                         set end_1 1
512                         break
513                     }
514                 }
515                 break
516             }
517             if { [gets $file_b line_b] == $eof } {
518                 set end_2 1
519                 break
520             }
521         }
523         if { $diff_pass } { 
524             break 
525         } elseif { $end_1 && $end_2 } { 
526             break
527         } elseif { $end_1 } {
528             send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
529             verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
530             set differences 1
531             break
532         } elseif { $end_2 } {
533             send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
534             verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
535             set differences 1
536             break
537         } else {
538             verbose "regexp \"^$line_b$\"\nline   \"$line_a\"" 3
539             if ![regexp "^$line_b$" "$line_a"] {
540                 send_log "regexp_diff match failure\n"
541                 send_log "regexp \"^$line_b$\"\nline   \"$line_a\"\n"
542                 verbose "regexp_diff match failure\n" 3
543                 set differences 1
544             }
545         }
546     }
548     if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
549         send_log "$file_1 and $file_2 are different lengths\n"
550         verbose "$file_1 and $file_2 are different lengths" 3
551         set differences 1
552     }
554     close $file_a
555     close $file_b
557     return $differences
560 proc file_contents { filename } {
561     set file [open $filename r]
562     set contents [read $file]
563     close $file
564     return $contents
567 proc verbose_eval { expr { level 1 } } {
568     global verbose
569     if $verbose>$level then { eval verbose "$expr" $level }
572 # This definition is taken from an unreleased version of DejaGnu.  Once
573 # that version gets released, and has been out in the world for a few
574 # months at least, it may be safe to delete this copy.
575 if ![string length [info proc prune_warnings]] {
576     #
577     # prune_warnings -- delete various system verbosities from TEXT.
578     #
579     # An example is:
580     # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
581     #
582     # Sites with particular verbose os's may wish to override this in site.exp.
583     #
584     proc prune_warnings { text } {
585         # This is from sun4's.  Do it for all machines for now.
586         # The "\\1" is to try to preserve a "\n" but only if necessary.
587         regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
589         # It might be tempting to get carried away and delete blank lines, etc.
590         # Just delete *exactly* what we're ask to, and that's it.
591         return $text
592     }