| # Copyright (C) 1992-2019, 2020 Free Software Foundation, Inc. |
| # |
| # This file is part of DejaGnu. |
| # |
| # DejaGnu 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. |
| # |
| # DejaGnu 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 DejaGnu; if not, write to the Free Software Foundation, |
| # Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. |
| |
| # This file was written by Rob Savoye <rob@welcomehome.org>. |
| |
| # A hairy pattern to recognize text. |
| set text "\[- A-Za-z0-9\.\;\"\_\:\'\`\(\)\!\#\=\+\?\&\*<>]" |
| |
| set SIZE size |
| if { [which $SIZE] == 0 } { |
| perror "Can't find $SIZE." 0 |
| } |
| |
| # Get the size of the various section in OBJECT. |
| proc exe_size {object} { |
| global SIZE |
| |
| # Make sure size exists |
| if { [which $SIZE] == 0 } { |
| return [list "-1" "Can't find $SIZE."] |
| } else { |
| verbose "Using $SIZE for \"size\" program." 2 |
| } |
| set status [catch "exec $SIZE -V" output] |
| if {[regexp "GNU size" $output] == 0} { |
| perror "Need GNU size from the binutils" 0 |
| return [list "-1" "Need GNU size."] |
| } |
| |
| # Get the object size. We pass -x, to force hex output |
| verbose "Getting the object file size for $object" 2 |
| set status [catch "exec $SIZE -x $object" output] |
| verbose -log "Size of $object is\n$output" 2 |
| |
| # Remove the header line from the size output. This currently only |
| # works with GNU size |
| regsub "text.*filename\[\r\n\]*" $output "" output |
| |
| # look for the size of the .text section |
| regexp "\[\r\n\]*0x\[0-9a-fA-F\]*" $output text |
| regsub "\[\r\n\]*0x\[0-9a-fA-F\]*\[ \t\]*" $output "" output |
| |
| # look for the size of the .data section |
| regexp "0x\[0-9a-fA-F\]*\[ \t\]*" $output data |
| regsub "0x\[0-9a-fA-F\]*\[ \t\]*" $output "" output |
| |
| # Values returns as hex |
| return [list $text $data] |
| } |
| |
| # Run the host's native compiler, not the cross one. Filter out the |
| # warnings and other extraneous stuff. |
| # Returns: |
| # A "" (empty) string if everything worked, or the |
| # output if there was a problem. |
| # |
| proc host_compile {compline} { |
| global INCLUDES |
| global LIBS |
| global CXX, CC |
| |
| # execute the compiler |
| verbose "Compiling for the host using: $CC $INCLUDES $LIBS $compline" 2 |
| set status [catch "exec $CC $INCLUDES $LIBS $compline" comp_output] |
| verbose "Compiler returned $comp_output" 2 |
| |
| # prune common warnings and other stuff we can safely ignore |
| set comp_output [prune_warnings $comp_output] |
| |
| # Trim multiple CR/LF pairs out to keep things consistent |
| regsub "^\[\r\n\]+" $comp_output "" comp_output |
| |
| # if we got a compiler error, log it |
| if { [lindex $status 0] != 0 } { |
| verbose -log "compiler exited with status [lindex $status 0]" |
| } |
| if { [lindex $status 1] ne "" } { |
| verbose -log "output is:\n[lindex $status 1]" 2 |
| } |
| |
| # return the filtered output |
| return $comp_output |
| } |
| |
| # Execute the executable file, and analyse the output for the test |
| # state keywords. |
| # Returns: |
| # A "" (empty) string if everything worked, or an error message |
| # if there was a problem. |
| # |
| proc host_execute {args} { |
| set timeoutmsg "Timed out: Never got started, " |
| set timeout 100 |
| set file all |
| set timetol 0 |
| set arguments "" |
| |
| if { [llength $args] == 0 } { |
| return "No executable specified." |
| } else { |
| set executable [lindex $args 0] |
| set arguments [lrange $args 1 end] |
| } |
| |
| verbose "The executable is $executable" 2 |
| verbose "The arguments are $arguments" 2 |
| if { [file exists "./${executable}"] } { |
| set executable "./${executable}" |
| } |
| if { ![file exists $executable] } { |
| perror "The executable, \"$executable\" is missing" 0 |
| return "No source file found" |
| } |
| |
| # Spawn the executable and look for the DejaGnu output messages. |
| eval [list spawn -noecho $executable] $arguments |
| expect { |
| -re {(?:\A|\n)\t([][[:upper:]]+):([^\n]+)\n} { |
| set output [string trim $expect_out(2,string)] |
| switch -- $expect_out(1,string) { |
| NOTE { verbose $output 2 } |
| PASSED { pass $output } |
| FAILED { fail $output } |
| XPASSED { xpass $output } |
| XFAILED { xfail $output } |
| UNTESTED { untested $output } |
| UNRESOLVED { unresolved $output } |
| default { |
| unresolved "unknown unit test token $expect_out(1,string)" |
| } |
| } |
| set timetol 0 |
| exp_continue |
| } |
| -re {^Totals} { |
| # Flush the stream to allow the child process to finish writing |
| # logs or other information, instead of sending SIGPIPE. |
| expect -re {.+} { exp_continue } |
| verbose "All done" 2 |
| } |
| -re {^[^\r\n]*([0-9][0-9]:..:..:[^\n]*)\n} { |
| # No one seems to know why this pattern is here or what it is |
| # supposed to match. I suspect that it is obsolete. -- jcb, 2020 |
| verbose [string trim $expect_out(1,string)] 3 |
| set timetol 0 |
| exp_continue |
| } |
| -re {^[^\n]*\n} { |
| # Skip other lines produced by the test program. |
| set timetol 0 |
| exp_continue |
| } |
| full_buffer { |
| perror "Expect matching buffer overrun while running\ |
| $executable $arguments" |
| } |
| eof { |
| } |
| timeout { |
| warning "Timed out executing test case" |
| if { $timetol <= 2 } { |
| incr timetol |
| exp_continue |
| } else { |
| catch close |
| return "Timed out executing test case" |
| } |
| } |
| } |
| |
| # force a close of the executable to be safe. |
| catch close |
| return "" |
| } |