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

📄 entry.c

📁 Exuberant Ctags is a multilanguage reimplementation of the much-underused ctags(1) program and is i
💻 C
📖 第 1 页 / 共 2 页
字号:
			}		}		if (TagFile.fp == NULL)		{			error (FATAL | PERROR, "cannot open tag file");			exit (1);		}	}	if (TagsToStdout)		TagFile.directory = eStrdup (CurrentDirectory);	else		TagFile.directory = absoluteDirname (TagFile.name);}#ifdef USE_REPLACEMENT_TRUNCATE/*  Replacement for missing library function. */static int replacementTruncate (const char *const name, const long size){	char *tempName = NULL;	FILE *fp = tempFile ("w", &tempName);	fclose (fp);	copyFile (name, tempName, size);	copyFile (tempName, name, WHOLE_FILE);	remove (tempName);	eFree (tempName);	return 0;}#endifstatic void sortTagFile (void){	if (TagFile.numTags.added > 0L)	{		if (Option.sorted != SO_UNSORTED)		{			verbose ("sorting tag file\n");#ifdef EXTERNAL_SORT			externalSortTags (TagsToStdout);#else			internalSortTags (TagsToStdout);#endif		}		else if (TagsToStdout)			catFile (tagFileName ());	}	if (TagsToStdout)		remove (tagFileName ());  /* remove temporary file */}static void resizeTagFile (const long newSize){	int result;#ifdef USE_REPLACEMENT_TRUNCATE	result = replacementTruncate (TagFile.name, newSize);#else# ifdef HAVE_TRUNCATE	result = truncate (TagFile.name, (off_t) newSize);# else	const int fd = open (TagFile.name, O_RDWR);	if (fd == -1)		result = -1;	else	{#  ifdef HAVE_FTRUNCATE		result = ftruncate (fd, (off_t) newSize);#  else#   ifdef HAVE_CHSIZE		result = chsize (fd, newSize);#   endif#  endif		close (fd);	}# endif#endif	if (result == -1)		fprintf (errout, "Cannot shorten tag file: errno = %d\n", errno);}static void writeEtagsIncludes (FILE *const fp){	if (Option.etagsInclude)	{		unsigned int i;		for (i = 0  ;  i < stringListCount (Option.etagsInclude)  ;  ++i)		{			vString *item = stringListItem (Option.etagsInclude, i);			fprintf (fp, "\f\n%s,include\n", vStringValue (item));		}	}}extern void closeTagFile (const boolean resize){	long desiredSize, size;	if (Option.etags)		writeEtagsIncludes (TagFile.fp);	desiredSize = ftell (TagFile.fp);	fseek (TagFile.fp, 0L, SEEK_END);	size = ftell (TagFile.fp);	fclose (TagFile.fp);	if (resize  &&  desiredSize < size)	{		DebugStatement (			debugPrintf (DEBUG_STATUS, "shrinking %s from %ld to %ld bytes\n",				TagFile.name, size, desiredSize); )		resizeTagFile (desiredSize);	}	sortTagFile ();	eFree (TagFile.name);	TagFile.name = NULL;}extern void beginEtagsFile (void){	TagFile.etags.fp = tempFile ("w+b", &TagFile.etags.name);	TagFile.etags.byteCount = 0;}extern void endEtagsFile (const char *const name){	const char *line;	fprintf (TagFile.fp, "\f\n%s,%ld\n", name, (long) TagFile.etags.byteCount);	if (TagFile.etags.fp != NULL)	{		rewind (TagFile.etags.fp);		while ((line = readLine (TagFile.vLine, TagFile.etags.fp)) != NULL)			fputs (line, TagFile.fp);		fclose (TagFile.etags.fp);		remove (TagFile.etags.name);		eFree (TagFile.etags.name);		TagFile.etags.fp = NULL;		TagFile.etags.name = NULL;	}}/* *  Tag entry management *//*  This function copies the current line out to a specified file. It has no *  effect on the fileGetc () function.  During copying, any '\' characters *  are doubled and a leading '^' or trailing '$' is also quoted. End of line *  characters (line feed or carriage return) are dropped. */static size_t writeSourceLine (FILE *const fp, const char *const line){	size_t length = 0;	const char *p;	/*  Write everything up to, but not including, a line end character.	 */	for (p = line  ;  *p != '\0'  ;  ++p)	{		const int next = *(p + 1);		const int c = *p;		if (c == CRETURN  ||  c == NEWLINE)			break;		/*  If character is '\', or a terminal '$', then quote it.		 */		if (c == BACKSLASH  ||  c == (Option.backward ? '?' : '/')  ||			(c == '$'  &&  (next == NEWLINE  ||  next == CRETURN)))		{			putc (BACKSLASH, fp);			++length;		}		putc (c, fp);		++length;	}	return length;}/*  Writes "line", stripping leading and duplicate white space. */static size_t writeCompactSourceLine (FILE *const fp, const char *const line){	boolean lineStarted = FALSE;	size_t  length = 0;	const char *p;	int c;	/*  Write everything up to, but not including, the newline.	 */	for (p = line, c = *p  ;  c != NEWLINE  &&  c != '\0'  ;  c = *++p)	{		if (lineStarted  || ! isspace (c))  /* ignore leading spaces */		{			lineStarted = TRUE;			if (isspace (c))			{				int next;				/*  Consume repeating white space.				 */				while (next = *(p+1) , isspace (next)  &&  next != NEWLINE)					++p;				c = ' ';  /* force space character for any white space */			}			if (c != CRETURN  ||  *(p + 1) != NEWLINE)			{				putc (c, fp);				++length;			}		}	}	return length;}static int writeXrefEntry (const tagEntryInfo *const tag){	const char *const line =			readSourceLine (TagFile.vLine, tag->filePosition, NULL);	int length;	if (Option.tagFileFormat == 1)		length = fprintf (TagFile.fp, "%-16s %4lu %-16s ", tag->name,				tag->lineNumber, tag->sourceFileName);	else		length = fprintf (TagFile.fp, "%-16s %-10s %4lu %-16s ", tag->name,				tag->kindName, tag->lineNumber, tag->sourceFileName);	length += writeCompactSourceLine (TagFile.fp, line);	putc (NEWLINE, TagFile.fp);	++length;	return length;}/*  Truncates the text line containing the tag at the character following the *  tag, providing a character which designates the end of the tag. */static void truncateTagLine (		char *const line, const char *const token, const boolean discardNewline){	char *p = strstr (line, token);	if (p != NULL)	{		p += strlen (token);		if (*p != '\0'  &&  ! (*p == '\n'  &&  discardNewline))			++p;    /* skip past character terminating character */		*p = '\0';	}}static int writeEtagsEntry (const tagEntryInfo *const tag){	int length;	if (tag->isFileEntry)		length = fprintf (TagFile.etags.fp, "\177%s\001%lu,0\n",				tag->name, tag->lineNumber);	else	{		long seekValue;		char *const line =				readSourceLine (TagFile.vLine, tag->filePosition, &seekValue);		if (tag->truncateLine)			truncateTagLine (line, tag->name, TRUE);		else			line [strlen (line) - 1] = '\0';		length = fprintf (TagFile.etags.fp, "%s\177%s\001%lu,%ld\n", line,				tag->name, tag->lineNumber, seekValue);	}	TagFile.etags.byteCount += length;	return length;}static int addExtensionFields (const tagEntryInfo *const tag){	const char* const kindKey = Option.extensionFields.kindKey ? "kind:" : "";	boolean first = TRUE;	const char* separator = ";\"";	const char* const empty = "";	int length = 0;/* "sep" returns a value only the first time it is evaluated */#define sep (first ? (first = FALSE, separator) : empty)	if (tag->kindName != NULL && (Option.extensionFields.kindLong  ||		 (Option.extensionFields.kind  && tag->kind == '\0')))		length += fprintf (TagFile.fp,"%s\t%s%s", sep, kindKey, tag->kindName);	else if (tag->kind != '\0'  && (Option.extensionFields.kind  ||			(Option.extensionFields.kindLong  &&  tag->kindName == NULL)))		length += fprintf (TagFile.fp, "%s\t%s%c", sep, kindKey, tag->kind);	if (Option.extensionFields.lineNumber)		length += fprintf (TagFile.fp, "%s\tline:%ld", sep, tag->lineNumber);	if (Option.extensionFields.language  &&  tag->language != NULL)		length += fprintf (TagFile.fp, "%s\tlanguage:%s", sep, tag->language);	if (Option.extensionFields.scope  &&			tag->extensionFields.scope [0] != NULL  &&			tag->extensionFields.scope [1] != NULL)		length += fprintf (TagFile.fp, "%s\t%s:%s", sep,				tag->extensionFields.scope [0],				tag->extensionFields.scope [1]);	if (Option.extensionFields.typeRef  &&			tag->extensionFields.typeRef [0] != NULL  &&			tag->extensionFields.typeRef [1] != NULL)		length += fprintf (TagFile.fp, "%s\ttyperef:%s:%s", sep,				tag->extensionFields.typeRef [0],				tag->extensionFields.typeRef [1]);	if (Option.extensionFields.fileScope  &&  tag->isFileScope)		length += fprintf (TagFile.fp, "%s\tfile:", sep);	if (Option.extensionFields.inheritance  &&			tag->extensionFields.inheritance != NULL)		length += fprintf (TagFile.fp, "%s\tinherits:%s", sep,				tag->extensionFields.inheritance);	if (Option.extensionFields.access  &&  tag->extensionFields.access != NULL)		length += fprintf (TagFile.fp, "%s\taccess:%s", sep,				tag->extensionFields.access);	if (Option.extensionFields.implementation  &&			tag->extensionFields.implementation != NULL)		length += fprintf (TagFile.fp, "%s\timplementation:%s", sep,				tag->extensionFields.implementation);	if (Option.extensionFields.signature  &&			tag->extensionFields.signature != NULL)		length += fprintf (TagFile.fp, "%s\tsignature:%s", sep,				tag->extensionFields.signature);	return length;#undef sep}static int writePatternEntry (const tagEntryInfo *const tag){	char *const line = readSourceLine (TagFile.vLine, tag->filePosition, NULL);	const int searchChar = Option.backward ? '?' : '/';	boolean newlineTerminated;	int length = 0;	if (tag->truncateLine)		truncateTagLine (line, tag->name, FALSE);	newlineTerminated = (boolean) (line [strlen (line) - 1] == '\n');	length += fprintf (TagFile.fp, "%c^", searchChar);	length += writeSourceLine (TagFile.fp, line);	length += fprintf (TagFile.fp, "%s%c", newlineTerminated ? "$":"", searchChar);	return length;}static int writeLineNumberEntry (const tagEntryInfo *const tag){	return fprintf (TagFile.fp, "%lu", tag->lineNumber);}static int writeCtagsEntry (const tagEntryInfo *const tag){	int length = fprintf (TagFile.fp, "%s\t%s\t",		tag->name, tag->sourceFileName);	if (tag->lineNumberEntry)		length += writeLineNumberEntry (tag);	else		length += writePatternEntry (tag);	if (includeExtensionFlags ())		length += addExtensionFields (tag);	length += fprintf (TagFile.fp, "\n");	return length;}extern void makeTagEntry (const tagEntryInfo *const tag){	Assert (tag->name != NULL);	if (tag->name [0] == '\0')		error (WARNING, "ignoring null tag in %s", vStringValue (File.name));	else	{		int length = 0;		DebugStatement ( debugEntry (tag); )		if (Option.xref)		{			if (! tag->isFileEntry)				length = writeXrefEntry (tag);		}		else if (Option.etags)			length = writeEtagsEntry (tag);		else			length = writeCtagsEntry (tag);		++TagFile.numTags.added;		rememberMaxLengths (strlen (tag->name), (size_t) length);		DebugStatement ( fflush (TagFile.fp); )	}}extern void initTagEntry (tagEntryInfo *const e, const char *const name){	Assert (File.source.name != NULL);	memset (e, 0, sizeof (tagEntryInfo));	e->lineNumberEntry = (boolean) (Option.locate == EX_LINENUM);	e->lineNumber      = getSourceLineNumber ();	e->language        = getSourceLanguageName ();	e->filePosition    = getInputFilePosition ();	e->sourceFileName  = getSourceFileTagPath ();	e->name            = name;}/* vi:set tabstop=4 shiftwidth=4: */

⌨️ 快捷键说明

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