// Resumption Exception Tests #include #include "except-io.hfa" exception yin {}; exception yang {}; exception zen {}; vtable(yin) yin_vt; vtable(yang) yang_vt; vtable(zen) zen_vt; void in_void(void); int main(int argc, char * argv[]) { yin a_yin = {&yin_vt}; yang a_yang = {&yang_vt}; zen a_zen = {&zen_vt}; // The simple throw catchResume test. try { loud_exit a = "simple try clause"; sout | "simple throw"; throwResume a_zen; sout | "end of try clause"; } catchResume (zen * error) { loud_exit a = "simple catch clause"; sout | "simple catch"; } sout | nl; // Throw catch-all test. try { throwResume a_zen; } catchResume (exception_t * error) { sout | "catch-all"; } sout | nl; // Don't catch if handler does not match exception. try { try { throwResume a_yin; } catchResume (zen *) { sout | "caught yin as zen"; } } catchResume (yang *) { sout | "caught yin as yang"; } catchResume (yin *) { sout | "caught yin as yin"; } sout | nl; // Test rethrowing an exception. try { try { loud_exit a = "rethrow inner try"; sout | "rethrow inner try"; throwResume a_zen; } catchResume (zen *) { loud_exit a = "rethrowing catch clause"; sout | "caught throw, will rethrow"; throwResume; } } catchResume (zen *) { loud_exit a = "rethrow catch clause"; sout | "caught rethrow"; } sout | nl; // Throw a different exception in a catch. try { try { throwResume a_yin; } catchResume (yin *) { sout | "caught yin, will throw yang"; throwResume a_yang; } catchResume (yang *) { sout | "caught exception from same try"; } } catchResume (yang *) { sout | "caught yang"; } sout | nl; // Another throw in the catch does not interfere. try { try { sout | "throwing first exception"; throwResume a_yin; } catchResume (yin *) { sout | "caught first exception"; try { sout | "throwing second exception"; throwResume a_yang; } catchResume (yang *) { sout | "caught second exception"; } throwResume; } } catchResume (yin *) { sout | "recaught first exception"; } catchResume (yang *) { sout | "caught second exception (bad location)"; } sout | nl; // Check successive operations. try { try { throwResume a_zen; throwResume a_zen; } catchResume (zen *) { sout | "inner catch"; } throwResume a_zen; } catchResume (zen *) { sout | "outer catch"; } sout | nl; in_void(); } // Do a throw and rethrow in a void function. void in_void(void) { zen a_zen = {&zen_vt}; try { try { sout | "throw"; throwResume a_zen; } catchResume (zen *) { sout | "rethrow"; throwResume; } } catchResume (zen *) { sout | "handle"; } }