📄 c.c
字号:
{ 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 + -