/* ** OSSP ex - Exception Handling Library ** Copyright (c) 2002 Ralf S. Engelschall ** Copyright (c) 2002 The OSSP Project ** Copyright (c) 2002 Cable & Wireless Deutschland ** ** This file is part of OSSP ex, an exception handling library ** which can be found at http://www.ossp.org/pkg/ex/. ** ** 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.0 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 file; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ** USA, or contact the OSSP project . ** ** ex_test.c: exception handling test suite */ #include #include #include #include "ts.h" #include "ex.h" TS_TEST(test_controlflow) { ex_t ex; volatile int n; ts_test_check(TS_CTX, "basic nested control flow"); n = 1; ex_try { if (n != 1) ts_test_fail(TS_CTX, "M1: n=%d (!= 1)", n); n++; ex_try { if (n != 2) ts_test_fail(TS_CTX, "M2: n=%d (!= 2)", n); n++; ex_throw(0, 0, 0); } ex_catch (ex) { if (n != 3) ts_test_fail(TS_CTX, "M3: n=%d (!= 1)", n); n++; ex_rethrow; } ts_test_fail(TS_CTX, "MX: n=%d (expected: not reached)", n); } ex_catch (ex) { if (n != 4) ts_test_fail(TS_CTX, "M4: n=%d (!= 4)", n); n++; } if (n != 5) ts_test_fail(TS_CTX, "M5: n=%d (!= 5)", n); } TS_TEST(test_value) { ex_t ex; ex_try { ex_throw(1, 2, 3); } ex_catch (ex) { ts_test_check(TS_CTX, "exception value passing"); if (ex.ex_class != (void *)1) ts_test_fail(TS_CTX, "ex_class=0x%lx (!= 1)", (long)ex.ex_class); if (ex.ex_object != (void *)2) ts_test_fail(TS_CTX, "ex_object=0x%lx (!= 2)", (long)ex.ex_object); if (ex.ex_value != (void *)3) ts_test_fail(TS_CTX, "ex_value=0x%lx (!= 3)", (long)ex.ex_value); } } TS_TEST(test_variables) { ex_t ex; int r1, r2; volatile int v1, v2; r1 = r2 = v1 = v2 = 1234; ex_try { r2 = 5678; v2 = 5678; ex_throw(0, 0, 0); } ex_catch (ex) { ts_test_check(TS_CTX, "variable preservation"); if (r1 != 1234) ts_test_fail(TS_CTX, "r1=%d (!= 1234)", r1); if (v1 != 1234) ts_test_fail(TS_CTX, "v1=%d (!= 1234)", v1); /* r2 is allowed to be destroyed because not volatile */ if (v2 != 5678) ts_test_fail(TS_CTX, "v2=%d (!= 5678)", v2); } } TS_TEST(test_shield) { ex_t ex; ts_test_check(TS_CTX, "exception shielding"); if (ex_shielded) ts_test_fail(TS_CTX, "unexpected shielded scope"); ex_try { ex_shield { if (!ex_shielded) ts_test_fail(TS_CTX, "unexpected non-shielded scope"); ex_throw(0, 0, 0); } if (ex_shielded) ts_test_fail(TS_CTX, "unexpected shielded scope"); } ex_catch (ex) { ts_test_fail(TS_CTX, "unexpected exception catched"); } } int main(int argc, char *argv[]) { ts_suite_t *ts; int n; ts = ts_suite_new("OSSP ex (Exception Handling)"); ts_suite_test(ts, test_controlflow, "basic nested control flow"); ts_suite_test(ts, test_value, "exception value passing"); ts_suite_test(ts, test_variables, "variable value preservation"); ts_suite_test(ts, test_shield, "exception shielding"); n = ts_suite_run(ts); ts_suite_free(ts); return n; }