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

📄 entry.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 2 页
字号:
	    {
		length += fprintf(TagFile.fp, "%s%s:%s", separator,
				  getTypeString(pMember->type),pMember->parent);

		if ((File.language == LANG_CPP || File.language == LANG_JAVA) &&
		    pMember->visibility != VIS_UNDEFINED)
		{
		    length += fprintf(TagFile.fp, "%s%s:", separator,
				    getVisibilityString(pMember->visibility));
		}
	    }
	    break;
	}
    }
    return length;
}

static int writeLineNumberEntry( tag )
    const tagInfo *const tag;
{
    return fprintf(TagFile.fp, "%lu", tag->lineNumber);
}

static int writePatternEntry( tag, type )
    const tagInfo *const tag;
    const tagType type;
{
    char *const line = getSourceLine(&TagFile.line, tag->location);
    const int searchChar = Option.backward ? '?' : '/';
    boolean newlineTerminated;
    int length = 0;

    if (type == TAG_DEFINE_OBJ  ||  type == TAG_DEFINE_FUNC)
	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 writeCtagsEntry( tag, pMember, scope, type, useLineNumber )
    const tagInfo *const tag;
    const memberInfo *const pMember;
    const tagScope scope;
    const tagType type;
    const boolean useLineNumber;
{
    int length = fprintf(TagFile.fp, "%s\t%s\t", tag->name, File.name);

    if (useLineNumber || type == TAG_SOURCE_FILE)
	length += writeLineNumberEntry(tag);
    else
	length += writePatternEntry(tag, type);

    if (includeExtensionFlags())
	length += addExtensionFlags(pMember, scope, type);

    length += fprintf(TagFile.fp, "\n");

    return length;
}

static void writeTagEntry( tag, pMember, scope, type, useLineNumber )
    const tagInfo *const tag;
    const memberInfo *const pMember;
    const tagScope scope;
    const tagType type;
    const boolean useLineNumber;
{
    size_t length;

    if (Option.etags)
	length = writeEtagsEntry(tag, pMember, scope, type);
    else
	length = writeCtagsEntry(tag, pMember, scope, type, useLineNumber);

    ++TagFile.numTags.added;
    rememberMaxLengths(strlen(tag->name), length);
}

static boolean includeTag( scope, type )
    const tagScope scope;
    const tagType type;
{
    boolean include;

    if (scope == SCOPE_STATIC  &&  ! Option.include.statics)
	include = FALSE;
    else switch (type)
    {
	case TAG_CLASS:		include = Option.include.classNames;	break;
	case TAG_DEFINE_OBJ:
	case TAG_DEFINE_FUNC:	include = Option.include.defines;	break;
	case TAG_ENUM:		include = Option.include.enumNames;	break;
	case TAG_ENUMERATOR:	include = Option.include.enumerators;	break;
	case TAG_FUNCDECL:	include = Option.include.prototypes;	break;
	case TAG_FUNCTION:	include = Option.include.functions;	break;
	case TAG_INTERFACE:	include = Option.include.interfaceNames;break;
	case TAG_MEMBER:	include = Option.include.members;	break;
	case TAG_NAMESPACE:	include = Option.include.namespaceNames;break;
	case TAG_SOURCE_FILE:	include = Option.include.sourceFiles;	break;
	case TAG_STRUCT:	include = Option.include.structNames;	break;
	case TAG_TYPEDEF:	include = Option.include.typedefs;	break;
	case TAG_UNION:		include = Option.include.unionNames;	break;
	case TAG_VARIABLE:	include = Option.include.variables;	break;
	case TAG_EXTERN_VAR:	include = Option.include.externVars;	break;
	default:		include = FALSE;			break;
    }
    return include;
}

static void writeExtraMemberTagEntry( tag, pMember, scope, type,
				      useLineNumber, format )
    const tagInfo *const tag;
    const memberInfo *const pMember;
    const tagScope scope;
    const tagType type;
    const boolean useLineNumber;
    const char *const format;
{
    switch (type)
    {
	case TAG_FUNCDECL:
	case TAG_FUNCTION:
	case TAG_MEMBER:
	{
	    tagInfo prefixedTag;

	    prefixedTag = *tag;
	    sprintf(prefixedTag.name, format, pMember->parent, tag->name);
	    writeTagEntry(&prefixedTag, pMember, scope, type, useLineNumber);
	}
	default: break;
    }
}

static void makeExtraMemberTagEntry( tag, pMember, scope, type, useLineNumber )
    const tagInfo *const tag;
    const memberInfo *const pMember;
    const tagScope scope;
    const tagType type;
    const boolean useLineNumber;
{
    if (File.language == LANG_CPP  &&
	(pMember->type == MEMBER_CLASS  ||  pMember->type == MEMBER_STRUCT))
    {
	writeExtraMemberTagEntry(tag, pMember, scope, type, useLineNumber, "%s::%s");
    }
    else if (File.language == LANG_JAVA  &&  pMember->type == MEMBER_CLASS)
    {
	writeExtraMemberTagEntry(tag, pMember, scope, type, useLineNumber, "%s.%s");
    }
}

/*  This function generates a tag for the object in name, whose tag line is
 *  located at a given seek offset.
 */
static void makeTagEntry( tag, pMember, scope, type, useLineNumber )
    const tagInfo *const tag;
    const memberInfo *const pMember;
    const tagScope scope;
    const tagType type;
    const boolean useLineNumber;
{
    if (includeTag(scope, type)  &&  tag->name[0] != '\0')
    {
	if (Option.xref)
	    writeXrefEntry(tag, type);
	else
	{
	    writeTagEntry(tag, pMember, scope, type, useLineNumber);
	    if (Option.include.classPrefix  &&  pMember->parent[0] != '0')
		makeExtraMemberTagEntry(tag, pMember, scope, type, useLineNumber);
	}
	DebugStatement( debugEntry(scope, type, tag->name, pMember); )
    }
}

extern void makeTag( tag, pMember, scope, type )
    const tagInfo *const tag;
    const memberInfo *const pMember;
    const tagScope scope;
    const tagType type;
{
    makeTagEntry(tag, pMember, scope, type,
		 (boolean)(Option.locate == EX_LINENUM));
}

extern void makeDefineTag( tag, scope, parameterized )
    const tagInfo *const tag;
    const tagScope scope;
    const boolean parameterized;
{
    const tagType type = (parameterized ? TAG_DEFINE_FUNC : TAG_DEFINE_OBJ);

    makeTagEntry(tag, &NoClass, scope, type,
		 (boolean)(Option.locate != EX_PATTERN));
}

/*----------------------------------------------------------------------------
*-	Pseudo tag support
----------------------------------------------------------------------------*/

static void writePseudoTag( tagName, fileName, pattern )
    const char *const tagName;
    const char *const fileName;
    const char *const pattern;
{
    const size_t length = fprintf(TagFile.fp, "%s%s\t%s\t/%s/\n",
				 PSEUDO_TAG_PREFIX, tagName, fileName, pattern);
    ++TagFile.numTags.added;
    rememberMaxLengths(strlen(tagName), length);
}

extern void addPseudoTags()
{
    if (! Option.xref  &&  ! Option.etags)
    {
	char format[11];
	const char *formatComment = "unknown format";

	sprintf(format, "%u", Option.tagFileFormat);

	if (Option.tagFileFormat == 1)
	    formatComment = "original ctags format";
	else if (Option.tagFileFormat == 2)
	    formatComment =
		    "extended format; --format=1 will not append ;\" to lines";

	writePseudoTag("TAG_FILE_FORMAT", format, formatComment);
	writePseudoTag("TAG_FILE_SORTED", Option.sorted ? "1":"0",
		       "0=unsorted, 1=sorted");
	writePseudoTag("TAG_PROGRAM_AUTHOR",	AUTHOR_NAME,  AUTHOR_EMAIL);
	writePseudoTag("TAG_PROGRAM_NAME",	PROGRAM_NAME, "");
	writePseudoTag("TAG_PROGRAM_URL",	PROGRAM_URL,  "official site");
	writePseudoTag("TAG_PROGRAM_VERSION",	PROGRAM_VERSION,
		       "with C++ and Java support");
    }
}

static void updateSortedFlag( line, fp, startOfLine )
    const char *const line;
    FILE *const fp;
    const long startOfLine;
{
    const char *const tab = strchr(line, '\t');

    if (tab != NULL)
    {
	const long boolOffset = tab - line + 1;	/* where it should be */

	if (line[boolOffset] == '0'  ||  line[boolOffset] == '1')
	{
	    const long nextLine = ftell(fp);

	    fseek(fp, startOfLine + boolOffset, SEEK_SET);
	    fputc(Option.sorted ? '1' : '0', fp);
	    fseek(fp, nextLine, SEEK_SET);
	}
    }
}

/*  Look through all line beginning with "!_TAG_FILE", and update those which
 *  require it.
 */
extern unsigned long updatePseudoTags()
{
    enum { maxClassLength = 20 };
    char class[maxClassLength + 1];
    FILE *const fp = TagFile.fp;
    long startOfLine = 0;
    unsigned long linesRead = 0;
    size_t classLength;
    const char *line;

    sprintf(class, "%sTAG_FILE", PSEUDO_TAG_PREFIX);
    classLength = strlen(class);
    DebugStatement( assert(classLength < maxClassLength); )
    rewind(fp);
    line = readLine(&TagFile.line, fp);
    while (line != NULL  &&  line[0] == class[0])
    {
	++linesRead;
	if (strncmp(line, class, classLength) == 0)
	{
	    char tab, classType[16];

	    if (sscanf(line + classLength, "%15s%c", classType, &tab) == 2  &&
		tab == '\t')
	    {
		if (strcmp(classType, "_SORTED") == 0)
		    updateSortedFlag(line, fp, startOfLine);
	    }
	    startOfLine = ftell(fp);
	}
	line = readLine(&TagFile.line, fp);
    }
    while (line != NULL)			/* skip to end of file */
    {
	++linesRead;
	line = readLine(&TagFile.line, fp);
    }
    return linesRead;
}

/* vi:set tabstop=8 shiftwidth=4: */

⌨️ 快捷键说明

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