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" 23 static 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 */ 31 static 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 39 Dt_t* _dtopen(Dtdisc_t* disc, Dtmethod_t* meth, unsigned long version) 40 #else 41 Dt_t* _dtopen(disc, meth, version) 42 Dtdisc_t* disc; 43 Dtmethod_t* meth; 44 unsigned 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 111 Dt_t* dtopen(Dtdisc_t* disc, Dtmethod_t* meth) 112 #else 113 Dt_t* dtopen(disc, meth) 114 Dtdisc_t* disc; 115 Dtmethod_t* meth; 116 #endif 117 { 118 return _dtopen(disc, meth, 20050420L); 119 } 120 121 /* below are private functions used across CDT modules */ 122 Dtlink_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 146 void _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 157 int 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 166 Void_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