#include #include #include #include #include //////////////////////////////////////////////////////////////////////// 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, test_done = 0; jmp_buf jmp; char *test_protect_msg = 0; #define protect_note_failure() test_protect_note_failure(test_protect_msg,__FILE__,__LINE__) #define protect_fail(msg) if (1) {test_protect_msg=msg;longjmp(jmp,1);} #define protect(a) if(setjmp(jmp) == 0) { a; } else {protect_note_failure();} #define test(p,a,b) test_test((p),((setjmp(jmp) == 0) ? (a):(protect_note_failure(),0),(b),__FILE__,__LINE__)) #define die(msg) if (1) { \ std::cerr << __FILE__ << ":" << __LINE__ << ": die( " << msg << " ) called" << std::endl; \ protect_fail( "attempting to recover from call to die..." ); \ } void test_test(int points, int condn, char *err_msg, char* file, int line) { if (condn) { score += points; } else { std::cerr << file << ":" << line << ": Test failed. " << err_msg << ", -" << points << " points." << std::endl; } } void test_protect_note_failure(char *msg, char *file, int line) { std::cerr << file << ":" << line << ": " << msg << std::endl; } void test_report() { std::cout << title << ": score " << score << " out of " << possible << " possible " << std::endl; test_done = 1; } //////////////////////////////////////////////////////////////////////// struct SIGLISTTYPE { char *name; int num; char *comment; } siglist[] = { {"SIGHUP", 1 , "hangup "}, {"SIGINT", 2 , "interrupt "}, {"SIGQUIT", 3 , "quit "}, {"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? "}, {"SIGTERM", 15 , "software termination signal from kill "}, {"SIGURG", 16 , "urgent condition on IO channel "}, {"SIGXCPU", 24 , "exceeded CPU time limit "}, {"SIGXFSZ", 25 , "exceeded file size limit "}, {"???", -1 , "UNKNOWN"}, }; typedef void (*sig_t)(int); int signal_count = 0; int signalled = 0; void test_trap_signal(int sig); void test_trap_exit(); 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); atexit(test_trap_exit); } void test_trap_signal(int sig) { int i = 0; while(siglist[i].num != -1 && siglist[i].num != sig) ++i; std::cerr << "WARNING: caught signal " << siglist[i].name << " [ " << siglist[i].comment << "]." << std::endl; protect_fail("attempting to recover from caught signal..."); } void test_trap_exit() { if (!test_done) { std::cerr << "WARNING: caught premature exit" << std::endl; protect_fail("attempting to recover from premature exit..."); } }