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

static void *FUNC_chdl_funptr;
EXPORTCH int chvastart_chdl(void *varg) {
  ChInterp_t interp;
  ChVaList_t ap;
  double *a;
  ChType_t elementtype;
  int num, d_a, ext_a_1, ext_a_2;
  int arg_count, funarg_count, retval = 0;
  double d1;
  int n;

  Ch_VaStart(interp, ap, varg);

  /* Number of arguments passed from Ch space*/
  arg_count = Ch_VaCount(interp, ap); 
  printf("Number of arguments before first calling of Ch_VaArg() is %d\n", arg_count);

  /* Data type of 1st argument */
  elementtype = Ch_VaDataType(interp, ap); 
  if(elementtype == CH_DOUBLETYPE) {
    printf("Data type of the 1st argument is double\n");
  }

  if(Ch_VaArrayType(interp, ap) == CH_CARRAYTYPE) {
    printf("The 1st argument is C array\n");
  }
  else if(Ch_VaArrayType(interp, ap) == CH_CARRAYPTRTYPE) {
    printf("The 1st argument is pointer to C array\n");
  }

  /* Dimension of 1st argument */
  d_a = Ch_VaArrayDim(interp, ap);        
  printf("Dimension of the 1st argument is = %d\n", d_a);

  /* Number of elements of 1st argument */
  num = Ch_VaArrayNum(interp, ap);        
  printf("Number of elements of the 1st argument is = %d\n", num);

  /* Number of elements in the 1st dimension of the 1st argument */ 
  ext_a_1 = Ch_VaArrayExtent(interp, ap, 0);
  printf("Extent of the 1st dimension of the 1st argument is = %d\n", ext_a_1);
 
  /* Number of elements in the 2nd dimension of the 1st argument */ 
  ext_a_2 = Ch_VaArrayExtent(interp, ap, 1);
  printf("Extent of the 2nd dimension of the 1st argument is = %d\n", ext_a_2);

  /* Return the 1st argument, and step to the next argument */
  a = Ch_VaArg(interp, ap, double*);  

  /* Number of the rest of arguments */
  arg_count = Ch_VaCount(interp, ap); 
  printf("\nNumber of the rest of arguments after the 1st calling of "
         "Ch_VaArg() is %d\n", arg_count);

  /* Data type of 2nd argument */
  elementtype = Ch_VaDataType(interp, ap); 
  if(elementtype == CH_DOUBLETYPE) {
    printf("Element data type of the 2nd argument is double\n");
  } 

  /* Return the 2nd argument, and step to the next argument */
  d1 = Ch_VaArg(interp, ap, double);

  /* Number of the rest of arguments */
  arg_count = Ch_VaCount(interp, ap);
  printf("\nNumber of the rest of arguments after the 2nd calling of "
         "Ch_VaArg() is %d\n", arg_count);

  /* Data type of 3nd argument */
  elementtype = Ch_VaDataType(interp, ap); 
  if(elementtype == CH_INTTYPE) {
    printf("Return type of function of the 3nd argument of pointer to function is int\n");
  } 

  if(Ch_VaIsFunc(interp, ap)) {
    printf("Element data type of the 3nd argument is pointer to function\n");
  } 
  funarg_count = Ch_VaFuncArgNum(interp, ap);
  printf("Number of arguments of the function pointed to by "
         "the 3nd argument is %d\n", funarg_count);
  if(Ch_VaFuncArgDataType(interp, ap, 0) == CH_INTTYPE)
    printf("Arg 1 of the function pointed to by the 3nd argument is int\n");
  if(Ch_VaFuncArgDataType(interp, ap, 1) == CH_INTTYPE)
    printf("Arg 2 of the function pointed to by the 3nd argument is int\n");

  /* Return the 3rd argument */
  FUNC_chdl_funptr = Ch_VaArg(interp, ap, void*);

  /* Data type of 4th argument */
  elementtype = Ch_VaDataType(interp, ap); 
  if(elementtype == CH_DOUBLETYPE) {
    printf("Return type of function of the 4th argument of pointer to function is double\n");
  } 

  if(Ch_VaIsFunc(interp, ap)) {
    printf("Element data type of the 4th argument is pointer to function\n");
  } 

  if(Ch_VaArrayType(interp, ap) == CH_CHARRAYTYPE) {
    printf("Return type of function of the 4th argument of pointer to function "
           "is computational array\n");
  }
  funarg_count = Ch_VaFuncArgNum(interp, ap);
  printf("Number of arguments of the function pointed to by the 4th \
argument is %d\n", funarg_count);

  /* Return the 4th argument */
  FUNC_chdl_funptr = Ch_VaArg(interp, ap, void*);

  /* Data type of 5th argument */
  elementtype = Ch_VaDataType(interp, ap);
  if(elementtype == CH_DOUBLETYPE) {
    printf("Element data type of the 5th argument is double\n");
  }

  if(Ch_VaArrayType(interp, ap) == CH_CHARRAYTYPE) {
    printf("The 5th argument is computational array\n");
  }
  else if(Ch_VaArrayType(interp, ap) == CH_CHARRAYPTRTYPE) {
    printf("The 5th argument is pointer to computational array\n");
  }

  /* Dimension of 5th argument */
  d_a = Ch_VaArrayDim(interp, ap);
  printf("Dimension of the 5th argument is = %d\n", d_a);

  /* Number of elements in the 1st dimension of the 5th argument */
  ext_a_1 = Ch_VaArrayExtent(interp, ap, 0);
  printf("Extent of the 1st dimension of the 5th argument is = %d\n", ext_a_1);

  /* Number of elements in the 2nd dimension of the 5th argument */
  ext_a_2 = Ch_VaArrayExtent(interp, ap, 1);
  printf("Extent of the 2nd dimension of the 5th argument is = %d\n", ext_a_2);

  /* Return the 5th argument, and step to the next argument */
  a = Ch_VaArg(interp, ap, double*);

  /* Return the 6th argument, and step to the next argument */
  n = Ch_VaArg(interp, ap, int);
  printf("n from the 6th argument is = %d\n", n);

  /* Dimension of 7th argument */
  n = Ch_VaArrayDim(interp, ap);
  printf("Dimension of the 7th argument is = %d\n", n);

  /* Number of elements in the 1st dimension of the 7th argument */
  ext_a_1 = Ch_VaArrayExtent(interp, ap, 0);
  printf("Extent of the 1st dimension of the 7th argument is = %d\n", ext_a_1);

  /* Return the 7th argument, and step to the next argument */
  a = Ch_VaArg(interp, ap, double*);

  /* Dimension of 8th argument */
  n = Ch_VaArrayDim(interp, ap);
  printf("Dimension of the 8th argument is = %d\n", n);

  /* Number of elements in the 1st dimension of the 8th argument */
  ext_a_1 = Ch_VaArrayExtent(interp, ap, 0);
  printf("Extent of the 1st dimension of the 8th argument is = %d\n", ext_a_1);

  /* Return the 8th argument, and step to the next argument */
  a = Ch_VaArg(interp, ap, double*);

  Ch_VaEnd(interp, ap);
  return retval;
}
