/* `end' points to the equal sign. Parse from right to left to get the * identifier. Assume we're dealing with something of form \s*\w+\s*=> */ static void makeTagFromLeftSide (const char *begin, const char *end, vString *name, vString *package) { tagEntryInfo entry; const char *b, *e; if (! PerlKinds[K_CONSTANT].enabled) return; for (e = end - 1; e > begin && isspace(*e); --e) ; if (e < begin) return; for (b = e; b >= begin && isIdentifier(*b); --b) ; /* Identifier must be either beginning of line of have some whitespace * on its left: */ if (b < begin || isspace(*b) || ',' == *b) ++b; else if (b != begin) return; if (e - b + 1 <= 0) return; /* Left side of => has an invalid identifier. */ vStringClear(name); vStringNCatS(name, b, e - b + 1); initTagEntry(&entry, vStringValue(name), &(PerlKinds[K_CONSTANT])); makeTagEntry(&entry); if (Option.include.qualifiedTags && package && vStringLength(package)) { vStringClear(name); vStringCopy(name, package); vStringNCatS(name, b, e - b + 1); initTagEntry(&entry, vStringValue(name), &(PerlKinds[K_CONSTANT])); makeTagEntry(&entry); } }
static void makeTag (tokenInfo *const token, const goKind kind) { const char *const name = vStringValue (token->string); tagEntryInfo e; initTagEntry (&e, name); if (!GoKinds [kind].enabled) return; e.lineNumber = token->lineNumber; e.filePosition = token->filePosition; e.kindName = GoKinds [kind].name; e.kind = GoKinds [kind].letter; makeTagEntry (&e); if (scope && Option.include.qualifiedTags) { vString *qualifiedName = vStringNew (); vStringCopy (qualifiedName, scope); vStringCatS (qualifiedName, "."); vStringCat (qualifiedName, token->string); e.name = vStringValue (qualifiedName); makeTagEntry (&e); vStringDelete (qualifiedName); } }
static void makeEiffelFeatureTag (tokenInfo *const token) { if (EiffelKinds [EKIND_FEATURE].enabled && (token->isExported || isXtagEnabled(XTAG_FILE_SCOPE))) { const char *const name = vStringValue (token->string); tagEntryInfo e; initTagEntry (&e, name, &(EiffelKinds [EKIND_FEATURE])); e.isFileScope = (boolean) (! token->isExported); if (e.isFileScope) markTagExtraBit (&e, XTAG_FILE_SCOPE); e.extensionFields.scopeKind = &(EiffelKinds [EKIND_CLASS]); e.extensionFields.scopeName = vStringValue (token->className); makeTagEntry (&e); if (isXtagEnabled(XTAG_QUALIFIED_TAGS)) { vString* qualified = vStringNewInit (vStringValue (token->className)); vStringPut (qualified, '.'); vStringCat (qualified, token->string); e.name = vStringValue (qualified); markTagExtraBit (&e, XTAG_QUALIFIED_TAGS); makeTagEntry (&e); vStringDelete (qualified); } } vStringCopy (token->featureName, token->string); }
static void makeTag (tokenInfo *const token, const goKind kind, tokenInfo *const parent_token, const goKind parent_kind, const char *argList) { const char *const name = vStringValue (token->string); tagEntryInfo e; initTagEntry (&e, name, &(GoKinds [kind])); if (!GoKinds [kind].enabled) return; e.lineNumber = token->lineNumber; e.filePosition = token->filePosition; if (argList) e.extensionFields.signature = argList; if (parent_kind != GOTAG_UNDEFINED && parent_token != NULL) { e.extensionFields.scopeKind = &(GoKinds[parent_kind]); e.extensionFields.scopeName = vStringValue (parent_token->string); } makeTagEntry (&e); if (scope && isXtagEnabled(XTAG_QUALIFIED_TAGS)) { vString *qualifiedName = vStringNew (); vStringCopy (qualifiedName, scope); vStringCatS (qualifiedName, "."); vStringCat (qualifiedName, token->string); e.name = vStringValue (qualifiedName); makeTagEntry (&e); vStringDelete (qualifiedName); } }
static void makeEiffelFeatureTag (tokenInfo *const token) { if (EiffelKinds [EKIND_FEATURE].enabled && (token->isExported || Option.include.fileScope)) { const char *const name = vStringValue (token->string); tagEntryInfo e; initTagEntry (&e, name); e.isFileScope = (boolean) (! token->isExported); e.kindName = EiffelKinds [EKIND_FEATURE].name; e.kind = EiffelKinds [EKIND_FEATURE].letter; e.extensionFields.scope [0] = EiffelKinds [EKIND_CLASS].name; e.extensionFields.scope [1] = vStringValue (token->className); makeTagEntry (&e); if (Option.include.qualifiedTags) { vString* qualified = vStringNewInit (vStringValue (token->className)); vStringPut (qualified, '.'); vStringCat (qualified, token->string); e.name = vStringValue (qualified); makeTagEntry (&e); vStringDelete (qualified); } } vStringCopy (token->featureName, token->string); }
static void makePythonLoggingConfigTag (const char *section, const char *key, const char *value, void *userData) { tagEntryInfo e; if (section && (strncmp (LOGGER_PREFIX, section, LOGGER_LEN) == 0)) { if (key == NULL && value == NULL) { const char *logger = section + LOGGER_LEN; if (logger [0] == '\0') goto out; initTagEntry (&e, logger, PythonLoggingConfigKinds + K_LOGGER_SECTION); *((int *)userData) = makeTagEntry (&e); } else if (key && (strcmp (key, "qualname") == 0) && value && value[0] != '\0') { initTagEntry (&e, value, PythonLoggingConfigKinds + K_LOGGER_QUALNAME); e.extensionFields.scopeIndex = *((int *)userData); makeTagEntry (&e); } } out: return; }
static void makeJsTag (tokenInfo *const token, const jsKind kind, vString *const signature) { if (JsKinds [kind].enabled && ! token->ignoreTag ) { const char *name = vStringValue (token->string); vString *fullscope = vStringNewCopy (token->scope); const char *p; tagEntryInfo e; if ( (p = strrchr (name, '.')) != NULL ) { if (vStringLength (fullscope) > 0) vStringPut (fullscope, '.'); vStringNCatS (fullscope, name, (size_t) (p - name)); name = p + 1; } initTagEntry (&e, name); e.lineNumber = token->lineNumber; e.filePosition = token->filePosition; e.kindName = JsKinds [kind].name; e.kind = JsKinds [kind].letter; if ( vStringLength(fullscope) > 0 ) { jsKind parent_kind = JSTAG_CLASS; /* * If we're creating a function (and not a method), * guess we're inside another function */ if (kind == JSTAG_FUNCTION) parent_kind = JSTAG_FUNCTION; e.extensionFields.scope[0] = JsKinds [parent_kind].name; e.extensionFields.scope[1] = vStringValue (fullscope); } if (signature && vStringLength(signature)) { size_t i; /* sanitize signature by replacing all control characters with a * space (because it's simple). * there should never be any junk in a valid signature, but who * knows what the user wrote and CTags doesn't cope well with weird * characters. */ for (i = 0; i < signature->length; i++) { unsigned char c = (unsigned char) signature->buffer[i]; if (c < 0x20 /* below space */ || c == 0x7F /* DEL */) signature->buffer[i] = ' '; } e.extensionFields.signature = vStringValue(signature); } makeTagEntry (&e); vStringDelete (fullscope); } }
static void parse_class (xmlNode *node) { xmlNode *i; gchar *name; g_assert (node); name = (gchar*)xmlGetProp (node, (const xmlChar*)"name"); if (!name) return; tagEntryInfo *tag = (tagEntryInfo*)malloc (sizeof (tagEntryInfo)); initTagEntry (tag, name); tag->isFileScope = 1; tag->kindName = "class"; tag->kind = 'c'; get_file_pos (node->line, &tag->filePosition, File.fp); tag->lineNumber = node->line; makeTagEntry (tag); for (i = node->children; i; i = i->next) { makeTags (i, name); } }
static int makeDefineTag (const char *const name, bool parameterized, bool undef) { const bool isFileScope = (bool) (! isInputHeaderFile ()); if (!Cpp.defineMacroKind) return CORK_NIL; if (isFileScope && !isXtagEnabled(XTAG_FILE_SCOPE)) return CORK_NIL; if ( /* condition for definition tag */ ((!undef) && Cpp.defineMacroKind->enabled) || /* condition for reference tag */ (undef && isXtagEnabled(XTAG_REFERENCE_TAGS))) { tagEntryInfo e; initTagEntry (&e, name, Cpp.defineMacroKind); e.lineNumberEntry = (bool) (Option.locate == EX_LINENUM); e.isFileScope = isFileScope; e.truncateLine = true; if (parameterized) e.extensionFields.signature = cppGetSignature (); makeTagEntry (&e); if (parameterized) eFree((char *) e.extensionFields.signature); } return CORK_NIL; }
static void makeTxt2tagsTag (const vString* const name, const NestingLevels *const nls, Txt2tagsKind type) { tagEntryInfo e; vString *scope = NULL; kindOption *kind = &Txt2tagsKinds[type]; initTagEntry (&e, vStringValue(name)); e.kindName = kind->name; e.kind = kind->letter; if (nls->n > 0) { int i; kindOption *parentKind; scope = vStringNew(); for (i = 0; i < nls->n; i++) { if (vStringLength(scope) > 0) vStringPut(scope, SCOPE_SEPARATOR); vStringCat(scope, nls->levels[i].name); } parentKind = &Txt2tagsKinds[nls->levels[nls->n - 1].type]; e.extensionFields.scope[0] = parentKind->name; e.extensionFields.scope[1] = vStringValue(scope); } makeTagEntry(&e); vStringDelete(scope); }
static void makeTexTag (tokenInfo *const token, texKind kind) { if (TexKinds [kind].enabled) { const char *const name = vStringValue (token->string); vString *parentKind = vStringNew(); vString *parentName = vStringNew(); tagEntryInfo e; initTagEntry (&e, name); e.lineNumber = token->lineNumber; e.filePosition = token->filePosition; e.kindName = TexKinds [kind].name; e.kind = TexKinds [kind].letter; getScopeInfo(kind, parentKind, parentName); if (vStringLength(parentKind) > 0) { e.extensionFields.scope [0] = vStringValue(parentKind); e.extensionFields.scope [1] = vStringValue(parentName); } makeTagEntry (&e); vStringDelete (parentKind); vStringDelete (parentName); } }
static void makeRstTag(const vString* const name, const int kind, const MIOPos filepos, char marker) { const NestingLevel *const nl = getNestingLevel(kind); if (vStringLength (name) > 0) { tagEntryInfo e; char m [2] = { [1] = '\0' }; initTagEntry (&e, vStringValue (name), &(RstKinds [kind])); e.lineNumber--; /* we want the line before the '---' underline chars */ e.filePosition = filepos; if (nl && nl->kindIndex < kind) { e.extensionFields.scopeKind = &(RstKinds [nl->kindIndex]); e.extensionFields.scopeName = vStringValue (nl->name); } m[0] = marker; attachParserField (&e, RstFields [F_SECTION_MARKER].ftype, m); makeTagEntry (&e); }
/* Given a string with the contents of a line directly after the "def" keyword, * extract all relevant information and create a tag. */ static void makeFunctionTag (vString *const function, vString *const parent, int is_class_parent, const char *arglist) { tagEntryInfo tag; if (vStringLength (parent) > 0) { if (is_class_parent) { initTagEntry (&tag, vStringValue (function), &(PythonKinds[K_METHOD])); tag.extensionFields.scopeKind = &(PythonKinds[K_CLASS]); } else { initTagEntry (&tag, vStringValue (function), &(PythonKinds[K_FUNCTION])); tag.extensionFields.scopeKind = &(PythonKinds[K_FUNCTION]); } tag.extensionFields.scopeName = vStringValue (parent); } else initTagEntry (&tag, vStringValue (function), &(PythonKinds[K_FUNCTION])); tag.extensionFields.signature = arglist; addAccessFields (&tag, function, is_class_parent ? K_METHOD : K_FUNCTION, vStringLength (parent) > 0, is_class_parent); makeTagEntry (&tag); }
static void makeEiffelLocalTag (tokenInfo *const token) { if (EiffelKinds [EKIND_LOCAL].enabled && Option.include.fileScope) { const char *const name = vStringValue (token->string); vString* scope = vStringNew (); tagEntryInfo e; initTagEntry (&e, name); e.isFileScope = TRUE; e.kindName = EiffelKinds [EKIND_LOCAL].name; e.kind = EiffelKinds [EKIND_LOCAL].letter; vStringCopy (scope, token->className); vStringPut (scope, '.'); vStringCat (scope, token->featureName); e.extensionFields.scope [0] = EiffelKinds [EKIND_FEATURE].name; e.extensionFields.scope [1] = vStringValue (scope); makeTagEntry (&e); vStringDelete (scope); } }
/* * Emits a tag for the given 'name' of kind 'kind' at the current nesting. */ static void emitRubyTag (vString* name, rubyKind kind) { tagEntryInfo tag; vString* scope; if (!RubyKinds[kind].enabled) { return; } vStringTerminate (name); scope = stringListToScope (nesting); initTagEntry (&tag, vStringValue (name)); if (vStringLength (scope) > 0) { tag.extensionFields.scope [0] = "class"; tag.extensionFields.scope [1] = vStringValue (scope); } tag.kindName = RubyKinds [kind].name; tag.kind = RubyKinds [kind].letter; makeTagEntry (&tag); stringListAdd (nesting, vStringNewCopy (name)); vStringClear (name); vStringDelete (scope); }
/* Ensure a constructor is not a type path beginning * with a module */ static void constructorValidation (vString * const ident, ocaToken what) { switch (what) { case Tok_Op: /* if we got a '.' which is an operator */ toDoNext = &globalScope; popStrongContext (); needStrongPoping = FALSE; break; case OcaKEYWORD_of: /* OK, it must be a constructor :) */ if (vStringLength (tempIdent) > 0) { makeTagEntry (&tempTag); vStringClear (tempIdent); } toDoNext = &tillTokenOrFallback; comeAfter = &typeSpecification; waitedToken = Tok_Pipe; break; case Tok_Pipe: /* OK, it was a constructor :) */ if (vStringLength (tempIdent) > 0) { makeTagEntry (&tempTag); vStringClear (tempIdent); } toDoNext = &typeSpecification; break; default: /* and mean that we're not facing a module name */ if (vStringLength (tempIdent) > 0) { makeTagEntry (&tempTag); vStringClear (tempIdent); } toDoNext = &tillTokenOrFallback; comeAfter = &typeSpecification; waitedToken = Tok_Pipe; /* nothing in the context, discard it */ popStrongContext (); /* to be sure we use this token */ globalScope (ident, what); } }
static void makeSmlTag (smlKind type, vString *name) { tagEntryInfo tag; initTagEntry (&tag, vStringValue (name)); tag.kindName = SmlKinds [type].name; tag.kind = SmlKinds [type].letter; makeTagEntry (&tag); }
static void makeTag (struct p6Ctx *ctx, int kind, const char *name, int len) { tagEntryInfo entry; vStringNCopyS(ctx->name, name, len); initTagEntry(&entry, vStringValue(ctx->name), &(perl6Kinds[kind])); makeTagEntry(&entry); }
static void makeTagWithScope (xmlNode *node, const struct sTagXpathMakeTagSpec *spec, struct sTagEntryInfo *tag, void *userData) { tag->extensionFields.scopeKind = userData? PlistKinds + K_KEY: NULL; tag->extensionFields.scopeName = userData; makeTagEntry (tag); }
/* Used to centralise tag creation, and be able to add * more information to it in the future */ static void addTag (vString * const ident, int kind) { if (OcamlKinds [kind].enabled && ident != NULL && vStringLength (ident) > 0) { tagEntryInfo toCreate; prepareTag (&toCreate, ident, kind); makeTagEntry (&toCreate); } }
static void makeBetaTag (const char* const name, const betaKind kind) { if (BetaKinds [kind].enabled) { tagEntryInfo e; initTagEntry (&e, name, & (BetaKinds [kind])); makeTagEntry (&e); } }
/* Used to centralise tag creation, and be able to add * more information to it in the future */ static int addTag (vString * const ident, int kind) { tagEntryInfo toCreate; if (! ObjcKinds[kind].enabled) return CORK_NIL; prepareTag (&toCreate, ident, kind); return makeTagEntry (&toCreate); }
static void makeRTag (const vString * const name, rKind kind) { tagEntryInfo e; Assert (kind < KIND_COUNT); initTagEntry (&e, vStringValue (name), &(RKinds[kind])); makeTagEntry (&e); }
static void makeTag (struct p6Ctx *ctx, int kind, const char *name, int len) { tagEntryInfo entry; vStringNCopyS(ctx->name, name, len); initTagEntry(&entry, vStringValue(ctx->name)); entry.kind = perl6Kinds[kind].letter; entry.kindName = perl6Kinds[kind].name; makeTagEntry(&entry); }
static void makeRTag(const vString* const name, int kind) { tagEntryInfo e; initTagEntry(&e, vStringValue(name)); e.kindName = RKinds[kind].name; e.kind = RKinds[kind].letter; makeTagEntry(&e); }
static void makeAbcTag (const vString* const name, boolean name_before) { tagEntryInfo e; initTagEntry (&e, vStringValue(name), &(AbcKinds[0])); if (name_before) e.lineNumber--; /* we want the line before the underline chars */ makeTagEntry(&e); }
static void makeTagWithProvidingScope (xmlNode *node, const tagXpathMakeTagSpec *spec, struct sTagEntryInfo *tag, void *userData) { int *index = (int *)userData; tag->extensionFields.scopeIndex = *index; *index = makeTagEntry (tag); }
static void createProtobufTag (const vString *name, int kind) { static tagEntryInfo tag; if (ProtobufKinds [kind].enabled) { initTagEntry (&tag, vStringValue (name), kind); makeTagEntry (&tag); } }
/* * Emits a tag for the given 'name' of kind 'kind' at the current nesting. */ static void emitRubyTag (vString* name, rubyKind kind) { tagEntryInfo tag; vString* scope; tagEntryInfo *parent; rubyKind parent_kind = K_UNDEFINED; NestingLevel *lvl; const char *unqualified_name; const char *qualified_name; int r; if (!RubyKinds[kind].enabled) { return; } vStringTerminate (name); scope = nestingLevelsToScope (nesting); lvl = nestingLevelsGetCurrent (nesting); parent = getEntryOfNestingLevel (lvl); if (parent) parent_kind = parent->kind - RubyKinds; qualified_name = vStringValue (name); unqualified_name = strrchr (qualified_name, SCOPE_SEPARATOR); if (unqualified_name && unqualified_name[1]) { if (unqualified_name > qualified_name) { if (vStringLength (scope) > 0) vStringPut (scope, SCOPE_SEPARATOR); vStringNCatS (scope, qualified_name, unqualified_name - qualified_name); /* assume module parent type for a lack of a better option */ parent_kind = K_MODULE; } unqualified_name++; } else unqualified_name = qualified_name; initTagEntry (&tag, unqualified_name, &(RubyKinds [kind])); if (vStringLength (scope) > 0) { Assert (0 <= parent_kind && (size_t) parent_kind < (ARRAY_SIZE (RubyKinds))); tag.extensionFields.scopeKind = &(RubyKinds [parent_kind]); tag.extensionFields.scopeName = vStringValue (scope); } r = makeTagEntry (&tag); nestingLevelsPush (nesting, r); vStringClear (name); vStringDelete (scope); }
static void makeBetaTag (const char* const name, const betaKind kind) { if (BetaKinds [kind].enabled) { tagEntryInfo e; initTagEntry (&e, name); e.kindName = BetaKinds [kind].name; e.kind = BetaKinds [kind].letter; makeTagEntry (&e); } }