1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1985-2011 AT&T Intellectual Property * 5* and is licensed under the * 6* Common Public License, Version 1.0 * 7* by AT&T Intellectual Property * 8* * 9* A copy of the License is available at * 10* http://www.opensource.org/licenses/cpl1.0.txt * 11* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 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 24/* Change discipline. 25** dt : dictionary 26** disc : discipline 27** 28** Written by Kiem-Phong Vo (5/26/96) 29*/ 30 31#if __STD_C 32static Void_t* dtmemory(Dt_t* dt,Void_t* addr,size_t size,Dtdisc_t* disc) 33#else 34static Void_t* dtmemory(dt, addr, size, disc) 35Dt_t* dt; /* dictionary */ 36Void_t* addr; /* address to be manipulate */ 37size_t size; /* size to obtain */ 38Dtdisc_t* disc; /* discipline */ 39#endif 40{ 41 if(addr) 42 { if(size == 0) 43 { free(addr); 44 return NIL(Void_t*); 45 } 46 else return realloc(addr,size); 47 } 48 else return size > 0 ? malloc(size) : NIL(Void_t*); 49} 50 51#if __STD_C 52Dtdisc_t* dtdisc(Dt_t* dt, Dtdisc_t* disc, int type) 53#else 54Dtdisc_t* dtdisc(dt,disc,type) 55Dt_t* dt; 56Dtdisc_t* disc; 57int type; 58#endif 59{ 60 reg Dtsearch_f searchf; 61 reg Dtlink_t *r, *t; 62 reg char* k; 63 reg Dtdisc_t* old; 64 65 if(!(old = dt->disc) ) /* initialization call from dtopen() */ 66 { dt->disc = disc; 67 if(!(dt->memoryf = disc->memoryf) ) 68 dt->memoryf = dtmemory; 69 return disc; 70 } 71 72 if(!disc) /* only want to know current discipline */ 73 return old; 74 75 searchf = dt->meth->searchf; 76 77 UNFLATTEN(dt); 78 79 if(old->eventf && (*old->eventf)(dt,DT_DISC,(Void_t*)disc,old) < 0) 80 return NIL(Dtdisc_t*); 81 82 dt->disc = disc; 83 if(!(dt->memoryf = disc->memoryf) ) 84 dt->memoryf = dtmemory; 85 86 if(dt->data->type&(DT_STACK|DT_QUEUE|DT_LIST)) 87 goto done; 88 else if(dt->data->type&DT_BAG) 89 { if(type&DT_SAMEHASH) 90 goto done; 91 else goto dt_renew; 92 } 93 else if(dt->data->type&(DT_SET|DT_BAG)) 94 { if((type&DT_SAMEHASH) && (type&DT_SAMECMP)) 95 goto done; 96 else goto dt_renew; 97 } 98 else /*if(dt->data->type&(DT_OSET|DT_OBAG))*/ 99 { if(type&DT_SAMECMP) 100 goto done; 101 dt_renew: 102 r = dtflatten(dt); 103 dt->data->type &= ~DT_FLATTEN; 104 dt->data->here = NIL(Dtlink_t*); 105 dt->data->size = 0; 106 107 if(dt->data->type&(DT_SET|DT_BAG)) 108 { reg Dtlink_t **s, **ends; 109 ends = (s = dt->data->htab) + dt->data->ntab; 110 while(s < ends) 111 *s++ = NIL(Dtlink_t*); 112 } 113 114 /* reinsert them */ 115 while(r) 116 { t = r->right; 117 if(!(type&DT_SAMEHASH)) /* new hash value */ 118 { k = (char*)_DTOBJ(r,disc->link); 119 k = _DTKEY((Void_t*)k,disc->key,disc->size); 120 r->hash = _DTHSH(dt,k,disc,disc->size); 121 } 122 (void)(*searchf)(dt,(Void_t*)r,DT_RENEW); 123 r = t; 124 } 125 } 126 127done: 128 return old; 129} 130