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

📄 readtags.c

📁 ctags-5.5.4.tar.gz,一个很好的代码开发以及编辑源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (file->program.author != NULL)	free (file->program.author);    if (file->program.name != NULL)	free (file->program.name);    if (file->program.url != NULL)	free (file->program.url);    if (file->program.version != NULL)	free (file->program.version);    memset (file, 0, sizeof (tagFile));    free (file);}static tagResult readNext (tagFile *const file, tagEntry *const entry){    tagResult result = TagFailure;    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 = TagFailure;    file->search.name = 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 = TagFailure;    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=8 shiftwidth=4: */

⌨️ 快捷键说明

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