diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 11420392e32..84fd2735c67 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -1315,6 +1315,10 @@ Prune messages matching @var{regexp} from the test output. @item @{ dg-output @var{regexp} [@{ target/xfail @var{selector} @}] @} This DejaGnu directive compares @var{regexp} to the combined output that the test executable writes to @file{stdout} and @file{stderr}. + +@item @{ dg-output-file @var{file} [@{ target/xfail @var{selector} @}] @} +Compares the content of @var{file} against the combined output that the +test executable writes to @file{stdout} and @file{stderr}. @end table @subsubsection Specify environment variables for a test diff --git a/gcc/testsuite/gcc.dg/dg-output-file-1-ilp32.txt b/gcc/testsuite/gcc.dg/dg-output-file-1-ilp32.txt new file mode 100644 index 00000000000..0255ead5693 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dg-output-file-1-ilp32.txt @@ -0,0 +1,3 @@ +This is a test output for ilp32 target +to verify +dg-output-file directive diff --git a/gcc/testsuite/gcc.dg/dg-output-file-1-lp64.txt b/gcc/testsuite/gcc.dg/dg-output-file-1-lp64.txt new file mode 100644 index 00000000000..e6d9c8ead41 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dg-output-file-1-lp64.txt @@ -0,0 +1,3 @@ +This is a test output for lp64 target +to verify +dg-output-file directive diff --git a/gcc/testsuite/gcc.dg/dg-output-file-1.c b/gcc/testsuite/gcc.dg/dg-output-file-1.c new file mode 100644 index 00000000000..5ad632c4e35 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dg-output-file-1.c @@ -0,0 +1,13 @@ +/* { dg-do run { target { lp64 || ilp32 } } } */ +/* { dg-options "-O2" } */ +/* { dg-output-file "dg-output-file-1-lp64.txt" { target lp64 } } */ +/* { dg-output-file "dg-output-file-1-ilp32.txt" { target ilp32 } } */ + +int +main () +{ + __builtin_printf ("This is a test output for %s target\n" + "to verify\n" + "dg-output-file directive\n", + __SIZEOF_LONG__ * __CHAR_BIT__ == 64 ? "lp64" : "ilp32"); +} diff --git a/gcc/testsuite/lib/dg-test-cleanup.exp b/gcc/testsuite/lib/dg-test-cleanup.exp index 27b1eb3da20..308ee002ef4 100644 --- a/gcc/testsuite/lib/dg-test-cleanup.exp +++ b/gcc/testsuite/lib/dg-test-cleanup.exp @@ -45,6 +45,7 @@ if { [info procs saved-dg-test] == [list] } { global multiline_expected_outputs global freeform_regexps global save_linenr_varnames + global output-file set additional_files "" set additional_sources "" @@ -70,6 +71,9 @@ if { [info procs saved-dg-test] == [list] } { if [info exists testname_with_flags] { unset testname_with_flags } + if [info exists output-file] { + unset output-file + } set nn_line_numbers_enabled 0 set multiline_expected_outputs [] set freeform_regexps [] diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp index f5ad4247a61..eadc1cd90bc 100644 --- a/gcc/testsuite/lib/gcc-dg.exp +++ b/gcc/testsuite/lib/gcc-dg.exp @@ -473,6 +473,7 @@ if { [info procs ${tool}_load] != [list] \ global tool global shouldfail global set_target_env_var + global output-file set saved_target_env_var [list] if { [info exists set_target_env_var] \ @@ -497,6 +498,75 @@ if { [info procs ${tool}_load] != [list] \ } set result [list [lindex $result 0] [prune_file_path [lindex $result 1]]] + if { [info exists output-file] && [lindex $result 0] eq "pass" } { + if { [lindex ${output-file} 0] eq "F" } { + setup_xfail "*-*-*" + } + set output [lindex $result 1] + set idx 0 + set linenum 1 + set outfile [open [lindex ${output-file} 1]] + set do_fail 0 + set name [file tail [lindex ${output-file} 1]] + verbose "output-file args is $args program is $program" 1 + while { [gets $outfile line] >= 0 } { + if { $linenum != 1 } { + set c [string index $output $idx] + if { $c eq "\n" } { + set idx [expr $idx + 1] + } elseif { $c eq "\r" } { + set idx [expr $idx + 1] + set c [string index $output $idx] + if { $c eq "\n" } { + set idx [expr $idx + 1] + } + } else { + set do_fail 1 + fail "$name output file test" + send_log "Unexpected character $c on line [expr $linenum - 1] where new-line expected\n" + verbose "Failed test for output line [expr $linenum - 1]" 3 + break + } + } + set len [string length $line] + set output_line [string range $output $idx [expr $idx + $len - 1]] + if { $line ne $output_line } { + set do_fail 1 + fail "$name output file test" + send_log "Output line $linenum was:\n$output_line\nShould match (from [lindex ${output-file} 1]):\n$line\n" + verbose "Failed test for output line $linenum $line" 3 + break + } + set idx [expr $idx + $len] + incr linenum + } + close $outfile + if { $do_fail == 0 } { + set c [string index $output $idx] + if { $c eq "\n" } { + set idx [expr $idx + 1] + } elseif { $c eq "\r" } { + set idx [expr $idx + 1] + set c [string index $output $idx] + if { $c eq "\n" } { + set idx [expr $idx + 1] + } + } else { + incr linenum -1 + } + set c [string index $output $idx] + if { $c ne "" } { + fail "$name output file test" + send_log "Unexpected character $c on line $linenum where and of output expected\n" + verbose "Failed test for output line $linenum" 3 + break + } else { + pass "$name output file test" + verbose "Passed test for output file [lindex ${output-file} 1]" 3 + } + } + unset output + } return $result } } @@ -575,6 +645,35 @@ proc restore-compiler-env-var { } { } } +# Indicate expected program output in a file. +# +proc dg-output-file { args } { + global output-file + global srcdir subdir + + if { [llength $args] > 3 } { + error "[lindex $args 0]: too many arguments" + } + + # Allow target dependent output. + + if { ![info exists output-file] } { + set output-file "P" + } + set expected [lindex ${output-file} 0] + if { [llength $args] >= 3 } { + switch -- [dg-process-target [lindex $args 2]] { + "N" { return } + "S" { } + "F" { set expected "F" } + # Don't override a previous xfail. + "P" { } + } + } + + set output-file [list $expected $srcdir/$subdir/[lindex $args 1]] +} + # Utility routines. #