/* * call-seq: TAGS.destroy! => nil * * Destroys the tags, freeing all resources allocated for it. */ VALUE notmuch_rb_tags_destroy (VALUE self) { notmuch_tags_t *tags; Data_Get_Notmuch_Tags (self, tags); notmuch_tags_destroy (tags); DATA_PTR (self) = NULL; return Qnil; }
static int do_search_tags (notmuch_database_t *notmuch, const search_format_t *format, notmuch_query_t *query) { notmuch_messages_t *messages = NULL; notmuch_tags_t *tags; const char *tag; int first_tag = 1; /* Special-case query of "*" for better performance. */ if (strcmp (notmuch_query_get_query_string (query), "*") == 0) { tags = notmuch_database_get_all_tags (notmuch); } else { messages = notmuch_query_search_messages (query); if (messages == NULL) return 1; tags = notmuch_messages_collect_tags (messages); } if (tags == NULL) return 1; fputs (format->results_start, stdout); for (; notmuch_tags_valid (tags); notmuch_tags_move_to_next (tags)) { tag = notmuch_tags_get (tags); if (! first_tag) fputs (format->item_sep, stdout); format->item_id (tags, "", tag); first_tag = 0; } notmuch_tags_destroy (tags); if (messages) notmuch_messages_destroy (messages); if (first_tag) fputs (format->results_null, stdout); else fputs (format->results_end, stdout); return 0; }
static int do_search_tags (const search_context_t *ctx) { notmuch_messages_t *messages = NULL; notmuch_tags_t *tags; const char *tag; sprinter_t *format = ctx->format; notmuch_query_t *query = ctx->query; notmuch_database_t *notmuch = ctx->notmuch; /* should the following only special case if no excluded terms * specified? */ /* Special-case query of "*" for better performance. */ if (strcmp (notmuch_query_get_query_string (query), "*") == 0) { tags = notmuch_database_get_all_tags (notmuch); } else { notmuch_status_t status; status = notmuch_query_search_messages_st (query, &messages); if (print_status_query ("notmuch search", query, status)) return 1; tags = notmuch_messages_collect_tags (messages); } if (tags == NULL) return 1; format->begin_list (format); for (; notmuch_tags_valid (tags); notmuch_tags_move_to_next (tags)) { tag = notmuch_tags_get (tags); format->string (format, tag); format->separator (format); } notmuch_tags_destroy (tags); if (messages) notmuch_messages_destroy (messages); format->end (format); return 0; }
notmuch_tags_t * notmuch_messages_collect_tags (notmuch_messages_t *messages) { notmuch_string_list_t *tags; notmuch_tags_t *msg_tags; notmuch_message_t *msg; GHashTable *htable; GList *keys, *l; const char *tag; tags = _notmuch_string_list_create (messages); if (tags == NULL) return NULL; htable = g_hash_table_new_full (g_str_hash, g_str_equal, free, NULL); while ((msg = notmuch_messages_get (messages))) { msg_tags = notmuch_message_get_tags (msg); while ((tag = notmuch_tags_get (msg_tags))) { g_hash_table_insert (htable, xstrdup (tag), NULL); notmuch_tags_move_to_next (msg_tags); } notmuch_tags_destroy (msg_tags); notmuch_message_destroy (msg); notmuch_messages_move_to_next (messages); } keys = g_hash_table_get_keys (htable); for (l = keys; l; l = l->next) { _notmuch_string_list_append (tags, (char *)l->data); } g_list_free (keys); g_hash_table_destroy (htable); _notmuch_string_list_sort (tags); return _notmuch_tags_create (messages, tags); }
static int makes_changes (notmuch_message_t *message, tag_op_list_t *list, tag_op_flag_t flags) { size_t i; notmuch_tags_t *tags; notmuch_bool_t changes = FALSE; /* First, do we delete an existing tag? */ changes = FALSE; for (tags = notmuch_message_get_tags (message); ! changes && notmuch_tags_valid (tags); notmuch_tags_move_to_next (tags)) { const char *cur_tag = notmuch_tags_get (tags); int last_op = (flags & TAG_FLAG_REMOVE_ALL) ? -1 : 0; /* scan backwards to get last operation */ i = list->count; while (i > 0) { i--; if (strcmp (cur_tag, list->ops[i].tag) == 0) { last_op = list->ops[i].remove ? -1 : 1; break; } } changes = (last_op == -1); } notmuch_tags_destroy (tags); if (changes) return TRUE; /* Now check for adding new tags */ for (i = 0; i < list->count; i++) { notmuch_bool_t exists = FALSE; if (list->ops[i].remove) continue; for (tags = notmuch_message_get_tags (message); notmuch_tags_valid (tags); notmuch_tags_move_to_next (tags)) { const char *cur_tag = notmuch_tags_get (tags); if (strcmp (cur_tag, list->ops[i].tag) == 0) { exists = TRUE; break; } } notmuch_tags_destroy (tags); /* the following test is conservative, * in the sense it ignores cases like +foo ... -foo * but this is OK from a correctness point of view */ if (! exists) return TRUE; } return FALSE; }