[geany/geany] 8e804b: entry: Add the remaining code from uctags
Jiří Techet
git-noreply at xxxxx
Mon Dec 17 21:05:45 UTC 2018
Branch: refs/heads/master
Author: Jiří Techet <techet at gmail.com>
Committer: Jiří Techet <techet at gmail.com>
Date: Sun, 09 Oct 2016 17:58:24 UTC
Commit: 8e804b3145db03b674e634fab876979d04df424e
https://github.com/geany/geany/commit/8e804b3145db03b674e634fab876979d04df424e
Log Message:
-----------
entry: Add the remaining code from uctags
Also enable compilation of forgotten kind.c
Modified Paths:
--------------
ctags/Makefile.am
ctags/main/entry.c
ctags/main/entry.h
ctags/main/parse.c
Modified: ctags/Makefile.am
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -77,6 +77,7 @@ libctags_la_SOURCES = \
main/htable.h \
main/keyword.c \
main/keyword.h \
+ main/kind.c \
main/kind.h \
main/lcpp.c \
main/lcpp.h \
Modified: ctags/main/entry.c
782 lines changed, 777 insertions(+), 5 deletions(-)
===================================================================
@@ -295,7 +295,70 @@ static long unsigned int updatePseudoTags (MIO *const mio)
* Tag file management
*/
+static bool isValidTagAddress (const char *const excmd)
+{
+ bool isValid = false;
+
+ if (strchr ("/?", excmd [0]) != NULL)
+ isValid = true;
+ else
+ {
+ char *address = xMalloc (strlen (excmd) + 1, char);
+ if (sscanf (excmd, "%[^;\n]", address) == 1 &&
+ strspn (address,"0123456789") == strlen (address))
+ isValid = true;
+ eFree (address);
+ }
+ return isValid;
+}
+
+static bool isCtagsLine (const char *const line)
+{
+ enum fieldList { TAG, TAB1, SRC_FILE, TAB2, EXCMD, NUM_FIELDS };
+ bool ok = false; /* we assume not unless confirmed */
+ const size_t fieldLength = strlen (line) + 1;
+ char *const fields = xMalloc (NUM_FIELDS * fieldLength, char);
+ if (fields == NULL)
+ error (FATAL, "Cannot analyze tag file");
+ else
+ {
+#define field(x) (fields + ((size_t) (x) * fieldLength))
+
+ const int numFields = sscanf (
+ line, "%[^\t]%[\t]%[^\t]%[\t]%[^\r\n]",
+ field (TAG), field (TAB1), field (SRC_FILE),
+ field (TAB2), field (EXCMD));
+
+ /* There must be exactly five fields: two tab fields containing
+ * exactly one tab each, the tag must not begin with "#", and the
+ * file name should not end with ";", and the excmd must be
+ * acceptable.
+ *
+ * These conditions will reject tag-looking lines like:
+ * int a; <C-comment>
+ * #define LABEL <C-comment>
+ */
+ if (numFields == NUM_FIELDS &&
+ strlen (field (TAB1)) == 1 &&
+ strlen (field (TAB2)) == 1 &&
+ field (TAG) [0] != '#' &&
+ field (SRC_FILE) [strlen (field (SRC_FILE)) - 1] != ';' &&
+ isValidTagAddress (field (EXCMD)))
+ ok = true;
+
+ eFree (fields);
+ }
+ return ok;
+}
+
+static bool isEtagsLine (const char *const line)
+{
+ bool result = false;
+ if (line [0] == '\f')
+ result = (bool) (line [1] == '\n' || line [1] == '\r');
+ return result;
+}
static bool isTagFile (const char *const filename)
{
@@ -310,6 +373,8 @@ static bool isTagFile (const char *const filename)
if (line == NULL)
ok = true;
+ else
+ ok = (bool) (isCtagsLine (line) || isEtagsLine (line));
mio_free (mio);
}
return ok;
@@ -436,10 +501,576 @@ static int replacementTruncate (const char *const name, const long size)
#endif
+#ifndef EXTERNAL_SORT
+static void internalSortTagFile (void)
+{
+ MIO *mio;
+
+ /* Open/Prepare the tag file and place its lines into allocated buffers.
+ */
+ if (TagsToStdout)
+ {
+ mio = TagFile.mio;
+ mio_seek (mio, 0, SEEK_SET);
+ }
+ else
+ {
+ mio = mio_new_file (tagFileName (), "r");
+ if (mio == NULL)
+ failedSort (mio, NULL);
+ }
+
+ internalSortTags (TagsToStdout,
+ mio,
+ TagFile.numTags.added + TagFile.numTags.prev);
+
+ if (! TagsToStdout)
+ mio_free (mio);
+}
+#endif
+
+static void sortTagFile (void)
+{
+ if (TagFile.numTags.added > 0L)
+ {
+ if (Option.sorted != SO_UNSORTED)
+ {
+ verbose ("sorting tag file\n");
+#ifdef EXTERNAL_SORT
+ externalSortTags (TagsToStdout, TagFile.mio);
+#else
+ internalSortTagFile ();
+#endif
+ }
+ else if (TagsToStdout)
+ catFile (TagFile.mio);
+ }
+}
+
+static void resizeTagFile (const long newSize)
+{
+ int result;
+
+#ifdef USE_REPLACEMENT_TRUNCATE
+ result = replacementTruncate (TagFile.name, newSize);
+#else
+# ifdef HAVE_TRUNCATE
+ result = truncate (TagFile.name, (off_t) newSize);
+# else
+ const int fd = open (TagFile.name, O_RDWR);
+
+ if (fd == -1)
+ result = -1;
+ else
+ {
+# ifdef HAVE_FTRUNCATE
+ result = ftruncate (fd, (off_t) newSize);
+# else
+# ifdef HAVE_CHSIZE
+ result = chsize (fd, newSize);
+# endif
+# endif
+ close (fd);
+ }
+# endif
+#endif
+ if (result == -1)
+ fprintf (stderr, "Cannot shorten tag file: errno = %d\n", errno);
+}
+
+static void writeEtagsIncludes (MIO *const mio)
+{
+ if (Option.etagsInclude)
+ {
+ unsigned int i;
+ for (i = 0 ; i < stringListCount (Option.etagsInclude) ; ++i)
+ {
+ vString *item = stringListItem (Option.etagsInclude, i);
+ mio_printf (mio, "\f\n%s,include\n", vStringValue (item));
+ }
+ }
+}
+
+extern void closeTagFile (const bool resize)
+{
+ long desiredSize, size;
+
+ if (Option.etags)
+ writeEtagsIncludes (TagFile.mio);
+ mio_flush (TagFile.mio);
+ abort_if_ferror (TagFile.mio);
+ desiredSize = mio_tell (TagFile.mio);
+ mio_seek (TagFile.mio, 0L, SEEK_END);
+ size = mio_tell (TagFile.mio);
+ if (! TagsToStdout)
+ /* The tag file should be closed before resizing. */
+ if (mio_free (TagFile.mio) != 0)
+ error (FATAL | PERROR, "cannot close tag file");
+
+ if (resize && desiredSize < size)
+ {
+ DebugStatement (
+ debugPrintf (DEBUG_STATUS, "shrinking %s from %ld to %ld bytes\n",
+ TagFile.name, size, desiredSize); )
+ resizeTagFile (desiredSize);
+ }
+ sortTagFile ();
+ if (TagsToStdout)
+ {
+ if (mio_free (TagFile.mio) != 0)
+ error (FATAL | PERROR, "cannot close tag file");
+ remove (tagFileName ()); /* remove temporary file */
+ }
+ eFree (TagFile.name);
+ TagFile.name = NULL;
+}
+
/*
* Tag entry management
*/
+/* This function copies the current line out to a specified file. It has no
+ * effect on the fileGetc () function. During copying, any '\' characters
+ * are doubled and a leading '^' or trailing '$' is also quoted. End of line
+ * characters (line feed or carriage return) are dropped.
+ */
+static size_t appendInputLine (int putc_func (char , void *), const char *const line, void * data, bool *omitted)
+{
+ size_t length = 0;
+ const char *p;
+
+ /* Write everything up to, but not including, a line end character.
+ */
+ *omitted = false;
+ for (p = line ; *p != '\0' ; ++p)
+ {
+ const int next = *(p + 1);
+ const int c = *p;
+
+ if (c == CRETURN || c == NEWLINE)
+ break;
+
+ if (Option.patternLengthLimit != 0 && length >= Option.patternLengthLimit)
+ {
+ *omitted = true;
+ break;
+ }
+ /* If character is '\', or a terminal '$', then quote it.
+ */
+ if (c == BACKSLASH || c == (Option.backward ? '?' : '/') ||
+ (c == '$' && (next == NEWLINE || next == CRETURN)))
+ {
+ putc_func (BACKSLASH, data);
+ ++length;
+ }
+ putc_func (c, data);
+ ++length;
+ }
+
+ return length;
+}
+
+static int vstring_putc (char c, void *data)
+{
+ vString *str = data;
+ vStringPut (str, c);
+ return 1;
+}
+
+static int vstring_puts (const char* s, void *data)
+{
+ vString *str = data;
+ int len = vStringLength (str);
+ vStringCatS (str, s);
+ return vStringLength (str) - len;
+}
+
+static bool isPosSet(MIOPos pos)
+{
+ char * p = (char *)&pos;
+ bool r = false;
+ unsigned int i;
+
+ for (i = 0; i < sizeof(pos); i++)
+ r |= p[i];
+ return r;
+}
+
+extern char *readLineFromBypassAnyway (vString *const vLine, const tagEntryInfo *const tag,
+ long *const pSeekValue)
+{
+ char * line;
+
+ if (isPosSet (tag->filePosition) || (tag->pattern == NULL))
+ line = readLineFromBypass (vLine, tag->filePosition, pSeekValue);
+ else
+ line = NULL;
+/*
+ line = readLineFromBypassSlow (vLine, tag->lineNumber, tag->pattern, pSeekValue);
+*/
+ return line;
+}
+
+/* Truncates the text line containing the tag at the character following the
+ * tag, providing a character which designates the end of the tag.
+ */
+extern void truncateTagLine (
+ char *const line, const char *const token, const bool discardNewline)
+{
+ char *p = strstr (line, token);
+
+ if (p != NULL)
+ {
+ p += strlen (token);
+ if (*p != '\0' && ! (*p == '\n' && discardNewline))
+ ++p; /* skip past character terminating character */
+ *p = '\0';
+ }
+}
+
+static char* getFullQualifiedScopeNameFromCorkQueue (const tagEntryInfo * inner_scope)
+{
+
+ const kindOption *kind = NULL;
+ const tagEntryInfo *scope = inner_scope;
+ stringList *queue = stringListNew ();
+ vString *v;
+ vString *n;
+ unsigned int c;
+ const char *sep;
+
+ while (scope)
+ {
+ if (!scope->placeholder)
+ {
+ if (kind)
+ {
+ sep = scopeSeparatorFor (kind, scope->kind->letter);
+ v = vStringNewInit (sep);
+ stringListAdd (queue, v);
+ }
+ /* TODO: scope field of SCOPE can be used for optimization. */
+ v = vStringNewInit (scope->name);
+ stringListAdd (queue, v);
+ kind = scope->kind;
+ }
+ scope = getEntryInCorkQueue (scope->extensionFields.scopeIndex);
+ }
+
+ n = vStringNew ();
+ while ((c = stringListCount (queue)) > 0)
+ {
+ v = stringListLast (queue);
+ vStringCat (n, v);
+ vStringDelete (v);
+ stringListRemoveLast (queue);
+ }
+ stringListDelete (queue);
+
+ return vStringDeleteUnwrap (n);
+}
+
+extern void getTagScopeInformation (tagEntryInfo *const tag,
+ const char **kind, const char **name)
+{
+ if (kind)
+ *kind = NULL;
+ if (name)
+ *name = NULL;
+
+ if (tag->extensionFields.scopeKind == NULL
+ && tag->extensionFields.scopeName == NULL
+ && tag->extensionFields.scopeIndex != CORK_NIL
+ && TagFile.corkQueue.count > 0)
+ {
+ const tagEntryInfo * scope = NULL;
+ char *full_qualified_scope_name = NULL;
+
+ scope = getEntryInCorkQueue (tag->extensionFields.scopeIndex);
+ full_qualified_scope_name = getFullQualifiedScopeNameFromCorkQueue(scope);
+ Assert (full_qualified_scope_name);
+
+ /* Make the information reusable to generate full qualified entry, and xformat output*/
+ tag->extensionFields.scopeKind = scope->kind;
+ tag->extensionFields.scopeName = full_qualified_scope_name;
+ }
+
+ if (tag->extensionFields.scopeKind != NULL &&
+ tag->extensionFields.scopeName != NULL)
+ {
+ if (kind)
+ *kind = tag->extensionFields.scopeKind->name;
+ if (name)
+ *name = tag->extensionFields.scopeName;
+ }
+}
+
+
+extern int makePatternStringCommon (const tagEntryInfo *const tag,
+ int putc_func (char , void *),
+ int puts_func (const char* , void *),
+ void *output)
+{
+ int length = 0;
+
+ char *line;
+ int searchChar;
+ const char *terminator;
+ bool omitted;
+ size_t line_len;
+
+ bool making_cache = false;
+ int (* puts_o_func)(const char* , void *);
+ void * o_output;
+
+ static vString *cached_pattern;
+ static MIOPos cached_location;
+ if (TagFile.patternCacheValid
+ && (! tag->truncateLine)
+ && (memcmp (&tag->filePosition, &cached_location, sizeof(MIOPos)) == 0))
+ return puts_func (vStringValue (cached_pattern), output);
+
+ line = readLineFromBypass (TagFile.vLine, tag->filePosition, NULL);
+ if (line == NULL)
+ error (FATAL, "could not read tag line from %s at line %lu", getInputFileName (),tag->lineNumber);
+ if (tag->truncateLine)
+ truncateTagLine (line, tag->name, false);
+
+ line_len = strlen (line);
+ searchChar = Option.backward ? '?' : '/';
+ terminator = (bool) (line [line_len - 1] == '\n') ? "$": "";
+
+ if (!tag->truncateLine)
+ {
+ making_cache = true;
+ cached_pattern = vStringNewOrClear (cached_pattern);
+
+ puts_o_func = puts_func;
+ o_output = output;
+ putc_func = vstring_putc;
+ puts_func = vstring_puts;
+ output = cached_pattern;
+ }
+
+ length += putc_func(searchChar, output);
+/* if ((tag->boundaryInfo & BOUNDARY_START) == 0)
+ length += putc_func('^', output);*/
+ length += appendInputLine (putc_func, line, output, &omitted);
+ length += puts_func (omitted? "": terminator, output);
+ length += putc_func (searchChar, output);
+
+ if (making_cache)
+ {
+ puts_o_func (vStringValue (cached_pattern), o_output);
+ cached_location = tag->filePosition;
+ TagFile.patternCacheValid = true;
+ }
+
+ return length;
+}
+
+extern char* makePatternString (const tagEntryInfo *const tag)
+{
+ vString* pattern = vStringNew ();
+ makePatternStringCommon (tag, vstring_putc, vstring_puts, pattern);
+ return vStringDeleteUnwrap (pattern);
+}
+
+extern void attachParserField (tagEntryInfo *const tag, fieldType ftype, const char * value)
+{
+ Assert (tag->usedParserFields < PRE_ALLOCATED_PARSER_FIELDS);
+
+ tag->parserFields [tag->usedParserFields].ftype = ftype;
+ tag->parserFields [tag->usedParserFields].value = value;
+ tag->usedParserFields++;
+}
+
+extern void attachParserFieldToCorkEntry (int index,
+ fieldType type,
+ const char *value)
+{
+ tagEntryInfo * tag;
+ const char * v;
+
+ if (index == CORK_NIL)
+ return;
+
+ tag = getEntryInCorkQueue(index);
+ Assert (tag != NULL);
+
+ v = eStrdup (value);
+ attachParserField (tag, type, v);
+}
+
+static void copyParserFields (const tagEntryInfo *const tag, tagEntryInfo* slot)
+{
+ unsigned int i;
+ const char* value;
+
+ for (i = 0; i < tag->usedParserFields; i++)
+ {
+ value = tag->parserFields [i].value;
+ if (value)
+ value = eStrdup (value);
+
+ attachParserField (slot,
+ tag->parserFields [i].ftype,
+ value);
+ }
+}
+
+static void recordTagEntryInQueue (const tagEntryInfo *const tag, tagEntryInfo* slot)
+{
+ *slot = *tag;
+
+ if (slot->pattern)
+ slot->pattern = eStrdup (slot->pattern);
+ else if (!slot->lineNumberEntry)
+ slot->pattern = makePatternString (slot);
+
+ slot->inputFileName = eStrdup (slot->inputFileName);
+ slot->name = eStrdup (slot->name);
+ if (slot->extensionFields.access)
+ slot->extensionFields.access = eStrdup (slot->extensionFields.access);
+ if (slot->extensionFields.fileScope)
+ slot->extensionFields.fileScope = eStrdup (slot->extensionFields.fileScope);
+ if (slot->extensionFields.implementation)
+ slot->extensionFields.implementation = eStrdup (slot->extensionFields.implementation);
+ if (slot->extensionFields.inheritance)
+ slot->extensionFields.inheritance = eStrdup (slot->extensionFields.inheritance);
+ if (slot->extensionFields.scopeName)
+ slot->extensionFields.scopeName = eStrdup (slot->extensionFields.scopeName);
+ if (slot->extensionFields.signature)
+ slot->extensionFields.signature = eStrdup (slot->extensionFields.signature);
+ if (slot->extensionFields.varType)
+ slot->extensionFields.varType = eStrdup (slot->extensionFields.varType);
+#ifdef HAVE_LIBXML
+ if (slot->extensionFields.xpath)
+ slot->extensionFields.xpath = eStrdup (slot->extensionFields.xpath);
+#endif
+
+ if (slot->sourceLanguage)
+ slot->sourceLanguage = eStrdup (slot->sourceLanguage);
+ if (slot->sourceFileName)
+ slot->sourceFileName = eStrdup (slot->sourceFileName);
+
+ slot->usedParserFields = 0;
+ copyParserFields (tag, slot);
+}
+
+extern void clearParserFields (tagEntryInfo *const tag)
+{
+ unsigned int i;
+ const char* value;
+
+ for (i = 0; i < tag->usedParserFields; i++)
+ {
+ value = tag->parserFields[i].value;
+ if (value)
+ eFree ((char *)value);
+ tag->parserFields[i].value = NULL;
+ tag->parserFields[i].ftype = FIELD_UNKNOWN;
+ }
+}
+
+static void clearTagEntryInQueue (tagEntryInfo* slot)
+{
+ if (slot->pattern)
+ eFree ((char *)slot->pattern);
+ eFree ((char *)slot->inputFileName);
+ eFree ((char *)slot->name);
+
+ if (slot->extensionFields.access)
+ eFree ((char *)slot->extensionFields.access);
+ if (slot->extensionFields.fileScope)
+ eFree ((char *)slot->extensionFields.fileScope);
+ if (slot->extensionFields.implementation)
+ eFree ((char *)slot->extensionFields.implementation);
+ if (slot->extensionFields.inheritance)
+ eFree ((char *)slot->extensionFields.inheritance);
+ if (slot->extensionFields.scopeKind)
+ slot->extensionFields.scopeKind = NULL;
+ if (slot->extensionFields.scopeName)
+ eFree ((char *)slot->extensionFields.scopeName);
+ if (slot->extensionFields.signature)
+ eFree ((char *)slot->extensionFields.signature);
+ if (slot->extensionFields.varType)
+ eFree ((char *)slot->extensionFields.varType);
+#ifdef HAVE_LIBXML
+ if (slot->extensionFields.xpath)
+ eFree ((char *)slot->extensionFields.xpath);
+#endif
+
+ if (slot->sourceLanguage)
+ eFree ((char *)slot->sourceLanguage);
+ if (slot->sourceFileName)
+ eFree ((char *)slot->sourceFileName);
+
+ clearParserFields (slot);
+}
+
+static unsigned int queueTagEntry(const tagEntryInfo *const tag)
+{
+ unsigned int i;
+ void *tmp;
+ tagEntryInfo * slot;
+
+ if (! (TagFile.corkQueue.count < TagFile.corkQueue.length))
+ {
+ if (!TagFile.corkQueue.length)
+ TagFile.corkQueue.length = 1;
+
+ tmp = eRealloc (TagFile.corkQueue.queue,
+ sizeof (*TagFile.corkQueue.queue) * TagFile.corkQueue.length * 2);
+
+ TagFile.corkQueue.length *= 2;
+ TagFile.corkQueue.queue = tmp;
+ }
+
+ i = TagFile.corkQueue.count;
+ TagFile.corkQueue.count++;
+
+
+ slot = TagFile.corkQueue.queue + i;
+ recordTagEntryInQueue (tag, slot);
+
+ return i;
+}
+
+
+static void *writerData;
+static tagWriter *writer;
+
+extern void setTagWriter (tagWriter *t)
+{
+ writer = t;
+}
+
+extern bool outpuFormatUsedStdoutByDefault (void)
+{
+ return writer->useStdoutByDefault;
+}
+
+extern void setupWriter (void)
+{
+ if (writer->preWriteEntry)
+ writerData = writer->preWriteEntry (TagFile.mio);
+ else
+ writerData = NULL;
+}
+
+extern void teardownWriter (const char *filename)
+{
+ if (writer->postWriteEntry)
+ writer->postWriteEntry (TagFile.mio, filename, writerData);
+}
+
+static void buildFqTagCache (const tagEntryInfo *const tag)
+{
+ renderFieldEscaped (FIELD_SCOPE_KIND_LONG, tag, NO_PARSER_FIELD);
+ renderFieldEscaped (FIELD_SCOPE, tag, NO_PARSER_FIELD);
+}
+
static void writeTagEntry (const tagEntryInfo *const tag)
{
int length = 0;
@@ -471,6 +1102,89 @@ static void writeTagEntry (const tagEntryInfo *const tag)
/*abort_if_ferror (TagFile.mio);*/
}
+extern bool writePseudoTag (const ptagDesc *desc,
+ const char *const fileName,
+ const char *const pattern,
+ const char *const parserName)
+{
+ int length;
+
+ if (writer->writePtagEntry == NULL)
+ return false;
+
+ length = writer->writePtagEntry (TagFile.mio, desc, fileName,
+ pattern, parserName, writerData);
+ abort_if_ferror (TagFile.mio);
+
+ ++TagFile.numTags.added;
+ rememberMaxLengths (strlen (desc->name), (size_t) length);
+
+ return true;
+}
+
+extern void corkTagFile(void)
+{
+ TagFile.cork++;
+ if (TagFile.cork == 1)
+ {
+ TagFile.corkQueue.length = 1;
+ TagFile.corkQueue.count = 1;
+ TagFile.corkQueue.queue = eMalloc (sizeof (*TagFile.corkQueue.queue));
+ memset (TagFile.corkQueue.queue, 0, sizeof (*TagFile.corkQueue.queue));
+ }
+}
+
+extern void uncorkTagFile(void)
+{
+ unsigned int i;
+
+ TagFile.cork--;
+
+ if (TagFile.cork > 0)
+ return ;
+
+ for (i = 1; i < TagFile.corkQueue.count; i++)
+ {
+ tagEntryInfo *tag = TagFile.corkQueue.queue + i;
+ writeTagEntry (tag);
+/* if (doesInputLanguageRequestAutomaticFQTag ()
+ && isXtagEnabled (XTAG_QUALIFIED_TAGS)
+ && tag->extensionFields.scopeKind
+ && tag->extensionFields.scopeName
+ && tag->extensionFields.scopeIndex)
+ makeQualifiedTagEntry (tag);*/
+ }
+ for (i = 1; i < TagFile.corkQueue.count; i++)
+ clearTagEntryInQueue (TagFile.corkQueue.queue + i);
+
+ memset (TagFile.corkQueue.queue, 0,
+ sizeof (*TagFile.corkQueue.queue) * TagFile.corkQueue.count);
+ TagFile.corkQueue.count = 0;
+ eFree (TagFile.corkQueue.queue);
+ TagFile.corkQueue.queue = NULL;
+ TagFile.corkQueue.length = 0;
+}
+
+extern tagEntryInfo *getEntryInCorkQueue (unsigned int n)
+{
+ if ((CORK_NIL < n) && (n < TagFile.corkQueue.count))
+ return TagFile.corkQueue.queue + n;
+ else
+ return NULL;
+}
+
+extern tagEntryInfo *getEntryOfNestingLevel (const NestingLevel *nl)
+{
+ if (nl == NULL)
+ return NULL;
+/* return getEntryInCorkQueue (nl->corkIndex); */
+}
+
+extern size_t countEntryInCorkQueue (void)
+{
+ return TagFile.corkQueue.count;
+}
+
extern int makeTagEntry (const tagEntryInfo *const tag)
{
int r = CORK_NIL;
@@ -504,6 +1218,58 @@ extern int makeTagEntry (const tagEntryInfo *const tag)
return r;
}
+extern int makeQualifiedTagEntry (const tagEntryInfo *const e)
+{
+ int r = CORK_NIL;
+ tagEntryInfo x;
+ char xk;
+ const char *sep;
+ static vString *fqn;
+
+ if (isXtagEnabled (XTAG_QUALIFIED_TAGS))
+ {
+ x = *e;
+ markTagExtraBit (&x, XTAG_QUALIFIED_TAGS);
+
+ fqn = vStringNewOrClear (fqn);
+
+ if (e->extensionFields.scopeName)
+ {
+ vStringCatS (fqn, e->extensionFields.scopeName);
+ xk = e->extensionFields.scopeKind->letter;
+ sep = scopeSeparatorFor (e->kind, xk);
+ vStringCatS (fqn, sep);
+ }
+ else
+ {
+ /* This is an top level item. prepend a root separator
+ if the kind of the item has. */
+ sep = scopeSeparatorFor (e->kind, KIND_NULL);
+ if (sep == NULL)
+ {
+ /* No root separator. The name of the
+ oritinal tag and that of full qualified tag
+ are the same; recording the full qualified tag
+ is meaningless. */
+ return r;
+ }
+ else
+ vStringCatS (fqn, sep);
+ }
+ vStringCatS (fqn, e->name);
+
+ x.name = vStringValue (fqn);
+ /* makeExtraTagEntry of c.c doesn't clear scope
+ releated fields. */
+#if 0
+ x.extensionFields.scopeKind = NULL;
+ x.extensionFields.scopeName = NULL;
+#endif
+ r = makeTagEntry (&x);
+ }
+ return r;
+}
+
extern void initTagEntry (tagEntryInfo *const e, const char *const name,
const kindOption *kind)
{
@@ -575,11 +1341,6 @@ extern void initTagEntryFull (tagEntryInfo *const e, const char *const name,
e->parserFields[i].ftype = FIELD_UNKNOWN;
}
-extern void setTagWriter (tagWriter *t)
-{
-/* writer = t; */
-}
-
extern void markTagExtraBit (tagEntryInfo *const tag, xtagType extra)
{
unsigned int index;
@@ -593,6 +1354,17 @@ extern void markTagExtraBit (tagEntryInfo *const tag, xtagType extra)
tag->extra [ index ] |= (1 << offset);
}
+extern bool isTagExtraBitMarked (const tagEntryInfo *const tag, xtagType extra)
+{
+ unsigned int index = (extra / 8);
+ unsigned int offset = (extra % 8);
+
+ Assert (extra < XTAG_COUNT);
+ Assert (extra != XTAG_UNKNOWN);
+
+ return !! ((tag->extra [ index ]) & (1 << offset));
+}
+
extern unsigned long numTagsAdded(void)
{
return TagFile.numTags.added;
Modified: ctags/main/entry.h
33 lines changed, 31 insertions(+), 2 deletions(-)
===================================================================
@@ -30,8 +30,6 @@
#define WHOLE_FILE -1L
#define includeExtensionFlags() (Option.tagFileFormat > 1)
-#define CORK_NIL 0
-
/*
* DATA DECLARATIONS
*/
@@ -113,6 +111,8 @@ extern void freeTagFileResources (void);
extern const char *tagFileName (void);
extern void openTagFile (void);
extern void closeTagFile (const bool resize);
+extern void setupWriter (void);
+extern void teardownWriter (const char *inputFilename);
extern int makeTagEntry (const tagEntryInfo *const tag);
extern void initTagEntry (tagEntryInfo *const e, const char *const name,
const kindOption *kind);
@@ -128,6 +128,7 @@ extern void initTagEntryFull (tagEntryInfo *const e, const char *const name,
const char *sourceFileName,
const char* sourceLanguage,
long sourceLineNumberDifference);
+extern int makeQualifiedTagEntry (const tagEntryInfo *const e);
extern unsigned long numTagsAdded(void);
extern void setNumTagsAdded (unsigned long nadded);
@@ -140,6 +141,34 @@ extern void setTagFilePosition (MIOPos *p);
extern const char* getTagFileDirectory (void);
extern void getTagScopeInformation (tagEntryInfo *const tag,
const char **kind, const char **name);
+
+/* Getting line associated with tag */
+extern char *readLineFromBypassAnyway (vString *const vLine, const tagEntryInfo *const tag,
+ long *const pSeekValue);
+
+/* Generating pattern associated tag, caller must do eFree for the returned value. */
+extern char* makePatternString (const tagEntryInfo *const tag);
+
+
+/* language is optional: can be NULL. */
+extern bool writePseudoTag (const ptagDesc *pdesc,
+ const char *const fileName,
+ const char *const pattern,
+ const char *const parserName);
+
+#define CORK_NIL 0
+void corkTagFile(void);
+void uncorkTagFile(void);
+tagEntryInfo *getEntryInCorkQueue (unsigned int n);
+tagEntryInfo *getEntryOfNestingLevel (const NestingLevel *nl);
+size_t countEntryInCorkQueue (void);
+
+extern void makeFileTag (const char *const fileName);
+
extern void markTagExtraBit (tagEntryInfo *const tag, xtagType extra);
+extern bool isTagExtraBitMarked (const tagEntryInfo *const tag, xtagType extra);
+
+extern void attachParserField (tagEntryInfo *const tag, fieldType ftype, const char* value);
+extern void attachParserFieldToCorkEntry (int index, fieldType ftype, const char* value);
#endif /* CTAGS_MAIN_ENTRY_H */
Modified: ctags/main/parse.c
15 lines changed, 0 insertions(+), 15 deletions(-)
===================================================================
@@ -568,21 +568,6 @@ extern void printKindOptions (void)
* File parsing
*/
-static void makeFileTag (const char *const fileName)
-{
- if (isXtagEnabled(XTAG_FILE_NAMES))
- {
- tagEntryInfo tag;
- initTagEntry (&tag, baseFilename (fileName), getInputLanguageFileKind ());
-
- tag.isFileEntry = true;
- tag.lineNumberEntry = true;
- tag.lineNumber = 1;
-
- makeTagEntry (&tag);
- }
-}
-
static bool createTagsForFile (const char *const fileName,
const langType language,
const unsigned int passCount)
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Commits
mailing list