#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>

extern int cppSanityCheck();
extern void cppCall();

static jmp_buf jumpPoint;


static void entryPoint() {
#if defined(UNSAFE_JUMP)
  /* this is unsafe. We'll setjmp here, then call into C++ which will
   * create a non-POD object on the stack then call back into our C module
   * which will longjmp(). We'll land up back here without having unwound
   * the C++ stack, and with no way to go back.
   */
  if (setjmp(jumpPoint) != 0) {
    /* just returned from our jump. */
    return;
  }
#endif
  /* this would generally be a call to a dlopen()ed function pointer to an extern "C" function in practice ...*/
  cppCall();
}

static void doSomeStuff() {
  /* While doing some work, we hit an error and longjmp() */
  longjmp(jumpPoint, 1);
}

void calledFromCppCode() {
#if !defined(UNSAFE_JUMP)
  /* this is OK, since we won't enter the C++ module again between setjmp() and longjmp() */
  if (setjmp(jumpPoint) != 0) {
    /* Just returned from our jump */
    return;
  }
#endif
  doSomeStuff();
}


int main() {
  entryPoint();
  int ret = cppSanityCheck();
  if (ret != 0) {
    printf("***** About to exit with LEAKED OBJECTS NOT PROPERLY CLEANED UP ****\n");
  }
} 
