Example #1
0
/* scope can be NULL.
 * lang can be -1 */
static int
fill_find_tags_array (GPtrArray *dst, const GPtrArray *src,
					  const char *name, const char *scope, int type, gboolean partial,
					  gint lang, gboolean first)
{
	TMTag **match;
	int tagIter, count;

	if ((!src) || (!dst) || (!name) || (!*name))
		return 0;

	match = tm_tags_find (src, name, partial, &count);
	if (count && match && *match)
	{
		for (tagIter = 0; tagIter < count; ++tagIter)
		{
			if (! scope || (match[tagIter]->atts.entry.scope &&
				0 == strcmp(match[tagIter]->atts.entry.scope, scope)))
			{
				if (type & match[tagIter]->type)
				if (lang == -1 || match_langs(lang, match[tagIter]))
				{
					g_ptr_array_add (dst, match[tagIter]);
					if (first)
						break;
				}
			}
		}
	}
	return dst->len;
}
Example #2
0
static void fill_find_tags_array(GPtrArray *dst, const GPtrArray *src,
	const char *name, const char *scope, TMTagType type, TMParserType lang)
{
	TMTag **tag;
	guint i, num;

	if (!src || !dst || !name || !*name)
		return;

	tag = tm_tags_find(src, name, FALSE, &num);
	for (i = 0; i < num; ++i)
	{
		if ((type & (*tag)->type) &&
			tm_tag_langs_compatible(lang, (*tag)->lang) &&
			(!scope || g_strcmp0((*tag)->scope, scope) == 0))
		{
			g_ptr_array_add(dst, *tag);
		}
		tag++;
	}
}
Example #3
0
void tm_source_file_set_tag_arglist(const char *tag_name, const char *arglist)
{
	int count;
	TMTag **tags, *tag;

	if (NULL == arglist ||
		NULL == tag_name ||
		NULL == current_source_file ||
		NULL == current_source_file->work_object.tags_array)
	{
		return;
	}

	tags = tm_tags_find(current_source_file->work_object.tags_array, tag_name, FALSE, FALSE,
			&count);
	if (tags != NULL && count == 1)
	{
		tag = tags[0];
		g_free(tag->atts.entry.arglist);
		tag->atts.entry.arglist = g_strdup(arglist);
	}
}
Example #4
0
static void fill_find_tags_array_prefix(GPtrArray *dst, const GPtrArray *src,
	const char *name, TMParserType lang, guint max_num)
{
	TMTag **tag, *last = NULL;
	guint i, count, num;

	if (!src || !dst || !name || !*name)
		return;

	num = 0;
	tag = tm_tags_find(src, name, TRUE, &count);
	for (i = 0; i < count && num < max_num; ++i)
	{
		if (tm_tag_langs_compatible(lang, (*tag)->lang) &&
			!tm_tag_is_anon(*tag) &&
			(!last || g_strcmp0(last->name, (*tag)->name) != 0))
		{
			g_ptr_array_add(dst, *tag);
			last = *tag;
			num++;
		}
		tag++;
	}
}
Example #5
0
void tm_tags_remove_file_tags(TMSourceFile *source_file, GPtrArray *tags_array)
{
	guint i;

	/* Now we choose between an algorithm with complexity O(tags_array->len) and
	 * O(source_file->tags_array->len * log(tags_array->len)). The latter algorithm
	 * is better when tags_array contains many times more tags than
	 * source_file->tags_array so instead of trying to find the removed tags
	 * linearly, binary search is used. The constant 20 is more or less random
	 * but seems to work well. It's exact value isn't so critical because it's
	 * the extremes where the difference is the biggest: when
	 * source_file->tags_array->len == tags_array->len (single file open) and
	 * source_file->tags_array->len << tags_array->len (the number of tags
	 * from the file is a small fraction of all tags).
	 */
	if (source_file->tags_array->len != 0 &&
		tags_array->len / source_file->tags_array->len < 20)
	{
		for (i = 0; i < tags_array->len; i++)
		{
			TMTag *tag = tags_array->pdata[i];

			if (tag->file == source_file)
				tags_array->pdata[i] = NULL;
		}
	}
	else
	{
		GPtrArray *to_delete = g_ptr_array_sized_new(source_file->tags_array->len);

		for (i = 0; i < source_file->tags_array->len; i++)
		{
			guint j;
			guint tag_count;
			TMTag **found;
			TMTag *tag = source_file->tags_array->pdata[i];

			found = tm_tags_find(tags_array, tag->name, FALSE, TRUE, &tag_count);

			for (j = 0; j < tag_count; j++)
			{
				if (*found != NULL && (*found)->file == source_file)
				{
					/* we cannot set the pointer to NULL now because the search wouldn't work */
					g_ptr_array_add(to_delete, found);
					/* no break - if there are multiple tags of the same name, we would
					 * always find the first instance and wouldn't remove others; duplicates
					 * in the to_delete list aren't a problem */
				}
				found++;
			}
		}

		for (i = 0; i < to_delete->len; i++)
		{
			TMTag **tag = to_delete->pdata[i];
			*tag = NULL;
		}
		g_ptr_array_free(to_delete, TRUE);
	}

	tm_tags_prune(tags_array);
}
Example #6
0
const GPtrArray *tm_workspace_find(const char *name, int type, TMTagAttrType *attrs
 , gboolean partial, langType lang)
{
	static GPtrArray *tags = NULL;
	TMTag **matches[2];
	int len, tagCount[2]={0,0}, tagIter;
	gint tags_lang;

	if ((!theWorkspace) || (!name))
		return NULL;
	len = strlen(name);
	if (!len)
		return NULL;
	if (tags)
		g_ptr_array_set_size(tags, 0);
	else
		tags = g_ptr_array_new();

	matches[0] = tm_tags_find(theWorkspace->work_object.tags_array, name, partial, &tagCount[0]);
	matches[1] = tm_tags_find(theWorkspace->global_tags, name, partial, &tagCount[1]);

	/* file tags */
	if (matches[0] && *matches[0])
	{
		/* tag->atts.file.lang contains the line of the tag and
		 * tags->atts.entry.file->lang contains the language */
		tags_lang = (*matches[0])->atts.entry.file->lang;

		for (tagIter=0;tagIter<tagCount[0];++tagIter)
		{
			if ((type & (*matches[0])->type) && (lang == -1 || tags_lang == lang))
				g_ptr_array_add(tags, *matches[0]);
			if (partial)
			{
				if (0 != strncmp((*matches[0])->name, name, len))
					break;
			}
			else
			{
				if (0 != strcmp((*matches[0])->name, name))
					break;
			}
			++ matches[0];
		}
	}

	/* global tags */
	if (matches[1] && *matches[1])
	{
		int tags_lang_alt = 0;
		/* tag->atts.file.lang contains the language and
		 * tags->atts.entry.file is NULL */
		tags_lang = (*matches[1])->atts.file.lang;
		/* tags_lang_alt is used to load C global tags only once for C and C++
		 * lang = 1 is C++, lang = 0 is C
		 * if we have lang 0, than accept also lang 1 for C++ */
		if (tags_lang == 0)	/* C or C++ */
			tags_lang_alt = 1;
		else
			tags_lang_alt = tags_lang; /* otherwise just ignore it */

		for (tagIter=0;tagIter<tagCount[1];++tagIter)
		{
			if ((type & (*matches[1])->type) && (lang == -1 ||
				tags_lang == lang || tags_lang_alt == lang))
				g_ptr_array_add(tags, *matches[1]);

			if (partial)
			{
				if (0 != strncmp((*matches[1])->name, name, len))
					break;
			}
			else
			{
				if (0 != strcmp((*matches[1])->name, name))
					break;
			}
			++ matches[1];
		}
	}

	if (attrs)
		tm_tags_sort(tags, attrs, TRUE);
	return tags;
}