/* Copyright (c) 2001-2009 by SoftIntegration, Inc. All Rights Reserved */
#include <ch.h>
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>

typedef int (*FUNC)(int num, ChVaList_t ap);
extern int func2(FUNC, ...);

static ChInterp_t interp;
static void *vfunc_chdl_funptr;
static int vfunc_chdl_funarg(int num, ChVaList_t ap) {
    int retval;
    int j;
    double d;
    ChVaList_t ap_ch;

    ap_ch = Ch_VarArgsCreate(interp);
    if(num >= 1) {
      j  = va_arg(ap, int);
      Ch_VarArgsAddArg(interp, &ap_ch, CH_INTTYPE, j);
    }
    if(num >= 2) {
      d  = va_arg(ap, double);
      Ch_VarArgsAddArg(interp, &ap_ch, CH_DOUBLETYPE, d);
    }
    Ch_CallFuncByAddr(interp, vfunc_chdl_funptr, &retval, num, ap_ch);  
    Ch_VarArgsDelete(interp, ap_ch);
    return retval;
}

EXPORTCH int func2_chdl(void *varg)
{
   ChVaList_t ap;
   int count, num;
   int retval;

   Ch_VaStart(interp, ap, varg);
   count = Ch_VaCount(interp, ap);
   printf("Total args passed to func2_chdl() in C code = %d\n", count);
   num = Ch_VaFuncArgNum(interp, ap);
   if(num == INT_MAX)
     printf("Passed pointer to func in func2_chdl has varaible number arg\n");
   else
     printf("Passed pointer to func in func2_chdl has %d arg\n", num);
   vfunc_chdl_funptr = Ch_VaArg(interp, ap, void *);

   if(vfunc_chdl_funptr != NULL) {
      int num;
      int j =10;
      double d = 20;
      num = 0;
      retval = func2(vfunc_chdl_funarg, num);
      num = 1;
      retval = func2(vfunc_chdl_funarg, num, j);
      num = 2;
      retval = func2(vfunc_chdl_funarg, num, j, d);
   }
   else {
      printf("passed fun argument to func2_chdl() is NULL\n");
   }

   Ch_VaEnd(interp, ap);
   return retval;
}

