1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// \file 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Provides a number of useful functions that are roughly equivalent 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// to java HashTable and List for the purposes of Antlr 3 C runtime. 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Also useable by the C programmer for things like symbol tables pointers 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// and so on. 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// [The "BSD licence"] 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// http://www.temporal-wave.com 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// http://www.linkedin.com/in/jimidle 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// All rights reserved. 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Redistribution and use in source and binary forms, with or without 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// modification, are permitted provided that the following conditions 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// are met: 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 1. Redistributions of source code must retain the above copyright 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// notice, this list of conditions and the following disclaimer. 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 2. Redistributions in binary form must reproduce the above copyright 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// notice, this list of conditions and the following disclaimer in the 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// documentation and/or other materials provided with the distribution. 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 3. The name of the author may not be used to endorse or promote products 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// derived from this software without specific prior written permission. 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <antlr3.h> 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "antlr3collections.h" 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Interface functions for hash table 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// String based keys 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void antlr3HashDelete (pANTLR3_HASH_TABLE table, void * key); 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * antlr3HashGet (pANTLR3_HASH_TABLE table, void * key); 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_HASH_ENTRY antlr3HashRemove (pANTLR3_HASH_TABLE table, void * key); 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_INT32 antlr3HashPut (pANTLR3_HASH_TABLE table, void * key, void * element, void (ANTLR3_CDECL *freeptr)(void *)); 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Integer based keys (Lists and so on) 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void antlr3HashDeleteI (pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key); 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * antlr3HashGetI (pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key); 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_HASH_ENTRY antlr3HashRemoveI (pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key); 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_INT32 antlr3HashPutI (pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key, void * element, void (ANTLR3_CDECL *freeptr)(void *)); 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void antlr3HashFree (pANTLR3_HASH_TABLE table); 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 antlr3HashSize (pANTLR3_HASH_TABLE table); 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// ----------- 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Interface functions for enumeration 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic int antlr3EnumNext (pANTLR3_HASH_ENUM en, pANTLR3_HASH_KEY * key, void ** data); 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void antlr3EnumFree (pANTLR3_HASH_ENUM en); 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Interface functions for List 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void antlr3ListFree (pANTLR3_LIST list); 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void antlr3ListDelete(pANTLR3_LIST list, ANTLR3_INTKEY key); 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * antlr3ListGet (pANTLR3_LIST list, ANTLR3_INTKEY key); 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_INT32 antlr3ListPut (pANTLR3_LIST list, ANTLR3_INTKEY key, void * element, void (ANTLR3_CDECL *freeptr)(void *)); 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_INT32 antlr3ListAdd (pANTLR3_LIST list, void * element, void (ANTLR3_CDECL *freeptr)(void *)); 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * antlr3ListRemove(pANTLR3_LIST list, ANTLR3_INTKEY key); 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 antlr3ListSize (pANTLR3_LIST list); 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Interface functions for Stack 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void antlr3StackFree (pANTLR3_STACK stack); 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * antlr3StackPop (pANTLR3_STACK stack); 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * antlr3StackGet (pANTLR3_STACK stack, ANTLR3_INTKEY key); 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN antlr3StackPush (pANTLR3_STACK stack, void * element, void (ANTLR3_CDECL *freeptr)(void *)); 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 antlr3StackSize (pANTLR3_STACK stack); 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * antlr3StackPeek (pANTLR3_STACK stack); 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Interface functions for vectors 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void ANTLR3_CDECL antlr3VectorFree (pANTLR3_VECTOR vector); 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void antlr3VectorDel (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry); 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * antlr3VectorGet (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry); 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * antrl3VectorRemove (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry); 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void antlr3VectorClear (pANTLR3_VECTOR vector); 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 antlr3VectorAdd (pANTLR3_VECTOR vector, void * element, void (ANTLR3_CDECL *freeptr)(void *)); 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 antlr3VectorSet (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry, void * element, void (ANTLR3_CDECL *freeptr)(void *), ANTLR3_BOOLEAN freeExisting); 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 antlr3VectorSize (pANTLR3_VECTOR vector); 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN antlr3VectorSwap (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry1, ANTLR3_UINT32 entry2); 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void newPool (pANTLR3_VECTOR_FACTORY factory); 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void closeVectorFactory (pANTLR3_VECTOR_FACTORY factory); 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_VECTOR newVector (pANTLR3_VECTOR_FACTORY factory); 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void returnVector (pANTLR3_VECTOR_FACTORY factory, pANTLR3_VECTOR vector); 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Interface functions for int TRIE 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_TRIE_ENTRY intTrieGet (pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key); 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN intTrieDel (pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key); 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN intTrieAdd (pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key, ANTLR3_UINT32 type, ANTLR3_INTKEY intType, void * data, void (ANTLR3_CDECL *freeptr)(void *)); 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void intTrieFree (pANTLR3_INT_TRIE trie); 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Interface functions for topological sorter 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void addEdge (pANTLR3_TOPO topo, ANTLR3_UINT32 edge, ANTLR3_UINT32 dependency); 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_UINT32 sortToArray (pANTLR3_TOPO topo); 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void sortVector (pANTLR3_TOPO topo, pANTLR3_VECTOR v); 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void freeTopo (pANTLR3_TOPO topo); 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Local function to advance enumeration structure pointers 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void antlr3EnumNextEntry(pANTLR3_HASH_ENUM en); 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 125324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverpANTLR3_HASH_TABLE 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3HashTableNew(ANTLR3_UINT32 sizeHint) 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // All we have to do is create the hashtable tracking structure 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // and allocate memory for the requested number of buckets. 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_TABLE table; 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 bucket; // Used to traverse the buckets 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table = ANTLR3_MALLOC(sizeof(ANTLR3_HASH_TABLE)); 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Error out if no memory left 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (table == NULL) 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Allocate memory for the buckets 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->buckets = (pANTLR3_HASH_BUCKET) ANTLR3_MALLOC((size_t) (sizeof(ANTLR3_HASH_BUCKET) * sizeHint)); 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (table->buckets == NULL) 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE((void *)table); 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Modulo of the table, (bucket count). 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->modulo = sizeHint; 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->count = 0; /* Nothing in there yet ( I hope) */ 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Initialize the buckets to empty 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (bucket = 0; bucket < sizeHint; bucket++) 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->buckets[bucket].entries = NULL; 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Exclude duplicate entries by default 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->allowDups = ANTLR3_FALSE; 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Assume that keys should by strduped before they are 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * entered in the table. 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->doStrdup = ANTLR3_TRUE; 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Install the interface 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->get = antlr3HashGet; 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->put = antlr3HashPut; 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->del = antlr3HashDelete; 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->remove = antlr3HashRemove; 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->getI = antlr3HashGetI; 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->putI = antlr3HashPutI; 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->delI = antlr3HashDeleteI; 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->removeI = antlr3HashRemoveI; 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->size = antlr3HashSize; 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->free = antlr3HashFree; 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return table; 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3HashFree(pANTLR3_HASH_TABLE table) 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 bucket; /* Used to traverse the buckets */ 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_BUCKET thisBucket; 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY entry; 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY nextEntry; 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Free the table, all buckets and all entries, and all the 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * keys and data (if the table exists) 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (table != NULL) 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (bucket = 0; bucket < table->modulo; bucket++) 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisBucket = &(table->buckets[bucket]); 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Allow sparse tables, though we don't create them as such at present 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( thisBucket != NULL) 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = thisBucket->entries; 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Search all entries in the bucket and free them up 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (entry != NULL) 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Save next entry - we do not want to access memory in entry after we 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * have freed it. 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextEntry = entry->nextEntry; 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Free any data pointer, this only happens if the user supplied 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * a pointer to a routine that knwos how to free the structure they 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * added to the table. 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry->free != NULL) 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->free(entry->data); 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Free the key memory - we know that we allocated this 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry->keybase.type == ANTLR3_HASH_TYPE_STR && entry->keybase.key.sKey != NULL) 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(entry->keybase.key.sKey); 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Free this entry 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(entry); 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = nextEntry; /* Load next pointer to see if we shoud free it */ 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Invalidate the current pointer 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisBucket->entries = NULL; 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now we can free the bucket memory 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(table->buckets); 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now we free teh memory for the table itself 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(table); 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** return the current size of the hash table 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 antlr3HashSize (pANTLR3_HASH_TABLE table) 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return table->count; 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Remove a numeric keyed entry from a hash table if it exists, 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * no error if it does not exist. 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_HASH_ENTRY antlr3HashRemoveI (pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key) 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 hash; 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_BUCKET bucket; 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY entry; 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY * nextPointer; 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* First we need to know the hash of the provided key 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hash = (ANTLR3_UINT32)(key % (ANTLR3_INTKEY)(table->modulo)); 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Knowing the hash, we can find the bucket 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver bucket = table->buckets + hash; 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now, we traverse the entries in the bucket until 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we find the key or the end of the entries in the bucket. 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * We track the element prior to the one we are examining 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * as we need to set its next pointer to the next pointer 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * of the entry we are deleting (if we find it). 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = bucket->entries; /* Entry to examine */ 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextPointer = & bucket->entries; /* Where to put the next pointer of the deleted entry */ 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (entry != NULL) 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* See if this is the entry we wish to delete 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry->keybase.key.iKey == key) 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* It was the correct entry, so we set the next pointer 305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * of the previous entry to the next pointer of this 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * located one, which takes it out of the chain. 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver (*nextPointer) = entry->nextEntry; 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->count--; 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return entry; 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We found an entry but it wasn't the one that was wanted, so 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * move to the next one, if any. 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextPointer = & (entry->nextEntry); /* Address of the next pointer in the current entry */ 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = entry->nextEntry; /* Address of the next element in the bucket (if any) */ 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; /* Not found */ 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Remove the element in the hash table for a particular 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * key value, if it exists - no error if it does not. 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_HASH_ENTRY 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3HashRemove(pANTLR3_HASH_TABLE table, void * key) 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 hash; 334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_BUCKET bucket; 335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY entry; 336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY * nextPointer; 337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* First we need to know the hash of the provided key 339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hash = antlr3Hash(key, (ANTLR3_UINT32)strlen((const char *)key)); 341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Knowing the hash, we can find the bucket 343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver bucket = table->buckets + (hash % table->modulo); 345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now, we traverse the entries in the bucket until 347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we find the key or the end of the entires in the bucket. 348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * We track the element prior to the one we are exmaining 349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * as we need to set its next pointer to the next pointer 350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * of the entry we are deleting (if we find it). 351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = bucket->entries; /* Entry to examine */ 353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextPointer = & bucket->entries; /* Where to put the next pointer of the deleted entry */ 354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (entry != NULL) 356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* See if this is the entry we wish to delete 358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (strcmp((const char *)key, (const char *)entry->keybase.key.sKey) == 0) 360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* It was the correct entry, so we set the next pointer 362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * of the previous entry to the next pointer of this 363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * located one, which takes it out of the chain. 364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver (*nextPointer) = entry->nextEntry; 366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Release the key - if we allocated that 368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (table->doStrdup == ANTLR3_TRUE) 370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(entry->keybase.key.sKey); 372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->keybase.key.sKey = NULL; 374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->count--; 376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return entry; 378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We found an entry but it wasn't the one that was wanted, so 382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * move to the next one, if any. 383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextPointer = & (entry->nextEntry); /* Address of the next pointer in the current entry */ 385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = entry->nextEntry; /* Address of the next element in the bucket (if any) */ 386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; /* Not found */ 390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Takes the element with the supplied key out of the list, and deletes the data 393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * calling the supplied free() routine if any. 394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3HashDeleteI (pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key) 397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY entry; 399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = antlr3HashRemoveI(table, key); 401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now we can free the elements and the entry in order 403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry != NULL && entry->free != NULL) 405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Call programmer supplied function to release this entry data 407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->free(entry->data); 409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->data = NULL; 410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Finally release the space for this entry block. 412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(entry); 414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Takes the element with the supplied key out of the list, and deletes the data 417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * calling the supplied free() routine if any. 418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3HashDelete (pANTLR3_HASH_TABLE table, void * key) 421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY entry; 423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = antlr3HashRemove(table, key); 425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now we can free the elements and the entry in order 427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry != NULL && entry->free != NULL) 429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Call programmer supplied function to release this entry data 431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->free(entry->data); 433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->data = NULL; 434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Finally release the space for this entry block. 436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(entry); 438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Return the element pointer in the hash table for a particular 441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * key value, or NULL if it don't exist (or was itself NULL). 442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * 444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3HashGetI(pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key) 445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 hash; 447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_BUCKET bucket; 448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY entry; 449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* First we need to know the hash of the provided key 451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hash = (ANTLR3_UINT32)(key % (ANTLR3_INTKEY)(table->modulo)); 453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Knowing the hash, we can find the bucket 455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver bucket = table->buckets + hash; 457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now we can inspect the key at each entry in the bucket 459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * and see if we have a match. 460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = bucket->entries; 462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (entry != NULL) 464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry->keybase.key.iKey == key) 466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Match was found, return the data pointer for this entry 468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return entry->data; 470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = entry->nextEntry; 472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* If we got here, then we did not find the key 475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Return the element pointer in the hash table for a particular 480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * key value, or NULL if it don't exist (or was itself NULL). 481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * 483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3HashGet(pANTLR3_HASH_TABLE table, void * key) 484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 hash; 486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_BUCKET bucket; 487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY entry; 488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* First we need to know the hash of the provided key 491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hash = antlr3Hash(key, (ANTLR3_UINT32)strlen((const char *)key)); 493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Knowing the hash, we can find the bucket 495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver bucket = table->buckets + (hash % table->modulo); 497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now we can inspect the key at each entry in the bucket 499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * and see if we have a match. 500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = bucket->entries; 502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (entry != NULL) 504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (strcmp((const char *)key, (const char *)entry->keybase.key.sKey) == 0) 506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Match was found, return the data pointer for this entry 508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return entry->data; 510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = entry->nextEntry; 512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* If we got here, then we did not find the key 515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Add the element pointer in to the table, based upon the 520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * hash of the provided key. 521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_INT32 523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3HashPutI(pANTLR3_HASH_TABLE table, ANTLR3_INTKEY key, void * element, void (ANTLR3_CDECL *freeptr)(void *)) 524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 hash; 526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_BUCKET bucket; 527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY entry; 528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY * newPointer; 529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* First we need to know the hash of the provided key 531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hash = (ANTLR3_UINT32)(key % (ANTLR3_INTKEY)(table->modulo)); 533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Knowing the hash, we can find the bucket 535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver bucket = table->buckets + hash; 537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Knowing the bucket, we can traverse the entries until we 539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we find a NULL pointer or we find that this is already 540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * in the table and duplicates were not allowed. 541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newPointer = &bucket->entries; 543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (*newPointer != NULL) 545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* The value at new pointer is pointing to an existing entry. 547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If duplicates are allowed then we don't care what it is, but 548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * must reject this add if the key is the same as the one we are 549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * supplied with. 550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (table->allowDups == ANTLR3_FALSE) 552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ((*newPointer)->keybase.key.iKey == key) 554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_ERR_HASHDUP; 556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Point to the next entry pointer of the current entry we 560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are traversing, if it is NULL we will create our new 561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * structure and point this to it. 562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newPointer = &((*newPointer)->nextEntry); 564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* newPointer is now pointing at the pointer where we need to 567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * add our new entry, so let's crate the entry and add it in. 568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = (pANTLR3_HASH_ENTRY)ANTLR3_MALLOC((size_t)sizeof(ANTLR3_HASH_ENTRY)); 570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry == NULL) 572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_ERR_NOMEM; 574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->data = element; /* Install the data element supplied */ 577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->free = freeptr; /* Function that knows how to release the entry */ 578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->keybase.type = ANTLR3_HASH_TYPE_INT; /* Indicate the key type stored here for when we free */ 579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->keybase.key.iKey = key; /* Record the key value */ 580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->nextEntry = NULL; /* Ensure that the forward pointer ends the chain */ 581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *newPointer = entry; /* Install the next entry in this bucket */ 583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->count++; 585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_SUCCESS; 587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Add the element pointer in to the table, based upon the 591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * hash of the provided key. 592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_INT32 594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3HashPut(pANTLR3_HASH_TABLE table, void * key, void * element, void (ANTLR3_CDECL *freeptr)(void *)) 595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 hash; 597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_BUCKET bucket; 598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY entry; 599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY * newPointer; 600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* First we need to know the hash of the provided key 602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hash = antlr3Hash(key, (ANTLR3_UINT32)strlen((const char *)key)); 604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Knowing the hash, we can find the bucket 606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver bucket = table->buckets + (hash % table->modulo); 608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Knowign the bucket, we can traverse the entries until we 610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we find a NULL pointer ofr we find that this is already 611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * in the table and duplicates were not allowed. 612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newPointer = &bucket->entries; 614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (*newPointer != NULL) 616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* The value at new pointer is pointing to an existing entry. 618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If duplicates are allowed then we don't care what it is, but 619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * must reject this add if the key is the same as the one we are 620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * supplied with. 621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (table->allowDups == ANTLR3_FALSE) 623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (strcmp((const char*) key, (const char *)(*newPointer)->keybase.key.sKey) == 0) 625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_ERR_HASHDUP; 627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Point to the next entry pointer of the current entry we 631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are traversing, if it is NULL we will create our new 632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * structure and point this to it. 633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newPointer = &((*newPointer)->nextEntry); 635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* newPointer is now poiting at the pointer where we need to 638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * add our new entry, so let's crate the entry and add it in. 639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = (pANTLR3_HASH_ENTRY)ANTLR3_MALLOC((size_t)sizeof(ANTLR3_HASH_ENTRY)); 641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry == NULL) 643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_ERR_NOMEM; 645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->data = element; /* Install the data element supplied */ 648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->free = freeptr; /* Function that knows how to release the entry */ 649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->keybase.type = ANTLR3_HASH_TYPE_STR; /* Indicate the key type stored here for free() */ 650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (table->doStrdup == ANTLR3_TRUE) 651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->keybase.key.sKey = ANTLR3_STRDUP(key); /* Record the key value */ 653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->keybase.key.sKey = key; /* Record the key value */ 657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry->nextEntry = NULL; /* Ensure that the forward pointer ends the chain */ 659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *newPointer = entry; /* Install the next entry in this bucket */ 661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver table->count++; 663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_SUCCESS; 665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** \brief Creates an enumeration structure to traverse the hash table. 668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \param table Table to enumerate 670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \return Pointer to enumeration structure. 671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 672324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverpANTLR3_HASH_ENUM 673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3EnumNew (pANTLR3_HASH_TABLE table) 674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENUM en; 676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Allocate structure memory 678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver en = (pANTLR3_HASH_ENUM) ANTLR3_MALLOC((size_t)sizeof(ANTLR3_HASH_ENUM)); 680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Check that the allocation was good 682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (en == NULL) 684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (pANTLR3_HASH_ENUM) ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); 686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Initialize the start pointers 689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver en->table = table; 691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver en->bucket = 0; /* First bucket */ 692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver en->entry = en->table->buckets->entries; /* First entry to return */ 693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Special case in that the first bucket may not have anything in it 695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * but the antlr3EnumNext() function expects that the en->entry is 696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * set to the next valid pointer. Hence if it is not a valid element 697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * pointer, attempt to find the next one that is, (table may be empty 698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * of course. 699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (en->entry == NULL) 701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver antlr3EnumNextEntry(en); 703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Install the interface 706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver en->free = antlr3EnumFree; 708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver en->next = antlr3EnumNext; 709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* All is good 711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return en; 713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** \brief Return the next entry in the hashtable being traversed by the supplied 716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * enumeration. 717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \param[in] en Pointer to the enumeration tracking structure 719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \param key Pointer to void pointer, where the key pointer is returned. 720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \param data Pointer to void pointer where the data pointer is returned. 721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \return 722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * - ANTLR3_SUCCESS if there was a next key 723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * - ANTLR3_FAIL if there were no more keys 724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \remark 726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * No checking of input structure is performed! 727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic int 729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3EnumNext (pANTLR3_HASH_ENUM en, pANTLR3_HASH_KEY * key, void ** data) 730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* If the current entry is valid, then use it 732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (en->bucket >= en->table->modulo) 734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Already exhausted the table 736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_FAIL; 738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Pointers are already set to the current entry to return, or 741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we would not be at this point in the logic flow. 742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *key = &(en->entry->keybase); 744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *data = en->entry->data; 745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Return pointers are set up, so now we move the element 747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * pointer to the next in the table (if any). 748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver antlr3EnumNextEntry(en); 750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_SUCCESS; 752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** \brief Local function to advance the entry pointer of an enumeration 755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * structure to the next valid entry (if there is one). 756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \param[in] enum Pointer to ANTLR3 enumeration structure returned by antlr3EnumNew() 758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \remark 760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * - The function always leaves the pointers pointing at a valid entry if there 761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * is one, so if the entry pointer is NULL when this function exits, there were 762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * no more entries in the table. 763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3EnumNextEntry(pANTLR3_HASH_ENUM en) 766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_BUCKET bucket; 768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* See if the current entry pointer is valid first of all 770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (en->entry != NULL) 772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Current entry was a valid point, see if there is another 774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * one in the chain. 775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (en->entry->nextEntry != NULL) 777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Next entry in the enumeration is just the next entry 779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * in the chain. 780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver en->entry = en->entry->nextEntry; 782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* There were no more entries in the current bucket, if there are 787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * more buckets then chase them until we find an entry. 788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver en->bucket++; 790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (en->bucket < en->table->modulo) 792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* There was one more bucket, see if it has any elements in it 794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver bucket = en->table->buckets + en->bucket; 796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (bucket->entries != NULL) 798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* There was an entry in this bucket, so we can use it 800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * for the next entry in the enumeration. 801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver en->entry = bucket->entries; 803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* There was nothing in the bucket we just examined, move to the 807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * next one. 808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver en->bucket++; 810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Here we have exhausted all buckets and the enumeration pointer will 813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * have its bucket count = table->modulo which signifies that we are done. 814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** \brief Frees up the memory structures that represent a hash table 818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * enumeration. 819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * \param[in] enum Pointer to ANTLR3 enumeration structure returned by antlr3EnumNew() 820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3EnumFree (pANTLR3_HASH_ENUM en) 823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Nothing to check, we just free it. 825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(en); 827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Given an input key of arbitrary length, return a hash value of 830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * it. This can then be used (with suitable modulo) to index other 831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * structures. 832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 833324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3_API ANTLR3_UINT32 834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3Hash(void * key, ANTLR3_UINT32 keylen) 835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Accumulate the hash value of the key 837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 hash; 839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_UINT8 keyPtr; 840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 i1; 841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hash = 0; 843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver keyPtr = (pANTLR3_UINT8) key; 844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Iterate the key and accumulate the hash 846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while(keylen > 0) 848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hash = (hash << 4) + (*(keyPtr++)); 850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ((i1=hash&0xf0000000) != 0) 852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hash = hash ^ (i1 >> 24); 854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hash = hash ^ i1; 855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver keylen--; 857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return hash; 860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 862324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3_API pANTLR3_LIST 863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3ListNew (ANTLR3_UINT32 sizeHint) 864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_LIST list; 866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Allocate memory 868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list = (pANTLR3_LIST)ANTLR3_MALLOC((size_t)sizeof(ANTLR3_LIST)); 870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (list == NULL) 872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (pANTLR3_LIST)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); 874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now we need to add a new table 877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list->table = antlr3HashTableNew(sizeHint); 879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (list->table == (pANTLR3_HASH_TABLE)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM)) 881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (pANTLR3_LIST)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); 883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Allocation was good, install interface 886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list->free = antlr3ListFree; 888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list->del = antlr3ListDelete; 889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list->get = antlr3ListGet; 890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list->add = antlr3ListAdd; 891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list->remove = antlr3ListRemove; 892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list->put = antlr3ListPut; 893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list->size = antlr3ListSize; 894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return list; 896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 antlr3ListSize (pANTLR3_LIST list) 899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return list->table->size(list->table); 901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3ListFree (pANTLR3_LIST list) 905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Free the hashtable that stores the list 907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list->table->free(list->table); 909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Free the allocation for the list itself 911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(list); 913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3ListDelete (pANTLR3_LIST list, ANTLR3_INTKEY key) 917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list->table->delI(list->table, key); 919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * 922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3ListGet (pANTLR3_LIST list, ANTLR3_INTKEY key) 923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return list->table->getI(list->table, key); 925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Add the supplied element to the list, at the next available key 928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_INT32 antlr3ListAdd (pANTLR3_LIST list, void * element, void (ANTLR3_CDECL *freeptr)(void *)) 930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_INTKEY key; 932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 933324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver key = list->table->size(list->table) + 1; 934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return list->put(list, key, element, freeptr); 935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 937324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Remove from the list, but don't free the element, just send it back to the 938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * caller. 939324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * 941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3ListRemove (pANTLR3_LIST list, ANTLR3_INTKEY key) 942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_HASH_ENTRY entry; 944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entry = list->table->removeI(list->table, key); 946324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 947324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry != NULL) 948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return entry->data; 950324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_INT32 958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3ListPut (pANTLR3_LIST list, ANTLR3_INTKEY key, void * element, void (ANTLR3_CDECL *freeptr)(void *)) 959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return list->table->putI(list->table, key, element, freeptr); 961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 963324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3_API pANTLR3_STACK 964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3StackNew (ANTLR3_UINT32 sizeHint) 965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_STACK stack; 967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Allocate memory 969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack = (pANTLR3_STACK)ANTLR3_MALLOC((size_t)sizeof(ANTLR3_STACK)); 971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (stack == NULL) 973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 974324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (pANTLR3_STACK)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); 975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now we need to add a new table 978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->vector = antlr3VectorNew(sizeHint); 980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->top = NULL; 981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (stack->vector == (pANTLR3_VECTOR)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM)) 983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (pANTLR3_STACK)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); 985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Looks good, now add the interface 988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->get = antlr3StackGet; 990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->free = antlr3StackFree; 991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->pop = antlr3StackPop; 992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->push = antlr3StackPush; 993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->size = antlr3StackSize; 994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->peek = antlr3StackPeek; 995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return stack; 997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 antlr3StackSize (pANTLR3_STACK stack) 1000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return stack->vector->count; 1002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 1006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3StackFree (pANTLR3_STACK stack) 1007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1008324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Free the list that supports the stack 1009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->vector->free(stack->vector); 1011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->vector = NULL; 1012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->top = NULL; 1013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(stack); 1015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * 1018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3StackPop (pANTLR3_STACK stack) 1019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Delete the element that is currently at the top of the stack 1021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->vector->del(stack->vector, stack->vector->count - 1); 1023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // And get the element that is the now the top of the stack (if anything) 1025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // NOTE! This is not quite like a 'real' stack, which would normally return you 1026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // the current top of the stack, then remove it from the stack. 1027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // TODO: Review this, it is correct for follow sets which is what this was done for 1028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // but is not as obvious when using it as a 'real'stack. 1029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->top = stack->vector->get(stack->vector, stack->vector->count - 1); 1031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return stack->top; 1032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * 1035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3StackGet (pANTLR3_STACK stack, ANTLR3_INTKEY key) 1036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return stack->vector->get(stack->vector, (ANTLR3_UINT32)key); 1038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * 1041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3StackPeek (pANTLR3_STACK stack) 1042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return stack->top; 1044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN 1047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3StackPush (pANTLR3_STACK stack, void * element, void (ANTLR3_CDECL *freeptr)(void *)) 1048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stack->top = element; 1050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (ANTLR3_BOOLEAN)(stack->vector->add(stack->vector, element, freeptr)); 1051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1053324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3_API pANTLR3_VECTOR 1054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3VectorNew (ANTLR3_UINT32 sizeHint) 1055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_VECTOR vector; 1057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Allocate memory for the vector structure itself 1060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector = (pANTLR3_VECTOR) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_VECTOR))); 1062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (vector == NULL) 1064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (pANTLR3_VECTOR)ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); 1066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Now fill in the defaults 1069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver antlr3SetVectorApi(vector, sizeHint); 1071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // And everything is hunky dory 1073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return vector; 1075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1077324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3_API void 1078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3SetVectorApi (pANTLR3_VECTOR vector, ANTLR3_UINT32 sizeHint) 1079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 initialSize; 1081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Allow vectors to be guessed by ourselves, so input size can be zero 1083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (sizeHint > ANTLR3_VECTOR_INTERNAL_SIZE) 1085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver initialSize = sizeHint; 1087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver initialSize = ANTLR3_VECTOR_INTERNAL_SIZE; 1091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (sizeHint > ANTLR3_VECTOR_INTERNAL_SIZE) 1094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements = (pANTLR3_VECTOR_ELEMENT)ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_VECTOR_ELEMENT) * initialSize)); 1096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements = vector->internal; 1100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (vector->elements == NULL) 1103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(vector); 1105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 1106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Memory allocated successfully 1109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->count = 0; // No entries yet of course 1111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elementsSize = initialSize; // Available entries 1112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Now we can install the API 1114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->add = antlr3VectorAdd; 1116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->del = antlr3VectorDel; 1117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->get = antlr3VectorGet; 1118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->free = antlr3VectorFree; 1119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->set = antlr3VectorSet; 1120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->remove = antrl3VectorRemove; 1121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->clear = antlr3VectorClear; 1122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->size = antlr3VectorSize; 1123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->swap = antlr3VectorSwap; 1124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Assume that this is not a factory made vector 1126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->factoryMade = ANTLR3_FALSE; 1128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Clear the entries in a vector. 1131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Clearing the vector leaves its capacity the same but 1132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// it walks the entries first to see if any of them 1133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// have a free routine that must be called. 1134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 1135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 1136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3VectorClear (pANTLR3_VECTOR vector) 1137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 entry; 1139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We must traverse every entry in the vector and if it has 1141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // a pointer to a free function then we call it with the 1142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // the entry pointer 1143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (entry = 0; entry < vector->count; entry++) 1145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (vector->elements[entry].freeptr != NULL) 1147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].freeptr(vector->elements[entry].element); 1149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].freeptr = NULL; 1151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].element = NULL; 1152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Having called any free pointers, we just reset the entry count 1155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // back to zero. 1156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->count = 0; 1158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic 1161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid ANTLR3_CDECL antlr3VectorFree (pANTLR3_VECTOR vector) 1162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 entry; 1164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We must traverse every entry in the vector and if it has 1166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // a pointer to a free function then we call it with the 1167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // the entry pointer 1168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (entry = 0; entry < vector->count; entry++) 1170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (vector->elements[entry].freeptr != NULL) 1172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].freeptr(vector->elements[entry].element); 1174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].freeptr = NULL; 1176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].element = NULL; 1177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (vector->factoryMade == ANTLR3_FALSE) 1180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // The entries are freed, so free the element allocation 1182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (vector->elementsSize > ANTLR3_VECTOR_INTERNAL_SIZE) 1184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(vector->elements); 1186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements = NULL; 1188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Finally, free the allocation for the vector itself 1190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(vector); 1192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void antlr3VectorDel (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry) 1196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Check this is a valid request first 1198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry >= vector->count) 1200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 1202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Valid request, check for free pointer and call it if present 1205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (vector->elements[entry].freeptr != NULL) 1207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].freeptr(vector->elements[entry].element); 1209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].freeptr = NULL; 1210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry == vector->count - 1) 1213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Ensure the pointer is never reused by accident, but otherwise just 1215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // decrement the pointer. 1216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].element = NULL; 1218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Need to shuffle trailing pointers back over the deleted entry 1222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_MEMMOVE(vector->elements + entry, vector->elements + entry + 1, sizeof(ANTLR3_VECTOR_ELEMENT) * (vector->count - entry - 1)); 1224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // One less entry in the vector now 1227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->count--; 1229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * antlr3VectorGet (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry) 1232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Ensure this is a valid request 1234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry < vector->count) 1236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return vector->elements[entry].element; 1238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // I know nothing, Mr. Fawlty! 1242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 1244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Remove the entry from the vector, but do not free any entry, even if it has 1248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// a free pointer. 1249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// 1250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void * antrl3VectorRemove (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry) 1251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver void * element; 1253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Check this is a valid request first 1255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry >= vector->count) 1257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 1259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Valid request, return the sorted pointer 1262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver element = vector->elements[entry].element; 1265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry == vector->count - 1) 1267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Ensure the pointer is never reused by accident, but otherwise just 1269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // decrement the pointer. 1270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /// 1271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].element = NULL; 1272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].freeptr = NULL; 1273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Need to shuffle trailing pointers back over the deleted entry 1277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_MEMMOVE(vector->elements + entry, vector->elements + entry + 1, sizeof(ANTLR3_VECTOR_ELEMENT) * (vector->count - entry - 1)); 1279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // One less entry in the vector now 1282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->count--; 1284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return element; 1286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 1289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3VectorResize (pANTLR3_VECTOR vector, ANTLR3_UINT32 hint) 1290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 newSize; 1292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Need to resize the element pointers. We double the allocation 1294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // we already have unless asked for a specific increase. 1295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (hint == 0 || hint < vector->elementsSize) 1297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newSize = vector->elementsSize * 2; 1299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newSize = hint * 2; 1303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Now we know how many we need, so we see if we have just expanded 1306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // past the built in vector elements or were already past that 1307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (vector->elementsSize > ANTLR3_VECTOR_INTERNAL_SIZE) 1309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We were already larger than the internal size, so we just 1311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // use realloc so that the pointers are copied for us 1312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements = (pANTLR3_VECTOR_ELEMENT)ANTLR3_REALLOC(vector->elements, (sizeof(ANTLR3_VECTOR_ELEMENT)* newSize)); 1314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // The current size was less than or equal to the internal array size and as we always start 1318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // with a size that is at least the maximum internal size, then we must need to allocate new memory 1319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // for external pointers. We don't want to take the time to calculate if a requested element 1320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // is part of the internal or external entries, so we copy the internal ones to the new space 1321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements = (pANTLR3_VECTOR_ELEMENT)ANTLR3_MALLOC((sizeof(ANTLR3_VECTOR_ELEMENT)* newSize)); 1323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_MEMCPY(vector->elements, vector->internal, ANTLR3_VECTOR_INTERNAL_SIZE * sizeof(ANTLR3_VECTOR_ELEMENT)); 1324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elementsSize = newSize; 1327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Add the supplied pointer and freeing function pointer to the list, 1330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// expanding the vector if needed. 1331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// 1332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 antlr3VectorAdd (pANTLR3_VECTOR vector, void * element, void (ANTLR3_CDECL *freeptr)(void *)) 1333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Do we need to resize the vector table? 1335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (vector->count == vector->elementsSize) 1337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver antlr3VectorResize(vector, 0); // Give no hint, we let it add 1024 or double it 1339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Insert the new entry 1342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[vector->count].element = element; 1344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[vector->count].freeptr = freeptr; 1345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->count++; // One more element counted 1347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (ANTLR3_UINT32)(vector->count); 1349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Replace the element at the specified entry point with the supplied 1353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// entry. 1354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// 1355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 1356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3VectorSet (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry, void * element, void (ANTLR3_CDECL *freeptr)(void *), ANTLR3_BOOLEAN freeExisting) 1357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // If the vector is currently not big enough, then we expand it 1360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry >= vector->elementsSize) 1362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver antlr3VectorResize(vector, entry); // We will get at least this many 1364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Valid request, replace the current one, freeing any prior entry if told to 1367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( entry < vector->count // If actually replacing an element 1369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver && freeExisting // And told to free any existing element 1370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver && vector->elements[entry].freeptr != NULL // And the existing element has a free pointer 1371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ) 1372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].freeptr(vector->elements[entry].element); 1374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Install the new pointers 1377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].freeptr = freeptr; 1379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry].element = element; 1380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry >= vector->count) 1382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->count = entry + 1; 1384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (ANTLR3_UINT32)(entry); // Indicates the replacement was successful 1386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Replace the element at the specified entry point with the supplied 1390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// entry. 1391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// 1392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN 1393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3VectorSwap (pANTLR3_VECTOR vector, ANTLR3_UINT32 entry1, ANTLR3_UINT32 entry2) 1394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver void * tempEntry; 1397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver void (ANTLR3_CDECL *freeptr)(void *); 1398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // If the vector is currently not big enough, then we do nothing 1400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (entry1 >= vector->elementsSize || entry2 >= vector->elementsSize) 1402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_FALSE; 1404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Valid request, swap them 1407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tempEntry = vector->elements[entry1].element; 1409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver freeptr = vector->elements[entry1].freeptr; 1410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Install the new pointers 1412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry1].freeptr = vector->elements[entry2].freeptr; 1414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry1].element = vector->elements[entry2].element; 1415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry2].freeptr = freeptr; 1417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements[entry2].element = tempEntry; 1418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_TRUE; 1420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT32 antlr3VectorSize (pANTLR3_VECTOR vector) 1424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return vector->count; 1426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#ifdef ANTLR3_WINDOWS 1429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#pragma warning (push) 1430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#pragma warning (disable : 4100) 1431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#endif 1432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// Vector factory creation 1433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/// 1434324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3_API pANTLR3_VECTOR_FACTORY 1435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3VectorFactoryNew (ANTLR3_UINT32 sizeHint) 1436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_VECTOR_FACTORY factory; 1438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Allocate memory for the factory 1440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory = (pANTLR3_VECTOR_FACTORY)ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_VECTOR_FACTORY))); 1442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (factory == NULL) 1444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 1446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Factory memory is good, so create a new vector pool 1449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->pools = NULL; 1451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->thisPool = -1; 1452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newPool(factory); 1454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Initialize the API, ignore the hint as this algorithm does 1456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // a better job really. 1457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver antlr3SetVectorApi(&(factory->unTruc), ANTLR3_VECTOR_INTERNAL_SIZE); 1459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->unTruc.factoryMade = ANTLR3_TRUE; 1461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Install the factory API 1463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->close = closeVectorFactory; 1465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->newVector = newVector; 1466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->returnVector = returnVector; 1467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Create a stack to accumulate reusable vectors 1469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->freeStack = antlr3StackNew(16); 1471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return factory; 1472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#ifdef ANTLR3_WINDOWS 1474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#pragma warning (pop) 1475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#endif 1476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 1478324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverreturnVector (pANTLR3_VECTOR_FACTORY factory, pANTLR3_VECTOR vector) 1479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // First we need to clear out anything that is still in the vector 1481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->clear(vector); 1483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We have a free stack available so we can add the vector we were 1485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // given into the free chain. The vector has to have come from this 1486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // factory, so we already know how to release its memory when it 1487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // dies by virtue of the factory being closed. 1488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->freeStack->push(factory->freeStack, vector, NULL); 1490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // TODO: remove this line once happy printf("Returned vector %08X to the pool, stack size is %d\n", vector, factory->freeStack->size(factory->freeStack)); 1492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 1495324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvernewPool(pANTLR3_VECTOR_FACTORY factory) 1496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Increment factory count 1498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->thisPool++; 1500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Ensure we have enough pointers allocated 1502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->pools = (pANTLR3_VECTOR *) 1504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_REALLOC( (void *)factory->pools, /* Current pools pointer (starts at NULL) */ 1505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver (ANTLR3_UINT32)((factory->thisPool + 1) * sizeof(pANTLR3_VECTOR *)) /* Memory for new pool pointers */ 1506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ); 1507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Allocate a new pool for the factory 1509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->pools[factory->thisPool] = 1511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver (pANTLR3_VECTOR) 1512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_VECTOR) * ANTLR3_FACTORY_VPOOL_SIZE)); 1513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Reset the counters 1516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->nextVector = 0; 1518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Done 1520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 1522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 1525324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvercloseVectorFactory (pANTLR3_VECTOR_FACTORY factory) 1526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_VECTOR pool; 1528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_INT32 poolCount; 1529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 limit; 1530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 vector; 1531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_VECTOR check; 1532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // First see if we have a free chain stack to release? 1534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (factory->freeStack != NULL) 1536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->freeStack->free(factory->freeStack); 1538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We iterate the vector pools one at a time 1541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (poolCount = 0; poolCount <= factory->thisPool; poolCount++) 1543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Pointer to current pool 1545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pool = factory->pools[poolCount]; 1547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Work out how many tokens we need to check in this pool. 1549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver limit = (poolCount == factory->thisPool ? factory->nextVector : ANTLR3_FACTORY_VPOOL_SIZE); 1551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Marginal condition, we might be at the start of a brand new pool 1553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * where the nextToken is 0 and nothing has been allocated. 1554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (limit > 0) 1556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We have some vectors allocated from this pool 1558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (vector = 0; vector < limit; vector++) 1560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Next one in the chain 1562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver check = pool + vector; 1564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Call the free function on each of the vectors in the pool, 1566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // which in turn will cause any elements it holds that also have a free 1567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // pointer to be freed. However, because any vector may be in any other 1568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // vector, we don't free the element allocations yet. We do that in a 1569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // a specific pass, coming up next. The vector free function knows that 1570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // this is a factory allocated pool vector and so it won't free things it 1571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // should not. 1572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver check->free(check); 1574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We iterate the vector pools one at a time once again, but this time 1579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we are going to free up any allocated element pointers. Note that we are doing this 1580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * so that we do not try to release vectors twice. When building ASTs we just copy 1581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the vectors all over the place and they may be embedded in this vector pool 1582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * numerous times. 1583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (poolCount = 0; poolCount <= factory->thisPool; poolCount++) 1585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Pointer to current pool 1587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pool = factory->pools[poolCount]; 1589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Work out how many tokens we need to check in this pool. 1591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver limit = (poolCount == factory->thisPool ? factory->nextVector : ANTLR3_FACTORY_VPOOL_SIZE); 1593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Marginal condition, we might be at the start of a brand new pool 1595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * where the nextToken is 0 and nothing has been allocated. 1596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (limit > 0) 1598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We have some vectors allocated from this pool 1600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (vector = 0; vector < limit; vector++) 1602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Next one in the chain 1604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver check = pool + vector; 1606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Anything in here should be factory made, but we do this just 1608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // to triple check. We just free up the elements if they were 1609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // allocated beyond the internal size. 1610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (check->factoryMade == ANTLR3_TRUE && check->elementsSize > ANTLR3_VECTOR_INTERNAL_SIZE) 1612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(check->elements); 1614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver check->elements = NULL; 1615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We can now free this pool allocation as we have called free on every element in every vector 1620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // and freed any memory for pointers the grew beyond the internal size limit. 1621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(factory->pools[poolCount]); 1623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->pools[poolCount] = NULL; 1624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* All the pools are deallocated we can free the pointers to the pools 1627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * now. 1628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(factory->pools); 1630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Finally, we can free the space for the factory itself 1632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(factory); 1634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_VECTOR 1638324c4644fee44b9898524c09511bd33c3f12e2dfBen GruvernewVector(pANTLR3_VECTOR_FACTORY factory) 1639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_VECTOR vector; 1641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // If we have anything on the re claim stack, reuse it 1643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector = factory->freeStack->peek(factory->freeStack); 1645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (vector != NULL) 1647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Cool we got something we could reuse 1649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->freeStack->pop(factory->freeStack); 1651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // TODO: remove this line once happy printf("Reused vector %08X from stack, size is now %d\n", vector, factory->freeStack->size(factory->freeStack)); 1653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return vector; 1654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // See if we need a new vector pool before allocating a new 1658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // one 1659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (factory->nextVector >= ANTLR3_FACTORY_VPOOL_SIZE) 1661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We ran out of vectors in the current pool, so we need a new pool 1663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newPool(factory); 1665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Assuming everything went well (we are trying for performance here so doing minimal 1668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // error checking. Then we can work out what the pointer is to the next vector. 1669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector = factory->pools[factory->thisPool] + factory->nextVector; 1671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver factory->nextVector++; 1672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We have our token pointer now, so we can initialize it to the predefined model. 1674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver antlr3SetVectorApi(vector, ANTLR3_VECTOR_INTERNAL_SIZE); 1676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->factoryMade = ANTLR3_TRUE; 1677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We know that the pool vectors are created at the default size, which means they 1679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // will start off using their internal entry pointers. We must intialize our pool vector 1680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // to point to its own internal entry table and not the pre-made one. 1681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vector->elements = vector->internal; 1683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // TODO: remove this line once happy printf("Used a new vector at %08X from the pools as nothing on the reusue stack\n", vector); 1685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // And we are done 1687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 1688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return vector; 1689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Array of left most significant bit positions for an 8 bit 1692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * element provides an efficient way to find the highest bit 1693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * that is set in an n byte value (n>0). Assuming the values will all hit the data cache, 1694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * coding without conditional elements should allow branch 1695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * prediction to work well and of course a parallel instruction cache 1696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * will whip through this. Otherwise we must loop shifting a one 1697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * bit and masking. The values we tend to be placing in out integer 1698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * patricia trie are usually a lot lower than the 64 bits we 1699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * allow for the key allows. Hence there is a lot of redundant looping and 1700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * shifting in a while loop. Whereas, the lookup table is just 1701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * a few ands and indirect lookups, while testing for 0. This 1702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * is likely to be done in parallel on many processors available 1703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * when I wrote this. If this code survives as long as yacc, then 1704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * I may already be dead by the time you read this and maybe there is 1705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * a single machine instruction to perform the operation. What 1706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * else are you going to do with all those transistors? Jim 2007 1707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * The table is probably obvious but it is just the number 0..7 1709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * of the MSB in each integer value 0..256 1710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT8 bitIndex[256] = 1712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0, // 0 - Just for padding 1714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0, // 1 1715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1, 1, // 2..3 1716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2, 2, 2, 2, // 4..7 1717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 3, 3, 3, 3, 3, 3, 3, 3, // 8+ 1718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 16+ 1719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 32+ 1720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 64+ 1722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 128+ 1726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 1733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 1734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Rather than use the bit index of a trie node to shift 1736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 0x01 left that many times, then & with the result, it is 1737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * faster to use the bit index as an index into this table 1738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * which holds precomputed masks for any of the 64 bits 1739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we need to mask off singly. The data values will stay in 1740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * cache while ever a trie is in heavy use, such as in 1741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * memoization. It is also pretty enough to be ASCII art. 1742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_UINT64 bitMask[64] = 1744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000004ULL, 0x0000000000000008ULL, 1746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000000000000010ULL, 0x0000000000000020ULL, 0x0000000000000040ULL, 0x0000000000000080ULL, 1747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000000000000100ULL, 0x0000000000000200ULL, 0x0000000000000400ULL, 0x0000000000000800ULL, 1748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000000000001000ULL, 0x0000000000002000ULL, 0x0000000000004000ULL, 0x0000000000008000ULL, 1749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000000000010000ULL, 0x0000000000020000ULL, 0x0000000000040000ULL, 0x0000000000080000ULL, 1750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000000000100000ULL, 0x0000000000200000ULL, 0x0000000000400000ULL, 0x0000000000800000ULL, 1751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000000001000000ULL, 0x0000000002000000ULL, 0x0000000004000000ULL, 0x0000000008000000ULL, 1752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000000010000000ULL, 0x0000000020000000ULL, 0x0000000040000000ULL, 0x0000000080000000ULL, 1753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000000100000000ULL, 0x0000000200000000ULL, 0x0000000400000000ULL, 0x0000000800000000ULL, 1754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000001000000000ULL, 0x0000002000000000ULL, 0x0000004000000000ULL, 0x0000008000000000ULL, 1755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000010000000000ULL, 0x0000020000000000ULL, 0x0000040000000000ULL, 0x0000080000000000ULL, 1756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0000100000000000ULL, 0x0000200000000000ULL, 0x0000400000000000ULL, 0x0000800000000000ULL, 1757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0001000000000000ULL, 0x0002000000000000ULL, 0x0004000000000000ULL, 0x0008000000000000ULL, 1758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0010000000000000ULL, 0x0020000000000000ULL, 0x0040000000000000ULL, 0x0080000000000000ULL, 1759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x0100000000000000ULL, 0x0200000000000000ULL, 0x0400000000000000ULL, 0x0800000000000000ULL, 1760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 0x1000000000000000ULL, 0x2000000000000000ULL, 0x4000000000000000ULL, 0x8000000000000000ULL 1761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}; 1762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/* INT TRIE Implementation of depth 64 bits, being the number of bits 1764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * in a 64 bit integer. 1765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1767324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverpANTLR3_INT_TRIE 1768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3IntTrieNew(ANTLR3_UINT32 depth) 1769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_INT_TRIE trie; 1771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie = (pANTLR3_INT_TRIE) ANTLR3_CALLOC(1, sizeof(ANTLR3_INT_TRIE)); /* Base memory required */ 1773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (trie == NULL) 1775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (pANTLR3_INT_TRIE) ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); 1777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now we need to allocate the root node. This makes it easier 1780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * to use the tree as we don't have to do anything special 1781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * for the root node. 1782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie->root = (pANTLR3_INT_TRIE_NODE) ANTLR3_CALLOC(1, sizeof(ANTLR3_INT_TRIE)); 1784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (trie->root == NULL) 1786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(trie); 1788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (pANTLR3_INT_TRIE) ANTLR3_FUNC_PTR(ANTLR3_ERR_NOMEM); 1789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie->add = intTrieAdd; 1792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie->del = intTrieDel; 1793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie->free = intTrieFree; 1794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie->get = intTrieGet; 1795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now we seed the root node with the index being the 1797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * highest left most bit we want to test, which limits the 1798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * keys in the trie. This is the trie 'depth'. The limit for 1799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * this implementation is 63 (bits 0..63). 1800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie->root->bitNum = depth; 1802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* And as we have nothing in here yet, we set both child pointers 1804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * of the root node to point back to itself. 1805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie->root->leftN = trie->root; 1807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie->root->rightN = trie->root; 1808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie->count = 0; 1809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Finally, note that the key for this root node is 0 because 1811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we use calloc() to initialise it. 1812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return trie; 1815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Search the int Trie and return a pointer to the first bucket indexed 1818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * by the key if it is contained in the trie, otherwise NULL. 1819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_TRIE_ENTRY 1821324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverintTrieGet (pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key) 1822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_INT_TRIE_NODE thisNode; 1824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_INT_TRIE_NODE nextNode; 1825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (trie->count == 0) 1827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; /* Nothing in this trie yet */ 1829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Starting at the root node in the trie, compare the bit index 1831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * of the current node with its next child node (starts left from root). 1832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * When the bit index of the child node is greater than the bit index of the current node 1833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * then by definition (as the bit index decreases as we descent the trie) 1834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we have reached a 'backward' pointer. A backward pointer means we 1835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * have reached the only node that can be reached by the bits given us so far 1836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * and it must either be the key we are looking for, or if not then it 1837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * means the entry was not in the trie, and we return NULL. A backward pointer 1838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * points back in to the tree structure rather than down (deeper) within the 1839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * tree branches. 1840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisNode = trie->root; /* Start at the root node */ 1842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode = thisNode->leftN; /* Examine the left node from the root */ 1843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* While we are descending the tree nodes... 1845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (thisNode->bitNum > nextNode->bitNum) 1847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Next node now becomes the new 'current' node 1849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisNode = nextNode; 1851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We now test the bit indicated by the bitmap in the next node 1853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * in the key we are searching for. The new next node is the 1854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * right node if that bit is set and the left node it is not. 1855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (key & bitMask[nextNode->bitNum]) 1857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode = nextNode->rightN; /* 1 is right */ 1859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode = nextNode->leftN; /* 0 is left */ 1863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Here we have reached a node where the bitMap index is lower than 1867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * its parent. This means it is pointing backward in the tree and 1868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * must therefore be a terminal node, being the only point than can 1869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * be reached with the bits seen so far. It is either the actual key 1870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we wanted, or if that key is not in the trie it is another key 1871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * that is currently the only one that can be reached by those bits. 1872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * That situation would obviously change if the key was to be added 1873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * to the trie. 1874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Hence it only remains to test whether this is actually the key or not. 1876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (nextNode->key == key) 1878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* This was the key, so return the entry pointer 1880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return nextNode->buckets; 1882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; /* That key is not in the trie (note that we set the pointer to -1 if no payload) */ 1886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN 1891324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverintTrieDel (pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key) 1892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_INT_TRIE_NODE p; 1894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver p=trie->root; 1896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver key = key; 1897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_FALSE; 1899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 1900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Add an entry into the INT trie. 1902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Basically we descend the trie as we do when searching it, which will 1903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * locate the only node in the trie that can be reached by the bit pattern of the 1904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * key. If the key is actually at that node, then if the trie accepts duplicates 1905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we add the supplied data in a new chained bucket to that data node. If it does 1906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * not accept duplicates then we merely return FALSE in case the caller wants to know 1907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * whether the key was already in the trie. 1908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If the node we locate is not the key we are looking to add, then we insert a new node 1909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * into the trie with a bit index of the leftmost differing bit and the left or right 1910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * node pointing to itself or the data node we are inserting 'before'. 1911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic ANTLR3_BOOLEAN 1913324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverintTrieAdd (pANTLR3_INT_TRIE trie, ANTLR3_INTKEY key, ANTLR3_UINT32 type, ANTLR3_INTKEY intVal, void * data, void (ANTLR3_CDECL *freeptr)(void *)) 1914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 1915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_INT_TRIE_NODE thisNode; 1916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_INT_TRIE_NODE nextNode; 1917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_INT_TRIE_NODE entNode; 1918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 depth; 1919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_TRIE_ENTRY newEnt; 1920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_TRIE_ENTRY nextEnt; 1921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_INTKEY xorKey; 1922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Cache the bit depth of this trie, which is always the highest index, 1924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * which is in the root node 1925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver depth = trie->root->bitNum; 1927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisNode = trie->root; /* Start with the root node */ 1929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode = trie->root->leftN; /* And assume we start to the left */ 1930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now find the only node that can be currently reached by the bits in the 1932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * key we are being asked to insert. 1933324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (thisNode->bitNum > nextNode->bitNum) 1935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Still descending the structure, next node becomes current. 1937324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisNode = nextNode; 1939324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (key & bitMask[nextNode->bitNum]) 1941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Bit at the required index was 1, so travers the right node from here 1943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode = nextNode->rightN; 1945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1946324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1947324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Bit at the required index was 0, so we traverse to the left 1949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1950324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode = nextNode->leftN; 1951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Here we have located the only node that can be reached by the 1954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * bits in the requested key. It could in fact be that key or the node 1955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we need to use to insert the new key. 1956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (nextNode->key == key) 1958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We have located an exact match, but we will only append to the bucket chain 1960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * if this trie accepts duplicate keys. 1961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (trie->allowDups ==ANTLR3_TRUE) 1963324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Yes, we are accepting duplicates 1965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newEnt = (pANTLR3_TRIE_ENTRY)ANTLR3_CALLOC(1, sizeof(ANTLR3_TRIE_ENTRY)); 1967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (newEnt == NULL) 1969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Out of memory, all we can do is return the fact that the insert failed. 1971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_FALSE; 1973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1974324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Otherwise insert this in the chain 1976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newEnt->type = type; 1978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newEnt->freeptr = freeptr; 1979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (type == ANTLR3_HASH_TYPE_STR) 1980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newEnt->data.ptr = data; 1982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 1984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newEnt->data.intVal = intVal; 1986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We want to be able to traverse the stored elements in the order that they were 1989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * added as duplicate keys. We might need to revise this opinion if we end up having many duplicate keys 1990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * as perhaps reverse order is just as good, so long as it is ordered. 1991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 1992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextEnt = nextNode->buckets; 1993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (nextEnt->next != NULL) 1994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 1995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextEnt = nextEnt->next; 1996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 1997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextEnt->next = newEnt; 1998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie->count++; 2000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_TRUE; 2001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We found the key is already there and we are not allowed duplicates in this 2005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * trie. 2006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_FALSE; 2008324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Here we have discovered the only node that can be reached by the bits in the key 2012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * but we have found that this node is not the key we need to insert. We must find the 2013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the leftmost bit by which the current key for that node and the new key we are going 2014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * to insert, differ. While this nested series of ifs may look a bit strange, experimentation 2015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * showed that it allows a machine code path that works well with predicated execution 2016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver xorKey = (key ^ nextNode->key); /* Gives 1 bits only where they differ then we find the left most 1 bit*/ 2018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Most common case is a 32 bit key really 2020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#ifdef ANTLR3_USE_64BIT 2022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (xorKey & 0xFFFFFFFF00000000) 2023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (xorKey & 0xFFFF000000000000) 2025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (xorKey & 0xFF00000000000000) 2027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver depth = 56 + bitIndex[((xorKey & 0xFF00000000000000)>>56)]; 2029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver depth = 48 + bitIndex[((xorKey & 0x00FF000000000000)>>48)]; 2033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (xorKey & 0x0000FF0000000000) 2038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver depth = 40 + bitIndex[((xorKey & 0x0000FF0000000000)>>40)]; 2040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver depth = 32 + bitIndex[((xorKey & 0x000000FF00000000)>>32)]; 2044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#endif 2049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (xorKey & 0x00000000FFFF0000) 2051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (xorKey & 0x00000000FF000000) 2053324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver depth = 24 + bitIndex[((xorKey & 0x00000000FF000000)>>24)]; 2055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver depth = 16 + bitIndex[((xorKey & 0x0000000000FF0000)>>16)]; 2059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (xorKey & 0x000000000000FF00) 2064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver depth = 8 + bitIndex[((xorKey & 0x0000000000000FF00)>>8)]; 2066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver depth = bitIndex[xorKey & 0x00000000000000FF]; 2070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We have located the leftmost differing bit, indicated by the depth variable. So, we know what 2075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * bit index we are to insert the new entry at. There are two cases, being where the two keys 2076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * differ at a bit position that is not currently part of the bit testing, where they differ on a bit 2077324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * that is currently being skipped in the indexed comparisons, and where they differ on a bit 2078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * that is merely lower down in the current bit search. If the bit index went bit 4, bit 2 and they differ 2079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 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 2080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * then we have the easy bit <pun>. 2081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * So, set up to descend the tree again, but this time looking for the insert point 2083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * according to whether we skip the bit that differs or not. 2084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisNode = trie->root; 2086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entNode = trie->root->leftN; 2087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Note the slight difference in the checks here to cover both cases 2089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (thisNode->bitNum > entNode->bitNum && entNode->bitNum > depth) 2091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Still descending the structure, next node becomes current. 2093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisNode = entNode; 2095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (key & bitMask[entNode->bitNum]) 2097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Bit at the required index was 1, so traverse the right node from here 2099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entNode = entNode->rightN; 2101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Bit at the required index was 0, so we traverse to the left 2105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver entNode = entNode->leftN; 2107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We have located the correct insert point for this new key, so we need 2111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * to allocate our entry and insert it etc. 2112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode = (pANTLR3_INT_TRIE_NODE)ANTLR3_CALLOC(1, sizeof(ANTLR3_INT_TRIE_NODE)); 2114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (nextNode == NULL) 2115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* All that work and no memory - bummer. 2117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_FALSE; 2119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Build a new entry block for the new node 2122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newEnt = (pANTLR3_TRIE_ENTRY)ANTLR3_CALLOC(1, sizeof(ANTLR3_TRIE_ENTRY)); 2124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (newEnt == NULL) 2126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Out of memory, all we can do is return the fact that the insert failed. 2128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_FALSE; 2130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Otherwise enter this in our new node 2133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newEnt->type = type; 2135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newEnt->freeptr = freeptr; 2136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (type == ANTLR3_HASH_TYPE_STR) 2137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newEnt->data.ptr = data; 2139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newEnt->data.intVal = intVal; 2143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Install it 2145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode->buckets = newEnt; 2147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode->key = key; 2148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode->bitNum = depth; 2149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Work out the right and left pointers for this new node, which involve 2151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * terminating with the current found node either right or left according 2152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * to whether the current index bit is 1 or 0 2153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (key & bitMask[depth]) 2155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode->leftN = entNode; /* Terminates at previous position */ 2157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode->rightN = nextNode; /* Terminates with itself */ 2158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode->rightN = entNode; /* Terminates at previous position */ 2162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextNode->leftN = nextNode; /* Terminates with itself */ 2163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Finally, we need to change the pointers at the node we located 2166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * for inserting. If the key bit at its index is set then the right 2167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * pointer for that node becomes the newly created node, otherwise the left 2168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * pointer does. 2169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (key & bitMask[thisNode->bitNum] ) 2171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisNode->rightN = nextNode; 2173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisNode->leftN = nextNode; 2177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Et voila 2180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver trie->count++; 2182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ANTLR3_TRUE; 2183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 2185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Release memory allocated to this tree. 2186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Basic algorithm is that we do a depth first left descent and free 2187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * up any nodes that are not backward pointers. 2188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 2190324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverfreeIntNode(pANTLR3_INT_TRIE_NODE node) 2191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 2192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_TRIE_ENTRY thisEntry; 2193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_TRIE_ENTRY nextEntry; 2194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* If this node has a left pointer that is not a back pointer 2196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * then recursively call to free this 2197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (node->bitNum > node->leftN->bitNum) 2199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* We have a left node that needs descending, so do it. 2201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver freeIntNode(node->leftN); 2203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* The left nodes from here should now be dealt with, so 2206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we need to descend any right nodes that are not back pointers 2207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (node->bitNum > node->rightN->bitNum) 2209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* There are some right nodes to descend and deal with. 2211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver freeIntNode(node->rightN); 2213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now all the children are dealt with, we can destroy 2216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * this node too 2217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisEntry = node->buckets; 2219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (thisEntry != NULL) 2221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nextEntry = thisEntry->next; 2223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Do we need to call a custom free pointer for this string entry? 2225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (thisEntry->type == ANTLR3_HASH_TYPE_STR && thisEntry->freeptr != NULL) 2227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisEntry->freeptr(thisEntry->data.ptr); 2229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Now free the data for this bucket entry 2232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(thisEntry); 2234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver thisEntry = nextEntry; /* See if there are any more to free */ 2235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* The bucket entry is now gone, so we can free the memory for 2238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the entry itself. 2239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(node); 2241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* And that should be it for everything under this node and itself 2243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 2245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Called to free all nodes and the structure itself. 2247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 2249324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverintTrieFree (pANTLR3_INT_TRIE trie) 2250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 2251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Descend from the root and free all the nodes 2252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver freeIntNode(trie->root); 2254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* the nodes are all gone now, so we need only free the memory 2256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * for the structure itself 2257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(trie); 2259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 2260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** 2263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Allocate and initialize a new ANTLR3 topological sorter, which can be 2264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * used to define edges that identify numerical node indexes that depend on other 2265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * numerical node indexes, which can then be sorted topologically such that 2266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * any node is sorted after all its dependent nodes. 2267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Use: 2269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * /verbatim 2271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_TOPO topo; 2273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo = antlr3NewTopo(); 2274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo == NULL) { out of memory } 2276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->addEdge(topo, 3, 0); // Node 3 depends on node 0 2278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->addEdge(topo, 0, 1); // Node - depends on node 1 2279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->sortVector(topo, myVector); // Sort the vector in place (node numbers are the vector entry numbers) 2280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * /verbatim 2282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2283324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverANTLR3_API pANTLR3_TOPO 2284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverantlr3TopoNew() 2285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 2286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_TOPO topo = (pANTLR3_TOPO)ANTLR3_MALLOC(sizeof(ANTLR3_TOPO)); 2287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo == NULL) 2289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NULL; 2291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Initialize variables 2294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->visited = NULL; // Don't know how big it is yet 2297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->limit = 1; // No edges added yet 2298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->edges = NULL; // No edges added yet 2299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->sorted = NULL; // Nothing sorted at the start 2300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->cycle = NULL; // No cycles at the start 2301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->cycleMark = 0; // No cycles at the start 2302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->hasCycle = ANTLR3_FALSE; // No cycle at the start 2303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // API 2305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->addEdge = addEdge; 2307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->sortToArray = sortToArray; 2308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->sortVector = sortVector; 2309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->free = freeTopo; 2310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return topo; 2312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 2313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Topological sorter 2314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// 2315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 2316324c4644fee44b9898524c09511bd33c3f12e2dfBen GruveraddEdge (pANTLR3_TOPO topo, ANTLR3_UINT32 edge, ANTLR3_UINT32 dependency) 2317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 2318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 i; 2319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 maxEdge; 2320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_BITSET edgeDeps; 2321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (edge>dependency) 2323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver maxEdge = edge; 2325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 2327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver maxEdge = dependency; 2329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We need to add an edge to says that the node indexed by 'edge' is 2331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // dependent on the node indexed by 'dependency' 2332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // First see if we have enough room in the edges array to add the edge? 2335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->edges == NULL) 2337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We don't have any edges yet, so create an array to hold them 2339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->edges = ANTLR3_CALLOC(sizeof(pANTLR3_BITSET) * (maxEdge + 1), 1); 2341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->edges == NULL) 2342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 2344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Set the limit to what we have now 2347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->limit = maxEdge + 1; 2349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else if (topo->limit <= maxEdge) 2351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // WE have some edges but not enough 2353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->edges = ANTLR3_REALLOC(topo->edges, sizeof(pANTLR3_BITSET) * (maxEdge + 1)); 2355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->edges == NULL) 2356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 2358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Initialize the new bitmaps to ;indicate we have no edges defined yet 2361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (i = topo->limit; i <= maxEdge; i++) 2363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *((topo->edges) + i) = NULL; 2365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Set the limit to what we have now 2368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->limit = maxEdge + 1; 2370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // If the edge was flagged as depending on itself, then we just 2373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // do nothing as it means this routine was just called to add it 2374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // in to the list of nodes. 2375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (edge == dependency) 2377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 2379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Pick up the bit map for the requested edge 2382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver edgeDeps = *((topo->edges) + edge); 2384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (edgeDeps == NULL) 2386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // No edges are defined yet for this node 2388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver edgeDeps = antlr3BitsetNew(0); 2390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *((topo->edges) + edge) = edgeDeps; 2391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (edgeDeps == NULL ) 2392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; // Out of memory 2394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Set the bit in the bitmap that corresponds to the requested 2398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // dependency. 2399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver edgeDeps->add(edgeDeps, dependency); 2401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // And we are all set 2403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 2405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 2406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** 2409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Given a starting node, descend its dependent nodes (ones that it has edges 2410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * to) until we find one without edges. Having found a node without edges, we have 2411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * discovered the bottom of a depth first search, which we can then ascend, adding 2412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the nodes in order from the bottom, which gives us the dependency order. 2413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 2414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 2415324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDFS(pANTLR3_TOPO topo, ANTLR3_UINT32 node) 2416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 2417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_BITSET edges; 2418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Guard against a revisit and check for cycles 2420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->hasCycle == ANTLR3_TRUE) 2422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; // We don't do anything else if we found a cycle 2424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->visited->isMember(topo->visited, node)) 2427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Check to see if we found a cycle. To do this we search the 2429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // current cycle stack and see if we find this node already in the stack. 2430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 i; 2432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (i=0; i<topo->cycleMark; i++) 2434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->cycle[i] == node) 2436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Stop! We found a cycle in the input, so rejig the cycle 2438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // stack so that it only contains the cycle and set the cycle flag 2439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // which will tell the caller what happened 2440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 l; 2442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (l = i; l < topo->cycleMark; l++) 2444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->cycle[l - i] = topo->cycle[l]; // Move to zero base in the cycle list 2446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Recalculate the limit 2449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->cycleMark -= i; 2451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Signal disaster 2453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->hasCycle = ANTLR3_TRUE; 2455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 2458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // So far, no cycles have been found and we have not visited this node yet, 2461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // so this node needs to go into the cycle stack before we continue 2462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // then we will take it out of the stack once we have descended all its 2463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // dependencies. 2464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->cycle[topo->cycleMark++] = node; 2466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // First flag that we have visited this node 2468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->visited->add(topo->visited, node); 2470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Now, if this node has edges, then we want to ensure we visit 2472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // them all before we drop through and add this node into the sorted 2473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // list. 2474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver edges = *((topo->edges) + node); 2476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (edges != NULL) 2477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We have some edges, so visit each of the edge nodes 2479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // that have not already been visited. 2480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 numBits; // How many bits are in the set 2482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 i; 2483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 range; 2484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver numBits = edges->numBits(edges); 2486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver range = edges->size(edges); // Number of set bits 2487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Stop if we exahust the bit list or have checked the 2489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // number of edges that this node refers to (so we don't 2490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // check bits at the end that cannot possibly be set). 2491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (i=0; i<= numBits && range > 0; i++) 2493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (edges->isMember(edges, i)) 2495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver range--; // About to check another one 2497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Found an edge, make sure we visit and descend it 2499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DFS(topo, i); 2501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // At this point we will have visited all the dependencies 2506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // of this node and they will be ordered (even if there are cycles) 2507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // So we just add the node into the sorted list at the 2508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // current index position. 2509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->sorted[topo->limit++] = node; 2511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Remove this node from the cycle list if we have not detected a cycle 2513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->hasCycle == ANTLR3_FALSE) 2515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->cycleMark--; 2517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 2520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 2521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic pANTLR3_UINT32 2523324c4644fee44b9898524c09511bd33c3f12e2dfBen GruversortToArray (pANTLR3_TOPO topo) 2524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 2525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 v; 2526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 oldLimit; 2527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Guard against being called with no edges defined 2529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->edges == NULL) 2531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return 0; 2533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // First we need a vector to populate with enough 2535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // entries to accomodate the sorted list and another to accomodate 2536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // the maximum cycle we could detect which is all nodes such as 0->1->2->3->0 2537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->sorted = ANTLR3_MALLOC(topo->limit * sizeof(ANTLR3_UINT32)); 2539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->cycle = ANTLR3_MALLOC(topo->limit * sizeof(ANTLR3_UINT32)); 2540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Next we need an empty bitset to show whether we have visited a node 2542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // or not. This is the bit that gives us linear time of course as we are essentially 2543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // dropping through the nodes in depth first order and when we get to a node that 2544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // has no edges, we pop back up the stack adding the nodes we traversed in reverse 2545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // order. 2546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->visited = antlr3BitsetNew(0); 2548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Now traverse the nodes as if we were just going left to right, but 2550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // then descend each node unless it has already been visited. 2551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver oldLimit = topo->limit; // Number of nodes to traverse linearly 2553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->limit = 0; // Next entry in the sorted table 2554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (v = 0; v < oldLimit; v++) 2556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // If we did not already visit this node, then descend it until we 2558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // get a node without edges or arrive at a node we have already visited. 2559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->visited->isMember(topo->visited, v) == ANTLR3_FALSE) 2561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We have not visited this one so descend it 2563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DFS(topo, v); 2565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Break the loop if we detect a cycle as we have no need to go any 2568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // further 2569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->hasCycle == ANTLR3_TRUE) 2571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break; 2573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Reset the limit to the number we recorded as if we hit a 2577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // cycle, then limit will have stopped at the node where we 2578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // discovered the cycle, but in order to free the edge bitmaps 2579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // we need to know how many we may have allocated and traverse them all. 2580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->limit = oldLimit; 2582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Having traversed all the nodes we were given, we 2584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // are guaranteed to have ordered all the nodes or detected a 2585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // cycle. 2586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return topo->sorted; 2588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 2589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 2591324c4644fee44b9898524c09511bd33c3f12e2dfBen GruversortVector (pANTLR3_TOPO topo, pANTLR3_VECTOR v) 2592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 2593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // To sort a vector, we first perform the 2594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // sort to an array, then use the results to reorder the vector 2595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // we are given. This is just a convenience routine that allows you to 2596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // sort the children of a tree node into topological order before or 2597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // during an AST walk. This can be useful for optimizations that require 2598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // dag reorders and also when the input stream defines thigns that are 2599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // interdependent and you want to walk the list of the generated trees 2600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // for those things in topological order so you can ignore the interdependencies 2601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // at that point. 2602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 i; 2604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Used as a lookup index to find the current location in the vector of 2606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // the vector entry that was originally at position [0], [1], [2] etc 2607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_UINT32 vIndex; 2609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Sort into an array, then we can use the array that is 2611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // stored in the topo 2612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->sortToArray(topo) == 0) 2614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; // There were no edges 2616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->hasCycle == ANTLR3_TRUE) 2619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; // Do nothing if we detected a cycle 2621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Ensure that the vector we are sorting is at least as big as the 2624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // the input sequence we were adsked to sort. It does not matter if it is 2625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // bigger as thaat probably just means that nodes numbered higher than the 2626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // limit had no dependencies and so can be left alone. 2627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->limit > v->count) 2629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We can only sort the entries that we have dude! The caller is 2631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // responsible for ensuring the vector is the correct one and is the 2632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // correct size etc. 2633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->limit = v->count; 2635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We need to know the locations of each of the entries 2637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // in the vector as we don't want to duplicate them in a new vector. We 2638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // just use an indirection table to get the vector entry for a particular sequence 2639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // acording to where we moved it last. Then we can just swap vector entries until 2640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // we are done :-) 2641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vIndex = ANTLR3_MALLOC(topo->limit * sizeof(ANTLR3_UINT32)); 2643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Start index, each vector entry is located where you think it is 2645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (i = 0; i < topo->limit; i++) 2647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vIndex[i] = i; 2649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Now we traverse the sorted array and moved the entries of 2652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // the vector around according to the sort order and the indirection 2653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // table we just created. The index telsl us where in the vector the 2654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // original element entry n is now located via vIndex[n]. 2655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (i=0; i < topo->limit; i++) 2657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 ind; 2659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // If the vector entry at i is already the one that it 2661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // should be, then we skip moving it of course. 2662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (vIndex[topo->sorted[i]] == i) 2664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver continue; 2666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // The vector entry at i, should be replaced with the 2669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // vector entry indicated by topo->sorted[i]. The vector entry 2670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // at topo->sorted[i] may have already been swapped out though, so we 2671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // find where it is now and move it from there to i. 2672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ind = vIndex[topo->sorted[i]]; 2674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver v->swap(v, i, ind); 2675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Update our index. The element at i is now the one we wanted 2677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // to be sorted here and the element we swapped out is now the 2678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // element that was at i just before we swapped it. If you are lost now 2679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // don't worry about it, we are just reindexing on the fly is all. 2680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vIndex[topo->sorted[i]] = i; 2682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver vIndex[i] = ind; 2683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Having traversed all the entries, we have sorted the vector in place. 2686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(vIndex); 2688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 2689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 2690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic void 2692324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverfreeTopo (pANTLR3_TOPO topo) 2693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 2694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_UINT32 i; 2695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Free the result vector 2697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->sorted != NULL) 2699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(topo->sorted); 2701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->sorted = NULL; 2702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Free the visited map 2705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->visited != NULL) 2707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->visited->free(topo->visited); 2710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->visited = NULL; 2711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Free any edgemaps 2714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->edges != NULL) 2716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver pANTLR3_BITSET edgeList; 2718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (i=0; i<topo->limit; i++) 2721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver edgeList = *((topo->edges) + i); 2723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (edgeList != NULL) 2724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver edgeList->free(edgeList); 2726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(topo->edges); 2730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver topo->edges = NULL; 2732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Free any cycle map 2734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // 2735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (topo->cycle != NULL) 2736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 2737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(topo->cycle); 2738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 2739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3_FREE(topo); 2741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 2742