/* Copyright 1989-93 GROUPE BULL -- See license conditions in file COPYRIGHT */
/*************\
*             *
* KL_STRUCT   *
* DEFINITIONS *
*             *
\*************/

#ifndef INCLUDE_Kl_STRUCT_H
#define INCLUDE_Kl_STRUCT_H

/* type */

typedef struct _KlStruct {
    KlKLONE_HEADER;
    char *ptr;				/* the C object itself */
    struct _KlStructClass *structclass;	/* here we must store structure desc */
}        *KlStruct;

typedef struct _KlCAccessor {
    int offset;				/* offset in structure */
    KlMethod access;			/* func(addr, val or 0, clos, KlStruct)*/
    AnyPtr data;			/* closure */
} *KlCAccessor;
    
typedef struct _KlStructClass {
    KlKLONE_HEADER;
    KlAtom name;
    KlHash slots;
    int size;				/* sizeof. not mandatory */
					/* Redefinable system methods */
    KlMethod make;			/* how to create object */
    KlMethod free;			/* how to free object (d. free) */
    KlMethod print;			/* how to print an object */
    KlMethod parse;			/* how to parse from a printed rep. */
    KlMethod defget;			/* treat slot not found case */
    KlMethod defput;			/* treat slot not found case */
} *KlStructClass;

typedef struct _KlStructArray {
    KlKLONE_HEADER;
    char *ptr;				/* ptr to the C array itself */
    int elt_size;			/* size of element */
    KlMethod access;			/* access to one element */
    int max_size;			/* number of elements, 0 = no check */
    KlMethod free;			/* free method */
    AnyPtr data;
}        *KlStructArray;

typedef struct _KlCWrapper {		/* not used yet */
    KlKLONE_HEADER;
    int arity;
    KlO(*body) ();
    KlMethod *arguments;		/* converters for arguments */
    KlMethod return_type;		/* converter for return */
    AnyPtr data;			/* closure */
}        *KlCWrapper;

/* exported functions */
KlStructClass KlStructClassMake();
void KlDeclareStructClassSlot();
KlStruct KlStructMake();
KlO KlStructClassFreeDefault();
KlO KlStructClassParseDefault();
KlO KlStructClassPrintDefault();

/* accessor functions */
EXT KlO KlStructAccessorChar();
EXT KlO KlStructAccessorShort();
EXT KlO KlStructAccessorInt();
EXT KlO KlStructAccessorLong();
EXT KlO KlStructAccessorFloat();
EXT KlO KlStructAccessorDouble();
EXT KlO KlStructAccessorPtr();
EXT KlO KlStructAccessorStructPtr();
EXT KlO KlStructAccessorString();
EXT KlO KlStructAccessorArray();
EXT KlO KlStructAccessorArrayPtr();
EXT KlO KlStructAccessorKlone();

EXT KlMethod KlStructAccessorScalar[sizeof(long)+1];

/* macros */

#define KlStructAccessorScalarOf(t) KlStructAccessorScalarOfAux[sizeof(t)]
#define KlIsAStruct(obj)  ((obj)->type == KlStructType)
#define KlMustBeStruct(obj, n)  KlArgumentMustBe(obj, n, KlStructType)
#define KlIsAStructClass(obj)  ((obj)->type == KlStructClassType)
#define KlMustBeStructClass(obj, n)  \
    KlArgumentMustBe(obj, n, KlStructClassType)
#define KlIsAStructArray(obj)  ((obj)->type == KlStructArrayType)
#define KlMustBeStructArray(obj, n)  \
    KlArgumentMustBe(obj, n, KlStructArrayType)

#define KlMustBeStructClassStruct(o,n,c) \
    { KlMustBeStruct((o),(n)) ; } \
    ( ((((KlStruct) (o))->structclass) != (c)) \
     && KlBadArgument ((o),(n),(((KlStruct) (o))->structclass->name)) )

#define KlCObjectOfStruct(c) (((KlStruct) (c))->ptr)

/* check for a struct of some particular class */
#define KlIsAStructOfClass(obj, struct_class) \
    (KlIsAStruct(obj) && ((KlStruct) obj)->structclass == (struct_class))
#define KlMustBeStructOfClass(obj, struct_class, n) \
    (KlIsAStructOfClass(obj, struct_class) \
    || KlBadArgument(obj, n, struct_class->name))

/* methods */

EXT KlType KlStructType;
EXT KlType KlStructClassType;
EXT KlType KlStructArrayType;

/* compatibility interface */
#define KlStructClass_name_get(structclass) \
    (structclass)->name
#define KlStructClass_name_set(structclass, newvalue) \
    KlDecRef((structclass)->name), \
    KlIncRef((structclass)->name = (KlAtom) newvalue)
#define KlStructClass_slots_get(structclass) \
    (structclass)->slots
#define KlStructClass_slots_set(structclass, newvalue) \
    KlDecRef((structclass)->slots), \
    KlIncRef((structclass)->slots = (KlAtom) newvalue)
#define KlStructClass_print_get(structclass) \
    (structclass)->print
#define KlStructClass_print_set(structclass, newvalue) \
    (structclass)->print = (KlMethod) newvalue
#define KlStructClass_make_get(structclass) \
    (structclass)->make
#define KlStructClass_make_set(structclass, newvalue) \
    (structclass)->make = (KlMethod) newvalue
#define KlStructClass_free_get(structclass) \
    (structclass)->free
#define KlStructClass_free_set(structclass, newvalue) \
    (structclass)->free = (KlMethod) newvalue
#define KlStructClass_defget_get(structclass) \
    (structclass)->defget
#define KlStructClass_defget_set(structclass, newvalue) \
    (structclass)->defget = (KlMethod) newvalue
#define KlStructClass_defput_get(structclass) \
    (structclass)->defput
#define KlStructClass_defput_set(structclass, newvalue) \
    (structclass)->defput = (KlMethod) newvalue

#endif					/* INCLUDE_Kl_STRUCT_H */


syntax highlighted by Code2HTML, v. 0.9.1