📄 c.c
字号:
else if (isLanguage (Lang_vera))
result = VeraKinds [veraTagKind (type)].enabled;
else
result = CKinds [cTagKind (type)].enabled;
return result;
}
static tagType declToTagType (const declType declaration)
{
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 addOtherFields (tagEntryInfo* const tag, const tagType type,
const statementInfo *const st, vString *const scope)
{
/* 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;
}
}
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 findScopeHierarchy (vString *const string,
const statementInfo *const st)
{
const char* const anon = "<anonymous>";
boolean nonAnonPresent = FALSE;
vStringClear (string);
if (isType (st->context, TOKEN_NAME))
{
vStringCopy (string, st->context->name);
nonAnonPresent = TRUE;
}
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);
if (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);
nonAnonPresent = TRUE;
}
else
vStringCopyS (string, anon);
if (vStringLength (temp) > 0)
addContextSeparator (string);
vStringCat (string, temp);
}
}
vStringDelete (temp);
if (! nonAnonPresent)
vStringClear (string);
}
}
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 ();
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);
makeTagEntry (&e);
makeExtraTagEntry (type, &e, scope);
vStringDelete (scope);
}
}
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)
{
skipToFormattedBraceMatch ();
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -