Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libast / hash / hashalloc.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: hashalloc.c /main/3 1995/11/01 17:31:52 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *         THIS IS PROPRIETARY SOURCE CODE LICENSED BY          *
29 *                          AT&T CORP.                          *
30 *                                                              *
31 *                Copyright (c) 1995 AT&T Corp.                 *
32 *                     All Rights Reserved                      *
33 *                                                              *
34 *           This software is licensed by AT&T Corp.            *
35 *       under the terms and conditions of the license in       *
36 *       http://www.research.att.com/orgs/ssr/book/reuse        *
37 *                                                              *
38 *               This software was created by the               *
39 *           Software Engineering Research Department           *
40 *                    AT&T Bell Laboratories                    *
41 *                                                              *
42 *               For further information contact                *
43 *                     gsf@research.att.com                     *
44 *                                                              *
45 ***************************************************************/
46
47 /* : : generated by proto : : */
48
49 #if !defined(__PROTO__)
50 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
51 #if defined(__cplusplus)
52 #define __MANGLE__      "C"
53 #else
54 #define __MANGLE__
55 #endif
56 #define __STDARG__
57 #define __PROTO__(x)    x
58 #define __OTORP__(x)
59 #define __PARAM__(n,o)  n
60 #if !defined(__STDC__) && !defined(__cplusplus)
61 #if !defined(c_plusplus)
62 #define const
63 #endif
64 #define signed
65 #define void            int
66 #define volatile
67 #define __V_            char
68 #else
69 #define __V_            void
70 #endif
71 #else
72 #define __PROTO__(x)    ()
73 #define __OTORP__(x)    x
74 #define __PARAM__(n,o)  o
75 #define __MANGLE__
76 #define __V_            char
77 #define const
78 #define signed
79 #define void            int
80 #define volatile
81 #endif
82 #if defined(__cplusplus) || defined(c_plusplus)
83 #define __VARARG__      ...
84 #else
85 #define __VARARG__
86 #endif
87 #if defined(__STDARG__)
88 #define __VA_START__(p,a)       va_start(p,a)
89 #else
90 #define __VA_START__(p,a)       va_start(p)
91 #endif
92 #endif
93 static const char id_hash[] = "\n@(#)hash (AT&T Bell Laboratories) 05/09/95\0\n";
94
95 #include "hashlib.h"
96
97 #if _DLL_INDIRECT_DATA && !_DLL
98 static Hash_info_t      hash_info_data;
99 Hash_info_t             hash_info = &hash_info_data;
100 #else
101 Hash_info_t             hash_info = { 0 };
102 #endif
103
104 /*
105  * create a new hash table
106  */
107
108 Hash_table_t*
109 hashalloc __PARAM__((Hash_table_t* ref, ...), (va_alist)) __OTORP__(va_dcl)
110 { __OTORP__(Hash_table_t* ref; )
111         register Hash_table_t*  tab;
112         register Hash_table_t*  ret = 0;
113         register int            internal;
114         int                     n;
115         va_list                 ap;
116         va_list                 va[4];
117         va_list*                vp = va;
118         HASHregion              region = 0;
119         __V_*                   handle;
120
121         __VA_START__(ap, ref); __OTORP__(ref = va_arg(ap, Hash_table_t* );)
122
123         /*
124          * check for HASH_region which must be first
125          */
126
127         n = va_arg(ap, int);
128         if (!ref && n == HASH_region)
129         {
130                 region = va_arg(ap, HASHregion);
131                 handle = va_arg(ap, __V_*);
132                 n = va_arg(ap, int);
133                 if (!(tab = (Hash_table_t*)(*region)(handle, NiL, sizeof(Hash_table_t), 0)))
134                         goto out;
135                 memset(tab, 0, sizeof(Hash_table_t));
136         }
137         else if (!(tab = newof(0, Hash_table_t, 1, 0)))
138                 goto out;
139         tab->bucketsize = (sizeof(Hash_header_t) + sizeof(char*) - 1) / sizeof(char*);
140         if (ref)
141         {
142                 tab->flags = ref->flags & ~HASH_RESET;
143                 tab->root = ref->root;
144                 internal = HASH_INTERNAL;
145         }
146         else
147         {
148                 if (region)
149                 {
150                         if (!(tab->root = (Hash_root_t*)(*region)(handle, NiL, sizeof(Hash_root_t), 0)))
151                                 goto out;
152                         memset(tab->root, 0, sizeof(Hash_root_t));
153                 }
154                 else if (!(tab->root = newof(0, Hash_root_t, 1, 0)))
155                         goto out;
156                 if (!(tab->root->local = newof(0, Hash_local_t, 1, 0)))
157                         goto out;
158                 if (tab->root->local->region = region)
159                         tab->root->local->handle = handle;
160                 tab->root->meanchain = HASHMEANCHAIN;
161                 internal = 0;
162         }
163         tab->size = HASHMINSIZE;
164         for (;;)
165         {
166                 switch (n) 
167                 {
168                 case HASH_alloc:
169                         if (ref) goto out;
170                         tab->root->local->alloc = va_arg(ap, HASHalloc);
171                         break;
172                 case HASH_bucketsize:
173                         n = (va_arg(ap, int) + sizeof(char*) - 1) / sizeof(char*);
174                         if (n > UCHAR_MAX) goto out;
175                         if (n > tab->bucketsize) tab->bucketsize = n;
176                         break;
177                 case HASH_clear:
178                         tab->flags &= ~(va_arg(ap, int) & ~internal);
179                         break;
180                 case HASH_compare:
181                         if (ref) goto out;
182                         tab->root->local->compare = va_arg(ap, HASHcompare);
183                         break;
184                 case HASH_free:
185                         if (ref) goto out;
186                         tab->root->local->free = va_arg(ap, HASHfree);
187                         break;
188                 case HASH_hash:
189                         if (ref) goto out;
190                         tab->root->local->hash = va_arg(ap, HASHhash);
191                         break;
192                 case HASH_meanchain:
193                         if (ref) goto out;
194                         tab->root->meanchain = va_arg(ap, int);
195                         break;
196                 case HASH_name:
197                         tab->name = va_arg(ap, char*);
198                         break;
199                 case HASH_namesize:
200                         if (ref) goto out;
201                         tab->root->namesize = va_arg(ap, int);
202                         break;
203                 case HASH_region:
204                         goto out;
205                 case HASH_set:
206                         tab->flags |= (va_arg(ap, int) & ~internal);
207                         break;
208                 case HASH_size:
209                         tab->size = va_arg(ap, int);
210                         if (tab->size & (tab->size - 1)) tab->flags |= HASH_FIXED;
211                         break;
212                 case HASH_table:
213                         tab->table = va_arg(ap, Hash_bucket_t**);
214                         tab->flags |= HASH_STATIC;
215                         break;
216                 case HASH_va_list:
217 #ifdef __ppc
218                         if (vp < &va[elementsof(va)])
219                         {
220                                 __va_copy( *vp, ap );
221                                 vp++;
222                         }
223                         __va_copy(ap, *((va_list *) va_arg(ap, va_list)) );
224 #else
225                         if (vp < &va[elementsof(va)]) *vp++ = ap;
226                         ap = va_arg(ap, va_list);
227 #endif
228                         break;
229                 case 0:
230                         if (vp > va)
231                         {
232 #ifdef __ppc
233                                 vp--;
234                                 __va_copy( ap, *vp );
235 #else
236                                 ap = *--vp;
237 #endif
238                                 break;
239                         }
240                         if (tab->flags & HASH_SCOPE)
241                         {
242                                 if (!(tab->scope = ref)) goto out;
243                                 ref->frozen++;
244                         }
245                         if (!tab->table)
246                         {
247                                 if (region)
248                                 {
249                                         if (!(tab->table = (Hash_bucket_t**)(*region)(handle, NiL, sizeof(Hash_bucket_t*) * tab->size, 0)))
250                                                 goto out;
251                                         memset(tab->table, 0, sizeof(Hash_bucket_t*) * tab->size);
252                                 }
253                                 else if (!(tab->table = newof(0, Hash_bucket_t*, tab->size, 0))) goto out;
254                         }
255                         if (!ref)
256                         {
257                                 tab->root->flags = tab->flags & HASH_INTERNAL;
258                                 tab->root->next = hash_info.list;
259                                 hash_info.list = tab->root;
260                         }
261                         if (!region)
262                         {
263                                 tab->next = tab->root->references;
264                                 tab->root->references = tab;
265                         }
266                         ret = tab;
267                         goto out;
268                 default:
269                         goto out;
270                 }
271                 n = va_arg(ap, int);
272         }
273  out:
274         va_end(ap);
275         if (!ret) hashfree(tab);
276         return(ret);
277 }