Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New tagmanager query module #1187

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
93 changes: 39 additions & 54 deletions src/tagmanager/tm_query.c
Expand Up @@ -22,6 +22,7 @@
#include "tm_query.h"
#include "tm_tag.h"
#include "tm_parser.h"
#include "tm_source_file.h"


struct TMQuery
Expand Down Expand Up @@ -78,15 +79,12 @@ TMQuery *tm_query_new(const TMWorkspace *workspace, gint data_sources)

q->workspace = workspace;
q->data_sources = data_sources;
q->names = g_ptr_array_new();
q->names = g_ptr_array_new_with_free_func(free_g_string);
q->langs = g_array_new(FALSE, FALSE, sizeof(TMParserType));
q->scopes = g_ptr_array_new();
q->scopes = g_ptr_array_new_with_free_func(free_g_string);
q->type = -1;
q->refcount = 1;

g_ptr_array_set_free_func(q->names, free_g_string);
g_ptr_array_set_free_func(q->scopes, g_free);

return q;
}

Expand Down Expand Up @@ -149,9 +147,16 @@ gint tm_query_add_name(TMQuery *q, const gchar *name, gssize name_len)
* @return 0 on succcess, < 0 on error.
*/
GEANY_API_SYMBOL
gint tm_query_add_scope(TMQuery *q, const gchar *scope)
gint tm_query_add_scope(TMQuery *q, const gchar *scope, gssize scope_len)
{
g_ptr_array_add(q->scopes, g_strdup(scope));
GString *s;

if (scope_len < 0)
s = g_string_new(scope);
else
s = g_string_new_len(scope, scope_len);

g_ptr_array_add(q->scopes, s);

return 0;
}
Expand Down Expand Up @@ -183,7 +188,7 @@ gint tm_query_add_lang(TMQuery *q, TMParserType lang)
* multiple values.
*
* @param q The query to operate on.
* @param type Bitmasp of the tag time to filter, see @a TMTagType.
* @param type Bitmask of the tag type to filter, see @a TMTagType.
*
* @return 0 on succcess, < 0 on error.
*/
Expand All @@ -199,15 +204,6 @@ gint tm_query_set_tag_type(TMQuery *q, TMTagType type)
}


/* tm_tag_compare() expects pointer to pointers to tags, because it's
* used for GPtrArrays (therefore it's qsort-like). GQueue passes pointer
* to tags. */
static gint tag_compare_ptr(gconstpointer a, gconstpointer b, gpointer data)
{
return tm_tag_compare(&a, &b, data);
}


/** Execute a query
*
* The query will be executed according to the applied filters. Filters
Expand Down Expand Up @@ -239,73 +235,62 @@ static gint tag_compare_ptr(gconstpointer a, gconstpointer b, gpointer data)
GEANY_API_SYMBOL
GPtrArray *tm_query_exec(TMQuery *q, TMTagAttrType *sort_attr, TMTagAttrType *dedup_attr)
{
TMTag **tags, *tag;
gint ntags;
guint i;
TMTag *tag;
guint i, ntags;
GString *s;
GQueue res = G_QUEUE_INIT;
TMSortOptions sort_options;
GList *node, *next;
gchar *scope;
TMParserType *lang;
GPtrArray *ret;
TMTagAttrType def_sort_attr[] = { tm_tag_attr_name_t, 0 };

sort_options.sort_attrs = NULL;
/* tags_array isn not needed by tm_tag_compare(), but for tm_search_cmp() */
sort_options.tags_array = NULL;
sort_options.first = TRUE;
ret = g_ptr_array_new();

foreach_ptr_array(s, i, q->names)
{
TMTag **ptag;
sort_options.cmp_len = s->len;
TMTag **tags;
if (q->data_sources & TM_QUERY_SOURCE_GLOBAL_TAGS)
{
tags = tm_tags_find(q->workspace->global_tags, s->str, s->len, &ntags);
foreach_c_array(ptag, tags, ntags)
g_queue_insert_sorted(&res, *ptag, tag_compare_ptr, &sort_options);
if (ntags)
{
g_ptr_array_set_size(ret, ret->len + ntags);
memcpy(&ret->pdata[ret->len], *tags, ntags * sizeof(gpointer));
}
}
if (q->data_sources & TM_QUERY_SOURCE_SESSION_TAGS)
{
tags = tm_tags_find(q->workspace->tags_array, s->str, s->len, &ntags);
foreach_c_array(ptag, tags, ntags)
g_queue_insert_sorted(&res, *ptag, tag_compare_ptr, &sort_options);
tags = tm_tags_find(q->workspace->global_tags, s->str, s->len, &ntags);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is q->workspace->global_tags correct here? You do the same as in the TM_QUERY_SOURCE_GLOBAL_TAGS case above.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, copy&paste error. Was correct in the initial commit.

if (ntags)
{
g_ptr_array_set_size(ret, ret->len + ntags);
memcpy(&ret->pdata[ret->len], *tags, ntags * sizeof(gpointer));
}
}
}

/* Filter tags according to scope, type and lang. */
for (node = res.head; node; node = next)
foreach_ptr_array(tag, i, ret)
{
gboolean match = TRUE;

next = node->next;
tag = node->data;
foreach_ptr_array(scope, i, q->scopes)
match = match && (g_strcmp0(tag->scope, scope) == 0);
foreach_ptr_array(s, i, q->scopes)
match = match && (strncmp(FALLBACK(tag->scope, ""), s->str, s->len) == 0);

foreach_array(gint, lang, q->langs)
match = match && tm_tag_langs_compatible(*lang, tag->lang);

if (match && q->type >= 0)
match = tag->type & q->type;

/* Remove tag from the results. tags are unowned so removing is easy */
/* Remove tag from the results. Can use the fast variant since order
* doesn't matter until after this loop. */
if (!match)
g_queue_unlink(&res, node);
}

/* Convert GQueue to GPtrArray for sort, dedup and return */
i = 0;
ret = g_ptr_array_sized_new(g_queue_get_length(&res));
foreach_list(node, res.head)
{
tag = (TMTag *) node->data;
g_ptr_array_insert(ret, i++, tag);
g_ptr_array_remove_index_fast(ret, i);
}
g_list_free(res.head);

if (sort_attr)
tm_tags_sort(ret, sort_attr, FALSE, FALSE);
/* Always sort by name, unless wanted otherwise by the caller */
if (!sort_attr)
sort_attr = def_sort_attr;
tm_tags_sort(ret, sort_attr, FALSE, FALSE);

if (dedup_attr)
tm_tags_dedup(ret, dedup_attr, FALSE);
Expand Down
2 changes: 1 addition & 1 deletion src/tagmanager/tm_query.h
Expand Up @@ -28,7 +28,7 @@ TMQuery *tm_query_new(const TMWorkspace *workspace, gint data_sources);
void tm_query_free(TMQuery *q);

gint tm_query_add_name(TMQuery *q, const gchar *name, gssize name_len);
gint tm_query_add_scope(TMQuery *q, const gchar *scope);
gint tm_query_add_scope(TMQuery *q, const gchar *scope, gssize scope_len);
gint tm_query_add_lang(TMQuery *q, TMParserType lang);
gint tm_query_set_tag_type(TMQuery *q, TMTagType type);

Expand Down