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

📄 c.c

📁 Exuberant Ctags is a multilanguage reimplementation of the much-underused ctags(1) program and is i
💻 C
📖 第 1 页 / 共 5 页
字号:
{	tagType type = TAG_UNDEFINED;	switch (declaration)	{		case DECL_CLASS:        type = TAG_CLASS;       break;		case DECL_ENUM:         type = TAG_ENUM;        break;		case DECL_EVENT:        type = TAG_EVENT;       break;		case DECL_FUNCTION:     type = TAG_FUNCTION;    break;		case DECL_INTERFACE:    type = TAG_INTERFACE;   break;		case DECL_NAMESPACE:    type = TAG_NAMESPACE;   break;		case DECL_PROGRAM:      type = TAG_PROGRAM;     break;		case DECL_TASK:         type = TAG_TASK;        break;		case DECL_STRUCT:       type = TAG_STRUCT;      break;		case DECL_UNION:        type = TAG_UNION;       break;		default: Assert ("Unexpected declaration" == NULL); break;	}	return type;}static const char* accessField (const statementInfo *const st){	const char* result = NULL;	if (isLanguage (Lang_cpp)  &&  st->scope == SCOPE_FRIEND)		result = "friend";	else if (st->member.access != ACCESS_UNDEFINED)		result = accessString (st->member.access);	return result;}static void addContextSeparator (vString *const scope){	if (isLanguage (Lang_c)  ||  isLanguage (Lang_cpp))		vStringCatS (scope, "::");	else if (isLanguage (Lang_java) || isLanguage (Lang_csharp))		vStringCatS (scope, ".");}static void addOtherFields (tagEntryInfo* const tag, const tagType type,							const statementInfo *const st,							vString *const scope, vString *const typeRef){	/*  For selected tag types, append an extension flag designating the	 *  parent object in which the tag is defined.	 */	switch (type)	{		default: break;		case TAG_FUNCTION:		case TAG_METHOD:		case TAG_PROTOTYPE:			if (vStringLength (Signature) > 0)				tag->extensionFields.signature = vStringValue (Signature);		case TAG_CLASS:		case TAG_ENUM:		case TAG_ENUMERATOR:		case TAG_EVENT:		case TAG_FIELD:		case TAG_INTERFACE:		case TAG_MEMBER:		case TAG_NAMESPACE:		case TAG_PROPERTY:		case TAG_STRUCT:		case TAG_TASK:		case TAG_TYPEDEF:		case TAG_UNION:			if (vStringLength (scope) > 0  &&				(isMember (st) || st->parent->declaration == DECL_NAMESPACE))			{				if (isType (st->context, TOKEN_NAME))					tag->extensionFields.scope [0] = tagName (TAG_CLASS);				else					tag->extensionFields.scope [0] =						tagName (declToTagType (parentDecl (st)));				tag->extensionFields.scope [1] = vStringValue (scope);			}			if ((type == TAG_CLASS  ||  type == TAG_INTERFACE  ||				 type == TAG_STRUCT) && vStringLength (st->parentClasses) > 0)			{				tag->extensionFields.inheritance =						vStringValue (st->parentClasses);			}			if (st->implementation != IMP_DEFAULT &&				(isLanguage (Lang_cpp) || isLanguage (Lang_csharp) ||				 isLanguage (Lang_java)))			{				tag->extensionFields.implementation =						implementationString (st->implementation);			}			if (isMember (st))			{				tag->extensionFields.access = accessField (st);			}			break;	}	/* Add typename info, type of the tag and name of struct/union/etc. */	if ((type == TAG_TYPEDEF || type == TAG_VARIABLE || type == TAG_MEMBER)			&& isContextualStatement(st))	{		char *p;		tag->extensionFields.typeRef [0] =						tagName (declToTagType (st->declaration));		p = vStringValue (st->blockName->name);		/*  If there was no {} block get the name from the token before the		 *  name (current token is ';' or ',', previous token is the name).		 */		if (p == NULL || *p == '\0')		{			tokenInfo *const prev2 = prevToken (st, 2);			if (isType (prev2, TOKEN_NAME))				p = vStringValue (prev2->name);		}		/* Prepend the scope name if there is one. */		if (vStringLength (scope) > 0)		{			vStringCopy(typeRef, scope);			addContextSeparator (typeRef);			vStringCatS(typeRef, p);			p = vStringValue (typeRef);		}		tag->extensionFields.typeRef [1] = p;	}}static void findScopeHierarchy (vString *const string,								const statementInfo *const st){	vStringClear (string);	if (isType (st->context, TOKEN_NAME))		vStringCopy (string, st->context->name);	if (st->parent != NULL)	{		vString *temp = vStringNew ();		const statementInfo *s;		for (s = st->parent  ;  s != NULL  ;  s = s->parent)		{			if (isContextualStatement (s) ||				s->declaration == DECL_NAMESPACE ||				s->declaration == DECL_PROGRAM)			{				vStringCopy (temp, string);				vStringClear (string);				Assert (isType (s->blockName, TOKEN_NAME));				if (isType (s->context, TOKEN_NAME) &&					vStringLength (s->context->name) > 0)				{					vStringCat (string, s->context->name);					addContextSeparator (string);				}				vStringCat (string, s->blockName->name);				if (vStringLength (temp) > 0)					addContextSeparator (string);				vStringCat (string, temp);			}		}		vStringDelete (temp);	}}static void makeExtraTagEntry (const tagType type, tagEntryInfo *const e,							   vString *const scope){	if (Option.include.qualifiedTags  &&		scope != NULL  &&  vStringLength (scope) > 0)	{		vString *const scopedName = vStringNew ();		if (type != TAG_ENUMERATOR)			vStringCopy (scopedName, scope);		else		{			/* remove last component (i.e. enumeration name) from scope */			const char* const sc = vStringValue (scope);			const char* colon = strrchr (sc, ':');			if (colon != NULL)			{				while (*colon == ':'  &&  colon > sc)					--colon;				vStringNCopy (scopedName, scope, colon + 1 - sc);			}		}		if (vStringLength (scopedName) > 0)		{			addContextSeparator (scopedName);			vStringCatS (scopedName, e->name);			e->name = vStringValue (scopedName);			makeTagEntry (e);		}		vStringDelete (scopedName);	}}static void makeTag (const tokenInfo *const token,					 const statementInfo *const st,					 boolean isFileScope, const tagType type){	/*  Nothing is really of file scope when it appears in a header file.	 */	isFileScope = (boolean) (isFileScope && ! isHeaderFile ());	if (isType (token, TOKEN_NAME)  &&  vStringLength (token->name) > 0  &&		includeTag (type, isFileScope))	{		vString *scope = vStringNew ();		/* Use "typeRef" to store the typename from addOtherFields() until		 * it's used in makeTagEntry().		 */		vString *typeRef = vStringNew ();		tagEntryInfo e;		initTagEntry (&e, vStringValue (token->name));		e.lineNumber	= token->lineNumber;		e.filePosition	= token->filePosition;		e.isFileScope	= isFileScope;		e.kindName		= tagName (type);		e.kind			= tagLetter (type);		findScopeHierarchy (scope, st);		addOtherFields (&e, type, st, scope, typeRef);		makeTagEntry (&e);		makeExtraTagEntry (type, &e, scope);		vStringDelete (scope);		vStringDelete (typeRef);	}}static boolean isValidTypeSpecifier (const declType declaration){	boolean result;	switch (declaration)	{		case DECL_BASE:		case DECL_CLASS:		case DECL_ENUM:		case DECL_EVENT:		case DECL_STRUCT:		case DECL_UNION:			result = TRUE;			break;		default:			result = FALSE;			break;	}	return result;}static void qualifyEnumeratorTag (const statementInfo *const st,								  const tokenInfo *const nameToken){	if (isType (nameToken, TOKEN_NAME))		makeTag (nameToken, st, TRUE, TAG_ENUMERATOR);}static void qualifyFunctionTag (const statementInfo *const st,								const tokenInfo *const nameToken){	if (isType (nameToken, TOKEN_NAME))	{		tagType type;		const boolean isFileScope =						(boolean) (st->member.access == ACCESS_PRIVATE ||						(!isMember (st)  &&  st->scope == SCOPE_STATIC));		if (isLanguage (Lang_java) || isLanguage (Lang_csharp))			type = TAG_METHOD;		else if (isLanguage (Lang_vera)  &&  st->declaration == DECL_TASK)			type = TAG_TASK;		else			type = TAG_FUNCTION;		makeTag (nameToken, st, isFileScope, type);	}}static void qualifyFunctionDeclTag (const statementInfo *const st,									const tokenInfo *const nameToken){	if (! isType (nameToken, TOKEN_NAME))		;	else if (isLanguage (Lang_java) || isLanguage (Lang_csharp))		qualifyFunctionTag (st, nameToken);	else if (st->scope == SCOPE_TYPEDEF)		makeTag (nameToken, st, TRUE, TAG_TYPEDEF);	else if (isValidTypeSpecifier (st->declaration) && ! isLanguage (Lang_csharp))		makeTag (nameToken, st, TRUE, TAG_PROTOTYPE);}static void qualifyCompoundTag (const statementInfo *const st,								const tokenInfo *const nameToken){	if (isType (nameToken, TOKEN_NAME))	{		const tagType type = declToTagType (st->declaration);		const boolean fileScoped = (boolean)				(!(isLanguage (Lang_java) ||				   isLanguage (Lang_csharp) ||				   isLanguage (Lang_vera)));		if (type != TAG_UNDEFINED)			makeTag (nameToken, st, fileScoped, type);	}}static void qualifyBlockTag (statementInfo *const st,							 const tokenInfo *const nameToken){	switch (st->declaration)	{		case DECL_CLASS:		case DECL_ENUM:		case DECL_INTERFACE:		case DECL_NAMESPACE:		case DECL_PROGRAM:		case DECL_STRUCT:		case DECL_UNION:			qualifyCompoundTag (st, nameToken);			break;		default: break;	}}static void qualifyVariableTag (const statementInfo *const st,								const tokenInfo *const nameToken){	/*	We have to watch that we do not interpret a declaration of the	 *	form "struct tag;" as a variable definition. In such a case, the	 *	token preceding the name will be a keyword.	 */	if (! isType (nameToken, TOKEN_NAME))		;	else if (st->scope == SCOPE_TYPEDEF)		makeTag (nameToken, st, TRUE, TAG_TYPEDEF);	else if (st->declaration == DECL_EVENT)		makeTag (nameToken, st, (boolean) (st->member.access == ACCESS_PRIVATE),				TAG_EVENT);	else if (st->declaration == DECL_PACKAGE)		makeTag (nameToken, st, FALSE, TAG_PACKAGE);	else if (isValidTypeSpecifier (st->declaration))	{		if (st->notVariable)			;		else if (isMember (st))		{			if (isLanguage (Lang_java) || isLanguage (Lang_csharp))				makeTag (nameToken, st,						(boolean) (st->member.access == ACCESS_PRIVATE), TAG_FIELD);			else if (st->scope == SCOPE_GLOBAL  ||  st->scope == SCOPE_STATIC)				makeTag (nameToken, st, TRUE, TAG_MEMBER);		}		else		{			if (st->scope == SCOPE_EXTERN  ||  ! st->haveQualifyingName)				makeTag (nameToken, st, FALSE, TAG_EXTERN_VAR);			else if (st->inFunction)				makeTag (nameToken, st, (boolean) (st->scope == SCOPE_STATIC),						TAG_LOCAL);			else				makeTag (nameToken, st, (boolean) (st->scope == SCOPE_STATIC),						TAG_VARIABLE);		}	}}/**   Parsing functions*/static int skipToOneOf (const char *const chars){	int c;	do		c = cppGetc ();	while (c != EOF  &&  c != '\0'  &&  strchr (chars, c) == NULL);	return c;}/*  Skip to the next non-white character. */static int skipToNonWhite (void){	boolean found = FALSE;	int c;#if 0	do		c = cppGetc ();	while (isspace (c));#else	while (1)	{		c = cppGetc ();		if (isspace (c))			found = TRUE;		else			break;	}	if (CollectingSignature && found)		vStringPut (Signature, ' ');#endif	return c;}/*  Skips to the next brace in column 1. This is intended for cases where *  preprocessor constructs result in unbalanced braces. */static void skipToFormattedBraceMatch (void){	int c, next;	c = cppGetc ();	next = cppGetc ();	while (c != EOF  &&  (c != '\n'  ||  next != '}'))	{		c = next;		next = cppGetc ();	}}/*  Skip to the matching character indicated by the pair string. If skipping *  to a matching brace and any brace is found within a different level of a *  #if conditional statement while brace formatting is in effect, we skip to *  the brace matched by its formatting. It is assumed that we have already *  read the character which starts the group (i.e. the first character of *  "pair"). */static void skipToMatch (const char *const pair){	const boolean braceMatching = (boolean) (strcmp ("{}", pair) == 0);	const boolean braceFormatting = (boolean) (isBraceFormat () && braceMatching);	const unsigned int initialLevel = getDirectiveNestLevel ();	const int begin = pair [0], end = pair [1];	const unsigned long inputLineNumber = getInputLineNumber ();	int matchLevel = 1;	int c = '\0';	while (matchLevel > 0  &&  (c = skipToNonWhite ()) != EOF)	{		if (CollectingSignature)			vStringPut (Signature, c);		if (c == begin)		{			++matchLevel;			if (braceFormatting  &&  getDirectiveNestLevel () != initialLevel)			{				skipToFormattedBraceMatch ();				break;			}		}		else if (c == end)		{			--matchLevel;			if (braceFormatting  &&  getDirectiveNestLevel () != initialLevel)			{

⌨️ 快捷键说明

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