/* Copyright (c) 2001-2009 by SoftIntegration, Inc. All Rights Reserved */
/* file name: vararg.c 
   example for testing functions Ch_VaVarArgs*()
*/
#include <ch.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>

typedef struct {int i1; double d1; char c1; float f1;} SS1;
void func(int n, ...);
void vfunc(int n, ChVaList_t ap_c);

EXPORTCH void vfunc_chdl(void *varg) {
    ChInterp_t interp;
    void * ap; /* equivalent to va_list ap */
    ChVaList_t ap_ch;
    int ii;
    void *memhandle; 

    Ch_VaStart(interp, ap, varg);
    ii = Ch_VaArg(interp, ap, int);
    ap_ch = Ch_VaArg(interp, ap, ChVaList_t);

    ap_c = Ch_VaVarArgsCreate(interp, ap_ch, &memhandle);
    vfunc(ii, ap_c);
    Ch_VaVarArgsDelete(interp, memhandle);

    Ch_VaEnd(interp, ap);
    return;
}

void vfunc(int n, va_list ap_c) {
    char c1;
    int i1;
    short s1;
    float f1;
    double d1;
    double  *pd1 = &d1;       /* pointer to double */
    double  **ppd1 = &pd1;    /* pointer to double */
    float  *af1;              /* for array */
    SS1    ss1;               /* struct */
    int i2;
    float f2;
    double d2;

    printf("The first argument is %d\n", n);

    c1 = va_arg(ap_c, char);
    printf("\nc1 = %c\n", c1);
    i1 = va_arg(ap_c, int);
    printf("i1 = %d\n", i1);
    s1 = va_arg(ap_c, short);
    printf("s1 = %d\n", s1);
    f1 = va_arg(ap_c, float);
    printf("f1 = %f\n", f1);
    d1 = va_arg(ap_c, double);
    printf("d1 = %f\n", d1);

    pd1= va_arg(ap_c, double*);
    printf("\n*pd1 = %f\n", *pd1);
    ppd1= va_arg(ap_c, double**);
    printf("**ppd1 = %f\n", **ppd1);
    af1 = va_arg(ap_c, float*);
    printf("af1[1][1] = %f\n", *(af1+5));

    ss1 = va_arg(ap_c, SS1);
    printf("\nss1.i1 = %d\n", ss1.i1);
    printf("ss1.d1 = %f\n", ss1.d1);
    printf("ss1.c1 = %c\n", ss1.c1);
    printf("ss1.f1 = %f\n", ss1.f1);

    f2 = va_arg(ap_c, float);
    printf("f2 = %f\n", f2);
/*
    i2 = va_arg(ap_c, int);
    printf("i2 = %d\n", i2);
    d2 = va_arg(ap_c, double);
    printf("d2 = %f\n", d2);
*/

    return;
}


void func(int n, ...) {
    va_list ap;
   
    va_start(ap, n);
    vfunc(n, ap);
    va_end(ap);
    return;
}
