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

📄 readtags.c

📁 ctags的最新版5.7,可以比较5.6版看看,免费下载
💻 C
📖 第 1 页 / 共 2 页
字号:
		free (file->program.name);	if (file->program.url != NULL)		free (file->program.url);	if (file->program.version != NULL)		free (file->program.version);	if (file->search.name != NULL)		free (file->search.name);	memset (file, 0, sizeof (tagFile));	free (file);}static tagResult readNext (tagFile *const file, tagEntry *const entry){	tagResult result;	if (file == NULL  ||  ! file->initialized)		result = TagFailure;	else if (! readTagLine (file))		result = TagFailure;	else	{		if (entry != NULL)			parseTagLine (file, entry);		result = TagSuccess;	}	return result;}static const char *readFieldValue (	const tagEntry *const entry, const char *const key){	const char *result = NULL;	int i;	if (strcmp (key, "kind") == 0)		result = entry->kind;	else if (strcmp (key, "file") == 0)		result = EmptyString;	else for (i = 0  ;  i < entry->fields.count  &&  result == NULL  ;  ++i)		if (strcmp (entry->fields.list [i].key, key) == 0)			result = entry->fields.list [i].value;	return result;}static int readTagLineSeek (tagFile *const file, const off_t pos){	int result = 0;	if (fseek (file->fp, pos, SEEK_SET) == 0)	{		result = readTagLine (file);  /* read probable partial line */		if (pos > 0  &&  result)			result = readTagLine (file);  /* read complete line */	}	return result;}static int nameComparison (tagFile *const file){	int result;	if (file->search.ignorecase)	{		if (file->search.partial)			result = strnuppercmp (file->search.name, file->name.buffer,					file->search.nameLength);		else			result = struppercmp (file->search.name, file->name.buffer);	}	else	{		if (file->search.partial)			result = strncmp (file->search.name, file->name.buffer,					file->search.nameLength);		else			result = strcmp (file->search.name, file->name.buffer);	}	return result;}static void findFirstNonMatchBefore (tagFile *const file){#define JUMP_BACK 512	int more_lines;	int comp;	off_t start = file->pos;	off_t pos = start;	do	{		if (pos < (off_t) JUMP_BACK)			pos = 0;		else			pos = pos - JUMP_BACK;		more_lines = readTagLineSeek (file, pos);		comp = nameComparison (file);	} while (more_lines  &&  comp == 0  &&  pos > 0  &&  pos < start);}static tagResult findFirstMatchBefore (tagFile *const file){	tagResult result = TagFailure;	int more_lines;	off_t start = file->pos;	findFirstNonMatchBefore (file);	do	{		more_lines = readTagLine (file);		if (nameComparison (file) == 0)			result = TagSuccess;	} while (more_lines  &&  result != TagSuccess  &&  file->pos < start);	return result;}static tagResult findBinary (tagFile *const file){	tagResult result = TagFailure;	off_t lower_limit = 0;	off_t upper_limit = file->size;	off_t last_pos = 0;	off_t pos = upper_limit / 2;	while (result != TagSuccess)	{		if (! readTagLineSeek (file, pos))		{			/* in case we fell off end of file */			result = findFirstMatchBefore (file);			break;		}		else if (pos == last_pos)		{			/* prevent infinite loop if we backed up to beginning of file */			break;		}		else		{			const int comp = nameComparison (file);			last_pos = pos;			if (comp < 0)			{				upper_limit = pos;				pos = lower_limit + ((upper_limit - lower_limit) / 2);			}			else if (comp > 0)			{				lower_limit = pos;				pos = lower_limit + ((upper_limit - lower_limit) / 2);			}			else if (pos == 0)				result = TagSuccess;			else				result = findFirstMatchBefore (file);		}	}	return result;}static tagResult findSequential (tagFile *const file){	tagResult result = TagFailure;	if (file->initialized)	{		while (result == TagFailure  &&  readTagLine (file))		{			if (nameComparison (file) == 0)				result = TagSuccess;		}	}	return result;}static tagResult find (tagFile *const file, tagEntry *const entry,					   const char *const name, const int options){	tagResult result;	if (file->search.name != NULL)		free (file->search.name);	file->search.name = duplicate (name);	file->search.nameLength = strlen (name);	file->search.partial = (options & TAG_PARTIALMATCH) != 0;	file->search.ignorecase = (options & TAG_IGNORECASE) != 0;	fseek (file->fp, 0, SEEK_END);	file->size = ftell (file->fp);	rewind (file->fp);	if ((file->sortMethod == TAG_SORTED      && !file->search.ignorecase) ||		(file->sortMethod == TAG_FOLDSORTED  &&  file->search.ignorecase))	{#ifdef DEBUG		printf ("<performing binary search>\n");#endif		result = findBinary (file);	}	else	{#ifdef DEBUG		printf ("<performing sequential search>\n");#endif		result = findSequential (file);	}	if (result != TagSuccess)		file->search.pos = file->size;	else	{		file->search.pos = file->pos;		if (entry != NULL)			parseTagLine (file, entry);	}	return result;}static tagResult findNext (tagFile *const file, tagEntry *const entry){	tagResult result;	if ((file->sortMethod == TAG_SORTED      && !file->search.ignorecase) ||		(file->sortMethod == TAG_FOLDSORTED  &&  file->search.ignorecase))	{		result = tagsNext (file, entry);		if (result == TagSuccess  && nameComparison (file) != 0)			result = TagFailure;	}	else	{		result = findSequential (file);		if (result == TagSuccess  &&  entry != NULL)			parseTagLine (file, entry);	}	return result;}/**  EXTERNAL INTERFACE*/extern tagFile *tagsOpen (const char *const filePath, tagFileInfo *const info){	return initialize (filePath, info);}extern tagResult tagsSetSortType (tagFile *const file, const sortType type){	tagResult result = TagFailure;	if (file != NULL  &&  file->initialized)	{		file->sortMethod = type;		result = TagSuccess;	}	return result;}extern tagResult tagsFirst (tagFile *const file, tagEntry *const entry){	tagResult result = TagFailure;	if (file != NULL  &&  file->initialized)	{		gotoFirstLogicalTag (file);		result = readNext (file, entry);	}	return result;}extern tagResult tagsNext (tagFile *const file, tagEntry *const entry){	tagResult result = TagFailure;	if (file != NULL  &&  file->initialized)		result = readNext (file, entry);	return result;}extern const char *tagsField (const tagEntry *const entry, const char *const key){	const char *result = NULL;	if (entry != NULL)		result = readFieldValue (entry, key);	return result;}extern tagResult tagsFind (tagFile *const file, tagEntry *const entry,						   const char *const name, const int options){	tagResult result = TagFailure;	if (file != NULL  &&  file->initialized)		result = find (file, entry, name, options);	return result;}extern tagResult tagsFindNext (tagFile *const file, tagEntry *const entry){	tagResult result = TagFailure;	if (file != NULL  &&  file->initialized)		result = findNext (file, entry);	return result;}extern tagResult tagsClose (tagFile *const file){	tagResult result = TagFailure;	if (file != NULL  &&  file->initialized)	{		terminate (file);		result = TagSuccess;	}	return result;}/**  TEST FRAMEWORK*/#ifdef READTAGS_MAINstatic const char *TagFileName = "tags";static const char *ProgramName;static int extensionFields;static int SortOverride;static sortType SortMethod;static void printTag (const tagEntry *entry){	int i;	int first = 1;	const char* separator = ";\"";	const char* const empty = "";/* "sep" returns a value only the first time it is evaluated */#define sep (first ? (first = 0, separator) : empty)	printf ("%s\t%s\t%s",		entry->name, entry->file, entry->address.pattern);	if (extensionFields)	{		if (entry->kind != NULL  &&  entry->kind [0] != '\0')			printf ("%s\tkind:%s", sep, entry->kind);		if (entry->fileScope)			printf ("%s\tfile:", sep);#if 0		if (entry->address.lineNumber > 0)			printf ("%s\tline:%lu", sep, entry->address.lineNumber);#endif		for (i = 0  ;  i < entry->fields.count  ;  ++i)			printf ("%s\t%s:%s", sep, entry->fields.list [i].key,				entry->fields.list [i].value);	}	putchar ('\n');#undef sep}static void findTag (const char *const name, const int options){	tagFileInfo info;	tagEntry entry;	tagFile *const file = tagsOpen (TagFileName, &info);	if (file == NULL)	{		fprintf (stderr, "%s: cannot open tag file: %s: %s\n",				ProgramName, strerror (info.status.error_number), name);		exit (1);	}	else	{		if (SortOverride)			tagsSetSortType (file, SortMethod);		if (tagsFind (file, &entry, name, options) == TagSuccess)		{			do			{				printTag (&entry);			} while (tagsFindNext (file, &entry) == TagSuccess);		}		tagsClose (file);	}}static void listTags (void){	tagFileInfo info;	tagEntry entry;	tagFile *const file = tagsOpen (TagFileName, &info);	if (file == NULL)	{		fprintf (stderr, "%s: cannot open tag file: %s: %s\n",				ProgramName, strerror (info.status.error_number), TagFileName);		exit (1);	}	else	{		while (tagsNext (file, &entry) == TagSuccess)			printTag (&entry);		tagsClose (file);	}}const char *const Usage =	"Find tag file entries matching specified names.\n\n"	"Usage: %s [-ilp] [-s[0|1]] [-t file] [name(s)]\n\n"	"Options:\n"	"    -e           Include extension fields in output.\n"	"    -i           Perform case-insensitive matching.\n"	"    -l           List all tags.\n"	"    -p           Perform partial matching.\n"	"    -s[0|1|2]    Override sort detection of tag file.\n"	"    -t file      Use specified tag file (default: \"tags\").\n"	"Note that options are acted upon as encountered, so order is significant.\n";extern int main (int argc, char **argv){	int options = 0;	int actionSupplied = 0;	int i;	ProgramName = argv [0];	if (argc == 1)	{		fprintf (stderr, Usage, ProgramName);		exit (1);	}	for (i = 1  ;  i < argc  ;  ++i)	{		const char *const arg = argv [i];		if (arg [0] != '-')		{			findTag (arg, options);			actionSupplied = 1;		}		else		{			size_t j;			for (j = 1  ;  arg [j] != '\0'  ;  ++j)			{				switch (arg [j])				{					case 'e': extensionFields = 1;         break;					case 'i': options |= TAG_IGNORECASE;   break;					case 'p': options |= TAG_PARTIALMATCH; break;					case 'l': listTags (); actionSupplied = 1; break;								case 't':						if (arg [j+1] != '\0')						{							TagFileName = arg + j + 1;							j += strlen (TagFileName);						}						else if (i + 1 < argc)							TagFileName = argv [++i];						else						{							fprintf (stderr, Usage, ProgramName);							exit (1);						}						break;					case 's':						SortOverride = 1;						++j;						if (arg [j] == '\0')							SortMethod = TAG_SORTED;						else if (strchr ("012", arg[j]) != NULL)							SortMethod = (sortType) (arg[j] - '0');						else						{							fprintf (stderr, Usage, ProgramName);							exit (1);						}						break;					default:						fprintf (stderr, "%s: unknown option: %c\n",									ProgramName, arg[j]);						exit (1);						break;				}			}		}	}	if (! actionSupplied)	{		fprintf (stderr,			"%s: no action specified: specify tag name(s) or -l option\n",			ProgramName);		exit (1);	}	return 0;}#endif/* vi:set tabstop=4 shiftwidth=4: */

⌨️ 快捷键说明

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