#include "xxl.h"
#include <stdlib.h>
#define FAIL(why) \
do { \
fprintf(stderr, "%s\n", (why)); \
exit(1); \
} while (0)
typedef struct {
int cleaned;
} test_asset_t;
static void
cleanup_test_asset(void *asset, void *arg)
{
((test_asset_t *)asset)->cleaned = 1;
}
static void
test_catch(void)
{
int caught, pass;
for (pass = 0; pass < 3; pass++)
{
XXL_TRY_BEGIN {
caught = 0;
switch (pass)
{
case 0: XXL_THROW_ERROR(0x42174217, NULL);
case 1: XXL_THROW_ERROR(0x17421742, NULL);
case 2: break;
}
}
XXL_CATCH(0x42174217) { caught = 1; }
XXL_EXCEPT { caught = 2; }
XXL_TRY_END;
switch (pass)
{
case 0:
if (caught == 0) FAIL("Did not catch exception 0x42174217\n");
if (caught == 2) FAIL("Caught 0x42174217 as 0x17421742\n");
if (caught != 1) FAIL("(catch pass 0) 'caught' is totally wrong!\n");
break;
case 1:
if (caught == 0) FAIL("Did not catch exception 0x17421742\n");
if (caught == 1) FAIL("Caught 0x17421742 as 0x42174217\n");
if (caught != 2) FAIL("(catch pass 1) 'caught' is totally wrong!\n");
break;
default:
if (caught != 0) FAIL("Exception caught when none thrown\n");
break;
}
}
}
static void
test_finally(void)
{
int caught, finally, pass;
for (pass = 0; pass < 3; pass++)
{
XXL_TRY_BEGIN
{
caught = finally = 0;
switch (pass)
{
case 0: break;
case 1: XXL_THROW_ERROR(0x42174217, NULL);
case 2: XXL_THROW_ERROR(0x17421742, NULL);
}
}
XXL_CATCH(0x42174217) { caught = 1; }
XXL_EXCEPT { caught = 2; }
XXL_FINALLY { finally = 1; }
XXL_TRY_END;
switch (pass)
{
case 0:
if (caught == 1) FAIL("Caught 0x42174217 when none thrown with finally\n");
if (caught == 2) FAIL("Caught 0x17421742 when none thrown with finally\n");
if (caught != 0) FAIL("(finally pass 0) 'caught' is totally wrong!\n");
if (!finally) FAIL("Finally failed to run when no exception thrown\n");
break;
case 1:
if (caught == 0) FAIL("Did not catch exception 0x42174217 with finally\n");
if (caught == 2) FAIL("Caught 0x42174217 as 0x17421742 with finally\n");
if (caught != 1) FAIL("(finally pass 1) 'caught' is totally wrong!\n");
if (!finally) FAIL("Finally failed to run when specific exception caught\n");
break;
case 2:
if (caught == 0) FAIL("Did not catch exception 0x17421742 with finally\n");
if (caught == 1) FAIL("Caught 0x17421742 as 0x42174217 with finally\n");
if (caught != 2) FAIL("(finally pass 2) 'caught' is totally wrong!\n");
if (!finally) FAIL("Finally failed to run when non-specific exception caught\n");
break;
}
}
}
static void
test_assets(void)
{
int pass;
test_asset_t asset;
xxl_assettype_t type;
for (pass = 0; pass < 8; pass++)
{
XXL_TRY_BEGIN
{
asset.cleaned = 0;
switch (pass)
{
case 0: case 4: type = XXL_ASSET_PERMANENT; break;
case 1: case 5: type = XXL_ASSET_TEMPORARY; break;
case 2: case 6: type = XXL_ASSET_PROMOTE; break;
case 3: case 7: type = XXL_ASSET_DEMOTE; break;
}
XXL_ASSET_SAVE(&asset, cleanup_test_asset, NULL, type);
if (pass > 3) XXL_THROW_ERROR(0x42174217, NULL);
}
XXL_EXCEPT {}
XXL_TRY_END;
switch (pass)
{
case 0:
if (asset.cleaned)
FAIL("PERMANENT asset cleaned; no exception thrown\n");
break;
case 1:
if (!asset.cleaned)
FAIL("TEMPORARY asset NOT cleaned; no exception thrown\n");
break;
case 2:
if (asset.cleaned)
FAIL("PROMOTE asset cleaned; no exception thrown\n");
break;
case 3:
if (!asset.cleaned)
FAIL("DEMOTE asset NOT cleaned; no exception thrown\n");
break;
case 4:
if (asset.cleaned)
FAIL("PERMANENT asset cleaned; exception thrown\n");
break;
case 5:
if (!asset.cleaned)
FAIL("TEMPORARY asset NOT cleaned; exception thrown\n");
break;
case 6:
if (!asset.cleaned)
FAIL("PROMOTE asset NOT cleaned; exception thrown\n");
break;
case 7:
if (asset.cleaned)
FAIL("DEMOTE asset cleaned; exception thrown\n");
break;
}
}
}
static void
test_nested(void)
{
int caught, inner_finally, outer_finally, pass;
for (pass = 0; pass < 2; pass++)
{
XXL_TRY_BEGIN
{
caught = inner_finally = outer_finally = 0;
XXL_TRY_BEGIN
{
switch (pass)
{
case 0: XXL_THROW_ERROR(0x42174217, NULL);
case 1: XXL_THROW_ERROR(0x17421742, NULL);
}
}
XXL_CATCH(0x42174217) { XXL_RETHROW_ERROR(); }
XXL_FINALLY { inner_finally = 1; }
XXL_TRY_END;
}
XXL_CATCH(0x42174217) { caught = 1; }
XXL_CATCH(0x17421742) { caught = 2; }
XXL_FINALLY { outer_finally = 1; }
XXL_TRY_END;
switch (pass)
{
case 0:
if (caught == 0) FAIL("Outer try did not catch 0x42174217\n");
if (caught == 2) FAIL("Outer try caught 0x42174217 as 0x17421742\n");
if (caught != 1) FAIL("(nested pass 0) 'caught' is totally wrong!\n");
if (!inner_finally) FAIL("(nested pass 0) Inner finally block did not run\n");
if (!outer_finally) FAIL("(nested pass 0) Outer finally block did not run\n");
break;
case 1:
if (caught == 0) FAIL("Outer try did not catch 0x17421742\n");
if (caught == 1) FAIL("Outer try caught 0x17421742 as 0x42174217\n");
if (caught != 2) FAIL("(nested pass 1) 'caught' is totally wrong!\n");
if (!inner_finally) FAIL("(nested pass 1) Inner finally block did not run\n");
if (!outer_finally) FAIL("(nested pass 1) Outer finally block did not run\n");
break;
}
}
}
int main(int argc, char *agrv[])
{
printf("Testing simple exception catching ...\n");
test_catch();
printf("Testing simple finally block execution ...\n");
test_finally();
printf("Testing simple asset management ...\n");
test_assets();
printf("Testing nested exception handling ...\n");
test_nested();
exit(0);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1