mirror of https://gitee.com/Nocallback/dejagnu.git
9 changed files with 553 additions and 44 deletions
@ -0,0 +1,215 @@ |
|||
/*
|
|||
* Copyright (C) 2000, 2001 Free Software Foundation, Inc. |
|||
* |
|||
* This program 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. |
|||
*/ |
|||
|
|||
/* This is the include generated by configuring */ |
|||
#include <config.h> |
|||
|
|||
#ifndef __DEJAGNU_H__ |
|||
#define __DEJAGNU_H__ |
|||
|
|||
#include <stdio.h> |
|||
|
|||
static int passed; |
|||
static int failed; |
|||
static int untest; |
|||
static int unresolve; |
|||
|
|||
inline void |
|||
pass (const char *s) { |
|||
passed++; |
|||
printf ("\tPASSED: %s\n", s); |
|||
} |
|||
|
|||
inline void |
|||
fail (const char *s) { |
|||
failed++; |
|||
printf ("\tFAILED: %s\n", s); |
|||
} |
|||
|
|||
inline void |
|||
untested (const char *s) { |
|||
untest++; |
|||
printf ("\tUNTESTED: %s\n", s); |
|||
} |
|||
|
|||
inline void |
|||
unresolved (const char *s) { |
|||
unresolve++; |
|||
printf ("\tUNRESOLVED: %s\n", s); |
|||
} |
|||
|
|||
inline void |
|||
totals (void) { |
|||
printf ("\nTotals:\n"); |
|||
printf ("\t#passed:\t\t%d\n", passed); |
|||
printf ("\t#failed:\t\t%d\n", failed); |
|||
if (untest) |
|||
printf ("\t#untested:\t\t%d\n", untest); |
|||
if (unresolve) |
|||
printf ("\t#unresolved:\t\t%d\n", unresolved); |
|||
} |
|||
|
|||
#ifdef __cplusplus |
|||
|
|||
#include <iostream> |
|||
#include <iomanip> |
|||
#include <fstream> |
|||
#include <string> |
|||
#include <strstream> |
|||
|
|||
char *outstate[] = { |
|||
"FAILED: ", |
|||
"PASSED: ", |
|||
"UNTESTED: ", |
|||
"UNRESOLVED: " |
|||
}; |
|||
|
|||
#if 0 |
|||
extern ios& __iomanip_testout (ios&, int); |
|||
inline smanip<int> testout (int n) { |
|||
return smanip<int> (__iomanip_testout, n); |
|||
} |
|||
ios & __iomanip_testout (ios& i, int x) { |
|||
return i; |
|||
} |
|||
|
|||
template<class T> |
|||
class OMANIP { |
|||
private: |
|||
T i; |
|||
ostream &(*f)(ostream&, T); |
|||
public: |
|||
OMANIP(ostream& (*ff)(ostream&, T), T ii) : f(ff), i(ii) { |
|||
} |
|||
friend ostream operator<<(ostream& us, OMANIP& m) { |
|||
return m.f(os,m.i); |
|||
} |
|||
}; |
|||
|
|||
ostream& |
|||
freakout(ostream& os, int x) { |
|||
return os << "FREAKOUT" ; |
|||
// return x << "TESTOUT " << x ;
|
|||
} |
|||
|
|||
OMANIP<int> testout(int i) { |
|||
return OMANIP<int>(&freakout,i); |
|||
} |
|||
#endif |
|||
|
|||
char *testout (int x) { |
|||
const int len = 128; |
|||
static char buf[len]; |
|||
static ostrstream oss(buf, len, ios::out); |
|||
oss.seekp(ios::beg); |
|||
oss << outstate[x] << ends; |
|||
return buf; |
|||
} |
|||
|
|||
enum teststate {FAILED, PASSED,UNTESTED,UNRESOLVED} laststate; |
|||
|
|||
class TestState { |
|||
private: |
|||
teststate laststate; |
|||
string lastmsg; |
|||
public: |
|||
TestState(void) { |
|||
passed = 0; |
|||
failed = 0; |
|||
untest = 0; |
|||
unresolve = 0; |
|||
} |
|||
~TestState(void) { |
|||
totals(); |
|||
}; |
|||
|
|||
void testrun (bool b, string s) { |
|||
if (b) |
|||
pass (s); |
|||
else |
|||
fail (s); |
|||
} |
|||
|
|||
void pass (string s) { |
|||
passed++; |
|||
laststate = PASSED; |
|||
lastmsg = s; |
|||
cout << "\t" << testout(PASSED) << s << endl; |
|||
} |
|||
void pass (const char *c) { |
|||
string s = c; |
|||
pass (s); |
|||
} |
|||
|
|||
void fail (string s) { |
|||
failed++; |
|||
laststate = FAILED; |
|||
lastmsg = s; |
|||
cout << "\t" << testout(FAILED) << s << endl; |
|||
} |
|||
void fail (const char *c) { |
|||
string s = c; |
|||
fail (s); |
|||
} |
|||
|
|||
void untested (string s) { |
|||
untest++; |
|||
laststate = UNTESTED; |
|||
lastmsg = s; |
|||
cout << "\t" << testout(UNTESTED) << s << endl; |
|||
} |
|||
void untested (const char *c) { |
|||
string s = c; |
|||
untested (s); |
|||
} |
|||
|
|||
void unresolved (string s) { |
|||
unresolve++; |
|||
laststate = UNRESOLVED; |
|||
lastmsg = s; |
|||
cout << "\t" << testout(UNRESOLVED) << s << endl; |
|||
} |
|||
void unresolved (const char *c) { |
|||
string s = c; |
|||
unresolved (s); |
|||
} |
|||
void totals (void) { |
|||
cout << "\t#passed:\t\t" << passed << endl; |
|||
cout << "\t#failed:\t\t" << failed << endl; |
|||
if (untest) |
|||
cout << "\t#untested:\t\t" << untest << endl; |
|||
if (unresolve) |
|||
cout << "\t#unresolved:\t\t" << unresolve << endl; |
|||
} |
|||
|
|||
friend ostream & operator << (ostream &os, TestState& t) { |
|||
return os << "\t" << outstate[t.laststate] << t.lastmsg ; |
|||
} |
|||
|
|||
int GetState(void) { |
|||
return laststate; |
|||
} |
|||
string GetMsg(void) { |
|||
return lastmsg; |
|||
} |
|||
}; |
|||
|
|||
#endif // __cplusplus
|
|||
#endif // _DEJAGNU_H_
|
|||
|
|||
|
|||
@ -0,0 +1,174 @@ |
|||
# a hairy pattern to recognize text |
|||
set text "\[- A-Za-z0-9\.\;\"\_\:\'\`\(\)\!\#\=\+\?\&\*]" |
|||
|
|||
set SIZE size |
|||
if { [which $SIZE] == 0 } { |
|||
perror "Can't find $SIZE." |
|||
} |
|||
|
|||
# Get the size of the various section in an object file |
|||
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 consistant |
|||
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] != "" } { |
|||
verbose -log "output is:\n[lindex $status 1]" 2; |
|||
} |
|||
|
|||
# return the filtered output |
|||
return ${comp_output} |
|||
} |
|||
|
|||
# Execute the executable file, and anaylyse 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} { |
|||
global text |
|||
|
|||
set timeoutmsg "Timed out: Never got started, " |
|||
set timeout 100 |
|||
set file all |
|||
set timetol 0 |
|||
set arguments "" |
|||
|
|||
expect_before buffer_full { perror "Buffer full" } |
|||
|
|||
if { [llength $args] == 0} { |
|||
set executable $args |
|||
} else { |
|||
set executable [string trimleft [lindex [split $args " "] 0] "\{"] |
|||
set params [string trimleft [lindex [split $args " "] 1] "\{"] |
|||
set params [string trimright $params "\}"] |
|||
} |
|||
|
|||
verbose "The executable is $executable" 2 |
|||
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 from the |
|||
# test case. |
|||
# spawn -noecho -open [open "|./${executable}" "r"] |
|||
spawn -noecho "./${executable}" ${params} |
|||
expect { |
|||
-re "\[0-9\]\[0-9\]:..:..:${text}\r\n" { |
|||
regsub "\[\n\r\t\]*NOTE: " $expect_out(0,string) "" output |
|||
verbose "$output" 3 |
|||
set timetol 0 |
|||
exp_continue |
|||
} |
|||
-re "NOTE:${text}*" { |
|||
regsub "\[\n\r\t\]*NOTE: " $expect_out(0,string) "" output |
|||
verbose "$output" 2 |
|||
set timetol 0 |
|||
exp_continue |
|||
} |
|||
-re "PASSED:${text}*" { |
|||
regsub "\[\n\r\t\]*PASSED: " $expect_out(0,string) "" output |
|||
pass "$output" |
|||
set timetol 0 |
|||
exp_continue |
|||
} |
|||
-re "FAILED:${text}*" { |
|||
regsub "\[\n\r\t\]*FAILED: " $expect_out(0,string) "" output |
|||
fail "$output" |
|||
set timetol 0 |
|||
exp_continue |
|||
} |
|||
-re "UNTESTED:${text}*" { |
|||
regsub "\[\n\r\t\]*TESTED: " $expect_out(0,string) "" output |
|||
untested "$output" |
|||
set timetol 0 |
|||
exp_continue |
|||
} |
|||
-re "UNRESOLVED:${text}*" { |
|||
regsub "\[\n\r\t\]*UNRESOLVED: " $expect_out(0,string) "" output |
|||
unresolved "$output" |
|||
set timetol 0 |
|||
exp_continue |
|||
} |
|||
-re "Totals" { |
|||
verbose "All done" 2 |
|||
} |
|||
eof { |
|||
# unresolved "${executable} died prematurely" |
|||
# catch close |
|||
# return "${executable} died prematurely" |
|||
} |
|||
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 "" |
|||
} |
|||
|
|||
Loading…
Reference in new issue