#ifndef _CDT_H
#define _CDT_H 1
#ifndef CDT_VERSION
#ifdef _API_ast
#define CDT_VERSION _API_ast
#else
#define CDT_VERSION 20111111L
#endif
#endif
#ifndef AST_PLUGIN_VERSION
#define AST_PLUGIN_VERSION(v) (v)
#endif
#define CDT_PLUGIN_VERSION AST_PLUGIN_VERSION(20111111L)
#if _PACKAGE_ast
#include <ast_std.h>
#else
#include <ast_common.h>
#include <string.h>
#endif
#define DT_ZERO ((unsigned int)0)
#define DT_ONES (~DT_ZERO)
#define DT_HIBIT (~(DT_ONES >> 1) )
#define DT_LOBIT ((unsigned int)1)
#define DT_NBITS (sizeof(unsigned int)*8)
#define Dtuint_t uintptr_t
typedef struct _dtlink_s Dtlink_t;
typedef struct _dthold_s Dthold_t;
typedef struct _dtdisc_s Dtdisc_t;
typedef struct _dtmethod_s Dtmethod_t;
typedef struct _dtdata_s Dtdata_t;
typedef struct _dtuser_s Dtuser_t;
typedef struct _dt_s Dt_t;
typedef struct _dtstat_s Dtstat_t;
typedef Void_t* (*Dtsearch_f)_ARG_((Dt_t*,Void_t*,int));
typedef Void_t* (*Dtmake_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*));
typedef void (*Dtfree_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*));
typedef int (*Dtcompar_f)_ARG_((Dt_t*,Void_t*,Void_t*,Dtdisc_t*));
typedef unsigned int (*Dthash_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*));
typedef Void_t* (*Dtmemory_f)_ARG_((Dt_t*,Void_t*,size_t,Dtdisc_t*));
typedef int (*Dtevent_f)_ARG_((Dt_t*,int,Void_t*,Dtdisc_t*));
typedef int (*Dttype_f)_ARG_((Dt_t*,int));
struct _dtuser_s
{ unsigned int lock;
Void_t* data;
};
struct _dtlink_s
{
#if CDT_VERSION < 20111111L
Dtlink_t* right;
union
{ unsigned int _hash;
Dtlink_t* _left;
} hl;
#else
union
{ Dtlink_t* __rght;
Dtlink_t* __ptbl;
} rh;
union
{ Dtlink_t* __left;
unsigned int __hash;
} lh;
#endif
};
struct _dthold_s
{ Dtlink_t hdr;
Void_t* obj;
};
struct _dtmethod_s
{ Dtsearch_f searchf;
unsigned int type;
int (*eventf)_ARG_((Dt_t*, int, Void_t*));
char* name;
char* description;
};
struct _dtdisc_s
{ int key;
int size;
int link;
Dtmake_f makef;
Dtfree_f freef;
Dtcompar_f comparf;
Dthash_f hashf;
Dtmemory_f memoryf;
Dtevent_f eventf;
};
#define DTDISC(dc,ky,sz,lk,mkf,frf,cmpf,hshf,memf,evf) \
( (dc)->key = (int)(ky), (dc)->size = (int)(sz), (dc)->link = (int)(lk), \
(dc)->makef = (mkf), (dc)->freef = (frf), \
(dc)->comparf = (cmpf), (dc)->hashf = (hshf), \
(dc)->memoryf = (memf), (dc)->eventf = (evf) )
#ifdef offsetof
#define DTOFFSET(struct_s, member) offsetof(struct_s, member)
#else
#define DTOFFSET(struct_s, member) ((int)(&((struct_s*)0)->member))
#endif
struct _dt_s
{ Dtsearch_f searchf;
Dtdisc_t* disc;
Dtdata_t* data;
Dtmemory_f memoryf;
Dtmethod_t* meth;
ssize_t nview;
Dt_t* view;
Dt_t* walk;
Dtuser_t* user;
Dttype_f typef;
};
#define DT_MAXRECURSE 1024
#define DT_MAXSIZE 256
struct _dtstat_s
{ unsigned int meth;
ssize_t size;
ssize_t space;
ssize_t mlev;
ssize_t msize;
ssize_t lsize[DT_MAXSIZE];
ssize_t tsize[DT_MAXSIZE];
};
#define DT_SET 0000000001
#define DT_BAG 0000000002
#define DT_OSET 0000000004
#define DT_OBAG 0000000010
#define DT_LIST 0000000020
#define DT_STACK 0000000040
#define DT_QUEUE 0000000100
#define DT_DEQUE 0000000200
#define DT_RHSET 0000000400
#define DT_RHBAG 0000001000
#define DT_METHODS 0000001777
#define DT_ORDERED (DT_OSET|DT_OBAG)
#define DT_SAMECMP 0000000001
#define DT_SAMEHASH 0000000002
#define DT_INSERT 0000000001
#define DT_DELETE 0000000002
#define DT_SEARCH 0000000004
#define DT_NEXT 0000000010
#define DT_PREV 0000000020
#define DT_FIRST 0000000200
#define DT_LAST 0000000400
#define DT_MATCH 0000001000
#define DT_ATTACH 0000004000
#define DT_DETACH 0000010000
#define DT_APPEND 0000020000
#define DT_ATLEAST 0000040000
#define DT_ATMOST 0000100000
#define DT_REMOVE 0002000000
#define DT_TOANNOUNCE (DT_INSERT|DT_DELETE|DT_SEARCH|DT_NEXT|DT_PREV|DT_FIRST|DT_LAST|DT_MATCH|DT_ATTACH|DT_DETACH|DT_APPEND|DT_ATLEAST|DT_ATMOST|DT_REMOVE)
#define DT_RELINK 0000002000
#define DT_FLATTEN 0000000040
#define DT_CLEAR 0000000100
#define DT_EXTRACT 0000200000
#define DT_RESTORE 0000400000
#define DT_STAT 0001000000
#define DT_OPERATIONS (DT_TOANNOUNCE|DT_RELINK|DT_FLATTEN|DT_CLEAR|DT_EXTRACT|DT_RESTORE|DT_STAT)
#define DT_INDATA 0010000000
#define DT_SHARE 0020000000
#define DT_ANNOUNCE 0040000000
#define DT_OPTIMIZE 0100000000
#define DT_OPEN 1
#define DT_ENDOPEN 5
#define DT_CLOSE 2
#define DT_ENDCLOSE 6
#define DT_DISC 3
#define DT_METH 4
#define DT_HASHSIZE 7
#define DT_ERROR 0xbad
_BEGIN_EXTERNS_
#if _BLD_cdt && defined(__EXPORT__)
#define extern __EXPORT__
#endif
#if !_BLD_cdt && defined(__IMPORT__)
#define extern __IMPORT__
#endif
extern Dtmethod_t* Dtset;
extern Dtmethod_t* Dtbag;
extern Dtmethod_t* Dtoset;
extern Dtmethod_t* Dtobag;
extern Dtmethod_t* Dtlist;
extern Dtmethod_t* Dtstack;
extern Dtmethod_t* Dtqueue;
extern Dtmethod_t* Dtdeque;
#if _PACKAGE_ast
#define dtplugin(name) ((Dtmethod_t*)dllmeth("cdt", name, CDT_PLUGIN_VERSION))
#define Dtrhbag dtplugin("rehash:Dtrhbag")
#define Dtrhset dtplugin("rehash:Dtrhset")
#else
#if CDTPROPRIETARY
extern Dtmethod_t* Dtrhset;
extern Dtmethod_t* Dtrhbag;
#endif
#endif
#undef extern
#if _BLD_cdt && defined(__EXPORT__)
#define extern __EXPORT__
#endif
extern Dt_t* dtopen _ARG_((Dtdisc_t*, Dtmethod_t*));
extern int dtclose _ARG_((Dt_t*));
extern Dt_t* dtview _ARG_((Dt_t*, Dt_t*));
extern Dtdisc_t* dtdisc _ARG_((Dt_t* dt, Dtdisc_t*, int));
extern Dtmethod_t* dtmethod _ARG_((Dt_t*, Dtmethod_t*));
extern int dtwalk _ARG_((Dt_t*, int(*)(Dt_t*,Void_t*,Void_t*), Void_t*));
extern int dtcustomize _ARG_((Dt_t*, int, int));
extern unsigned int dtstrhash _ARG_((unsigned int, Void_t*, ssize_t));
extern int dtuserlock _ARG_((Dt_t*, unsigned int, int));
extern Void_t* dtuserdata _ARG_((Dt_t*, Void_t*, unsigned int));
extern Dt_t* _dtopen _ARG_((Dtdisc_t*, Dtmethod_t*, unsigned long));
#define dtopen(dc,mt) _dtopen((dc), (mt), CDT_VERSION)
#undef extern
#if _PACKAGE_ast && !defined(_CDTLIB_H)
#if _BLD_dll && defined(__EXPORT__)
#define extern __EXPORT__
#endif
extern void* dllmeth(const char*, const char*, unsigned long);
#undef extern
#endif
_END_EXTERNS_
#define _DT(dt) ((Dt_t*)(dt))
#define _DTLNK(dc,o) ((Dtlink_t*)((char*)(o) + (dc)->link) )
#define _DTO(dc,l) (Void_t*)((char*)(l) - (dc)->link)
#define _DTOBJ(dc,l) ((dc)->link >= 0 ? _DTO(dc,l) : ((Dthold_t*)(l))->obj )
#define _DTK(dc,o) ((char*)(o) + (dc)->key)
#define _DTKEY(dc,o) (Void_t*)((dc)->size >= 0 ? _DTK(dc,o) : *((char**)_DTK(dc,o)) )
#define _DTCMP(dt,k1,k2,dc) \
((dc)->comparf ? (*(dc)->comparf)((dt), (k1), (k2), (dc)) : \
(dc)->size > 0 ? memcmp((Void_t*)(k1), ((Void_t*)k2), (dc)->size) : \
strcmp((char*)(k1), ((char*)k2)) )
#define _DTHSH(dt,ky,dc) ((dc)->hashf ? (*(dc)->hashf)((dt), (ky), (dc)) : \
dtstrhash(0, (ky), (dc)->size) )
#define dtvnext(d) (_DT(d)->view)
#define dtvcount(d) (_DT(d)->nview)
#define dtvhere(d) (_DT(d)->walk)
#define dtlink(d,e) (((Dtlink_t*)(e))->rh.__rght)
#define dtobj(d,e) _DTOBJ(_DT(d)->disc, (e))
#define dtfirst(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_FIRST)
#define dtnext(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_NEXT)
#define dtatleast(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_ATLEAST)
#define dtlast(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_LAST)
#define dtprev(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_PREV)
#define dtatmost(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_ATMOST)
#define dtsearch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_SEARCH)
#define dtmatch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_MATCH)
#define dtinsert(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_INSERT)
#define dtappend(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_APPEND)
#define dtdelete(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_DELETE)
#define dtremove(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_REMOVE)
#define dtattach(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_ATTACH)
#define dtdetach(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_DETACH)
#define dtclear(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_CLEAR)
#define dtflatten(d) (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_FLATTEN)
#define dtextract(d) (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_EXTRACT)
#define dtrestore(d,l) (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(l),DT_RESTORE)
#define dtstat(d,s) (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(s),DT_STAT)
#define dtsize(d) (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_STAT)
#define DT_PRIME 17109811
#define dtcharhash(h,c) (((unsigned int)(h) + (unsigned int)(c)) * DT_PRIME )
#endif