diff options
| author | David Bremner <bremner@debian.org> | 2012-04-04 23:27:01 -0300 |
|---|---|---|
| committer | David Bremner <bremner@debian.org> | 2012-04-04 23:27:01 -0300 |
| commit | 4adefd4c497a1977db36317ed34c406565fb201d (patch) | |
| tree | 1d1d7c6cea688d8ef71f70a9a022165f60be3140 /lib | |
| parent | 954cf155718a5a7576a7a578d836b76e15d312a4 (diff) | |
| parent | 331f0cac61802606e0103c35453656d2299cbfe3 (diff) | |
Merge tag 'debian/0.12-1' into squeeze-backports
notmuch Debian 0.12-1 upload (same as 0.12 + debian changelog fix)
Conflicts:
debian/changelog
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/database.cc | 34 | ||||
| -rw-r--r-- | lib/index.cc | 19 | ||||
| -rw-r--r-- | lib/messages.c | 6 | ||||
| -rw-r--r-- | lib/notmuch-private.h | 2 | ||||
| -rw-r--r-- | lib/notmuch.h | 6 | ||||
| -rw-r--r-- | lib/query.cc | 35 |
6 files changed, 88 insertions, 14 deletions
diff --git a/lib/database.cc b/lib/database.cc index 8103bd96..16c4354f 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -582,15 +582,15 @@ notmuch_database_t * notmuch_database_open (const char *path, notmuch_database_mode_t mode) { + void *local = talloc_new (NULL); notmuch_database_t *notmuch = NULL; - char *notmuch_path = NULL, *xapian_path = NULL; + char *notmuch_path, *xapian_path; struct stat st; int err; unsigned int i, version; static int initialized = 0; - if (asprintf (¬much_path, "%s/%s", path, ".notmuch") == -1) { - notmuch_path = NULL; + if (! (notmuch_path = talloc_asprintf (local, "%s/%s", path, ".notmuch"))) { fprintf (stderr, "Out of memory\n"); goto DONE; } @@ -602,8 +602,7 @@ notmuch_database_open (const char *path, goto DONE; } - if (asprintf (&xapian_path, "%s/%s", notmuch_path, "xapian") == -1) { - xapian_path = NULL; + if (! (xapian_path = talloc_asprintf (local, "%s/%s", notmuch_path, "xapian"))) { fprintf (stderr, "Out of memory\n"); goto DONE; } @@ -617,7 +616,7 @@ notmuch_database_open (const char *path, initialized = 1; } - notmuch = talloc (NULL, notmuch_database_t); + notmuch = talloc_zero (NULL, notmuch_database_t); notmuch->exception_reported = FALSE; notmuch->path = talloc_strdup (notmuch, path); @@ -703,14 +702,12 @@ notmuch_database_open (const char *path, } catch (const Xapian::Error &error) { fprintf (stderr, "A Xapian exception occurred opening database: %s\n", error.get_msg().c_str()); + notmuch_database_close (notmuch); notmuch = NULL; } DONE: - if (notmuch_path) - free (notmuch_path); - if (xapian_path) - free (xapian_path); + talloc_free (local); return notmuch; } @@ -719,7 +716,8 @@ void notmuch_database_close (notmuch_database_t *notmuch) { try { - if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE) + if (notmuch->xapian_db != NULL && + notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE) (static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))->flush (); } catch (const Xapian::Error &error) { if (! notmuch->exception_reported) { @@ -728,6 +726,17 @@ notmuch_database_close (notmuch_database_t *notmuch) } } + /* Many Xapian objects (and thus notmuch objects) hold references to + * the database, so merely deleting the database may not suffice to + * close it. Thus, we explicitly close it here. */ + if (notmuch->xapian_db != NULL) { + try { + notmuch->xapian_db->close(); + } catch (const Xapian::Error &error) { + /* do nothing */ + } + } + delete notmuch->term_gen; delete notmuch->query_parser; delete notmuch->xapian_db; @@ -1816,6 +1825,9 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch, if (message_ret == NULL) return NOTMUCH_STATUS_NULL_POINTER; + /* return NULL on any failure */ + *message_ret = NULL; + local = talloc_new (notmuch); try { diff --git a/lib/index.cc b/lib/index.cc index e8e9922b..e3777322 100644 --- a/lib/index.cc +++ b/lib/index.cc @@ -315,6 +315,7 @@ _index_mime_part (notmuch_message_t *message, GByteArray *byte_array; GMimeContentDisposition *disposition; char *body; + const char *charset; if (! part) { fprintf (stderr, "Warning: Not indexing empty mime part.\n"); @@ -339,6 +340,10 @@ _index_mime_part (notmuch_message_t *message, if (i > 1) fprintf (stderr, "Warning: Unexpected extra parts of multipart/signed. Indexing anyway.\n"); } + if (GMIME_IS_MULTIPART_ENCRYPTED (multipart)) { + /* Don't index encrypted parts. */ + continue; + } _index_mime_part (message, g_mime_multipart_get_part (multipart, i)); } @@ -386,6 +391,20 @@ _index_mime_part (notmuch_message_t *message, g_mime_stream_filter_add (GMIME_STREAM_FILTER (filter), discard_uuencode_filter); + charset = g_mime_object_get_content_type_parameter (part, "charset"); + if (charset) { + GMimeFilter *charset_filter; + charset_filter = g_mime_filter_charset_new (charset, "UTF-8"); + /* This result can be NULL for things like "unknown-8bit". + * Don't set a NULL filter as that makes GMime print + * annoying assertion-failure messages on stderr. */ + if (charset_filter) { + g_mime_stream_filter_add (GMIME_STREAM_FILTER (filter), + charset_filter); + g_object_unref (charset_filter); + } + } + wrapper = g_mime_part_get_content_object (GMIME_PART (part)); if (wrapper) g_mime_data_wrapper_write_to_stream (wrapper, filter); diff --git a/lib/messages.c b/lib/messages.c index 7bcd1abf..11218648 100644 --- a/lib/messages.c +++ b/lib/messages.c @@ -127,8 +127,10 @@ notmuch_messages_get (notmuch_messages_t *messages) void notmuch_messages_move_to_next (notmuch_messages_t *messages) { - if (! messages->is_of_list_type) - return _notmuch_mset_messages_move_to_next (messages); + if (! messages->is_of_list_type) { + _notmuch_mset_messages_move_to_next (messages); + return; + } if (messages->iterator == NULL) return; diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index 60a932fc..7bf153e0 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -458,7 +458,7 @@ typedef struct _notmuch_string_node { struct _notmuch_string_node *next; } notmuch_string_node_t; -typedef struct _notmuch_string_list { +typedef struct visible _notmuch_string_list { int length; notmuch_string_node_t *head; notmuch_string_node_t **tail; diff --git a/lib/notmuch.h b/lib/notmuch.h index 9f23a106..7929fe72 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -457,6 +457,12 @@ notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); notmuch_sort_t notmuch_query_get_sort (notmuch_query_t *query); +/* Add a tag that will be excluded from the query results by default. + * This exclusion will be overridden if this tag appears explicitly in + * the query. */ +void +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); + /* Execute a query for threads, returning a notmuch_threads_t object * which can be used to iterate over the results. The returned threads * object is owned by the query and as such, will only be valid until diff --git a/lib/query.cc b/lib/query.cc index b6c0f12d..0b366025 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -27,6 +27,7 @@ struct _notmuch_query { notmuch_database_t *notmuch; const char *query_string; notmuch_sort_t sort; + notmuch_string_list_t *exclude_terms; }; typedef struct _notmuch_mset_messages { @@ -76,6 +77,8 @@ notmuch_query_create (notmuch_database_t *notmuch, query->sort = NOTMUCH_SORT_NEWEST_FIRST; + query->exclude_terms = _notmuch_string_list_create (query); + return query; } @@ -97,6 +100,13 @@ notmuch_query_get_sort (notmuch_query_t *query) return query->sort; } +void +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) +{ + char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag); + _notmuch_string_list_append (query->exclude_terms, term); +} + /* We end up having to call the destructors explicitly because we had * to use "placement new" in order to initialize C++ objects within a * block that we allocated with talloc. So C++ is making talloc @@ -112,6 +122,27 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages) return 0; } +/* Return a query that does not match messages with the excluded tags + * registered with the query. Any tags that explicitly appear in + * xquery will not be excluded. */ +static Xapian::Query +_notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) +{ + for (notmuch_string_node_t *term = query->exclude_terms->head; term; + term = term->next) { + Xapian::TermIterator it = xquery.get_terms_begin (); + Xapian::TermIterator end = xquery.get_terms_end (); + for (; it != end; it++) { + if ((*it).compare (term->string) == 0) + break; + } + if (it == end) + xquery = Xapian::Query (Xapian::Query::OP_AND_NOT, + xquery, Xapian::Query (term->string)); + } + return xquery; +} + notmuch_messages_t * notmuch_query_search_messages (notmuch_query_t *query) { @@ -157,6 +188,8 @@ notmuch_query_search_messages (notmuch_query_t *query) mail_query, string_query); } + final_query = _notmuch_exclude_tags (query, final_query); + enquire.set_weighting_scheme (Xapian::BoolWeight()); switch (query->sort) { @@ -436,6 +469,8 @@ notmuch_query_count_messages (notmuch_query_t *query) mail_query, string_query); } + final_query = _notmuch_exclude_tags (query, final_query); + enquire.set_weighting_scheme(Xapian::BoolWeight()); enquire.set_docid_order(Xapian::Enquire::ASCENDING); |
