// Termination 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 catch test. try { loud_exit a = "simple try clause"; sout | "simple throw"; throw a_zen; sout | "end of try clause"; } catch (zen * error) { loud_exit a = "simple catch clause"; sout | "simple catch"; } sout | nl; // Throw catch-all test. try { throw a_zen; } catch (exception_t * error) { sout | "catch-all"; } sout | nl; // Don't catch if handler does not match exception. try { try { throw a_yin; } catch (zen *) { sout | "caught yin as zen"; } } catch (yang *) { sout | "caught yin as yang"; } catch (yin *) { sout | "caught yin as yin"; } sout | nl; // Test rethrowing an exception. try { try { loud_exit a = "rethrow inner try"; sout | "rethrow inner try"; throw a_zen; } catch (zen *) { loud_exit a = "rethrowing catch clause"; sout | "caught throw, will rethrow"; throw; } } catch (zen *) { loud_exit a = "rethrow catch clause"; sout | "caught rethrow"; } sout | nl; // Throw a different exception in a catch. try { try { throw a_yin; } catch (yin *) { sout | "caught yin, will throw yang"; throw a_yang; } catch (yang *) { sout | "caught exception from same try"; } } catch (yang *) { sout | "caught yang"; } sout | nl; // Another throw in the catch does not interfere. try { try { sout | "throwing first exception"; throw a_yin; } catch (yin *) { sout | "caught first exception"; try { sout | "throwing second exception"; throw a_yang; } catch (yang *) { sout | "caught second exception"; } throw; } } catch (yin *) { sout | "recaught first exception"; } catch (yang *) { sout | "caught second exception (bad location)"; } sout | nl; // Check successive operations. try { try { throw a_zen; throw a_zen; } catch (zen *) { sout | "inner catch"; } throw a_zen; } catch (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"; throw a_zen; } catch (zen *) { sout | "rethrow"; throw; } } catch (zen *) { sout | "handle"; } }