#ifndef _TEST_UTILITIES_H #define _TEST_UTILITIES_H #include #include #include #define test(p,a,b) test_test(p,a,b,__FILE__,__LINE__) #define die(msg) do { \ std::cerr << __FILE__ << ":" << __LINE__ << ": Fatal error: " << msg << std::endl; \ test_report(); \ signal(SIGQUIT, NULL); \ kill(0, SIGQUIT); \ } while(0) struct SIGLISTTYPE { char *name; int num; char *comment; } siglist[] = { {"SIGILL", 4 , "illegal instruction (not reset when caught) "}, {"SIGTRAP", 5 , "trace trap (not reset when caught) "}, {"SIGABRT", 6 , "abort() "}, {"SIGEMT", 7 , "EMT instruction "}, {"SIGFPE", 8 , "floating point exception "}, {"SIGBUS", 10 , "bus error "}, {"SIGSEGV", 11 , "segmentation violation "}, {"SIGSYS", 12 , "bad argument to system call "}, {"SIGPIPE", 13 , "write on a pipe with no one to read it "}, {"SIGALRM", 14 , "alarm clock -- is your running time too slow? "}, {"???", -1 , "UNKNOWN"}, }; class SelfInitInt { public: int i; SelfInitInt() : i (3141159) {}; }; std::ostream& operator<<(std::ostream& out, const SelfInitInt& x) { out << x.i; return out; } char *title; int score = 0, possible = 0; typedef void (*sig_t)(int); int signal_count = 0; int signalled = 0; void test_report() { std::cout << title << ": score " << score << " out of " << possible << " possible " << std::endl; } void test_trap_signal(int sig) { int i = 0; while(siglist[i].num != -1 && siglist[i].num != sig) ++i; die("signal " << siglist[i].name << " [ " << siglist[i].comment << "] received."); } void test_init(int poss, char *t) { possible = poss; title = t; for(int i = 0; siglist[i].num != -1; ++i) signal(i, test_trap_signal); } void test_test(int points, int condn, char *err_msg, char* file, int line) { if (signalled == 0 && condn) { score += points; } else { std::cerr << file << ":" << line << ": Test failed. " << err_msg << ", -" << points << "points." << std::endl; } } #endif