📄 antlr3collections.c
字号:
/** \brief Creates an enumeration structure to traverse the hash table. * * \param table Table to enumerate * \return Pointer to enumeration structure. */pANTLR3_HASH_ENUMantlr3EnumNew (pANTLR3_HASH_TABLE table){ pANTLR3_HASH_ENUM en; /* Allocate structure memory */ en = (pANTLR3_HASH_ENUM) ANTLR3_MALLOC((size_t)sizeof(ANTLR3_HASH_ENUM)); /* Check that the allocation was good */ if (en == NULL) { return (pANTLR3_HASH_ENUM) ANTLR3_ERR_NOMEM; } /* Initialize the start pointers */ en->table = table; en->bucket = 0; /* First bucket */ en->entry = en->table->buckets->entries; /* First entry to return */ /* Special case in that the first bucket may not have anything in it * but the antlr3EnumNext() function expects that the en->entry is * set to the next valid pointer. Hence if it is not a valid element * pointer, attempt to find the next one that is, (table may be empty * of course. */ if (en->entry == NULL) { antlr3EnumNextEntry(en); } /* Install the interface */ en->free = antlr3EnumFree; en->next = antlr3EnumNext; /* All is good */ return en;}/** \brief Return the next entry in the hashtable ebign traversed by the supplied * enumeration. * * \param[in] en Pointer to the enumeration tracking structure * \param key Pointer to void pointer, where the key pointer is returned. * \param data Pointer to void pointer where the data poitner is returned. * \return * - ANTLR3_SUCCESS if there was a next key * - ANTLR3_FAIL if there were no more keys * * \remark * No checking of input structure is performed! */static intantlr3EnumNext (pANTLR3_HASH_ENUM en, void ** key, void ** data){ /* If the current entry is valid, then use it */ if (en->bucket >= en->table->modulo) { /* Already exhausted the table */ return ANTLR3_FAIL; } /* Pointers are already set to the current entry to return, or * we would not be at this point in the logic flow. */ *key = en->entry->key; *data = en->entry->data; /* Return pointers are set up, so now we move the element * pointer to the next in the table (if any). */ antlr3EnumNextEntry(en); return ANTLR3_SUCCESS;}/** \brief Local function to avance the entry pointer of an enumeration * structure to the next vlaid entry (if there is one). * * \param[in] enum Pointer to ANTLR3 enumeratio structure returned by antlr3EnumNew() * * \remark * - The function always leaves the pointers pointing at a valid enrty if there * is one, so if the entry pointer is NULL when this function exits, there were * no more entries in the table. */static voidantlr3EnumNextEntry(pANTLR3_HASH_ENUM en){ pANTLR3_HASH_BUCKET bucket; /* See if the current entry pointer is valid fisrt of all */ if (en->entry != NULL) { /* Current entry was a vlaid point, see if ther eis another * one in the chain. */ if (en->entry->nextEntry != NULL) { /* Next entry in the enumeration is just the next entry * in the chain. */ en->entry = en->entry->nextEntry; return; } } /* There were no more entries in the current bucket, if there are * more buckets then chase them until we find an entry. */ en->bucket++; while (en->bucket < en->table->modulo) { /* There was one more bucket, see if it has any elements in it */ bucket = en->table->buckets + en->bucket; if (bucket->entries != NULL) { /* There was an entry in this bucket, so we can use it * for the next entry in the enumeration. */ en->entry = bucket->entries; return; } /* There was nothing in the bucket we just examined, move to the * next one. */ en->bucket++; } /* Here we have exhausted all buckets and the enumeration pointer will * have its bucket count = table->modulo whicih signifies that we are done. */}/** \brief Frees up the memory structures that represent a hash table * enumeration. * \param[in] enum Pointer to ANTLR3 enumeratio structure returned by antlr3EnumNew() */static voidantlr3EnumFree (pANTLR3_HASH_ENUM en){ /* Nothing to check, we just free it. */ ANTLR3_FREE(en);}/** Given an input key of arbitrary length, return a hash value of * it. This can then be used (with suitable modulo) to index other * structures. */ANTLR3_API ANTLR3_UINT32antlr3Hash(void * key, ANTLR3_UINT32 keylen){ /* Accumulate the hash value of the key */ ANTLR3_UINT32 hash; pANTLR3_UINT8 keyPtr; ANTLR3_UINT32 i1; hash = 0; keyPtr = (pANTLR3_UINT8) key; /* Iterate the key and accumulate the hash */ while(keylen > 0) { hash = (hash << 4) + (*(keyPtr++)); if ((i1=hash&0xf0000000) != 0) { hash = hash ^ (i1 >> 24); hash = hash ^ i1; } keylen--; } return hash;}ANTLR3_API pANTLR3_LISTantlr3ListNew (ANTLR3_UINT32 sizeHint){ pANTLR3_LIST list; /* Allocate memory */ list = (pANTLR3_LIST)ANTLR3_MALLOC((size_t)sizeof(ANTLR3_LIST)); if (list == NULL) { return (pANTLR3_LIST)ANTLR3_ERR_NOMEM; } /* Now we need to add a new table */ list->table = antlr3HashTableNew(sizeHint); if (list->table == (pANTLR3_HASH_TABLE)ANTLR3_ERR_NOMEM) { return (pANTLR3_LIST)ANTLR3_ERR_NOMEM; } /* Allocation was good, install interface */ list->free = antlr3ListFree; list->del = antlr3ListDelete; list->get = antlr3ListGet; list->add = antlr3ListAdd; list->remove = antlr3ListRemove; list->put = antlr3ListPut; list->size = antlr3ListSize; return list;}static ANTLR3_UINT64 antlr3ListSize (pANTLR3_LIST list){ return list->table->size(list->table);}static voidantlr3ListFree (pANTLR3_LIST list){ /* Free the hashtable that stores the list */ list->table->free(list->table); /* Free the allocation for the list itself */ ANTLR3_FREE(list);}static voidantlr3ListDelete (pANTLR3_LIST list, ANTLR3_UINT64 key){ ANTLR3_UINT8 charKey[32]; sprintf((char *)charKey, "%d", key); list->table->del(list->table, charKey);}static void *antlr3ListGet (pANTLR3_LIST list, ANTLR3_UINT64 key){ ANTLR3_UINT8 charKey[32]; sprintf((char *)charKey, "%d", key); return list->table->get(list->table, charKey);}/** Add the supplied element to the list, at the next available key */static ANTLR3_INT32 antlr3ListAdd (pANTLR3_LIST list, void * element, void (*freeptr)(void *)){ ANTLR3_UINT64 key; key = list->table->size(list->table) + 1; return list->put(list, key, element, freeptr);}/** Remove from the list, but don't free the element, just send it back to the * caller. */static void *antlr3ListRemove (pANTLR3_LIST list, ANTLR3_UINT64 key){ pANTLR3_HASH_ENTRY entry; ANTLR3_UINT8 charKey[32]; sprintf((char *)charKey, "%d", key); entry = list->table->remove(list->table, charKey); if (entry != NULL) { return entry->data; } else { return NULL; }}static ANTLR3_INT32antlr3ListPut (pANTLR3_LIST list, ANTLR3_UINT64 key, void * element, void (*freeptr)(void *)){ ANTLR3_UINT8 charKey[32]; sprintf((char *)charKey, "%d", key); return list->table->put(list->table, (void *)charKey, element, freeptr);}ANTLR3_API pANTLR3_STACKantlr3StackNew (ANTLR3_UINT32 sizeHint){ pANTLR3_STACK stack; /* Allocate memory */ stack = (pANTLR3_STACK)ANTLR3_MALLOC((size_t)sizeof(ANTLR3_STACK)); if (stack == NULL) { return (pANTLR3_STACK)ANTLR3_ERR_NOMEM; } /* Now we need to add a new table */ stack->list = antlr3ListNew(sizeHint); stack->top = NULL; if (stack->list == (pANTLR3_LIST)ANTLR3_ERR_NOMEM) { return (pANTLR3_STACK)ANTLR3_ERR_NOMEM; } /* Looks good, now add the interface */ stack->get = antlr3StackGet; stack->free = antlr3StackFree; stack->pop = antlr3StackPop; stack->push = antlr3StackPush; stack->size = antlr3StackSize; stack->peek = antlr3StackPeek; return stack;}static ANTLR3_UINT64 antlr3StackSize (pANTLR3_STACK stack){ return stack->list->size(stack->list);}static voidantlr3StackFree (pANTLR3_STACK stack){ /* Free the list that supports the stack */ stack->list->free(stack->list); stack->top = NULL; ANTLR3_FREE(stack);}static voidantlr3StackPop (pANTLR3_STACK stack){ stack->list->del(stack->list, stack->list->table->count); stack->top = stack->list->get(stack->list, stack->list->table->count);}static void *antlr3StackGet (pANTLR3_STACK stack, ANTLR3_UINT64 key){ return stack->list->get(stack->list, key);}static void *antlr3StackPeek (pANTLR3_STACK stack){ return stack->top;}static ANTLR3_BOOLEAN antlr3StackPush (pANTLR3_STACK stack, void * element, void (*freeptr)(void *)){ ANTLR3_UINT64 pushno;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -