1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1985-2012 AT&T Intellectual Property * 5* and is licensed under the * 6* Eclipse Public License, Version 1.0 * 7* by AT&T Intellectual Property * 8* * 9* A copy of the License is available at * 10* http://www.eclipse.org/org/documents/epl-v10.html * 11* (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12* * 13* Information and Software Systems Research * 14* AT&T Research * 15* Florham Park NJ * 16* * 17* Glenn Fowler <gsf@research.att.com> * 18* David Korn <dgk@research.att.com> * 19* Phong Vo <kpv@research.att.com> * 20* * 21***********************************************************************/ 22#include "dthdr.h" 23static char* Version = "\n@(#)$Id: cdt (AT&T Labs - Research) 2011-11-11 $\0\n"; 24 25/* Make a new dictionary 26** 27** Written by Kiem-Phong Vo (5/25/96) 28*/ 29 30/* map operation bits from the 2005 version to the current version */ 31static int _dttype2005(Dt_t* dt, int type) 32{ 33 if (type == DT_DELETE && (dt->meth->type&(DT_OBAG|DT_BAG))) 34 type = DT_REMOVE; 35 return type; 36} 37 38#if __STD_C 39Dt_t* _dtopen(Dtdisc_t* disc, Dtmethod_t* meth, unsigned long version) 40#else 41Dt_t* _dtopen(disc, meth, version) 42Dtdisc_t* disc; 43Dtmethod_t* meth; 44unsigned long version; 45#endif 46{ 47 Dtdata_t *data; 48 Dt_t *dt, pdt; 49 int ev, type; 50 51 if(!disc || !meth) 52 return NIL(Dt_t*); 53 54 dt = NIL(Dt_t*); 55 data = NIL(Dtdata_t*); 56 type = meth->type; 57 58 memset(&pdt, 0, sizeof(Dt_t)); 59 pdt.searchf = meth->searchf; 60 pdt.meth = meth; 61 dtdisc(&pdt,disc,0); /* note that this sets pdt.memoryf */ 62 63 if(disc->eventf) 64 { if((ev = (*disc->eventf)(&pdt,DT_OPEN,(Void_t*)(&data),disc)) < 0) 65 return NIL(Dt_t*); /* something bad happened */ 66 else if(ev > 0) 67 { if(data) /* shared data are being restored */ 68 { if((data->type & DT_METHODS) != meth->type) 69 { DTERROR(&pdt, "Error in matching methods to restore dictionary"); 70 return NIL(Dt_t*); 71 } 72 pdt.data = data; 73 } 74 } 75 else 76 { if(data) /* dt should be allocated with dt->data */ 77 type |= DT_INDATA; 78 } 79 } 80 81 if(!pdt.data) /* allocate method-specific data */ 82 if((*meth->eventf)(&pdt, DT_OPEN, NIL(Void_t*)) < 0 || !pdt.data ) 83 return NIL(Dt_t*); 84 pdt.data->type |= type; 85 86 /* now allocate/initialize the actual dictionary structure */ 87 if(pdt.data->type&DT_INDATA) 88 dt = &pdt.data->dict; 89 else if(!(dt = (Dt_t*) malloc(sizeof(Dt_t))) ) 90 { (void)(*meth->eventf)(&pdt, DT_CLOSE, NIL(Void_t*)); 91 DTERROR(&pdt, "Error in allocating a new dictionary"); 92 return NIL(Dt_t*); 93 } 94 95 *dt = pdt; 96 97 dt->user = &dt->data->user; /* space allocated for application usage */ 98 99 if(disc->eventf) /* signal opening is done */ 100 (void)(*disc->eventf)(dt, DT_ENDOPEN, (Void_t*)0, disc); 101 102 /* set mapping of operation bits between versions as needed */ 103 if(version < 20111111L) 104 dt->typef = _dttype2005; 105 106 return dt; 107} 108 109#undef dtopen /* deal with binary upward compatibility for op bits */ 110#if __STD_C 111Dt_t* dtopen(Dtdisc_t* disc, Dtmethod_t* meth) 112#else 113Dt_t* dtopen(disc, meth) 114Dtdisc_t* disc; 115Dtmethod_t* meth; 116#endif 117{ 118 return _dtopen(disc, meth, 20050420L); 119} 120 121/* below are private functions used across CDT modules */ 122Dtlink_t* _dtmake(Dt_t* dt, Void_t* obj, int type) 123{ 124 Dthold_t *h; 125 Dtdisc_t *disc = dt->disc; 126 127 /* if obj is a prototype, make a real one */ 128 if(!(type&DT_ATTACH) && disc->makef && !(obj = (*disc->makef)(dt, obj, disc)) ) 129 return NIL(Dtlink_t*); 130 131 if(disc->link >= 0) /* holder is embedded in obj itself */ 132 return _DTLNK(disc, obj); 133 134 /* create a holder to hold obj */ 135 if((h = (Dthold_t*)(dt->memoryf)(dt, NIL(Void_t*), sizeof(Dthold_t), disc)) ) 136 h->obj = obj; 137 else 138 { DTERROR(dt, "Error in allocating an object holder"); 139 if(!(type&DT_ATTACH) && disc->makef && disc->freef) 140 (void)(*disc->freef)(dt, obj, disc); /* free just-made obj */ 141 } 142 143 return (Dtlink_t*)h; 144} 145 146void _dtfree(Dt_t* dt, Dtlink_t* l, int type) 147{ 148 Dtdisc_t *disc = dt->disc; 149 150 if(!(type&DT_DETACH) && disc->freef) /* free object */ 151 (void)(*disc->freef)(dt, _DTOBJ(disc,l), disc); 152 153 if(disc->link < 0) /* free holder */ 154 (void)(*dt->memoryf)(dt, (Void_t*)l, 0, disc); 155} 156 157int dtuserlock(Dt_t* dt, unsigned int key, int type) 158{ 159 if(type > 0) 160 return asolock(&dt->data->user.lock, key, ASO_LOCK); 161 else if(type < 0) 162 return asolock(&dt->data->user.lock, key, ASO_UNLOCK); 163 else return asolock(&dt->data->user.lock, key, ASO_TRYLOCK); 164} 165 166Void_t* dtuserdata(Dt_t* dt, Void_t* data, unsigned int key) 167{ 168 if(key == 0) 169 return dt->data->user.data; 170 else if(dtuserlock(dt, key, 1) < 0 ) 171 return NIL(Void_t*); 172 else 173 { dt->data->user.data = data; 174 dtuserlock(dt, key, -1); 175 return data; 176 } 177} 178