/* -----------------------------------------------------------------------------
 * chickenrun.swg
 * ----------------------------------------------------------------------------- */

#include <chicken.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__BORLANDC__) || defined(_WATCOM)
# ifndef snprintf
#  define snprintf _snprintf
# endif
#endif

#ifdef __cplusplus
extern "C" {
#endif

#define SWIG_malloc(size) \
  malloc(size)
#define SWIG_free(mem) \
  free(mem)
#define SWIG_MakeString(c) \
  SWIG_Chicken_MakeString(c)
#define SWIG_ConvertPtr(s, result, type, flags) \
  SWIG_Chicken_ConvertPtr(s, result, type, flags)
#define SWIG_MustGetPtr(s, type, argnum, flags) \
  SWIG_Chicken_MustGetPtr(s, type, argnum, flags)
#define SWIG_NewPointerObj(ptr, type, owner) \
  SWIG_Chicken_NewPointerObj((void*)ptr, type, owner, &known_space)
#define swig_barf SWIG_Chicken_Barf
#define SWIG_ThrowException(val) SWIG_Chicken_ThrowException(val)

#define SWIG_contract_assert(expr, message) if (!(expr)) { \
                                              SWIG_Chicken_Barf(SWIG_BARF1_CONTRACT_ASSERT, C_text(message)); } else

/* Runtime API */
#define SWIG_GetModule(clientdata) SWIG_Chicken_GetModule(clientdata)
#define SWIG_SetModule(clientdata, pointer) SWIG_Chicken_SetModule(pointer)

#define C_swig_is_bool(x) C_truep (C_booleanp (x))
#define C_swig_is_char(x) C_truep (C_charp (x))
#define C_swig_is_fixnum(x) C_truep (C_fixnump (x))
#define C_swig_is_flonum(x) (C_truep (C_blockp (x)) && C_truep (C_flonump (x)))
#define C_swig_is_string(x) (C_truep (C_blockp (x)) && C_truep (C_stringp (x)))
#define C_swig_is_vector(x) (C_truep (C_blockp (x)) && C_truep (C_vectorp (x)))
#define C_swig_is_list(x) (C_truep (C_i_listp (x)))
#define C_swig_is_pair(x) (C_truep (C_blockp(x)) && C_truep (C_pairp(x)))
#define C_swig_is_ptr(x) (C_truep (C_blockp (x)) && C_truep (C_pointerp (x)))
#define C_swig_is_swigpointer(x) (C_truep (C_blockp(x)) && C_truep (C_swigpointerp(x)))
#define C_swig_is_closurep(x) (C_truep (C_blockp(x)) && C_truep(C_closurep(x)))
#define C_swig_is_number(x) (C_swig_is_fixnum(x) || C_swig_is_flonum(x))
#define C_swig_is_long(x) C_swig_is_number(x)

#define C_swig_sizeof_closure(num) (num+1)

#define SWIG_Chicken_SetupArgout { \
  C_word *a = C_alloc(C_swig_sizeof_closure(2)); \
  C_word *closure = a; \
  *(a++)=C_CLOSURE_TYPE|2; \
  *(a++)=(C_word)SWIG_Chicken_ApplyResults; \
  *(a++)=continuation; \
  continuation=(C_word)closure; \
}

#define SWIG_APPEND_VALUE(obj) { \
  C_word val = (C_word)(obj); \
  if (val != C_SCHEME_UNDEFINED) { \
    C_word *a = C_alloc(C_swig_sizeof_closure(3)); \
    C_word *closure = a; \
    *(a++)=C_CLOSURE_TYPE|3; \
    *(a++)=(C_word)SWIG_Chicken_MultiResultBuild; \
    *(a++)=(C_word)continuation; \
    *(a++)=val; \
    continuation=(C_word)closure; \
  } }

#define SWIG_Chicken_FindCreateProxy(func,obj) \
  if (C_swig_is_swigpointer(obj)) { \
    swig_type_info *t = (swig_type_info *) C_block_item(obj, 1); \
    if (t && t->clientdata &&    ((swig_chicken_clientdata *)t->clientdata)->gc_proxy_create) { \
      func = CHICKEN_gc_root_ref( ((swig_chicken_clientdata *)t->clientdata)->gc_proxy_create); \
    } else { \
      func = C_SCHEME_FALSE; \
    } \
  } else { \
    func = C_SCHEME_FALSE; \
  }


enum {
  SWIG_BARF1_BAD_ARGUMENT_TYPE /* 1 arg */,
  SWIG_BARF1_ARGUMENT_NULL /* 1 arg */,
  SWIG_BARF1_CONTRACT_ASSERT /* 1 arg */,
};

typedef C_word (*swig_chicken_destructor)(C_word,C_word,C_word,C_word);
typedef struct swig_chicken_clientdata {
  void *gc_proxy_create;
  swig_chicken_destructor destroy;
} swig_chicken_clientdata;
  
static char *
SWIG_Chicken_MakeString(C_word str) {
  char *ret;
  size_t l;

  l = C_header_size(str);
  ret = (char *) SWIG_malloc( (l + 1) * sizeof(char));
  if (!ret) return NULL;

  memcpy(ret, C_c_string(str), l);
  ret[l] = '\0';
  return ret;
}

static C_word SWIG_Chicken_LookupSymbol(char *name, C_SYMBOL_TABLE *stable) {
  C_word *a = C_alloc(C_SIZEOF_STRING (strlen (name)));
  C_word n = C_string2(&a, name);
  C_word sym = C_find_symbol(n, stable);
  if (C_truep(sym)) {
    return C_symbol_value(sym);
  } else {
    return C_SCHEME_FALSE;
  }
}

/* Just a helper function.  Do not export it */
static void SWIG_Chicken_Panic (C_char *) C_noret;
static void SWIG_Chicken_Panic (C_char *msg)
{
  C_word *a = C_alloc (C_SIZEOF_STRING (strlen (msg)));
  C_word scmmsg = C_string2 (&a, msg);
  C_halt (scmmsg);
  exit (5); /* should never get here */
}

static void
SWIG_Chicken_Barf(int code, C_char *msg, ...) C_noret;
static void
SWIG_Chicken_Barf(int code, C_char *msg, ...)
{
  char *errorhook = C_text("\003syserror-hook");
  C_word *a = C_alloc (C_SIZEOF_STRING (strlen (errorhook)));
  C_word err = C_intern2 (&a, errorhook);
  int c = -1;
  int i, barfval;
  va_list v;

  
  C_temporary_stack = C_temporary_stack_bottom;
  err = C_block_item(err, 0);

  if(C_immediatep (err))
    SWIG_Chicken_Panic (C_text ("`##sys#error-hook' is not defined"));

  switch (code) {
  case SWIG_BARF1_BAD_ARGUMENT_TYPE:
    barfval = C_BAD_ARGUMENT_TYPE_ERROR;
    c = 1;
    break;
  case SWIG_BARF1_ARGUMENT_NULL:
    barfval = C_BAD_ARGUMENT_TYPE_ERROR;
    c = 1;
    break;
  case SWIG_BARF1_CONTRACT_ASSERT:
    barfval = C_BAD_ARGUMENT_TYPE_ERROR;
    c = 1;
    break;
  default:
    SWIG_Chicken_Panic (C_text (msg));
  };

  if(c > 0 && !C_immediatep (err)) {
    C_save (C_fix (barfval));

    i = c;
    if (i) {
      C_word *b = C_alloc (C_SIZEOF_STRING (strlen (msg)));
      C_word scmmsg = C_string2 (&b, msg);
      C_save (scmmsg);
      i--;
    }

    va_start (v, msg);

    while(i--)
      C_save (va_arg (v, C_word));

    va_end (v);
    C_do_apply (c + 1, err, 
		C_SCHEME_UNDEFINED);  /* <- no continuation is passed:
					 '##sys#error-hook' may not
					 return! */
  }
  else if (msg) {
    SWIG_Chicken_Panic (msg);
  }
  else {
    SWIG_Chicken_Panic (C_text ("unspecified panic"));
  }
}

static void SWIG_Chicken_ThrowException(C_word value) C_noret;
static void SWIG_Chicken_ThrowException(C_word value)
{
  char *aborthook = C_text("\003sysabort");
  C_word *a = C_alloc(C_SIZEOF_STRING(strlen(aborthook)));
  C_word abort = C_intern2(&a, aborthook);

  abort = C_block_item(abort, 0);
  if (C_immediatep(abort))
    SWIG_Chicken_Panic(C_text("`##sys#abort' is not defined"));

  C_save(value);
  C_do_apply(1, abort, C_SCHEME_UNDEFINED);
}

static void
SWIG_Chicken_Finalizer(C_word argc, C_word closure, C_word continuation, C_word s)
{
  swig_type_info *type;
  swig_chicken_clientdata *cdata;

  if (argc == 3 && s != C_SCHEME_FALSE && C_swig_is_swigpointer(s)) {
    type = (swig_type_info *) C_block_item(s, 1);
    if (type) {
      cdata = (swig_chicken_clientdata *) type->clientdata;
      if (cdata && cdata->destroy) {
	/* this will not return, but will continue correctly */
        cdata->destroy(3,closure,continuation,s);
      }
    }
  }
  C_kontinue(continuation, C_SCHEME_UNDEFINED);
}
static C_word finalizer_obj[2] = {(C_word) (C_CLOSURE_TYPE|1), (C_word) SWIG_Chicken_Finalizer};

static C_word
SWIG_Chicken_NewPointerObj(void *ptr, swig_type_info *type, int owner, C_word **data)
{
  swig_chicken_clientdata *cdata = (swig_chicken_clientdata *) type->clientdata;

  if (ptr == NULL)
    return C_SCHEME_FALSE;
  else {
    C_word cptr = C_swigmpointer(data, ptr, type);
    /* add finalizer to object */
    #ifndef SWIG_CHICKEN_NO_COLLECTION
    if (owner)
      C_do_register_finalizer(cptr, (C_word) finalizer_obj);
    #endif

    return cptr;
  }
}

/* Return 0 if successful. */
static int
SWIG_Chicken_ConvertPtr(C_word s, void **result, swig_type_info *type, int flags)
{
  swig_cast_info *cast;
  swig_type_info *from;

  if (s == C_SCHEME_FALSE) {
    *result = NULL;
    return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
  } else if (C_swig_is_swigpointer(s)) {
    /* try and convert type */
    from = (swig_type_info *) C_block_item(s, 1);
    if (!from) return 1;
    if (type) {
      cast = SWIG_TypeCheckStruct(from, type);
      if (cast) {
        int newmemory = 0;
        *result = SWIG_TypeCast(cast, (void *) C_block_item(s, 0), &newmemory);
        assert(!newmemory); /* newmemory handling not yet implemented */
      } else {
        return 1;
      }
    } else {
      *result = (void *) C_block_item(s, 0);
    }

    /* check if we are disowning this object */
    if (flags & SWIG_POINTER_DISOWN) {
      C_do_unregister_finalizer(s);
    }
  } else {
    return 1;
  }

  return 0;
}

static SWIGINLINE void *
SWIG_Chicken_MustGetPtr (C_word s, swig_type_info *type, int argnum, int flags)
{
  void *result;
  char err_msg[256];
  if (SWIG_Chicken_ConvertPtr(s, &result, type, flags)) {
    /* type mismatch */
    snprintf(err_msg, sizeof(err_msg), "Type error in argument #%i: expected %s", argnum, (type->str ? type->str : type->name));
    SWIG_Chicken_Barf(SWIG_BARF1_BAD_ARGUMENT_TYPE, err_msg);
  }
  return result;
}

static char *chicken_runtimevar_name = "type_pointer" SWIG_TYPE_TABLE_NAME;

static swig_module_info *
SWIG_Chicken_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
    swig_module_info *ret = 0;
    C_word sym;

    /* lookup the type pointer... it is stored in its own symbol table */
    C_SYMBOL_TABLE *stable = C_find_symbol_table("swig_runtime_data" SWIG_RUNTIME_VERSION);
    if (stable != NULL) {
      sym = SWIG_Chicken_LookupSymbol(chicken_runtimevar_name, stable);
      if (C_truep(sym) && C_swig_is_ptr(sym)) {
        ret = (swig_module_info *) C_block_item(sym, 0);
      }
    }

    return ret;
}

static void
SWIG_Chicken_SetModule(swig_module_info *module) {
    C_word *a;
    C_SYMBOL_TABLE *stable;
    C_word sym;
    C_word pointer;
    static C_word *space = 0;
    
    /* type pointer is stored in its own symbol table */
    stable = C_find_symbol_table("swig_runtime_data" SWIG_RUNTIME_VERSION);
    if (stable == NULL) {
      stable = C_new_symbol_table("swig_runtime_data" SWIG_RUNTIME_VERSION, 16);
    }

    if (!space) {
      space = (C_word *) C_malloc((C_SIZEOF_POINTER + C_SIZEOF_INTERNED_SYMBOL(C_strlen(chicken_runtimevar_name))) * sizeof(C_word));
    }
    a = space;
    pointer = C_mpointer(&a, (void *) module);
    sym = C_intern_in(&a, C_strlen(chicken_runtimevar_name), chicken_runtimevar_name, stable);
    C_set_block_item(sym, 0, pointer);
}

static C_word SWIG_Chicken_MultiResultBuild(C_word num, C_word closure, C_word lst) {
  C_word cont = C_block_item(closure,1);
  C_word obj = C_block_item(closure,2);
  C_word func;

  SWIG_Chicken_FindCreateProxy(func,obj);

  if (C_swig_is_closurep(func)) {
    ((C_proc4)(void *)C_block_item(func, 0))(4,func,cont,obj,lst);
  } else {
    C_word *a = C_alloc(C_SIZEOF_PAIR);
    C_kontinue(cont,C_pair(&a,obj,lst));
  }
  return C_SCHEME_UNDEFINED; /* never reached */
}

static C_word SWIG_Chicken_ApplyResults(C_word num, C_word closure, C_word result) {
  C_apply_values(3,C_SCHEME_UNDEFINED,C_block_item(closure,1),result);
  return C_SCHEME_UNDEFINED; /* never reached */
}

#ifdef __cplusplus
}
#endif
