xref: /aosp_15_r20/external/antlr/runtime/C/src/antlr3collections.c (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robot /// \file
2*16467b97STreehugger Robot /// Provides a number of useful functions that are roughly equivalent
3*16467b97STreehugger Robot /// to java HashTable and List for the purposes of Antlr 3 C runtime.
4*16467b97STreehugger Robot /// Also useable by the C programmer for things like symbol tables pointers
5*16467b97STreehugger Robot /// and so on.
6*16467b97STreehugger Robot ///
7*16467b97STreehugger Robot ///
8*16467b97STreehugger Robot 
9*16467b97STreehugger Robot // [The "BSD licence"]
10*16467b97STreehugger Robot // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
11*16467b97STreehugger Robot // http://www.temporal-wave.com
12*16467b97STreehugger Robot // http://www.linkedin.com/in/jimidle
13*16467b97STreehugger Robot //
14*16467b97STreehugger Robot // All rights reserved.
15*16467b97STreehugger Robot //
16*16467b97STreehugger Robot // Redistribution and use in source and binary forms, with or without
17*16467b97STreehugger Robot // modification, are permitted provided that the following conditions
18*16467b97STreehugger Robot // are met:
19*16467b97STreehugger Robot // 1. Redistributions of source code must retain the above copyright
20*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer.
21*16467b97STreehugger Robot // 2. Redistributions in binary form must reproduce the above copyright
22*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer in the
23*16467b97STreehugger Robot //    documentation and/or other materials provided with the distribution.
24*16467b97STreehugger Robot // 3. The name of the author may not be used to endorse or promote products
25*16467b97STreehugger Robot //    derived from this software without specific prior written permission.
26*16467b97STreehugger Robot //
27*16467b97STreehugger Robot // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28*16467b97STreehugger Robot // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29*16467b97STreehugger Robot // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30*16467b97STreehugger Robot // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31*16467b97STreehugger Robot // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32*16467b97STreehugger Robot // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33*16467b97STreehugger Robot // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34*16467b97STreehugger Robot // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35*16467b97STreehugger Robot // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36*16467b97STreehugger Robot // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37*16467b97STreehugger Robot 
38*16467b97STreehugger Robot #include    <antlr3.h>
39*16467b97STreehugger Robot 
40*16467b97STreehugger Robot #include "antlr3collections.h"
41*16467b97STreehugger Robot 
42*16467b97STreehugger Robot // Interface functions for hash table
43*16467b97STreehugger Robot //
44*16467b97STreehugger Robot 
45*16467b97STreehugger Robot // String based keys
46*16467b97STreehugger Robot //
47*16467b97STreehugger Robot static void					antlr3HashDelete    (pANTLR3_HASH_TABLE table, void * key);
48*16467b97STreehugger Robot static void *				antlr3HashGet	(pANTLR3_HASH_TABLE table, void * key);
49*16467b97STreehugger Robot static pANTLR3_HASH_ENTRY   antlr3HashRemove    (pANTLR3_HASH_TABLE table, void * key);
50*16467b97STreehugger Robot static ANTLR3_INT32			antlr3HashPut	(pANTLR3_HASH_TABLE table, void * key, void * element, void (ANTLR3_CDECL *freeptr)(void *));
51*16467b97STreehugger Robot 
52*16467b97STreehugger Robot // Integer based keys (Lists and so on)
53*16467b97STreehugger Robot //
54*16467b97STreehugger Robot static void					antlr3HashDeleteI   (pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key);
55*16467b97STreehugger Robot static void *				antlr3HashGetI	(pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key);
56*16467b97STreehugger Robot static pANTLR3_HASH_ENTRY   antlr3HashRemoveI   (pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key);
57*16467b97STreehugger Robot static ANTLR3_INT32			antlr3HashPutI	(pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key, void * element, void (ANTLR3_CDECL *freeptr)(void *));
58*16467b97STreehugger Robot 
59*16467b97STreehugger Robot static void					antlr3HashFree	(pANTLR3_HASH_TABLE table);
60*16467b97STreehugger Robot static ANTLR3_UINT32	    antlr3HashSize	(pANTLR3_HASH_TABLE table);
61*16467b97STreehugger Robot 
62*16467b97STreehugger Robot // -----------
63*16467b97STreehugger Robot 
64*16467b97STreehugger Robot // Interface functions for enumeration
65*16467b97STreehugger Robot //
66*16467b97STreehugger Robot static int	    antlr3EnumNext	    (pANTLR3_HASH_ENUM en, pANTLR3_HASH_KEY * key, void ** data);
67*16467b97STreehugger Robot static void	    antlr3EnumFree	    (pANTLR3_HASH_ENUM en);
68*16467b97STreehugger Robot 
69*16467b97STreehugger Robot // Interface functions for List
70*16467b97STreehugger Robot //
71*16467b97STreehugger Robot static void				antlr3ListFree	(pANTLR3_LIST list);
72*16467b97STreehugger Robot static void				antlr3ListDelete(pANTLR3_LIST list, ANTLR3_INTKEY key);
73*16467b97STreehugger Robot static void *			antlr3ListGet	(pANTLR3_LIST list, ANTLR3_INTKEY key);
74*16467b97STreehugger Robot static ANTLR3_INT32		antlr3ListPut	(pANTLR3_LIST list, ANTLR3_INTKEY key, void * element, void (ANTLR3_CDECL *freeptr)(void *));
75*16467b97STreehugger Robot static ANTLR3_INT32		antlr3ListAdd   (pANTLR3_LIST list, void * element, void (ANTLR3_CDECL *freeptr)(void *));
76*16467b97STreehugger Robot static void *			antlr3ListRemove(pANTLR3_LIST list, ANTLR3_INTKEY key);
77*16467b97STreehugger Robot static ANTLR3_UINT32	antlr3ListSize	(pANTLR3_LIST list);
78*16467b97STreehugger Robot 
79*16467b97STreehugger Robot // Interface functions for Stack
80*16467b97STreehugger Robot //
81*16467b97STreehugger Robot static void				antlr3StackFree	(pANTLR3_STACK  stack);
82*16467b97STreehugger Robot static void *			antlr3StackPop	(pANTLR3_STACK	stack);
83*16467b97STreehugger Robot static void *			antlr3StackGet	(pANTLR3_STACK	stack, ANTLR3_INTKEY key);
84*16467b97STreehugger Robot static ANTLR3_BOOLEAN	antlr3StackPush	(pANTLR3_STACK	stack, void * element, void (ANTLR3_CDECL *freeptr)(void *));
85*16467b97STreehugger Robot static ANTLR3_UINT32	antlr3StackSize	(pANTLR3_STACK	stack);
86*16467b97STreehugger Robot static void *			antlr3StackPeek	(pANTLR3_STACK	stack);
87*16467b97STreehugger Robot 
88*16467b97STreehugger Robot // Interface functions for vectors
89*16467b97STreehugger Robot //
90*16467b97STreehugger Robot static	void ANTLR3_CDECL	antlr3VectorFree	(pANTLR3_VECTOR vector);
91*16467b97STreehugger Robot static	void				antlr3VectorDel		(pANTLR3_VECTOR vector, ANTLR3_UINT32 entry);
92*16467b97STreehugger Robot static	void *				antlr3VectorGet		(pANTLR3_VECTOR vector, ANTLR3_UINT32 entry);
93*16467b97STreehugger Robot static	void *				antrl3VectorRemove	(pANTLR3_VECTOR vector, ANTLR3_UINT32 entry);
94*16467b97STreehugger Robot static	void				antlr3VectorClear	(pANTLR3_VECTOR vector);
95*16467b97STreehugger Robot static	ANTLR3_UINT32		antlr3VectorAdd		(pANTLR3_VECTOR vector, void * element, void (ANTLR3_CDECL *freeptr)(void *));
96*16467b97STreehugger Robot static	ANTLR3_UINT32		antlr3VectorSet		(pANTLR3_VECTOR vector, ANTLR3_UINT32 entry, void * element, void (ANTLR3_CDECL *freeptr)(void *), ANTLR3_BOOLEAN freeExisting);
97*16467b97STreehugger Robot static	ANTLR3_UINT32		antlr3VectorSize    (pANTLR3_VECTOR vector);
98*16467b97STreehugger Robot static	ANTLR3_BOOLEAN      antlr3VectorSwap	(pANTLR3_VECTOR vector, ANTLR3_UINT32 entry1, ANTLR3_UINT32 entry2);
99*16467b97STreehugger Robot 
100*16467b97STreehugger Robot static  ANTLR3_BOOLEAN      newPool             (pANTLR3_VECTOR_FACTORY factory);
101*16467b97STreehugger Robot static  void				closeVectorFactory  (pANTLR3_VECTOR_FACTORY factory);
102*16467b97STreehugger Robot static	pANTLR3_VECTOR		newVector			(pANTLR3_VECTOR_FACTORY factory);
103*16467b97STreehugger Robot static	void				returnVector		(pANTLR3_VECTOR_FACTORY factory, pANTLR3_VECTOR vector);
104*16467b97STreehugger Robot 
105*16467b97STreehugger Robot 
106*16467b97STreehugger Robot // Interface functions for int TRIE
107*16467b97STreehugger Robot //
108*16467b97STreehugger Robot static	pANTLR3_TRIE_ENTRY	intTrieGet		(pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key);
109*16467b97STreehugger Robot static	ANTLR3_BOOLEAN		intTrieDel		(pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key);
110*16467b97STreehugger Robot static	ANTLR3_BOOLEAN		intTrieAdd		(pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key, ANTLR3_UINT32 type, ANTLR3_INTKEY intType, void * data, void (ANTLR3_CDECL *freeptr)(void *));
111*16467b97STreehugger Robot static	void				intTrieFree		(pANTLR3_INT_TRIE trie);
112*16467b97STreehugger Robot 
113*16467b97STreehugger Robot 
114*16467b97STreehugger Robot // Interface functions for topological sorter
115*16467b97STreehugger Robot //
116*16467b97STreehugger Robot static  void            addEdge          (pANTLR3_TOPO topo, ANTLR3_UINT32 edge, ANTLR3_UINT32 dependency);
117*16467b97STreehugger Robot static  pANTLR3_UINT32  sortToArray      (pANTLR3_TOPO topo);
118*16467b97STreehugger Robot static  void            sortVector       (pANTLR3_TOPO topo, pANTLR3_VECTOR v);
119*16467b97STreehugger Robot static  void            freeTopo         (pANTLR3_TOPO topo);
120*16467b97STreehugger Robot 
121*16467b97STreehugger Robot // Local function to advance enumeration structure pointers
122*16467b97STreehugger Robot //
123*16467b97STreehugger Robot static void antlr3EnumNextEntry(pANTLR3_HASH_ENUM en);
124*16467b97STreehugger Robot 
125*16467b97STreehugger Robot pANTLR3_HASH_TABLE
antlr3HashTableNew(ANTLR3_UINT32 sizeHint)126*16467b97STreehugger Robot antlr3HashTableNew(ANTLR3_UINT32 sizeHint)
127*16467b97STreehugger Robot {
128*16467b97STreehugger Robot 	// All we have to do is create the hashtable tracking structure
129*16467b97STreehugger Robot 	// and allocate memory for the requested number of buckets.
130*16467b97STreehugger Robot 	//
131*16467b97STreehugger Robot 	pANTLR3_HASH_TABLE	table;
132*16467b97STreehugger Robot 
133*16467b97STreehugger Robot 	ANTLR3_UINT32	bucket;	// Used to traverse the buckets
134*16467b97STreehugger Robot 
135*16467b97STreehugger Robot 	table   = (pANTLR3_HASH_TABLE)ANTLR3_MALLOC(sizeof(ANTLR3_HASH_TABLE));
136*16467b97STreehugger Robot 
137*16467b97STreehugger Robot 	// Error out if no memory left
138*16467b97STreehugger Robot 	if	(table	== NULL)
139*16467b97STreehugger Robot 	{
140*16467b97STreehugger Robot 		return	NULL;
141*16467b97STreehugger Robot 	}
142*16467b97STreehugger Robot 
143*16467b97STreehugger Robot 	// Allocate memory for the buckets
144*16467b97STreehugger Robot 	//
145*16467b97STreehugger Robot 	table->buckets = (pANTLR3_HASH_BUCKET) ANTLR3_MALLOC((size_t) (sizeof(ANTLR3_HASH_BUCKET) * sizeHint));
146*16467b97STreehugger Robot 
147*16467b97STreehugger Robot 	if	(table->buckets == NULL)
148*16467b97STreehugger Robot 	{
149*16467b97STreehugger Robot 		ANTLR3_FREE((void *)table);
150*16467b97STreehugger Robot 		return	NULL;
151*16467b97STreehugger Robot 	}
152*16467b97STreehugger Robot 
153*16467b97STreehugger Robot 	// Modulo of the table, (bucket count).
154*16467b97STreehugger Robot 	//
155*16467b97STreehugger Robot 	table->modulo   = sizeHint;
156*16467b97STreehugger Robot 
157*16467b97STreehugger Robot 	table->count    = 0;	    /* Nothing in there yet ( I hope)	*/
158*16467b97STreehugger Robot 
159*16467b97STreehugger Robot 	/* Initialize the buckets to empty
160*16467b97STreehugger Robot 	*/
161*16467b97STreehugger Robot 	for	(bucket = 0; bucket < sizeHint; bucket++)
162*16467b97STreehugger Robot 	{
163*16467b97STreehugger Robot 		table->buckets[bucket].entries = NULL;
164*16467b97STreehugger Robot 	}
165*16467b97STreehugger Robot 
166*16467b97STreehugger Robot 	/* Exclude duplicate entries by default
167*16467b97STreehugger Robot 	*/
168*16467b97STreehugger Robot 	table->allowDups	= ANTLR3_FALSE;
169*16467b97STreehugger Robot 
170*16467b97STreehugger Robot     /* Assume that keys should by strduped before they are
171*16467b97STreehugger Robot      * entered in the table.
172*16467b97STreehugger Robot      */
173*16467b97STreehugger Robot     table->doStrdup     = ANTLR3_TRUE;
174*16467b97STreehugger Robot 
175*16467b97STreehugger Robot 	/* Install the interface
176*16467b97STreehugger Robot 	*/
177*16467b97STreehugger Robot 
178*16467b97STreehugger Robot 	table->get		=  antlr3HashGet;
179*16467b97STreehugger Robot 	table->put		=  antlr3HashPut;
180*16467b97STreehugger Robot 	table->del		=  antlr3HashDelete;
181*16467b97STreehugger Robot 	table->remove	=  antlr3HashRemove;
182*16467b97STreehugger Robot 
183*16467b97STreehugger Robot 	table->getI		=  antlr3HashGetI;
184*16467b97STreehugger Robot 	table->putI		=  antlr3HashPutI;
185*16467b97STreehugger Robot 	table->delI		=  antlr3HashDeleteI;
186*16467b97STreehugger Robot 	table->removeI	=  antlr3HashRemoveI;
187*16467b97STreehugger Robot 
188*16467b97STreehugger Robot 	table->size		=  antlr3HashSize;
189*16467b97STreehugger Robot 	table->free		=  antlr3HashFree;
190*16467b97STreehugger Robot 
191*16467b97STreehugger Robot 	return  table;
192*16467b97STreehugger Robot }
193*16467b97STreehugger Robot 
194*16467b97STreehugger Robot static void
antlr3HashFree(pANTLR3_HASH_TABLE table)195*16467b97STreehugger Robot antlr3HashFree(pANTLR3_HASH_TABLE table)
196*16467b97STreehugger Robot {
197*16467b97STreehugger Robot     ANTLR3_UINT32	bucket;	/* Used to traverse the buckets	*/
198*16467b97STreehugger Robot 
199*16467b97STreehugger Robot     pANTLR3_HASH_BUCKET	thisBucket;
200*16467b97STreehugger Robot     pANTLR3_HASH_ENTRY	entry;
201*16467b97STreehugger Robot     pANTLR3_HASH_ENTRY	nextEntry;
202*16467b97STreehugger Robot 
203*16467b97STreehugger Robot     /* Free the table, all buckets and all entries, and all the
204*16467b97STreehugger Robot      * keys and data (if the table exists)
205*16467b97STreehugger Robot      */
206*16467b97STreehugger Robot     if	(table	!= NULL)
207*16467b97STreehugger Robot     {
208*16467b97STreehugger Robot 	for	(bucket = 0; bucket < table->modulo; bucket++)
209*16467b97STreehugger Robot 	{
210*16467b97STreehugger Robot 	    thisBucket	= &(table->buckets[bucket]);
211*16467b97STreehugger Robot 
212*16467b97STreehugger Robot 	    /* Allow sparse tables, though we don't create them as such at present
213*16467b97STreehugger Robot 	     */
214*16467b97STreehugger Robot 	    if	( thisBucket != NULL)
215*16467b97STreehugger Robot 	    {
216*16467b97STreehugger Robot 		entry	= thisBucket->entries;
217*16467b97STreehugger Robot 
218*16467b97STreehugger Robot 		/* Search all entries in the bucket and free them up
219*16467b97STreehugger Robot 		 */
220*16467b97STreehugger Robot 		while	(entry != NULL)
221*16467b97STreehugger Robot 		{
222*16467b97STreehugger Robot 		    /* Save next entry - we do not want to access memory in entry after we
223*16467b97STreehugger Robot 		     * have freed it.
224*16467b97STreehugger Robot 		     */
225*16467b97STreehugger Robot 		    nextEntry	= entry->nextEntry;
226*16467b97STreehugger Robot 
227*16467b97STreehugger Robot 		    /* Free any data pointer, this only happens if the user supplied
228*16467b97STreehugger Robot 		     * a pointer to a routine that knwos how to free the structure they
229*16467b97STreehugger Robot 		     * added to the table.
230*16467b97STreehugger Robot 		     */
231*16467b97STreehugger Robot 		    if	(entry->free != NULL)
232*16467b97STreehugger Robot 		    {
233*16467b97STreehugger Robot 			entry->free(entry->data);
234*16467b97STreehugger Robot 		    }
235*16467b97STreehugger Robot 
236*16467b97STreehugger Robot 		    /* Free the key memory - we know that we allocated this
237*16467b97STreehugger Robot 		     */
238*16467b97STreehugger Robot 		    if	(entry->keybase.type == ANTLR3_HASH_TYPE_STR && entry->keybase.key.sKey != NULL)
239*16467b97STreehugger Robot 		    {
240*16467b97STreehugger Robot 			ANTLR3_FREE(entry->keybase.key.sKey);
241*16467b97STreehugger Robot 		    }
242*16467b97STreehugger Robot 
243*16467b97STreehugger Robot 		    /* Free this entry
244*16467b97STreehugger Robot 		     */
245*16467b97STreehugger Robot 		    ANTLR3_FREE(entry);
246*16467b97STreehugger Robot 		    entry   = nextEntry;    /* Load next pointer to see if we shoud free it */
247*16467b97STreehugger Robot 		}
248*16467b97STreehugger Robot 		/* Invalidate the current pointer
249*16467b97STreehugger Robot 		 */
250*16467b97STreehugger Robot 		thisBucket->entries = NULL;
251*16467b97STreehugger Robot 	    }
252*16467b97STreehugger Robot 	}
253*16467b97STreehugger Robot 
254*16467b97STreehugger Robot 	/* Now we can free the bucket memory
255*16467b97STreehugger Robot 	 */
256*16467b97STreehugger Robot 	ANTLR3_FREE(table->buckets);
257*16467b97STreehugger Robot     }
258*16467b97STreehugger Robot 
259*16467b97STreehugger Robot     /* Now we free teh memory for the table itself
260*16467b97STreehugger Robot      */
261*16467b97STreehugger Robot     ANTLR3_FREE(table);
262*16467b97STreehugger Robot }
263*16467b97STreehugger Robot 
264*16467b97STreehugger Robot /** return the current size of the hash table
265*16467b97STreehugger Robot  */
antlr3HashSize(pANTLR3_HASH_TABLE table)266*16467b97STreehugger Robot static ANTLR3_UINT32	antlr3HashSize	    (pANTLR3_HASH_TABLE table)
267*16467b97STreehugger Robot {
268*16467b97STreehugger Robot     return  table->count;
269*16467b97STreehugger Robot }
270*16467b97STreehugger Robot 
271*16467b97STreehugger Robot /** Remove a numeric keyed entry from a hash table if it exists,
272*16467b97STreehugger Robot  *  no error if it does not exist.
273*16467b97STreehugger Robot  */
antlr3HashRemoveI(pANTLR3_HASH_TABLE table,ANTLR3_INTKEY key)274*16467b97STreehugger Robot static pANTLR3_HASH_ENTRY   antlr3HashRemoveI   (pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key)
275*16467b97STreehugger Robot {
276*16467b97STreehugger Robot     ANTLR3_UINT32	    hash;
277*16467b97STreehugger Robot     pANTLR3_HASH_BUCKET	    bucket;
278*16467b97STreehugger Robot     pANTLR3_HASH_ENTRY	    entry;
279*16467b97STreehugger Robot     pANTLR3_HASH_ENTRY	    * nextPointer;
280*16467b97STreehugger Robot 
281*16467b97STreehugger Robot     /* First we need to know the hash of the provided key
282*16467b97STreehugger Robot      */
283*16467b97STreehugger Robot     hash    = (ANTLR3_UINT32)(key % (ANTLR3_INTKEY)(table->modulo));
284*16467b97STreehugger Robot 
285*16467b97STreehugger Robot     /* Knowing the hash, we can find the bucket
286*16467b97STreehugger Robot      */
287*16467b97STreehugger Robot     bucket  = table->buckets + hash;
288*16467b97STreehugger Robot 
289*16467b97STreehugger Robot     /* Now, we traverse the entries in the bucket until
290*16467b97STreehugger Robot      * we find the key or the end of the entries in the bucket.
291*16467b97STreehugger Robot      * We track the element prior to the one we are examining
292*16467b97STreehugger Robot      * as we need to set its next pointer to the next pointer
293*16467b97STreehugger Robot      * of the entry we are deleting (if we find it).
294*16467b97STreehugger Robot      */
295*16467b97STreehugger Robot     entry	    =   bucket->entries;    /* Entry to examine					    */
296*16467b97STreehugger Robot     nextPointer	    = & bucket->entries;    /* Where to put the next pointer of the deleted entry   */
297*16467b97STreehugger Robot 
298*16467b97STreehugger Robot     while   (entry != NULL)
299*16467b97STreehugger Robot     {
300*16467b97STreehugger Robot 	/* See if this is the entry we wish to delete
301*16467b97STreehugger Robot 	 */
302*16467b97STreehugger Robot 	if  (entry->keybase.key.iKey == key)
303*16467b97STreehugger Robot 	{
304*16467b97STreehugger Robot 	    /* It was the correct entry, so we set the next pointer
305*16467b97STreehugger Robot 	     * of the previous entry to the next pointer of this
306*16467b97STreehugger Robot 	     * located one, which takes it out of the chain.
307*16467b97STreehugger Robot 	     */
308*16467b97STreehugger Robot 	    (*nextPointer)		= entry->nextEntry;
309*16467b97STreehugger Robot 
310*16467b97STreehugger Robot 	    table->count--;
311*16467b97STreehugger Robot 
312*16467b97STreehugger Robot 	    return entry;
313*16467b97STreehugger Robot 	}
314*16467b97STreehugger Robot 	else
315*16467b97STreehugger Robot 	{
316*16467b97STreehugger Robot 	    /* We found an entry but it wasn't the one that was wanted, so
317*16467b97STreehugger Robot 	     * move to the next one, if any.
318*16467b97STreehugger Robot 	     */
319*16467b97STreehugger Robot 	    nextPointer	= & (entry->nextEntry);	    /* Address of the next pointer in the current entry	    */
320*16467b97STreehugger Robot 	    entry	= entry->nextEntry;	    /* Address of the next element in the bucket (if any)   */
321*16467b97STreehugger Robot 	}
322*16467b97STreehugger Robot     }
323*16467b97STreehugger Robot 
324*16467b97STreehugger Robot     return NULL;  /* Not found */
325*16467b97STreehugger Robot }
326*16467b97STreehugger Robot 
327*16467b97STreehugger Robot /** Remove the element in the hash table for a particular
328*16467b97STreehugger Robot  *  key value, if it exists - no error if it does not.
329*16467b97STreehugger Robot  */
330*16467b97STreehugger Robot static pANTLR3_HASH_ENTRY
antlr3HashRemove(pANTLR3_HASH_TABLE table,void * key)331*16467b97STreehugger Robot antlr3HashRemove(pANTLR3_HASH_TABLE table, void * key)
332*16467b97STreehugger Robot {
333*16467b97STreehugger Robot     ANTLR3_UINT32	    hash;
334*16467b97STreehugger Robot     pANTLR3_HASH_BUCKET	    bucket;
335*16467b97STreehugger Robot     pANTLR3_HASH_ENTRY	    entry;
336*16467b97STreehugger Robot     pANTLR3_HASH_ENTRY	    * nextPointer;
337*16467b97STreehugger Robot 
338*16467b97STreehugger Robot     /* First we need to know the hash of the provided key
339*16467b97STreehugger Robot      */
340*16467b97STreehugger Robot     hash    = antlr3Hash(key, (ANTLR3_UINT32)strlen((const char *)key));
341*16467b97STreehugger Robot 
342*16467b97STreehugger Robot     /* Knowing the hash, we can find the bucket
343*16467b97STreehugger Robot      */
344*16467b97STreehugger Robot     bucket  = table->buckets + (hash % table->modulo);
345*16467b97STreehugger Robot 
346*16467b97STreehugger Robot     /* Now, we traverse the entries in the bucket until
347*16467b97STreehugger Robot      * we find the key or the end of the entires in the bucket.
348*16467b97STreehugger Robot      * We track the element prior to the one we are exmaining
349*16467b97STreehugger Robot      * as we need to set its next pointer to the next pointer
350*16467b97STreehugger Robot      * of the entry we are deleting (if we find it).
351*16467b97STreehugger Robot      */
352*16467b97STreehugger Robot     entry	    =   bucket->entries;    /* Entry to examine					    */
353*16467b97STreehugger Robot     nextPointer	    = & bucket->entries;    /* Where to put the next pointer of the deleted entry   */
354*16467b97STreehugger Robot 
355*16467b97STreehugger Robot     while   (entry != NULL)
356*16467b97STreehugger Robot     {
357*16467b97STreehugger Robot 	/* See if this is the entry we wish to delete
358*16467b97STreehugger Robot 	 */
359*16467b97STreehugger Robot 	if  (strcmp((const char *)key, (const char *)entry->keybase.key.sKey) == 0)
360*16467b97STreehugger Robot 	{
361*16467b97STreehugger Robot 	    /* It was the correct entry, so we set the next pointer
362*16467b97STreehugger Robot 	     * of the previous entry to the next pointer of this
363*16467b97STreehugger Robot 	     * located one, which takes it out of the chain.
364*16467b97STreehugger Robot 	     */
365*16467b97STreehugger Robot 	    (*nextPointer)		= entry->nextEntry;
366*16467b97STreehugger Robot 
367*16467b97STreehugger Robot 	    /* Release the key - if we allocated that
368*16467b97STreehugger Robot 	     */
369*16467b97STreehugger Robot         if (table->doStrdup == ANTLR3_TRUE)
370*16467b97STreehugger Robot         {
371*16467b97STreehugger Robot             ANTLR3_FREE(entry->keybase.key.sKey);
372*16467b97STreehugger Robot         }
373*16467b97STreehugger Robot 	    entry->keybase.key.sKey	= NULL;
374*16467b97STreehugger Robot 
375*16467b97STreehugger Robot 	    table->count--;
376*16467b97STreehugger Robot 
377*16467b97STreehugger Robot 	    return entry;
378*16467b97STreehugger Robot 	}
379*16467b97STreehugger Robot 	else
380*16467b97STreehugger Robot 	{
381*16467b97STreehugger Robot 	    /* We found an entry but it wasn't the one that was wanted, so
382*16467b97STreehugger Robot 	     * move to the next one, if any.
383*16467b97STreehugger Robot 	     */
384*16467b97STreehugger Robot 	    nextPointer	= & (entry->nextEntry);	    /* Address of the next pointer in the current entry	    */
385*16467b97STreehugger Robot 	    entry	= entry->nextEntry;	    /* Address of the next element in the bucket (if any)   */
386*16467b97STreehugger Robot 	}
387*16467b97STreehugger Robot     }
388*16467b97STreehugger Robot 
389*16467b97STreehugger Robot     return NULL;  /* Not found */
390*16467b97STreehugger Robot }
391*16467b97STreehugger Robot 
392*16467b97STreehugger Robot /** Takes the element with the supplied key out of the list, and deletes the data
393*16467b97STreehugger Robot  *  calling the supplied free() routine if any.
394*16467b97STreehugger Robot  */
395*16467b97STreehugger Robot static void
antlr3HashDeleteI(pANTLR3_HASH_TABLE table,ANTLR3_INTKEY key)396*16467b97STreehugger Robot antlr3HashDeleteI    (pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key)
397*16467b97STreehugger Robot {
398*16467b97STreehugger Robot     pANTLR3_HASH_ENTRY	entry;
399*16467b97STreehugger Robot 
400*16467b97STreehugger Robot     entry = antlr3HashRemoveI(table, key);
401*16467b97STreehugger Robot 
402*16467b97STreehugger Robot     /* Now we can free the elements and the entry in order
403*16467b97STreehugger Robot      */
404*16467b97STreehugger Robot     if	(entry != NULL && entry->free != NULL)
405*16467b97STreehugger Robot     {
406*16467b97STreehugger Robot 	/* Call programmer supplied function to release this entry data
407*16467b97STreehugger Robot 	 */
408*16467b97STreehugger Robot 	entry->free(entry->data);
409*16467b97STreehugger Robot 	entry->data = NULL;
410*16467b97STreehugger Robot     }
411*16467b97STreehugger Robot     /* Finally release the space for this entry block.
412*16467b97STreehugger Robot      */
413*16467b97STreehugger Robot     ANTLR3_FREE(entry);
414*16467b97STreehugger Robot }
415*16467b97STreehugger Robot 
416*16467b97STreehugger Robot /** Takes the element with the supplied key out of the list, and deletes the data
417*16467b97STreehugger Robot  *  calling the supplied free() routine if any.
418*16467b97STreehugger Robot  */
419*16467b97STreehugger Robot static void
antlr3HashDelete(pANTLR3_HASH_TABLE table,void * key)420*16467b97STreehugger Robot antlr3HashDelete    (pANTLR3_HASH_TABLE table, void * key)
421*16467b97STreehugger Robot {
422*16467b97STreehugger Robot     pANTLR3_HASH_ENTRY	entry;
423*16467b97STreehugger Robot 
424*16467b97STreehugger Robot     entry = antlr3HashRemove(table, key);
425*16467b97STreehugger Robot 
426*16467b97STreehugger Robot     /* Now we can free the elements and the entry in order
427*16467b97STreehugger Robot      */
428*16467b97STreehugger Robot     if	(entry != NULL && entry->free != NULL)
429*16467b97STreehugger Robot     {
430*16467b97STreehugger Robot 	/* Call programmer supplied function to release this entry data
431*16467b97STreehugger Robot 	 */
432*16467b97STreehugger Robot 	entry->free(entry->data);
433*16467b97STreehugger Robot 	entry->data = NULL;
434*16467b97STreehugger Robot     }
435*16467b97STreehugger Robot     /* Finally release the space for this entry block.
436*16467b97STreehugger Robot      */
437*16467b97STreehugger Robot     ANTLR3_FREE(entry);
438*16467b97STreehugger Robot }
439*16467b97STreehugger Robot 
440*16467b97STreehugger Robot /** Return the element pointer in the hash table for a particular
441*16467b97STreehugger Robot  *  key value, or NULL if it don't exist (or was itself NULL).
442*16467b97STreehugger Robot  */
443*16467b97STreehugger Robot static void *
antlr3HashGetI(pANTLR3_HASH_TABLE table,ANTLR3_INTKEY key)444*16467b97STreehugger Robot antlr3HashGetI(pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key)
445*16467b97STreehugger Robot {
446*16467b97STreehugger Robot     ANTLR3_UINT32	    hash;
447*16467b97STreehugger Robot     pANTLR3_HASH_BUCKET	    bucket;
448*16467b97STreehugger Robot     pANTLR3_HASH_ENTRY	    entry;
449*16467b97STreehugger Robot 
450*16467b97STreehugger Robot     /* First we need to know the hash of the provided key
451*16467b97STreehugger Robot      */
452*16467b97STreehugger Robot     hash    = (ANTLR3_UINT32)(key % (ANTLR3_INTKEY)(table->modulo));
453*16467b97STreehugger Robot 
454*16467b97STreehugger Robot     /* Knowing the hash, we can find the bucket
455*16467b97STreehugger Robot      */
456*16467b97STreehugger Robot     bucket  = table->buckets + hash;
457*16467b97STreehugger Robot 
458*16467b97STreehugger Robot     /* Now we can inspect the key at each entry in the bucket
459*16467b97STreehugger Robot      * and see if we have a match.
460*16467b97STreehugger Robot      */
461*16467b97STreehugger Robot     entry   = bucket->entries;
462*16467b97STreehugger Robot 
463*16467b97STreehugger Robot     while   (entry != NULL)
464*16467b97STreehugger Robot     {
465*16467b97STreehugger Robot 	if  (entry->keybase.key.iKey == key)
466*16467b97STreehugger Robot 	{
467*16467b97STreehugger Robot 	    /* Match was found, return the data pointer for this entry
468*16467b97STreehugger Robot 	     */
469*16467b97STreehugger Robot 	    return  entry->data;
470*16467b97STreehugger Robot 	}
471*16467b97STreehugger Robot 	entry = entry->nextEntry;
472*16467b97STreehugger Robot     }
473*16467b97STreehugger Robot 
474*16467b97STreehugger Robot     /* If we got here, then we did not find the key
475*16467b97STreehugger Robot      */
476*16467b97STreehugger Robot     return  NULL;
477*16467b97STreehugger Robot }
478*16467b97STreehugger Robot 
479*16467b97STreehugger Robot /** Return the element pointer in the hash table for a particular
480*16467b97STreehugger Robot  *  key value, or NULL if it don't exist (or was itself NULL).
481*16467b97STreehugger Robot  */
482*16467b97STreehugger Robot static void *
antlr3HashGet(pANTLR3_HASH_TABLE table,void * key)483*16467b97STreehugger Robot antlr3HashGet(pANTLR3_HASH_TABLE table, void * key)
484*16467b97STreehugger Robot {
485*16467b97STreehugger Robot     ANTLR3_UINT32	    hash;
486*16467b97STreehugger Robot     pANTLR3_HASH_BUCKET	    bucket;
487*16467b97STreehugger Robot     pANTLR3_HASH_ENTRY	    entry;
488*16467b97STreehugger Robot 
489*16467b97STreehugger Robot 
490*16467b97STreehugger Robot     /* First we need to know the hash of the provided key
491*16467b97STreehugger Robot      */
492*16467b97STreehugger Robot     hash    = antlr3Hash(key, (ANTLR3_UINT32)strlen((const char *)key));
493*16467b97STreehugger Robot 
494*16467b97STreehugger Robot     /* Knowing the hash, we can find the bucket
495*16467b97STreehugger Robot      */
496*16467b97STreehugger Robot     bucket  = table->buckets + (hash % table->modulo);
497*16467b97STreehugger Robot 
498*16467b97STreehugger Robot     /* Now we can inspect the key at each entry in the bucket
499*16467b97STreehugger Robot      * and see if we have a match.
500*16467b97STreehugger Robot      */
501*16467b97STreehugger Robot     entry   = bucket->entries;
502*16467b97STreehugger Robot 
503*16467b97STreehugger Robot     while   (entry != NULL)
504*16467b97STreehugger Robot     {
505*16467b97STreehugger Robot 	if  (strcmp((const char *)key, (const char *)entry->keybase.key.sKey) == 0)
506*16467b97STreehugger Robot 	{
507*16467b97STreehugger Robot 	    /* Match was found, return the data pointer for this entry
508*16467b97STreehugger Robot 	     */
509*16467b97STreehugger Robot 	    return  entry->data;
510*16467b97STreehugger Robot 	}
511*16467b97STreehugger Robot 	entry = entry->nextEntry;
512*16467b97STreehugger Robot     }
513*16467b97STreehugger Robot 
514*16467b97STreehugger Robot     /* If we got here, then we did not find the key
515*16467b97STreehugger Robot      */
516*16467b97STreehugger Robot     return  NULL;
517*16467b97STreehugger Robot }
518*16467b97STreehugger Robot 
519*16467b97STreehugger Robot /** Add the element pointer in to the table, based upon the
520*16467b97STreehugger Robot  *  hash of the provided key.
521*16467b97STreehugger Robot  */
522*16467b97STreehugger Robot static	ANTLR3_INT32
antlr3HashPutI(pANTLR3_HASH_TABLE table,ANTLR3_INTKEY key,void * element,void (ANTLR3_CDECL * freeptr)(void *))523*16467b97STreehugger Robot antlr3HashPutI(pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key, void * element, void (ANTLR3_CDECL *freeptr)(void *))
524*16467b97STreehugger Robot {
525*16467b97STreehugger Robot 	ANTLR3_UINT32	    hash;
526*16467b97STreehugger Robot 	pANTLR3_HASH_BUCKET	    bucket;
527*16467b97STreehugger Robot 	pANTLR3_HASH_ENTRY	    entry;
528*16467b97STreehugger Robot 	pANTLR3_HASH_ENTRY	    * newPointer;
529*16467b97STreehugger Robot 
530*16467b97STreehugger Robot 	/* First we need to know the hash of the provided key
531*16467b97STreehugger Robot 	*/
532*16467b97STreehugger Robot 	hash    = (ANTLR3_UINT32)(key % (ANTLR3_INTKEY)(table->modulo));
533*16467b97STreehugger Robot 
534*16467b97STreehugger Robot 	/* Knowing the hash, we can find the bucket
535*16467b97STreehugger Robot 	*/
536*16467b97STreehugger Robot 	bucket  = table->buckets + hash;
537*16467b97STreehugger Robot 
538*16467b97STreehugger Robot 	/* Knowing the bucket, we can traverse the entries until we
539*16467b97STreehugger Robot 	* we find a NULL pointer or we find that this is already
540*16467b97STreehugger Robot 	* in the table and duplicates were not allowed.
541*16467b97STreehugger Robot 	*/
542*16467b97STreehugger Robot 	newPointer	= &bucket->entries;
543*16467b97STreehugger Robot 
544*16467b97STreehugger Robot 	while   (*newPointer !=  NULL)
545*16467b97STreehugger Robot 	{
546*16467b97STreehugger Robot 		/* The value at new pointer is pointing to an existing entry.
547*16467b97STreehugger Robot 		* If duplicates are allowed then we don't care what it is, but
548*16467b97STreehugger Robot 		* must reject this add if the key is the same as the one we are
549*16467b97STreehugger Robot 		* supplied with.
550*16467b97STreehugger Robot 		*/
551*16467b97STreehugger Robot 		if  (table->allowDups == ANTLR3_FALSE)
552*16467b97STreehugger Robot 		{
553*16467b97STreehugger Robot 			if	((*newPointer)->keybase.key.iKey == key)
554*16467b97STreehugger Robot 			{
555*16467b97STreehugger Robot 				return	ANTLR3_ERR_HASHDUP;
556*16467b97STreehugger Robot 			}
557*16467b97STreehugger Robot 		}
558*16467b97STreehugger Robot 
559*16467b97STreehugger Robot 		/* Point to the next entry pointer of the current entry we
560*16467b97STreehugger Robot 		* are traversing, if it is NULL we will create our new
561*16467b97STreehugger Robot 		* structure and point this to it.
562*16467b97STreehugger Robot 		*/
563*16467b97STreehugger Robot 		newPointer = &((*newPointer)->nextEntry);
564*16467b97STreehugger Robot 	}
565*16467b97STreehugger Robot 
566*16467b97STreehugger Robot 	/* newPointer is now pointing at the pointer where we need to
567*16467b97STreehugger Robot 	* add our new entry, so let's crate the entry and add it in.
568*16467b97STreehugger Robot 	*/
569*16467b97STreehugger Robot 	entry   = (pANTLR3_HASH_ENTRY)ANTLR3_MALLOC((size_t)sizeof(ANTLR3_HASH_ENTRY));
570*16467b97STreehugger Robot 
571*16467b97STreehugger Robot 	if	(entry == NULL)
572*16467b97STreehugger Robot 	{
573*16467b97STreehugger Robot 		return	ANTLR3_ERR_NOMEM;
574*16467b97STreehugger Robot 	}
575*16467b97STreehugger Robot 
576*16467b97STreehugger Robot 	entry->data			= element;		/* Install the data element supplied			*/
577*16467b97STreehugger Robot 	entry->free			= freeptr;		/* Function that knows how to release the entry		*/
578*16467b97STreehugger Robot 	entry->keybase.type		= ANTLR3_HASH_TYPE_INT;	/* Indicate the key type stored here for when we free	*/
579*16467b97STreehugger Robot 	entry->keybase.key.iKey	= key;			/* Record the key value					*/
580*16467b97STreehugger Robot 	entry->nextEntry		= NULL;			/* Ensure that the forward pointer ends the chain	*/
581*16467b97STreehugger Robot 
582*16467b97STreehugger Robot 	*newPointer	= entry;    /* Install the next entry in this bucket	*/
583*16467b97STreehugger Robot 
584*16467b97STreehugger Robot 	table->count++;
585*16467b97STreehugger Robot 
586*16467b97STreehugger Robot 	return  ANTLR3_SUCCESS;
587*16467b97STreehugger Robot }
588*16467b97STreehugger Robot 
589*16467b97STreehugger Robot 
590*16467b97STreehugger Robot /** Add the element pointer in to the table, based upon the
591*16467b97STreehugger Robot  *  hash of the provided key.
592*16467b97STreehugger Robot  */
593*16467b97STreehugger Robot static	ANTLR3_INT32
antlr3HashPut(pANTLR3_HASH_TABLE table,void * key,void * element,void (ANTLR3_CDECL * freeptr)(void *))594*16467b97STreehugger Robot antlr3HashPut(pANTLR3_HASH_TABLE table, void * key, void * element, void (ANTLR3_CDECL *freeptr)(void *))
595*16467b97STreehugger Robot {
596*16467b97STreehugger Robot 	ANTLR3_UINT32	    hash;
597*16467b97STreehugger Robot 	pANTLR3_HASH_BUCKET	    bucket;
598*16467b97STreehugger Robot 	pANTLR3_HASH_ENTRY	    entry;
599*16467b97STreehugger Robot 	pANTLR3_HASH_ENTRY	    * newPointer;
600*16467b97STreehugger Robot 
601*16467b97STreehugger Robot 	/* First we need to know the hash of the provided key
602*16467b97STreehugger Robot 	*/
603*16467b97STreehugger Robot 	hash    = antlr3Hash(key, (ANTLR3_UINT32)strlen((const char *)key));
604*16467b97STreehugger Robot 
605*16467b97STreehugger Robot 	/* Knowing the hash, we can find the bucket
606*16467b97STreehugger Robot 	*/
607*16467b97STreehugger Robot 	bucket  = table->buckets + (hash % table->modulo);
608*16467b97STreehugger Robot 
609*16467b97STreehugger Robot 	/* Knowign the bucket, we can traverse the entries until we
610*16467b97STreehugger Robot 	* we find a NULL pointer ofr we find that this is already
611*16467b97STreehugger Robot 	* in the table and duplicates were not allowed.
612*16467b97STreehugger Robot 	*/
613*16467b97STreehugger Robot 	newPointer	= &bucket->entries;
614*16467b97STreehugger Robot 
615*16467b97STreehugger Robot 	while   (*newPointer !=  NULL)
616*16467b97STreehugger Robot 	{
617*16467b97STreehugger Robot 		/* The value at new pointer is pointing to an existing entry.
618*16467b97STreehugger Robot 		* If duplicates are allowed then we don't care what it is, but
619*16467b97STreehugger Robot 		* must reject this add if the key is the same as the one we are
620*16467b97STreehugger Robot 		* supplied with.
621*16467b97STreehugger Robot 		*/
622*16467b97STreehugger Robot 		if  (table->allowDups == ANTLR3_FALSE)
623*16467b97STreehugger Robot 		{
624*16467b97STreehugger Robot 			if	(strcmp((const char*) key, (const char *)(*newPointer)->keybase.key.sKey) == 0)
625*16467b97STreehugger Robot 			{
626*16467b97STreehugger Robot 				return	ANTLR3_ERR_HASHDUP;
627*16467b97STreehugger Robot 			}
628*16467b97STreehugger Robot 		}
629*16467b97STreehugger Robot 
630*16467b97STreehugger Robot 		/* Point to the next entry pointer of the current entry we
631*16467b97STreehugger Robot 		* are traversing, if it is NULL we will create our new
632*16467b97STreehugger Robot 		* structure and point this to it.
633*16467b97STreehugger Robot 		*/
634*16467b97STreehugger Robot 		newPointer = &((*newPointer)->nextEntry);
635*16467b97STreehugger Robot 	}
636*16467b97STreehugger Robot 
637*16467b97STreehugger Robot 	/* newPointer is now poiting at the pointer where we need to
638*16467b97STreehugger Robot 	* add our new entry, so let's crate the entry and add it in.
639*16467b97STreehugger Robot 	*/
640*16467b97STreehugger Robot 	entry   = (pANTLR3_HASH_ENTRY)ANTLR3_MALLOC((size_t)sizeof(ANTLR3_HASH_ENTRY));
641*16467b97STreehugger Robot 
642*16467b97STreehugger Robot 	if	(entry == NULL)
643*16467b97STreehugger Robot 	{
644*16467b97STreehugger Robot 		return	ANTLR3_ERR_NOMEM;
645*16467b97STreehugger Robot 	}
646*16467b97STreehugger Robot 
647*16467b97STreehugger Robot 	entry->data			= element;					/* Install the data element supplied				*/
648*16467b97STreehugger Robot 	entry->free			= freeptr;					/* Function that knows how to release the entry	    */
649*16467b97STreehugger Robot 	entry->keybase.type	= ANTLR3_HASH_TYPE_STR;     /* Indicate the key type stored here for free()	    */
650*16467b97STreehugger Robot     if  (table->doStrdup == ANTLR3_TRUE)
651*16467b97STreehugger Robot     {
652*16467b97STreehugger Robot         entry->keybase.key.sKey	= ANTLR3_STRDUP(key);	/* Record the key value								*/
653*16467b97STreehugger Robot     }
654*16467b97STreehugger Robot     else
655*16467b97STreehugger Robot     {
656*16467b97STreehugger Robot         entry->keybase.key.sKey	= (pANTLR3_UINT8)key;                  /* Record the key value								*/
657*16467b97STreehugger Robot     }
658*16467b97STreehugger Robot 	entry->nextEntry		= NULL;					/* Ensure that the forward pointer ends the chain   */
659*16467b97STreehugger Robot 
660*16467b97STreehugger Robot 	*newPointer	= entry;    /* Install the next entry in this bucket	*/
661*16467b97STreehugger Robot 
662*16467b97STreehugger Robot 	table->count++;
663*16467b97STreehugger Robot 
664*16467b97STreehugger Robot 	return  ANTLR3_SUCCESS;
665*16467b97STreehugger Robot }
666*16467b97STreehugger Robot 
667*16467b97STreehugger Robot /** \brief Creates an enumeration structure to traverse the hash table.
668*16467b97STreehugger Robot  *
669*16467b97STreehugger Robot  * \param table Table to enumerate
670*16467b97STreehugger Robot  * \return Pointer to enumeration structure.
671*16467b97STreehugger Robot  */
672*16467b97STreehugger Robot pANTLR3_HASH_ENUM
antlr3EnumNew(pANTLR3_HASH_TABLE table)673*16467b97STreehugger Robot antlr3EnumNew	(pANTLR3_HASH_TABLE table)
674*16467b97STreehugger Robot {
675*16467b97STreehugger Robot     pANTLR3_HASH_ENUM	en;
676*16467b97STreehugger Robot 
677*16467b97STreehugger Robot     /* Allocate structure memory
678*16467b97STreehugger Robot      */
679*16467b97STreehugger Robot     en    = (pANTLR3_HASH_ENUM) ANTLR3_MALLOC((size_t)sizeof(ANTLR3_HASH_ENUM));
680*16467b97STreehugger Robot 
681*16467b97STreehugger Robot     /* Check that the allocation was good
682*16467b97STreehugger Robot      */
683*16467b97STreehugger Robot     if	(en == NULL)
684*16467b97STreehugger Robot     {
685*16467b97STreehugger Robot 	return	(pANTLR3_HASH_ENUM) ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
686*16467b97STreehugger Robot     }
687*16467b97STreehugger Robot 
688*16467b97STreehugger Robot     /* Initialize the start pointers
689*16467b97STreehugger Robot     */
690*16467b97STreehugger Robot     en->table	= table;
691*16467b97STreehugger Robot     en->bucket	= 0;				/* First bucket		    */
692*16467b97STreehugger Robot     en->entry	= en->table->buckets->entries;	/* First entry to return    */
693*16467b97STreehugger Robot 
694*16467b97STreehugger Robot     /* Special case in that the first bucket may not have anything in it
695*16467b97STreehugger Robot      * but the antlr3EnumNext() function expects that the en->entry is
696*16467b97STreehugger Robot      * set to the next valid pointer. Hence if it is not a valid element
697*16467b97STreehugger Robot      * pointer, attempt to find the next one that is, (table may be empty
698*16467b97STreehugger Robot      * of course.
699*16467b97STreehugger Robot      */
700*16467b97STreehugger Robot     if	(en->entry == NULL)
701*16467b97STreehugger Robot     {
702*16467b97STreehugger Robot 	antlr3EnumNextEntry(en);
703*16467b97STreehugger Robot     }
704*16467b97STreehugger Robot 
705*16467b97STreehugger Robot     /* Install the interface
706*16467b97STreehugger Robot      */
707*16467b97STreehugger Robot     en->free	=  antlr3EnumFree;
708*16467b97STreehugger Robot     en->next	=  antlr3EnumNext;
709*16467b97STreehugger Robot 
710*16467b97STreehugger Robot     /* All is good
711*16467b97STreehugger Robot      */
712*16467b97STreehugger Robot     return  en;
713*16467b97STreehugger Robot }
714*16467b97STreehugger Robot 
715*16467b97STreehugger Robot /** \brief Return the next entry in the hashtable being traversed by the supplied
716*16467b97STreehugger Robot  *         enumeration.
717*16467b97STreehugger Robot  *
718*16467b97STreehugger Robot  * \param[in] en Pointer to the enumeration tracking structure
719*16467b97STreehugger Robot  * \param key	 Pointer to void pointer, where the key pointer is returned.
720*16467b97STreehugger Robot  * \param data	 Pointer to void pointer where the data pointer is returned.
721*16467b97STreehugger Robot  * \return
722*16467b97STreehugger Robot  *	- ANTLR3_SUCCESS if there was a next key
723*16467b97STreehugger Robot  *	- ANTLR3_FAIL	 if there were no more keys
724*16467b97STreehugger Robot  *
725*16467b97STreehugger Robot  * \remark
726*16467b97STreehugger Robot  *  No checking of input structure is performed!
727*16467b97STreehugger Robot  */
728*16467b97STreehugger Robot static int
antlr3EnumNext(pANTLR3_HASH_ENUM en,pANTLR3_HASH_KEY * key,void ** data)729*16467b97STreehugger Robot antlr3EnumNext	(pANTLR3_HASH_ENUM en, pANTLR3_HASH_KEY * key, void ** data)
730*16467b97STreehugger Robot {
731*16467b97STreehugger Robot     /* If the current entry is valid, then use it
732*16467b97STreehugger Robot      */
733*16467b97STreehugger Robot     if  (en->bucket >= en->table->modulo)
734*16467b97STreehugger Robot     {
735*16467b97STreehugger Robot         /* Already exhausted the table
736*16467b97STreehugger Robot          */
737*16467b97STreehugger Robot         return	ANTLR3_FAIL;
738*16467b97STreehugger Robot     }
739*16467b97STreehugger Robot 
740*16467b97STreehugger Robot     /* Pointers are already set to the current entry to return, or
741*16467b97STreehugger Robot      * we would not be at this point in the logic flow.
742*16467b97STreehugger Robot      */
743*16467b97STreehugger Robot     *key	= &(en->entry->keybase);
744*16467b97STreehugger Robot     *data	= en->entry->data;
745*16467b97STreehugger Robot 
746*16467b97STreehugger Robot     /* Return pointers are set up, so now we move the element
747*16467b97STreehugger Robot      * pointer to the next in the table (if any).
748*16467b97STreehugger Robot      */
749*16467b97STreehugger Robot     antlr3EnumNextEntry(en);
750*16467b97STreehugger Robot 
751*16467b97STreehugger Robot     return	ANTLR3_SUCCESS;
752*16467b97STreehugger Robot }
753*16467b97STreehugger Robot 
754*16467b97STreehugger Robot /** \brief Local function to advance the entry pointer of an enumeration
755*16467b97STreehugger Robot  * structure to the next valid entry (if there is one).
756*16467b97STreehugger Robot  *
757*16467b97STreehugger Robot  * \param[in] enum Pointer to ANTLR3 enumeration structure returned by antlr3EnumNew()
758*16467b97STreehugger Robot  *
759*16467b97STreehugger Robot  * \remark
760*16467b97STreehugger Robot  *   - The function always leaves the pointers pointing at a valid entry if there
761*16467b97STreehugger Robot  *     is one, so if the entry pointer is NULL when this function exits, there were
762*16467b97STreehugger Robot  *     no more entries in the table.
763*16467b97STreehugger Robot  */
764*16467b97STreehugger Robot static void
antlr3EnumNextEntry(pANTLR3_HASH_ENUM en)765*16467b97STreehugger Robot antlr3EnumNextEntry(pANTLR3_HASH_ENUM en)
766*16467b97STreehugger Robot {
767*16467b97STreehugger Robot     pANTLR3_HASH_BUCKET	bucket;
768*16467b97STreehugger Robot 
769*16467b97STreehugger Robot     /* See if the current entry pointer is valid first of all
770*16467b97STreehugger Robot      */
771*16467b97STreehugger Robot     if	(en->entry != NULL)
772*16467b97STreehugger Robot     {
773*16467b97STreehugger Robot 	/* Current entry was a valid point, see if there is another
774*16467b97STreehugger Robot 	 * one in the chain.
775*16467b97STreehugger Robot 	 */
776*16467b97STreehugger Robot 	if  (en->entry->nextEntry != NULL)
777*16467b97STreehugger Robot 	{
778*16467b97STreehugger Robot 	    /* Next entry in the enumeration is just the next entry
779*16467b97STreehugger Robot 	     * in the chain.
780*16467b97STreehugger Robot 	     */
781*16467b97STreehugger Robot 	    en->entry = en->entry->nextEntry;
782*16467b97STreehugger Robot 	    return;
783*16467b97STreehugger Robot 	}
784*16467b97STreehugger Robot     }
785*16467b97STreehugger Robot 
786*16467b97STreehugger Robot     /* There were no more entries in the current bucket, if there are
787*16467b97STreehugger Robot      * more buckets then chase them until we find an entry.
788*16467b97STreehugger Robot      */
789*16467b97STreehugger Robot     en->bucket++;
790*16467b97STreehugger Robot 
791*16467b97STreehugger Robot     while   (en->bucket < en->table->modulo)
792*16467b97STreehugger Robot     {
793*16467b97STreehugger Robot 	/* There was one more bucket, see if it has any elements in it
794*16467b97STreehugger Robot 	 */
795*16467b97STreehugger Robot 	bucket	= en->table->buckets + en->bucket;
796*16467b97STreehugger Robot 
797*16467b97STreehugger Robot 	if  (bucket->entries != NULL)
798*16467b97STreehugger Robot 	{
799*16467b97STreehugger Robot 	    /* There was an entry in this bucket, so we can use it
800*16467b97STreehugger Robot 	     * for the next entry in the enumeration.
801*16467b97STreehugger Robot 	     */
802*16467b97STreehugger Robot 	    en->entry	= bucket->entries;
803*16467b97STreehugger Robot 	    return;
804*16467b97STreehugger Robot 	}
805*16467b97STreehugger Robot 
806*16467b97STreehugger Robot 	/* There was nothing in the bucket we just examined, move to the
807*16467b97STreehugger Robot 	 * next one.
808*16467b97STreehugger Robot 	 */
809*16467b97STreehugger Robot 	en->bucket++;
810*16467b97STreehugger Robot     }
811*16467b97STreehugger Robot 
812*16467b97STreehugger Robot     /* Here we have exhausted all buckets and the enumeration pointer will
813*16467b97STreehugger Robot      * have its bucket count = table->modulo which signifies that we are done.
814*16467b97STreehugger Robot      */
815*16467b97STreehugger Robot }
816*16467b97STreehugger Robot 
817*16467b97STreehugger Robot /** \brief Frees up the memory structures that represent a hash table
818*16467b97STreehugger Robot  *  enumeration.
819*16467b97STreehugger Robot  * \param[in] enum Pointer to ANTLR3 enumeration structure returned by antlr3EnumNew()
820*16467b97STreehugger Robot  */
821*16467b97STreehugger Robot static void
antlr3EnumFree(pANTLR3_HASH_ENUM en)822*16467b97STreehugger Robot antlr3EnumFree	(pANTLR3_HASH_ENUM en)
823*16467b97STreehugger Robot {
824*16467b97STreehugger Robot     /* Nothing to check, we just free it.
825*16467b97STreehugger Robot      */
826*16467b97STreehugger Robot     ANTLR3_FREE(en);
827*16467b97STreehugger Robot }
828*16467b97STreehugger Robot 
829*16467b97STreehugger Robot /** Given an input key of arbitrary length, return a hash value of
830*16467b97STreehugger Robot  *  it. This can then be used (with suitable modulo) to index other
831*16467b97STreehugger Robot  *  structures.
832*16467b97STreehugger Robot  */
833*16467b97STreehugger Robot ANTLR3_API ANTLR3_UINT32
antlr3Hash(void * key,ANTLR3_UINT32 keylen)834*16467b97STreehugger Robot antlr3Hash(void * key, ANTLR3_UINT32 keylen)
835*16467b97STreehugger Robot {
836*16467b97STreehugger Robot     /* Accumulate the hash value of the key
837*16467b97STreehugger Robot      */
838*16467b97STreehugger Robot     ANTLR3_UINT32   hash;
839*16467b97STreehugger Robot     pANTLR3_UINT8   keyPtr;
840*16467b97STreehugger Robot     ANTLR3_UINT32   i1;
841*16467b97STreehugger Robot 
842*16467b97STreehugger Robot     hash    = 0;
843*16467b97STreehugger Robot     keyPtr  = (pANTLR3_UINT8) key;
844*16467b97STreehugger Robot 
845*16467b97STreehugger Robot     /* Iterate the key and accumulate the hash
846*16467b97STreehugger Robot      */
847*16467b97STreehugger Robot     while(keylen > 0)
848*16467b97STreehugger Robot     {
849*16467b97STreehugger Robot 	hash = (hash << 4) + (*(keyPtr++));
850*16467b97STreehugger Robot 
851*16467b97STreehugger Robot 	if ((i1=hash&0xf0000000) != 0)
852*16467b97STreehugger Robot 	{
853*16467b97STreehugger Robot 		hash = hash ^ (i1 >> 24);
854*16467b97STreehugger Robot 		hash = hash ^ i1;
855*16467b97STreehugger Robot 	}
856*16467b97STreehugger Robot 	keylen--;
857*16467b97STreehugger Robot     }
858*16467b97STreehugger Robot 
859*16467b97STreehugger Robot     return  hash;
860*16467b97STreehugger Robot }
861*16467b97STreehugger Robot 
862*16467b97STreehugger Robot ANTLR3_API  pANTLR3_LIST
antlr3ListNew(ANTLR3_UINT32 sizeHint)863*16467b97STreehugger Robot antlr3ListNew	(ANTLR3_UINT32 sizeHint)
864*16467b97STreehugger Robot {
865*16467b97STreehugger Robot     pANTLR3_LIST    list;
866*16467b97STreehugger Robot 
867*16467b97STreehugger Robot     /* Allocate memory
868*16467b97STreehugger Robot      */
869*16467b97STreehugger Robot     list    = (pANTLR3_LIST)ANTLR3_MALLOC((size_t)sizeof(ANTLR3_LIST));
870*16467b97STreehugger Robot 
871*16467b97STreehugger Robot     if	(list == NULL)
872*16467b97STreehugger Robot     {
873*16467b97STreehugger Robot 	return	(pANTLR3_LIST)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
874*16467b97STreehugger Robot     }
875*16467b97STreehugger Robot 
876*16467b97STreehugger Robot     /* Now we need to add a new table
877*16467b97STreehugger Robot      */
878*16467b97STreehugger Robot     list->table	= antlr3HashTableNew(sizeHint);
879*16467b97STreehugger Robot 
880*16467b97STreehugger Robot     if	(list->table == (pANTLR3_HASH_TABLE)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM))
881*16467b97STreehugger Robot     {
882*16467b97STreehugger Robot 	return	(pANTLR3_LIST)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
883*16467b97STreehugger Robot     }
884*16467b97STreehugger Robot 
885*16467b97STreehugger Robot     /* Allocation was good, install interface
886*16467b97STreehugger Robot      */
887*16467b97STreehugger Robot     list->free	    =  antlr3ListFree;
888*16467b97STreehugger Robot     list->del	    =  antlr3ListDelete;
889*16467b97STreehugger Robot     list->get	    =  antlr3ListGet;
890*16467b97STreehugger Robot     list->add	    =  antlr3ListAdd;
891*16467b97STreehugger Robot     list->remove    =  antlr3ListRemove;
892*16467b97STreehugger Robot     list->put	    =  antlr3ListPut;
893*16467b97STreehugger Robot     list->size	    =  antlr3ListSize;
894*16467b97STreehugger Robot 
895*16467b97STreehugger Robot     return  list;
896*16467b97STreehugger Robot }
897*16467b97STreehugger Robot 
antlr3ListSize(pANTLR3_LIST list)898*16467b97STreehugger Robot static ANTLR3_UINT32	antlr3ListSize	    (pANTLR3_LIST list)
899*16467b97STreehugger Robot {
900*16467b97STreehugger Robot     return  list->table->size(list->table);
901*16467b97STreehugger Robot }
902*16467b97STreehugger Robot 
903*16467b97STreehugger Robot static void
antlr3ListFree(pANTLR3_LIST list)904*16467b97STreehugger Robot antlr3ListFree	(pANTLR3_LIST list)
905*16467b97STreehugger Robot {
906*16467b97STreehugger Robot     /* Free the hashtable that stores the list
907*16467b97STreehugger Robot      */
908*16467b97STreehugger Robot     list->table->free(list->table);
909*16467b97STreehugger Robot 
910*16467b97STreehugger Robot     /* Free the allocation for the list itself
911*16467b97STreehugger Robot      */
912*16467b97STreehugger Robot     ANTLR3_FREE(list);
913*16467b97STreehugger Robot }
914*16467b97STreehugger Robot 
915*16467b97STreehugger Robot static void
antlr3ListDelete(pANTLR3_LIST list,ANTLR3_INTKEY key)916*16467b97STreehugger Robot antlr3ListDelete    (pANTLR3_LIST list, ANTLR3_INTKEY key)
917*16467b97STreehugger Robot {
918*16467b97STreehugger Robot     list->table->delI(list->table, key);
919*16467b97STreehugger Robot }
920*16467b97STreehugger Robot 
921*16467b97STreehugger Robot static void *
antlr3ListGet(pANTLR3_LIST list,ANTLR3_INTKEY key)922*16467b97STreehugger Robot antlr3ListGet	    (pANTLR3_LIST list, ANTLR3_INTKEY key)
923*16467b97STreehugger Robot {
924*16467b97STreehugger Robot     return list->table->getI(list->table, key);
925*16467b97STreehugger Robot }
926*16467b97STreehugger Robot 
927*16467b97STreehugger Robot /** Add the supplied element to the list, at the next available key
928*16467b97STreehugger Robot  */
antlr3ListAdd(pANTLR3_LIST list,void * element,void (ANTLR3_CDECL * freeptr)(void *))929*16467b97STreehugger Robot static ANTLR3_INT32	antlr3ListAdd   (pANTLR3_LIST list, void * element, void (ANTLR3_CDECL *freeptr)(void *))
930*16467b97STreehugger Robot {
931*16467b97STreehugger Robot     ANTLR3_INTKEY   key;
932*16467b97STreehugger Robot 
933*16467b97STreehugger Robot     key	    = list->table->size(list->table) + 1;
934*16467b97STreehugger Robot     return list->put(list, key, element, freeptr);
935*16467b97STreehugger Robot }
936*16467b97STreehugger Robot 
937*16467b97STreehugger Robot /** Remove from the list, but don't free the element, just send it back to the
938*16467b97STreehugger Robot  *  caller.
939*16467b97STreehugger Robot  */
940*16467b97STreehugger Robot static	void *
antlr3ListRemove(pANTLR3_LIST list,ANTLR3_INTKEY key)941*16467b97STreehugger Robot antlr3ListRemove	    (pANTLR3_LIST list, ANTLR3_INTKEY key)
942*16467b97STreehugger Robot {
943*16467b97STreehugger Robot     pANTLR3_HASH_ENTRY	    entry;
944*16467b97STreehugger Robot 
945*16467b97STreehugger Robot     entry = list->table->removeI(list->table, key);
946*16467b97STreehugger Robot 
947*16467b97STreehugger Robot     if	(entry != NULL)
948*16467b97STreehugger Robot     {
949*16467b97STreehugger Robot         return  entry->data;
950*16467b97STreehugger Robot     }
951*16467b97STreehugger Robot     else
952*16467b97STreehugger Robot     {
953*16467b97STreehugger Robot 	return	NULL;
954*16467b97STreehugger Robot     }
955*16467b97STreehugger Robot }
956*16467b97STreehugger Robot 
957*16467b97STreehugger Robot static	ANTLR3_INT32
antlr3ListPut(pANTLR3_LIST list,ANTLR3_INTKEY key,void * element,void (ANTLR3_CDECL * freeptr)(void *))958*16467b97STreehugger Robot antlr3ListPut	    (pANTLR3_LIST list, ANTLR3_INTKEY key, void * element, void (ANTLR3_CDECL *freeptr)(void *))
959*16467b97STreehugger Robot {
960*16467b97STreehugger Robot     return  list->table->putI(list->table, key, element, freeptr);
961*16467b97STreehugger Robot }
962*16467b97STreehugger Robot 
963*16467b97STreehugger Robot ANTLR3_API  pANTLR3_STACK
antlr3StackNew(ANTLR3_UINT32 sizeHint)964*16467b97STreehugger Robot antlr3StackNew	(ANTLR3_UINT32 sizeHint)
965*16467b97STreehugger Robot {
966*16467b97STreehugger Robot     pANTLR3_STACK   stack;
967*16467b97STreehugger Robot 
968*16467b97STreehugger Robot     /* Allocate memory
969*16467b97STreehugger Robot      */
970*16467b97STreehugger Robot     stack    = (pANTLR3_STACK)ANTLR3_MALLOC((size_t)sizeof(ANTLR3_STACK));
971*16467b97STreehugger Robot 
972*16467b97STreehugger Robot     if	(stack == NULL)
973*16467b97STreehugger Robot     {
974*16467b97STreehugger Robot 	return	(pANTLR3_STACK)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
975*16467b97STreehugger Robot     }
976*16467b97STreehugger Robot 
977*16467b97STreehugger Robot     /* Now we need to add a new table
978*16467b97STreehugger Robot      */
979*16467b97STreehugger Robot     stack->vector   = antlr3VectorNew(sizeHint);
980*16467b97STreehugger Robot     stack->top	    = NULL;
981*16467b97STreehugger Robot 
982*16467b97STreehugger Robot     if	(stack->vector == (pANTLR3_VECTOR)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM))
983*16467b97STreehugger Robot     {
984*16467b97STreehugger Robot 	return	(pANTLR3_STACK)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
985*16467b97STreehugger Robot     }
986*16467b97STreehugger Robot 
987*16467b97STreehugger Robot     /* Looks good, now add the interface
988*16467b97STreehugger Robot      */
989*16467b97STreehugger Robot     stack->get	=  antlr3StackGet;
990*16467b97STreehugger Robot     stack->free	=  antlr3StackFree;
991*16467b97STreehugger Robot     stack->pop	=  antlr3StackPop;
992*16467b97STreehugger Robot     stack->push	=  antlr3StackPush;
993*16467b97STreehugger Robot     stack->size	=  antlr3StackSize;
994*16467b97STreehugger Robot     stack->peek	=  antlr3StackPeek;
995*16467b97STreehugger Robot 
996*16467b97STreehugger Robot     return  stack;
997*16467b97STreehugger Robot }
998*16467b97STreehugger Robot 
antlr3StackSize(pANTLR3_STACK stack)999*16467b97STreehugger Robot static ANTLR3_UINT32	antlr3StackSize	    (pANTLR3_STACK stack)
1000*16467b97STreehugger Robot {
1001*16467b97STreehugger Robot     return  stack->vector->count;
1002*16467b97STreehugger Robot }
1003*16467b97STreehugger Robot 
1004*16467b97STreehugger Robot 
1005*16467b97STreehugger Robot static void
antlr3StackFree(pANTLR3_STACK stack)1006*16467b97STreehugger Robot antlr3StackFree	(pANTLR3_STACK  stack)
1007*16467b97STreehugger Robot {
1008*16467b97STreehugger Robot     /* Free the list that supports the stack
1009*16467b97STreehugger Robot      */
1010*16467b97STreehugger Robot     stack->vector->free(stack->vector);
1011*16467b97STreehugger Robot     stack->vector   = NULL;
1012*16467b97STreehugger Robot     stack->top	    = NULL;
1013*16467b97STreehugger Robot 
1014*16467b97STreehugger Robot     ANTLR3_FREE(stack);
1015*16467b97STreehugger Robot }
1016*16467b97STreehugger Robot 
1017*16467b97STreehugger Robot static void *
antlr3StackPop(pANTLR3_STACK stack)1018*16467b97STreehugger Robot antlr3StackPop	(pANTLR3_STACK	stack)
1019*16467b97STreehugger Robot {
1020*16467b97STreehugger Robot     // Delete the element that is currently at the top of the stack
1021*16467b97STreehugger Robot     //
1022*16467b97STreehugger Robot     stack->vector->del(stack->vector, stack->vector->count - 1);
1023*16467b97STreehugger Robot 
1024*16467b97STreehugger Robot     // And get the element that is the now the top of the stack (if anything)
1025*16467b97STreehugger Robot     // NOTE! This is not quite like a 'real' stack, which would normally return you
1026*16467b97STreehugger Robot     // the current top of the stack, then remove it from the stack.
1027*16467b97STreehugger Robot     // TODO: Review this, it is correct for follow sets which is what this was done for
1028*16467b97STreehugger Robot     //       but is not as obvious when using it as a 'real'stack.
1029*16467b97STreehugger Robot     //
1030*16467b97STreehugger Robot     stack->top = stack->vector->get(stack->vector, stack->vector->count - 1);
1031*16467b97STreehugger Robot     return stack->top;
1032*16467b97STreehugger Robot }
1033*16467b97STreehugger Robot 
1034*16467b97STreehugger Robot static void *
antlr3StackGet(pANTLR3_STACK stack,ANTLR3_INTKEY key)1035*16467b97STreehugger Robot antlr3StackGet	(pANTLR3_STACK stack, ANTLR3_INTKEY key)
1036*16467b97STreehugger Robot {
1037*16467b97STreehugger Robot     return  stack->vector->get(stack->vector, (ANTLR3_UINT32)key);
1038*16467b97STreehugger Robot }
1039*16467b97STreehugger Robot 
1040*16467b97STreehugger Robot static void *
antlr3StackPeek(pANTLR3_STACK stack)1041*16467b97STreehugger Robot antlr3StackPeek	(pANTLR3_STACK	stack)
1042*16467b97STreehugger Robot {
1043*16467b97STreehugger Robot     return  stack->top;
1044*16467b97STreehugger Robot }
1045*16467b97STreehugger Robot 
1046*16467b97STreehugger Robot static ANTLR3_BOOLEAN
antlr3StackPush(pANTLR3_STACK stack,void * element,void (ANTLR3_CDECL * freeptr)(void *))1047*16467b97STreehugger Robot antlr3StackPush	(pANTLR3_STACK stack, void * element, void (ANTLR3_CDECL *freeptr)(void *))
1048*16467b97STreehugger Robot {
1049*16467b97STreehugger Robot     stack->top	= element;
1050*16467b97STreehugger Robot     return (ANTLR3_BOOLEAN)(stack->vector->add(stack->vector, element, freeptr));
1051*16467b97STreehugger Robot }
1052*16467b97STreehugger Robot 
1053*16467b97STreehugger Robot ANTLR3_API  pANTLR3_VECTOR
antlr3VectorNew(ANTLR3_UINT32 sizeHint)1054*16467b97STreehugger Robot antlr3VectorNew	(ANTLR3_UINT32 sizeHint)
1055*16467b97STreehugger Robot {
1056*16467b97STreehugger Robot 	pANTLR3_VECTOR  vector;
1057*16467b97STreehugger Robot 
1058*16467b97STreehugger Robot 
1059*16467b97STreehugger Robot 	// Allocate memory for the vector structure itself
1060*16467b97STreehugger Robot 	//
1061*16467b97STreehugger Robot 	vector  = (pANTLR3_VECTOR) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_VECTOR)));
1062*16467b97STreehugger Robot 
1063*16467b97STreehugger Robot 	if	(vector == NULL)
1064*16467b97STreehugger Robot 	{
1065*16467b97STreehugger Robot 		return	(pANTLR3_VECTOR)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
1066*16467b97STreehugger Robot 	}
1067*16467b97STreehugger Robot 
1068*16467b97STreehugger Robot 	// Now fill in the defaults
1069*16467b97STreehugger Robot 	//
1070*16467b97STreehugger Robot     antlr3SetVectorApi(vector, sizeHint);
1071*16467b97STreehugger Robot 
1072*16467b97STreehugger Robot 	// And everything is hunky dory
1073*16467b97STreehugger Robot 	//
1074*16467b97STreehugger Robot 	return  vector;
1075*16467b97STreehugger Robot }
1076*16467b97STreehugger Robot 
1077*16467b97STreehugger Robot ANTLR3_API void
antlr3SetVectorApi(pANTLR3_VECTOR vector,ANTLR3_UINT32 sizeHint)1078*16467b97STreehugger Robot antlr3SetVectorApi  (pANTLR3_VECTOR vector, ANTLR3_UINT32 sizeHint)
1079*16467b97STreehugger Robot {
1080*16467b97STreehugger Robot     ANTLR3_UINT32   initialSize;
1081*16467b97STreehugger Robot 
1082*16467b97STreehugger Robot     // Allow vectors to be guessed by ourselves, so input size can be zero
1083*16467b97STreehugger Robot     //
1084*16467b97STreehugger Robot     if	(sizeHint > ANTLR3_VECTOR_INTERNAL_SIZE)
1085*16467b97STreehugger Robot     {
1086*16467b97STreehugger Robot         initialSize = sizeHint;
1087*16467b97STreehugger Robot     }
1088*16467b97STreehugger Robot     else
1089*16467b97STreehugger Robot     {
1090*16467b97STreehugger Robot         initialSize = ANTLR3_VECTOR_INTERNAL_SIZE;
1091*16467b97STreehugger Robot     }
1092*16467b97STreehugger Robot 
1093*16467b97STreehugger Robot     if  (sizeHint > ANTLR3_VECTOR_INTERNAL_SIZE)
1094*16467b97STreehugger Robot     {
1095*16467b97STreehugger Robot         vector->elements	= (pANTLR3_VECTOR_ELEMENT)ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_VECTOR_ELEMENT) * initialSize));
1096*16467b97STreehugger Robot     }
1097*16467b97STreehugger Robot     else
1098*16467b97STreehugger Robot     {
1099*16467b97STreehugger Robot         vector->elements    = vector->internal;
1100*16467b97STreehugger Robot     }
1101*16467b97STreehugger Robot 
1102*16467b97STreehugger Robot     if	(vector->elements == NULL)
1103*16467b97STreehugger Robot     {
1104*16467b97STreehugger Robot         ANTLR3_FREE(vector);
1105*16467b97STreehugger Robot         return;
1106*16467b97STreehugger Robot     }
1107*16467b97STreehugger Robot 
1108*16467b97STreehugger Robot     // Memory allocated successfully
1109*16467b97STreehugger Robot     //
1110*16467b97STreehugger Robot     vector->count			= 0;			// No entries yet of course
1111*16467b97STreehugger Robot     vector->elementsSize    = initialSize;  // Available entries
1112*16467b97STreehugger Robot 
1113*16467b97STreehugger Robot     // Now we can install the API
1114*16467b97STreehugger Robot     //
1115*16467b97STreehugger Robot     vector->add	    = antlr3VectorAdd;
1116*16467b97STreehugger Robot     vector->del	    = antlr3VectorDel;
1117*16467b97STreehugger Robot     vector->get	    = antlr3VectorGet;
1118*16467b97STreehugger Robot     vector->free    = antlr3VectorFree;
1119*16467b97STreehugger Robot     vector->set	    = antlr3VectorSet;
1120*16467b97STreehugger Robot     vector->remove  = antrl3VectorRemove;
1121*16467b97STreehugger Robot     vector->clear   = antlr3VectorClear;
1122*16467b97STreehugger Robot     vector->size    = antlr3VectorSize;
1123*16467b97STreehugger Robot     vector->swap    = antlr3VectorSwap;
1124*16467b97STreehugger Robot 
1125*16467b97STreehugger Robot     // Assume that this is not a factory made vector
1126*16467b97STreehugger Robot     //
1127*16467b97STreehugger Robot     vector->factoryMade	= ANTLR3_FALSE;
1128*16467b97STreehugger Robot }
1129*16467b97STreehugger Robot 
1130*16467b97STreehugger Robot // Clear the entries in a vector.
1131*16467b97STreehugger Robot // Clearing the vector leaves its capacity the same but
1132*16467b97STreehugger Robot // it walks the entries first to see if any of them
1133*16467b97STreehugger Robot // have a free routine that must be called.
1134*16467b97STreehugger Robot //
1135*16467b97STreehugger Robot static	void
antlr3VectorClear(pANTLR3_VECTOR vector)1136*16467b97STreehugger Robot antlr3VectorClear	(pANTLR3_VECTOR vector)
1137*16467b97STreehugger Robot {
1138*16467b97STreehugger Robot 	ANTLR3_UINT32   entry;
1139*16467b97STreehugger Robot 
1140*16467b97STreehugger Robot 	// We must traverse every entry in the vector and if it has
1141*16467b97STreehugger Robot 	// a pointer to a free function then we call it with the
1142*16467b97STreehugger Robot 	// the entry pointer
1143*16467b97STreehugger Robot 	//
1144*16467b97STreehugger Robot 	for	(entry = 0; entry < vector->count; entry++)
1145*16467b97STreehugger Robot 	{
1146*16467b97STreehugger Robot 		if  (vector->elements[entry].freeptr != NULL)
1147*16467b97STreehugger Robot 		{
1148*16467b97STreehugger Robot 			vector->elements[entry].freeptr(vector->elements[entry].element);
1149*16467b97STreehugger Robot 		}
1150*16467b97STreehugger Robot 		vector->elements[entry].freeptr    = NULL;
1151*16467b97STreehugger Robot 		vector->elements[entry].element    = NULL;
1152*16467b97STreehugger Robot 	}
1153*16467b97STreehugger Robot 
1154*16467b97STreehugger Robot 	// Having called any free pointers, we just reset the entry count
1155*16467b97STreehugger Robot 	// back to zero.
1156*16467b97STreehugger Robot 	//
1157*16467b97STreehugger Robot 	vector->count	= 0;
1158*16467b97STreehugger Robot }
1159*16467b97STreehugger Robot 
1160*16467b97STreehugger Robot static
antlr3VectorFree(pANTLR3_VECTOR vector)1161*16467b97STreehugger Robot void	ANTLR3_CDECL	antlr3VectorFree    (pANTLR3_VECTOR vector)
1162*16467b97STreehugger Robot {
1163*16467b97STreehugger Robot 	ANTLR3_UINT32   entry;
1164*16467b97STreehugger Robot 
1165*16467b97STreehugger Robot 	// We must traverse every entry in the vector and if it has
1166*16467b97STreehugger Robot 	// a pointer to a free function then we call it with the
1167*16467b97STreehugger Robot 	// the entry pointer
1168*16467b97STreehugger Robot 	//
1169*16467b97STreehugger Robot 	for	(entry = 0; entry < vector->count; entry++)
1170*16467b97STreehugger Robot 	{
1171*16467b97STreehugger Robot 		if  (vector->elements[entry].freeptr != NULL)
1172*16467b97STreehugger Robot 		{
1173*16467b97STreehugger Robot 			vector->elements[entry].freeptr(vector->elements[entry].element);
1174*16467b97STreehugger Robot 		}
1175*16467b97STreehugger Robot 		vector->elements[entry].freeptr    = NULL;
1176*16467b97STreehugger Robot 		vector->elements[entry].element    = NULL;
1177*16467b97STreehugger Robot 	}
1178*16467b97STreehugger Robot 
1179*16467b97STreehugger Robot 	if	(vector->factoryMade == ANTLR3_FALSE)
1180*16467b97STreehugger Robot 	{
1181*16467b97STreehugger Robot 		// The entries are freed, so free the element allocation
1182*16467b97STreehugger Robot 		//
1183*16467b97STreehugger Robot         if  (vector->elementsSize > ANTLR3_VECTOR_INTERNAL_SIZE)
1184*16467b97STreehugger Robot         {
1185*16467b97STreehugger Robot             ANTLR3_FREE(vector->elements);
1186*16467b97STreehugger Robot         }
1187*16467b97STreehugger Robot 		vector->elements = NULL;
1188*16467b97STreehugger Robot 
1189*16467b97STreehugger Robot 		// Finally, free the allocation for the vector itself
1190*16467b97STreehugger Robot 		//
1191*16467b97STreehugger Robot 		ANTLR3_FREE(vector);
1192*16467b97STreehugger Robot 	}
1193*16467b97STreehugger Robot }
1194*16467b97STreehugger Robot 
antlr3VectorDel(pANTLR3_VECTOR vector,ANTLR3_UINT32 entry)1195*16467b97STreehugger Robot static	void		antlr3VectorDel	    (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry)
1196*16467b97STreehugger Robot {
1197*16467b97STreehugger Robot 	// Check this is a valid request first
1198*16467b97STreehugger Robot 	//
1199*16467b97STreehugger Robot 	if	(entry >= vector->count)
1200*16467b97STreehugger Robot 	{
1201*16467b97STreehugger Robot 		return;
1202*16467b97STreehugger Robot 	}
1203*16467b97STreehugger Robot 
1204*16467b97STreehugger Robot 	// Valid request, check for free pointer and call it if present
1205*16467b97STreehugger Robot 	//
1206*16467b97STreehugger Robot 	if	(vector->elements[entry].freeptr != NULL)
1207*16467b97STreehugger Robot 	{
1208*16467b97STreehugger Robot 		vector->elements[entry].freeptr(vector->elements[entry].element);
1209*16467b97STreehugger Robot 		vector->elements[entry].freeptr    = NULL;
1210*16467b97STreehugger Robot 	}
1211*16467b97STreehugger Robot 
1212*16467b97STreehugger Robot 	if	(entry == vector->count - 1)
1213*16467b97STreehugger Robot 	{
1214*16467b97STreehugger Robot 		// Ensure the pointer is never reused by accident, but otherwise just
1215*16467b97STreehugger Robot 		// decrement the pointer.
1216*16467b97STreehugger Robot 		//
1217*16467b97STreehugger Robot 		vector->elements[entry].element    = NULL;
1218*16467b97STreehugger Robot 	}
1219*16467b97STreehugger Robot 	else
1220*16467b97STreehugger Robot 	{
1221*16467b97STreehugger Robot 		// Need to shuffle trailing pointers back over the deleted entry
1222*16467b97STreehugger Robot 		//
1223*16467b97STreehugger Robot 		ANTLR3_MEMMOVE(vector->elements + entry, vector->elements + entry + 1, sizeof(ANTLR3_VECTOR_ELEMENT) * (vector->count - entry - 1));
1224*16467b97STreehugger Robot 	}
1225*16467b97STreehugger Robot 
1226*16467b97STreehugger Robot 	// One less entry in the vector now
1227*16467b97STreehugger Robot 	//
1228*16467b97STreehugger Robot 	vector->count--;
1229*16467b97STreehugger Robot }
1230*16467b97STreehugger Robot 
antlr3VectorGet(pANTLR3_VECTOR vector,ANTLR3_UINT32 entry)1231*16467b97STreehugger Robot static	void *		antlr3VectorGet     (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry)
1232*16467b97STreehugger Robot {
1233*16467b97STreehugger Robot 	// Ensure this is a valid request
1234*16467b97STreehugger Robot 	//
1235*16467b97STreehugger Robot 	if	(entry < vector->count)
1236*16467b97STreehugger Robot 	{
1237*16467b97STreehugger Robot 		return	vector->elements[entry].element;
1238*16467b97STreehugger Robot 	}
1239*16467b97STreehugger Robot 	else
1240*16467b97STreehugger Robot 	{
1241*16467b97STreehugger Robot 		// I know nothing, Mr. Fawlty!
1242*16467b97STreehugger Robot 		//
1243*16467b97STreehugger Robot 		return	NULL;
1244*16467b97STreehugger Robot 	}
1245*16467b97STreehugger Robot }
1246*16467b97STreehugger Robot 
1247*16467b97STreehugger Robot /// Remove the entry from the vector, but do not free any entry, even if it has
1248*16467b97STreehugger Robot /// a free pointer.
1249*16467b97STreehugger Robot ///
antrl3VectorRemove(pANTLR3_VECTOR vector,ANTLR3_UINT32 entry)1250*16467b97STreehugger Robot static	void *		antrl3VectorRemove  (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry)
1251*16467b97STreehugger Robot {
1252*16467b97STreehugger Robot 	void * element;
1253*16467b97STreehugger Robot 
1254*16467b97STreehugger Robot 	// Check this is a valid request first
1255*16467b97STreehugger Robot 	//
1256*16467b97STreehugger Robot 	if	(entry >= vector->count)
1257*16467b97STreehugger Robot 	{
1258*16467b97STreehugger Robot 		return NULL;
1259*16467b97STreehugger Robot 	}
1260*16467b97STreehugger Robot 
1261*16467b97STreehugger Robot 	// Valid request, return the sorted pointer
1262*16467b97STreehugger Robot 	//
1263*16467b97STreehugger Robot 
1264*16467b97STreehugger Robot 	element				    = vector->elements[entry].element;
1265*16467b97STreehugger Robot 
1266*16467b97STreehugger Robot 	if	(entry == vector->count - 1)
1267*16467b97STreehugger Robot 	{
1268*16467b97STreehugger Robot 		// Ensure the pointer is never reused by accident, but otherwise just
1269*16467b97STreehugger Robot 		// decrement the pointer.
1270*16467b97STreehugger Robot 		///
1271*16467b97STreehugger Robot 		vector->elements[entry].element    = NULL;
1272*16467b97STreehugger Robot 		vector->elements[entry].freeptr    = NULL;
1273*16467b97STreehugger Robot 	}
1274*16467b97STreehugger Robot 	else
1275*16467b97STreehugger Robot 	{
1276*16467b97STreehugger Robot 		// Need to shuffle trailing pointers back over the deleted entry
1277*16467b97STreehugger Robot 		//
1278*16467b97STreehugger Robot 		ANTLR3_MEMMOVE(vector->elements + entry, vector->elements + entry + 1, sizeof(ANTLR3_VECTOR_ELEMENT) * (vector->count - entry - 1));
1279*16467b97STreehugger Robot 	}
1280*16467b97STreehugger Robot 
1281*16467b97STreehugger Robot 	// One less entry in the vector now
1282*16467b97STreehugger Robot 	//
1283*16467b97STreehugger Robot 	vector->count--;
1284*16467b97STreehugger Robot 
1285*16467b97STreehugger Robot 	return  element;
1286*16467b97STreehugger Robot }
1287*16467b97STreehugger Robot 
1288*16467b97STreehugger Robot static  ANTLR3_BOOLEAN
antlr3VectorResize(pANTLR3_VECTOR vector,ANTLR3_UINT32 hint)1289*16467b97STreehugger Robot antlr3VectorResize  (pANTLR3_VECTOR vector, ANTLR3_UINT32 hint)
1290*16467b97STreehugger Robot {
1291*16467b97STreehugger Robot 	ANTLR3_UINT32	newSize;
1292*16467b97STreehugger Robot 
1293*16467b97STreehugger Robot 	// Need to resize the element pointers. We double the allocation
1294*16467b97STreehugger Robot 	// we already have unless asked for a specific increase.
1295*16467b97STreehugger Robot     //
1296*16467b97STreehugger Robot     if (hint == 0 || hint < vector->elementsSize)
1297*16467b97STreehugger Robot     {
1298*16467b97STreehugger Robot         newSize = vector->elementsSize * 2;
1299*16467b97STreehugger Robot     }
1300*16467b97STreehugger Robot     else
1301*16467b97STreehugger Robot     {
1302*16467b97STreehugger Robot         newSize = hint * 2;
1303*16467b97STreehugger Robot     }
1304*16467b97STreehugger Robot 
1305*16467b97STreehugger Robot     // Now we know how many we need, so we see if we have just expanded
1306*16467b97STreehugger Robot     // past the built in vector elements or were already past that
1307*16467b97STreehugger Robot     //
1308*16467b97STreehugger Robot     if  (vector->elementsSize > ANTLR3_VECTOR_INTERNAL_SIZE)
1309*16467b97STreehugger Robot     {
1310*16467b97STreehugger Robot         // We were already larger than the internal size, so we just
1311*16467b97STreehugger Robot         // use realloc so that the pointers are copied for us
1312*16467b97STreehugger Robot         //
1313*16467b97STreehugger Robot 		pANTLR3_VECTOR_ELEMENT newElements = (pANTLR3_VECTOR_ELEMENT)ANTLR3_REALLOC(vector->elements, (sizeof(ANTLR3_VECTOR_ELEMENT)* newSize));
1314*16467b97STreehugger Robot 		if (newElements == NULL)
1315*16467b97STreehugger Robot 		{
1316*16467b97STreehugger Robot 			// realloc failed, but the old allocation is still there
1317*16467b97STreehugger Robot 			return ANTLR3_FALSE;
1318*16467b97STreehugger Robot 		}
1319*16467b97STreehugger Robot         vector->elements = newElements;
1320*16467b97STreehugger Robot     }
1321*16467b97STreehugger Robot     else
1322*16467b97STreehugger Robot     {
1323*16467b97STreehugger Robot         // The current size was less than or equal to the internal array size and as we always start
1324*16467b97STreehugger Robot         // with a size that is at least the maximum internal size, then we must need to allocate new memory
1325*16467b97STreehugger Robot         // for external pointers. We don't want to take the time to calculate if a requested element
1326*16467b97STreehugger Robot         // is part of the internal or external entries, so we copy the internal ones to the new space
1327*16467b97STreehugger Robot         //
1328*16467b97STreehugger Robot         vector->elements	= (pANTLR3_VECTOR_ELEMENT)ANTLR3_MALLOC((sizeof(ANTLR3_VECTOR_ELEMENT)* newSize));
1329*16467b97STreehugger Robot 		if (vector->elements == NULL)
1330*16467b97STreehugger Robot 		{
1331*16467b97STreehugger Robot 			// malloc failed
1332*16467b97STreehugger Robot 			return ANTLR3_FALSE;
1333*16467b97STreehugger Robot 		}
1334*16467b97STreehugger Robot         ANTLR3_MEMCPY(vector->elements, vector->internal, ANTLR3_VECTOR_INTERNAL_SIZE * sizeof(ANTLR3_VECTOR_ELEMENT));
1335*16467b97STreehugger Robot     }
1336*16467b97STreehugger Robot 
1337*16467b97STreehugger Robot 	vector->elementsSize	= newSize;
1338*16467b97STreehugger Robot 	return ANTLR3_TRUE;
1339*16467b97STreehugger Robot }
1340*16467b97STreehugger Robot 
1341*16467b97STreehugger Robot /// Add the supplied pointer and freeing function pointer to the list,
1342*16467b97STreehugger Robot /// expanding the vector if needed.
1343*16467b97STreehugger Robot ///
antlr3VectorAdd(pANTLR3_VECTOR vector,void * element,void (ANTLR3_CDECL * freeptr)(void *))1344*16467b97STreehugger Robot static	ANTLR3_UINT32    antlr3VectorAdd	    (pANTLR3_VECTOR vector, void * element, void (ANTLR3_CDECL *freeptr)(void *))
1345*16467b97STreehugger Robot {
1346*16467b97STreehugger Robot 	// Do we need to resize the vector table?
1347*16467b97STreehugger Robot 	//
1348*16467b97STreehugger Robot 	if	(vector->count == vector->elementsSize)
1349*16467b97STreehugger Robot 	{
1350*16467b97STreehugger Robot 		// Give no hint, we let it add 1024 or double it
1351*16467b97STreehugger Robot 		if (!antlr3VectorResize(vector, 0))
1352*16467b97STreehugger Robot 		{
1353*16467b97STreehugger Robot 			// Resize failed
1354*16467b97STreehugger Robot 			return 0;
1355*16467b97STreehugger Robot 		}
1356*16467b97STreehugger Robot 	}
1357*16467b97STreehugger Robot 
1358*16467b97STreehugger Robot 	// Insert the new entry
1359*16467b97STreehugger Robot 	//
1360*16467b97STreehugger Robot 	vector->elements[vector->count].element	= element;
1361*16467b97STreehugger Robot 	vector->elements[vector->count].freeptr	= freeptr;
1362*16467b97STreehugger Robot 
1363*16467b97STreehugger Robot 	vector->count++;	    // One more element counted
1364*16467b97STreehugger Robot 
1365*16467b97STreehugger Robot 	return  (ANTLR3_UINT32)(vector->count);
1366*16467b97STreehugger Robot 
1367*16467b97STreehugger Robot }
1368*16467b97STreehugger Robot 
1369*16467b97STreehugger Robot /// Replace the element at the specified entry point with the supplied
1370*16467b97STreehugger Robot /// entry.
1371*16467b97STreehugger Robot ///
1372*16467b97STreehugger Robot static	ANTLR3_UINT32
antlr3VectorSet(pANTLR3_VECTOR vector,ANTLR3_UINT32 entry,void * element,void (ANTLR3_CDECL * freeptr)(void *),ANTLR3_BOOLEAN freeExisting)1373*16467b97STreehugger Robot antlr3VectorSet	    (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry, void * element, void (ANTLR3_CDECL *freeptr)(void *), ANTLR3_BOOLEAN freeExisting)
1374*16467b97STreehugger Robot {
1375*16467b97STreehugger Robot 
1376*16467b97STreehugger Robot 	// If the vector is currently not big enough, then we expand it
1377*16467b97STreehugger Robot 	//
1378*16467b97STreehugger Robot 	if (entry >= vector->elementsSize)
1379*16467b97STreehugger Robot 	{
1380*16467b97STreehugger Robot 		// We will get at least this many
1381*16467b97STreehugger Robot 		if (!antlr3VectorResize(vector, entry))
1382*16467b97STreehugger Robot 		{
1383*16467b97STreehugger Robot 			// Resize failed
1384*16467b97STreehugger Robot 			return 0;
1385*16467b97STreehugger Robot 		}
1386*16467b97STreehugger Robot 	}
1387*16467b97STreehugger Robot 
1388*16467b97STreehugger Robot 	// Valid request, replace the current one, freeing any prior entry if told to
1389*16467b97STreehugger Robot 	//
1390*16467b97STreehugger Robot 	if	(		entry < vector->count						// If actually replacing an element
1391*16467b97STreehugger Robot 			&&	freeExisting								// And told to free any existing element
1392*16467b97STreehugger Robot 			&&	vector->elements[entry].freeptr != NULL		// And the existing element has a free pointer
1393*16467b97STreehugger Robot 		)
1394*16467b97STreehugger Robot 	{
1395*16467b97STreehugger Robot 		vector->elements[entry].freeptr(vector->elements[entry].element);
1396*16467b97STreehugger Robot 	}
1397*16467b97STreehugger Robot 
1398*16467b97STreehugger Robot 	// Install the new pointers
1399*16467b97STreehugger Robot 	//
1400*16467b97STreehugger Robot 	vector->elements[entry].freeptr	= freeptr;
1401*16467b97STreehugger Robot 	vector->elements[entry].element	= element;
1402*16467b97STreehugger Robot 
1403*16467b97STreehugger Robot 	if (entry >= vector->count)
1404*16467b97STreehugger Robot 	{
1405*16467b97STreehugger Robot 		vector->count = entry + 1;
1406*16467b97STreehugger Robot 	}
1407*16467b97STreehugger Robot 	return  (ANTLR3_UINT32)(entry);	    // Indicates the replacement was successful
1408*16467b97STreehugger Robot 
1409*16467b97STreehugger Robot }
1410*16467b97STreehugger Robot 
1411*16467b97STreehugger Robot /// Replace the element at the specified entry point with the supplied
1412*16467b97STreehugger Robot /// entry.
1413*16467b97STreehugger Robot ///
1414*16467b97STreehugger Robot static	ANTLR3_BOOLEAN
antlr3VectorSwap(pANTLR3_VECTOR vector,ANTLR3_UINT32 entry1,ANTLR3_UINT32 entry2)1415*16467b97STreehugger Robot antlr3VectorSwap	    (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry1, ANTLR3_UINT32 entry2)
1416*16467b97STreehugger Robot {
1417*16467b97STreehugger Robot 
1418*16467b97STreehugger Robot     void               * tempEntry;
1419*16467b97STreehugger Robot     void (ANTLR3_CDECL *freeptr)(void *);
1420*16467b97STreehugger Robot 
1421*16467b97STreehugger Robot 	// If the vector is currently not big enough, then we do nothing
1422*16467b97STreehugger Robot 	//
1423*16467b97STreehugger Robot 	if (entry1 >= vector->elementsSize || entry2 >= vector->elementsSize)
1424*16467b97STreehugger Robot 	{
1425*16467b97STreehugger Robot         return ANTLR3_FALSE;
1426*16467b97STreehugger Robot 	}
1427*16467b97STreehugger Robot 
1428*16467b97STreehugger Robot 	// Valid request, swap them
1429*16467b97STreehugger Robot 	//
1430*16467b97STreehugger Robot     tempEntry   = vector->elements[entry1].element;
1431*16467b97STreehugger Robot     freeptr     = vector->elements[entry1].freeptr;
1432*16467b97STreehugger Robot 
1433*16467b97STreehugger Robot 	// Install the new pointers
1434*16467b97STreehugger Robot 	//
1435*16467b97STreehugger Robot     vector->elements[entry1].freeptr	= vector->elements[entry2].freeptr;
1436*16467b97STreehugger Robot 	vector->elements[entry1].element	= vector->elements[entry2].element;
1437*16467b97STreehugger Robot 
1438*16467b97STreehugger Robot 	vector->elements[entry2].freeptr	= freeptr;
1439*16467b97STreehugger Robot 	vector->elements[entry2].element	= tempEntry;
1440*16467b97STreehugger Robot 
1441*16467b97STreehugger Robot 	return  ANTLR3_TRUE;
1442*16467b97STreehugger Robot 
1443*16467b97STreehugger Robot }
1444*16467b97STreehugger Robot 
antlr3VectorSize(pANTLR3_VECTOR vector)1445*16467b97STreehugger Robot static	ANTLR3_UINT32   antlr3VectorSize    (pANTLR3_VECTOR vector)
1446*16467b97STreehugger Robot {
1447*16467b97STreehugger Robot     return  vector->count;
1448*16467b97STreehugger Robot }
1449*16467b97STreehugger Robot 
1450*16467b97STreehugger Robot #ifdef ANTLR3_WINDOWS
1451*16467b97STreehugger Robot #pragma warning	(push)
1452*16467b97STreehugger Robot #pragma warning (disable : 4100)
1453*16467b97STreehugger Robot #endif
1454*16467b97STreehugger Robot /// Vector factory creation
1455*16467b97STreehugger Robot ///
1456*16467b97STreehugger Robot ANTLR3_API pANTLR3_VECTOR_FACTORY
antlr3VectorFactoryNew(ANTLR3_UINT32 sizeHint)1457*16467b97STreehugger Robot antlr3VectorFactoryNew	    (ANTLR3_UINT32 sizeHint)
1458*16467b97STreehugger Robot {
1459*16467b97STreehugger Robot 	pANTLR3_VECTOR_FACTORY  factory;
1460*16467b97STreehugger Robot 
1461*16467b97STreehugger Robot 	// Allocate memory for the factory
1462*16467b97STreehugger Robot 	//
1463*16467b97STreehugger Robot 	factory = (pANTLR3_VECTOR_FACTORY)ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_VECTOR_FACTORY)));
1464*16467b97STreehugger Robot 
1465*16467b97STreehugger Robot 	if	(factory == NULL)
1466*16467b97STreehugger Robot 	{
1467*16467b97STreehugger Robot 		return	NULL;
1468*16467b97STreehugger Robot 	}
1469*16467b97STreehugger Robot 
1470*16467b97STreehugger Robot 	// Factory memory is good, so create a new vector pool
1471*16467b97STreehugger Robot 	//
1472*16467b97STreehugger Robot     factory->pools      = NULL;
1473*16467b97STreehugger Robot     factory->thisPool   = -1;
1474*16467b97STreehugger Robot 
1475*16467b97STreehugger Robot     newPool(factory);
1476*16467b97STreehugger Robot 
1477*16467b97STreehugger Robot     // Initialize the API, ignore the hint as this algorithm does
1478*16467b97STreehugger Robot     // a better job really.
1479*16467b97STreehugger Robot     //
1480*16467b97STreehugger Robot     antlr3SetVectorApi(&(factory->unTruc), ANTLR3_VECTOR_INTERNAL_SIZE);
1481*16467b97STreehugger Robot 
1482*16467b97STreehugger Robot     factory->unTruc.factoryMade = ANTLR3_TRUE;
1483*16467b97STreehugger Robot 
1484*16467b97STreehugger Robot 	// Install the factory API
1485*16467b97STreehugger Robot 	//
1486*16467b97STreehugger Robot 	factory->close			= closeVectorFactory;
1487*16467b97STreehugger Robot 	factory->newVector		= newVector;
1488*16467b97STreehugger Robot 	factory->returnVector	= returnVector;
1489*16467b97STreehugger Robot 
1490*16467b97STreehugger Robot 	// Create a stack to accumulate reusable vectors
1491*16467b97STreehugger Robot 	//
1492*16467b97STreehugger Robot 	factory->freeStack		= antlr3StackNew(16);
1493*16467b97STreehugger Robot 	return  factory;
1494*16467b97STreehugger Robot }
1495*16467b97STreehugger Robot #ifdef ANTLR3_WINDOWS
1496*16467b97STreehugger Robot #pragma warning	(pop)
1497*16467b97STreehugger Robot #endif
1498*16467b97STreehugger Robot 
1499*16467b97STreehugger Robot static	void
returnVector(pANTLR3_VECTOR_FACTORY factory,pANTLR3_VECTOR vector)1500*16467b97STreehugger Robot returnVector		(pANTLR3_VECTOR_FACTORY factory, pANTLR3_VECTOR vector)
1501*16467b97STreehugger Robot {
1502*16467b97STreehugger Robot 	// First we need to clear out anything that is still in the vector
1503*16467b97STreehugger Robot 	//
1504*16467b97STreehugger Robot 	vector->clear(vector);
1505*16467b97STreehugger Robot 
1506*16467b97STreehugger Robot 	// We have a free stack available so we can add the vector we were
1507*16467b97STreehugger Robot 	// given into the free chain. The vector has to have come from this
1508*16467b97STreehugger Robot 	// factory, so we already know how to release its memory when it
1509*16467b97STreehugger Robot 	// dies by virtue of the factory being closed.
1510*16467b97STreehugger Robot 	//
1511*16467b97STreehugger Robot 	factory->freeStack->push(factory->freeStack, vector, NULL);
1512*16467b97STreehugger Robot 
1513*16467b97STreehugger Robot 	// TODO: remove this line once happy printf("Returned vector %08X to the pool, stack size is %d\n", vector, factory->freeStack->size(factory->freeStack));
1514*16467b97STreehugger Robot }
1515*16467b97STreehugger Robot 
1516*16467b97STreehugger Robot static ANTLR3_BOOLEAN
newPool(pANTLR3_VECTOR_FACTORY factory)1517*16467b97STreehugger Robot newPool(pANTLR3_VECTOR_FACTORY factory)
1518*16467b97STreehugger Robot {
1519*16467b97STreehugger Robot 	pANTLR3_VECTOR *newPools;
1520*16467b97STreehugger Robot 
1521*16467b97STreehugger Robot     /* Increment factory count
1522*16467b97STreehugger Robot      */
1523*16467b97STreehugger Robot     ++factory->thisPool;
1524*16467b97STreehugger Robot 
1525*16467b97STreehugger Robot     /* Ensure we have enough pointers allocated
1526*16467b97STreehugger Robot      */
1527*16467b97STreehugger Robot 	newPools = (pANTLR3_VECTOR *)
1528*16467b97STreehugger Robot 		ANTLR3_REALLOC(	(void *)factory->pools,	    /* Current pools pointer (starts at NULL)	*/
1529*16467b97STreehugger Robot 					(ANTLR3_UINT32)((factory->thisPool + 1) * sizeof(pANTLR3_VECTOR *))	/* Memory for new pool pointers */
1530*16467b97STreehugger Robot 					);
1531*16467b97STreehugger Robot 	if (newPools == NULL)
1532*16467b97STreehugger Robot 	{
1533*16467b97STreehugger Robot 		// realloc failed, but we still have the old allocation
1534*16467b97STreehugger Robot 		--factory->thisPool;
1535*16467b97STreehugger Robot 		return ANTLR3_FALSE;
1536*16467b97STreehugger Robot 	}
1537*16467b97STreehugger Robot 	factory->pools = newPools;
1538*16467b97STreehugger Robot 
1539*16467b97STreehugger Robot     /* Allocate a new pool for the factory
1540*16467b97STreehugger Robot      */
1541*16467b97STreehugger Robot     factory->pools[factory->thisPool]	=
1542*16467b97STreehugger Robot 			    (pANTLR3_VECTOR)
1543*16467b97STreehugger Robot 				ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_VECTOR) * ANTLR3_FACTORY_VPOOL_SIZE));
1544*16467b97STreehugger Robot 	if (factory->pools[factory->thisPool] == NULL)
1545*16467b97STreehugger Robot 	{
1546*16467b97STreehugger Robot 		// malloc failed
1547*16467b97STreehugger Robot 		--factory->thisPool;
1548*16467b97STreehugger Robot 		return ANTLR3_FALSE;
1549*16467b97STreehugger Robot 	}
1550*16467b97STreehugger Robot 
1551*16467b97STreehugger Robot 
1552*16467b97STreehugger Robot     /* Reset the counters
1553*16467b97STreehugger Robot      */
1554*16467b97STreehugger Robot     factory->nextVector	= 0;
1555*16467b97STreehugger Robot 
1556*16467b97STreehugger Robot     /* Done
1557*16467b97STreehugger Robot      */
1558*16467b97STreehugger Robot     return ANTLR3_TRUE;
1559*16467b97STreehugger Robot }
1560*16467b97STreehugger Robot 
1561*16467b97STreehugger Robot static  void
closeVectorFactory(pANTLR3_VECTOR_FACTORY factory)1562*16467b97STreehugger Robot closeVectorFactory  (pANTLR3_VECTOR_FACTORY factory)
1563*16467b97STreehugger Robot {
1564*16467b97STreehugger Robot     pANTLR3_VECTOR      pool;
1565*16467b97STreehugger Robot     ANTLR3_INT32        poolCount;
1566*16467b97STreehugger Robot     ANTLR3_UINT32       limit;
1567*16467b97STreehugger Robot     ANTLR3_UINT32       vector;
1568*16467b97STreehugger Robot     pANTLR3_VECTOR      check;
1569*16467b97STreehugger Robot 
1570*16467b97STreehugger Robot 	// First see if we have a free chain stack to release?
1571*16467b97STreehugger Robot 	//
1572*16467b97STreehugger Robot 	if	(factory->freeStack != NULL)
1573*16467b97STreehugger Robot 	{
1574*16467b97STreehugger Robot 		factory->freeStack->free(factory->freeStack);
1575*16467b97STreehugger Robot 	}
1576*16467b97STreehugger Robot 
1577*16467b97STreehugger Robot     /* We iterate the vector pools one at a time
1578*16467b97STreehugger Robot      */
1579*16467b97STreehugger Robot     for (poolCount = 0; poolCount <= factory->thisPool; poolCount++)
1580*16467b97STreehugger Robot     {
1581*16467b97STreehugger Robot         /* Pointer to current pool
1582*16467b97STreehugger Robot          */
1583*16467b97STreehugger Robot         pool = factory->pools[poolCount];
1584*16467b97STreehugger Robot 
1585*16467b97STreehugger Robot         /* Work out how many tokens we need to check in this pool.
1586*16467b97STreehugger Robot          */
1587*16467b97STreehugger Robot         limit = (poolCount == factory->thisPool ? factory->nextVector : ANTLR3_FACTORY_VPOOL_SIZE);
1588*16467b97STreehugger Robot 
1589*16467b97STreehugger Robot         /* Marginal condition, we might be at the start of a brand new pool
1590*16467b97STreehugger Robot          * where the nextToken is 0 and nothing has been allocated.
1591*16467b97STreehugger Robot          */
1592*16467b97STreehugger Robot         if (limit > 0)
1593*16467b97STreehugger Robot         {
1594*16467b97STreehugger Robot             /* We have some vectors allocated from this pool
1595*16467b97STreehugger Robot              */
1596*16467b97STreehugger Robot             for (vector = 0; vector < limit; vector++)
1597*16467b97STreehugger Robot             {
1598*16467b97STreehugger Robot                 /* Next one in the chain
1599*16467b97STreehugger Robot                  */
1600*16467b97STreehugger Robot                 check = pool + vector;
1601*16467b97STreehugger Robot 
1602*16467b97STreehugger Robot                 // Call the free function on each of the vectors in the pool,
1603*16467b97STreehugger Robot                 // which in turn will cause any elements it holds that also have a free
1604*16467b97STreehugger Robot                 // pointer to be freed. However, because any vector may be in any other
1605*16467b97STreehugger Robot                 // vector, we don't free the element allocations yet. We do that in a
1606*16467b97STreehugger Robot                 // a specific pass, coming up next. The vector free function knows that
1607*16467b97STreehugger Robot                 // this is a factory allocated pool vector and so it won't free things it
1608*16467b97STreehugger Robot                 // should not.
1609*16467b97STreehugger Robot                 //
1610*16467b97STreehugger Robot                 check->free(check);
1611*16467b97STreehugger Robot             }
1612*16467b97STreehugger Robot         }
1613*16467b97STreehugger Robot     }
1614*16467b97STreehugger Robot 
1615*16467b97STreehugger Robot     /* We iterate the vector pools one at a time once again, but this time
1616*16467b97STreehugger Robot      * we are going to free up any allocated element pointers. Note that we are doing this
1617*16467b97STreehugger Robot      * so that we do not try to release vectors twice. When building ASTs we just copy
1618*16467b97STreehugger Robot      * the vectors all over the place and they may be embedded in this vector pool
1619*16467b97STreehugger Robot      * numerous times.
1620*16467b97STreehugger Robot      */
1621*16467b97STreehugger Robot     for (poolCount = 0; poolCount <= factory->thisPool; poolCount++)
1622*16467b97STreehugger Robot     {
1623*16467b97STreehugger Robot         /* Pointer to current pool
1624*16467b97STreehugger Robot          */
1625*16467b97STreehugger Robot         pool = factory->pools[poolCount];
1626*16467b97STreehugger Robot 
1627*16467b97STreehugger Robot         /* Work out how many tokens we need to check in this pool.
1628*16467b97STreehugger Robot          */
1629*16467b97STreehugger Robot         limit = (poolCount == factory->thisPool ? factory->nextVector : ANTLR3_FACTORY_VPOOL_SIZE);
1630*16467b97STreehugger Robot 
1631*16467b97STreehugger Robot         /* Marginal condition, we might be at the start of a brand new pool
1632*16467b97STreehugger Robot          * where the nextToken is 0 and nothing has been allocated.
1633*16467b97STreehugger Robot          */
1634*16467b97STreehugger Robot         if (limit > 0)
1635*16467b97STreehugger Robot         {
1636*16467b97STreehugger Robot             /* We have some vectors allocated from this pool
1637*16467b97STreehugger Robot              */
1638*16467b97STreehugger Robot             for (vector = 0; vector < limit; vector++)
1639*16467b97STreehugger Robot             {
1640*16467b97STreehugger Robot                 /* Next one in the chain
1641*16467b97STreehugger Robot                  */
1642*16467b97STreehugger Robot                 check = pool + vector;
1643*16467b97STreehugger Robot 
1644*16467b97STreehugger Robot                 // Anything in here should be factory made, but we do this just
1645*16467b97STreehugger Robot                 // to triple check. We just free up the elements if they were
1646*16467b97STreehugger Robot                 // allocated beyond the internal size.
1647*16467b97STreehugger Robot                 //
1648*16467b97STreehugger Robot                 if (check->factoryMade == ANTLR3_TRUE && check->elementsSize > ANTLR3_VECTOR_INTERNAL_SIZE)
1649*16467b97STreehugger Robot                 {
1650*16467b97STreehugger Robot                     ANTLR3_FREE(check->elements);
1651*16467b97STreehugger Robot                     check->elements = NULL;
1652*16467b97STreehugger Robot                 }
1653*16467b97STreehugger Robot             }
1654*16467b97STreehugger Robot         }
1655*16467b97STreehugger Robot 
1656*16467b97STreehugger Robot         // We can now free this pool allocation as we have called free on every element in every vector
1657*16467b97STreehugger Robot         // and freed any memory for pointers the grew beyond the internal size limit.
1658*16467b97STreehugger Robot         //
1659*16467b97STreehugger Robot         ANTLR3_FREE(factory->pools[poolCount]);
1660*16467b97STreehugger Robot         factory->pools[poolCount] = NULL;
1661*16467b97STreehugger Robot     }
1662*16467b97STreehugger Robot 
1663*16467b97STreehugger Robot     /* All the pools are deallocated we can free the pointers to the pools
1664*16467b97STreehugger Robot      * now.
1665*16467b97STreehugger Robot      */
1666*16467b97STreehugger Robot     ANTLR3_FREE(factory->pools);
1667*16467b97STreehugger Robot 
1668*16467b97STreehugger Robot     /* Finally, we can free the space for the factory itself
1669*16467b97STreehugger Robot      */
1670*16467b97STreehugger Robot     ANTLR3_FREE(factory);
1671*16467b97STreehugger Robot 
1672*16467b97STreehugger Robot }
1673*16467b97STreehugger Robot 
1674*16467b97STreehugger Robot static pANTLR3_VECTOR
newVector(pANTLR3_VECTOR_FACTORY factory)1675*16467b97STreehugger Robot newVector(pANTLR3_VECTOR_FACTORY factory)
1676*16467b97STreehugger Robot {
1677*16467b97STreehugger Robot     pANTLR3_VECTOR vector;
1678*16467b97STreehugger Robot 
1679*16467b97STreehugger Robot 	// If we have anything on the re claim stack, reuse it
1680*16467b97STreehugger Robot 	//
1681*16467b97STreehugger Robot 	vector = (pANTLR3_VECTOR)factory->freeStack->peek(factory->freeStack);
1682*16467b97STreehugger Robot 
1683*16467b97STreehugger Robot 	if  (vector != NULL)
1684*16467b97STreehugger Robot 	{
1685*16467b97STreehugger Robot 		// Cool we got something we could reuse
1686*16467b97STreehugger Robot 		//
1687*16467b97STreehugger Robot 		factory->freeStack->pop(factory->freeStack);
1688*16467b97STreehugger Robot 
1689*16467b97STreehugger Robot 		// TODO: remove this line once happy printf("Reused vector %08X from stack, size is now %d\n", vector, factory->freeStack->size(factory->freeStack));
1690*16467b97STreehugger Robot 		return vector;
1691*16467b97STreehugger Robot 
1692*16467b97STreehugger Robot 	}
1693*16467b97STreehugger Robot 
1694*16467b97STreehugger Robot 	// See if we need a new vector pool before allocating a new
1695*16467b97STreehugger Robot     // one
1696*16467b97STreehugger Robot     //
1697*16467b97STreehugger Robot     if (factory->nextVector >= ANTLR3_FACTORY_VPOOL_SIZE)
1698*16467b97STreehugger Robot     {
1699*16467b97STreehugger Robot         // We ran out of vectors in the current pool, so we need a new pool
1700*16467b97STreehugger Robot         //
1701*16467b97STreehugger Robot         if (!newPool(factory))
1702*16467b97STreehugger Robot 		{
1703*16467b97STreehugger Robot 			// new pool creation failed
1704*16467b97STreehugger Robot 			return NULL;
1705*16467b97STreehugger Robot 		}
1706*16467b97STreehugger Robot     }
1707*16467b97STreehugger Robot 
1708*16467b97STreehugger Robot     // Assuming everything went well (we are trying for performance here so doing minimal
1709*16467b97STreehugger Robot     // error checking. Then we can work out what the pointer is to the next vector.
1710*16467b97STreehugger Robot     //
1711*16467b97STreehugger Robot     vector = factory->pools[factory->thisPool] + factory->nextVector;
1712*16467b97STreehugger Robot     factory->nextVector++;
1713*16467b97STreehugger Robot 
1714*16467b97STreehugger Robot     // We have our token pointer now, so we can initialize it to the predefined model.
1715*16467b97STreehugger Robot     //
1716*16467b97STreehugger Robot     antlr3SetVectorApi(vector, ANTLR3_VECTOR_INTERNAL_SIZE);
1717*16467b97STreehugger Robot     vector->factoryMade = ANTLR3_TRUE;
1718*16467b97STreehugger Robot 
1719*16467b97STreehugger Robot     // We know that the pool vectors are created at the default size, which means they
1720*16467b97STreehugger Robot     // will start off using their internal entry pointers. We must initialize our pool vector
1721*16467b97STreehugger Robot     // to point to its own internal entry table and not the pre-made one.
1722*16467b97STreehugger Robot     //
1723*16467b97STreehugger Robot     vector->elements = vector->internal;
1724*16467b97STreehugger Robot 
1725*16467b97STreehugger Robot 		// TODO: remove this line once happy printf("Used a new vector at %08X from the pools as nothing on the reusue stack\n", vector);
1726*16467b97STreehugger Robot 
1727*16467b97STreehugger Robot     // And we are done
1728*16467b97STreehugger Robot     //
1729*16467b97STreehugger Robot     return vector;
1730*16467b97STreehugger Robot }
1731*16467b97STreehugger Robot 
1732*16467b97STreehugger Robot /** Array of left most significant bit positions for an 8 bit
1733*16467b97STreehugger Robot  *  element provides an efficient way to find the highest bit
1734*16467b97STreehugger Robot  *  that is set in an n byte value (n>0). Assuming the values will all hit the data cache,
1735*16467b97STreehugger Robot  *  coding without conditional elements should allow branch
1736*16467b97STreehugger Robot  *  prediction to work well and of course a parallel instruction cache
1737*16467b97STreehugger Robot  *  will whip through this. Otherwise we must loop shifting a one
1738*16467b97STreehugger Robot  *  bit and masking. The values we tend to be placing in out integer
1739*16467b97STreehugger Robot  *  patricia trie are usually a lot lower than the 64 bits we
1740*16467b97STreehugger Robot  *  allow for the key allows. Hence there is a lot of redundant looping and
1741*16467b97STreehugger Robot  *  shifting in a while loop. Whereas, the lookup table is just
1742*16467b97STreehugger Robot  *  a few ands and indirect lookups, while testing for 0. This
1743*16467b97STreehugger Robot  *  is likely to be done in parallel on many processors available
1744*16467b97STreehugger Robot  *  when I wrote this. If this code survives as long as yacc, then
1745*16467b97STreehugger Robot  *  I may already be dead by the time you read this and maybe there is
1746*16467b97STreehugger Robot  *  a single machine instruction to perform the operation. What
1747*16467b97STreehugger Robot  *  else are you going to do with all those transistors? Jim 2007
1748*16467b97STreehugger Robot  *
1749*16467b97STreehugger Robot  * The table is probably obvious but it is just the number 0..7
1750*16467b97STreehugger Robot  * of the MSB in each integer value 0..256
1751*16467b97STreehugger Robot  */
1752*16467b97STreehugger Robot static ANTLR3_UINT8 bitIndex[256] =
1753*16467b97STreehugger Robot {
1754*16467b97STreehugger Robot     0,													// 0 - Just for padding
1755*16467b97STreehugger Robot     0,													// 1
1756*16467b97STreehugger Robot     1, 1,												// 2..3
1757*16467b97STreehugger Robot     2, 2, 2, 2,											// 4..7
1758*16467b97STreehugger Robot     3, 3, 3, 3, 3, 3, 3, 3,								// 8+
1759*16467b97STreehugger Robot     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,	    // 16+
1760*16467b97STreehugger Robot     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,	    // 32+
1761*16467b97STreehugger Robot 	5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1762*16467b97STreehugger Robot     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,	    // 64+
1763*16467b97STreehugger Robot 	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1764*16467b97STreehugger Robot 	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1765*16467b97STreehugger Robot 	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1766*16467b97STreehugger Robot     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,	    // 128+
1767*16467b97STreehugger Robot 	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1768*16467b97STreehugger Robot 	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1769*16467b97STreehugger Robot 	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1770*16467b97STreehugger Robot 	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1771*16467b97STreehugger Robot 	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1772*16467b97STreehugger Robot 	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1773*16467b97STreehugger Robot 	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
1774*16467b97STreehugger Robot };
1775*16467b97STreehugger Robot 
1776*16467b97STreehugger Robot /** Rather than use the bit index of a trie node to shift
1777*16467b97STreehugger Robot  *  0x01 left that many times, then & with the result, it is
1778*16467b97STreehugger Robot  *  faster to use the bit index as an index into this table
1779*16467b97STreehugger Robot  *  which holds precomputed masks for any of the 64 bits
1780*16467b97STreehugger Robot  *  we need to mask off singly. The data values will stay in
1781*16467b97STreehugger Robot  *  cache while ever a trie is in heavy use, such as in
1782*16467b97STreehugger Robot  *  memoization. It is also pretty enough to be ASCII art.
1783*16467b97STreehugger Robot  */
1784*16467b97STreehugger Robot static ANTLR3_UINT64 bitMask[64] =
1785*16467b97STreehugger Robot {
1786*16467b97STreehugger Robot     0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000004ULL, 0x0000000000000008ULL,
1787*16467b97STreehugger Robot     0x0000000000000010ULL, 0x0000000000000020ULL, 0x0000000000000040ULL, 0x0000000000000080ULL,
1788*16467b97STreehugger Robot     0x0000000000000100ULL, 0x0000000000000200ULL, 0x0000000000000400ULL, 0x0000000000000800ULL,
1789*16467b97STreehugger Robot     0x0000000000001000ULL, 0x0000000000002000ULL, 0x0000000000004000ULL, 0x0000000000008000ULL,
1790*16467b97STreehugger Robot     0x0000000000010000ULL, 0x0000000000020000ULL, 0x0000000000040000ULL, 0x0000000000080000ULL,
1791*16467b97STreehugger Robot     0x0000000000100000ULL, 0x0000000000200000ULL, 0x0000000000400000ULL, 0x0000000000800000ULL,
1792*16467b97STreehugger Robot     0x0000000001000000ULL, 0x0000000002000000ULL, 0x0000000004000000ULL, 0x0000000008000000ULL,
1793*16467b97STreehugger Robot     0x0000000010000000ULL, 0x0000000020000000ULL, 0x0000000040000000ULL, 0x0000000080000000ULL,
1794*16467b97STreehugger Robot     0x0000000100000000ULL, 0x0000000200000000ULL, 0x0000000400000000ULL, 0x0000000800000000ULL,
1795*16467b97STreehugger Robot     0x0000001000000000ULL, 0x0000002000000000ULL, 0x0000004000000000ULL, 0x0000008000000000ULL,
1796*16467b97STreehugger Robot     0x0000010000000000ULL, 0x0000020000000000ULL, 0x0000040000000000ULL, 0x0000080000000000ULL,
1797*16467b97STreehugger Robot     0x0000100000000000ULL, 0x0000200000000000ULL, 0x0000400000000000ULL, 0x0000800000000000ULL,
1798*16467b97STreehugger Robot     0x0001000000000000ULL, 0x0002000000000000ULL, 0x0004000000000000ULL, 0x0008000000000000ULL,
1799*16467b97STreehugger Robot     0x0010000000000000ULL, 0x0020000000000000ULL, 0x0040000000000000ULL, 0x0080000000000000ULL,
1800*16467b97STreehugger Robot     0x0100000000000000ULL, 0x0200000000000000ULL, 0x0400000000000000ULL, 0x0800000000000000ULL,
1801*16467b97STreehugger Robot     0x1000000000000000ULL, 0x2000000000000000ULL, 0x4000000000000000ULL, 0x8000000000000000ULL
1802*16467b97STreehugger Robot };
1803*16467b97STreehugger Robot 
1804*16467b97STreehugger Robot /* INT TRIE Implementation of depth 64 bits, being the number of bits
1805*16467b97STreehugger Robot  * in a 64 bit integer.
1806*16467b97STreehugger Robot  */
1807*16467b97STreehugger Robot 
1808*16467b97STreehugger Robot pANTLR3_INT_TRIE
antlr3IntTrieNew(ANTLR3_UINT32 depth)1809*16467b97STreehugger Robot antlr3IntTrieNew(ANTLR3_UINT32 depth)
1810*16467b97STreehugger Robot {
1811*16467b97STreehugger Robot 	pANTLR3_INT_TRIE	trie;
1812*16467b97STreehugger Robot 
1813*16467b97STreehugger Robot 	trie    = (pANTLR3_INT_TRIE) ANTLR3_CALLOC(1, sizeof(ANTLR3_INT_TRIE));	/* Base memory required	*/
1814*16467b97STreehugger Robot 
1815*16467b97STreehugger Robot 	if (trie == NULL)
1816*16467b97STreehugger Robot 	{
1817*16467b97STreehugger Robot 		return	(pANTLR3_INT_TRIE) ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
1818*16467b97STreehugger Robot 	}
1819*16467b97STreehugger Robot 
1820*16467b97STreehugger Robot 	/* Now we need to allocate the root node. This makes it easier
1821*16467b97STreehugger Robot 	 * to use the tree as we don't have to do anything special
1822*16467b97STreehugger Robot 	 * for the root node.
1823*16467b97STreehugger Robot 	 */
1824*16467b97STreehugger Robot 	trie->root	= (pANTLR3_INT_TRIE_NODE) ANTLR3_CALLOC(1, sizeof(ANTLR3_INT_TRIE));
1825*16467b97STreehugger Robot 
1826*16467b97STreehugger Robot 	if (trie->root == NULL)
1827*16467b97STreehugger Robot 	{
1828*16467b97STreehugger Robot 		ANTLR3_FREE(trie);
1829*16467b97STreehugger Robot 		return	(pANTLR3_INT_TRIE) ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM);
1830*16467b97STreehugger Robot 	}
1831*16467b97STreehugger Robot 
1832*16467b97STreehugger Robot 	trie->add	= intTrieAdd;
1833*16467b97STreehugger Robot 	trie->del	= intTrieDel;
1834*16467b97STreehugger Robot 	trie->free	= intTrieFree;
1835*16467b97STreehugger Robot 	trie->get	= intTrieGet;
1836*16467b97STreehugger Robot 
1837*16467b97STreehugger Robot 	/* Now we seed the root node with the index being the
1838*16467b97STreehugger Robot 	 * highest left most bit we want to test, which limits the
1839*16467b97STreehugger Robot 	 * keys in the trie. This is the trie 'depth'. The limit for
1840*16467b97STreehugger Robot 	 * this implementation is 63 (bits 0..63).
1841*16467b97STreehugger Robot 	 */
1842*16467b97STreehugger Robot 	trie->root->bitNum = depth;
1843*16467b97STreehugger Robot 
1844*16467b97STreehugger Robot 	/* And as we have nothing in here yet, we set both child pointers
1845*16467b97STreehugger Robot 	 * of the root node to point back to itself.
1846*16467b97STreehugger Robot 	 */
1847*16467b97STreehugger Robot 	trie->root->leftN	= trie->root;
1848*16467b97STreehugger Robot 	trie->root->rightN	= trie->root;
1849*16467b97STreehugger Robot 	trie->count			= 0;
1850*16467b97STreehugger Robot 
1851*16467b97STreehugger Robot 	/* Finally, note that the key for this root node is 0 because
1852*16467b97STreehugger Robot 	 * we use calloc() to initialise it.
1853*16467b97STreehugger Robot 	 */
1854*16467b97STreehugger Robot 
1855*16467b97STreehugger Robot 	return trie;
1856*16467b97STreehugger Robot }
1857*16467b97STreehugger Robot 
1858*16467b97STreehugger Robot /** Search the int Trie and return a pointer to the first bucket indexed
1859*16467b97STreehugger Robot  *  by the key if it is contained in the trie, otherwise NULL.
1860*16467b97STreehugger Robot  */
1861*16467b97STreehugger Robot static	pANTLR3_TRIE_ENTRY
intTrieGet(pANTLR3_INT_TRIE trie,ANTLR3_INTKEY key)1862*16467b97STreehugger Robot intTrieGet	(pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key)
1863*16467b97STreehugger Robot {
1864*16467b97STreehugger Robot 	pANTLR3_INT_TRIE_NODE    thisNode;
1865*16467b97STreehugger Robot 	pANTLR3_INT_TRIE_NODE    nextNode;
1866*16467b97STreehugger Robot 
1867*16467b97STreehugger Robot 	if (trie->count == 0)
1868*16467b97STreehugger Robot 	{
1869*16467b97STreehugger Robot 		return NULL;	    /* Nothing in this trie yet	*/
1870*16467b97STreehugger Robot 	}
1871*16467b97STreehugger Robot 	/* Starting at the root node in the trie, compare the bit index
1872*16467b97STreehugger Robot 	 * of the current node with its next child node (starts left from root).
1873*16467b97STreehugger Robot 	 * When the bit index of the child node is greater than the bit index of the current node
1874*16467b97STreehugger Robot 	 * then by definition (as the bit index decreases as we descent the trie)
1875*16467b97STreehugger Robot 	 * we have reached a 'backward' pointer. A backward pointer means we
1876*16467b97STreehugger Robot 	 * have reached the only node that can be reached by the bits given us so far
1877*16467b97STreehugger Robot 	 * and it must either be the key we are looking for, or if not then it
1878*16467b97STreehugger Robot 	 * means the entry was not in the trie, and we return NULL. A backward pointer
1879*16467b97STreehugger Robot 	 * points back in to the tree structure rather than down (deeper) within the
1880*16467b97STreehugger Robot 	 * tree branches.
1881*16467b97STreehugger Robot 	 */
1882*16467b97STreehugger Robot 	thisNode	= trie->root;		/* Start at the root node		*/
1883*16467b97STreehugger Robot 	nextNode	= thisNode->leftN;	/* Examine the left node from the root	*/
1884*16467b97STreehugger Robot 
1885*16467b97STreehugger Robot 	/* While we are descending the tree nodes...
1886*16467b97STreehugger Robot 	 */
1887*16467b97STreehugger Robot 	while (thisNode->bitNum > nextNode->bitNum)
1888*16467b97STreehugger Robot 	{
1889*16467b97STreehugger Robot 		/* Next node now becomes the new 'current' node
1890*16467b97STreehugger Robot 		 */
1891*16467b97STreehugger Robot 		thisNode    = nextNode;
1892*16467b97STreehugger Robot 
1893*16467b97STreehugger Robot 		/* We now test the bit indicated by the bitmap in the next node
1894*16467b97STreehugger Robot 		 * in the key we are searching for. The new next node is the
1895*16467b97STreehugger Robot 		 * right node if that bit is set and the left node it is not.
1896*16467b97STreehugger Robot 		 */
1897*16467b97STreehugger Robot 		if (key & bitMask[nextNode->bitNum])
1898*16467b97STreehugger Robot 		{
1899*16467b97STreehugger Robot 			nextNode = nextNode->rightN;	/* 1 is right	*/
1900*16467b97STreehugger Robot 		}
1901*16467b97STreehugger Robot 		else
1902*16467b97STreehugger Robot 		{
1903*16467b97STreehugger Robot 			nextNode = nextNode->leftN;		/* 0 is left	*/
1904*16467b97STreehugger Robot 		}
1905*16467b97STreehugger Robot 	}
1906*16467b97STreehugger Robot 
1907*16467b97STreehugger Robot 	/* Here we have reached a node where the bitMap index is lower than
1908*16467b97STreehugger Robot 	 * its parent. This means it is pointing backward in the tree and
1909*16467b97STreehugger Robot 	 * must therefore be a terminal node, being the only point than can
1910*16467b97STreehugger Robot 	 * be reached with the bits seen so far. It is either the actual key
1911*16467b97STreehugger Robot 	 * we wanted, or if that key is not in the trie it is another key
1912*16467b97STreehugger Robot 	 * that is currently the only one that can be reached by those bits.
1913*16467b97STreehugger Robot 	 * That situation would obviously change if the key was to be added
1914*16467b97STreehugger Robot 	 * to the trie.
1915*16467b97STreehugger Robot 	 *
1916*16467b97STreehugger Robot 	 * Hence it only remains to test whether this is actually the key or not.
1917*16467b97STreehugger Robot 	 */
1918*16467b97STreehugger Robot 	if (nextNode->key == key)
1919*16467b97STreehugger Robot 	{
1920*16467b97STreehugger Robot 		/* This was the key, so return the entry pointer
1921*16467b97STreehugger Robot 		 */
1922*16467b97STreehugger Robot 		return	nextNode->buckets;
1923*16467b97STreehugger Robot 	}
1924*16467b97STreehugger Robot 	else
1925*16467b97STreehugger Robot 	{
1926*16467b97STreehugger Robot 		return	NULL;	/* That key is not in the trie (note that we set the pointer to -1 if no payload) */
1927*16467b97STreehugger Robot 	}
1928*16467b97STreehugger Robot }
1929*16467b97STreehugger Robot 
1930*16467b97STreehugger Robot 
1931*16467b97STreehugger Robot static	ANTLR3_BOOLEAN
intTrieDel(pANTLR3_INT_TRIE trie,ANTLR3_INTKEY key)1932*16467b97STreehugger Robot intTrieDel	(pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key)
1933*16467b97STreehugger Robot {
1934*16467b97STreehugger Robot     pANTLR3_INT_TRIE_NODE   p;
1935*16467b97STreehugger Robot 
1936*16467b97STreehugger Robot     p=trie->root;
1937*16467b97STreehugger Robot 
1938*16467b97STreehugger Robot     return ANTLR3_FALSE;
1939*16467b97STreehugger Robot }
1940*16467b97STreehugger Robot 
1941*16467b97STreehugger Robot /** Add an entry into the INT trie.
1942*16467b97STreehugger Robot  *  Basically we descend the trie as we do when searching it, which will
1943*16467b97STreehugger Robot  *  locate the only node in the trie that can be reached by the bit pattern of the
1944*16467b97STreehugger Robot  *  key. If the key is actually at that node, then if the trie accepts duplicates
1945*16467b97STreehugger Robot  *  we add the supplied data in a new chained bucket to that data node. If it does
1946*16467b97STreehugger Robot  *  not accept duplicates then we merely return FALSE in case the caller wants to know
1947*16467b97STreehugger Robot  *  whether the key was already in the trie.
1948*16467b97STreehugger Robot  *  If the node we locate is not the key we are looking to add, then we insert a new node
1949*16467b97STreehugger Robot  *  into the trie with a bit index of the leftmost differing bit and the left or right
1950*16467b97STreehugger Robot  *  node pointing to itself or the data node we are inserting 'before'.
1951*16467b97STreehugger Robot  */
1952*16467b97STreehugger Robot static	ANTLR3_BOOLEAN
intTrieAdd(pANTLR3_INT_TRIE trie,ANTLR3_INTKEY key,ANTLR3_UINT32 type,ANTLR3_INTKEY intVal,void * data,void (ANTLR3_CDECL * freeptr)(void *))1953*16467b97STreehugger Robot intTrieAdd	(pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key, ANTLR3_UINT32 type, ANTLR3_INTKEY intVal, void * data, void (ANTLR3_CDECL *freeptr)(void *))
1954*16467b97STreehugger Robot {
1955*16467b97STreehugger Robot 	pANTLR3_INT_TRIE_NODE   thisNode;
1956*16467b97STreehugger Robot 	pANTLR3_INT_TRIE_NODE   nextNode;
1957*16467b97STreehugger Robot 	pANTLR3_INT_TRIE_NODE   entNode;
1958*16467b97STreehugger Robot 	ANTLR3_UINT32			depth;
1959*16467b97STreehugger Robot 	pANTLR3_TRIE_ENTRY	    newEnt;
1960*16467b97STreehugger Robot 	pANTLR3_TRIE_ENTRY	    nextEnt;
1961*16467b97STreehugger Robot 	ANTLR3_INTKEY		    xorKey;
1962*16467b97STreehugger Robot 
1963*16467b97STreehugger Robot 	/* Cache the bit depth of this trie, which is always the highest index,
1964*16467b97STreehugger Robot 	 * which is in the root node
1965*16467b97STreehugger Robot 	 */
1966*16467b97STreehugger Robot 	depth   = trie->root->bitNum;
1967*16467b97STreehugger Robot 
1968*16467b97STreehugger Robot 	thisNode	= trie->root;		/* Start with the root node	    */
1969*16467b97STreehugger Robot 	nextNode	= trie->root->leftN;	/* And assume we start to the left  */
1970*16467b97STreehugger Robot 
1971*16467b97STreehugger Robot 	/* Now find the only node that can be currently reached by the bits in the
1972*16467b97STreehugger Robot 	 * key we are being asked to insert.
1973*16467b97STreehugger Robot 	 */
1974*16467b97STreehugger Robot 	while (thisNode->bitNum  > nextNode->bitNum)
1975*16467b97STreehugger Robot 	{
1976*16467b97STreehugger Robot 		/* Still descending the structure, next node becomes current.
1977*16467b97STreehugger Robot 		 */
1978*16467b97STreehugger Robot 		thisNode = nextNode;
1979*16467b97STreehugger Robot 
1980*16467b97STreehugger Robot 		if (key & bitMask[nextNode->bitNum])
1981*16467b97STreehugger Robot 		{
1982*16467b97STreehugger Robot 			/* Bit at the required index was 1, so travers the right node from here
1983*16467b97STreehugger Robot 			 */
1984*16467b97STreehugger Robot 			nextNode = nextNode->rightN;
1985*16467b97STreehugger Robot 		}
1986*16467b97STreehugger Robot 		else
1987*16467b97STreehugger Robot 		{
1988*16467b97STreehugger Robot 			/* Bit at the required index was 0, so we traverse to the left
1989*16467b97STreehugger Robot 			 */
1990*16467b97STreehugger Robot 			nextNode = nextNode->leftN;
1991*16467b97STreehugger Robot 		}
1992*16467b97STreehugger Robot 	}
1993*16467b97STreehugger Robot 	/* Here we have located the only node that can be reached by the
1994*16467b97STreehugger Robot 	 * bits in the requested key. It could in fact be that key or the node
1995*16467b97STreehugger Robot 	 * we need to use to insert the new key.
1996*16467b97STreehugger Robot 	 */
1997*16467b97STreehugger Robot 	if (nextNode->key == key)
1998*16467b97STreehugger Robot 	{
1999*16467b97STreehugger Robot 		/* We have located an exact match, but we will only append to the bucket chain
2000*16467b97STreehugger Robot 		 * if this trie accepts duplicate keys.
2001*16467b97STreehugger Robot 		 */
2002*16467b97STreehugger Robot 		if (trie->allowDups ==ANTLR3_TRUE)
2003*16467b97STreehugger Robot 		{
2004*16467b97STreehugger Robot 			/* Yes, we are accepting duplicates
2005*16467b97STreehugger Robot 			 */
2006*16467b97STreehugger Robot 			newEnt = (pANTLR3_TRIE_ENTRY)ANTLR3_CALLOC(1, sizeof(ANTLR3_TRIE_ENTRY));
2007*16467b97STreehugger Robot 
2008*16467b97STreehugger Robot 			if (newEnt == NULL)
2009*16467b97STreehugger Robot 			{
2010*16467b97STreehugger Robot 				/* Out of memory, all we can do is return the fact that the insert failed.
2011*16467b97STreehugger Robot 				 */
2012*16467b97STreehugger Robot 				return	ANTLR3_FALSE;
2013*16467b97STreehugger Robot 			}
2014*16467b97STreehugger Robot 
2015*16467b97STreehugger Robot 			/* Otherwise insert this in the chain
2016*16467b97STreehugger Robot 			*/
2017*16467b97STreehugger Robot 			newEnt->type	= type;
2018*16467b97STreehugger Robot 			newEnt->freeptr	= freeptr;
2019*16467b97STreehugger Robot 			if (type == ANTLR3_HASH_TYPE_STR)
2020*16467b97STreehugger Robot 			{
2021*16467b97STreehugger Robot 				newEnt->data.ptr = data;
2022*16467b97STreehugger Robot 			}
2023*16467b97STreehugger Robot 			else
2024*16467b97STreehugger Robot 			{
2025*16467b97STreehugger Robot 				newEnt->data.intVal = intVal;
2026*16467b97STreehugger Robot 			}
2027*16467b97STreehugger Robot 
2028*16467b97STreehugger Robot 			/* We want to be able to traverse the stored elements in the order that they were
2029*16467b97STreehugger Robot 			 * added as duplicate keys. We might need to revise this opinion if we end up having many duplicate keys
2030*16467b97STreehugger Robot 			 * as perhaps reverse order is just as good, so long as it is ordered.
2031*16467b97STreehugger Robot 			 */
2032*16467b97STreehugger Robot 			nextEnt = nextNode->buckets;
2033*16467b97STreehugger Robot 			while (nextEnt->next != NULL)
2034*16467b97STreehugger Robot 			{
2035*16467b97STreehugger Robot 				nextEnt = nextEnt->next;
2036*16467b97STreehugger Robot 			}
2037*16467b97STreehugger Robot 			nextEnt->next = newEnt;
2038*16467b97STreehugger Robot 
2039*16467b97STreehugger Robot 			trie->count++;
2040*16467b97STreehugger Robot 			return  ANTLR3_TRUE;
2041*16467b97STreehugger Robot 		}
2042*16467b97STreehugger Robot 		else
2043*16467b97STreehugger Robot 		{
2044*16467b97STreehugger Robot 			/* We found the key is already there and we are not allowed duplicates in this
2045*16467b97STreehugger Robot 			 * trie.
2046*16467b97STreehugger Robot 			 */
2047*16467b97STreehugger Robot 			return  ANTLR3_FALSE;
2048*16467b97STreehugger Robot 		}
2049*16467b97STreehugger Robot 	}
2050*16467b97STreehugger Robot 
2051*16467b97STreehugger Robot 	/* Here we have discovered the only node that can be reached by the bits in the key
2052*16467b97STreehugger Robot 	 * but we have found that this node is not the key we need to insert. We must find the
2053*16467b97STreehugger Robot 	 * the leftmost bit by which the current key for that node and the new key we are going
2054*16467b97STreehugger Robot 	 * to insert, differ. While this nested series of ifs may look a bit strange, experimentation
2055*16467b97STreehugger Robot 	 * showed that it allows a machine code path that works well with predicated execution
2056*16467b97STreehugger Robot 	 */
2057*16467b97STreehugger Robot 	xorKey = (key ^ nextNode->key);   /* Gives 1 bits only where they differ then we find the left most 1 bit*/
2058*16467b97STreehugger Robot 
2059*16467b97STreehugger Robot 	/* Most common case is a 32 bit key really
2060*16467b97STreehugger Robot 	 */
2061*16467b97STreehugger Robot #ifdef	ANTLR3_USE_64BIT
2062*16467b97STreehugger Robot 	if	(xorKey & 0xFFFFFFFF00000000)
2063*16467b97STreehugger Robot 	{
2064*16467b97STreehugger Robot 		if  (xorKey & 0xFFFF000000000000)
2065*16467b97STreehugger Robot 		{
2066*16467b97STreehugger Robot 			if	(xorKey & 0xFF00000000000000)
2067*16467b97STreehugger Robot 			{
2068*16467b97STreehugger Robot 				depth = 56 + bitIndex[((xorKey & 0xFF00000000000000)>>56)];
2069*16467b97STreehugger Robot 			}
2070*16467b97STreehugger Robot 			else
2071*16467b97STreehugger Robot 			{
2072*16467b97STreehugger Robot 				depth = 48 + bitIndex[((xorKey & 0x00FF000000000000)>>48)];
2073*16467b97STreehugger Robot 			}
2074*16467b97STreehugger Robot 		}
2075*16467b97STreehugger Robot 		else
2076*16467b97STreehugger Robot 		{
2077*16467b97STreehugger Robot 			if	(xorKey & 0x0000FF0000000000)
2078*16467b97STreehugger Robot 			{
2079*16467b97STreehugger Robot 				depth = 40 + bitIndex[((xorKey & 0x0000FF0000000000)>>40)];
2080*16467b97STreehugger Robot 			}
2081*16467b97STreehugger Robot 			else
2082*16467b97STreehugger Robot 			{
2083*16467b97STreehugger Robot 				depth = 32 + bitIndex[((xorKey & 0x000000FF00000000)>>32)];
2084*16467b97STreehugger Robot 			}
2085*16467b97STreehugger Robot 		}
2086*16467b97STreehugger Robot 	}
2087*16467b97STreehugger Robot 	else
2088*16467b97STreehugger Robot #endif
2089*16467b97STreehugger Robot 	{
2090*16467b97STreehugger Robot 		if  (xorKey & 0x00000000FFFF0000)
2091*16467b97STreehugger Robot 		{
2092*16467b97STreehugger Robot 			if	(xorKey & 0x00000000FF000000)
2093*16467b97STreehugger Robot 			{
2094*16467b97STreehugger Robot 				depth = 24 + bitIndex[((xorKey & 0x00000000FF000000)>>24)];
2095*16467b97STreehugger Robot 			}
2096*16467b97STreehugger Robot 			else
2097*16467b97STreehugger Robot 			{
2098*16467b97STreehugger Robot 				depth = 16 + bitIndex[((xorKey & 0x0000000000FF0000)>>16)];
2099*16467b97STreehugger Robot 			}
2100*16467b97STreehugger Robot 		}
2101*16467b97STreehugger Robot 		else
2102*16467b97STreehugger Robot 		{
2103*16467b97STreehugger Robot 			if	(xorKey & 0x000000000000FF00)
2104*16467b97STreehugger Robot 			{
2105*16467b97STreehugger Robot 				depth = 8 + bitIndex[((xorKey & 0x0000000000000FF00)>>8)];
2106*16467b97STreehugger Robot 			}
2107*16467b97STreehugger Robot 			else
2108*16467b97STreehugger Robot 			{
2109*16467b97STreehugger Robot 				depth = bitIndex[xorKey & 0x00000000000000FF];
2110*16467b97STreehugger Robot 			}
2111*16467b97STreehugger Robot 		}
2112*16467b97STreehugger Robot 	}
2113*16467b97STreehugger Robot 
2114*16467b97STreehugger Robot     /* We have located the leftmost differing bit, indicated by the depth variable. So, we know what
2115*16467b97STreehugger Robot      * bit index we are to insert the new entry at. There are two cases, being where the two keys
2116*16467b97STreehugger Robot      * differ at a bit position that is not currently part of the bit testing, where they differ on a bit
2117*16467b97STreehugger Robot      * that is currently being skipped in the indexed comparisons, and where they differ on a bit
2118*16467b97STreehugger Robot      * that is merely lower down in the current bit search. If the bit index went bit 4, bit 2 and they differ
2119*16467b97STreehugger Robot      * at bit 3, then we have the "skipped" bit case. But if that chain was Bit 4, Bit 2 and they differ at bit 1
2120*16467b97STreehugger Robot      * then we have the easy bit <pun>.
2121*16467b97STreehugger Robot      *
2122*16467b97STreehugger Robot      * So, set up to descend the tree again, but this time looking for the insert point
2123*16467b97STreehugger Robot      * according to whether we skip the bit that differs or not.
2124*16467b97STreehugger Robot      */
2125*16467b97STreehugger Robot     thisNode	= trie->root;
2126*16467b97STreehugger Robot     entNode	= trie->root->leftN;
2127*16467b97STreehugger Robot 
2128*16467b97STreehugger Robot     /* Note the slight difference in the checks here to cover both cases
2129*16467b97STreehugger Robot      */
2130*16467b97STreehugger Robot     while (thisNode->bitNum > entNode->bitNum && entNode->bitNum > depth)
2131*16467b97STreehugger Robot     {
2132*16467b97STreehugger Robot 	/* Still descending the structure, next node becomes current.
2133*16467b97STreehugger Robot 	 */
2134*16467b97STreehugger Robot 	thisNode = entNode;
2135*16467b97STreehugger Robot 
2136*16467b97STreehugger Robot 	if (key & bitMask[entNode->bitNum])
2137*16467b97STreehugger Robot 	{
2138*16467b97STreehugger Robot 	    /* Bit at the required index was 1, so traverse the right node from here
2139*16467b97STreehugger Robot 	     */
2140*16467b97STreehugger Robot 	    entNode = entNode->rightN;
2141*16467b97STreehugger Robot 	}
2142*16467b97STreehugger Robot 	else
2143*16467b97STreehugger Robot 	{
2144*16467b97STreehugger Robot 	    /* Bit at the required index was 0, so we traverse to the left
2145*16467b97STreehugger Robot 	     */
2146*16467b97STreehugger Robot 	    entNode = entNode->leftN;
2147*16467b97STreehugger Robot 	}
2148*16467b97STreehugger Robot     }
2149*16467b97STreehugger Robot 
2150*16467b97STreehugger Robot     /* We have located the correct insert point for this new key, so we need
2151*16467b97STreehugger Robot      * to allocate our entry and insert it etc.
2152*16467b97STreehugger Robot      */
2153*16467b97STreehugger Robot     nextNode	= (pANTLR3_INT_TRIE_NODE)ANTLR3_CALLOC(1, sizeof(ANTLR3_INT_TRIE_NODE));
2154*16467b97STreehugger Robot     if (nextNode == NULL)
2155*16467b97STreehugger Robot     {
2156*16467b97STreehugger Robot 	/* All that work and no memory - bummer.
2157*16467b97STreehugger Robot 	 */
2158*16467b97STreehugger Robot 	return	ANTLR3_FALSE;
2159*16467b97STreehugger Robot     }
2160*16467b97STreehugger Robot 
2161*16467b97STreehugger Robot     /* Build a new entry block for the new node
2162*16467b97STreehugger Robot      */
2163*16467b97STreehugger Robot     newEnt = (pANTLR3_TRIE_ENTRY)ANTLR3_CALLOC(1, sizeof(ANTLR3_TRIE_ENTRY));
2164*16467b97STreehugger Robot 
2165*16467b97STreehugger Robot     if (newEnt == NULL)
2166*16467b97STreehugger Robot     {
2167*16467b97STreehugger Robot 	/* Out of memory, all we can do is return the fact that the insert failed.
2168*16467b97STreehugger Robot 	 */
2169*16467b97STreehugger Robot 	return	ANTLR3_FALSE;
2170*16467b97STreehugger Robot     }
2171*16467b97STreehugger Robot 
2172*16467b97STreehugger Robot     /* Otherwise enter this in our new node
2173*16467b97STreehugger Robot     */
2174*16467b97STreehugger Robot     newEnt->type	= type;
2175*16467b97STreehugger Robot     newEnt->freeptr	= freeptr;
2176*16467b97STreehugger Robot     if (type == ANTLR3_HASH_TYPE_STR)
2177*16467b97STreehugger Robot     {
2178*16467b97STreehugger Robot 	newEnt->data.ptr = data;
2179*16467b97STreehugger Robot     }
2180*16467b97STreehugger Robot     else
2181*16467b97STreehugger Robot     {
2182*16467b97STreehugger Robot 	newEnt->data.intVal = intVal;
2183*16467b97STreehugger Robot     }
2184*16467b97STreehugger Robot     /* Install it
2185*16467b97STreehugger Robot      */
2186*16467b97STreehugger Robot     nextNode->buckets	= newEnt;
2187*16467b97STreehugger Robot     nextNode->key	= key;
2188*16467b97STreehugger Robot     nextNode->bitNum	= depth;
2189*16467b97STreehugger Robot 
2190*16467b97STreehugger Robot     /* Work out the right and left pointers for this new node, which involve
2191*16467b97STreehugger Robot      * terminating with the current found node either right or left according
2192*16467b97STreehugger Robot      * to whether the current index bit is 1 or 0
2193*16467b97STreehugger Robot      */
2194*16467b97STreehugger Robot     if (key & bitMask[depth])
2195*16467b97STreehugger Robot     {
2196*16467b97STreehugger Robot 	nextNode->leftN	    = entNode;	    /* Terminates at previous position	*/
2197*16467b97STreehugger Robot 	nextNode->rightN    = nextNode;	    /* Terminates with itself		*/
2198*16467b97STreehugger Robot     }
2199*16467b97STreehugger Robot     else
2200*16467b97STreehugger Robot     {
2201*16467b97STreehugger Robot 	nextNode->rightN   = entNode;	    /* Terminates at previous position	*/
2202*16467b97STreehugger Robot 	nextNode->leftN    = nextNode;	    /* Terminates with itself		*/
2203*16467b97STreehugger Robot     }
2204*16467b97STreehugger Robot 
2205*16467b97STreehugger Robot     /* Finally, we need to change the pointers at the node we located
2206*16467b97STreehugger Robot      * for inserting. If the key bit at its index is set then the right
2207*16467b97STreehugger Robot      * pointer for that node becomes the newly created node, otherwise the left
2208*16467b97STreehugger Robot      * pointer does.
2209*16467b97STreehugger Robot      */
2210*16467b97STreehugger Robot     if (key & bitMask[thisNode->bitNum] )
2211*16467b97STreehugger Robot     {
2212*16467b97STreehugger Robot 	thisNode->rightN    = nextNode;
2213*16467b97STreehugger Robot     }
2214*16467b97STreehugger Robot     else
2215*16467b97STreehugger Robot     {
2216*16467b97STreehugger Robot 	thisNode->leftN	    = nextNode;
2217*16467b97STreehugger Robot     }
2218*16467b97STreehugger Robot 
2219*16467b97STreehugger Robot     /* Et voila
2220*16467b97STreehugger Robot      */
2221*16467b97STreehugger Robot     trie->count++;
2222*16467b97STreehugger Robot     return  ANTLR3_TRUE;
2223*16467b97STreehugger Robot 
2224*16467b97STreehugger Robot }
2225*16467b97STreehugger Robot /** Release memory allocated to this tree.
2226*16467b97STreehugger Robot  *  Basic algorithm is that we do a depth first left descent and free
2227*16467b97STreehugger Robot  *  up any nodes that are not backward pointers.
2228*16467b97STreehugger Robot  */
2229*16467b97STreehugger Robot static void
freeIntNode(pANTLR3_INT_TRIE_NODE node)2230*16467b97STreehugger Robot freeIntNode(pANTLR3_INT_TRIE_NODE node)
2231*16467b97STreehugger Robot {
2232*16467b97STreehugger Robot     pANTLR3_TRIE_ENTRY	thisEntry;
2233*16467b97STreehugger Robot     pANTLR3_TRIE_ENTRY	nextEntry;
2234*16467b97STreehugger Robot 
2235*16467b97STreehugger Robot     /* If this node has a left pointer that is not a back pointer
2236*16467b97STreehugger Robot      * then recursively call to free this
2237*16467b97STreehugger Robot      */
2238*16467b97STreehugger Robot     if (node->bitNum > node->leftN->bitNum)
2239*16467b97STreehugger Robot     {
2240*16467b97STreehugger Robot 	/* We have a left node that needs descending, so do it.
2241*16467b97STreehugger Robot 	 */
2242*16467b97STreehugger Robot 	freeIntNode(node->leftN);
2243*16467b97STreehugger Robot     }
2244*16467b97STreehugger Robot 
2245*16467b97STreehugger Robot     /* The left nodes from here should now be dealt with, so
2246*16467b97STreehugger Robot      * we need to descend any right nodes that are not back pointers
2247*16467b97STreehugger Robot      */
2248*16467b97STreehugger Robot     if (node->bitNum > node->rightN->bitNum)
2249*16467b97STreehugger Robot     {
2250*16467b97STreehugger Robot 	/* There are some right nodes to descend and deal with.
2251*16467b97STreehugger Robot 	 */
2252*16467b97STreehugger Robot 	freeIntNode(node->rightN);
2253*16467b97STreehugger Robot     }
2254*16467b97STreehugger Robot 
2255*16467b97STreehugger Robot     /* Now all the children are dealt with, we can destroy
2256*16467b97STreehugger Robot      * this node too
2257*16467b97STreehugger Robot      */
2258*16467b97STreehugger Robot     thisEntry	= node->buckets;
2259*16467b97STreehugger Robot 
2260*16467b97STreehugger Robot     while (thisEntry != NULL)
2261*16467b97STreehugger Robot     {
2262*16467b97STreehugger Robot 	nextEntry   = thisEntry->next;
2263*16467b97STreehugger Robot 
2264*16467b97STreehugger Robot 	/* Do we need to call a custom free pointer for this string entry?
2265*16467b97STreehugger Robot 	 */
2266*16467b97STreehugger Robot 	if (thisEntry->type == ANTLR3_HASH_TYPE_STR && thisEntry->freeptr != NULL)
2267*16467b97STreehugger Robot 	{
2268*16467b97STreehugger Robot 	    thisEntry->freeptr(thisEntry->data.ptr);
2269*16467b97STreehugger Robot 	}
2270*16467b97STreehugger Robot 
2271*16467b97STreehugger Robot 	/* Now free the data for this bucket entry
2272*16467b97STreehugger Robot 	 */
2273*16467b97STreehugger Robot 	ANTLR3_FREE(thisEntry);
2274*16467b97STreehugger Robot 	thisEntry = nextEntry;	    /* See if there are any more to free    */
2275*16467b97STreehugger Robot     }
2276*16467b97STreehugger Robot 
2277*16467b97STreehugger Robot     /* The bucket entry is now gone, so we can free the memory for
2278*16467b97STreehugger Robot      * the entry itself.
2279*16467b97STreehugger Robot      */
2280*16467b97STreehugger Robot     ANTLR3_FREE(node);
2281*16467b97STreehugger Robot 
2282*16467b97STreehugger Robot     /* And that should be it for everything under this node and itself
2283*16467b97STreehugger Robot      */
2284*16467b97STreehugger Robot }
2285*16467b97STreehugger Robot 
2286*16467b97STreehugger Robot /** Called to free all nodes and the structure itself.
2287*16467b97STreehugger Robot  */
2288*16467b97STreehugger Robot static	void
intTrieFree(pANTLR3_INT_TRIE trie)2289*16467b97STreehugger Robot intTrieFree	(pANTLR3_INT_TRIE trie)
2290*16467b97STreehugger Robot {
2291*16467b97STreehugger Robot     /* Descend from the root and free all the nodes
2292*16467b97STreehugger Robot      */
2293*16467b97STreehugger Robot     freeIntNode(trie->root);
2294*16467b97STreehugger Robot 
2295*16467b97STreehugger Robot     /* the nodes are all gone now, so we need only free the memory
2296*16467b97STreehugger Robot      * for the structure itself
2297*16467b97STreehugger Robot      */
2298*16467b97STreehugger Robot     ANTLR3_FREE(trie);
2299*16467b97STreehugger Robot }
2300*16467b97STreehugger Robot 
2301*16467b97STreehugger Robot 
2302*16467b97STreehugger Robot /**
2303*16467b97STreehugger Robot  * Allocate and initialize a new ANTLR3 topological sorter, which can be
2304*16467b97STreehugger Robot  * used to define edges that identify numerical node indexes that depend on other
2305*16467b97STreehugger Robot  * numerical node indexes, which can then be sorted topologically such that
2306*16467b97STreehugger Robot  * any node is sorted after all its dependent nodes.
2307*16467b97STreehugger Robot  *
2308*16467b97STreehugger Robot  * Use:
2309*16467b97STreehugger Robot  *
2310*16467b97STreehugger Robot  * /verbatim
2311*16467b97STreehugger Robot 
2312*16467b97STreehugger Robot   pANTLR3_TOPO topo;
2313*16467b97STreehugger Robot   topo = antlr3NewTopo();
2314*16467b97STreehugger Robot 
2315*16467b97STreehugger Robot   if (topo == NULL) { out of memory }
2316*16467b97STreehugger Robot 
2317*16467b97STreehugger Robot   topo->addEdge(topo, 3, 0); // Node 3 depends on node 0
2318*16467b97STreehugger Robot   topo->addEdge(topo, 0, 1); // Node - depends on node 1
2319*16467b97STreehugger Robot   topo->sortVector(topo, myVector); // Sort the vector in place (node numbers are the vector entry numbers)
2320*16467b97STreehugger Robot 
2321*16467b97STreehugger Robot  * /verbatim
2322*16467b97STreehugger Robot  */
2323*16467b97STreehugger Robot ANTLR3_API pANTLR3_TOPO
antlr3TopoNew()2324*16467b97STreehugger Robot antlr3TopoNew()
2325*16467b97STreehugger Robot {
2326*16467b97STreehugger Robot     pANTLR3_TOPO topo = (pANTLR3_TOPO)ANTLR3_MALLOC(sizeof(ANTLR3_TOPO));
2327*16467b97STreehugger Robot 
2328*16467b97STreehugger Robot     if  (topo == NULL)
2329*16467b97STreehugger Robot     {
2330*16467b97STreehugger Robot         return NULL;
2331*16467b97STreehugger Robot     }
2332*16467b97STreehugger Robot 
2333*16467b97STreehugger Robot     // Initialize variables
2334*16467b97STreehugger Robot     //
2335*16467b97STreehugger Robot 
2336*16467b97STreehugger Robot     topo->visited   = NULL;                 // Don't know how big it is yet
2337*16467b97STreehugger Robot     topo->limit     = 1;                    // No edges added yet
2338*16467b97STreehugger Robot     topo->edges     = NULL;                 // No edges added yet
2339*16467b97STreehugger Robot     topo->sorted    = NULL;                 // Nothing sorted at the start
2340*16467b97STreehugger Robot     topo->cycle     = NULL;                 // No cycles at the start
2341*16467b97STreehugger Robot     topo->cycleMark = 0;                    // No cycles at the start
2342*16467b97STreehugger Robot     topo->hasCycle  = ANTLR3_FALSE;         // No cycle at the start
2343*16467b97STreehugger Robot 
2344*16467b97STreehugger Robot     // API
2345*16467b97STreehugger Robot     //
2346*16467b97STreehugger Robot     topo->addEdge       = addEdge;
2347*16467b97STreehugger Robot     topo->sortToArray   = sortToArray;
2348*16467b97STreehugger Robot     topo->sortVector    = sortVector;
2349*16467b97STreehugger Robot     topo->free          = freeTopo;
2350*16467b97STreehugger Robot 
2351*16467b97STreehugger Robot     return topo;
2352*16467b97STreehugger Robot }
2353*16467b97STreehugger Robot // Topological sorter
2354*16467b97STreehugger Robot //
2355*16467b97STreehugger Robot static  void
addEdge(pANTLR3_TOPO topo,ANTLR3_UINT32 edge,ANTLR3_UINT32 dependency)2356*16467b97STreehugger Robot addEdge          (pANTLR3_TOPO topo, ANTLR3_UINT32 edge, ANTLR3_UINT32 dependency)
2357*16467b97STreehugger Robot {
2358*16467b97STreehugger Robot     ANTLR3_UINT32   i;
2359*16467b97STreehugger Robot     ANTLR3_UINT32   maxEdge;
2360*16467b97STreehugger Robot     pANTLR3_BITSET  edgeDeps;
2361*16467b97STreehugger Robot 
2362*16467b97STreehugger Robot     if (edge>dependency)
2363*16467b97STreehugger Robot     {
2364*16467b97STreehugger Robot         maxEdge = edge;
2365*16467b97STreehugger Robot     }
2366*16467b97STreehugger Robot     else
2367*16467b97STreehugger Robot     {
2368*16467b97STreehugger Robot         maxEdge = dependency;
2369*16467b97STreehugger Robot     }
2370*16467b97STreehugger Robot     // We need to add an edge to says that the node indexed by 'edge' is
2371*16467b97STreehugger Robot     // dependent on the node indexed by 'dependency'
2372*16467b97STreehugger Robot     //
2373*16467b97STreehugger Robot 
2374*16467b97STreehugger Robot     // First see if we have enough room in the edges array to add the edge?
2375*16467b97STreehugger Robot     //
2376*16467b97STreehugger Robot     if (topo->edges == NULL)
2377*16467b97STreehugger Robot     {
2378*16467b97STreehugger Robot         // We don't have any edges yet, so create an array to hold them
2379*16467b97STreehugger Robot         //
2380*16467b97STreehugger Robot         topo->edges = (pANTLR3_BITSET*)ANTLR3_CALLOC(sizeof(pANTLR3_BITSET) * (maxEdge + 1), 1);
2381*16467b97STreehugger Robot         if (topo->edges == NULL)
2382*16467b97STreehugger Robot         {
2383*16467b97STreehugger Robot             return;
2384*16467b97STreehugger Robot         }
2385*16467b97STreehugger Robot 
2386*16467b97STreehugger Robot         // Set the limit to what we have now
2387*16467b97STreehugger Robot         //
2388*16467b97STreehugger Robot         topo->limit = maxEdge + 1;
2389*16467b97STreehugger Robot     }
2390*16467b97STreehugger Robot     else if (topo->limit <= maxEdge)
2391*16467b97STreehugger Robot     {
2392*16467b97STreehugger Robot         // WE have some edges but not enough
2393*16467b97STreehugger Robot         //
2394*16467b97STreehugger Robot         topo->edges = (pANTLR3_BITSET*)ANTLR3_REALLOC(topo->edges, sizeof(pANTLR3_BITSET) * (maxEdge + 1));
2395*16467b97STreehugger Robot         if (topo->edges == NULL)
2396*16467b97STreehugger Robot         {
2397*16467b97STreehugger Robot             return;
2398*16467b97STreehugger Robot         }
2399*16467b97STreehugger Robot 
2400*16467b97STreehugger Robot         // Initialize the new bitmaps to ;indicate we have no edges defined yet
2401*16467b97STreehugger Robot         //
2402*16467b97STreehugger Robot         for (i = topo->limit; i <= maxEdge; i++)
2403*16467b97STreehugger Robot         {
2404*16467b97STreehugger Robot             *((topo->edges) + i) = NULL;
2405*16467b97STreehugger Robot         }
2406*16467b97STreehugger Robot 
2407*16467b97STreehugger Robot         // Set the limit to what we have now
2408*16467b97STreehugger Robot         //
2409*16467b97STreehugger Robot         topo->limit = maxEdge + 1;
2410*16467b97STreehugger Robot     }
2411*16467b97STreehugger Robot 
2412*16467b97STreehugger Robot     // If the edge was flagged as depending on itself, then we just
2413*16467b97STreehugger Robot     // do nothing as it means this routine was just called to add it
2414*16467b97STreehugger Robot     // in to the list of nodes.
2415*16467b97STreehugger Robot     //
2416*16467b97STreehugger Robot     if  (edge == dependency)
2417*16467b97STreehugger Robot     {
2418*16467b97STreehugger Robot         return;
2419*16467b97STreehugger Robot     }
2420*16467b97STreehugger Robot 
2421*16467b97STreehugger Robot     // Pick up the bit map for the requested edge
2422*16467b97STreehugger Robot     //
2423*16467b97STreehugger Robot     edgeDeps = *((topo->edges) + edge);
2424*16467b97STreehugger Robot 
2425*16467b97STreehugger Robot     if  (edgeDeps == NULL)
2426*16467b97STreehugger Robot     {
2427*16467b97STreehugger Robot         // No edges are defined yet for this node
2428*16467b97STreehugger Robot         //
2429*16467b97STreehugger Robot         edgeDeps                = antlr3BitsetNew(0);
2430*16467b97STreehugger Robot         *((topo->edges) + edge) = edgeDeps;
2431*16467b97STreehugger Robot         if (edgeDeps == NULL )
2432*16467b97STreehugger Robot         {
2433*16467b97STreehugger Robot             return;  // Out of memory
2434*16467b97STreehugger Robot         }
2435*16467b97STreehugger Robot     }
2436*16467b97STreehugger Robot 
2437*16467b97STreehugger Robot     // Set the bit in the bitmap that corresponds to the requested
2438*16467b97STreehugger Robot     // dependency.
2439*16467b97STreehugger Robot     //
2440*16467b97STreehugger Robot     edgeDeps->add(edgeDeps, dependency);
2441*16467b97STreehugger Robot 
2442*16467b97STreehugger Robot     // And we are all set
2443*16467b97STreehugger Robot     //
2444*16467b97STreehugger Robot     return;
2445*16467b97STreehugger Robot }
2446*16467b97STreehugger Robot 
2447*16467b97STreehugger Robot 
2448*16467b97STreehugger Robot /**
2449*16467b97STreehugger Robot  * Given a starting node, descend its dependent nodes (ones that it has edges
2450*16467b97STreehugger Robot  * to) until we find one without edges. Having found a node without edges, we have
2451*16467b97STreehugger Robot  * discovered the bottom of a depth first search, which we can then ascend, adding
2452*16467b97STreehugger Robot  * the nodes in order from the bottom, which gives us the dependency order.
2453*16467b97STreehugger Robot  */
2454*16467b97STreehugger Robot static void
DFS(pANTLR3_TOPO topo,ANTLR3_UINT32 node)2455*16467b97STreehugger Robot DFS(pANTLR3_TOPO topo, ANTLR3_UINT32 node)
2456*16467b97STreehugger Robot {
2457*16467b97STreehugger Robot     pANTLR3_BITSET edges;
2458*16467b97STreehugger Robot 
2459*16467b97STreehugger Robot     // Guard against a revisit and check for cycles
2460*16467b97STreehugger Robot     //
2461*16467b97STreehugger Robot     if  (topo->hasCycle == ANTLR3_TRUE)
2462*16467b97STreehugger Robot     {
2463*16467b97STreehugger Robot         return; // We don't do anything else if we found a cycle
2464*16467b97STreehugger Robot     }
2465*16467b97STreehugger Robot 
2466*16467b97STreehugger Robot     if  (topo->visited->isMember(topo->visited, node))
2467*16467b97STreehugger Robot     {
2468*16467b97STreehugger Robot         // Check to see if we found a cycle. To do this we search the
2469*16467b97STreehugger Robot         // current cycle stack and see if we find this node already in the stack.
2470*16467b97STreehugger Robot         //
2471*16467b97STreehugger Robot         ANTLR3_UINT32   i;
2472*16467b97STreehugger Robot 
2473*16467b97STreehugger Robot         for (i=0; i<topo->cycleMark; i++)
2474*16467b97STreehugger Robot         {
2475*16467b97STreehugger Robot             if  (topo->cycle[i] == node)
2476*16467b97STreehugger Robot             {
2477*16467b97STreehugger Robot                 // Stop! We found a cycle in the input, so rejig the cycle
2478*16467b97STreehugger Robot                 // stack so that it only contains the cycle and set the cycle flag
2479*16467b97STreehugger Robot                 // which will tell the caller what happened
2480*16467b97STreehugger Robot                 //
2481*16467b97STreehugger Robot                 ANTLR3_UINT32 l;
2482*16467b97STreehugger Robot 
2483*16467b97STreehugger Robot                 for (l = i; l < topo->cycleMark; l++)
2484*16467b97STreehugger Robot                 {
2485*16467b97STreehugger Robot                     topo->cycle[l - i] = topo->cycle[l];    // Move to zero base in the cycle list
2486*16467b97STreehugger Robot                 }
2487*16467b97STreehugger Robot 
2488*16467b97STreehugger Robot                 // Recalculate the limit
2489*16467b97STreehugger Robot                 //
2490*16467b97STreehugger Robot                 topo->cycleMark -= i;
2491*16467b97STreehugger Robot 
2492*16467b97STreehugger Robot                 // Signal disaster
2493*16467b97STreehugger Robot                 //
2494*16467b97STreehugger Robot                 topo->hasCycle = ANTLR3_TRUE;
2495*16467b97STreehugger Robot             }
2496*16467b97STreehugger Robot         }
2497*16467b97STreehugger Robot         return;
2498*16467b97STreehugger Robot     }
2499*16467b97STreehugger Robot 
2500*16467b97STreehugger Robot     // So far, no cycles have been found and we have not visited this node yet,
2501*16467b97STreehugger Robot     // so this node needs to go into the cycle stack before we continue
2502*16467b97STreehugger Robot     // then we will take it out of the stack once we have descended all its
2503*16467b97STreehugger Robot     // dependencies.
2504*16467b97STreehugger Robot     //
2505*16467b97STreehugger Robot     topo->cycle[topo->cycleMark++] = node;
2506*16467b97STreehugger Robot 
2507*16467b97STreehugger Robot     // First flag that we have visited this node
2508*16467b97STreehugger Robot     //
2509*16467b97STreehugger Robot     topo->visited->add(topo->visited, node);
2510*16467b97STreehugger Robot 
2511*16467b97STreehugger Robot     // Now, if this node has edges, then we want to ensure we visit
2512*16467b97STreehugger Robot     // them all before we drop through and add this node into the sorted
2513*16467b97STreehugger Robot     // list.
2514*16467b97STreehugger Robot     //
2515*16467b97STreehugger Robot     edges = *((topo->edges) + node);
2516*16467b97STreehugger Robot     if  (edges != NULL)
2517*16467b97STreehugger Robot     {
2518*16467b97STreehugger Robot         // We have some edges, so visit each of the edge nodes
2519*16467b97STreehugger Robot         // that have not already been visited.
2520*16467b97STreehugger Robot         //
2521*16467b97STreehugger Robot         ANTLR3_UINT32   numBits;	    // How many bits are in the set
2522*16467b97STreehugger Robot         ANTLR3_UINT32   i;
2523*16467b97STreehugger Robot         ANTLR3_UINT32   range;
2524*16467b97STreehugger Robot 
2525*16467b97STreehugger Robot         numBits = edges->numBits(edges);
2526*16467b97STreehugger Robot         range   = edges->size(edges);   // Number of set bits
2527*16467b97STreehugger Robot 
2528*16467b97STreehugger Robot         // Stop if we exahust the bit list or have checked the
2529*16467b97STreehugger Robot         // number of edges that this node refers to (so we don't
2530*16467b97STreehugger Robot         // check bits at the end that cannot possibly be set).
2531*16467b97STreehugger Robot         //
2532*16467b97STreehugger Robot         for (i=0; i<= numBits && range > 0; i++)
2533*16467b97STreehugger Robot         {
2534*16467b97STreehugger Robot             if  (edges->isMember(edges, i))
2535*16467b97STreehugger Robot             {
2536*16467b97STreehugger Robot                 range--;        // About to check another one
2537*16467b97STreehugger Robot 
2538*16467b97STreehugger Robot                 // Found an edge, make sure we visit and descend it
2539*16467b97STreehugger Robot                 //
2540*16467b97STreehugger Robot                 DFS(topo, i);
2541*16467b97STreehugger Robot             }
2542*16467b97STreehugger Robot         }
2543*16467b97STreehugger Robot     }
2544*16467b97STreehugger Robot 
2545*16467b97STreehugger Robot     // At this point we will have visited all the dependencies
2546*16467b97STreehugger Robot     // of this node and they will be ordered (even if there are cycles)
2547*16467b97STreehugger Robot     // So we just add the node into the sorted list at the
2548*16467b97STreehugger Robot     // current index position.
2549*16467b97STreehugger Robot     //
2550*16467b97STreehugger Robot     topo->sorted[topo->limit++] = node;
2551*16467b97STreehugger Robot 
2552*16467b97STreehugger Robot     // Remove this node from the cycle list if we have not detected a cycle
2553*16467b97STreehugger Robot     //
2554*16467b97STreehugger Robot     if  (topo->hasCycle == ANTLR3_FALSE)
2555*16467b97STreehugger Robot     {
2556*16467b97STreehugger Robot         topo->cycleMark--;
2557*16467b97STreehugger Robot     }
2558*16467b97STreehugger Robot 
2559*16467b97STreehugger Robot     return;
2560*16467b97STreehugger Robot }
2561*16467b97STreehugger Robot 
2562*16467b97STreehugger Robot static  pANTLR3_UINT32
sortToArray(pANTLR3_TOPO topo)2563*16467b97STreehugger Robot sortToArray      (pANTLR3_TOPO topo)
2564*16467b97STreehugger Robot {
2565*16467b97STreehugger Robot     ANTLR3_UINT32 v;
2566*16467b97STreehugger Robot     ANTLR3_UINT32 oldLimit;
2567*16467b97STreehugger Robot 
2568*16467b97STreehugger Robot     // Guard against being called with no edges defined
2569*16467b97STreehugger Robot     //
2570*16467b97STreehugger Robot     if  (topo->edges == NULL)
2571*16467b97STreehugger Robot     {
2572*16467b97STreehugger Robot         return NULL;
2573*16467b97STreehugger Robot     }
2574*16467b97STreehugger Robot     // First we need a vector to populate with enough
2575*16467b97STreehugger Robot     // entries to accommodate the sorted list and another to accommodate
2576*16467b97STreehugger Robot     // the maximum cycle we could detect which is all nodes such as 0->1->2->3->0
2577*16467b97STreehugger Robot     //
2578*16467b97STreehugger Robot     topo->sorted    = (pANTLR3_UINT32)ANTLR3_MALLOC(topo->limit * sizeof(ANTLR3_UINT32));
2579*16467b97STreehugger Robot 	if (topo->sorted == NULL)
2580*16467b97STreehugger Robot 	{
2581*16467b97STreehugger Robot 		return NULL;
2582*16467b97STreehugger Robot 	}
2583*16467b97STreehugger Robot     topo->cycle     = (pANTLR3_UINT32)ANTLR3_MALLOC(topo->limit * sizeof(ANTLR3_UINT32));
2584*16467b97STreehugger Robot 	if (topo->cycle == NULL)
2585*16467b97STreehugger Robot 	{
2586*16467b97STreehugger Robot 		return NULL;
2587*16467b97STreehugger Robot 	}
2588*16467b97STreehugger Robot 
2589*16467b97STreehugger Robot     // Next we need an empty bitset to show whether we have visited a node
2590*16467b97STreehugger Robot     // or not. This is the bit that gives us linear time of course as we are essentially
2591*16467b97STreehugger Robot     // dropping through the nodes in depth first order and when we get to a node that
2592*16467b97STreehugger Robot     // has no edges, we pop back up the stack adding the nodes we traversed in reverse
2593*16467b97STreehugger Robot     // order.
2594*16467b97STreehugger Robot     //
2595*16467b97STreehugger Robot     topo->visited   = antlr3BitsetNew(0);
2596*16467b97STreehugger Robot 
2597*16467b97STreehugger Robot     // Now traverse the nodes as if we were just going left to right, but
2598*16467b97STreehugger Robot     // then descend each node unless it has already been visited.
2599*16467b97STreehugger Robot     //
2600*16467b97STreehugger Robot     oldLimit    = topo->limit;     // Number of nodes to traverse linearly
2601*16467b97STreehugger Robot     topo->limit = 0;               // Next entry in the sorted table
2602*16467b97STreehugger Robot 
2603*16467b97STreehugger Robot     for (v = 0; v < oldLimit; v++)
2604*16467b97STreehugger Robot     {
2605*16467b97STreehugger Robot         // If we did not already visit this node, then descend it until we
2606*16467b97STreehugger Robot         // get a node without edges or arrive at a node we have already visited.
2607*16467b97STreehugger Robot         //
2608*16467b97STreehugger Robot         if  (topo->visited->isMember(topo->visited, v) == ANTLR3_FALSE)
2609*16467b97STreehugger Robot         {
2610*16467b97STreehugger Robot             // We have not visited this one so descend it
2611*16467b97STreehugger Robot             //
2612*16467b97STreehugger Robot             DFS(topo, v);
2613*16467b97STreehugger Robot         }
2614*16467b97STreehugger Robot 
2615*16467b97STreehugger Robot         // Break the loop if we detect a cycle as we have no need to go any
2616*16467b97STreehugger Robot         // further
2617*16467b97STreehugger Robot         //
2618*16467b97STreehugger Robot         if  (topo->hasCycle == ANTLR3_TRUE)
2619*16467b97STreehugger Robot         {
2620*16467b97STreehugger Robot             break;
2621*16467b97STreehugger Robot         }
2622*16467b97STreehugger Robot     }
2623*16467b97STreehugger Robot 
2624*16467b97STreehugger Robot     // Reset the limit to the number we recorded as if we hit a
2625*16467b97STreehugger Robot     // cycle, then limit will have stopped at the node where we
2626*16467b97STreehugger Robot     // discovered the cycle, but in order to free the edge bitmaps
2627*16467b97STreehugger Robot     // we need to know how many we may have allocated and traverse them all.
2628*16467b97STreehugger Robot     //
2629*16467b97STreehugger Robot     topo->limit = oldLimit;
2630*16467b97STreehugger Robot 
2631*16467b97STreehugger Robot     // Having traversed all the nodes we were given, we
2632*16467b97STreehugger Robot     // are guaranteed to have ordered all the nodes or detected a
2633*16467b97STreehugger Robot     // cycle.
2634*16467b97STreehugger Robot     //
2635*16467b97STreehugger Robot     return topo->sorted;
2636*16467b97STreehugger Robot }
2637*16467b97STreehugger Robot 
2638*16467b97STreehugger Robot static  void
sortVector(pANTLR3_TOPO topo,pANTLR3_VECTOR v)2639*16467b97STreehugger Robot sortVector       (pANTLR3_TOPO topo, pANTLR3_VECTOR v)
2640*16467b97STreehugger Robot {
2641*16467b97STreehugger Robot     // To sort a vector, we first perform the
2642*16467b97STreehugger Robot     // sort to an array, then use the results to reorder the vector
2643*16467b97STreehugger Robot     // we are given. This is just a convenience routine that allows you to
2644*16467b97STreehugger Robot     // sort the children of a tree node into topological order before or
2645*16467b97STreehugger Robot     // during an AST walk. This can be useful for optimizations that require
2646*16467b97STreehugger Robot     // dag reorders and also when the input stream defines things that are
2647*16467b97STreehugger Robot     // interdependent and you want to walk the list of the generated trees
2648*16467b97STreehugger Robot     // for those things in topological order so you can ignore the interdependencies
2649*16467b97STreehugger Robot     // at that point.
2650*16467b97STreehugger Robot     //
2651*16467b97STreehugger Robot     ANTLR3_UINT32 i;
2652*16467b97STreehugger Robot 
2653*16467b97STreehugger Robot     // Used as a lookup index to find the current location in the vector of
2654*16467b97STreehugger Robot     // the vector entry that was originally at position [0], [1], [2] etc
2655*16467b97STreehugger Robot     //
2656*16467b97STreehugger Robot     pANTLR3_UINT32  vIndex;
2657*16467b97STreehugger Robot 
2658*16467b97STreehugger Robot     // Sort into an array, then we can use the array that is
2659*16467b97STreehugger Robot     // stored in the topo
2660*16467b97STreehugger Robot     //
2661*16467b97STreehugger Robot     if  (topo->sortToArray(topo) == 0)
2662*16467b97STreehugger Robot     {
2663*16467b97STreehugger Robot         return;     // There were no edges
2664*16467b97STreehugger Robot     }
2665*16467b97STreehugger Robot 
2666*16467b97STreehugger Robot     if  (topo->hasCycle == ANTLR3_TRUE)
2667*16467b97STreehugger Robot     {
2668*16467b97STreehugger Robot         return;  // Do nothing if we detected a cycle
2669*16467b97STreehugger Robot     }
2670*16467b97STreehugger Robot 
2671*16467b97STreehugger Robot     // Ensure that the vector we are sorting is at least as big as the
2672*16467b97STreehugger Robot     // the input sequence we were asked to sort. It does not matter if it is
2673*16467b97STreehugger Robot     // bigger as that probably just means that nodes numbered higher than the
2674*16467b97STreehugger Robot     // limit had no dependencies and so can be left alone.
2675*16467b97STreehugger Robot     //
2676*16467b97STreehugger Robot     if  (topo->limit > v->count)
2677*16467b97STreehugger Robot     {
2678*16467b97STreehugger Robot         // We can only sort the entries that we have dude! The caller is
2679*16467b97STreehugger Robot         // responsible for ensuring the vector is the correct one and is the
2680*16467b97STreehugger Robot         // correct size etc.
2681*16467b97STreehugger Robot         //
2682*16467b97STreehugger Robot         topo->limit = v->count;
2683*16467b97STreehugger Robot     }
2684*16467b97STreehugger Robot     // We need to know the locations of each of the entries
2685*16467b97STreehugger Robot     // in the vector as we don't want to duplicate them in a new vector. We
2686*16467b97STreehugger Robot     // just use an indirection table to get the vector entry for a particular sequence
2687*16467b97STreehugger Robot     // according to where we moved it last. Then we can just swap vector entries until
2688*16467b97STreehugger Robot     // we are done :-)
2689*16467b97STreehugger Robot     //
2690*16467b97STreehugger Robot     vIndex = (pANTLR3_UINT32)ANTLR3_MALLOC(topo->limit * sizeof(ANTLR3_UINT32));
2691*16467b97STreehugger Robot 	if (vIndex == NULL)
2692*16467b97STreehugger Robot 	{
2693*16467b97STreehugger Robot 		// malloc failed
2694*16467b97STreehugger Robot 		return;
2695*16467b97STreehugger Robot 	}
2696*16467b97STreehugger Robot 
2697*16467b97STreehugger Robot     // Start index, each vector entry is located where you think it is
2698*16467b97STreehugger Robot     //
2699*16467b97STreehugger Robot     for (i = 0; i < topo->limit; i++)
2700*16467b97STreehugger Robot     {
2701*16467b97STreehugger Robot         vIndex[i] = i;
2702*16467b97STreehugger Robot     }
2703*16467b97STreehugger Robot 
2704*16467b97STreehugger Robot     // Now we traverse the sorted array and moved the entries of
2705*16467b97STreehugger Robot     // the vector around according to the sort order and the indirection
2706*16467b97STreehugger Robot     // table we just created. The index telsl us where in the vector the
2707*16467b97STreehugger Robot     // original element entry n is now located via vIndex[n].
2708*16467b97STreehugger Robot     //
2709*16467b97STreehugger Robot     for (i=0; i < topo->limit; i++)
2710*16467b97STreehugger Robot     {
2711*16467b97STreehugger Robot         ANTLR3_UINT32   ind;
2712*16467b97STreehugger Robot 
2713*16467b97STreehugger Robot         // If the vector entry at i is already the one that it
2714*16467b97STreehugger Robot         // should be, then we skip moving it of course.
2715*16467b97STreehugger Robot         //
2716*16467b97STreehugger Robot         if  (vIndex[topo->sorted[i]] == i)
2717*16467b97STreehugger Robot         {
2718*16467b97STreehugger Robot             continue;
2719*16467b97STreehugger Robot         }
2720*16467b97STreehugger Robot 
2721*16467b97STreehugger Robot         // The vector entry at i, should be replaced with the
2722*16467b97STreehugger Robot         // vector entry indicated by topo->sorted[i]. The vector entry
2723*16467b97STreehugger Robot         // at topo->sorted[i] may have already been swapped out though, so we
2724*16467b97STreehugger Robot         // find where it is now and move it from there to i.
2725*16467b97STreehugger Robot         //
2726*16467b97STreehugger Robot         ind     = vIndex[topo->sorted[i]];
2727*16467b97STreehugger Robot         v->swap(v, i, ind);
2728*16467b97STreehugger Robot 
2729*16467b97STreehugger Robot         // Update our index. The element at i is now the one we wanted
2730*16467b97STreehugger Robot         // to be sorted here and the element we swapped out is now the
2731*16467b97STreehugger Robot         // element that was at i just before we swapped it. If you are lost now
2732*16467b97STreehugger Robot         // don't worry about it, we are just reindexing on the fly is all.
2733*16467b97STreehugger Robot         //
2734*16467b97STreehugger Robot         vIndex[topo->sorted[i]] = i;
2735*16467b97STreehugger Robot         vIndex[i] = ind;
2736*16467b97STreehugger Robot     }
2737*16467b97STreehugger Robot 
2738*16467b97STreehugger Robot     // Having traversed all the entries, we have sorted the vector in place.
2739*16467b97STreehugger Robot     //
2740*16467b97STreehugger Robot     ANTLR3_FREE(vIndex);
2741*16467b97STreehugger Robot     return;
2742*16467b97STreehugger Robot }
2743*16467b97STreehugger Robot 
2744*16467b97STreehugger Robot static  void
freeTopo(pANTLR3_TOPO topo)2745*16467b97STreehugger Robot freeTopo             (pANTLR3_TOPO topo)
2746*16467b97STreehugger Robot {
2747*16467b97STreehugger Robot     ANTLR3_UINT32   i;
2748*16467b97STreehugger Robot 
2749*16467b97STreehugger Robot     // Free the result vector
2750*16467b97STreehugger Robot     //
2751*16467b97STreehugger Robot     if  (topo->sorted != NULL)
2752*16467b97STreehugger Robot     {
2753*16467b97STreehugger Robot         ANTLR3_FREE(topo->sorted);
2754*16467b97STreehugger Robot         topo->sorted = NULL;
2755*16467b97STreehugger Robot     }
2756*16467b97STreehugger Robot 
2757*16467b97STreehugger Robot     // Free the visited map
2758*16467b97STreehugger Robot     //
2759*16467b97STreehugger Robot     if  (topo->visited != NULL)
2760*16467b97STreehugger Robot     {
2761*16467b97STreehugger Robot 
2762*16467b97STreehugger Robot         topo->visited->free(topo->visited);
2763*16467b97STreehugger Robot         topo->visited = NULL;
2764*16467b97STreehugger Robot     }
2765*16467b97STreehugger Robot 
2766*16467b97STreehugger Robot     // Free any edgemaps
2767*16467b97STreehugger Robot     //
2768*16467b97STreehugger Robot     if  (topo->edges != NULL)
2769*16467b97STreehugger Robot     {
2770*16467b97STreehugger Robot         pANTLR3_BITSET edgeList;
2771*16467b97STreehugger Robot 
2772*16467b97STreehugger Robot 
2773*16467b97STreehugger Robot         for (i=0; i<topo->limit; i++)
2774*16467b97STreehugger Robot         {
2775*16467b97STreehugger Robot             edgeList = *((topo->edges) + i);
2776*16467b97STreehugger Robot             if  (edgeList != NULL)
2777*16467b97STreehugger Robot             {
2778*16467b97STreehugger Robot                 edgeList->free(edgeList);
2779*16467b97STreehugger Robot             }
2780*16467b97STreehugger Robot         }
2781*16467b97STreehugger Robot 
2782*16467b97STreehugger Robot         ANTLR3_FREE(topo->edges);
2783*16467b97STreehugger Robot     }
2784*16467b97STreehugger Robot     topo->edges = NULL;
2785*16467b97STreehugger Robot 
2786*16467b97STreehugger Robot     // Free any cycle map
2787*16467b97STreehugger Robot     //
2788*16467b97STreehugger Robot     if  (topo->cycle != NULL)
2789*16467b97STreehugger Robot     {
2790*16467b97STreehugger Robot         ANTLR3_FREE(topo->cycle);
2791*16467b97STreehugger Robot     }
2792*16467b97STreehugger Robot 
2793*16467b97STreehugger Robot     ANTLR3_FREE(topo);
2794*16467b97STreehugger Robot }
2795