Update svn merge history.
[sdcc.git] / sdcc / src / SDCChasht.c
blobd3ab0303e9130b41f62969f4d9411f1fc212ab0a
1 /*-----------------------------------------------------------------
2 SDCChast.c - contains support routines for hashtables
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #include <stdio.h>
26 #include <string.h>
27 #include <limits.h>
28 #include "SDCCerr.h"
29 #include "SDCCglobl.h"
30 #include "SDCChasht.h"
31 #include "newalloc.h"
33 #define DEFAULT_HTAB_SIZE 128
35 /*-----------------------------------------------------------------*/
36 /* newHashtItem - creates a new hashtable Item */
37 /*-----------------------------------------------------------------*/
38 static hashtItem *
39 _newHashtItem (int key, void *pkey, void *item)
41 hashtItem *htip;
43 htip = Safe_alloc ( sizeof (hashtItem));
45 htip->key = key;
46 htip->pkey = pkey;
47 htip->item = item;
48 htip->next = NULL;
49 return htip;
52 /*-----------------------------------------------------------------*/
53 /* newHashTable - allocates a new hashtable of size */
54 /*-----------------------------------------------------------------*/
55 hTab *
56 newHashTable (int size)
58 hTab *htab;
60 htab = Safe_alloc ( sizeof (hTab));
62 if (!(htab->table = Safe_alloc ((size + 1) * sizeof (hashtItem *))))
64 fprintf (stderr, "out of virtual memory %s %d\n",
65 __FILE__, (size + 1) * (int) sizeof (hashtItem *));
66 exit (1);
68 htab->minKey = htab->size = size;
69 return htab;
73 void
74 hTabAddItemLong (hTab ** htab, int key, void *pkey, void *item)
76 hashtItem *htip;
77 hashtItem *last;
79 if (!(*htab))
80 *htab = newHashTable (DEFAULT_HTAB_SIZE);
82 if (key > (*htab)->size)
84 int i;
85 (*htab)->table = Safe_realloc ((*htab)->table,
86 (key * 2 + 2) * sizeof (hashtItem *));
87 for (i = (*htab)->size + 1; i <= (key * 2 + 1); i++)
88 (*htab)->table[i] = NULL;
89 (*htab)->size = key * 2 + 1;
92 /* update the key */
93 if ((*htab)->maxKey < key)
94 (*htab)->maxKey = key;
96 if ((*htab)->minKey > key)
97 (*htab)->minKey = key;
99 /* create the item */
100 htip = _newHashtItem (key, pkey, item);
102 /* if there is a clash then goto end of chain */
103 if ((last = (*htab)->table[key]))
105 while (last->next)
106 last = last->next;
107 last->next = htip;
109 else
110 /* else just add it */
111 (*htab)->table[key] = htip;
112 (*htab)->nItems++;
115 /*-----------------------------------------------------------------*/
116 /* hTabAddItem - adds an item to the hash table */
117 /*-----------------------------------------------------------------*/
118 void
119 hTabAddItem (hTab ** htab, int key, void *item)
121 hTabAddItemLong (htab, key, NULL, item);
124 /*-----------------------------------------------------------------*/
125 /* hTabDeleteItem - either delete an item */
126 /*-----------------------------------------------------------------*/
127 void
128 hTabDeleteItem (hTab ** htab, int key,
129 const void *item, DELETE_ACTION action,
130 int (*compareFunc) (const void *, const void *))
132 hashtItem *htip, **htipp;
134 if (!(*htab))
135 return;
137 /* first check if anything exists in the slot */
138 if (!(*htab)->table[key])
139 return;
141 /* if delete chain */
142 if (action == DELETE_CHAIN)
143 (*htab)->table[key] = NULL;
144 else
147 /* delete specific item */
148 /* if a compare function is given then use the compare */
149 /* function to find the item, else just compare the items */
151 htipp = &((*htab)->table[key]);
152 htip = (*htab)->table[key];
153 for (; htip; htip = htip->next)
156 if (compareFunc ? compareFunc (item, htip->item) :
157 (item == htip->item))
159 *htipp = htip->next;
160 break;
163 htipp = &(htip->next);
168 (*htab)->nItems--;
170 if (!(*htab)->nItems)
172 *htab = NULL;
176 /*-----------------------------------------------------------------*/
177 /* hTabDeleteAll - deletes all items in a hash table to reduce mem */
178 /* leaks written by */
179 /* "BESSIERE Jerome" <BESSIERE_Jerome@stna.dgac.fr> */
180 /*-----------------------------------------------------------------*/
181 void
182 hTabDeleteAll (hTab * p)
184 if (p && p->table)
186 register int i;
187 register hashtItem *jc, *jn;
188 for (i = 0; i < p->size; i++)
191 if (!(jc = p->table[i]))
192 continue;
193 jn = jc->next;
194 while (jc)
196 Safe_free (jc);
197 if ((jc = jn))
198 jn = jc->next;
200 p->table[i] = NULL;
202 Safe_free (p->table);
206 /*-----------------------------------------------------------------*/
207 /* hTabClearAll - clear all entries in the table (does not free) */
208 /*-----------------------------------------------------------------*/
209 void
210 hTabClearAll (hTab * htab)
213 if (!htab || !htab->table)
215 printf ("null table\n");
216 return;
218 memset (htab->table, 0, htab->size * sizeof (hashtItem *));
220 htab->minKey = htab->size;
221 htab->currKey = htab->nItems = htab->maxKey = 0;
224 static const hashtItem *
225 _findItem (hTab * htab, int key, void *item, int (*compareFunc) (void *, void *))
227 hashtItem *htip;
229 for (htip = htab->table[key]; htip; htip = htip->next)
231 /* if a compare function is given use it */
232 if (compareFunc && compareFunc (item, htip->item))
233 break;
234 else if (item == htip->item)
235 break;
237 return htip;
240 static const hashtItem *
241 _findByKey (hTab * htab, int key, const void *pkey, int (*compare) (const void *, const void *))
243 hashtItem *htip;
245 assert (compare);
247 if (!htab)
248 return NULL;
250 for (htip = htab->table[key]; htip; htip = htip->next)
252 /* if a compare function is given use it */
253 if (compare && compare (pkey, htip->pkey))
255 break;
257 else
259 if (pkey == htip->pkey)
261 break;
265 return htip;
268 void *
269 hTabFindByKey (hTab * h, int key, const void *pkey, int (*compare) (const void *, const void *))
271 const hashtItem *item;
273 if ((item = _findByKey (h, key, pkey, compare)))
274 return item->item;
275 return NULL;
278 int
279 hTabDeleteByKey (hTab ** h, int key, const void *pkey, int (*compare) (const void *, const void *))
281 hashtItem *htip, **htipp;
282 bool found = FALSE;
284 if (!(*h))
285 return 0;
287 /* first check if anything exists in the slot */
288 if (!(*h)->table[key])
289 return 0;
291 /* delete specific item */
292 /* if a compare function is given then use the compare */
293 /* function to find the item, else just compare the items */
295 htipp = &((*h)->table[key]);
296 htip = (*h)->table[key];
297 for (; htip; htip = htip->next)
299 if (
300 (compare && compare (pkey, htip->pkey)) ||
301 pkey == htip->pkey)
303 *htipp = htip->next;
304 found = TRUE;
305 break;
307 htipp = &(htip->next);
310 if (found == TRUE)
312 (*h)->nItems--;
314 if (!(*h)->nItems)
316 *h = NULL;
320 return 1;
323 /*-----------------------------------------------------------------*/
324 /* hTabIsInTable - will determine if an Item is in the hasht */
325 /*-----------------------------------------------------------------*/
326 int
327 hTabIsInTable (hTab * htab, int key,
328 void *item, int (*compareFunc) (void *, void *))
330 if (_findItem (htab, key, item, compareFunc))
331 return 1;
332 return 0;
335 /*-----------------------------------------------------------------*/
336 /* hTabFirstItem - returns the first Item in the hTab */
337 /*-----------------------------------------------------------------*/
338 void *
339 hTabFirstItem (hTab * htab, int *k)
341 int key;
343 if (!htab)
344 return NULL;
346 for (key = htab->minKey; key <= htab->maxKey; key++)
348 if (htab->table[key])
350 htab->currItem = htab->table[key];
351 htab->currKey = key;
352 *k = key;
353 return htab->table[key]->item;
356 return NULL;
359 /*-----------------------------------------------------------------*/
360 /* hTabNextItem - returns the next item in the hTab */
361 /*-----------------------------------------------------------------*/
362 void *
363 hTabNextItem (hTab * htab, int *k)
365 int key;
367 if (!htab)
368 return NULL;
370 /* if this chain not ended then */
371 if (htab->currItem->next)
373 *k = htab->currItem->key;
374 return (htab->currItem = htab->currItem->next)->item;
377 /* find the next chain which has something */
378 for (key = htab->currKey + 1; key <= htab->maxKey; key++)
380 if (htab->table[key])
382 htab->currItem = htab->table[key];
383 *k = htab->currKey = key;
384 return htab->table[key]->item;
388 return NULL;
391 /*-----------------------------------------------------------------*/
392 /* hTabFirstItemWK - returns the first Item in the hTab for a key */
393 /*-----------------------------------------------------------------*/
394 void *
395 hTabFirstItemWK (hTab * htab, int wk)
398 if (!htab)
399 return NULL;
401 if (wk < htab->minKey || wk > htab->maxKey)
402 return NULL;
404 htab->currItem = htab->table[wk];
405 htab->currKey = wk;
407 return (htab->table[wk] ? htab->table[wk]->item : NULL);
410 /*-----------------------------------------------------------------*/
411 /* hTabNextItem - returns the next item in the hTab for a key */
412 /*-----------------------------------------------------------------*/
413 void *
414 hTabNextItemWK (hTab * htab)
417 if (!htab)
418 return NULL;
420 /* if this chain not ended then */
421 if (htab->currItem->next)
423 return (htab->currItem = htab->currItem->next)->item;
426 return NULL;
429 /*-----------------------------------------------------------------*/
430 /* hTabFromTable - hash Table from a hash table */
431 /*-----------------------------------------------------------------*/
432 hTab *
433 hTabFromTable (hTab * htab)
435 hTab *nhtab;
436 hashtItem *htip;
437 int key;
439 if (!htab)
440 return NULL;
442 nhtab = newHashTable (htab->size);
444 for (key = htab->minKey; key <= htab->maxKey; key++)
447 for (htip = htab->table[key]; htip; htip = htip->next)
448 hTabAddItem (&nhtab, htip->key, htip->item);
451 return nhtab;
454 /*-----------------------------------------------------------------*/
455 /* isHtabsEqual - returns 1 if all items in htab1 is found in htab2 */
456 /*-----------------------------------------------------------------*/
457 int
458 isHtabsEqual (hTab * htab1, hTab * htab2,
459 int (*compareFunc) (void *, void *))
461 void *item;
462 int key;
464 if (htab1 == htab2)
465 return 1;
467 if (htab1 == NULL || htab2 == NULL)
468 return 0;
470 /* if they are different sizes then */
471 if (htab1->nItems != htab2->nItems)
472 return 0;
474 /* now do an item by item check */
475 for (item = hTabFirstItem (htab1, &key); item;
476 item = hTabNextItem (htab1, &key))
477 if (!hTabIsInTable (htab2, key, item, compareFunc))
478 return 0;
480 return 1;
484 /*-----------------------------------------------------------------*/
485 /* hTabSearch - returns the first Item with the specified key */
486 /*-----------------------------------------------------------------*/
487 hashtItem *
488 hTabSearch (hTab * htab, int key)
490 if (!htab)
491 return NULL;
493 if ((key < htab->minKey) || (key > htab->maxKey))
494 return NULL;
496 if (!htab->table[key])
497 return NULL;
499 return htab->table[key];
502 /*-----------------------------------------------------------------*/
503 /* hTabItemWithKey - returns the first item with the given key */
504 /*-----------------------------------------------------------------*/
505 void *
506 hTabItemWithKey (hTab * htab, int key)
508 hashtItem *htip;
510 if (!(htip = hTabSearch (htab, key)))
511 return NULL;
513 return htip->item;
516 /*-----------------------------------------------------------------*/
517 /* hTabMaxKey - return the maxKey of item in the hashTable */
518 /*-----------------------------------------------------------------*/
519 int hTabMaxKey (hTab *htab)
521 return (htab ? htab->maxKey : 0);
524 /*-----------------------------------------------------------------*/
525 /*hTabAddItemIfNotP - adds an item with nothing found with key */
526 /*-----------------------------------------------------------------*/
527 void
528 hTabAddItemIfNotP (hTab ** htab, int key, void *item)
530 if (!*htab)
532 hTabAddItem (htab, key, item);
533 return;
536 if (hTabItemWithKey (*htab, key))
537 return;
539 hTabAddItem (htab, key, item);
542 /** Simple implementation of a hash table which uses
543 string (key, value) pairs. If a key already exists in the
544 table, the newly added value will replace it.
545 This is used for the assembler token table. The replace existing
546 condition is used to implement inheritance.
548 static int
549 _compare (const void *s1, const void *s2)
551 return !strcmp (s1, s2);
554 static int
555 _hash (const char *sz)
557 /* Dumb for now */
558 return *sz;
561 void
562 shash_add (hTab ** h, const char *szKey, const char *szValue)
564 char *val;
565 int key = _hash (szKey);
567 /* Find value of the item */
568 val = (char *)hTabFindByKey(*h, key, szKey, _compare);
569 /* Delete any that currently exist */
570 hTabDeleteByKey(h, key, szKey, _compare);
571 /* Deallocate old value in not NULL */
572 if (val != NULL)
573 Safe_free(val);
574 /* Duplicate new value if not NULL */
575 if (szValue != NULL)
576 szValue = Safe_strdup(szValue);
577 /* Now add in ours */
578 hTabAddItemLong (h, key, Safe_strdup (szKey), (void *)szValue);
581 const char *
582 shash_find (hTab * h, const char *szKey)
584 int key = _hash (szKey);
585 return (char *) hTabFindByKey (h, key, szKey, _compare);