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
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 -------------------------------------------------------------------------*/
29 #include "SDCCglobl.h"
30 #include "SDCChasht.h"
33 #define DEFAULT_HTAB_SIZE 128
35 /*-----------------------------------------------------------------*/
36 /* newHashtItem - creates a new hashtable Item */
37 /*-----------------------------------------------------------------*/
39 _newHashtItem (int key
, void *pkey
, void *item
)
43 htip
= Safe_alloc ( sizeof (hashtItem
));
52 /*-----------------------------------------------------------------*/
53 /* newHashTable - allocates a new hashtable of size */
54 /*-----------------------------------------------------------------*/
56 newHashTable (int size
)
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
*));
68 htab
->minKey
= htab
->size
= size
;
74 hTabAddItemLong (hTab
** htab
, int key
, void *pkey
, void *item
)
80 *htab
= newHashTable (DEFAULT_HTAB_SIZE
);
82 if (key
> (*htab
)->size
)
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;
93 if ((*htab
)->maxKey
< key
)
94 (*htab
)->maxKey
= key
;
96 if ((*htab
)->minKey
> key
)
97 (*htab
)->minKey
= key
;
100 htip
= _newHashtItem (key
, pkey
, item
);
102 /* if there is a clash then goto end of chain */
103 if ((last
= (*htab
)->table
[key
]))
110 /* else just add it */
111 (*htab
)->table
[key
] = htip
;
115 /*-----------------------------------------------------------------*/
116 /* hTabAddItem - adds an item to the hash table */
117 /*-----------------------------------------------------------------*/
119 hTabAddItem (hTab
** htab
, int key
, void *item
)
121 hTabAddItemLong (htab
, key
, NULL
, item
);
124 /*-----------------------------------------------------------------*/
125 /* hTabDeleteItem - either delete an item */
126 /*-----------------------------------------------------------------*/
128 hTabDeleteItem (hTab
** htab
, int key
,
129 const void *item
, DELETE_ACTION action
,
130 int (*compareFunc
) (const void *, const void *))
132 hashtItem
*htip
, **htipp
;
137 /* first check if anything exists in the slot */
138 if (!(*htab
)->table
[key
])
141 /* if delete chain */
142 if (action
== DELETE_CHAIN
)
143 (*htab
)->table
[key
] = NULL
;
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
))
163 htipp
= &(htip
->next
);
170 if (!(*htab
)->nItems
)
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 /*-----------------------------------------------------------------*/
182 hTabDeleteAll (hTab
* p
)
187 register hashtItem
*jc
, *jn
;
188 for (i
= 0; i
< p
->size
; i
++)
191 if (!(jc
= p
->table
[i
]))
202 Safe_free (p
->table
);
206 /*-----------------------------------------------------------------*/
207 /* hTabClearAll - clear all entries in the table (does not free) */
208 /*-----------------------------------------------------------------*/
210 hTabClearAll (hTab
* htab
)
213 if (!htab
|| !htab
->table
)
215 printf ("null table\n");
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 *))
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
))
234 else if (item
== htip
->item
)
240 static const hashtItem
*
241 _findByKey (hTab
* htab
, int key
, const void *pkey
, int (*compare
) (const void *, const void *))
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
))
259 if (pkey
== htip
->pkey
)
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
)))
279 hTabDeleteByKey (hTab
** h
, int key
, const void *pkey
, int (*compare
) (const void *, const void *))
281 hashtItem
*htip
, **htipp
;
287 /* first check if anything exists in the slot */
288 if (!(*h
)->table
[key
])
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
)
300 (compare
&& compare (pkey
, htip
->pkey
)) ||
307 htipp
= &(htip
->next
);
323 /*-----------------------------------------------------------------*/
324 /* hTabIsInTable - will determine if an Item is in the hasht */
325 /*-----------------------------------------------------------------*/
327 hTabIsInTable (hTab
* htab
, int key
,
328 void *item
, int (*compareFunc
) (void *, void *))
330 if (_findItem (htab
, key
, item
, compareFunc
))
335 /*-----------------------------------------------------------------*/
336 /* hTabFirstItem - returns the first Item in the hTab */
337 /*-----------------------------------------------------------------*/
339 hTabFirstItem (hTab
* htab
, int *k
)
346 for (key
= htab
->minKey
; key
<= htab
->maxKey
; key
++)
348 if (htab
->table
[key
])
350 htab
->currItem
= htab
->table
[key
];
353 return htab
->table
[key
]->item
;
359 /*-----------------------------------------------------------------*/
360 /* hTabNextItem - returns the next item in the hTab */
361 /*-----------------------------------------------------------------*/
363 hTabNextItem (hTab
* htab
, int *k
)
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
;
391 /*-----------------------------------------------------------------*/
392 /* hTabFirstItemWK - returns the first Item in the hTab for a key */
393 /*-----------------------------------------------------------------*/
395 hTabFirstItemWK (hTab
* htab
, int wk
)
401 if (wk
< htab
->minKey
|| wk
> htab
->maxKey
)
404 htab
->currItem
= htab
->table
[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 /*-----------------------------------------------------------------*/
414 hTabNextItemWK (hTab
* htab
)
420 /* if this chain not ended then */
421 if (htab
->currItem
->next
)
423 return (htab
->currItem
= htab
->currItem
->next
)->item
;
429 /*-----------------------------------------------------------------*/
430 /* hTabFromTable - hash Table from a hash table */
431 /*-----------------------------------------------------------------*/
433 hTabFromTable (hTab
* htab
)
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
);
454 /*-----------------------------------------------------------------*/
455 /* isHtabsEqual - returns 1 if all items in htab1 is found in htab2 */
456 /*-----------------------------------------------------------------*/
458 isHtabsEqual (hTab
* htab1
, hTab
* htab2
,
459 int (*compareFunc
) (void *, void *))
467 if (htab1
== NULL
|| htab2
== NULL
)
470 /* if they are different sizes then */
471 if (htab1
->nItems
!= htab2
->nItems
)
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
))
484 /*-----------------------------------------------------------------*/
485 /* hTabSearch - returns the first Item with the specified key */
486 /*-----------------------------------------------------------------*/
488 hTabSearch (hTab
* htab
, int key
)
493 if ((key
< htab
->minKey
) || (key
> htab
->maxKey
))
496 if (!htab
->table
[key
])
499 return htab
->table
[key
];
502 /*-----------------------------------------------------------------*/
503 /* hTabItemWithKey - returns the first item with the given key */
504 /*-----------------------------------------------------------------*/
506 hTabItemWithKey (hTab
* htab
, int key
)
510 if (!(htip
= hTabSearch (htab
, key
)))
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 /*-----------------------------------------------------------------*/
528 hTabAddItemIfNotP (hTab
** htab
, int key
, void *item
)
532 hTabAddItem (htab
, key
, item
);
536 if (hTabItemWithKey (*htab
, key
))
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.
549 _compare (const void *s1
, const void *s2
)
551 return !strcmp (s1
, s2
);
555 _hash (const char *sz
)
562 shash_add (hTab
** h
, const char *szKey
, const char *szValue
)
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 */
574 /* Duplicate new value if not NULL */
576 szValue
= Safe_strdup(szValue
);
577 /* Now add in ours */
578 hTabAddItemLong (h
, key
, Safe_strdup (szKey
), (void *)szValue
);
582 shash_find (hTab
* h
, const char *szKey
)
584 int key
= _hash (szKey
);
585 return (char *) hTabFindByKey (h
, key
, szKey
, _compare
);