Added global auto completion tags for PHP and LaTeX.
git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@475 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
parent
3a435bf29e
commit
570793a6ef
@ -8,7 +8,9 @@ EXTRA_DIST = \
|
||||
geany.spec \
|
||||
geany.glade \
|
||||
geany.gladep \
|
||||
global.tags \
|
||||
data/global.tags \
|
||||
data/global.tags \
|
||||
data/latex.tags \
|
||||
data/filetypes.*
|
||||
|
||||
uninstall-local:
|
||||
@ -26,7 +28,9 @@ install-data-local:
|
||||
done \
|
||||
fi
|
||||
$(mkinstalldirs) $(DESTDIR)$(pkgdatadir); \
|
||||
$(INSTALL_DATA) global.tags $(DESTDIR)$(pkgdatadir); \
|
||||
$(INSTALL_DATA) data/global.tags $(DESTDIR)$(pkgdatadir); \
|
||||
$(INSTALL_DATA) data/php.tags $(DESTDIR)$(pkgdatadir); \
|
||||
$(INSTALL_DATA) data/latex.tags $(DESTDIR)$(pkgdatadir); \
|
||||
$(INSTALL_DATA) COPYING $(DESTDIR)$(pkgdatadir)/GPL-2; \
|
||||
for file in $(srcdir)/data/*; do \
|
||||
if test -f $$file; then \
|
||||
|
||||
1327
data/latex.tags
Normal file
1327
data/latex.tags
Normal file
File diff suppressed because it is too large
Load Diff
2738
data/php.tags
Normal file
2738
data/php.tags
Normal file
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,8 @@
|
||||
|
||||
static style_set *types[GEANY_MAX_FILE_TYPES] = { NULL };
|
||||
static gboolean global_c_tags_loaded = FALSE;
|
||||
static gboolean global_php_tags_loaded = FALSE;
|
||||
static gboolean global_latex_tags_loaded = FALSE;
|
||||
|
||||
|
||||
/* simple wrapper function to print file errors in DEBUG mode */
|
||||
@ -371,7 +373,8 @@ static void styleset_c_init(void)
|
||||
// load global tags file for C autocompletion
|
||||
if (! app->ignore_global_tags && ! global_c_tags_loaded)
|
||||
{
|
||||
tm_workspace_load_global_tags(GEANY_DATA_DIR G_DIR_SEPARATOR_S "global.tags");
|
||||
// 0 is the langType used in TagManager (see the table in tagmanager/parsers.h)
|
||||
tm_workspace_load_global_tags(GEANY_DATA_DIR G_DIR_SEPARATOR_S "global.tags", 0);
|
||||
global_c_tags_loaded = TRUE;
|
||||
}
|
||||
}
|
||||
@ -501,7 +504,9 @@ static void styleset_cpp_init(void)
|
||||
// load global tags file for C autocompletion
|
||||
if (! app->ignore_global_tags && ! global_c_tags_loaded)
|
||||
{
|
||||
tm_workspace_load_global_tags(GEANY_DATA_DIR G_DIR_SEPARATOR_S "global.tags");
|
||||
// 0 is the langType used in TagManager (see the table in tagmanager/parsers.h)
|
||||
// C++ is a special case, here we use 0 to have C global tags in C++, too
|
||||
tm_workspace_load_global_tags(GEANY_DATA_DIR G_DIR_SEPARATOR_S "global.tags", 0);
|
||||
global_c_tags_loaded = TRUE;
|
||||
}
|
||||
}
|
||||
@ -725,6 +730,14 @@ static void styleset_latex_init(void)
|
||||
styleset_get_wordchars(config, config_home, GEANY_FILETYPES_LATEX, GEANY_WORDCHARS);
|
||||
filetypes_get_config(config, config_home, GEANY_FILETYPES_LATEX);
|
||||
|
||||
// load global tags file for LaTeX autocompletion
|
||||
if (! app->ignore_global_tags && ! global_latex_tags_loaded)
|
||||
{
|
||||
// 8 is the langType used in TagManager (see the table in tagmanager/parsers.h)
|
||||
tm_workspace_load_global_tags(GEANY_DATA_DIR G_DIR_SEPARATOR_S "latex.tags", 8);
|
||||
global_latex_tags_loaded = TRUE;
|
||||
}
|
||||
|
||||
g_key_file_free(config);
|
||||
g_key_file_free(config_home);
|
||||
g_free(f);
|
||||
@ -765,6 +778,14 @@ static void styleset_php_init(void)
|
||||
styleset_get_wordchars(config, config_home, GEANY_FILETYPES_PHP, GEANY_WORDCHARS"$");
|
||||
filetypes_get_config(config, config_home, GEANY_FILETYPES_PHP);
|
||||
|
||||
// load global tags file for PHP autocompletion
|
||||
if (! app->ignore_global_tags && ! global_php_tags_loaded)
|
||||
{
|
||||
// 6 is the langType used in TagManager (see the table in tagmanager/parsers.h)
|
||||
tm_workspace_load_global_tags(GEANY_DATA_DIR G_DIR_SEPARATOR_S "php.tags", 6);
|
||||
global_php_tags_loaded = TRUE;
|
||||
}
|
||||
|
||||
g_key_file_free(config);
|
||||
g_key_file_free(config_home);
|
||||
g_free(f);
|
||||
|
||||
@ -243,69 +243,7 @@ static long unsigned int updatePseudoTags (FILE *const fp)
|
||||
* Tag file management
|
||||
*/
|
||||
|
||||
static boolean isValidTagAddress (const char *const excmd)
|
||||
{
|
||||
boolean 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 boolean isCtagsLine (const char *const line)
|
||||
{
|
||||
enum fieldList { TAG, TAB1, SRC_FILE, TAB2, EXCMD, NUM_FIELDS };
|
||||
boolean 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
|
||||
* accceptable.
|
||||
*
|
||||
* 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 boolean isEtagsLine (const char *const line)
|
||||
{
|
||||
boolean result = FALSE;
|
||||
if (line [0] == '\f')
|
||||
result = (boolean) (line [1] == '\n' || line [1] == '\r');
|
||||
return result;
|
||||
}
|
||||
|
||||
static boolean isTagFile (const char *const filename)
|
||||
{
|
||||
@ -320,8 +258,6 @@ static boolean isTagFile (const char *const filename)
|
||||
|
||||
if (line == NULL)
|
||||
ok = TRUE;
|
||||
else
|
||||
ok = (boolean) (isCtagsLine (line) || isEtagsLine (line));
|
||||
fclose (fp);
|
||||
}
|
||||
return ok;
|
||||
@ -389,32 +325,23 @@ extern void openTagFile (void)
|
||||
"\"%s\" doesn't look like a tag file; I refuse to overwrite it.",
|
||||
TagFile.name);
|
||||
|
||||
if (Option.etags)
|
||||
if (Option.append && fileExists)
|
||||
{
|
||||
TagFile.fp = fopen (TagFile.name, "r+");
|
||||
if (TagFile.fp != NULL)
|
||||
{
|
||||
if (Option.append && fileExists)
|
||||
TagFile.fp = fopen (TagFile.name, "a+b");
|
||||
else
|
||||
TagFile.fp = fopen (TagFile.name, "w+b");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Option.append && fileExists)
|
||||
{
|
||||
TagFile.fp = fopen (TagFile.name, "r+");
|
||||
if (TagFile.fp != NULL)
|
||||
{
|
||||
TagFile.numTags.prev = updatePseudoTags (TagFile.fp);
|
||||
fclose (TagFile.fp);
|
||||
TagFile.fp = fopen (TagFile.name, "a+");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TagFile.fp = fopen (TagFile.name, "w");
|
||||
if (TagFile.fp != NULL)
|
||||
addPseudoTags ();
|
||||
}
|
||||
TagFile.numTags.prev = updatePseudoTags (TagFile.fp);
|
||||
fclose (TagFile.fp);
|
||||
TagFile.fp = fopen (TagFile.name, "a+");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TagFile.fp = fopen (TagFile.name, "w");
|
||||
if (TagFile.fp != NULL)
|
||||
addPseudoTags ();
|
||||
}
|
||||
|
||||
if (TagFile.fp == NULL)
|
||||
{
|
||||
error (FATAL | PERROR, "cannot open tag file");
|
||||
@ -446,338 +373,11 @@ static int replacementTruncate (const char *const name, const long size)
|
||||
|
||||
#endif
|
||||
|
||||
static void sortTagFile (void)
|
||||
{
|
||||
if (TagFile.numTags.added > 0L)
|
||||
{
|
||||
if (Option.sorted)
|
||||
{
|
||||
verbose ("sorting tag file\n");
|
||||
#ifdef EXTERNAL_SORT
|
||||
externalSortTags (TagsToStdout);
|
||||
#else
|
||||
internalSortTags (TagsToStdout);
|
||||
#endif
|
||||
}
|
||||
else if (TagsToStdout)
|
||||
catFile (tagFileName ());
|
||||
}
|
||||
if (TagsToStdout)
|
||||
remove (tagFileName ()); /* remove temporary file */
|
||||
}
|
||||
|
||||
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 (errout, "Cannot shorten tag file: errno = %d\n", errno);
|
||||
}
|
||||
|
||||
static void writeEtagsIncludes (FILE *const fp)
|
||||
{
|
||||
if (Option.etagsInclude)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0 ; i < stringListCount (Option.etagsInclude) ; ++i)
|
||||
{
|
||||
vString *item = stringListItem (Option.etagsInclude, i);
|
||||
fprintf (fp, "\f\n%s,include\n", vStringValue (item));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern void closeTagFile (const boolean resize)
|
||||
{
|
||||
long desiredSize, size;
|
||||
|
||||
if (Option.etags)
|
||||
writeEtagsIncludes (TagFile.fp);
|
||||
desiredSize = ftell (TagFile.fp);
|
||||
fseek (TagFile.fp, 0L, SEEK_END);
|
||||
size = ftell (TagFile.fp);
|
||||
fclose (TagFile.fp);
|
||||
if (resize && desiredSize < size)
|
||||
{
|
||||
DebugStatement (
|
||||
debugPrintf (DEBUG_STATUS, "shrinking %s from %ld to %ld bytes\n",
|
||||
TagFile.name, size, desiredSize); )
|
||||
resizeTagFile (desiredSize);
|
||||
}
|
||||
sortTagFile ();
|
||||
eFree (TagFile.name);
|
||||
TagFile.name = NULL;
|
||||
}
|
||||
|
||||
extern void beginEtagsFile (void)
|
||||
{
|
||||
TagFile.etags.fp = tempFile ("w+b", &TagFile.etags.name);
|
||||
TagFile.etags.byteCount = 0;
|
||||
}
|
||||
|
||||
extern void endEtagsFile (const char *const name)
|
||||
{
|
||||
const char *line;
|
||||
|
||||
fprintf (TagFile.fp, "\f\n%s,%ld\n", name, (long) TagFile.etags.byteCount);
|
||||
if (TagFile.etags.fp != NULL)
|
||||
{
|
||||
rewind (TagFile.etags.fp);
|
||||
while ((line = readLine (TagFile.vLine, TagFile.etags.fp)) != NULL)
|
||||
fputs (line, TagFile.fp);
|
||||
fclose (TagFile.etags.fp);
|
||||
remove (TagFile.etags.name);
|
||||
eFree (TagFile.etags.name);
|
||||
TagFile.etags.fp = NULL;
|
||||
TagFile.etags.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 writeSourceLine (FILE *const fp, const char *const line)
|
||||
{
|
||||
size_t length = 0;
|
||||
const char *p;
|
||||
|
||||
/* Write everything up to, but not including, a line end character.
|
||||
*/
|
||||
for (p = line ; *p != '\0' ; ++p)
|
||||
{
|
||||
const int next = *(p + 1);
|
||||
const int c = *p;
|
||||
|
||||
if (c == CRETURN || c == NEWLINE)
|
||||
break;
|
||||
|
||||
/* If character is '\', or a terminal '$', then quote it.
|
||||
*/
|
||||
if (c == BACKSLASH || c == (Option.backward ? '?' : '/') ||
|
||||
(c == '$' && (next == NEWLINE || next == CRETURN)))
|
||||
{
|
||||
putc (BACKSLASH, fp);
|
||||
++length;
|
||||
}
|
||||
putc (c, fp);
|
||||
++length;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
/* Writes "line", stripping leading and duplicate white space.
|
||||
*/
|
||||
static size_t writeCompactSourceLine (FILE *const fp, const char *const line)
|
||||
{
|
||||
boolean lineStarted = FALSE;
|
||||
size_t length = 0;
|
||||
const char *p;
|
||||
int c;
|
||||
|
||||
/* Write everything up to, but not including, the newline.
|
||||
*/
|
||||
for (p = line, c = *p ; c != NEWLINE && c != '\0' ; c = *++p)
|
||||
{
|
||||
if (lineStarted || ! isspace (c)) /* ignore leading spaces */
|
||||
{
|
||||
lineStarted = TRUE;
|
||||
if (isspace (c))
|
||||
{
|
||||
int next;
|
||||
|
||||
/* Consume repeating white space.
|
||||
*/
|
||||
while (next = *(p+1) , isspace (next) && next != NEWLINE)
|
||||
++p;
|
||||
c = ' '; /* force space character for any white space */
|
||||
}
|
||||
if (c != CRETURN || *(p + 1) != NEWLINE)
|
||||
{
|
||||
putc (c, fp);
|
||||
++length;
|
||||
}
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
static int writeXrefEntry (const tagEntryInfo *const tag)
|
||||
{
|
||||
const char *const line =
|
||||
readSourceLine (TagFile.vLine, tag->filePosition, NULL);
|
||||
int length = fprintf (TagFile.fp, "%-20s %-10s %4lu %-14s ", tag->name,
|
||||
tag->kindName, tag->lineNumber, tag->sourceFileName);
|
||||
|
||||
length += writeCompactSourceLine (TagFile.fp, line);
|
||||
putc (NEWLINE, TagFile.fp);
|
||||
++length;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/* Truncates the text line containing the tag at the character following the
|
||||
* tag, providing a character which designates the end of the tag.
|
||||
*/
|
||||
static void truncateTagLine (char *const line, const char *const token,
|
||||
const boolean 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 int writeEtagsEntry (const tagEntryInfo *const tag)
|
||||
{
|
||||
int length;
|
||||
|
||||
if (tag->isFileEntry)
|
||||
length = fprintf (TagFile.etags.fp, "\177%s\001%lu,0\n",
|
||||
tag->name, tag->lineNumber);
|
||||
else
|
||||
{
|
||||
long seekValue;
|
||||
char *const line =
|
||||
readSourceLine (TagFile.vLine, tag->filePosition, &seekValue);
|
||||
|
||||
if (tag->truncateLine)
|
||||
truncateTagLine (line, tag->name, TRUE);
|
||||
else
|
||||
line [strlen (line) - 1] = '\0';
|
||||
|
||||
length = fprintf (TagFile.etags.fp, "%s\177%s\001%lu,%ld\n", line,
|
||||
tag->name, tag->lineNumber, seekValue);
|
||||
}
|
||||
TagFile.etags.byteCount += length;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static int addExtensionFields (const tagEntryInfo *const tag)
|
||||
{
|
||||
const char* const kindKey = Option.extensionFields.kindKey ? "kind:" : "";
|
||||
int length = fprintf (TagFile.fp, ";\"");
|
||||
|
||||
if (tag->kindName != NULL && (
|
||||
Option.extensionFields.kindLong || tag->kind == '\0'))
|
||||
length += fprintf (TagFile.fp, "\t%s%s", kindKey, tag->kindName);
|
||||
else if (tag->kind != '\0' && (
|
||||
! Option.extensionFields.kindLong || tag->kindName == NULL))
|
||||
length += fprintf (TagFile.fp, "\t%s%c", kindKey, tag->kind);
|
||||
|
||||
if (Option.extensionFields.lineNumber)
|
||||
length += fprintf (TagFile.fp, "\tline:%ld", tag->lineNumber);
|
||||
|
||||
if (Option.extensionFields.language && tag->language != NULL)
|
||||
length += fprintf (TagFile.fp, "\tlanguage:%s", tag->language);
|
||||
|
||||
if (Option.extensionFields.scope &&
|
||||
tag->extensionFields.scope [0] != NULL &&
|
||||
tag->extensionFields.scope [1] != NULL)
|
||||
length += fprintf (TagFile.fp, "\t%s:%s",
|
||||
tag->extensionFields.scope [0],
|
||||
tag->extensionFields.scope [1]);
|
||||
|
||||
if (Option.extensionFields.fileScope && tag->isFileScope)
|
||||
length += fprintf (TagFile.fp, "\tfile:");
|
||||
|
||||
if (Option.extensionFields.inheritance &&
|
||||
tag->extensionFields.inheritance != NULL)
|
||||
length += fprintf (TagFile.fp, "\tinherits:%s",
|
||||
tag->extensionFields.inheritance);
|
||||
|
||||
if (Option.extensionFields.access && tag->extensionFields.access != NULL)
|
||||
length += fprintf (TagFile.fp, "\taccess:%s",
|
||||
tag->extensionFields.access);
|
||||
|
||||
if (Option.extensionFields.implementation &&
|
||||
tag->extensionFields.implementation != NULL)
|
||||
length += fprintf (TagFile.fp, "\timplementation:%s",
|
||||
tag->extensionFields.implementation);
|
||||
|
||||
if ((Option.extensionFields.argList) &&
|
||||
(tag->extensionFields.arglist != NULL))
|
||||
length += fprintf(TagFile.fp, "\targlist:%s", tag->extensionFields.arglist);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static int writePatternEntry (const tagEntryInfo *const tag)
|
||||
{
|
||||
char *const line = readSourceLine (TagFile.vLine, tag->filePosition, NULL);
|
||||
const int searchChar = Option.backward ? '?' : '/';
|
||||
boolean newlineTerminated;
|
||||
int length = 0;
|
||||
|
||||
if (tag->truncateLine)
|
||||
truncateTagLine (line, tag->name, FALSE);
|
||||
newlineTerminated = (boolean) (line [strlen (line) - 1] == '\n');
|
||||
|
||||
length += fprintf (TagFile.fp, "%c^", searchChar);
|
||||
length += writeSourceLine (TagFile.fp, line);
|
||||
length += fprintf (TagFile.fp, "%s%c", newlineTerminated ? "$":"",
|
||||
searchChar);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
static int writeLineNumberEntry (const tagEntryInfo *const tag)
|
||||
{
|
||||
return fprintf (TagFile.fp, "%lu", tag->lineNumber);
|
||||
}
|
||||
|
||||
static int writeCtagsEntry (const tagEntryInfo *const tag)
|
||||
{
|
||||
int length = fprintf (TagFile.fp, "%s\t%s\t",
|
||||
tag->name, tag->sourceFileName);
|
||||
|
||||
if (tag->lineNumberEntry)
|
||||
length += writeLineNumberEntry (tag);
|
||||
else
|
||||
length += writePatternEntry (tag);
|
||||
|
||||
if (includeExtensionFlags ())
|
||||
length += addExtensionFields (tag);
|
||||
|
||||
length += fprintf (TagFile.fp, "\n");
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
extern void makeTagEntry (const tagEntryInfo *const tag)
|
||||
{
|
||||
@ -788,18 +388,8 @@ extern void makeTagEntry (const tagEntryInfo *const tag)
|
||||
{
|
||||
int length = 0;
|
||||
|
||||
DebugStatement ( debugEntry (tag); )
|
||||
if (NULL != TagEntryFunction)
|
||||
length = TagEntryFunction(tag);
|
||||
else if (Option.xref)
|
||||
{
|
||||
if (! tag->isFileEntry)
|
||||
length = writeXrefEntry (tag);
|
||||
}
|
||||
else if (Option.etags)
|
||||
length = writeEtagsEntry (tag);
|
||||
else
|
||||
length = writeCtagsEntry (tag);
|
||||
|
||||
++TagFile.numTags.added;
|
||||
rememberMaxLengths (strlen (tag->name), (size_t) length);
|
||||
|
||||
@ -60,10 +60,11 @@ typedef struct _TMSourceFile
|
||||
} TMSourceFile;
|
||||
|
||||
/*! Initializes a TMSourceFile structure from a file name. */
|
||||
gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_name, gboolean update);
|
||||
gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_name,
|
||||
gboolean update, const char *name);
|
||||
|
||||
/*! Initializes a TMSourceFile structure and returns a pointer to it. */
|
||||
TMWorkObject *tm_source_file_new(const char *file_name, gboolean update);
|
||||
TMWorkObject *tm_source_file_new(const char *file_name, gboolean update, const char *name);
|
||||
|
||||
/*! Destroys the contents of the source file. Note that the tags are owned by the
|
||||
source file and are also destroyed when the source file is destroyed. If pointers
|
||||
|
||||
@ -174,9 +174,11 @@ gboolean tm_tag_init(TMTag *tag, TMSourceFile *file, const tagEntryInfo *tag_ent
|
||||
\param tag The TMTag structure to populate
|
||||
\param file The TMSourceFile struct (assigned to the file member)
|
||||
\param fp FILE pointer from where the tag line is read
|
||||
\param mode langType - if set to greater than 0, the alternative parser is used and mode represents
|
||||
the langType to use for the tags
|
||||
\return TRUE on success, FALSE on FAILURE
|
||||
*/
|
||||
gboolean tm_tag_init_from_file(TMTag *tag, TMSourceFile *file, FILE *fp);
|
||||
gboolean tm_tag_init_from_file(TMTag *tag, TMSourceFile *file, FILE *fp, gint mode);
|
||||
|
||||
/*!
|
||||
Creates a new tag structure from a tagEntryInfo pointer and a TMSOurceFile pointer
|
||||
@ -190,7 +192,7 @@ TMTag *tm_tag_new(TMSourceFile *file, const tagEntryInfo *tag_entry);
|
||||
/*!
|
||||
Same as tm_tag_new() except that the tag attributes are read from file
|
||||
*/
|
||||
TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp);
|
||||
TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp, gint mode);
|
||||
|
||||
/*!
|
||||
Writes tag information to the given FILE *.
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
workspace, though, to use tag manager, unless you need things like global tags
|
||||
and a place to store all current open projects and individual files. TMWorkspace
|
||||
is derived from TMWorkObject.
|
||||
|
||||
|
||||
The following example demonstrates the use of workspace functions to create global tags.
|
||||
\include tm_global_tags.c
|
||||
*/
|
||||
@ -89,7 +89,8 @@ gboolean tm_workspace_remove_object(TMWorkObject *work_object, gboolean free);
|
||||
\return TRUE on success, FALSE on failure.
|
||||
\sa tm_workspace_create_global_tags()
|
||||
*/
|
||||
gboolean tm_workspace_load_global_tags(const char *tags_file);
|
||||
gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode);
|
||||
//gboolean tm_workspace_load_global_tags(const char *tags_file);
|
||||
|
||||
/*! Creates a list of global tags. Ideally, this should be created once during
|
||||
installations so that all users can use the same file. Thsi is because a full
|
||||
@ -130,10 +131,12 @@ void tm_workspace_dump(void);
|
||||
\param type The tag types to return (TMTagType). Can be a bitmask.
|
||||
\param attrs The attributes to sort and dedup on (0 terminated integer array).
|
||||
\param partial Whether partial match is allowed.
|
||||
\param lang Specifies the language(see the table in parsers.h) of the tags to be found,
|
||||
-1 for all
|
||||
\return Array of matching tags. Do not free() it since it is a static member.
|
||||
*/
|
||||
const GPtrArray *tm_workspace_find(const char *name, int type, TMTagAttrType *attrs
|
||||
, gboolean partial);
|
||||
, gboolean partial, langType lang);
|
||||
|
||||
/*! Returns a list of parent classes for the given class name
|
||||
\param name Name of the class
|
||||
|
||||
@ -33,6 +33,26 @@
|
||||
TclParser, \
|
||||
ShParser
|
||||
|
||||
/*
|
||||
langType of each parser
|
||||
0 CParser
|
||||
1 CppParser
|
||||
2 JavaParser
|
||||
3 MakefileParser
|
||||
4 PascalParser
|
||||
5 PerlParser
|
||||
6 PhpParser
|
||||
7 PythonParser
|
||||
8 LaTeXParser
|
||||
9 AsmParser
|
||||
10 ConfParser
|
||||
11 SqlParser
|
||||
12 DocBookParser
|
||||
13 CssParser
|
||||
14 RubyParser
|
||||
15 TclParser
|
||||
16 ShParser
|
||||
*/
|
||||
#endif /* _PARSERS_H */
|
||||
|
||||
/* vi:set tabstop=8 shiftwidth=4: */
|
||||
|
||||
@ -282,6 +282,6 @@ GList *tm_file_entry_list(TMFileEntry *entry, GList *files)
|
||||
files = tm_file_entry_list((TMFileEntry *) tmp->data, files);
|
||||
}
|
||||
if (!files)
|
||||
g_list_reverse(files);
|
||||
files = g_list_reverse(files);
|
||||
return files;
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ gboolean tm_project_add_file(TMProject *project, const char *file_name
|
||||
}
|
||||
if (NULL == source_file)
|
||||
{
|
||||
if (NULL == (source_file = tm_source_file_new(file_name, TRUE)))
|
||||
if (NULL == (source_file = tm_source_file_new(file_name, TRUE, NULL)))
|
||||
{
|
||||
g_warning("Unable to create source file for file %s", file_name);
|
||||
g_free(path);
|
||||
@ -375,12 +375,12 @@ gboolean tm_project_open(TMProject *project, gboolean force)
|
||||
tm_project_set_ignorelist(project);
|
||||
if (NULL == (fp = fopen(project->work_object.file_name, "r")))
|
||||
return FALSE;
|
||||
while (NULL != (tag = tm_tag_new_from_file(source_file, fp)))
|
||||
while (NULL != (tag = tm_tag_new_from_file(source_file, fp, 0)))
|
||||
{
|
||||
if (tm_tag_file_t == tag->type)
|
||||
{
|
||||
if (!(source_file = TM_SOURCE_FILE(
|
||||
tm_source_file_new(tag->name, FALSE))))
|
||||
tm_source_file_new(tag->name, FALSE, NULL))))
|
||||
{
|
||||
#ifdef TM_DEBUG
|
||||
g_warning("Unable to create source file %s", tag->name);
|
||||
|
||||
@ -26,7 +26,7 @@ guint source_file_class_id = 0;
|
||||
static TMSourceFile *current_source_file = NULL;
|
||||
|
||||
gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_name
|
||||
, gboolean update)
|
||||
, gboolean update, const char* name)
|
||||
{
|
||||
if (0 == source_file_class_id)
|
||||
source_file_class_id = tm_work_object_register(tm_source_file_free
|
||||
@ -39,7 +39,10 @@ gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_name
|
||||
if (FALSE == tm_work_object_init(&(source_file->work_object),
|
||||
source_file_class_id, file_name, FALSE))
|
||||
return FALSE;
|
||||
source_file->lang = LANG_AUTO;
|
||||
if (name == NULL)
|
||||
source_file->lang = LANG_AUTO;
|
||||
else
|
||||
source_file->lang = getNamedLanguage(name);
|
||||
source_file->inactive = FALSE;
|
||||
if (NULL == LanguageTable)
|
||||
{
|
||||
@ -54,10 +57,10 @@ gboolean tm_source_file_init(TMSourceFile *source_file, const char *file_name
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TMWorkObject *tm_source_file_new(const char *file_name, gboolean update)
|
||||
TMWorkObject *tm_source_file_new(const char *file_name, gboolean update, const char *name)
|
||||
{
|
||||
TMSourceFile *source_file = g_new(TMSourceFile, 1);
|
||||
if (TRUE != tm_source_file_init(source_file, file_name, update))
|
||||
if (TRUE != tm_source_file_init(source_file, file_name, update, name))
|
||||
{
|
||||
g_free(source_file);
|
||||
return NULL;
|
||||
@ -92,6 +95,7 @@ gboolean tm_source_file_parse(TMSourceFile *source_file)
|
||||
{
|
||||
const char *file_name;
|
||||
gboolean status = TRUE;
|
||||
int passCount = 0;
|
||||
|
||||
if ((NULL == source_file) || (NULL == source_file->work_object.file_name))
|
||||
{
|
||||
@ -99,9 +103,6 @@ gboolean tm_source_file_parse(TMSourceFile *source_file)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef TM_DEBUG
|
||||
g_message("Parsing %s", source_file->work_object.file_name);
|
||||
#endif
|
||||
file_name = source_file->work_object.file_name;
|
||||
if (NULL == LanguageTable)
|
||||
{
|
||||
@ -111,43 +112,31 @@ gboolean tm_source_file_parse(TMSourceFile *source_file)
|
||||
TagEntryFunction = tm_source_file_tags;
|
||||
}
|
||||
current_source_file = source_file;
|
||||
|
||||
if (LANG_AUTO == source_file->lang)
|
||||
source_file->lang = getFileLanguage (file_name);
|
||||
if (source_file->lang == LANG_IGNORE)
|
||||
|
||||
if (source_file->lang < 0 || ! LanguageTable [source_file->lang]->enabled)
|
||||
return status;
|
||||
|
||||
while ((TRUE == status) && (passCount < 3))
|
||||
{
|
||||
#ifdef TM_DEBUG
|
||||
g_warning("ignoring %s (unknown language)\n", file_name);
|
||||
#endif
|
||||
}
|
||||
else if (! LanguageTable [source_file->lang]->enabled)
|
||||
{
|
||||
#ifdef TM_DEBUG
|
||||
g_warning("ignoring %s (language disabled)\n", file_name);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
int passCount = 0;
|
||||
while ((TRUE == status) && (passCount < 3))
|
||||
if (source_file->work_object.tags_array)
|
||||
tm_tags_array_free(source_file->work_object.tags_array, FALSE);
|
||||
if (fileOpen (file_name, source_file->lang))
|
||||
{
|
||||
if (source_file->work_object.tags_array)
|
||||
tm_tags_array_free(source_file->work_object.tags_array, FALSE);
|
||||
if (fileOpen (file_name, source_file->lang))
|
||||
{
|
||||
if (LanguageTable [source_file->lang]->parser != NULL)
|
||||
LanguageTable [source_file->lang]->parser ();
|
||||
else if (LanguageTable [source_file->lang]->parser2 != NULL)
|
||||
status = LanguageTable [source_file->lang]->parser2 (passCount);
|
||||
fileClose ();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning("Unable to open %s", file_name);
|
||||
return FALSE;
|
||||
}
|
||||
++ passCount;
|
||||
if (LanguageTable [source_file->lang]->parser != NULL)
|
||||
LanguageTable [source_file->lang]->parser ();
|
||||
else if (LanguageTable [source_file->lang]->parser2 != NULL)
|
||||
status = LanguageTable [source_file->lang]->parser2 (passCount);
|
||||
fileClose ();
|
||||
}
|
||||
return TRUE;
|
||||
else
|
||||
{
|
||||
g_warning("Unable to open %s", file_name);
|
||||
return FALSE;
|
||||
}
|
||||
++ passCount;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -197,10 +197,12 @@ TMTag *tm_tag_new(TMSourceFile *file, const tagEntryInfo *tag_entry)
|
||||
TAG_FREE(tag);
|
||||
return NULL;
|
||||
}
|
||||
// if I don't do the following, tag->atts.file.lang has an undefined value, which is quite bad
|
||||
tag->atts.file.lang = file->lang;
|
||||
return tag;
|
||||
}
|
||||
|
||||
gboolean tm_tag_init_from_file(TMTag *tag, TMSourceFile *file, FILE *fp)
|
||||
gboolean tm_tag_init_from_file(TMTag *tag, TMSourceFile *file, FILE *fp, gint mode)
|
||||
{
|
||||
guchar buf[BUFSIZ];
|
||||
guchar *start, *end;
|
||||
@ -209,88 +211,121 @@ gboolean tm_tag_init_from_file(TMTag *tag, TMSourceFile *file, FILE *fp)
|
||||
|
||||
if ((NULL == fgets((gchar*)buf, BUFSIZ, fp)) || ('\0' == *buf))
|
||||
return FALSE;
|
||||
for (start = end = buf, status = TRUE; (TRUE == status); start = end, ++ end)
|
||||
if (mode == 0)
|
||||
{
|
||||
while ((*end < TA_NAME) && (*end != '\0') && (*end != '\n'))
|
||||
++ end;
|
||||
if (('\0' == *end) || ('\n' == *end))
|
||||
status = FALSE;
|
||||
changed_char = *end;
|
||||
*end = '\0';
|
||||
if (NULL == tag->name)
|
||||
for (start = end = buf, status = TRUE; (TRUE == status); start = end, ++ end)
|
||||
{
|
||||
if (!isprint(*start))
|
||||
return FALSE;
|
||||
else
|
||||
tag->name = g_strdup((gchar*)start);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (*start)
|
||||
while ((*end < TA_NAME) && (*end != '\0') && (*end != '\n'))
|
||||
++ end;
|
||||
if (('\0' == *end) || ('\n' == *end))
|
||||
status = FALSE;
|
||||
changed_char = *end;
|
||||
*end = '\0';
|
||||
if (NULL == tag->name)
|
||||
{
|
||||
case TA_LINE:
|
||||
tag->atts.entry.line = atol((gchar*)start + 1);
|
||||
break;
|
||||
case TA_LOCAL:
|
||||
tag->atts.entry.local = atoi((gchar*)start + 1);
|
||||
break;
|
||||
case TA_TYPE:
|
||||
tag->type = (TMTagType) atoi((gchar*)start + 1);
|
||||
break;
|
||||
case TA_ARGLIST:
|
||||
tag->atts.entry.arglist = g_strdup((gchar*)start + 1);
|
||||
break;
|
||||
case TA_SCOPE:
|
||||
tag->atts.entry.scope = g_strdup((gchar*)start + 1);
|
||||
break;
|
||||
case TA_VARTYPE:
|
||||
tag->atts.entry.var_type = g_strdup((gchar*)start + 1);
|
||||
break;
|
||||
case TA_INHERITS:
|
||||
tag->atts.entry.inheritance = g_strdup((gchar*)start + 1);
|
||||
break;
|
||||
case TA_TIME:
|
||||
if (tm_tag_file_t != tag->type)
|
||||
{
|
||||
g_warning("Got time attribute for non-file tag %s", tag->name);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
tag->atts.file.timestamp = atol((gchar*)start + 1);
|
||||
break;
|
||||
case TA_LANG:
|
||||
if (tm_tag_file_t != tag->type)
|
||||
{
|
||||
g_warning("Got lang attribute for non-file tag %s", tag->name);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
tag->atts.file.lang = atoi((gchar*)start + 1);
|
||||
break;
|
||||
case TA_INACTIVE:
|
||||
if (tm_tag_file_t != tag->type)
|
||||
{
|
||||
g_warning("Got inactive attribute for non-file tag %s", tag->name);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
tag->atts.file.inactive = (gboolean) atoi((gchar*)start + 1);
|
||||
break;
|
||||
case TA_ACCESS:
|
||||
tag->atts.entry.access = *(start + 1);
|
||||
break;
|
||||
case TA_IMPL:
|
||||
tag->atts.entry.impl = *(start + 1);
|
||||
break;
|
||||
default:
|
||||
#ifdef TM_DEBUG
|
||||
g_warning("Unknown attribute %s", start + 1);
|
||||
#endif
|
||||
break;
|
||||
if (!isprint(*start))
|
||||
return FALSE;
|
||||
else
|
||||
tag->name = g_strdup((gchar*)start);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (*start)
|
||||
{
|
||||
case TA_LINE:
|
||||
tag->atts.entry.line = atol((gchar*)start + 1);
|
||||
break;
|
||||
case TA_LOCAL:
|
||||
tag->atts.entry.local = atoi((gchar*)start + 1);
|
||||
break;
|
||||
case TA_TYPE:
|
||||
tag->type = (TMTagType) atoi((gchar*)start + 1);
|
||||
break;
|
||||
case TA_ARGLIST:
|
||||
tag->atts.entry.arglist = g_strdup((gchar*)start + 1);
|
||||
break;
|
||||
case TA_SCOPE:
|
||||
tag->atts.entry.scope = g_strdup((gchar*)start + 1);
|
||||
break;
|
||||
case TA_VARTYPE:
|
||||
tag->atts.entry.var_type = g_strdup((gchar*)start + 1);
|
||||
break;
|
||||
case TA_INHERITS:
|
||||
tag->atts.entry.inheritance = g_strdup((gchar*)start + 1);
|
||||
break;
|
||||
case TA_TIME:
|
||||
if (tm_tag_file_t != tag->type)
|
||||
{
|
||||
g_warning("Got time attribute for non-file tag %s", tag->name);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
tag->atts.file.timestamp = atol((gchar*)start + 1);
|
||||
break;
|
||||
case TA_LANG:
|
||||
if (tm_tag_file_t != tag->type)
|
||||
{
|
||||
g_warning("Got lang attribute for non-file tag %s", tag->name);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
tag->atts.file.lang = atoi((gchar*)start + 1);
|
||||
break;
|
||||
case TA_INACTIVE:
|
||||
if (tm_tag_file_t != tag->type)
|
||||
{
|
||||
g_warning("Got inactive attribute for non-file tag %s", tag->name);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
tag->atts.file.inactive = (gboolean) atoi((gchar*)start + 1);
|
||||
break;
|
||||
case TA_ACCESS:
|
||||
tag->atts.entry.access = *(start + 1);
|
||||
break;
|
||||
case TA_IMPL:
|
||||
tag->atts.entry.impl = *(start + 1);
|
||||
break;
|
||||
default:
|
||||
#ifdef TM_DEBUG
|
||||
g_warning("Unknown attribute %s", start + 1);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
*end = changed_char;
|
||||
}
|
||||
*end = changed_char;
|
||||
}
|
||||
else
|
||||
{
|
||||
// alternative parser for PHP and LaTeX global tags files with the following format
|
||||
// tagname|return value|arglist|description\n
|
||||
gchar **fields;
|
||||
guint field_len;
|
||||
for (start = end = buf, status = TRUE; (TRUE == status); start = end, ++ end)
|
||||
{
|
||||
while ((*end < TA_NAME) && (*end != '\0') && (*end != '\n'))
|
||||
++ end;
|
||||
if (('\0' == *end) || ('\n' == *end))
|
||||
status = FALSE;
|
||||
//changed_char = *end;
|
||||
*end = '\0';
|
||||
if (NULL == tag->name && !isprint(*start))
|
||||
return FALSE;
|
||||
|
||||
fields = g_strsplit((gchar*)start, "|", -1);
|
||||
field_len = g_strv_length(fields);
|
||||
|
||||
if (field_len >= 1) tag->name = g_strdup(fields[0]);
|
||||
else tag->name = NULL;
|
||||
if (field_len >= 2 && fields[1] != NULL) tag->atts.entry.var_type = g_strdup(fields[1]);
|
||||
if (field_len >= 3 && fields[2] != NULL) tag->atts.entry.arglist = g_strdup(fields[2]);
|
||||
tag->atts.file.lang = mode;
|
||||
tag->type = tm_tag_prototype_t;
|
||||
g_strfreev(fields);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == tag->name)
|
||||
return FALSE;
|
||||
if (tm_tag_file_t != tag->type)
|
||||
@ -298,12 +333,12 @@ gboolean tm_tag_init_from_file(TMTag *tag, TMSourceFile *file, FILE *fp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp)
|
||||
TMTag *tm_tag_new_from_file(TMSourceFile *file, FILE *fp, gint mode)
|
||||
{
|
||||
TMTag *tag;
|
||||
|
||||
TAG_NEW(tag);
|
||||
if (FALSE == tm_tag_init_from_file(tag, file, fp))
|
||||
if (FALSE == tm_tag_init_from_file(tag, file, fp, mode))
|
||||
{
|
||||
TAG_FREE(tag);
|
||||
return NULL;
|
||||
|
||||
@ -133,10 +133,11 @@ gboolean tm_workspace_remove_object(TMWorkObject *w, gboolean free)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean tm_workspace_load_global_tags(const char *tags_file)
|
||||
gboolean tm_workspace_load_global_tags(const char *tags_file, gint mode)
|
||||
{
|
||||
FILE *fp;
|
||||
TMTag *tag;
|
||||
TMTagAttrType attr[] = { tm_tag_attr_name_t, 0 };
|
||||
|
||||
if (NULL == (fp = fopen(tags_file, "r")))
|
||||
return FALSE;
|
||||
@ -144,9 +145,14 @@ gboolean tm_workspace_load_global_tags(const char *tags_file)
|
||||
tm_create_workspace();
|
||||
if (NULL == theWorkspace->global_tags)
|
||||
theWorkspace->global_tags = g_ptr_array_new();
|
||||
while (NULL != (tag = tm_tag_new_from_file(NULL, fp)))
|
||||
while (NULL != (tag = tm_tag_new_from_file(NULL, fp, mode)))
|
||||
g_ptr_array_add(theWorkspace->global_tags, tag);
|
||||
fclose(fp);
|
||||
|
||||
// resort the whole array, because tm_tags_find expects a sorted array and it is not sorted
|
||||
// when global.tags, php.tags and latex.tags are loaded at the same time
|
||||
tm_tags_sort(theWorkspace->global_tags, attr, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -278,7 +284,7 @@ gboolean tm_workspace_create_global_tags(const char *pre_process, const char **i
|
||||
g_free(command);
|
||||
unlink(temp_file);
|
||||
g_free(temp_file);
|
||||
source_file = tm_source_file_new(temp_file2, TRUE);
|
||||
source_file = tm_source_file_new(temp_file2, TRUE, NULL);
|
||||
if (NULL == source_file)
|
||||
{
|
||||
unlink(temp_file2);
|
||||
@ -435,7 +441,7 @@ void tm_workspace_dump(void)
|
||||
}
|
||||
|
||||
const GPtrArray *tm_workspace_find(const char *name, int type, TMTagAttrType *attrs
|
||||
, gboolean partial)
|
||||
, gboolean partial, langType lang)
|
||||
{
|
||||
static GPtrArray *tags = NULL;
|
||||
TMTag **matches[2], **match;
|
||||
@ -460,7 +466,7 @@ const GPtrArray *tm_workspace_find(const char *name, int type, TMTagAttrType *at
|
||||
{
|
||||
for (tagIter=0;tagIter<tagCount[i];++tagIter)
|
||||
{
|
||||
if (type & (*match)->type)
|
||||
if ((type & (*match)->type) && (lang == -1 || (*match)->atts.file.lang == lang))
|
||||
g_ptr_array_add(tags, *match);
|
||||
if (partial)
|
||||
{
|
||||
@ -498,7 +504,7 @@ const GPtrArray *tm_workspace_get_parents(const gchar *name)
|
||||
parents = g_ptr_array_new();
|
||||
else
|
||||
g_ptr_array_set_size(parents, 0);
|
||||
matches = tm_workspace_find(name, tm_tag_class_t, type, FALSE);
|
||||
matches = tm_workspace_find(name, tm_tag_class_t, type, FALSE, -1);
|
||||
if ((NULL == matches) || (0 == matches->len))
|
||||
return NULL;
|
||||
g_ptr_array_add(parents, matches->pdata[0]);
|
||||
@ -517,7 +523,7 @@ const GPtrArray *tm_workspace_get_parents(const gchar *name)
|
||||
}
|
||||
if (parents->len == j)
|
||||
{
|
||||
matches = tm_workspace_find(*klass, tm_tag_class_t, type, FALSE);
|
||||
matches = tm_workspace_find(*klass, tm_tag_class_t, type, FALSE, -1);
|
||||
if ((NULL != matches) && (0 < matches->len))
|
||||
g_ptr_array_add(parents, matches->pdata[0]);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user