/* Copyright (c) 2001 by SoftIntegration, Inc. All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SoftIntegration  */
/* The copyright notice above does not evidence any    */
/* actual or intended publication of such source code. */


#ifndef _CH_H
#define	_CH_H

#ifdef  _CH_KERNEL
#include <osdef.h> /* different os features are massaged here */
#endif /* _CH_KERNEL */

#include <stdlib.h> /* for size_t */
#if defined(__STDC__) || defined(__cplusplus) || defined(_WIN32)
#include<stdarg.h>  /* for va_list */
#else
#include<varargs.h> /* for va_list */
#endif

#ifdef  __cplusplus
extern "C" {
#endif

/* WINDOWS for WIn95/98/NT are defined in dlcomp command */
#if defined(WINDOWS) || defined(_WIN32)
#ifndef CALLBACK
#ifdef _MAC
#define CALLBACK PASCAL
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define CALLBACK __stdcall
#else
#define CALLBACK
#endif
#endif
  #ifdef  __cplusplus /* C++ program */
  #define IMPORTCH extern "C" __declspec(dllimport)
  #define EXPORTCH extern "C" __declspec(dllexport)
  #define EXPORTCHCLASS __declspec(dllexport)
  #else               /* C program */
  #define IMPORTCH extern __declspec(dllimport)
  #define EXPORTCH __declspec(dllexport)
  #endif
#else /* Unix */
#define IMPORTCH extern
#define CALLBACK
  #ifdef  __cplusplus /* C++ program */
  #define EXPORTCH extern "C"
  #define EXPORTCHCLASS 
  #else
  #define EXPORTCH
  #endif
#endif

/* element type in Ch */
typedef enum _elementtype {
    CH_UNDEFINETYPE,/* undefined type */
    /* simple type */
    CH_CHARTYPE=10, /* char */
    CH_UCHARTYPE,   /* unsigned char */
    CH_SHORTTYPE,   /* short */
    CH_USHORTTYPE,  /* unsigned short */
    CH_INTTYPE,     /* int, long int */
    CH_UINTTYPE,    /* unsigned int, unsigned long int */
    CH_LLINTTYPE,   /* long long int */
    CH_ULLINTTYPE,  /* unsigned long long int */
    CH_FLOATTYPE,   /* float */
    CH_DOUBLETYPE,  /* double */
    CH_LDOUBLETYPE, /* long double */
    CH_COMPLEXTYPE, /* float complex */
    CH_LCOMPLEXTYPE,/* long complex */
    CH_STRINGTYPE,  /* string_t type */
    CH_FILETYPE,    /* FILE */
    CH_VOIDTYPE,    /* void */
    CH_PROCTYPE,    /* function type */
    CH_STRUCTTYPE,  /* struct */
    CH_CLASSTYPE,   /* class */
    CH_UNIONTYPE,   /* union */
    CH_ENUMTYPE,    /* enum */

/* returned Ch array type for Ch_VaArrayType(), Ch_VaArrayType(), and Ch_funcArgArrayType() */
/* CH_CARRAYTYPE and CH_CHARRAYTYPE are also used in ChVarArgsAddArg() and Ch_SetVar() */
/* Ch_VarArgsAddArg(&arglist, CH_CARRAYTYPE, CH_INTTYPE, a, dim, extent, ...) */
/* Ch_VarArgsAddArg(&arglist, CH_CHARRAYTYPE, CH_INTTYPE, a, dim, extent, ...) */
    CH_CARRAYTYPE=80,  /* int a[3] */
    CH_CARRAYPTRTYPE,  /* int (*ap)[3]; */
    CH_CARRAYVLATYPE,  /* int a[n]; int func(int a[n], int b[:], int c[&]) */
    CH_CHARRAYTYPE,    /* array int a[3] */
    CH_CHARRAYPTRTYPE, /* array int (*ap)[3] */
    CH_CHARRAYVLATYPE, /* array int a[n]; int fun(array int a[n], array int b[:], array int c[&]) */

    /* pointer */
    CH_NULLTYPE = 100, /* NULL */
    CH_VOIDPTRTYPE,    /* void* */
    CH_CHARPTRTYPE,    /* char* */
    CH_UCHARPTRTYPE,   /* unsigned char* */
    CH_SHORTPTRTYPE,   /* short* */
    CH_USHORTPTRTYPE,  /* unsigned short* */
    CH_INTPTRTYPE,     /* int*, long int * */
    CH_UINTPTRTYPE,    /* unsigned int*, unsigned long int * */
    CH_LLINTPTRTYPE,   /* long long int* */
    CH_ULLINTPTRTYPE,  /* unsigned long long int* */
    CH_FLOATPTRTYPE,   /* float* */
    CH_DOUBLEPTRTYPE,  /* double* */
    CH_LDOUBLEPTRTYPE, /* long double* */
    CH_COMPLEXPTRTYPE, /* float complex* */
    CH_LCOMPLEXPTRTYPE,/* long complex* */
    CH_STRINGPTRTYPE,  /* string_t * */
    CH_PROCPTRTYPE,    /* function ptr type */
    CH_FILEPTRTYPE,    /* FILE * */
    CH_STRUCTPTRTYPE,  /* struct * */
    CH_CLASSPTRTYPE,   /* class* */
    CH_UNIONPTRTYPE,   /* union * */
    CH_ENUMPTRTYPE,    /* enum * */

    /* double pointer */
    CH_VOIDPTR2TYPE=200,/* void** */
    CH_CHARPTR2TYPE,    /* char** */
    CH_UCHARPTR2TYPE,   /* unsigned char** */
    CH_SHORTPTR2TYPE,   /* short** */
    CH_USHORTPTR2TYPE,  /* unsigned short** */
    CH_INTPTR2TYPE,     /* int*, long int** */
    CH_UINTPTR2TYPE,    /* unsigned int**, unsigned long int** */
    CH_LLINTPTR2TYPE,   /* long long int** */
    CH_ULLINTPTR2TYPE,  /* unsigned long long int** */
    CH_FLOATPTR2TYPE,   /* float** */
    CH_DOUBLEPTR2TYPE,  /* double** */
    CH_LDOUBLEPTR2TYPE, /* long double** */
    CH_COMPLEXPTR2TYPE, /* float complex** */
    CH_LCOMPLEXPTR2TYPE,/* long complex** */
    CH_STRINGPTR2TYPE,  /* string_t ** */
    CH_FILEPTR2TYPE,    /* FILE ** */
    CH_STRUCTPTR2TYPE,  /* struct ** for now */
    CH_CLASSPTR2TYPE,   /* class ** */
    CH_UNIONPTR2TYPE,    /* union ** */
    CH_ENUMPTR2TYPE     /* enum ** */
} ChType_t;

typedef void *ChInterp_t;  /* pointer to  Ch interpreter structure */
typedef void *ChVaList_t;     /* pointer to  Ch list from Ch_VaStart() */

/* the return value for APIs of int type */
#define CH_OK 0
#define CH_ERROR (-1)
#define CH_ABORT 1

/* APIs for building dynamically loaded lib .dl to 
   interface binary C functions and C++ methdods */
/* #define Ch_VaStart(list, varg) list = (ChVaList_t)varg; */
#define Ch_VaStart(interp, list, varg) list = (ChVaList_t)__builtin_Ch_VaStart(&interp, varg);
#define Ch_VaArg(interp, list, type) ((type*)__builtin_Ch_VaArg(interp, (void **)&list))[0]
extern void *__builtin_Ch_VaStart (ChInterp_t *interp, void *varg);
extern void *__builtin_Ch_VaArg (ChInterp_t interp, void** list);
/* extern int   Ch_VaElementtype(ChInterp_t interp, ChVaList_t ap); */ /* obsolete, use Ch_VaDataType() */
extern int   Ch_VaCount(ChInterp_t interp, ChVaList_t ap);
extern void  Ch_VaEnd(ChInterp_t interp, ChVaList_t ap);
extern ChType_t Ch_VaDataType(ChInterp_t interp, ChVaList_t ap);
extern ChType_t Ch_VaArrayType(ChInterp_t interp, ChVaList_t ap);
extern int   Ch_VaArrayDim(ChInterp_t interp, ChVaList_t ap);
extern int   Ch_VaArrayExtent(ChInterp_t interp, ChVaList_t ap, int index); /* int a[n][m]; index 0 for n, index 1 for m */
extern int   Ch_VaIsFunc(ChInterp_t interp, ChVaList_t ap);
extern int   Ch_VaIsFuncVarArg(ChInterp_t interp, ChVaList_t ap);
extern ChType_t Ch_VaFuncArgDataType(ChInterp_t interp, ChVaList_t ap, int argnum);
extern int   Ch_VaFuncArgNum(ChInterp_t interp, ChVaList_t ap); 
/* extern void *Ch_VaStructAddr(ChInterp_t interp, ChVaList_t ap); */ /* obsolete, use Ch_VaUserDefinedAddr() */ 
/* extern void *Ch_VaStructSize(ChInterp_t interp, ChVaList_t ap); */ /* obsolete, use Ch_VaUserDefinedSize() */ 
extern void *Ch_VaUserDefinedAddr(ChInterp_t interp, ChVaList_t ap); 
extern char *Ch_VaUserDefinedName(ChInterp_t interp, ChVaList_t ap); 
extern int   Ch_VaUserDefinedSize(ChInterp_t interp, ChVaList_t ap); 
/* For calling C funtions of int func(ChInterp_t interp, int param, ...) in _chd.c */
/* va_list Ch_VaVarArgsCreate(ChInterp_t interp, ChVaList_t ap, void **memhandle); */
extern void *Ch_VaVarArgsCreate(ChInterp_t interp, ChVaList_t ap, void **memhandle);
extern void  Ch_VaVarArgsDelete(ChInterp_t interp, void *memhandle);
/* For calling Ch funtions of int func(int param, ...) and int func(int param, ChVaList_t ap)
   from Ch_CallFuncByName() */
extern ChVaList_t Ch_VarArgsCreate(ChInterp_t interp);
extern int   Ch_VarArgsAddArg(ChInterp_t interp, ChVaList_t *arglistp, ChType_t atype, ... /* type arg */ 
                                                                /* CH_CHARRAYTYPE, atype, a, dim, extent */
                                                                /* char *tagname, void *arg */);
extern int   Ch_VarArgsAddArgExpr(ChInterp_t interp, ChVaList_t *arglistp, const char *expr);
extern void  Ch_VarArgsDelete(ChInterp_t interp, ChVaList_t arglist);

/* general API */
extern char* Ch_Home(ChInterp_t interp); 
extern void *Ch_SymbolAddrByName(ChInterp_t interp, const char *name);
extern int   Ch_CallFuncByAddr(ChInterp_t interp, void *fptr, void *retval, ...);
extern int   Ch_CallFuncByName(ChInterp_t interp, const char *name, void *retval, ...);
extern int   Ch_CallFuncByNameVar(ChInterp_t interp, const char *name, void *retval, ChVaList_t arglist);
extern int   Ch_CppChangeThisPointer(ChInterp_t interp, void *thisp, size_t size); 
extern int   Ch_CppIsArrayElement(ChInterp_t interp);
/* extern void* Ch_GetSymbol(ChInterp_t interp, const char *name); */ /* obsolete , use Ch_SymbolAddrByName(interp, name) */

#ifdef  __cplusplus
}
#endif

#endif  /* _CH_H*/

