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

typedef int (*FUNC)();
int func0(int a, int b, int c)
{
   int a1 = a;
   int b1 = b;
   int c1 = c;
   printf("func0() called\n");
   return a+b+c;
}

int func1(int a, int b)
{
   printf("func0() called\n");
   return a+b;
}

int func2() {
   printf("func2() called\n");
   return 10;
}

int func3(void) {
   printf("func3() called\n");
   return 10;
}

int func4(int a, int b, ...) {
   int i, vacount;
   va_list ap;
   int sum;
   int val;
   float valf;
   double vald;

   printf("func4() called\n");
   sum = a+b;
   va_start(ap, b);
   vacount = va_count(ap);
   for(i=0; i<vacount; i++) {
      if(va_elementtype(ap)  == elementtype(int)) {
         val = va_arg(ap, int);
         printf("arg %d = %d\n", i+3, val);
         sum += val;
      }
      else if(va_elementtype(ap)  == elementtype(float)) {
         valf = va_arg(ap, float);
         printf("arg %d = %f\n", i+3, valf);
         sum += valf;
      }
      else if(va_elementtype(ap)  == elementtype(double)) {
         vald = va_arg(ap, double);
         printf("arg %d = %f\n", i+3, vald);
         sum += vald;
      }
   }
   return sum;
}

int chvaisfuncvararg(FUNC f, int i, int j) {
   void *handle, *fptr;
   int retval;

   handle = dlopen("libch.dl", RTLD_LAZY);
   if(handle == NULL) {
      printf("Error: %s(): dlopen(): %s\n", __func__, dlerror());
      return -1;
   }
   fptr = dlsym(handle, "chvaisfuncvararg_chdl");
   if(fptr == NULL) {
      printf("Error: %s(): dlsym(): %s\n", __func__, dlerror());
      return -1;
   }
   dlrunfun(fptr, &retval, chvaisfuncvararg, f, i, j);
   return retval;
}

int main() {
   int x = 5;
   int y = 6;
   printf("x=%d, y=%d ==> x+y=%d\n", x, y, chvaisfuncvararg((FUNC)func0, x, y));
   printf("sum=%d\n", chvaisfuncvararg((FUNC)func1, x, y));
   printf("sum=%d\n", chvaisfuncvararg((FUNC)func2, x, y));
   printf("sum=%d\n", chvaisfuncvararg((FUNC)func3, x, y));
   printf("sum=%d\n", chvaisfuncvararg(NULL, x, y));
   printf("sum=%d\n", chvaisfuncvararg((FUNC)func4, x, y));
   return 0;
}


