⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyword.c

📁 Exuberant Ctags is a multilanguage reimplementation of the much-underused ctags(1) program and is i
💻 C
字号:
/**   $Id: keyword.c,v 1.6 2006/05/30 04:37:12 darren Exp $**   Copyright (c) 1998-2002, Darren Hiebert**   This source code is released for free distribution under the terms of the*   GNU General Public License.**   Manages a keyword hash.*//**   INCLUDE FILES*/#include "general.h"  /* must always come first */#include <string.h>#include "debug.h"#include "keyword.h"#include "options.h"#include "routines.h"/**   MACROS*/#define HASH_EXPONENT 7  /* must be less than 17 *//**   DATA DECLARATIONS*/typedef struct sHashEntry {	struct sHashEntry *next;	const char *string;	langType language;	int value;} hashEntry;/**   DATA DEFINITIONS*/static const unsigned int TableSize = 1 << HASH_EXPONENT;static hashEntry **HashTable = NULL;/**   FUNCTION DEFINITIONS*/static hashEntry **getHashTable (void){	static boolean allocated = FALSE;	if (! allocated)	{		unsigned int i;		HashTable = xMalloc (TableSize, hashEntry*);		for (i = 0  ;  i < TableSize  ;  ++i)			HashTable [i] = NULL;		allocated = TRUE;	}	return HashTable;}static hashEntry *getHashTableEntry (unsigned long hashedValue){	hashEntry **const table = getHashTable ();	hashEntry *entry;	Assert (hashedValue < TableSize);	entry = table [hashedValue];	return entry;}static unsigned long hashValue (const char *const string){	unsigned long value = 0;	const unsigned char *p;	Assert (string != NULL);	/*  We combine the various words of the multiword key using the method	 *  described on page 512 of Vol. 3 of "The Art of Computer Programming".	 */	for (p = (const unsigned char *) string  ;  *p != '\0'  ;  ++p)	{		value <<= 1;		if (value & 0x00000100L)			value = (value & 0x000000ffL) + 1L;		value ^= *p;	}	/*  Algorithm from page 509 of Vol. 3 of "The Art of Computer Programming"	 *  Treats "value" as a 16-bit integer plus 16-bit fraction.	 */	value *= 40503L;               /* = 2^16 * 0.6180339887 ("golden ratio") */	value &= 0x0000ffffL;          /* keep fractional part */	value >>= 16 - HASH_EXPONENT;  /* scale up by hash size and move down */	return value;}static hashEntry *newEntry (		const char *const string, langType language, int value){	hashEntry *const entry = xMalloc (1, hashEntry);	entry->next     = NULL;	entry->string   = string;	entry->language = language;	entry->value    = value;	return entry;}/*  Note that it is assumed that a "value" of zero means an undefined keyword *  and clients of this function should observe this. Also, all keywords added *  should be added in lower case. If we encounter a case-sensitive language *  whose keywords are in upper case, we will need to redesign this. */extern void addKeyword (const char *const string, langType language, int value){	const unsigned long hashedValue = hashValue (string);	hashEntry *tableEntry = getHashTableEntry (hashedValue);	hashEntry *entry = tableEntry;	if (entry == NULL)	{		hashEntry **const table = getHashTable ();		table [hashedValue] = newEntry (string, language, value);	}	else	{		hashEntry *prev = NULL;		while (entry != NULL)		{			if (language == entry->language  &&				strcmp (string, entry->string) == 0)			{				Assert (("Already in table" == NULL));			}			prev = entry;			entry = entry->next;		}		if (entry == NULL)		{			Assert (prev != NULL);			prev->next = newEntry (string, language, value);		}	}}extern int lookupKeyword (const char *const string, langType language){	const unsigned long hashedValue = hashValue (string);	hashEntry *entry = getHashTableEntry (hashedValue);	int result = -1;	while (entry != NULL)	{		if (language == entry->language  &&  strcmp (string, entry->string) == 0)		{			result = entry->value;			break;		}		entry = entry->next;	}	return result;}extern void freeKeywordTable (void){	if (HashTable != NULL)	{		unsigned int i;		for (i = 0  ;  i < TableSize  ;  ++i)		{			hashEntry *entry = HashTable [i];			while (entry != NULL)			{				hashEntry *next = entry->next;				eFree (entry);				entry = next;			}		}		eFree (HashTable);	}}#ifdef DEBUGstatic void printEntry (const hashEntry *const entry){	printf ("  %-15s %-7s\n", entry->string, getLanguageName (entry->language));}static unsigned int printBucket (const unsigned int i){	hashEntry **const table = getHashTable ();	hashEntry *entry = table [i];	unsigned int measure = 1;	boolean first = TRUE;	printf ("%2d:", i);	if (entry == NULL)		printf ("\n");	else while (entry != NULL)	{		if (! first)			printf ("    ");		else		{			printf (" ");			first = FALSE;		}		printEntry (entry);		entry = entry->next;		measure = 2 * measure;	}	return measure - 1;}extern void printKeywordTable (void){	unsigned long emptyBucketCount = 0;	unsigned long measure = 0;	unsigned int i;	for (i = 0  ;  i < TableSize  ;  ++i)	{		const unsigned int pass = printBucket (i);		measure += pass;		if (pass == 0)			++emptyBucketCount;	}	printf ("spread measure = %ld\n", measure);	printf ("%ld empty buckets\n", emptyBucketCount);}#endif/* vi:set tabstop=4 shiftwidth=4: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -