/* catch-test.c
 *
 * Tests catch,throw and unwind-protect in C
 */

#include <ccatch.h>
#include <stdio.h>

catch_tag tag;

void foo(void);
void bar(void);
void call(void (*fn) (void), int i);

int main(int argc, char **argv)
{
  int res;

  init_ccatch();

  C_STARTCATCH(tag)
    printf("main ...\n");
    call(foo,3);
    printf("main, after foo.\n");
    res = 7;
  C_CATCH(tag)
    printf("catching!\n");
    res = result;
  C_ENDCATCH(tag)

  printf("Back in main, result is %d\n", res);

  C_STARTCATCH(tag)
    printf("main ...\n");
    call(bar,11);
    printf("main, after bar.\n");
    res = 18;
  C_CATCH(tag)
    printf("catching!\n");
    res = result;
  C_ENDCATCH(tag)

  printf("Back in main, result is %d\n",res);
  return 0;
}
#if 0
void call (void (*fn)(void), int i)
{
  protect_tag tag;
  C_PROTECTSTART(tag)
    /* This is the body */
    printf("Calling...\n");
    fn();
  C_CLEANUP(tag)
    /* This is the cleanup code */
    printf("Cleaning up. The number is %d\n", i);
  C_ENDPROTECT(tag)
  printf("Call finished\n");
}
#else
void call (void (*fn)(void), int i)
{
  protect_tag tag;
  C_UNWINDPROTECT(tag, {
    /* This is the body */
    printf("Calling...\n");
    fn();
  }, {
    /* This is the cleanup code */
    printf("Cleaning up. The number is %d\n", i);
  });
}
#endif


void foo()
{
  printf("foo, returning\n");
}


void bar()
{
  printf("bar, throwing...\n");
  C_THROW(tag, 17);
  printf("Can't happen");
}
