Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/hash/hashfree.c
1810 views
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
* 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 <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
/*
24
* Glenn Fowler
25
* AT&T Research
26
*
27
* hash table library
28
*/
29
30
#include "hashlib.h"
31
32
/*
33
* free (remove) a hash table
34
* can be called for partially constructed tables
35
* scope covered table pointer is returned
36
* root info freed when last reference freed
37
*/
38
39
Hash_table_t*
40
hashfree(register Hash_table_t* tab)
41
{
42
register Hash_bucket_t** sp;
43
register Hash_bucket_t* b;
44
register Hash_bucket_t* p;
45
Hash_bucket_t** sx;
46
Hash_root_t* rp;
47
Hash_table_t* tp;
48
Hash_free_f freevalue;
49
Hash_free_f freebucket;
50
Hash_region_f region;
51
void* handle;
52
53
if (!tab) return(0);
54
if (tab->table)
55
{
56
freebucket = 0;
57
freevalue = 0;
58
if (tab->root->local->free)
59
{
60
if (tab->root->flags & HASH_BUCKET) freebucket = tab->root->local->free;
61
else freevalue = tab->root->local->free;
62
}
63
if (region = tab->root->local->region)
64
handle = tab->root->local->handle;
65
sx = &tab->table[tab->size];
66
sp = &tab->table[0];
67
while (sp < sx)
68
{
69
b = *sp++;
70
while (b)
71
{
72
p = b;
73
b = b->next;
74
if (freebucket) (*freebucket)((char*)p);
75
else if (freevalue && p->value) (*freevalue)(p->value);
76
if (p->hash & HASH_FREENAME)
77
{
78
p->hash &= ~HASH_FREENAME;
79
if (region) (*region)(handle, p->name, 0, 0);
80
else free(p->name);
81
}
82
if (!(p->hash & HASH_KEEP))
83
{
84
if (region) (*region)(handle, p, 0, 0);
85
else free(p);
86
}
87
else if (p->hash & HASH_HIDES)
88
{
89
p->hash &= ~HASH_HIDES;
90
p->name = ((Hash_bucket_t*)p->name)->name;
91
}
92
}
93
}
94
if ((tab->flags & (HASH_RESIZE|HASH_STATIC)) != HASH_STATIC)
95
{
96
if (region) (*region)(handle, tab->table, 0, 0);
97
else free(tab->table);
98
}
99
}
100
else region = 0;
101
if (tab->root)
102
{
103
if (!region)
104
{
105
/*
106
* remove from the table lists
107
*/
108
109
if ((tp = tab->root->references) != tab)
110
{
111
for (; tp; tp = tp->next)
112
if (tp->next == tab)
113
{
114
tp->next = tab->next;
115
break;
116
}
117
}
118
else if (!(tab->root->references = tp->next))
119
{
120
if ((rp = hash_info.list) != tab->root)
121
{
122
for (; rp; rp = rp->next)
123
if (rp->next == tab->root)
124
{
125
rp->next = tab->root->next;
126
break;
127
}
128
}
129
else hash_info.list = rp->next;
130
}
131
}
132
if (!(tab->root->references))
133
{
134
if (tab->root->local)
135
free(tab->root->local);
136
if (region) (*region)(handle, tab->root, 0, 0);
137
else free(tab->root);
138
}
139
}
140
if (tp = tab->scope) tp->frozen--;
141
if (region) (*region)(handle, tab, 0, 0);
142
else free(tab);
143
return(tp);
144
}
145
146