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

typedef struct tags {
    int i; 
    double d;
} tags_t;
typedef class tagc {
  public:
    int i; 
    double d;
} tagc_t;
typedef union tagu {
    int i; 
    double d;
} tagu_t;
EXPORTCH void chuserdefinedname_chdl(void *varg) {
    ChInterp_t interp;
    ChVaList_t ap;
    int i, vacount;
    void *addr;
    size_t  size;
    char *name;
    tags_t s, *sp;
    tagc_t *cp;
    tagu_t u;

    Ch_VaStart(interp, ap, varg);
    vacount = Ch_VaCount(interp, ap);
    printf("vacount = %d\n", vacount);
    for(i = 0; i < vacount; i++) {
      addr = Ch_VaUserDefinedAddr(interp, ap);
      name = Ch_VaUserDefinedName(interp, ap);
      size = Ch_VaUserDefinedSize(interp, ap);
      if(Ch_VaDataType(interp, ap) == CH_STRUCTTYPE) {
         printf("Structure:\n");
         printf("address is %p, the size is %d, tag name is %s\n", addr, size, name);
         s = Ch_VaArg(interp, ap, struct tags);
         printf("s.i = %d, s.d = %f\n", s.i, s.d);
      }
      else if(Ch_VaDataType(interp, ap) == CH_STRUCTPTRTYPE) {
         printf("Pointer to structure:\n");
         printf("address is %p, the size is %d, tag name is %s\n", addr, size, name);
         sp = Ch_VaArg(interp, ap, struct tags*);
         printf("sp->i = %d, sp->d = %f\n", sp->i, sp->d);
      }
      else if(Ch_VaDataType(interp, ap) == CH_CLASSPTRTYPE) {
         printf("Class:\n");
         printf("address is %p, the size is %d, tag name is %s\n", addr, size, name);
         cp = Ch_VaArg(interp, ap, tagc_t*);
         printf("cp->i = %d, cp->d = %f\n", cp->i, cp->d);
      }
      else if(Ch_VaDataType(interp, ap) == CH_UNIONTYPE) {
         printf("Union:\n");
         printf("address is %p, the size is %d, tag name is %s\n", addr, size, name);
         u = Ch_VaArg(interp, ap, tagu_t);
         printf("u.i = %d, u.d = %f\n", u.i, u.d);
      }
    }
    Ch_VaEnd(interp, ap);
    return;
}
