mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-23 19:38:07 +01:00
lib: run uncrustify
This is the result of running $ uncrustify --replace --config ../devel/uncrustify.cfg *.c *.h *.cc in the lib directory
This commit is contained in:
parent
8a3f86f2f9
commit
2b62ca2e3b
24 changed files with 513 additions and 513 deletions
|
@ -34,7 +34,7 @@ parse_references (void *ctx,
|
||||||
* reference to the database. We should avoid making a message
|
* reference to the database. We should avoid making a message
|
||||||
* its own parent, thus the above check.
|
* its own parent, thus the above check.
|
||||||
*/
|
*/
|
||||||
return talloc_strdup(ctx, last_ref);
|
return talloc_strdup (ctx, last_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
@ -165,12 +165,12 @@ _resolve_message_id_to_thread_id_old (notmuch_database_t *notmuch,
|
||||||
metadata_key = _get_metadata_thread_id_key (ctx, message_id);
|
metadata_key = _get_metadata_thread_id_key (ctx, message_id);
|
||||||
thread_id_string = notmuch->xapian_db->get_metadata (metadata_key);
|
thread_id_string = notmuch->xapian_db->get_metadata (metadata_key);
|
||||||
|
|
||||||
if (thread_id_string.empty()) {
|
if (thread_id_string.empty ()) {
|
||||||
*thread_id_ret = talloc_strdup (ctx,
|
*thread_id_ret = talloc_strdup (ctx,
|
||||||
_notmuch_database_generate_thread_id (notmuch));
|
_notmuch_database_generate_thread_id (notmuch));
|
||||||
db->set_metadata (metadata_key, *thread_id_ret);
|
db->set_metadata (metadata_key, *thread_id_ret);
|
||||||
} else {
|
} else {
|
||||||
*thread_id_ret = talloc_strdup (ctx, thread_id_string.c_str());
|
*thread_id_ret = talloc_strdup (ctx, thread_id_string.c_str ());
|
||||||
}
|
}
|
||||||
|
|
||||||
talloc_free (metadata_key);
|
talloc_free (metadata_key);
|
||||||
|
@ -190,7 +190,7 @@ _merge_threads (notmuch_database_t *notmuch,
|
||||||
|
|
||||||
_notmuch_database_find_doc_ids (notmuch, "thread", loser_thread_id, &loser, &loser_end);
|
_notmuch_database_find_doc_ids (notmuch, "thread", loser_thread_id, &loser, &loser_end);
|
||||||
|
|
||||||
for ( ; loser != loser_end; loser++) {
|
for (; loser != loser_end; loser++) {
|
||||||
message = _notmuch_message_create (notmuch, notmuch,
|
message = _notmuch_message_create (notmuch, notmuch,
|
||||||
*loser, &private_status);
|
*loser, &private_status);
|
||||||
if (message == NULL) {
|
if (message == NULL) {
|
||||||
|
@ -264,7 +264,7 @@ _notmuch_database_link_message_to_parents (notmuch_database_t *notmuch,
|
||||||
last_ref_message_id);
|
last_ref_message_id);
|
||||||
} else if (in_reply_to_message_id) {
|
} else if (in_reply_to_message_id) {
|
||||||
_notmuch_message_add_term (message, "replyto",
|
_notmuch_message_add_term (message, "replyto",
|
||||||
in_reply_to_message_id);
|
in_reply_to_message_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
keys = g_hash_table_get_keys (parents);
|
keys = g_hash_table_get_keys (parents);
|
||||||
|
@ -317,7 +317,7 @@ _notmuch_database_link_message_to_children (notmuch_database_t *notmuch,
|
||||||
|
|
||||||
_notmuch_database_find_doc_ids (notmuch, "reference", message_id, &child, &children_end);
|
_notmuch_database_find_doc_ids (notmuch, "reference", message_id, &child, &children_end);
|
||||||
|
|
||||||
for ( ; child != children_end; child++) {
|
for (; child != children_end; child++) {
|
||||||
|
|
||||||
child_message = _notmuch_message_create (message, notmuch,
|
child_message = _notmuch_message_create (message, notmuch,
|
||||||
*child, &private_status);
|
*child, &private_status);
|
||||||
|
@ -461,7 +461,7 @@ _notmuch_database_link_message (notmuch_database_t *notmuch,
|
||||||
_notmuch_message_add_term (message, "thread", thread_id);
|
_notmuch_message_add_term (message, "thread", thread_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
DONE:
|
DONE:
|
||||||
talloc_free (local);
|
talloc_free (local);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -544,14 +544,14 @@ notmuch_database_index_file (notmuch_database_t *notmuch,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = _notmuch_database_link_message (notmuch, message,
|
ret = _notmuch_database_link_message (notmuch, message,
|
||||||
message_file, is_ghost);
|
message_file, is_ghost);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto DONE;
|
goto DONE;
|
||||||
|
|
||||||
if (is_new || is_ghost)
|
if (is_new || is_ghost)
|
||||||
_notmuch_message_set_header_values (message, date, from, subject);
|
_notmuch_message_set_header_values (message, date, from, subject);
|
||||||
|
|
||||||
if (!indexopts) {
|
if (! indexopts) {
|
||||||
def_indexopts = notmuch_database_get_default_indexopts (notmuch);
|
def_indexopts = notmuch_database_get_default_indexopts (notmuch);
|
||||||
indexopts = def_indexopts;
|
indexopts = def_indexopts;
|
||||||
}
|
}
|
||||||
|
@ -560,13 +560,13 @@ notmuch_database_index_file (notmuch_database_t *notmuch,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto DONE;
|
goto DONE;
|
||||||
|
|
||||||
if (! is_new && !is_ghost)
|
if (! is_new && ! is_ghost)
|
||||||
ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
|
ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
|
||||||
|
|
||||||
_notmuch_message_sync (message);
|
_notmuch_message_sync (message);
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch, "A Xapian exception occurred adding message: %s.\n",
|
_notmuch_database_log (notmuch, "A Xapian exception occurred adding message: %s.\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
goto DONE;
|
goto DONE;
|
||||||
|
|
|
@ -58,7 +58,7 @@ notmuch_database_set_config (notmuch_database_t *notmuch,
|
||||||
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred setting metadata: %s\n",
|
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred setting metadata: %s\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
}
|
}
|
||||||
return NOTMUCH_STATUS_SUCCESS;
|
return NOTMUCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ _metadata_value (notmuch_database_t *notmuch,
|
||||||
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred getting metadata: %s\n",
|
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred getting metadata: %s\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -123,11 +123,11 @@ notmuch_database_get_config_list (notmuch_database_t *notmuch,
|
||||||
try {
|
try {
|
||||||
|
|
||||||
new(&(list->iterator)) Xapian::TermIterator (notmuch->xapian_db->metadata_keys_begin
|
new(&(list->iterator)) Xapian::TermIterator (notmuch->xapian_db->metadata_keys_begin
|
||||||
(CONFIG_PREFIX + (prefix ? prefix : "")));
|
(CONFIG_PREFIX + (prefix ? prefix : "")));
|
||||||
|
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch, "A Xapian exception occurred getting metadata iterator: %s.\n",
|
_notmuch_database_log (notmuch, "A Xapian exception occurred getting metadata iterator: %s.\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ enum _notmuch_features {
|
||||||
* unset, file names are stored in document data.
|
* unset, file names are stored in document data.
|
||||||
*
|
*
|
||||||
* Introduced: version 1. */
|
* Introduced: version 1. */
|
||||||
NOTMUCH_FEATURE_FILE_TERMS = 1 << 0,
|
NOTMUCH_FEATURE_FILE_TERMS = 1 << 0,
|
||||||
|
|
||||||
/* If set, directory timestamps are stored in documents with
|
/* If set, directory timestamps are stored in documents with
|
||||||
* XDIRECTORY terms and relative paths. If unset, directory
|
* XDIRECTORY terms and relative paths. If unset, directory
|
||||||
|
@ -70,7 +70,7 @@ enum _notmuch_features {
|
||||||
* absolute paths.
|
* absolute paths.
|
||||||
*
|
*
|
||||||
* Introduced: version 1. */
|
* Introduced: version 1. */
|
||||||
NOTMUCH_FEATURE_DIRECTORY_DOCS = 1 << 1,
|
NOTMUCH_FEATURE_DIRECTORY_DOCS = 1 << 1,
|
||||||
|
|
||||||
/* If set, the from, subject, and message-id headers are stored in
|
/* If set, the from, subject, and message-id headers are stored in
|
||||||
* message document values. If unset, message documents *may*
|
* message document values. If unset, message documents *may*
|
||||||
|
@ -79,21 +79,21 @@ enum _notmuch_features {
|
||||||
*
|
*
|
||||||
* Introduced: optional in version 1, required as of version 3.
|
* Introduced: optional in version 1, required as of version 3.
|
||||||
*/
|
*/
|
||||||
NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES = 1 << 2,
|
NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES = 1 << 2,
|
||||||
|
|
||||||
/* If set, folder terms are boolean and path terms exist. If
|
/* If set, folder terms are boolean and path terms exist. If
|
||||||
* unset, folder terms are probabilistic and stemmed and path
|
* unset, folder terms are probabilistic and stemmed and path
|
||||||
* terms do not exist.
|
* terms do not exist.
|
||||||
*
|
*
|
||||||
* Introduced: version 2. */
|
* Introduced: version 2. */
|
||||||
NOTMUCH_FEATURE_BOOL_FOLDER = 1 << 3,
|
NOTMUCH_FEATURE_BOOL_FOLDER = 1 << 3,
|
||||||
|
|
||||||
/* If set, missing messages are stored in ghost mail documents.
|
/* If set, missing messages are stored in ghost mail documents.
|
||||||
* If unset, thread IDs of ghost messages are stored as database
|
* If unset, thread IDs of ghost messages are stored as database
|
||||||
* metadata instead of in ghost documents.
|
* metadata instead of in ghost documents.
|
||||||
*
|
*
|
||||||
* Introduced: version 3. */
|
* Introduced: version 3. */
|
||||||
NOTMUCH_FEATURE_GHOSTS = 1 << 4,
|
NOTMUCH_FEATURE_GHOSTS = 1 << 4,
|
||||||
|
|
||||||
|
|
||||||
/* If set, then the database was created after the introduction of
|
/* If set, then the database was created after the introduction of
|
||||||
|
@ -101,52 +101,52 @@ enum _notmuch_features {
|
||||||
* mixture of messages with indexed and non-indexed mime types.
|
* mixture of messages with indexed and non-indexed mime types.
|
||||||
*
|
*
|
||||||
* Introduced: version 3. */
|
* Introduced: version 3. */
|
||||||
NOTMUCH_FEATURE_INDEXED_MIMETYPES = 1 << 5,
|
NOTMUCH_FEATURE_INDEXED_MIMETYPES = 1 << 5,
|
||||||
|
|
||||||
/* If set, messages store the revision number of the last
|
/* If set, messages store the revision number of the last
|
||||||
* modification in NOTMUCH_VALUE_LAST_MOD.
|
* modification in NOTMUCH_VALUE_LAST_MOD.
|
||||||
*
|
*
|
||||||
* Introduced: version 3. */
|
* Introduced: version 3. */
|
||||||
NOTMUCH_FEATURE_LAST_MOD = 1 << 6,
|
NOTMUCH_FEATURE_LAST_MOD = 1 << 6,
|
||||||
|
|
||||||
/* If set, unprefixed terms are stored only for the message body,
|
/* If set, unprefixed terms are stored only for the message body,
|
||||||
* not for headers.
|
* not for headers.
|
||||||
*
|
*
|
||||||
* Introduced: version 3. */
|
* Introduced: version 3. */
|
||||||
NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY = 1 << 7,
|
NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY = 1 << 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* In C++, a named enum is its own type, so define bitwise operators
|
/* In C++, a named enum is its own type, so define bitwise operators
|
||||||
* on _notmuch_features. */
|
* on _notmuch_features. */
|
||||||
inline _notmuch_features
|
inline _notmuch_features
|
||||||
operator|(_notmuch_features a, _notmuch_features b)
|
operator| (_notmuch_features a, _notmuch_features b)
|
||||||
{
|
{
|
||||||
return static_cast<_notmuch_features>(
|
return static_cast<_notmuch_features>(
|
||||||
static_cast<unsigned>(a) | static_cast<unsigned>(b));
|
static_cast<unsigned>(a) | static_cast<unsigned>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _notmuch_features
|
inline _notmuch_features
|
||||||
operator&(_notmuch_features a, _notmuch_features b)
|
operator& (_notmuch_features a, _notmuch_features b)
|
||||||
{
|
{
|
||||||
return static_cast<_notmuch_features>(
|
return static_cast<_notmuch_features>(
|
||||||
static_cast<unsigned>(a) & static_cast<unsigned>(b));
|
static_cast<unsigned>(a) & static_cast<unsigned>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _notmuch_features
|
inline _notmuch_features
|
||||||
operator~(_notmuch_features a)
|
operator~ (_notmuch_features a)
|
||||||
{
|
{
|
||||||
return static_cast<_notmuch_features>(~static_cast<unsigned>(a));
|
return static_cast<_notmuch_features>(~static_cast<unsigned>(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _notmuch_features&
|
inline _notmuch_features&
|
||||||
operator|=(_notmuch_features &a, _notmuch_features b)
|
operator|= (_notmuch_features &a, _notmuch_features b)
|
||||||
{
|
{
|
||||||
a = a | b;
|
a = a | b;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _notmuch_features&
|
inline _notmuch_features&
|
||||||
operator&=(_notmuch_features &a, _notmuch_features b)
|
operator&= (_notmuch_features &a, _notmuch_features b)
|
||||||
{
|
{
|
||||||
a = a & b;
|
a = a & b;
|
||||||
return a;
|
return a;
|
||||||
|
@ -155,23 +155,23 @@ operator&=(_notmuch_features &a, _notmuch_features b)
|
||||||
/*
|
/*
|
||||||
* Configuration options for xapian database fields */
|
* Configuration options for xapian database fields */
|
||||||
typedef enum notmuch_field_flags {
|
typedef enum notmuch_field_flags {
|
||||||
NOTMUCH_FIELD_NO_FLAGS = 0,
|
NOTMUCH_FIELD_NO_FLAGS = 0,
|
||||||
NOTMUCH_FIELD_EXTERNAL = 1 << 0,
|
NOTMUCH_FIELD_EXTERNAL = 1 << 0,
|
||||||
NOTMUCH_FIELD_PROBABILISTIC = 1 << 1,
|
NOTMUCH_FIELD_PROBABILISTIC = 1 << 1,
|
||||||
NOTMUCH_FIELD_PROCESSOR = 1 << 2,
|
NOTMUCH_FIELD_PROCESSOR = 1 << 2,
|
||||||
} notmuch_field_flag_t;
|
} notmuch_field_flag_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* define bitwise operators to hide casts */
|
* define bitwise operators to hide casts */
|
||||||
inline notmuch_field_flag_t
|
inline notmuch_field_flag_t
|
||||||
operator|(notmuch_field_flag_t a, notmuch_field_flag_t b)
|
operator| (notmuch_field_flag_t a, notmuch_field_flag_t b)
|
||||||
{
|
{
|
||||||
return static_cast<notmuch_field_flag_t>(
|
return static_cast<notmuch_field_flag_t>(
|
||||||
static_cast<unsigned>(a) | static_cast<unsigned>(b));
|
static_cast<unsigned>(a) | static_cast<unsigned>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline notmuch_field_flag_t
|
inline notmuch_field_flag_t
|
||||||
operator&(notmuch_field_flag_t a, notmuch_field_flag_t b)
|
operator& (notmuch_field_flag_t a, notmuch_field_flag_t b)
|
||||||
{
|
{
|
||||||
return static_cast<notmuch_field_flag_t>(
|
return static_cast<notmuch_field_flag_t>(
|
||||||
static_cast<unsigned>(a) & static_cast<unsigned>(b));
|
static_cast<unsigned>(a) & static_cast<unsigned>(b));
|
||||||
|
@ -230,7 +230,7 @@ struct _notmuch_database {
|
||||||
|
|
||||||
/* Prior to database version 3, features were implied by the database
|
/* Prior to database version 3, features were implied by the database
|
||||||
* version number, so hard-code them for earlier versions. */
|
* version number, so hard-code them for earlier versions. */
|
||||||
#define NOTMUCH_FEATURES_V0 ((enum _notmuch_features)0)
|
#define NOTMUCH_FEATURES_V0 ((enum _notmuch_features) 0)
|
||||||
#define NOTMUCH_FEATURES_V1 (NOTMUCH_FEATURES_V0 | NOTMUCH_FEATURE_FILE_TERMS | \
|
#define NOTMUCH_FEATURES_V1 (NOTMUCH_FEATURES_V0 | NOTMUCH_FEATURE_FILE_TERMS | \
|
||||||
NOTMUCH_FEATURE_DIRECTORY_DOCS)
|
NOTMUCH_FEATURE_DIRECTORY_DOCS)
|
||||||
#define NOTMUCH_FEATURES_V2 (NOTMUCH_FEATURES_V1 | NOTMUCH_FEATURE_BOOL_FOLDER)
|
#define NOTMUCH_FEATURES_V2 (NOTMUCH_FEATURES_V1 | NOTMUCH_FEATURE_BOOL_FOLDER)
|
||||||
|
|
237
lib/database.cc
237
lib/database.cc
|
@ -32,10 +32,10 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <ftw.h>
|
#include <ftw.h>
|
||||||
|
|
||||||
#include <glib.h> /* g_free, GPtrArray, GHashTable */
|
#include <glib.h> /* g_free, GPtrArray, GHashTable */
|
||||||
#include <glib-object.h> /* g_type_init */
|
#include <glib-object.h> /* g_type_init */
|
||||||
|
|
||||||
#include <gmime/gmime.h> /* g_mime_init */
|
#include <gmime/gmime.h> /* g_mime_init */
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ typedef struct {
|
||||||
|
|
||||||
#define NOTMUCH_DATABASE_VERSION 3
|
#define NOTMUCH_DATABASE_VERSION 3
|
||||||
|
|
||||||
#define STRINGIFY(s) _SUB_STRINGIFY(s)
|
#define STRINGIFY(s) _SUB_STRINGIFY (s)
|
||||||
#define _SUB_STRINGIFY(s) #s
|
#define _SUB_STRINGIFY(s) #s
|
||||||
|
|
||||||
#if HAVE_XAPIAN_DB_RETRY_LOCK
|
#if HAVE_XAPIAN_DB_RETRY_LOCK
|
||||||
|
@ -263,59 +263,59 @@ typedef struct {
|
||||||
static const
|
static const
|
||||||
prefix_t prefix_table[] = {
|
prefix_t prefix_table[] = {
|
||||||
/* name term prefix flags */
|
/* name term prefix flags */
|
||||||
{ "type", "T", NOTMUCH_FIELD_NO_FLAGS },
|
{ "type", "T", NOTMUCH_FIELD_NO_FLAGS },
|
||||||
{ "reference", "XREFERENCE", NOTMUCH_FIELD_NO_FLAGS },
|
{ "reference", "XREFERENCE", NOTMUCH_FIELD_NO_FLAGS },
|
||||||
{ "replyto", "XREPLYTO", NOTMUCH_FIELD_NO_FLAGS },
|
{ "replyto", "XREPLYTO", NOTMUCH_FIELD_NO_FLAGS },
|
||||||
{ "directory", "XDIRECTORY", NOTMUCH_FIELD_NO_FLAGS },
|
{ "directory", "XDIRECTORY", NOTMUCH_FIELD_NO_FLAGS },
|
||||||
{ "file-direntry", "XFDIRENTRY", NOTMUCH_FIELD_NO_FLAGS },
|
{ "file-direntry", "XFDIRENTRY", NOTMUCH_FIELD_NO_FLAGS },
|
||||||
{ "directory-direntry", "XDDIRENTRY", NOTMUCH_FIELD_NO_FLAGS },
|
{ "directory-direntry", "XDDIRENTRY", NOTMUCH_FIELD_NO_FLAGS },
|
||||||
{ "body", "", NOTMUCH_FIELD_EXTERNAL |
|
{ "body", "", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROBABILISTIC},
|
NOTMUCH_FIELD_PROBABILISTIC },
|
||||||
{ "thread", "G", NOTMUCH_FIELD_EXTERNAL |
|
{ "thread", "G", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROCESSOR },
|
NOTMUCH_FIELD_PROCESSOR },
|
||||||
{ "tag", "K", NOTMUCH_FIELD_EXTERNAL |
|
{ "tag", "K", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROCESSOR },
|
NOTMUCH_FIELD_PROCESSOR },
|
||||||
{ "is", "K", NOTMUCH_FIELD_EXTERNAL |
|
{ "is", "K", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROCESSOR },
|
NOTMUCH_FIELD_PROCESSOR },
|
||||||
{ "id", "Q", NOTMUCH_FIELD_EXTERNAL },
|
{ "id", "Q", NOTMUCH_FIELD_EXTERNAL },
|
||||||
{ "mid", "Q", NOTMUCH_FIELD_EXTERNAL |
|
{ "mid", "Q", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROCESSOR },
|
NOTMUCH_FIELD_PROCESSOR },
|
||||||
{ "path", "P", NOTMUCH_FIELD_EXTERNAL|
|
{ "path", "P", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROCESSOR },
|
NOTMUCH_FIELD_PROCESSOR },
|
||||||
{ "property", "XPROPERTY", NOTMUCH_FIELD_EXTERNAL },
|
{ "property", "XPROPERTY", NOTMUCH_FIELD_EXTERNAL },
|
||||||
/*
|
/*
|
||||||
* Unconditionally add ':' to reduce potential ambiguity with
|
* Unconditionally add ':' to reduce potential ambiguity with
|
||||||
* overlapping prefixes and/or terms that start with capital
|
* overlapping prefixes and/or terms that start with capital
|
||||||
* letters. See Xapian document termprefixes.html for related
|
* letters. See Xapian document termprefixes.html for related
|
||||||
* discussion.
|
* discussion.
|
||||||
*/
|
*/
|
||||||
{ "folder", "XFOLDER:", NOTMUCH_FIELD_EXTERNAL |
|
{ "folder", "XFOLDER:", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROCESSOR },
|
NOTMUCH_FIELD_PROCESSOR },
|
||||||
#if HAVE_XAPIAN_FIELD_PROCESSOR
|
#if HAVE_XAPIAN_FIELD_PROCESSOR
|
||||||
{ "date", NULL, NOTMUCH_FIELD_EXTERNAL |
|
{ "date", NULL, NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROCESSOR },
|
NOTMUCH_FIELD_PROCESSOR },
|
||||||
{ "query", NULL, NOTMUCH_FIELD_EXTERNAL |
|
{ "query", NULL, NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROCESSOR },
|
NOTMUCH_FIELD_PROCESSOR },
|
||||||
#endif
|
#endif
|
||||||
{ "from", "XFROM", NOTMUCH_FIELD_EXTERNAL |
|
{ "from", "XFROM", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROBABILISTIC |
|
NOTMUCH_FIELD_PROBABILISTIC |
|
||||||
NOTMUCH_FIELD_PROCESSOR },
|
NOTMUCH_FIELD_PROCESSOR },
|
||||||
{ "to", "XTO", NOTMUCH_FIELD_EXTERNAL |
|
{ "to", "XTO", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROBABILISTIC },
|
NOTMUCH_FIELD_PROBABILISTIC },
|
||||||
{ "attachment", "XATTACHMENT", NOTMUCH_FIELD_EXTERNAL |
|
{ "attachment", "XATTACHMENT", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROBABILISTIC },
|
NOTMUCH_FIELD_PROBABILISTIC },
|
||||||
{ "mimetype", "XMIMETYPE", NOTMUCH_FIELD_EXTERNAL |
|
{ "mimetype", "XMIMETYPE", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROBABILISTIC },
|
NOTMUCH_FIELD_PROBABILISTIC },
|
||||||
{ "subject", "XSUBJECT", NOTMUCH_FIELD_EXTERNAL |
|
{ "subject", "XSUBJECT", NOTMUCH_FIELD_EXTERNAL |
|
||||||
NOTMUCH_FIELD_PROBABILISTIC |
|
NOTMUCH_FIELD_PROBABILISTIC |
|
||||||
NOTMUCH_FIELD_PROCESSOR},
|
NOTMUCH_FIELD_PROCESSOR },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_setup_query_field_default (const prefix_t *prefix, notmuch_database_t *notmuch)
|
_setup_query_field_default (const prefix_t *prefix, notmuch_database_t *notmuch)
|
||||||
{
|
{
|
||||||
if (prefix->prefix)
|
if (prefix->prefix)
|
||||||
notmuch->query_parser->add_prefix ("",prefix->prefix);
|
notmuch->query_parser->add_prefix ("", prefix->prefix);
|
||||||
if (prefix->flags & NOTMUCH_FIELD_PROBABILISTIC)
|
if (prefix->flags & NOTMUCH_FIELD_PROBABILISTIC)
|
||||||
notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);
|
notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);
|
||||||
else
|
else
|
||||||
|
@ -329,9 +329,9 @@ _notmuch_database_user_headers (notmuch_database_t *notmuch)
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
_user_prefix (void *ctx, const char* name)
|
_user_prefix (void *ctx, const char *name)
|
||||||
{
|
{
|
||||||
return talloc_asprintf(ctx, "XU%s:", name);
|
return talloc_asprintf (ctx, "XU%s:", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static notmuch_status_t
|
static notmuch_status_t
|
||||||
|
@ -357,7 +357,7 @@ _setup_user_query_fields (notmuch_database_t *notmuch)
|
||||||
prefix_t query_field;
|
prefix_t query_field;
|
||||||
|
|
||||||
const char *key = notmuch_config_list_key (list)
|
const char *key = notmuch_config_list_key (list)
|
||||||
+ sizeof (CONFIG_HEADER_PREFIX) - 1;
|
+ sizeof (CONFIG_HEADER_PREFIX) - 1;
|
||||||
|
|
||||||
_notmuch_string_map_append (notmuch->user_prefix,
|
_notmuch_string_map_append (notmuch->user_prefix,
|
||||||
key,
|
key,
|
||||||
|
@ -370,7 +370,7 @@ _setup_user_query_fields (notmuch_database_t *notmuch)
|
||||||
query_field.name = talloc_strdup (notmuch, key);
|
query_field.name = talloc_strdup (notmuch, key);
|
||||||
query_field.prefix = _user_prefix (notmuch, key);
|
query_field.prefix = _user_prefix (notmuch, key);
|
||||||
query_field.flags = NOTMUCH_FIELD_PROBABILISTIC
|
query_field.flags = NOTMUCH_FIELD_PROBABILISTIC
|
||||||
| NOTMUCH_FIELD_EXTERNAL;
|
| NOTMUCH_FIELD_EXTERNAL;
|
||||||
|
|
||||||
_setup_query_field_default (&query_field, notmuch);
|
_setup_query_field_default (&query_field, notmuch);
|
||||||
}
|
}
|
||||||
|
@ -388,10 +388,10 @@ _setup_query_field (const prefix_t *prefix, notmuch_database_t *notmuch)
|
||||||
Xapian::FieldProcessor *fp;
|
Xapian::FieldProcessor *fp;
|
||||||
|
|
||||||
if (STRNCMP_LITERAL (prefix->name, "date") == 0)
|
if (STRNCMP_LITERAL (prefix->name, "date") == 0)
|
||||||
fp = (new DateFieldProcessor())->release ();
|
fp = (new DateFieldProcessor ())->release ();
|
||||||
else if (STRNCMP_LITERAL(prefix->name, "query") == 0)
|
else if (STRNCMP_LITERAL (prefix->name, "query") == 0)
|
||||||
fp = (new QueryFieldProcessor (*notmuch->query_parser, notmuch))->release ();
|
fp = (new QueryFieldProcessor (*notmuch->query_parser, notmuch))->release ();
|
||||||
else if (STRNCMP_LITERAL(prefix->name, "thread") == 0)
|
else if (STRNCMP_LITERAL (prefix->name, "thread") == 0)
|
||||||
fp = (new ThreadFieldProcessor (*notmuch->query_parser, notmuch))->release ();
|
fp = (new ThreadFieldProcessor (*notmuch->query_parser, notmuch))->release ();
|
||||||
else
|
else
|
||||||
fp = (new RegexpFieldProcessor (prefix->name, prefix->flags,
|
fp = (new RegexpFieldProcessor (prefix->name, prefix->flags,
|
||||||
|
@ -399,7 +399,7 @@ _setup_query_field (const prefix_t *prefix, notmuch_database_t *notmuch)
|
||||||
|
|
||||||
/* we treat all field-processor fields as boolean in order to get the raw input */
|
/* we treat all field-processor fields as boolean in order to get the raw input */
|
||||||
if (prefix->prefix)
|
if (prefix->prefix)
|
||||||
notmuch->query_parser->add_prefix ("",prefix->prefix);
|
notmuch->query_parser->add_prefix ("", prefix->prefix);
|
||||||
notmuch->query_parser->add_boolean_prefix (prefix->name, fp);
|
notmuch->query_parser->add_boolean_prefix (prefix->name, fp);
|
||||||
} else {
|
} else {
|
||||||
_setup_query_field_default (prefix, notmuch);
|
_setup_query_field_default (prefix, notmuch);
|
||||||
|
@ -469,18 +469,18 @@ static const struct {
|
||||||
{ NOTMUCH_FEATURE_BOOL_FOLDER,
|
{ NOTMUCH_FEATURE_BOOL_FOLDER,
|
||||||
"exact folder:/path: search", "rw" },
|
"exact folder:/path: search", "rw" },
|
||||||
{ NOTMUCH_FEATURE_GHOSTS,
|
{ NOTMUCH_FEATURE_GHOSTS,
|
||||||
"mail documents for missing messages", "w"},
|
"mail documents for missing messages", "w" },
|
||||||
/* Knowledge of the index mime-types are not required for reading
|
/* Knowledge of the index mime-types are not required for reading
|
||||||
* a database because a reader will just be unable to query
|
* a database because a reader will just be unable to query
|
||||||
* them. */
|
* them. */
|
||||||
{ NOTMUCH_FEATURE_INDEXED_MIMETYPES,
|
{ NOTMUCH_FEATURE_INDEXED_MIMETYPES,
|
||||||
"indexed MIME types", "w"},
|
"indexed MIME types", "w" },
|
||||||
{ NOTMUCH_FEATURE_LAST_MOD,
|
{ NOTMUCH_FEATURE_LAST_MOD,
|
||||||
"modification tracking", "w"},
|
"modification tracking", "w" },
|
||||||
/* Existing databases will work fine for all queries not involving
|
/* Existing databases will work fine for all queries not involving
|
||||||
* 'body:' */
|
* 'body:' */
|
||||||
{ NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY,
|
{ NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY,
|
||||||
"index body and headers separately", "w"},
|
"index body and headers separately", "w" },
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
@ -529,8 +529,8 @@ notmuch_status_to_string (notmuch_status_t status)
|
||||||
|
|
||||||
void
|
void
|
||||||
_notmuch_database_log (notmuch_database_t *notmuch,
|
_notmuch_database_log (notmuch_database_t *notmuch,
|
||||||
const char *format,
|
const char *format,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
va_list va_args;
|
va_list va_args;
|
||||||
|
|
||||||
|
@ -545,8 +545,8 @@ _notmuch_database_log (notmuch_database_t *notmuch,
|
||||||
|
|
||||||
void
|
void
|
||||||
_notmuch_database_log_append (notmuch_database_t *notmuch,
|
_notmuch_database_log_append (notmuch_database_t *notmuch,
|
||||||
const char *format,
|
const char *format,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
va_list va_args;
|
va_list va_args;
|
||||||
|
|
||||||
|
@ -669,7 +669,7 @@ notmuch_database_find_message (notmuch_database_t *notmuch,
|
||||||
return NOTMUCH_STATUS_SUCCESS;
|
return NOTMUCH_STATUS_SUCCESS;
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch, "A Xapian exception occurred finding message: %s.\n",
|
_notmuch_database_log (notmuch, "A Xapian exception occurred finding message: %s.\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
*message_ret = NULL;
|
*message_ret = NULL;
|
||||||
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
|
@ -720,7 +720,7 @@ notmuch_database_create_verbose (const char *path,
|
||||||
err = stat (path, &st);
|
err = stat (path, &st);
|
||||||
if (err) {
|
if (err) {
|
||||||
IGNORE_RESULT (asprintf (&message, "Error: Cannot create database at %s: %s.\n",
|
IGNORE_RESULT (asprintf (&message, "Error: Cannot create database at %s: %s.\n",
|
||||||
path, strerror (errno)));
|
path, strerror (errno)));
|
||||||
status = NOTMUCH_STATUS_FILE_ERROR;
|
status = NOTMUCH_STATUS_FILE_ERROR;
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
|
@ -758,7 +758,7 @@ notmuch_database_create_verbose (const char *path,
|
||||||
|
|
||||||
status = notmuch_database_upgrade (notmuch, NULL, NULL);
|
status = notmuch_database_upgrade (notmuch, NULL, NULL);
|
||||||
if (status) {
|
if (status) {
|
||||||
notmuch_database_close(notmuch);
|
notmuch_database_close (notmuch);
|
||||||
notmuch = NULL;
|
notmuch = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -893,7 +893,7 @@ notmuch_database_open (const char *path,
|
||||||
notmuch_status_t status;
|
notmuch_status_t status;
|
||||||
|
|
||||||
status = notmuch_database_open_verbose (path, mode, database,
|
status = notmuch_database_open_verbose (path, mode, database,
|
||||||
&status_string);
|
&status_string);
|
||||||
|
|
||||||
if (status_string) {
|
if (status_string) {
|
||||||
fputs (status_string, stderr);
|
fputs (status_string, stderr);
|
||||||
|
@ -952,7 +952,7 @@ notmuch_database_open_verbose (const char *path,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the GLib type system and threads */
|
/* Initialize the GLib type system and threads */
|
||||||
#if !GLIB_CHECK_VERSION(2, 35, 1)
|
#if ! GLIB_CHECK_VERSION (2, 35, 1)
|
||||||
g_type_init ();
|
g_type_init ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -967,7 +967,7 @@ notmuch_database_open_verbose (const char *path,
|
||||||
notmuch->status_string = NULL;
|
notmuch->status_string = NULL;
|
||||||
notmuch->path = talloc_strdup (notmuch, path);
|
notmuch->path = talloc_strdup (notmuch, path);
|
||||||
|
|
||||||
strip_trailing(notmuch->path, '/');
|
strip_trailing (notmuch->path, '/');
|
||||||
|
|
||||||
notmuch->mode = mode;
|
notmuch->mode = mode;
|
||||||
notmuch->atomic_nesting = 0;
|
notmuch->atomic_nesting = 0;
|
||||||
|
@ -989,9 +989,9 @@ notmuch_database_open_verbose (const char *path,
|
||||||
version = notmuch_database_get_version (notmuch);
|
version = notmuch_database_get_version (notmuch);
|
||||||
if (version > NOTMUCH_DATABASE_VERSION) {
|
if (version > NOTMUCH_DATABASE_VERSION) {
|
||||||
IGNORE_RESULT (asprintf (&message,
|
IGNORE_RESULT (asprintf (&message,
|
||||||
"Error: Notmuch database at %s\n"
|
"Error: Notmuch database at %s\n"
|
||||||
" has a newer database format version (%u) than supported by this\n"
|
" has a newer database format version (%u) than supported by this\n"
|
||||||
" version of notmuch (%u).\n",
|
" version of notmuch (%u).\n",
|
||||||
notmuch_path, version, NOTMUCH_DATABASE_VERSION));
|
notmuch_path, version, NOTMUCH_DATABASE_VERSION));
|
||||||
notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
|
notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
|
||||||
notmuch_database_destroy (notmuch);
|
notmuch_database_destroy (notmuch);
|
||||||
|
@ -1008,9 +1008,9 @@ notmuch_database_open_verbose (const char *path,
|
||||||
&incompat_features);
|
&incompat_features);
|
||||||
if (incompat_features) {
|
if (incompat_features) {
|
||||||
IGNORE_RESULT (asprintf (&message,
|
IGNORE_RESULT (asprintf (&message,
|
||||||
"Error: Notmuch database at %s\n"
|
"Error: Notmuch database at %s\n"
|
||||||
" requires features (%s)\n"
|
" requires features (%s)\n"
|
||||||
" not supported by this version of notmuch.\n",
|
" not supported by this version of notmuch.\n",
|
||||||
notmuch_path, incompat_features));
|
notmuch_path, incompat_features));
|
||||||
notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
|
notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
|
||||||
notmuch_database_destroy (notmuch);
|
notmuch_database_destroy (notmuch);
|
||||||
|
@ -1067,7 +1067,7 @@ notmuch_database_open_verbose (const char *path,
|
||||||
status = _setup_user_query_fields (notmuch);
|
status = _setup_user_query_fields (notmuch);
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
IGNORE_RESULT (asprintf (&message, "A Xapian exception occurred opening database: %s\n",
|
IGNORE_RESULT (asprintf (&message, "A Xapian exception occurred opening database: %s\n",
|
||||||
error.get_msg().c_str()));
|
error.get_msg ().c_str ()));
|
||||||
notmuch_database_destroy (notmuch);
|
notmuch_database_destroy (notmuch);
|
||||||
notmuch = NULL;
|
notmuch = NULL;
|
||||||
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
|
@ -1108,16 +1108,16 @@ notmuch_database_close (notmuch_database_t *notmuch)
|
||||||
if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE &&
|
if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE &&
|
||||||
notmuch->atomic_nesting)
|
notmuch->atomic_nesting)
|
||||||
(static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))
|
(static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))
|
||||||
->cancel_transaction ();
|
->cancel_transaction ();
|
||||||
|
|
||||||
/* Close the database. This implicitly flushes
|
/* Close the database. This implicitly flushes
|
||||||
* outstanding changes. */
|
* outstanding changes. */
|
||||||
notmuch->xapian_db->close();
|
notmuch->xapian_db->close ();
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
if (! notmuch->exception_reported) {
|
if (! notmuch->exception_reported) {
|
||||||
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred closing database: %s\n",
|
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred closing database: %s\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1182,7 +1182,9 @@ class NotmuchCompactor : public Xapian::Compactor
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NotmuchCompactor(notmuch_compact_status_cb_t cb, void *closure) :
|
NotmuchCompactor(notmuch_compact_status_cb_t cb, void *closure) :
|
||||||
status_cb (cb), status_closure (closure) { }
|
status_cb (cb), status_closure (closure)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
set_status (const std::string &table, const std::string &status)
|
set_status (const std::string &table, const std::string &status)
|
||||||
|
@ -1193,9 +1195,9 @@ public:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (status.length () == 0)
|
if (status.length () == 0)
|
||||||
msg = talloc_asprintf (NULL, "compacting table %s", table.c_str());
|
msg = talloc_asprintf (NULL, "compacting table %s", table.c_str ());
|
||||||
else
|
else
|
||||||
msg = talloc_asprintf (NULL, " %s", status.c_str());
|
msg = talloc_asprintf (NULL, " %s", status.c_str ());
|
||||||
|
|
||||||
if (msg == NULL) {
|
if (msg == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -1265,8 +1267,7 @@ notmuch_database_compact (const char *path,
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
keep_backup = false;
|
keep_backup = false;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
keep_backup = true;
|
keep_backup = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1277,7 +1278,7 @@ notmuch_database_compact (const char *path,
|
||||||
}
|
}
|
||||||
if (errno != ENOENT) {
|
if (errno != ENOENT) {
|
||||||
_notmuch_database_log (notmuch, "Unknown error while stat()ing path: %s\n",
|
_notmuch_database_log (notmuch, "Unknown error while stat()ing path: %s\n",
|
||||||
strerror (errno));
|
strerror (errno));
|
||||||
ret = NOTMUCH_STATUS_FILE_ERROR;
|
ret = NOTMUCH_STATUS_FILE_ERROR;
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
|
@ -1296,21 +1297,21 @@ notmuch_database_compact (const char *path,
|
||||||
compactor.set_destdir (compact_xapian_path);
|
compactor.set_destdir (compact_xapian_path);
|
||||||
compactor.compact ();
|
compactor.compact ();
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch, "Error while compacting: %s\n", error.get_msg().c_str());
|
_notmuch_database_log (notmuch, "Error while compacting: %s\n", error.get_msg ().c_str ());
|
||||||
ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rename (xapian_path, backup_path)) {
|
if (rename (xapian_path, backup_path)) {
|
||||||
_notmuch_database_log (notmuch, "Error moving %s to %s: %s\n",
|
_notmuch_database_log (notmuch, "Error moving %s to %s: %s\n",
|
||||||
xapian_path, backup_path, strerror (errno));
|
xapian_path, backup_path, strerror (errno));
|
||||||
ret = NOTMUCH_STATUS_FILE_ERROR;
|
ret = NOTMUCH_STATUS_FILE_ERROR;
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rename (compact_xapian_path, xapian_path)) {
|
if (rename (compact_xapian_path, xapian_path)) {
|
||||||
_notmuch_database_log (notmuch, "Error moving %s to %s: %s\n",
|
_notmuch_database_log (notmuch, "Error moving %s to %s: %s\n",
|
||||||
compact_xapian_path, xapian_path, strerror (errno));
|
compact_xapian_path, xapian_path, strerror (errno));
|
||||||
ret = NOTMUCH_STATUS_FILE_ERROR;
|
ret = NOTMUCH_STATUS_FILE_ERROR;
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
|
@ -1318,7 +1319,7 @@ notmuch_database_compact (const char *path,
|
||||||
if (! keep_backup) {
|
if (! keep_backup) {
|
||||||
if (rmtree (backup_path)) {
|
if (rmtree (backup_path)) {
|
||||||
_notmuch_database_log (notmuch, "Error removing old database %s: %s\n",
|
_notmuch_database_log (notmuch, "Error removing old database %s: %s\n",
|
||||||
backup_path, strerror (errno));
|
backup_path, strerror (errno));
|
||||||
ret = NOTMUCH_STATUS_FILE_ERROR;
|
ret = NOTMUCH_STATUS_FILE_ERROR;
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
|
@ -1388,8 +1389,8 @@ notmuch_bool_t
|
||||||
notmuch_database_needs_upgrade (notmuch_database_t *notmuch)
|
notmuch_database_needs_upgrade (notmuch_database_t *notmuch)
|
||||||
{
|
{
|
||||||
return notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE &&
|
return notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE &&
|
||||||
((NOTMUCH_FEATURES_CURRENT & ~notmuch->features) ||
|
((NOTMUCH_FEATURES_CURRENT & ~notmuch->features) ||
|
||||||
(notmuch_database_get_version (notmuch) < NOTMUCH_DATABASE_VERSION));
|
(notmuch_database_get_version (notmuch) < NOTMUCH_DATABASE_VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
static volatile sig_atomic_t do_progress_notify = 0;
|
static volatile sig_atomic_t do_progress_notify = 0;
|
||||||
|
@ -1414,8 +1415,8 @@ handle_sigalrm (unused (int signal))
|
||||||
*/
|
*/
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_database_upgrade (notmuch_database_t *notmuch,
|
notmuch_database_upgrade (notmuch_database_t *notmuch,
|
||||||
void (*progress_notify) (void *closure,
|
void (*progress_notify)(void *closure,
|
||||||
double progress),
|
double progress),
|
||||||
void *closure)
|
void *closure)
|
||||||
{
|
{
|
||||||
void *local = talloc_new (NULL);
|
void *local = talloc_new (NULL);
|
||||||
|
@ -1510,8 +1511,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
|
||||||
goto DONE;
|
goto DONE;
|
||||||
for (;
|
for (;
|
||||||
notmuch_messages_valid (messages);
|
notmuch_messages_valid (messages);
|
||||||
notmuch_messages_move_to_next (messages))
|
notmuch_messages_move_to_next (messages)) {
|
||||||
{
|
|
||||||
if (do_progress_notify) {
|
if (do_progress_notify) {
|
||||||
progress_notify (closure, (double) count / total);
|
progress_notify (closure, (double) count / total);
|
||||||
do_progress_notify = 0;
|
do_progress_notify = 0;
|
||||||
|
@ -1568,8 +1568,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
|
||||||
|
|
||||||
for (t = notmuch->xapian_db->allterms_begin ("XTIMESTAMP");
|
for (t = notmuch->xapian_db->allterms_begin ("XTIMESTAMP");
|
||||||
t != t_end;
|
t != t_end;
|
||||||
t++)
|
t++) {
|
||||||
{
|
|
||||||
Xapian::PostingIterator p, p_end;
|
Xapian::PostingIterator p, p_end;
|
||||||
std::string term = *t;
|
std::string term = *t;
|
||||||
|
|
||||||
|
@ -1577,8 +1576,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
|
||||||
|
|
||||||
for (p = notmuch->xapian_db->postlist_begin (term);
|
for (p = notmuch->xapian_db->postlist_begin (term);
|
||||||
p != p_end;
|
p != p_end;
|
||||||
p++)
|
p++) {
|
||||||
{
|
|
||||||
Xapian::Document document;
|
Xapian::Document document;
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
notmuch_directory_t *directory;
|
notmuch_directory_t *directory;
|
||||||
|
@ -1592,7 +1590,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
|
||||||
mtime = Xapian::sortable_unserialise (
|
mtime = Xapian::sortable_unserialise (
|
||||||
document.get_value (NOTMUCH_VALUE_TIMESTAMP));
|
document.get_value (NOTMUCH_VALUE_TIMESTAMP));
|
||||||
|
|
||||||
directory = _notmuch_directory_create (notmuch, term.c_str() + 10,
|
directory = _notmuch_directory_create (notmuch, term.c_str () + 10,
|
||||||
NOTMUCH_FIND_CREATE, &status);
|
NOTMUCH_FIND_CREATE, &status);
|
||||||
notmuch_directory_set_mtime (directory, mtime);
|
notmuch_directory_set_mtime (directory, mtime);
|
||||||
notmuch_directory_destroy (directory);
|
notmuch_directory_destroy (directory);
|
||||||
|
@ -1641,7 +1639,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
|
||||||
|
|
||||||
if (private_status) {
|
if (private_status) {
|
||||||
_notmuch_database_log (notmuch,
|
_notmuch_database_log (notmuch,
|
||||||
"Upgrade failed while creating ghost messages.\n");
|
"Upgrade failed while creating ghost messages.\n");
|
||||||
status = COERCE_STATUS (private_status, "Unexpected status from _notmuch_message_initialize_ghost");
|
status = COERCE_STATUS (private_status, "Unexpected status from _notmuch_message_initialize_ghost");
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
|
@ -1657,7 +1655,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
|
||||||
db->set_metadata ("features", _print_features (local, notmuch->features));
|
db->set_metadata ("features", _print_features (local, notmuch->features));
|
||||||
db->set_metadata ("version", STRINGIFY (NOTMUCH_DATABASE_VERSION));
|
db->set_metadata ("version", STRINGIFY (NOTMUCH_DATABASE_VERSION));
|
||||||
|
|
||||||
DONE:
|
DONE:
|
||||||
if (status == NOTMUCH_STATUS_SUCCESS)
|
if (status == NOTMUCH_STATUS_SUCCESS)
|
||||||
db->commit_transaction ();
|
db->commit_transaction ();
|
||||||
else
|
else
|
||||||
|
@ -1697,12 +1695,12 @@ notmuch_database_begin_atomic (notmuch_database_t *notmuch)
|
||||||
(static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))->begin_transaction (false);
|
(static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))->begin_transaction (false);
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch, "A Xapian exception occurred beginning transaction: %s.\n",
|
_notmuch_database_log (notmuch, "A Xapian exception occurred beginning transaction: %s.\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
DONE:
|
DONE:
|
||||||
notmuch->atomic_nesting++;
|
notmuch->atomic_nesting++;
|
||||||
return NOTMUCH_STATUS_SUCCESS;
|
return NOTMUCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1731,7 +1729,7 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch)
|
||||||
db->commit ();
|
db->commit ();
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch, "A Xapian exception occurred committing transaction: %s.\n",
|
_notmuch_database_log (notmuch, "A Xapian exception occurred committing transaction: %s.\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
@ -1741,14 +1739,14 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch)
|
||||||
notmuch->atomic_dirty = false;
|
notmuch->atomic_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DONE:
|
DONE:
|
||||||
notmuch->atomic_nesting--;
|
notmuch->atomic_nesting--;
|
||||||
return NOTMUCH_STATUS_SUCCESS;
|
return NOTMUCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
notmuch_database_get_revision (notmuch_database_t *notmuch,
|
notmuch_database_get_revision (notmuch_database_t *notmuch,
|
||||||
const char **uuid)
|
const char **uuid)
|
||||||
{
|
{
|
||||||
if (uuid)
|
if (uuid)
|
||||||
*uuid = notmuch->uuid;
|
*uuid = notmuch->uuid;
|
||||||
|
@ -1866,7 +1864,7 @@ _notmuch_database_find_directory_id (notmuch_database_t *notmuch,
|
||||||
}
|
}
|
||||||
|
|
||||||
directory = _notmuch_directory_create (notmuch, path, flags, &status);
|
directory = _notmuch_directory_create (notmuch, path, flags, &status);
|
||||||
if (status || !directory) {
|
if (status || ! directory) {
|
||||||
*directory_id = -1;
|
*directory_id = -1;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -1920,7 +1918,7 @@ _notmuch_database_filename_to_direntry (void *ctx,
|
||||||
|
|
||||||
status = _notmuch_database_find_directory_id (notmuch, directory, flags,
|
status = _notmuch_database_find_directory_id (notmuch, directory, flags,
|
||||||
&directory_id);
|
&directory_id);
|
||||||
if (status || directory_id == (unsigned int)-1) {
|
if (status || directory_id == (unsigned int) -1) {
|
||||||
*direntry = NULL;
|
*direntry = NULL;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -1950,11 +1948,10 @@ _notmuch_database_relative_path (notmuch_database_t *notmuch,
|
||||||
relative = path;
|
relative = path;
|
||||||
|
|
||||||
if (*relative == '/') {
|
if (*relative == '/') {
|
||||||
while (*relative == '/' && *(relative+1) == '/')
|
while (*relative == '/' && *(relative + 1) == '/')
|
||||||
relative++;
|
relative++;
|
||||||
|
|
||||||
if (strncmp (relative, db_path, db_path_len) == 0)
|
if (strncmp (relative, db_path, db_path_len) == 0) {
|
||||||
{
|
|
||||||
relative += db_path_len;
|
relative += db_path_len;
|
||||||
while (*relative == '/')
|
while (*relative == '/')
|
||||||
relative++;
|
relative++;
|
||||||
|
@ -1980,7 +1977,7 @@ notmuch_database_get_directory (notmuch_database_t *notmuch,
|
||||||
NOTMUCH_FIND_LOOKUP, &status);
|
NOTMUCH_FIND_LOOKUP, &status);
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch, "A Xapian exception occurred getting directory: %s.\n",
|
_notmuch_database_log (notmuch, "A Xapian exception occurred getting directory: %s.\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
@ -2023,13 +2020,13 @@ notmuch_database_remove_message (notmuch_database_t *notmuch,
|
||||||
&message);
|
&message);
|
||||||
|
|
||||||
if (status == NOTMUCH_STATUS_SUCCESS && message) {
|
if (status == NOTMUCH_STATUS_SUCCESS && message) {
|
||||||
status = _notmuch_message_remove_filename (message, filename);
|
status = _notmuch_message_remove_filename (message, filename);
|
||||||
if (status == NOTMUCH_STATUS_SUCCESS)
|
if (status == NOTMUCH_STATUS_SUCCESS)
|
||||||
_notmuch_message_delete (message);
|
_notmuch_message_delete (message);
|
||||||
else if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
|
else if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
|
||||||
_notmuch_message_sync (message);
|
_notmuch_message_sync (message);
|
||||||
|
|
||||||
notmuch_message_destroy (message);
|
notmuch_message_destroy (message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -2060,7 +2057,7 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
|
||||||
try {
|
try {
|
||||||
status = _notmuch_database_filename_to_direntry (
|
status = _notmuch_database_filename_to_direntry (
|
||||||
local, notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry);
|
local, notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry);
|
||||||
if (status || !direntry)
|
if (status || ! direntry)
|
||||||
goto DONE;
|
goto DONE;
|
||||||
|
|
||||||
term = talloc_asprintf (local, "%s%s", prefix, direntry);
|
term = talloc_asprintf (local, "%s%s", prefix, direntry);
|
||||||
|
@ -2077,7 +2074,7 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
|
||||||
}
|
}
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred finding message by filename: %s\n",
|
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred finding message by filename: %s\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
@ -2122,15 +2119,15 @@ notmuch_database_get_all_tags (notmuch_database_t *db)
|
||||||
notmuch_string_list_t *tags;
|
notmuch_string_list_t *tags;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
i = db->xapian_db->allterms_begin();
|
i = db->xapian_db->allterms_begin ();
|
||||||
end = db->xapian_db->allterms_end();
|
end = db->xapian_db->allterms_end ();
|
||||||
tags = _notmuch_database_get_terms_with_prefix (db, i, end,
|
tags = _notmuch_database_get_terms_with_prefix (db, i, end,
|
||||||
_find_prefix ("tag"));
|
_find_prefix ("tag"));
|
||||||
_notmuch_string_list_sort (tags);
|
_notmuch_string_list_sort (tags);
|
||||||
return _notmuch_tags_create (db, tags);
|
return _notmuch_tags_create (db, tags);
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (db, "A Xapian exception occurred getting tags: %s.\n",
|
_notmuch_database_log (db, "A Xapian exception occurred getting tags: %s.\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
db->exception_reported = true;
|
db->exception_reported = true;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@ _create_filenames_for_terms_with_prefix (void *ctx,
|
||||||
notmuch_string_list_t *filename_list;
|
notmuch_string_list_t *filename_list;
|
||||||
Xapian::TermIterator i, end;
|
Xapian::TermIterator i, end;
|
||||||
|
|
||||||
i = notmuch->xapian_db->allterms_begin();
|
i = notmuch->xapian_db->allterms_begin ();
|
||||||
end = notmuch->xapian_db->allterms_end();
|
end = notmuch->xapian_db->allterms_end ();
|
||||||
filename_list = _notmuch_database_get_terms_with_prefix (ctx, i, end,
|
filename_list = _notmuch_database_get_terms_with_prefix (ctx, i, end,
|
||||||
prefix);
|
prefix);
|
||||||
if (unlikely (filename_list == NULL))
|
if (unlikely (filename_list == NULL))
|
||||||
|
@ -140,7 +140,7 @@ _notmuch_directory_create (notmuch_database_t *notmuch,
|
||||||
directory->document_id = directory->doc.get_docid ();
|
directory->document_id = directory->doc.get_docid ();
|
||||||
|
|
||||||
if (private_status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
|
if (private_status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
|
||||||
if (!create) {
|
if (! create) {
|
||||||
notmuch_directory_destroy (directory);
|
notmuch_directory_destroy (directory);
|
||||||
directory = NULL;
|
directory = NULL;
|
||||||
*status_ret = NOTMUCH_STATUS_SUCCESS;
|
*status_ret = NOTMUCH_STATUS_SUCCESS;
|
||||||
|
@ -187,8 +187,8 @@ _notmuch_directory_create (notmuch_database_t *notmuch,
|
||||||
directory->doc.get_value (NOTMUCH_VALUE_TIMESTAMP));
|
directory->doc.get_value (NOTMUCH_VALUE_TIMESTAMP));
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch,
|
_notmuch_database_log (notmuch,
|
||||||
"A Xapian exception occurred creating a directory: %s.\n",
|
"A Xapian exception occurred creating a directory: %s.\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
notmuch_directory_destroy (directory);
|
notmuch_directory_destroy (directory);
|
||||||
directory = NULL;
|
directory = NULL;
|
||||||
|
@ -224,7 +224,7 @@ notmuch_directory_set_mtime (notmuch_directory_t *directory,
|
||||||
|
|
||||||
try {
|
try {
|
||||||
directory->doc.add_value (NOTMUCH_VALUE_TIMESTAMP,
|
directory->doc.add_value (NOTMUCH_VALUE_TIMESTAMP,
|
||||||
Xapian::sortable_serialise (mtime));
|
Xapian::sortable_serialise (mtime));
|
||||||
|
|
||||||
db->replace_document (directory->document_id, directory->doc);
|
db->replace_document (directory->document_id, directory->doc);
|
||||||
|
|
||||||
|
@ -232,8 +232,8 @@ notmuch_directory_set_mtime (notmuch_directory_t *directory,
|
||||||
|
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch,
|
_notmuch_database_log (notmuch,
|
||||||
"A Xapian exception occurred setting directory mtime: %s.\n",
|
"A Xapian exception occurred setting directory mtime: %s.\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
@ -277,7 +277,7 @@ notmuch_directory_get_child_directories (notmuch_directory_t *directory)
|
||||||
directory->document_id);
|
directory->document_id);
|
||||||
|
|
||||||
child_directories = _create_filenames_for_terms_with_prefix (directory,
|
child_directories = _create_filenames_for_terms_with_prefix (directory,
|
||||||
directory->notmuch, term);
|
directory->notmuch, term);
|
||||||
|
|
||||||
talloc_free (term);
|
talloc_free (term);
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ notmuch_directory_delete (notmuch_directory_t *directory)
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (directory->notmuch,
|
_notmuch_database_log (directory->notmuch,
|
||||||
"A Xapian exception occurred deleting directory entry: %s.\n",
|
"A Xapian exception occurred deleting directory entry: %s.\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
directory->notmuch->exception_reported = true;
|
directory->notmuch->exception_reported = true;
|
||||||
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
117
lib/index.cc
117
lib/index.cc
|
@ -43,46 +43,46 @@ typedef struct {
|
||||||
* which we discard data. */
|
* which we discard data. */
|
||||||
static const int first_uuencode_skipping_state = 11;
|
static const int first_uuencode_skipping_state = 11;
|
||||||
static const scanner_state_t uuencode_states[] = {
|
static const scanner_state_t uuencode_states[] = {
|
||||||
{0, 'b', 'b', 1, 0},
|
{ 0, 'b', 'b', 1, 0 },
|
||||||
{1, 'e', 'e', 2, 0},
|
{ 1, 'e', 'e', 2, 0 },
|
||||||
{2, 'g', 'g', 3, 0},
|
{ 2, 'g', 'g', 3, 0 },
|
||||||
{3, 'i', 'i', 4, 0},
|
{ 3, 'i', 'i', 4, 0 },
|
||||||
{4, 'n', 'n', 5, 0},
|
{ 4, 'n', 'n', 5, 0 },
|
||||||
{5, ' ', ' ', 6, 0},
|
{ 5, ' ', ' ', 6, 0 },
|
||||||
{6, '0', '7', 7, 0},
|
{ 6, '0', '7', 7, 0 },
|
||||||
{7, '0', '7', 8, 0},
|
{ 7, '0', '7', 8, 0 },
|
||||||
{8, '0', '7', 9, 0},
|
{ 8, '0', '7', 9, 0 },
|
||||||
{9, ' ', ' ', 10, 0},
|
{ 9, ' ', ' ', 10, 0 },
|
||||||
{10, '\n', '\n', 11, 10},
|
{ 10, '\n', '\n', 11, 10 },
|
||||||
{11, 'M', 'M', 12, 0},
|
{ 11, 'M', 'M', 12, 0 },
|
||||||
{12, ' ', '`', 12, 11}
|
{ 12, ' ', '`', 12, 11 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The following table is intended to implement this DFA (in 'dot'
|
/* The following table is intended to implement this DFA (in 'dot'
|
||||||
format). Note that 2 and 3 are "hidden" states used to step through
|
* format). Note that 2 and 3 are "hidden" states used to step through
|
||||||
the possible out edges of state 1.
|
* the possible out edges of state 1.
|
||||||
|
*
|
||||||
digraph html_filter {
|
* digraph html_filter {
|
||||||
0 -> 1 [label="<"];
|
* 0 -> 1 [label="<"];
|
||||||
0 -> 0;
|
* 0 -> 0;
|
||||||
1 -> 4 [label="'"];
|
* 1 -> 4 [label="'"];
|
||||||
1 -> 5 [label="\""];
|
* 1 -> 5 [label="\""];
|
||||||
1 -> 0 [label=">"];
|
* 1 -> 0 [label=">"];
|
||||||
1 -> 1;
|
* 1 -> 1;
|
||||||
4 -> 1 [label="'"];
|
* 4 -> 1 [label="'"];
|
||||||
4 -> 4;
|
* 4 -> 4;
|
||||||
5 -> 1 [label="\""];
|
* 5 -> 1 [label="\""];
|
||||||
5 -> 5;
|
* 5 -> 5;
|
||||||
}
|
* }
|
||||||
*/
|
*/
|
||||||
static const int first_html_skipping_state = 1;
|
static const int first_html_skipping_state = 1;
|
||||||
static const scanner_state_t html_states[] = {
|
static const scanner_state_t html_states[] = {
|
||||||
{0, '<', '<', 1, 0},
|
{ 0, '<', '<', 1, 0 },
|
||||||
{1, '\'', '\'', 4, 2}, /* scanning for quote or > */
|
{ 1, '\'', '\'', 4, 2 }, /* scanning for quote or > */
|
||||||
{1, '"', '"', 5, 3},
|
{ 1, '"', '"', 5, 3 },
|
||||||
{1, '>', '>', 0, 1},
|
{ 1, '>', '>', 0, 1 },
|
||||||
{4, '\'', '\'', 1, 4}, /* inside single quotes */
|
{ 4, '\'', '\'', 1, 4 }, /* inside single quotes */
|
||||||
{5, '"', '"', 1, 5}, /* inside double quotes */
|
{ 5, '"', '"', 1, 5 }, /* inside double quotes */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Oh, how I wish that gobject didn't require so much noisy boilerplate!
|
/* Oh, how I wish that gobject didn't require so much noisy boilerplate!
|
||||||
|
@ -168,6 +168,7 @@ static GMimeFilter *
|
||||||
filter_copy (GMimeFilter *gmime_filter)
|
filter_copy (GMimeFilter *gmime_filter)
|
||||||
{
|
{
|
||||||
NotmuchFilterDiscardNonTerm *filter = (NotmuchFilterDiscardNonTerm *) gmime_filter;
|
NotmuchFilterDiscardNonTerm *filter = (NotmuchFilterDiscardNonTerm *) gmime_filter;
|
||||||
|
|
||||||
return notmuch_filter_discard_non_term_new (filter->content_type);
|
return notmuch_filter_discard_non_term_new (filter->content_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +191,7 @@ filter_filter (GMimeFilter *gmime_filter, char *inbuf, size_t inlen, size_t pres
|
||||||
|
|
||||||
next = filter->state;
|
next = filter->state;
|
||||||
while (inptr < inend) {
|
while (inptr < inend) {
|
||||||
/* Each state is defined by a contiguous set of rows of the
|
/* Each state is defined by a contiguous set of rows of the
|
||||||
* state table marked by a common value for '.state'. The
|
* state table marked by a common value for '.state'. The
|
||||||
* state numbers must be equal to the index of the first row
|
* state numbers must be equal to the index of the first row
|
||||||
* in a given state; thus the loop condition here looks for a
|
* in a given state; thus the loop condition here looks for a
|
||||||
|
@ -198,9 +199,9 @@ filter_filter (GMimeFilter *gmime_filter, char *inbuf, size_t inlen, size_t pres
|
||||||
* in the underlying DFA.
|
* in the underlying DFA.
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
if (*inptr >= states[next].a && *inptr <= states[next].b) {
|
if (*inptr >= states[next].a && *inptr <= states[next].b) {
|
||||||
next = states[next].next_if_match;
|
next = states[next].next_if_match;
|
||||||
} else {
|
} else {
|
||||||
next = states[next].next_if_not_match;
|
next = states[next].next_if_not_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +246,7 @@ notmuch_filter_discard_non_term_new (GMimeContentType *content_type)
|
||||||
static GType type = 0;
|
static GType type = 0;
|
||||||
NotmuchFilterDiscardNonTerm *filter;
|
NotmuchFilterDiscardNonTerm *filter;
|
||||||
|
|
||||||
if (!type) {
|
if (! type) {
|
||||||
static const GTypeInfo info = {
|
static const GTypeInfo info = {
|
||||||
.class_size = sizeof (NotmuchFilterDiscardNonTermClass),
|
.class_size = sizeof (NotmuchFilterDiscardNonTermClass),
|
||||||
.base_init = NULL,
|
.base_init = NULL,
|
||||||
|
@ -266,11 +267,11 @@ notmuch_filter_discard_non_term_new (GMimeContentType *content_type)
|
||||||
filter->content_type = content_type;
|
filter->content_type = content_type;
|
||||||
filter->state = 0;
|
filter->state = 0;
|
||||||
if (g_mime_content_type_is_type (content_type, "text", "html")) {
|
if (g_mime_content_type_is_type (content_type, "text", "html")) {
|
||||||
filter->states = html_states;
|
filter->states = html_states;
|
||||||
filter->first_skipping_state = first_html_skipping_state;
|
filter->first_skipping_state = first_html_skipping_state;
|
||||||
} else {
|
} else {
|
||||||
filter->states = uuencode_states;
|
filter->states = uuencode_states;
|
||||||
filter->first_skipping_state = first_uuencode_skipping_state;
|
filter->first_skipping_state = first_uuencode_skipping_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (GMimeFilter *) filter;
|
return (GMimeFilter *) filter;
|
||||||
|
@ -356,6 +357,7 @@ static void
|
||||||
_index_content_type (notmuch_message_t *message, GMimeObject *part)
|
_index_content_type (notmuch_message_t *message, GMimeObject *part)
|
||||||
{
|
{
|
||||||
GMimeContentType *content_type = g_mime_object_get_content_type (part);
|
GMimeContentType *content_type = g_mime_object_get_content_type (part);
|
||||||
|
|
||||||
if (content_type) {
|
if (content_type) {
|
||||||
char *mime_string = g_mime_content_type_get_mime_type (content_type);
|
char *mime_string = g_mime_content_type_get_mime_type (content_type);
|
||||||
if (mime_string) {
|
if (mime_string) {
|
||||||
|
@ -388,7 +390,7 @@ _index_mime_part (notmuch_message_t *message,
|
||||||
|
|
||||||
if (! part) {
|
if (! part) {
|
||||||
_notmuch_database_log (notmuch_message_get_database (message),
|
_notmuch_database_log (notmuch_message_get_database (message),
|
||||||
"Warning: Not indexing empty mime part.\n");
|
"Warning: Not indexing empty mime part.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,10 +401,10 @@ _index_mime_part (notmuch_message_t *message,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (GMIME_IS_MULTIPART_SIGNED (multipart))
|
if (GMIME_IS_MULTIPART_SIGNED (multipart))
|
||||||
_notmuch_message_add_term (message, "tag", "signed");
|
_notmuch_message_add_term (message, "tag", "signed");
|
||||||
|
|
||||||
if (GMIME_IS_MULTIPART_ENCRYPTED (multipart))
|
if (GMIME_IS_MULTIPART_ENCRYPTED (multipart))
|
||||||
_notmuch_message_add_term (message, "tag", "encrypted");
|
_notmuch_message_add_term (message, "tag", "encrypted");
|
||||||
|
|
||||||
for (i = 0; i < g_mime_multipart_get_count (multipart); i++) {
|
for (i = 0; i < g_mime_multipart_get_count (multipart); i++) {
|
||||||
notmuch_status_t status;
|
notmuch_status_t status;
|
||||||
|
@ -422,9 +424,9 @@ _index_mime_part (notmuch_message_t *message,
|
||||||
_index_content_type (message,
|
_index_content_type (message,
|
||||||
g_mime_multipart_get_part (multipart, i));
|
g_mime_multipart_get_part (multipart, i));
|
||||||
if (i == GMIME_MULTIPART_ENCRYPTED_CONTENT) {
|
if (i == GMIME_MULTIPART_ENCRYPTED_CONTENT) {
|
||||||
_index_encrypted_mime_part(message, indexopts,
|
_index_encrypted_mime_part (message, indexopts,
|
||||||
GMIME_MULTIPART_ENCRYPTED (part),
|
GMIME_MULTIPART_ENCRYPTED (part),
|
||||||
msg_crypto);
|
msg_crypto);
|
||||||
} else {
|
} else {
|
||||||
if (i != GMIME_MULTIPART_ENCRYPTED_VERSION) {
|
if (i != GMIME_MULTIPART_ENCRYPTED_VERSION) {
|
||||||
_notmuch_database_log (notmuch_message_get_database (message),
|
_notmuch_database_log (notmuch_message_get_database (message),
|
||||||
|
@ -456,16 +458,15 @@ _index_mime_part (notmuch_message_t *message,
|
||||||
|
|
||||||
if (! (GMIME_IS_PART (part))) {
|
if (! (GMIME_IS_PART (part))) {
|
||||||
_notmuch_database_log (notmuch_message_get_database (message),
|
_notmuch_database_log (notmuch_message_get_database (message),
|
||||||
"Warning: Not indexing unknown mime part: %s.\n",
|
"Warning: Not indexing unknown mime part: %s.\n",
|
||||||
g_type_name (G_OBJECT_TYPE (part)));
|
g_type_name (G_OBJECT_TYPE (part)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
disposition = g_mime_object_get_content_disposition (part);
|
disposition = g_mime_object_get_content_disposition (part);
|
||||||
if (disposition &&
|
if (disposition &&
|
||||||
strcasecmp (g_mime_content_disposition_get_disposition (disposition),
|
strcasecmp (g_mime_content_disposition_get_disposition (disposition),
|
||||||
GMIME_DISPOSITION_ATTACHMENT) == 0)
|
GMIME_DISPOSITION_ATTACHMENT) == 0) {
|
||||||
{
|
|
||||||
const char *filename = g_mime_part_get_filename (GMIME_PART (part));
|
const char *filename = g_mime_part_get_filename (GMIME_PART (part));
|
||||||
|
|
||||||
_notmuch_message_add_term (message, "tag", "attachment");
|
_notmuch_message_add_term (message, "tag", "attachment");
|
||||||
|
@ -531,10 +532,10 @@ _index_encrypted_mime_part (notmuch_message_t *message,
|
||||||
{
|
{
|
||||||
notmuch_status_t status;
|
notmuch_status_t status;
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
notmuch_database_t * notmuch = NULL;
|
notmuch_database_t *notmuch = NULL;
|
||||||
GMimeObject *clear = NULL;
|
GMimeObject *clear = NULL;
|
||||||
|
|
||||||
if (!indexopts || (notmuch_indexopts_get_decrypt_policy (indexopts) == NOTMUCH_DECRYPT_FALSE))
|
if (! indexopts || (notmuch_indexopts_get_decrypt_policy (indexopts) == NOTMUCH_DECRYPT_FALSE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
notmuch = notmuch_message_get_database (message);
|
notmuch = notmuch_message_get_database (message);
|
||||||
|
@ -544,15 +545,15 @@ _index_encrypted_mime_part (notmuch_message_t *message,
|
||||||
bool get_sk = (notmuch_indexopts_get_decrypt_policy (indexopts) == NOTMUCH_DECRYPT_TRUE);
|
bool get_sk = (notmuch_indexopts_get_decrypt_policy (indexopts) == NOTMUCH_DECRYPT_TRUE);
|
||||||
clear = _notmuch_crypto_decrypt (&attempted, notmuch_indexopts_get_decrypt_policy (indexopts),
|
clear = _notmuch_crypto_decrypt (&attempted, notmuch_indexopts_get_decrypt_policy (indexopts),
|
||||||
message, encrypted_data, get_sk ? &decrypt_result : NULL, &err);
|
message, encrypted_data, get_sk ? &decrypt_result : NULL, &err);
|
||||||
if (!attempted)
|
if (! attempted)
|
||||||
return;
|
return;
|
||||||
if (err || !clear) {
|
if (err || ! clear) {
|
||||||
if (decrypt_result)
|
if (decrypt_result)
|
||||||
g_object_unref (decrypt_result);
|
g_object_unref (decrypt_result);
|
||||||
if (err) {
|
if (err) {
|
||||||
_notmuch_database_log (notmuch, "Failed to decrypt during indexing. (%d:%d) [%s]\n",
|
_notmuch_database_log (notmuch, "Failed to decrypt during indexing. (%d:%d) [%s]\n",
|
||||||
err->domain, err->code, err->message);
|
err->domain, err->code, err->message);
|
||||||
g_error_free(err);
|
g_error_free (err);
|
||||||
} else {
|
} else {
|
||||||
_notmuch_database_log (notmuch, "Failed to decrypt during indexing. (unknown error)\n");
|
_notmuch_database_log (notmuch, "Failed to decrypt during indexing. (unknown error)\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,25 +24,26 @@ notmuch_indexopts_t *
|
||||||
notmuch_database_get_default_indexopts (notmuch_database_t *db)
|
notmuch_database_get_default_indexopts (notmuch_database_t *db)
|
||||||
{
|
{
|
||||||
notmuch_indexopts_t *ret = talloc_zero (db, notmuch_indexopts_t);
|
notmuch_indexopts_t *ret = talloc_zero (db, notmuch_indexopts_t);
|
||||||
if (!ret)
|
|
||||||
|
if (! ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret->crypto.decrypt = NOTMUCH_DECRYPT_AUTO;
|
ret->crypto.decrypt = NOTMUCH_DECRYPT_AUTO;
|
||||||
|
|
||||||
char * decrypt_policy;
|
char *decrypt_policy;
|
||||||
notmuch_status_t err = notmuch_database_get_config (db, "index.decrypt", &decrypt_policy);
|
notmuch_status_t err = notmuch_database_get_config (db, "index.decrypt", &decrypt_policy);
|
||||||
if (err)
|
if (err)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (decrypt_policy) {
|
if (decrypt_policy) {
|
||||||
if ((!(strcasecmp(decrypt_policy, "true"))) ||
|
if ((! (strcasecmp (decrypt_policy, "true"))) ||
|
||||||
(!(strcasecmp(decrypt_policy, "yes"))) ||
|
(! (strcasecmp (decrypt_policy, "yes"))) ||
|
||||||
(!(strcasecmp(decrypt_policy, "1"))))
|
(! (strcasecmp (decrypt_policy, "1"))))
|
||||||
notmuch_indexopts_set_decrypt_policy (ret, NOTMUCH_DECRYPT_TRUE);
|
notmuch_indexopts_set_decrypt_policy (ret, NOTMUCH_DECRYPT_TRUE);
|
||||||
else if ((!(strcasecmp(decrypt_policy, "false"))) ||
|
else if ((! (strcasecmp (decrypt_policy, "false"))) ||
|
||||||
(!(strcasecmp(decrypt_policy, "no"))) ||
|
(! (strcasecmp (decrypt_policy, "no"))) ||
|
||||||
(!(strcasecmp(decrypt_policy, "0"))))
|
(! (strcasecmp (decrypt_policy, "0"))))
|
||||||
notmuch_indexopts_set_decrypt_policy (ret, NOTMUCH_DECRYPT_FALSE);
|
notmuch_indexopts_set_decrypt_policy (ret, NOTMUCH_DECRYPT_FALSE);
|
||||||
else if (!strcasecmp(decrypt_policy, "nostash"))
|
else if (! strcasecmp (decrypt_policy, "nostash"))
|
||||||
notmuch_indexopts_set_decrypt_policy (ret, NOTMUCH_DECRYPT_NOSTASH);
|
notmuch_indexopts_set_decrypt_policy (ret, NOTMUCH_DECRYPT_NOSTASH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ notmuch_status_t
|
||||||
notmuch_indexopts_set_decrypt_policy (notmuch_indexopts_t *indexopts,
|
notmuch_indexopts_set_decrypt_policy (notmuch_indexopts_t *indexopts,
|
||||||
notmuch_decryption_policy_t decrypt_policy)
|
notmuch_decryption_policy_t decrypt_policy)
|
||||||
{
|
{
|
||||||
if (!indexopts)
|
if (! indexopts)
|
||||||
return NOTMUCH_STATUS_NULL_POINTER;
|
return NOTMUCH_STATUS_NULL_POINTER;
|
||||||
indexopts->crypto.decrypt = decrypt_policy;
|
indexopts->crypto.decrypt = decrypt_policy;
|
||||||
return NOTMUCH_STATUS_SUCCESS;
|
return NOTMUCH_STATUS_SUCCESS;
|
||||||
|
@ -63,7 +64,7 @@ notmuch_indexopts_set_decrypt_policy (notmuch_indexopts_t *indexopts,
|
||||||
notmuch_decryption_policy_t
|
notmuch_decryption_policy_t
|
||||||
notmuch_indexopts_get_decrypt_policy (const notmuch_indexopts_t *indexopts)
|
notmuch_indexopts_get_decrypt_policy (const notmuch_indexopts_t *indexopts)
|
||||||
{
|
{
|
||||||
if (!indexopts)
|
if (! indexopts)
|
||||||
return false;
|
return false;
|
||||||
return indexopts->crypto.decrypt;
|
return indexopts->crypto.decrypt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ _notmuch_message_file_open_ctx (notmuch_database_t *notmuch,
|
||||||
|
|
||||||
FAIL:
|
FAIL:
|
||||||
_notmuch_database_log (notmuch, "Error opening %s: %s\n",
|
_notmuch_database_log (notmuch, "Error opening %s: %s\n",
|
||||||
filename, strerror (errno));
|
filename, strerror (errno));
|
||||||
_notmuch_message_file_close (message);
|
_notmuch_message_file_close (message);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -110,7 +110,7 @@ _is_mbox (GMimeStream *stream)
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
/* Is this mbox? */
|
/* Is this mbox? */
|
||||||
if (g_mime_stream_read (stream, from_buf, sizeof (from_buf)) == sizeof(from_buf) &&
|
if (g_mime_stream_read (stream, from_buf, sizeof (from_buf)) == sizeof (from_buf) &&
|
||||||
strncmp (from_buf, "From ", 5) == 0)
|
strncmp (from_buf, "From ", 5) == 0)
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
|
@ -201,7 +201,8 @@ _notmuch_message_file_get_mime_message (notmuch_message_file_t *message,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
_extend_header (char *combined, const char *value) {
|
_extend_header (char *combined, const char *value)
|
||||||
|
{
|
||||||
char *decoded;
|
char *decoded;
|
||||||
|
|
||||||
decoded = g_mime_utils_header_decode_text (NULL, value);
|
decoded = g_mime_utils_header_decode_text (NULL, value);
|
||||||
|
@ -226,7 +227,7 @@ _extend_header (char *combined, const char *value) {
|
||||||
} else {
|
} else {
|
||||||
combined = decoded;
|
combined = decoded;
|
||||||
}
|
}
|
||||||
DONE:
|
DONE:
|
||||||
return combined;
|
return combined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +243,7 @@ _notmuch_message_file_get_combined_header (notmuch_message_file_t *message,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
||||||
for (int i=0; i < g_mime_header_list_get_count (headers); i++) {
|
for (int i = 0; i < g_mime_header_list_get_count (headers); i++) {
|
||||||
const char *value;
|
const char *value;
|
||||||
GMimeHeader *g_header = g_mime_header_list_get_header_at (headers, i);
|
GMimeHeader *g_header = g_mime_header_list_get_header_at (headers, i);
|
||||||
|
|
||||||
|
@ -264,7 +265,7 @@ _notmuch_message_file_get_combined_header (notmuch_message_file_t *message,
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
_notmuch_message_file_get_header (notmuch_message_file_t *message,
|
_notmuch_message_file_get_header (notmuch_message_file_t *message,
|
||||||
const char *header)
|
const char *header)
|
||||||
{
|
{
|
||||||
const char *value;
|
const char *value;
|
||||||
char *decoded;
|
char *decoded;
|
||||||
|
@ -366,7 +367,7 @@ _notmuch_message_file_get_headers (notmuch_message_file_t *message_file,
|
||||||
message_id = talloc_asprintf (message_file, "notmuch-sha1-%s", sha1);
|
message_id = talloc_asprintf (message_file, "notmuch-sha1-%s", sha1);
|
||||||
free (sha1);
|
free (sha1);
|
||||||
}
|
}
|
||||||
DONE:
|
DONE:
|
||||||
if (ret == NOTMUCH_STATUS_SUCCESS) {
|
if (ret == NOTMUCH_STATUS_SUCCESS) {
|
||||||
if (from_out)
|
if (from_out)
|
||||||
*from_out = from;
|
*from_out = from;
|
||||||
|
|
|
@ -27,7 +27,7 @@ skip_space_and_comments (const char **str)
|
||||||
} else if (*s == ')') {
|
} else if (*s == ')') {
|
||||||
nesting--;
|
nesting--;
|
||||||
} else if (*s == '\\') {
|
} else if (*s == '\\') {
|
||||||
if (*(s+1))
|
if (*(s + 1))
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
s++;
|
s++;
|
||||||
|
@ -90,7 +90,7 @@ _notmuch_message_id_parse (void *ctx, const char *message_id, const char **next)
|
||||||
|
|
||||||
for (r = result, len = strlen (r); *r; r++, len--)
|
for (r = result, len = strlen (r); *r; r++, len--)
|
||||||
if (*r == ' ' || *r == '\t')
|
if (*r == ' ' || *r == '\t')
|
||||||
memmove (r, r+1, len);
|
memmove (r, r + 1, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -115,7 +115,7 @@ notmuch_status_t
|
||||||
_notmuch_message_remove_all_properties (notmuch_message_t *message, const char *key, bool prefix)
|
_notmuch_message_remove_all_properties (notmuch_message_t *message, const char *key, bool prefix)
|
||||||
{
|
{
|
||||||
notmuch_status_t status;
|
notmuch_status_t status;
|
||||||
const char * term_prefix;
|
const char *term_prefix;
|
||||||
|
|
||||||
status = _notmuch_database_ensure_writable (notmuch_message_get_database (message));
|
status = _notmuch_database_ensure_writable (notmuch_message_get_database (message));
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -150,6 +150,7 @@ notmuch_message_properties_t *
|
||||||
notmuch_message_get_properties (notmuch_message_t *message, const char *key, notmuch_bool_t exact)
|
notmuch_message_get_properties (notmuch_message_t *message, const char *key, notmuch_bool_t exact)
|
||||||
{
|
{
|
||||||
notmuch_string_map_t *map;
|
notmuch_string_map_t *map;
|
||||||
|
|
||||||
map = _notmuch_message_property_map (message);
|
map = _notmuch_message_property_map (message);
|
||||||
return _notmuch_string_map_iterator_create (map, key, exact);
|
return _notmuch_string_map_iterator_create (map, key, exact);
|
||||||
}
|
}
|
||||||
|
|
153
lib/message.cc
153
lib/message.cc
|
@ -69,10 +69,10 @@ struct maildir_flag_tag {
|
||||||
|
|
||||||
/* ASCII ordered table of Maildir flags and associated tags */
|
/* ASCII ordered table of Maildir flags and associated tags */
|
||||||
static struct maildir_flag_tag flag2tag[] = {
|
static struct maildir_flag_tag flag2tag[] = {
|
||||||
{ 'D', "draft", false},
|
{ 'D', "draft", false },
|
||||||
{ 'F', "flagged", false},
|
{ 'F', "flagged", false },
|
||||||
{ 'P', "passed", false},
|
{ 'P', "passed", false },
|
||||||
{ 'R', "replied", false},
|
{ 'R', "replied", false },
|
||||||
{ 'S', "unread", true }
|
{ 'S', "unread", true }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -274,8 +274,8 @@ _notmuch_message_create_for_message_id (notmuch_database_t *notmuch,
|
||||||
|
|
||||||
doc_id = _notmuch_database_generate_doc_id (notmuch);
|
doc_id = _notmuch_database_generate_doc_id (notmuch);
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log(notmuch_message_get_database (message), "A Xapian exception occurred creating message: %s\n",
|
_notmuch_database_log (notmuch_message_get_database (message), "A Xapian exception occurred creating message: %s\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
*status_ret = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
|
*status_ret = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -306,10 +306,10 @@ _notmuch_message_get_term (notmuch_message_t *message,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const std::string &term = *i;
|
const std::string &term = *i;
|
||||||
if (strncmp (term.c_str(), prefix, prefix_len))
|
if (strncmp (term.c_str (), prefix, prefix_len))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
value = talloc_strdup (message, term.c_str() + prefix_len);
|
value = talloc_strdup (message, term.c_str () + prefix_len);
|
||||||
|
|
||||||
#if DEBUG_DATABASE_SANITY
|
#if DEBUG_DATABASE_SANITY
|
||||||
i++;
|
i++;
|
||||||
|
@ -350,32 +350,32 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message, void *field)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const char *thread_prefix = _find_prefix ("thread"),
|
const char *thread_prefix = _find_prefix ("thread"),
|
||||||
*tag_prefix = _find_prefix ("tag"),
|
*tag_prefix = _find_prefix ("tag"),
|
||||||
*id_prefix = _find_prefix ("id"),
|
*id_prefix = _find_prefix ("id"),
|
||||||
*type_prefix = _find_prefix ("type"),
|
*type_prefix = _find_prefix ("type"),
|
||||||
*filename_prefix = _find_prefix ("file-direntry"),
|
*filename_prefix = _find_prefix ("file-direntry"),
|
||||||
*property_prefix = _find_prefix ("property"),
|
*property_prefix = _find_prefix ("property"),
|
||||||
*reference_prefix = _find_prefix ("reference"),
|
*reference_prefix = _find_prefix ("reference"),
|
||||||
*replyto_prefix = _find_prefix ("replyto");
|
*replyto_prefix = _find_prefix ("replyto");
|
||||||
|
|
||||||
/* We do this all in a single pass because Xapian decompresses the
|
/* We do this all in a single pass because Xapian decompresses the
|
||||||
* term list every time you iterate over it. Thus, while this is
|
* term list every time you iterate over it. Thus, while this is
|
||||||
* slightly more costly than looking up individual fields if only
|
* slightly more costly than looking up individual fields if only
|
||||||
* one field of the message object is actually used, it's a huge
|
* one field of the message object is actually used, it's a huge
|
||||||
* win as more fields are used. */
|
* win as more fields are used. */
|
||||||
for (int count=0; count < 3; count++) {
|
for (int count = 0; count < 3; count++) {
|
||||||
try {
|
try {
|
||||||
i = message->doc.termlist_begin ();
|
i = message->doc.termlist_begin ();
|
||||||
end = message->doc.termlist_end ();
|
end = message->doc.termlist_end ();
|
||||||
|
|
||||||
/* Get thread */
|
/* Get thread */
|
||||||
if (!message->thread_id)
|
if (! message->thread_id)
|
||||||
message->thread_id =
|
message->thread_id =
|
||||||
_notmuch_message_get_term (message, i, end, thread_prefix);
|
_notmuch_message_get_term (message, i, end, thread_prefix);
|
||||||
|
|
||||||
/* Get tags */
|
/* Get tags */
|
||||||
assert (strcmp (thread_prefix, tag_prefix) < 0);
|
assert (strcmp (thread_prefix, tag_prefix) < 0);
|
||||||
if (!message->tag_list) {
|
if (! message->tag_list) {
|
||||||
message->tag_list =
|
message->tag_list =
|
||||||
_notmuch_database_get_terms_with_prefix (message, i, end,
|
_notmuch_database_get_terms_with_prefix (message, i, end,
|
||||||
tag_prefix);
|
tag_prefix);
|
||||||
|
@ -384,7 +384,7 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message, void *field)
|
||||||
|
|
||||||
/* Get id */
|
/* Get id */
|
||||||
assert (strcmp (tag_prefix, id_prefix) < 0);
|
assert (strcmp (tag_prefix, id_prefix) < 0);
|
||||||
if (!message->message_id)
|
if (! message->message_id)
|
||||||
message->message_id =
|
message->message_id =
|
||||||
_notmuch_message_get_term (message, i, end, id_prefix);
|
_notmuch_message_get_term (message, i, end, id_prefix);
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message, void *field)
|
||||||
* expand them to full file names when needed in
|
* expand them to full file names when needed in
|
||||||
* _notmuch_message_ensure_filename_list. */
|
* _notmuch_message_ensure_filename_list. */
|
||||||
assert (strcmp (type_prefix, filename_prefix) < 0);
|
assert (strcmp (type_prefix, filename_prefix) < 0);
|
||||||
if (!message->filename_term_list && !message->filename_list)
|
if (! message->filename_term_list && ! message->filename_list)
|
||||||
message->filename_term_list =
|
message->filename_term_list =
|
||||||
_notmuch_database_get_terms_with_prefix (message, i, end,
|
_notmuch_database_get_terms_with_prefix (message, i, end,
|
||||||
filename_prefix);
|
filename_prefix);
|
||||||
|
@ -415,14 +415,14 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message, void *field)
|
||||||
|
|
||||||
/* Get property terms. Mimic the setup with filenames above */
|
/* Get property terms. Mimic the setup with filenames above */
|
||||||
assert (strcmp (filename_prefix, property_prefix) < 0);
|
assert (strcmp (filename_prefix, property_prefix) < 0);
|
||||||
if (!message->property_map && !message->property_term_list)
|
if (! message->property_map && ! message->property_term_list)
|
||||||
message->property_term_list =
|
message->property_term_list =
|
||||||
_notmuch_database_get_terms_with_prefix (message, i, end,
|
_notmuch_database_get_terms_with_prefix (message, i, end,
|
||||||
property_prefix);
|
property_prefix);
|
||||||
|
|
||||||
/* get references */
|
/* get references */
|
||||||
assert (strcmp (property_prefix, reference_prefix) < 0);
|
assert (strcmp (property_prefix, reference_prefix) < 0);
|
||||||
if (!message->reference_list) {
|
if (! message->reference_list) {
|
||||||
message->reference_list =
|
message->reference_list =
|
||||||
_notmuch_database_get_terms_with_prefix (message, i, end,
|
_notmuch_database_get_terms_with_prefix (message, i, end,
|
||||||
reference_prefix);
|
reference_prefix);
|
||||||
|
@ -430,14 +430,14 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message, void *field)
|
||||||
|
|
||||||
/* Get reply to */
|
/* Get reply to */
|
||||||
assert (strcmp (property_prefix, replyto_prefix) < 0);
|
assert (strcmp (property_prefix, replyto_prefix) < 0);
|
||||||
if (!message->in_reply_to)
|
if (! message->in_reply_to)
|
||||||
message->in_reply_to =
|
message->in_reply_to =
|
||||||
_notmuch_message_get_term (message, i, end, replyto_prefix);
|
_notmuch_message_get_term (message, i, end, replyto_prefix);
|
||||||
|
|
||||||
|
|
||||||
/* It's perfectly valid for a message to have no In-Reply-To
|
/* It's perfectly valid for a message to have no In-Reply-To
|
||||||
* header. For these cases, we return an empty string. */
|
* header. For these cases, we return an empty string. */
|
||||||
if (!message->in_reply_to)
|
if (! message->in_reply_to)
|
||||||
message->in_reply_to = talloc_strdup (message, "");
|
message->in_reply_to = talloc_strdup (message, "");
|
||||||
|
|
||||||
/* all the way without an exception */
|
/* all the way without an exception */
|
||||||
|
@ -449,7 +449,7 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message, void *field)
|
||||||
notmuch_status_to_string (status));
|
notmuch_status_to_string (status));
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
INTERNAL_ERROR ("A Xapian exception occurred fetching message metadata: %s\n",
|
INTERNAL_ERROR ("A Xapian exception occurred fetching message metadata: %s\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
message->last_view = message->notmuch->view;
|
message->last_view = message->notmuch->view;
|
||||||
|
@ -508,7 +508,7 @@ const char *
|
||||||
notmuch_message_get_message_id (notmuch_message_t *message)
|
notmuch_message_get_message_id (notmuch_message_t *message)
|
||||||
{
|
{
|
||||||
_notmuch_message_ensure_metadata (message, message->message_id);
|
_notmuch_message_ensure_metadata (message, message->message_id);
|
||||||
if (!message->message_id)
|
if (! message->message_id)
|
||||||
INTERNAL_ERROR ("Message with document ID of %u has no message ID.\n",
|
INTERNAL_ERROR ("Message with document ID of %u has no message ID.\n",
|
||||||
message->doc_id);
|
message->doc_id);
|
||||||
return message->message_id;
|
return message->message_id;
|
||||||
|
@ -553,12 +553,12 @@ notmuch_message_get_header (notmuch_message_t *message, const char *header)
|
||||||
* it could just mean we didn't record the header. */
|
* it could just mean we didn't record the header. */
|
||||||
if ((message->notmuch->features &
|
if ((message->notmuch->features &
|
||||||
NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES) ||
|
NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES) ||
|
||||||
! value.empty())
|
! value.empty ())
|
||||||
return talloc_strdup (message, value.c_str ());
|
return talloc_strdup (message, value.c_str ());
|
||||||
|
|
||||||
} catch (Xapian::Error &error) {
|
} catch (Xapian::Error &error) {
|
||||||
_notmuch_database_log(notmuch_message_get_database (message), "A Xapian exception occurred when reading header: %s\n",
|
_notmuch_database_log (notmuch_message_get_database (message), "A Xapian exception occurred when reading header: %s\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
message->notmuch->exception_reported = true;
|
message->notmuch->exception_reported = true;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -590,7 +590,7 @@ const char *
|
||||||
notmuch_message_get_thread_id (notmuch_message_t *message)
|
notmuch_message_get_thread_id (notmuch_message_t *message)
|
||||||
{
|
{
|
||||||
_notmuch_message_ensure_metadata (message, message->thread_id);
|
_notmuch_message_ensure_metadata (message, message->thread_id);
|
||||||
if (!message->thread_id)
|
if (! message->thread_id)
|
||||||
INTERNAL_ERROR ("Message with document ID of %u has no thread ID.\n",
|
INTERNAL_ERROR ("Message with document ID of %u has no thread ID.\n",
|
||||||
message->doc_id);
|
message->doc_id);
|
||||||
return message->thread_id;
|
return message->thread_id;
|
||||||
|
@ -604,7 +604,8 @@ _notmuch_message_add_reply (notmuch_message_t *message,
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
_notmuch_message_get_thread_depth (notmuch_message_t *message) {
|
_notmuch_message_get_thread_depth (notmuch_message_t *message)
|
||||||
|
{
|
||||||
return message->thread_depth;
|
return message->thread_depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,7 +619,7 @@ _notmuch_message_label_depths (notmuch_message_t *message,
|
||||||
notmuch_messages_valid (messages);
|
notmuch_messages_valid (messages);
|
||||||
notmuch_messages_move_to_next (messages)) {
|
notmuch_messages_move_to_next (messages)) {
|
||||||
notmuch_message_t *child = notmuch_messages_get (messages);
|
notmuch_message_t *child = notmuch_messages_get (messages);
|
||||||
_notmuch_message_label_depths (child, depth+1);
|
_notmuch_message_label_depths (child, depth + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,7 +731,7 @@ _notmuch_message_remove_indexed_terms (notmuch_message_t *message)
|
||||||
type_prefix = _find_prefix ("type");
|
type_prefix = _find_prefix ("type");
|
||||||
|
|
||||||
/* Make sure we have the data to restore to Xapian*/
|
/* Make sure we have the data to restore to Xapian*/
|
||||||
_notmuch_message_ensure_metadata (message,NULL);
|
_notmuch_message_ensure_metadata (message, NULL);
|
||||||
|
|
||||||
/* Empirically, it turns out to be faster to remove all the terms,
|
/* Empirically, it turns out to be faster to remove all the terms,
|
||||||
* and add back the ones we want. */
|
* and add back the ones we want. */
|
||||||
|
@ -754,7 +755,7 @@ _notmuch_message_remove_indexed_terms (notmuch_message_t *message)
|
||||||
STRNCMP_LITERAL (tag, "signed") != 0 &&
|
STRNCMP_LITERAL (tag, "signed") != 0 &&
|
||||||
STRNCMP_LITERAL (tag, "attachment") != 0) {
|
STRNCMP_LITERAL (tag, "attachment") != 0) {
|
||||||
std::string term = tag_prefix + tag;
|
std::string term = tag_prefix + tag;
|
||||||
message->doc.add_term(term);
|
message->doc.add_term (term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,10 +765,10 @@ _notmuch_message_remove_indexed_terms (notmuch_message_t *message)
|
||||||
for (list = notmuch_message_get_properties (message, "", false);
|
for (list = notmuch_message_get_properties (message, "", false);
|
||||||
notmuch_message_properties_valid (list); notmuch_message_properties_move_to_next (list)) {
|
notmuch_message_properties_valid (list); notmuch_message_properties_move_to_next (list)) {
|
||||||
std::string term = property_prefix +
|
std::string term = property_prefix +
|
||||||
notmuch_message_properties_key(list) + "=" +
|
notmuch_message_properties_key (list) + "=" +
|
||||||
notmuch_message_properties_value(list);
|
notmuch_message_properties_value (list);
|
||||||
|
|
||||||
message->doc.add_term(term);
|
message->doc.add_term (term);
|
||||||
}
|
}
|
||||||
|
|
||||||
notmuch_message_properties_destroy (list);
|
notmuch_message_properties_destroy (list);
|
||||||
|
@ -777,7 +778,8 @@ _notmuch_message_remove_indexed_terms (notmuch_message_t *message)
|
||||||
|
|
||||||
|
|
||||||
/* Return true if p points at "new" or "cur". */
|
/* Return true if p points at "new" or "cur". */
|
||||||
static bool is_maildir (const char *p)
|
static bool
|
||||||
|
is_maildir (const char *p)
|
||||||
{
|
{
|
||||||
return strcmp (p, "cur") == 0 || strcmp (p, "new") == 0;
|
return strcmp (p, "cur") == 0 || strcmp (p, "new") == 0;
|
||||||
}
|
}
|
||||||
|
@ -972,7 +974,7 @@ _notmuch_message_remove_filename (notmuch_message_t *message,
|
||||||
|
|
||||||
status = _notmuch_database_filename_to_direntry (
|
status = _notmuch_database_filename_to_direntry (
|
||||||
local, message->notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry);
|
local, message->notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry);
|
||||||
if (status || !direntry)
|
if (status || ! direntry)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
/* Unlink this file from its parent directory. */
|
/* Unlink this file from its parent directory. */
|
||||||
|
@ -1041,7 +1043,7 @@ _notmuch_message_ensure_filename_list (notmuch_message_t *message)
|
||||||
message->filename_list = _notmuch_string_list_create (message);
|
message->filename_list = _notmuch_string_list_create (message);
|
||||||
node = message->filename_term_list->head;
|
node = message->filename_term_list->head;
|
||||||
|
|
||||||
if (!node) {
|
if (! node) {
|
||||||
/* A message document created by an old version of notmuch
|
/* A message document created by an old version of notmuch
|
||||||
* (prior to rename support) will have the filename in the
|
* (prior to rename support) will have the filename in the
|
||||||
* data of the document rather than as a file-direntry term.
|
* data of the document rather than as a file-direntry term.
|
||||||
|
@ -1108,8 +1110,7 @@ notmuch_message_get_filename (notmuch_message_t *message)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (message->filename_list->head == NULL ||
|
if (message->filename_list->head == NULL ||
|
||||||
message->filename_list->head->string == NULL)
|
message->filename_list->head->string == NULL) {
|
||||||
{
|
|
||||||
INTERNAL_ERROR ("message with no filename");
|
INTERNAL_ERROR ("message with no filename");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1162,8 +1163,8 @@ notmuch_message_get_date (notmuch_message_t *message)
|
||||||
try {
|
try {
|
||||||
value = message->doc.get_value (NOTMUCH_VALUE_TIMESTAMP);
|
value = message->doc.get_value (NOTMUCH_VALUE_TIMESTAMP);
|
||||||
} catch (Xapian::Error &error) {
|
} catch (Xapian::Error &error) {
|
||||||
_notmuch_database_log(notmuch_message_get_database (message), "A Xapian exception occurred when reading date: %s\n",
|
_notmuch_database_log (notmuch_message_get_database (message), "A Xapian exception occurred when reading date: %s\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
message->notmuch->exception_reported = true;
|
message->notmuch->exception_reported = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1188,7 +1189,7 @@ notmuch_message_get_tags (notmuch_message_t *message)
|
||||||
* possible to modify the message tags (which talloc_unlink's the
|
* possible to modify the message tags (which talloc_unlink's the
|
||||||
* current list from the message) while still iterating because
|
* current list from the message) while still iterating because
|
||||||
* the iterator will keep the current list alive. */
|
* the iterator will keep the current list alive. */
|
||||||
if (!talloc_reference (message, message->tag_list))
|
if (! talloc_reference (message, message->tag_list))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return tags;
|
return tags;
|
||||||
|
@ -1202,11 +1203,11 @@ _notmuch_message_get_author (notmuch_message_t *message)
|
||||||
|
|
||||||
void
|
void
|
||||||
_notmuch_message_set_author (notmuch_message_t *message,
|
_notmuch_message_set_author (notmuch_message_t *message,
|
||||||
const char *author)
|
const char *author)
|
||||||
{
|
{
|
||||||
if (message->author)
|
if (message->author)
|
||||||
talloc_free(message->author);
|
talloc_free (message->author);
|
||||||
message->author = talloc_strdup(message, author);
|
message->author = talloc_strdup (message, author);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1339,8 +1340,8 @@ _notmuch_message_delete (notmuch_message_t *message)
|
||||||
_notmuch_message_sync (ghost);
|
_notmuch_message_sync (ghost);
|
||||||
} else if (private_status == NOTMUCH_PRIVATE_STATUS_SUCCESS) {
|
} else if (private_status == NOTMUCH_PRIVATE_STATUS_SUCCESS) {
|
||||||
/* this is deeply weird, and we should not have gotten
|
/* this is deeply weird, and we should not have gotten
|
||||||
into this state. is there a better error message to
|
* into this state. is there a better error message to
|
||||||
return here? */
|
* return here? */
|
||||||
status = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
|
status = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1358,8 +1359,8 @@ _notmuch_message_delete (notmuch_message_t *message)
|
||||||
message = notmuch_messages_get (messages);
|
message = notmuch_messages_get (messages);
|
||||||
status = _notmuch_message_delete (message);
|
status = _notmuch_message_delete (message);
|
||||||
if (status) /* we'll report the last failure we see;
|
if (status) /* we'll report the last failure we see;
|
||||||
* if there is more than one failure, we
|
* if there is more than one failure, we
|
||||||
* forget about previous ones */
|
* forget about previous ones */
|
||||||
last_error = status;
|
last_error = status;
|
||||||
notmuch_message_destroy (message);
|
notmuch_message_destroy (message);
|
||||||
notmuch_messages_move_to_next (messages);
|
notmuch_messages_move_to_next (messages);
|
||||||
|
@ -1535,7 +1536,7 @@ _notmuch_message_has_term (notmuch_message_t *message,
|
||||||
Xapian::TermIterator i = message->doc.termlist_begin ();
|
Xapian::TermIterator i = message->doc.termlist_begin ();
|
||||||
i.skip_to (term);
|
i.skip_to (term);
|
||||||
if (i != message->doc.termlist_end () &&
|
if (i != message->doc.termlist_end () &&
|
||||||
!strcmp ((*i).c_str (), term))
|
! strcmp ((*i).c_str (), term))
|
||||||
out = true;
|
out = true;
|
||||||
} catch (Xapian::Error &error) {
|
} catch (Xapian::Error &error) {
|
||||||
status = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
|
status = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
|
||||||
|
@ -1635,8 +1636,7 @@ _filename_is_in_maildir (const char *filename)
|
||||||
dir = slash + 1;
|
dir = slash + 1;
|
||||||
|
|
||||||
if (STRNCMP_LITERAL (dir, "cur/") == 0 ||
|
if (STRNCMP_LITERAL (dir, "cur/") == 0 ||
|
||||||
STRNCMP_LITERAL (dir, "new/") == 0)
|
STRNCMP_LITERAL (dir, "new/") == 0) {
|
||||||
{
|
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1661,8 +1661,7 @@ _ensure_maildir_flags (notmuch_message_t *message, bool force)
|
||||||
|
|
||||||
for (filenames = notmuch_message_get_filenames (message);
|
for (filenames = notmuch_message_get_filenames (message);
|
||||||
notmuch_filenames_valid (filenames);
|
notmuch_filenames_valid (filenames);
|
||||||
notmuch_filenames_move_to_next (filenames))
|
notmuch_filenames_move_to_next (filenames)) {
|
||||||
{
|
|
||||||
filename = notmuch_filenames_get (filenames);
|
filename = notmuch_filenames_get (filenames);
|
||||||
dir = _filename_is_in_maildir (filename);
|
dir = _filename_is_in_maildir (filename);
|
||||||
|
|
||||||
|
@ -1712,11 +1711,10 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message)
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(flag2tag); i++) {
|
for (i = 0; i < ARRAY_SIZE (flag2tag); i++) {
|
||||||
if ((strchr (message->maildir_flags, flag2tag[i].flag) != NULL)
|
if ((strchr (message->maildir_flags, flag2tag[i].flag) != NULL)
|
||||||
^
|
^
|
||||||
flag2tag[i].inverse)
|
flag2tag[i].inverse) {
|
||||||
{
|
|
||||||
status = notmuch_message_add_tag (message, flag2tag[i].tag);
|
status = notmuch_message_add_tag (message, flag2tag[i].tag);
|
||||||
} else {
|
} else {
|
||||||
status = notmuch_message_remove_tag (message, flag2tag[i].tag);
|
status = notmuch_message_remove_tag (message, flag2tag[i].tag);
|
||||||
|
@ -1751,8 +1749,7 @@ _get_maildir_flag_actions (notmuch_message_t *message,
|
||||||
/* First, find flags for all set tags. */
|
/* First, find flags for all set tags. */
|
||||||
for (tags = notmuch_message_get_tags (message);
|
for (tags = notmuch_message_get_tags (message);
|
||||||
notmuch_tags_valid (tags);
|
notmuch_tags_valid (tags);
|
||||||
notmuch_tags_move_to_next (tags))
|
notmuch_tags_move_to_next (tags)) {
|
||||||
{
|
|
||||||
tag = notmuch_tags_get (tags);
|
tag = notmuch_tags_get (tags);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE (flag2tag); i++) {
|
for (i = 0; i < ARRAY_SIZE (flag2tag); i++) {
|
||||||
|
@ -1802,7 +1799,7 @@ _get_maildir_flag_actions (notmuch_message_t *message,
|
||||||
* non-ASCII ordering of flags), this function will return NULL
|
* non-ASCII ordering of flags), this function will return NULL
|
||||||
* (meaning that renaming would not be safe and should not occur).
|
* (meaning that renaming would not be safe and should not occur).
|
||||||
*/
|
*/
|
||||||
static char*
|
static char *
|
||||||
_new_maildir_filename (void *ctx,
|
_new_maildir_filename (void *ctx,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
const char *flags_to_set,
|
const char *flags_to_set,
|
||||||
|
@ -1822,13 +1819,12 @@ _new_maildir_filename (void *ctx,
|
||||||
info = strstr (filename, ":2,");
|
info = strstr (filename, ":2,");
|
||||||
|
|
||||||
if (info == NULL) {
|
if (info == NULL) {
|
||||||
info = filename + strlen(filename);
|
info = filename + strlen (filename);
|
||||||
} else {
|
} else {
|
||||||
/* Loop through existing flags in filename. */
|
/* Loop through existing flags in filename. */
|
||||||
for (flags = info + 3, last_flag = 0;
|
for (flags = info + 3, last_flag = 0;
|
||||||
*flags;
|
*flags;
|
||||||
last_flag = flag, flags++)
|
last_flag = flag, flags++) {
|
||||||
{
|
|
||||||
flag = *flags;
|
flag = *flags;
|
||||||
|
|
||||||
/* Original flags not in ASCII order. Abort. */
|
/* Original flags not in ASCII order. Abort. */
|
||||||
|
@ -1836,7 +1832,7 @@ _new_maildir_filename (void *ctx,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Non-ASCII flag. Abort. */
|
/* Non-ASCII flag. Abort. */
|
||||||
if (flag > sizeof(flag_map) - 1)
|
if (flag > sizeof (flag_map) - 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Repeated flag value. Abort. */
|
/* Repeated flag value. Abort. */
|
||||||
|
@ -1870,7 +1866,7 @@ _new_maildir_filename (void *ctx,
|
||||||
/* Messages in new/ without maildir info can be kept in new/ if no
|
/* Messages in new/ without maildir info can be kept in new/ if no
|
||||||
* flags have changed. */
|
* flags have changed. */
|
||||||
dir = (char *) _filename_is_in_maildir (filename);
|
dir = (char *) _filename_is_in_maildir (filename);
|
||||||
if (dir && STRNCMP_LITERAL (dir, "new/") == 0 && !*info && !flags_changed)
|
if (dir && STRNCMP_LITERAL (dir, "new/") == 0 && ! *info && ! flags_changed)
|
||||||
return talloc_strdup (ctx, filename);
|
return talloc_strdup (ctx, filename);
|
||||||
|
|
||||||
filename_new = (char *) talloc_size (ctx,
|
filename_new = (char *) talloc_size (ctx,
|
||||||
|
@ -1885,8 +1881,7 @@ _new_maildir_filename (void *ctx,
|
||||||
strcat (filename_new, ":2,");
|
strcat (filename_new, ":2,");
|
||||||
|
|
||||||
s = filename_new + strlen (filename_new);
|
s = filename_new + strlen (filename_new);
|
||||||
for (i = 0; i < sizeof (flag_map); i++)
|
for (i = 0; i < sizeof (flag_map); i++) {
|
||||||
{
|
|
||||||
if (flag_map[i]) {
|
if (flag_map[i]) {
|
||||||
*s = i;
|
*s = i;
|
||||||
s++;
|
s++;
|
||||||
|
@ -1915,8 +1910,7 @@ notmuch_message_tags_to_maildir_flags (notmuch_message_t *message)
|
||||||
|
|
||||||
for (filenames = notmuch_message_get_filenames (message);
|
for (filenames = notmuch_message_get_filenames (message);
|
||||||
notmuch_filenames_valid (filenames);
|
notmuch_filenames_valid (filenames);
|
||||||
notmuch_filenames_move_to_next (filenames))
|
notmuch_filenames_move_to_next (filenames)) {
|
||||||
{
|
|
||||||
filename = notmuch_filenames_get (filenames);
|
filename = notmuch_filenames_get (filenames);
|
||||||
|
|
||||||
if (! _filename_is_in_maildir (filename))
|
if (! _filename_is_in_maildir (filename))
|
||||||
|
@ -1978,8 +1972,7 @@ notmuch_message_remove_all_tags (notmuch_message_t *message)
|
||||||
|
|
||||||
for (tags = notmuch_message_get_tags (message);
|
for (tags = notmuch_message_get_tags (message);
|
||||||
notmuch_tags_valid (tags);
|
notmuch_tags_valid (tags);
|
||||||
notmuch_tags_move_to_next (tags))
|
notmuch_tags_move_to_next (tags)) {
|
||||||
{
|
|
||||||
tag = notmuch_tags_get (tags);
|
tag = notmuch_tags_get (tags);
|
||||||
|
|
||||||
private_status = _notmuch_message_remove_term (message, "tag", tag);
|
private_status = _notmuch_message_remove_term (message, "tag", tag);
|
||||||
|
@ -2057,8 +2050,8 @@ _notmuch_message_ensure_property_map (notmuch_message_t *message)
|
||||||
const char *key;
|
const char *key;
|
||||||
char *value;
|
char *value;
|
||||||
|
|
||||||
value = strchr(node->string, '=');
|
value = strchr (node->string, '=');
|
||||||
if (!value)
|
if (! value)
|
||||||
INTERNAL_ERROR ("malformed property term");
|
INTERNAL_ERROR ("malformed property term");
|
||||||
|
|
||||||
*value = '\0';
|
*value = '\0';
|
||||||
|
@ -2105,7 +2098,7 @@ notmuch_message_reindex (notmuch_message_t *message,
|
||||||
|
|
||||||
/* Save in case we need to delete message */
|
/* Save in case we need to delete message */
|
||||||
orig_thread_id = notmuch_message_get_thread_id (message);
|
orig_thread_id = notmuch_message_get_thread_id (message);
|
||||||
if (!orig_thread_id) {
|
if (! orig_thread_id) {
|
||||||
/* XXX TODO: make up new error return? */
|
/* XXX TODO: make up new error return? */
|
||||||
INTERNAL_ERROR ("message without thread-id");
|
INTERNAL_ERROR ("message without thread-id");
|
||||||
}
|
}
|
||||||
|
@ -2123,7 +2116,7 @@ notmuch_message_reindex (notmuch_message_t *message,
|
||||||
|
|
||||||
private_status = _notmuch_message_remove_indexed_terms (message);
|
private_status = _notmuch_message_remove_indexed_terms (message);
|
||||||
if (private_status) {
|
if (private_status) {
|
||||||
ret = COERCE_STATUS(private_status, "error removing terms");
|
ret = COERCE_STATUS (private_status, "error removing terms");
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2194,7 +2187,7 @@ notmuch_message_reindex (notmuch_message_t *message,
|
||||||
_notmuch_message_sync (message);
|
_notmuch_message_sync (message);
|
||||||
}
|
}
|
||||||
|
|
||||||
DONE:
|
DONE:
|
||||||
if (message_file)
|
if (message_file)
|
||||||
_notmuch_message_file_close (message_file);
|
_notmuch_message_file_close (message_file);
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ _notmuch_messages_has_next (notmuch_messages_t *messages)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (! messages->is_of_list_type)
|
if (! messages->is_of_list_type)
|
||||||
INTERNAL_ERROR("_notmuch_messages_has_next not implemented for msets");
|
INTERNAL_ERROR ("_notmuch_messages_has_next not implemented for msets");
|
||||||
|
|
||||||
return (messages->iterator->next != NULL);
|
return (messages->iterator->next != NULL);
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ notmuch_messages_collect_tags (notmuch_messages_t *messages)
|
||||||
|
|
||||||
keys = g_hash_table_get_keys (htable);
|
keys = g_hash_table_get_keys (htable);
|
||||||
for (l = keys; l; l = l->next) {
|
for (l = keys; l; l = l->next) {
|
||||||
_notmuch_string_list_append (tags, (char *)l->data);
|
_notmuch_string_list_append (tags, (char *) l->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_free (keys);
|
g_list_free (keys);
|
||||||
|
|
|
@ -60,7 +60,7 @@ NOTMUCH_BEGIN_DECLS
|
||||||
# define DEBUG_QUERY 1
|
# define DEBUG_QUERY 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define COMPILE_TIME_ASSERT(pred) ((void)sizeof(char[1 - 2*!(pred)]))
|
#define COMPILE_TIME_ASSERT(pred) ((void) sizeof (char[1 - 2 * ! (pred)]))
|
||||||
|
|
||||||
#define STRNCMP_LITERAL(var, literal) \
|
#define STRNCMP_LITERAL(var, literal) \
|
||||||
strncmp ((var), (literal), sizeof (literal) - 1)
|
strncmp ((var), (literal), sizeof (literal) - 1)
|
||||||
|
@ -69,11 +69,11 @@ NOTMUCH_BEGIN_DECLS
|
||||||
#define _NOTMUCH_VALID_BIT(bit) \
|
#define _NOTMUCH_VALID_BIT(bit) \
|
||||||
((bit) >= 0 && ((unsigned long) bit) < CHAR_BIT * sizeof (unsigned long long))
|
((bit) >= 0 && ((unsigned long) bit) < CHAR_BIT * sizeof (unsigned long long))
|
||||||
#define NOTMUCH_TEST_BIT(val, bit) \
|
#define NOTMUCH_TEST_BIT(val, bit) \
|
||||||
(_NOTMUCH_VALID_BIT(bit) ? !!((val) & (1ull << (bit))) : 0)
|
(_NOTMUCH_VALID_BIT (bit) ? ! ! ((val) & (1ull << (bit))) : 0)
|
||||||
#define NOTMUCH_SET_BIT(valp, bit) \
|
#define NOTMUCH_SET_BIT(valp, bit) \
|
||||||
(_NOTMUCH_VALID_BIT(bit) ? (*(valp) |= (1ull << (bit))) : *(valp))
|
(_NOTMUCH_VALID_BIT (bit) ? (*(valp) |= (1ull << (bit))) : *(valp))
|
||||||
#define NOTMUCH_CLEAR_BIT(valp, bit) \
|
#define NOTMUCH_CLEAR_BIT(valp, bit) \
|
||||||
(_NOTMUCH_VALID_BIT(bit) ? (*(valp) &= ~(1ull << (bit))) : *(valp))
|
(_NOTMUCH_VALID_BIT (bit) ? (*(valp) &= ~(1ull << (bit))) : *(valp))
|
||||||
|
|
||||||
#define unused(x) x __attribute__ ((unused))
|
#define unused(x) x __attribute__ ((unused))
|
||||||
|
|
||||||
|
@ -83,12 +83,12 @@ NOTMUCH_BEGIN_DECLS
|
||||||
/* these macros gain us a few percent of speed on gcc */
|
/* these macros gain us a few percent of speed on gcc */
|
||||||
#if (__GNUC__ >= 3)
|
#if (__GNUC__ >= 3)
|
||||||
/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
|
/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
|
||||||
as its first argument */
|
* as its first argument */
|
||||||
#ifndef likely
|
#ifndef likely
|
||||||
#define likely(x) __builtin_expect(!!(x), 1)
|
#define likely(x) __builtin_expect (! ! (x), 1)
|
||||||
#endif
|
#endif
|
||||||
#ifndef unlikely
|
#ifndef unlikely
|
||||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
#define unlikely(x) __builtin_expect (! ! (x), 0)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#ifndef likely
|
#ifndef likely
|
||||||
|
@ -124,17 +124,17 @@ typedef enum {
|
||||||
|
|
||||||
typedef enum _notmuch_private_status {
|
typedef enum _notmuch_private_status {
|
||||||
/* First, copy all the public status values. */
|
/* First, copy all the public status values. */
|
||||||
NOTMUCH_PRIVATE_STATUS_SUCCESS = NOTMUCH_STATUS_SUCCESS,
|
NOTMUCH_PRIVATE_STATUS_SUCCESS = NOTMUCH_STATUS_SUCCESS,
|
||||||
NOTMUCH_PRIVATE_STATUS_OUT_OF_MEMORY = NOTMUCH_STATUS_OUT_OF_MEMORY,
|
NOTMUCH_PRIVATE_STATUS_OUT_OF_MEMORY = NOTMUCH_STATUS_OUT_OF_MEMORY,
|
||||||
NOTMUCH_PRIVATE_STATUS_READ_ONLY_DATABASE = NOTMUCH_STATUS_READ_ONLY_DATABASE,
|
NOTMUCH_PRIVATE_STATUS_READ_ONLY_DATABASE = NOTMUCH_STATUS_READ_ONLY_DATABASE,
|
||||||
NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION = NOTMUCH_STATUS_XAPIAN_EXCEPTION,
|
NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION = NOTMUCH_STATUS_XAPIAN_EXCEPTION,
|
||||||
NOTMUCH_PRIVATE_STATUS_FILE_NOT_EMAIL = NOTMUCH_STATUS_FILE_NOT_EMAIL,
|
NOTMUCH_PRIVATE_STATUS_FILE_NOT_EMAIL = NOTMUCH_STATUS_FILE_NOT_EMAIL,
|
||||||
NOTMUCH_PRIVATE_STATUS_NULL_POINTER = NOTMUCH_STATUS_NULL_POINTER,
|
NOTMUCH_PRIVATE_STATUS_NULL_POINTER = NOTMUCH_STATUS_NULL_POINTER,
|
||||||
NOTMUCH_PRIVATE_STATUS_TAG_TOO_LONG = NOTMUCH_STATUS_TAG_TOO_LONG,
|
NOTMUCH_PRIVATE_STATUS_TAG_TOO_LONG = NOTMUCH_STATUS_TAG_TOO_LONG,
|
||||||
NOTMUCH_PRIVATE_STATUS_UNBALANCED_FREEZE_THAW = NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW,
|
NOTMUCH_PRIVATE_STATUS_UNBALANCED_FREEZE_THAW = NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW,
|
||||||
|
|
||||||
/* Then add our own private values. */
|
/* Then add our own private values. */
|
||||||
NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG = NOTMUCH_STATUS_LAST_STATUS,
|
NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG = NOTMUCH_STATUS_LAST_STATUS,
|
||||||
NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND,
|
NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND,
|
||||||
NOTMUCH_PRIVATE_STATUS_BAD_PREFIX,
|
NOTMUCH_PRIVATE_STATUS_BAD_PREFIX,
|
||||||
|
|
||||||
|
@ -150,14 +150,14 @@ typedef enum _notmuch_private_status {
|
||||||
* Note that the function _internal_error does not return. Evaluating
|
* Note that the function _internal_error does not return. Evaluating
|
||||||
* to NOTMUCH_STATUS_SUCCESS is done purely to appease the compiler.
|
* to NOTMUCH_STATUS_SUCCESS is done purely to appease the compiler.
|
||||||
*/
|
*/
|
||||||
#define COERCE_STATUS(private_status, format, ...) \
|
#define COERCE_STATUS(private_status, format, ...) \
|
||||||
((private_status >= (notmuch_private_status_t) NOTMUCH_STATUS_LAST_STATUS)\
|
((private_status >= (notmuch_private_status_t) NOTMUCH_STATUS_LAST_STATUS) \
|
||||||
? \
|
? \
|
||||||
_internal_error (format " (%s).\n", \
|
_internal_error (format " (%s).\n", \
|
||||||
##__VA_ARGS__, \
|
##__VA_ARGS__, \
|
||||||
__location__), \
|
__location__), \
|
||||||
(notmuch_status_t) NOTMUCH_PRIVATE_STATUS_SUCCESS \
|
(notmuch_status_t) NOTMUCH_PRIVATE_STATUS_SUCCESS \
|
||||||
: \
|
: \
|
||||||
(notmuch_status_t) private_status)
|
(notmuch_status_t) private_status)
|
||||||
|
|
||||||
/* Flags shared by various lookup functions. */
|
/* Flags shared by various lookup functions. */
|
||||||
|
@ -167,7 +167,7 @@ typedef enum _notmuch_find_flags {
|
||||||
NOTMUCH_FIND_LOOKUP = 0,
|
NOTMUCH_FIND_LOOKUP = 0,
|
||||||
/* If set, create the necessary document (or documents) if they
|
/* If set, create the necessary document (or documents) if they
|
||||||
* are missing. Requires a read/write database. */
|
* are missing. Requires a read/write database. */
|
||||||
NOTMUCH_FIND_CREATE = 1<<0,
|
NOTMUCH_FIND_CREATE = 1 << 0,
|
||||||
} notmuch_find_flags_t;
|
} notmuch_find_flags_t;
|
||||||
|
|
||||||
typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;
|
typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;
|
||||||
|
@ -185,7 +185,7 @@ _find_prefix (const char *name);
|
||||||
/* Lookup a prefix value by name, including possibly user defined prefixes
|
/* Lookup a prefix value by name, including possibly user defined prefixes
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *
|
||||||
_notmuch_database_prefix (notmuch_database_t *notmuch, const char *name);
|
_notmuch_database_prefix (notmuch_database_t *notmuch, const char *name);
|
||||||
|
|
||||||
char *
|
char *
|
||||||
_notmuch_message_id_compressed (void *ctx, const char *message_id);
|
_notmuch_message_id_compressed (void *ctx, const char *message_id);
|
||||||
|
@ -436,7 +436,7 @@ _notmuch_message_file_get_mime_message (notmuch_message_file_t *message,
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *
|
||||||
_notmuch_message_file_get_header (notmuch_message_file_t *message,
|
_notmuch_message_file_get_header (notmuch_message_file_t *message,
|
||||||
const char *header);
|
const char *header);
|
||||||
|
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
_notmuch_message_file_get_headers (notmuch_message_file_t *message_file,
|
_notmuch_message_file_get_headers (notmuch_message_file_t *message_file,
|
||||||
|
@ -568,7 +568,7 @@ void
|
||||||
_notmuch_message_remove_unprefixed_terms (notmuch_message_t *message);
|
_notmuch_message_remove_unprefixed_terms (notmuch_message_t *message);
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
_notmuch_message_get_thread_id_only(notmuch_message_t *message);
|
_notmuch_message_get_thread_id_only (notmuch_message_t *message);
|
||||||
|
|
||||||
size_t _notmuch_message_get_thread_depth (notmuch_message_t *message);
|
size_t _notmuch_message_get_thread_depth (notmuch_message_t *message);
|
||||||
|
|
||||||
|
@ -621,10 +621,10 @@ void
|
||||||
_notmuch_string_list_sort (notmuch_string_list_t *list);
|
_notmuch_string_list_sort (notmuch_string_list_t *list);
|
||||||
|
|
||||||
const notmuch_string_list_t *
|
const notmuch_string_list_t *
|
||||||
_notmuch_message_get_references(notmuch_message_t *message);
|
_notmuch_message_get_references (notmuch_message_t *message);
|
||||||
|
|
||||||
/* string-map.c */
|
/* string-map.c */
|
||||||
typedef struct _notmuch_string_map notmuch_string_map_t;
|
typedef struct _notmuch_string_map notmuch_string_map_t;
|
||||||
typedef struct _notmuch_string_map_iterator notmuch_string_map_iterator_t;
|
typedef struct _notmuch_string_map_iterator notmuch_string_map_iterator_t;
|
||||||
notmuch_string_map_t *
|
notmuch_string_map_t *
|
||||||
_notmuch_string_map_create (const void *ctx);
|
_notmuch_string_map_create (const void *ctx);
|
||||||
|
@ -704,7 +704,7 @@ NOTMUCH_END_DECLS
|
||||||
* template function for this to maintain type safety, and redefine
|
* template function for this to maintain type safety, and redefine
|
||||||
* talloc_steal to use it.
|
* talloc_steal to use it.
|
||||||
*/
|
*/
|
||||||
#if !(__GNUC__ >= 3)
|
#if ! (__GNUC__ >= 3)
|
||||||
template <class T> T *
|
template <class T> T *
|
||||||
_notmuch_talloc_steal (const void *new_ctx, const T *ptr)
|
_notmuch_talloc_steal (const void *new_ctx, const T *ptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,18 +57,18 @@ NOTMUCH_BEGIN_DECLS
|
||||||
* The library version number. This must agree with the soname
|
* The library version number. This must agree with the soname
|
||||||
* version in Makefile.local.
|
* version in Makefile.local.
|
||||||
*/
|
*/
|
||||||
#define LIBNOTMUCH_MAJOR_VERSION 5
|
#define LIBNOTMUCH_MAJOR_VERSION 5
|
||||||
#define LIBNOTMUCH_MINOR_VERSION 2
|
#define LIBNOTMUCH_MINOR_VERSION 2
|
||||||
#define LIBNOTMUCH_MICRO_VERSION 0
|
#define LIBNOTMUCH_MICRO_VERSION 0
|
||||||
|
|
||||||
|
|
||||||
#if defined (__clang_major__) && __clang_major__ >= 3 \
|
#if defined (__clang_major__) && __clang_major__ >= 3 \
|
||||||
|| defined (__GNUC__) && __GNUC__ >= 5 \
|
|| defined (__GNUC__) && __GNUC__ >= 5 \
|
||||||
|| defined (__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 5
|
|| defined (__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 5
|
||||||
#define NOTMUCH_DEPRECATED(major,minor) \
|
#define NOTMUCH_DEPRECATED(major, minor) \
|
||||||
__attribute__ ((deprecated ("function deprecated as of libnotmuch " #major "." #minor)))
|
__attribute__ ((deprecated ("function deprecated as of libnotmuch " #major "." #minor)))
|
||||||
#else
|
#else
|
||||||
#define NOTMUCH_DEPRECATED(major,minor) __attribute__ ((deprecated))
|
#define NOTMUCH_DEPRECATED(major, minor) __attribute__ ((deprecated))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,8 +95,8 @@ NOTMUCH_BEGIN_DECLS
|
||||||
* #endif
|
* #endif
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
#define LIBNOTMUCH_CHECK_VERSION(major, minor, micro) \
|
#define LIBNOTMUCH_CHECK_VERSION(major, minor, micro) \
|
||||||
(LIBNOTMUCH_MAJOR_VERSION > (major) || \
|
(LIBNOTMUCH_MAJOR_VERSION > (major) || \
|
||||||
(LIBNOTMUCH_MAJOR_VERSION == (major) && LIBNOTMUCH_MINOR_VERSION > (minor)) || \
|
(LIBNOTMUCH_MAJOR_VERSION == (major) && LIBNOTMUCH_MINOR_VERSION > (minor)) || \
|
||||||
(LIBNOTMUCH_MAJOR_VERSION == (major) && LIBNOTMUCH_MINOR_VERSION == (minor) && \
|
(LIBNOTMUCH_MAJOR_VERSION == (major) && LIBNOTMUCH_MINOR_VERSION == (minor) && \
|
||||||
LIBNOTMUCH_MICRO_VERSION >= (micro)))
|
LIBNOTMUCH_MICRO_VERSION >= (micro)))
|
||||||
|
@ -405,8 +405,8 @@ typedef void (*notmuch_compact_status_cb_t)(const char *message, void *closure);
|
||||||
* 'closure' is passed verbatim to any callback invoked.
|
* 'closure' is passed verbatim to any callback invoked.
|
||||||
*/
|
*/
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_database_compact (const char* path,
|
notmuch_database_compact (const char *path,
|
||||||
const char* backup_path,
|
const char *backup_path,
|
||||||
notmuch_compact_status_cb_t status_cb,
|
notmuch_compact_status_cb_t status_cb,
|
||||||
void *closure);
|
void *closure);
|
||||||
|
|
||||||
|
@ -467,8 +467,8 @@ notmuch_database_needs_upgrade (notmuch_database_t *database);
|
||||||
*/
|
*/
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_database_upgrade (notmuch_database_t *database,
|
notmuch_database_upgrade (notmuch_database_t *database,
|
||||||
void (*progress_notify) (void *closure,
|
void (*progress_notify)(void *closure,
|
||||||
double progress),
|
double progress),
|
||||||
void *closure);
|
void *closure);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -525,7 +525,7 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch);
|
||||||
*/
|
*/
|
||||||
unsigned long
|
unsigned long
|
||||||
notmuch_database_get_revision (notmuch_database_t *notmuch,
|
notmuch_database_get_revision (notmuch_database_t *notmuch,
|
||||||
const char **uuid);
|
const char **uuid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a directory object from the database for 'path'.
|
* Retrieve a directory object from the database for 'path'.
|
||||||
|
@ -551,7 +551,7 @@ notmuch_database_get_revision (notmuch_database_t *notmuch,
|
||||||
* directory not retrieved.
|
* directory not retrieved.
|
||||||
*
|
*
|
||||||
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
|
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
|
||||||
* database to use this function.
|
* database to use this function.
|
||||||
*/
|
*/
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_database_get_directory (notmuch_database_t *database,
|
notmuch_database_get_directory (notmuch_database_t *database,
|
||||||
|
@ -614,7 +614,7 @@ notmuch_database_get_directory (notmuch_database_t *database,
|
||||||
* mode so no message can be added.
|
* mode so no message can be added.
|
||||||
*
|
*
|
||||||
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
|
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
|
||||||
* database to use this function.
|
* database to use this function.
|
||||||
*
|
*
|
||||||
* @since libnotmuch 5.1 (notmuch 0.26)
|
* @since libnotmuch 5.1 (notmuch 0.26)
|
||||||
*/
|
*/
|
||||||
|
@ -632,7 +632,7 @@ notmuch_database_index_file (notmuch_database_t *database,
|
||||||
* use notmuch_database_index_file instead.
|
* use notmuch_database_index_file instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NOTMUCH_DEPRECATED(5,1)
|
NOTMUCH_DEPRECATED (5, 1)
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_database_add_message (notmuch_database_t *database,
|
notmuch_database_add_message (notmuch_database_t *database,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
|
@ -664,7 +664,7 @@ notmuch_database_add_message (notmuch_database_t *database,
|
||||||
* mode so no message can be removed.
|
* mode so no message can be removed.
|
||||||
*
|
*
|
||||||
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
|
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
|
||||||
* database to use this function.
|
* database to use this function.
|
||||||
*/
|
*/
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_database_remove_message (notmuch_database_t *database,
|
notmuch_database_remove_message (notmuch_database_t *database,
|
||||||
|
@ -722,7 +722,7 @@ notmuch_database_find_message (notmuch_database_t *database,
|
||||||
* NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred
|
* NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred
|
||||||
*
|
*
|
||||||
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
|
* NOTMUCH_STATUS_UPGRADE_REQUIRED: The caller must upgrade the
|
||||||
* database to use this function.
|
* database to use this function.
|
||||||
*/
|
*/
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
|
notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
|
||||||
|
@ -930,7 +930,7 @@ notmuch_query_search_threads (notmuch_query_t *query,
|
||||||
* use notmuch_query_search_threads instead.
|
* use notmuch_query_search_threads instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NOTMUCH_DEPRECATED(5,0)
|
NOTMUCH_DEPRECATED (5, 0)
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_query_search_threads_st (notmuch_query_t *query, notmuch_threads_t **out);
|
notmuch_query_search_threads_st (notmuch_query_t *query, notmuch_threads_t **out);
|
||||||
|
|
||||||
|
@ -986,7 +986,7 @@ notmuch_query_search_messages (notmuch_query_t *query,
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NOTMUCH_DEPRECATED(5,0)
|
NOTMUCH_DEPRECATED (5, 0)
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_query_search_messages_st (notmuch_query_t *query,
|
notmuch_query_search_messages_st (notmuch_query_t *query,
|
||||||
notmuch_messages_t **out);
|
notmuch_messages_t **out);
|
||||||
|
@ -1082,7 +1082,7 @@ notmuch_query_count_messages (notmuch_query_t *query, unsigned int *count);
|
||||||
* @deprecated Deprecated since libnotmuch 5.0 (notmuch 0.25). Please
|
* @deprecated Deprecated since libnotmuch 5.0 (notmuch 0.25). Please
|
||||||
* use notmuch_query_count_messages instead.
|
* use notmuch_query_count_messages instead.
|
||||||
*/
|
*/
|
||||||
NOTMUCH_DEPRECATED(5,0)
|
NOTMUCH_DEPRECATED (5, 0)
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_query_count_messages_st (notmuch_query_t *query, unsigned int *count);
|
notmuch_query_count_messages_st (notmuch_query_t *query, unsigned int *count);
|
||||||
|
|
||||||
|
@ -1100,7 +1100,7 @@ notmuch_query_count_messages_st (notmuch_query_t *query, unsigned int *count);
|
||||||
*
|
*
|
||||||
* NOTMUCH_STATUS_OUT_OF_MEMORY: Memory allocation failed. The value
|
* NOTMUCH_STATUS_OUT_OF_MEMORY: Memory allocation failed. The value
|
||||||
* of *count is not defined
|
* of *count is not defined
|
||||||
|
*
|
||||||
* NOTMUCH_STATUS_SUCCESS: query completed successfully.
|
* NOTMUCH_STATUS_SUCCESS: query completed successfully.
|
||||||
*
|
*
|
||||||
* NOTMUCH_STATUS_XAPIAN_EXCEPTION: a Xapian exception occurred. The
|
* NOTMUCH_STATUS_XAPIAN_EXCEPTION: a Xapian exception occurred. The
|
||||||
|
@ -1117,7 +1117,7 @@ notmuch_query_count_threads (notmuch_query_t *query, unsigned *count);
|
||||||
* @deprecated Deprecated as of libnotmuch 5.0 (notmuch 0.25). Please
|
* @deprecated Deprecated as of libnotmuch 5.0 (notmuch 0.25). Please
|
||||||
* use notmuch_query_count_threads_st instead.
|
* use notmuch_query_count_threads_st instead.
|
||||||
*/
|
*/
|
||||||
NOTMUCH_DEPRECATED(5,0)
|
NOTMUCH_DEPRECATED (5, 0)
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_query_count_threads_st (notmuch_query_t *query, unsigned *count);
|
notmuch_query_count_threads_st (notmuch_query_t *query, unsigned *count);
|
||||||
|
|
||||||
|
@ -1499,7 +1499,7 @@ notmuch_message_set_flag (notmuch_message_t *message,
|
||||||
* "date".
|
* "date".
|
||||||
*/
|
*/
|
||||||
time_t
|
time_t
|
||||||
notmuch_message_get_date (notmuch_message_t *message);
|
notmuch_message_get_date (notmuch_message_t *message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of the specified header from 'message' as a UTF-8 string.
|
* Get the value of the specified header from 'message' as a UTF-8 string.
|
||||||
|
|
|
@ -45,14 +45,14 @@ ParseTimeValueRangeProcessor::operator() (std::string &begin, std::string &end)
|
||||||
if (time (&now) == (time_t) -1)
|
if (time (&now) == (time_t) -1)
|
||||||
return Xapian::BAD_VALUENO;
|
return Xapian::BAD_VALUENO;
|
||||||
|
|
||||||
if (!begin.empty ()) {
|
if (! begin.empty ()) {
|
||||||
if (parse_time_string (begin.c_str (), &t, &now, PARSE_TIME_ROUND_DOWN))
|
if (parse_time_string (begin.c_str (), &t, &now, PARSE_TIME_ROUND_DOWN))
|
||||||
return Xapian::BAD_VALUENO;
|
return Xapian::BAD_VALUENO;
|
||||||
|
|
||||||
begin.assign (Xapian::sortable_serialise ((double) t));
|
begin.assign (Xapian::sortable_serialise ((double) t));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!end.empty ()) {
|
if (! end.empty ()) {
|
||||||
if (end == "!" && ! b.empty ())
|
if (end == "!" && ! b.empty ())
|
||||||
end = b;
|
end = b;
|
||||||
|
|
||||||
|
@ -67,12 +67,14 @@ ParseTimeValueRangeProcessor::operator() (std::string &begin, std::string &end)
|
||||||
|
|
||||||
#if HAVE_XAPIAN_FIELD_PROCESSOR
|
#if HAVE_XAPIAN_FIELD_PROCESSOR
|
||||||
/* XXX TODO: is throwing an exception the right thing to do here? */
|
/* XXX TODO: is throwing an exception the right thing to do here? */
|
||||||
Xapian::Query DateFieldProcessor::operator()(const std::string & str) {
|
Xapian::Query
|
||||||
|
DateFieldProcessor::operator() (const std::string & str)
|
||||||
|
{
|
||||||
time_t from, to, now;
|
time_t from, to, now;
|
||||||
|
|
||||||
/* Use the same 'now' for begin and end. */
|
/* Use the same 'now' for begin and end. */
|
||||||
if (time (&now) == (time_t) -1)
|
if (time (&now) == (time_t) -1)
|
||||||
throw Xapian::QueryParserError("Unable to get current time");
|
throw Xapian::QueryParserError ("Unable to get current time");
|
||||||
|
|
||||||
if (parse_time_string (str.c_str (), &from, &now, PARSE_TIME_ROUND_DOWN))
|
if (parse_time_string (str.c_str (), &from, &now, PARSE_TIME_ROUND_DOWN))
|
||||||
throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'");
|
throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'");
|
||||||
|
@ -80,8 +82,8 @@ Xapian::Query DateFieldProcessor::operator()(const std::string & str) {
|
||||||
if (parse_time_string (str.c_str (), &to, &now, PARSE_TIME_ROUND_UP_INCLUSIVE))
|
if (parse_time_string (str.c_str (), &to, &now, PARSE_TIME_ROUND_UP_INCLUSIVE))
|
||||||
throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'");
|
throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'");
|
||||||
|
|
||||||
return Xapian::Query(Xapian::Query::OP_AND,
|
return Xapian::Query (Xapian::Query::OP_AND,
|
||||||
Xapian::Query(Xapian::Query::OP_VALUE_GE, 0, Xapian::sortable_serialise ((double) from)),
|
Xapian::Query (Xapian::Query::OP_VALUE_GE, 0, Xapian::sortable_serialise ((double) from)),
|
||||||
Xapian::Query(Xapian::Query::OP_VALUE_LE, 0, Xapian::sortable_serialise ((double) to)));
|
Xapian::Query (Xapian::Query::OP_VALUE_LE, 0, Xapian::sortable_serialise ((double) to)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,14 +32,16 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ParseTimeValueRangeProcessor (Xapian::valueno slot_)
|
ParseTimeValueRangeProcessor (Xapian::valueno slot_)
|
||||||
: valno(slot_) { }
|
: valno (slot_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Xapian::valueno operator() (std::string &begin, std::string &end);
|
Xapian::valueno operator() (std::string &begin, std::string &end);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if HAVE_XAPIAN_FIELD_PROCESSOR
|
#if HAVE_XAPIAN_FIELD_PROCESSOR
|
||||||
class DateFieldProcessor : public Xapian::FieldProcessor {
|
class DateFieldProcessor : public Xapian::FieldProcessor {
|
||||||
Xapian::Query operator()(const std::string & str);
|
Xapian::Query operator() (const std::string & str);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#endif /* NOTMUCH_PARSE_TIME_VRP_H */
|
#endif /* NOTMUCH_PARSE_TIME_VRP_H */
|
||||||
|
|
|
@ -28,15 +28,17 @@
|
||||||
|
|
||||||
#if HAVE_XAPIAN_FIELD_PROCESSOR
|
#if HAVE_XAPIAN_FIELD_PROCESSOR
|
||||||
class QueryFieldProcessor : public Xapian::FieldProcessor {
|
class QueryFieldProcessor : public Xapian::FieldProcessor {
|
||||||
protected:
|
protected:
|
||||||
Xapian::QueryParser &parser;
|
Xapian::QueryParser &parser;
|
||||||
notmuch_database_t *notmuch;
|
notmuch_database_t *notmuch;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QueryFieldProcessor (Xapian::QueryParser &parser_, notmuch_database_t *notmuch_)
|
QueryFieldProcessor (Xapian::QueryParser &parser_, notmuch_database_t *notmuch_)
|
||||||
: parser(parser_), notmuch(notmuch_) { };
|
: parser (parser_), notmuch (notmuch_)
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
Xapian::Query operator()(const std::string & str);
|
Xapian::Query operator() (const std::string & str);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#endif /* NOTMUCH_QUERY_FP_H */
|
#endif /* NOTMUCH_QUERY_FP_H */
|
||||||
|
|
66
lib/query.cc
66
lib/query.cc
|
@ -71,12 +71,14 @@ static bool
|
||||||
_debug_query (void)
|
_debug_query (void)
|
||||||
{
|
{
|
||||||
char *env = getenv ("NOTMUCH_DEBUG_QUERY");
|
char *env = getenv ("NOTMUCH_DEBUG_QUERY");
|
||||||
|
|
||||||
return (env && strcmp (env, "") != 0);
|
return (env && strcmp (env, "") != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Explicit destructor call for placement new */
|
/* Explicit destructor call for placement new */
|
||||||
static int
|
static int
|
||||||
_notmuch_query_destructor (notmuch_query_t *query) {
|
_notmuch_query_destructor (notmuch_query_t *query)
|
||||||
|
{
|
||||||
query->xapian_query.~Query();
|
query->xapian_query.~Query();
|
||||||
query->terms.~set<std::string>();
|
query->terms.~set<std::string>();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -123,12 +125,12 @@ _notmuch_query_ensure_parsed (notmuch_query_t *query)
|
||||||
try {
|
try {
|
||||||
query->xapian_query =
|
query->xapian_query =
|
||||||
query->notmuch->query_parser->
|
query->notmuch->query_parser->
|
||||||
parse_query (query->query_string, NOTMUCH_QUERY_PARSER_FLAGS);
|
parse_query (query->query_string, NOTMUCH_QUERY_PARSER_FLAGS);
|
||||||
|
|
||||||
/* Xapian doesn't support skip_to on terms from a query since
|
/* Xapian doesn't support skip_to on terms from a query since
|
||||||
* they are unordered, so cache a copy of all terms in
|
* they are unordered, so cache a copy of all terms in
|
||||||
* something searchable.
|
* something searchable.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (Xapian::TermIterator t = query->xapian_query.get_terms_begin ();
|
for (Xapian::TermIterator t = query->xapian_query.get_terms_begin ();
|
||||||
t != query->xapian_query.get_terms_end (); ++t)
|
t != query->xapian_query.get_terms_end (); ++t)
|
||||||
|
@ -137,7 +139,7 @@ _notmuch_query_ensure_parsed (notmuch_query_t *query)
|
||||||
query->parsed = true;
|
query->parsed = true;
|
||||||
|
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
if (!query->notmuch->exception_reported) {
|
if (! query->notmuch->exception_reported) {
|
||||||
_notmuch_database_log (query->notmuch,
|
_notmuch_database_log (query->notmuch,
|
||||||
"A Xapian exception occurred parsing query: %s\n",
|
"A Xapian exception occurred parsing query: %s\n",
|
||||||
error.get_msg ().c_str ());
|
error.get_msg ().c_str ());
|
||||||
|
@ -188,7 +190,7 @@ notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag);
|
term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag);
|
||||||
if (query->terms.count(term) != 0)
|
if (query->terms.count (term) != 0)
|
||||||
return NOTMUCH_STATUS_IGNORED;
|
return NOTMUCH_STATUS_IGNORED;
|
||||||
|
|
||||||
_notmuch_string_list_append (query->exclude_terms, term);
|
_notmuch_string_list_append (query->exclude_terms, term);
|
||||||
|
@ -236,7 +238,7 @@ notmuch_query_search_messages_st (notmuch_query_t *query,
|
||||||
|
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_query_search_messages (notmuch_query_t *query,
|
notmuch_query_search_messages (notmuch_query_t *query,
|
||||||
notmuch_messages_t **out)
|
notmuch_messages_t **out)
|
||||||
{
|
{
|
||||||
return _notmuch_query_search_documents (query, "mail", out);
|
return _notmuch_query_search_documents (query, "mail", out);
|
||||||
}
|
}
|
||||||
|
@ -278,8 +280,7 @@ _notmuch_query_search_documents (notmuch_query_t *query,
|
||||||
Xapian::MSetIterator iterator;
|
Xapian::MSetIterator iterator;
|
||||||
|
|
||||||
if (strcmp (query_string, "") == 0 ||
|
if (strcmp (query_string, "") == 0 ||
|
||||||
strcmp (query_string, "*") == 0)
|
strcmp (query_string, "*") == 0) {
|
||||||
{
|
|
||||||
final_query = mail_query;
|
final_query = mail_query;
|
||||||
} else {
|
} else {
|
||||||
final_query = Xapian::Query (Xapian::Query::OP_AND,
|
final_query = Xapian::Query (Xapian::Query::OP_AND,
|
||||||
|
@ -291,15 +292,14 @@ _notmuch_query_search_documents (notmuch_query_t *query,
|
||||||
exclude_query = _notmuch_exclude_tags (query);
|
exclude_query = _notmuch_exclude_tags (query);
|
||||||
|
|
||||||
if (query->omit_excluded == NOTMUCH_EXCLUDE_TRUE ||
|
if (query->omit_excluded == NOTMUCH_EXCLUDE_TRUE ||
|
||||||
query->omit_excluded == NOTMUCH_EXCLUDE_ALL)
|
query->omit_excluded == NOTMUCH_EXCLUDE_ALL) {
|
||||||
{
|
|
||||||
final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
|
final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
|
||||||
final_query, exclude_query);
|
final_query, exclude_query);
|
||||||
} else { /* NOTMUCH_EXCLUDE_FLAG */
|
} else { /* NOTMUCH_EXCLUDE_FLAG */
|
||||||
exclude_query = Xapian::Query (Xapian::Query::OP_AND,
|
exclude_query = Xapian::Query (Xapian::Query::OP_AND,
|
||||||
exclude_query, final_query);
|
exclude_query, final_query);
|
||||||
|
|
||||||
enquire.set_weighting_scheme (Xapian::BoolWeight());
|
enquire.set_weighting_scheme (Xapian::BoolWeight ());
|
||||||
enquire.set_query (exclude_query);
|
enquire.set_query (exclude_query);
|
||||||
|
|
||||||
mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ());
|
mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ());
|
||||||
|
@ -318,7 +318,7 @@ _notmuch_query_search_documents (notmuch_query_t *query,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enquire.set_weighting_scheme (Xapian::BoolWeight());
|
enquire.set_weighting_scheme (Xapian::BoolWeight ());
|
||||||
|
|
||||||
switch (query->sort) {
|
switch (query->sort) {
|
||||||
case NOTMUCH_SORT_OLDEST_FIRST:
|
case NOTMUCH_SORT_OLDEST_FIRST:
|
||||||
|
@ -354,10 +354,10 @@ _notmuch_query_search_documents (notmuch_query_t *query,
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch,
|
_notmuch_database_log (notmuch,
|
||||||
"A Xapian exception occurred performing query: %s\n",
|
"A Xapian exception occurred performing query: %s\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
_notmuch_database_log_append (notmuch,
|
_notmuch_database_log_append (notmuch,
|
||||||
"Query string was: %s\n",
|
"Query string was: %s\n",
|
||||||
query->query_string);
|
query->query_string);
|
||||||
|
|
||||||
notmuch->exception_reported = true;
|
notmuch->exception_reported = true;
|
||||||
talloc_free (messages);
|
talloc_free (messages);
|
||||||
|
@ -408,8 +408,7 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages)
|
||||||
&status);
|
&status);
|
||||||
|
|
||||||
if (message == NULL &&
|
if (message == NULL &&
|
||||||
status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND)
|
status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
|
||||||
{
|
|
||||||
INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n");
|
INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,8 +438,8 @@ _notmuch_doc_id_set_init (void *ctx,
|
||||||
unsigned char *bitmap;
|
unsigned char *bitmap;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < arr->len; i++)
|
for (unsigned int i = 0; i < arr->len; i++)
|
||||||
max = MAX(max, g_array_index (arr, unsigned int, i));
|
max = MAX (max, g_array_index (arr, unsigned int, i));
|
||||||
bitmap = talloc_zero_array (ctx, unsigned char, DOCIDSET_WORD(max) + 1);
|
bitmap = talloc_zero_array (ctx, unsigned char, DOCIDSET_WORD (max) + 1);
|
||||||
|
|
||||||
if (bitmap == NULL)
|
if (bitmap == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
@ -450,7 +449,7 @@ _notmuch_doc_id_set_init (void *ctx,
|
||||||
|
|
||||||
for (unsigned int i = 0; i < arr->len; i++) {
|
for (unsigned int i = 0; i < arr->len; i++) {
|
||||||
unsigned int doc_id = g_array_index (arr, unsigned int, i);
|
unsigned int doc_id = g_array_index (arr, unsigned int, i);
|
||||||
bitmap[DOCIDSET_WORD(doc_id)] |= 1 << DOCIDSET_BIT(doc_id);
|
bitmap[DOCIDSET_WORD (doc_id)] |= 1 << DOCIDSET_BIT (doc_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -462,7 +461,7 @@ _notmuch_doc_id_set_contains (notmuch_doc_id_set_t *doc_ids,
|
||||||
{
|
{
|
||||||
if (doc_id >= doc_ids->bound)
|
if (doc_id >= doc_ids->bound)
|
||||||
return false;
|
return false;
|
||||||
return doc_ids->bitmap[DOCIDSET_WORD(doc_id)] & (1 << DOCIDSET_BIT(doc_id));
|
return doc_ids->bitmap[DOCIDSET_WORD (doc_id)] & (1 << DOCIDSET_BIT (doc_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -470,7 +469,7 @@ _notmuch_doc_id_set_remove (notmuch_doc_id_set_t *doc_ids,
|
||||||
unsigned int doc_id)
|
unsigned int doc_id)
|
||||||
{
|
{
|
||||||
if (doc_id < doc_ids->bound)
|
if (doc_id < doc_ids->bound)
|
||||||
doc_ids->bitmap[DOCIDSET_WORD(doc_id)] &= ~(1 << DOCIDSET_BIT(doc_id));
|
doc_ids->bitmap[DOCIDSET_WORD (doc_id)] &= ~(1 << DOCIDSET_BIT (doc_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Glib objects force use to use a talloc destructor as well, (but not
|
/* Glib objects force use to use a talloc destructor as well, (but not
|
||||||
|
@ -489,7 +488,7 @@ _notmuch_threads_destructor (notmuch_threads_t *threads)
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
notmuch_query_search_threads_st (notmuch_query_t *query, notmuch_threads_t **out)
|
notmuch_query_search_threads_st (notmuch_query_t *query, notmuch_threads_t **out)
|
||||||
{
|
{
|
||||||
return notmuch_query_search_threads(query, out);
|
return notmuch_query_search_threads (query, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
notmuch_status_t
|
notmuch_status_t
|
||||||
|
@ -624,8 +623,7 @@ _notmuch_query_count_documents (notmuch_query_t *query, const char *type, unsign
|
||||||
Xapian::MSet mset;
|
Xapian::MSet mset;
|
||||||
|
|
||||||
if (strcmp (query_string, "") == 0 ||
|
if (strcmp (query_string, "") == 0 ||
|
||||||
strcmp (query_string, "*") == 0)
|
strcmp (query_string, "*") == 0) {
|
||||||
{
|
|
||||||
final_query = mail_query;
|
final_query = mail_query;
|
||||||
} else {
|
} else {
|
||||||
final_query = Xapian::Query (Xapian::Query::OP_AND,
|
final_query = Xapian::Query (Xapian::Query::OP_AND,
|
||||||
|
@ -635,10 +633,10 @@ _notmuch_query_count_documents (notmuch_query_t *query, const char *type, unsign
|
||||||
exclude_query = _notmuch_exclude_tags (query);
|
exclude_query = _notmuch_exclude_tags (query);
|
||||||
|
|
||||||
final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
|
final_query = Xapian::Query (Xapian::Query::OP_AND_NOT,
|
||||||
final_query, exclude_query);
|
final_query, exclude_query);
|
||||||
|
|
||||||
enquire.set_weighting_scheme(Xapian::BoolWeight());
|
enquire.set_weighting_scheme (Xapian::BoolWeight ());
|
||||||
enquire.set_docid_order(Xapian::Enquire::ASCENDING);
|
enquire.set_docid_order (Xapian::Enquire::ASCENDING);
|
||||||
|
|
||||||
if (_debug_query ()) {
|
if (_debug_query ()) {
|
||||||
fprintf (stderr, "Exclude query is:\n%s\n",
|
fprintf (stderr, "Exclude query is:\n%s\n",
|
||||||
|
@ -657,12 +655,12 @@ _notmuch_query_count_documents (notmuch_query_t *query, const char *type, unsign
|
||||||
mset = enquire.get_mset (0, 1,
|
mset = enquire.get_mset (0, 1,
|
||||||
notmuch->xapian_db->get_doccount ());
|
notmuch->xapian_db->get_doccount ());
|
||||||
|
|
||||||
count = mset.get_matches_estimated();
|
count = mset.get_matches_estimated ();
|
||||||
|
|
||||||
} catch (const Xapian::Error &error) {
|
} catch (const Xapian::Error &error) {
|
||||||
_notmuch_database_log (notmuch,
|
_notmuch_database_log (notmuch,
|
||||||
"A Xapian exception occurred performing query: %s\n",
|
"A Xapian exception occurred performing query: %s\n",
|
||||||
error.get_msg().c_str());
|
error.get_msg ().c_str ());
|
||||||
_notmuch_database_log_append (notmuch,
|
_notmuch_database_log_append (notmuch,
|
||||||
"Query string was: %s\n",
|
"Query string was: %s\n",
|
||||||
query->query_string);
|
query->query_string);
|
||||||
|
|
|
@ -124,12 +124,13 @@ bool
|
||||||
RegexpPostingSource::check (Xapian::docid did, unused (double min_wt))
|
RegexpPostingSource::check (Xapian::docid did, unused (double min_wt))
|
||||||
{
|
{
|
||||||
started_ = true;
|
started_ = true;
|
||||||
if (!it_.check (did) || at_end ())
|
if (! it_.check (did) || at_end ())
|
||||||
return false;
|
return false;
|
||||||
return (regexec (®exp_, (*it_).c_str (), 0, NULL, 0) == 0);
|
return (regexec (®exp_, (*it_).c_str (), 0, NULL, 0) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Xapian::valueno _find_slot (std::string prefix)
|
static inline Xapian::valueno
|
||||||
|
_find_slot (std::string prefix)
|
||||||
{
|
{
|
||||||
if (prefix == "from")
|
if (prefix == "from")
|
||||||
return NOTMUCH_VALUE_FROM;
|
return NOTMUCH_VALUE_FROM;
|
||||||
|
@ -145,11 +146,11 @@ RegexpFieldProcessor::RegexpFieldProcessor (std::string prefix,
|
||||||
notmuch_field_flag_t options_,
|
notmuch_field_flag_t options_,
|
||||||
Xapian::QueryParser &parser_,
|
Xapian::QueryParser &parser_,
|
||||||
notmuch_database_t *notmuch_)
|
notmuch_database_t *notmuch_)
|
||||||
: slot (_find_slot (prefix)),
|
: slot (_find_slot (prefix)),
|
||||||
term_prefix (_find_prefix (prefix.c_str ())),
|
term_prefix (_find_prefix (prefix.c_str ())),
|
||||||
options (options_),
|
options (options_),
|
||||||
parser (parser_),
|
parser (parser_),
|
||||||
notmuch (notmuch_)
|
notmuch (notmuch_)
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -158,17 +159,17 @@ RegexpFieldProcessor::operator() (const std::string & str)
|
||||||
{
|
{
|
||||||
if (str.empty ()) {
|
if (str.empty ()) {
|
||||||
if (options & NOTMUCH_FIELD_PROBABILISTIC) {
|
if (options & NOTMUCH_FIELD_PROBABILISTIC) {
|
||||||
return Xapian::Query(Xapian::Query::OP_AND_NOT,
|
return Xapian::Query (Xapian::Query::OP_AND_NOT,
|
||||||
Xapian::Query::MatchAll,
|
Xapian::Query::MatchAll,
|
||||||
Xapian::Query (Xapian::Query::OP_WILDCARD, term_prefix));
|
Xapian::Query (Xapian::Query::OP_WILDCARD, term_prefix));
|
||||||
} else {
|
} else {
|
||||||
return Xapian::Query (term_prefix);
|
return Xapian::Query (term_prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str.at (0) == '/') {
|
if (str.at (0) == '/') {
|
||||||
if (str.length() > 1 && str.at (str.size () - 1) == '/'){
|
if (str.length () > 1 && str.at (str.size () - 1) == '/') {
|
||||||
std::string regexp_str = str.substr(1,str.size () - 2);
|
std::string regexp_str = str.substr (1, str.size () - 2);
|
||||||
if (slot != Xapian::BAD_VALUENO) {
|
if (slot != Xapian::BAD_VALUENO) {
|
||||||
RegexpPostingSource *postings = new RegexpPostingSource (slot, regexp_str);
|
RegexpPostingSource *postings = new RegexpPostingSource (slot, regexp_str);
|
||||||
return Xapian::Query (postings->release ());
|
return Xapian::Query (postings->release ());
|
||||||
|
@ -176,14 +177,14 @@ RegexpFieldProcessor::operator() (const std::string & str)
|
||||||
std::vector<std::string> terms;
|
std::vector<std::string> terms;
|
||||||
regex_t regexp;
|
regex_t regexp;
|
||||||
|
|
||||||
compile_regex(regexp, regexp_str.c_str ());
|
compile_regex (regexp, regexp_str.c_str ());
|
||||||
for (Xapian::TermIterator it = notmuch->xapian_db->allterms_begin (term_prefix);
|
for (Xapian::TermIterator it = notmuch->xapian_db->allterms_begin (term_prefix);
|
||||||
it != notmuch->xapian_db->allterms_end (); ++it) {
|
it != notmuch->xapian_db->allterms_end (); ++it) {
|
||||||
if (regexec (®exp, (*it).c_str () + term_prefix.size(),
|
if (regexec (®exp, (*it).c_str () + term_prefix.size (),
|
||||||
0, NULL, 0) == 0)
|
0, NULL, 0) == 0)
|
||||||
terms.push_back(*it);
|
terms.push_back (*it);
|
||||||
}
|
}
|
||||||
return Xapian::Query (Xapian::Query::OP_OR, terms.begin(), terms.end());
|
return Xapian::Query (Xapian::Query::OP_OR, terms.begin (), terms.end ());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw Xapian::QueryParserError ("unmatched regex delimiter in '" + str + "'");
|
throw Xapian::QueryParserError ("unmatched regex delimiter in '" + str + "'");
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
*/
|
*/
|
||||||
class RegexpPostingSource : public Xapian::PostingSource
|
class RegexpPostingSource : public Xapian::PostingSource
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
const Xapian::valueno slot_;
|
const Xapian::valueno slot_;
|
||||||
regex_t regexp_;
|
regex_t regexp_;
|
||||||
Xapian::Database db_;
|
Xapian::Database db_;
|
||||||
|
@ -46,7 +46,7 @@ class RegexpPostingSource : public Xapian::PostingSource
|
||||||
RegexpPostingSource (const RegexpPostingSource &);
|
RegexpPostingSource (const RegexpPostingSource &);
|
||||||
RegexpPostingSource &operator= (const RegexpPostingSource &);
|
RegexpPostingSource &operator= (const RegexpPostingSource &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RegexpPostingSource (Xapian::valueno slot, const std::string ®exp);
|
RegexpPostingSource (Xapian::valueno slot, const std::string ®exp);
|
||||||
~RegexpPostingSource ();
|
~RegexpPostingSource ();
|
||||||
void init (const Xapian::Database &db);
|
void init (const Xapian::Database &db);
|
||||||
|
@ -62,20 +62,22 @@ class RegexpPostingSource : public Xapian::PostingSource
|
||||||
|
|
||||||
|
|
||||||
class RegexpFieldProcessor : public Xapian::FieldProcessor {
|
class RegexpFieldProcessor : public Xapian::FieldProcessor {
|
||||||
protected:
|
protected:
|
||||||
Xapian::valueno slot;
|
Xapian::valueno slot;
|
||||||
std::string term_prefix;
|
std::string term_prefix;
|
||||||
notmuch_field_flag_t options;
|
notmuch_field_flag_t options;
|
||||||
Xapian::QueryParser &parser;
|
Xapian::QueryParser &parser;
|
||||||
notmuch_database_t *notmuch;
|
notmuch_database_t *notmuch;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RegexpFieldProcessor (std::string prefix, notmuch_field_flag_t options,
|
RegexpFieldProcessor (std::string prefix, notmuch_field_flag_t options,
|
||||||
Xapian::QueryParser &parser_, notmuch_database_t *notmuch_);
|
Xapian::QueryParser &parser_, notmuch_database_t *notmuch_);
|
||||||
|
|
||||||
~RegexpFieldProcessor () { };
|
~RegexpFieldProcessor ()
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
Xapian::Query operator()(const std::string & str);
|
Xapian::Query operator() (const std::string & str);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#endif /* NOTMUCH_REGEXP_FIELDS_H */
|
#endif /* NOTMUCH_REGEXP_FIELDS_H */
|
||||||
|
|
|
@ -55,6 +55,7 @@ char *
|
||||||
_notmuch_sha1_of_file (const char *filename)
|
_notmuch_sha1_of_file (const char *filename)
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
#define BLOCK_SIZE 4096
|
#define BLOCK_SIZE 4096
|
||||||
unsigned char block[BLOCK_SIZE];
|
unsigned char block[BLOCK_SIZE];
|
||||||
size_t bytes_read;
|
size_t bytes_read;
|
||||||
|
|
|
@ -67,8 +67,8 @@ _notmuch_string_list_append (notmuch_string_list_t *list,
|
||||||
static int
|
static int
|
||||||
cmpnode (const void *pa, const void *pb)
|
cmpnode (const void *pa, const void *pb)
|
||||||
{
|
{
|
||||||
notmuch_string_node_t *a = *(notmuch_string_node_t * const *)pa;
|
notmuch_string_node_t *a = *(notmuch_string_node_t *const *) pa;
|
||||||
notmuch_string_node_t *b = *(notmuch_string_node_t * const *)pb;
|
notmuch_string_node_t *b = *(notmuch_string_node_t *const *) pb;
|
||||||
|
|
||||||
return strcmp (a->string, b->string);
|
return strcmp (a->string, b->string);
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ _notmuch_string_list_sort (notmuch_string_list_t *list)
|
||||||
qsort (nodes, list->length, sizeof (*nodes), cmpnode);
|
qsort (nodes, list->length, sizeof (*nodes), cmpnode);
|
||||||
|
|
||||||
for (i = 0; i < list->length - 1; ++i)
|
for (i = 0; i < list->length - 1; ++i)
|
||||||
nodes[i]->next = nodes[i+1];
|
nodes[i]->next = nodes[i + 1];
|
||||||
nodes[i]->next = NULL;
|
nodes[i]->next = NULL;
|
||||||
list->head = nodes[0];
|
list->head = nodes[0];
|
||||||
list->tail = &nodes[i]->next;
|
list->tail = &nodes[i]->next;
|
||||||
|
|
|
@ -28,15 +28,17 @@
|
||||||
|
|
||||||
#if HAVE_XAPIAN_FIELD_PROCESSOR
|
#if HAVE_XAPIAN_FIELD_PROCESSOR
|
||||||
class ThreadFieldProcessor : public Xapian::FieldProcessor {
|
class ThreadFieldProcessor : public Xapian::FieldProcessor {
|
||||||
protected:
|
protected:
|
||||||
Xapian::QueryParser &parser;
|
Xapian::QueryParser &parser;
|
||||||
notmuch_database_t *notmuch;
|
notmuch_database_t *notmuch;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ThreadFieldProcessor (Xapian::QueryParser &parser_, notmuch_database_t *notmuch_)
|
ThreadFieldProcessor (Xapian::QueryParser &parser_, notmuch_database_t *notmuch_)
|
||||||
: parser(parser_), notmuch(notmuch_) { };
|
: parser (parser_), notmuch (notmuch_)
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
Xapian::Query operator()(const std::string & str);
|
Xapian::Query operator() (const std::string & str);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#endif /* NOTMUCH_THREAD_FP_H */
|
#endif /* NOTMUCH_THREAD_FP_H */
|
||||||
|
|
112
lib/thread.cc
112
lib/thread.cc
|
@ -22,12 +22,12 @@
|
||||||
#include "database-private.h"
|
#include "database-private.h"
|
||||||
|
|
||||||
#include <gmime/gmime.h>
|
#include <gmime/gmime.h>
|
||||||
#include <glib.h> /* GHashTable */
|
#include <glib.h> /* GHashTable */
|
||||||
|
|
||||||
#ifdef DEBUG_THREADING
|
#ifdef DEBUG_THREADING
|
||||||
#define THREAD_DEBUG(format, ...) fprintf(stderr, format " (%s).\n", ##__VA_ARGS__, __location__)
|
#define THREAD_DEBUG(format, ...) fprintf (stderr, format " (%s).\n", ##__VA_ARGS__, __location__)
|
||||||
#else
|
#else
|
||||||
#define THREAD_DEBUG(format, ...) do {} while (0) /* ignored */
|
#define THREAD_DEBUG(format, ...) do {} while (0) /* ignored */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct _notmuch_thread {
|
struct _notmuch_thread {
|
||||||
|
@ -165,8 +165,8 @@ _resolve_thread_authors_string (notmuch_thread_t *thread)
|
||||||
g_ptr_array_free (thread->matched_authors_array, true);
|
g_ptr_array_free (thread->matched_authors_array, true);
|
||||||
thread->matched_authors_array = NULL;
|
thread->matched_authors_array = NULL;
|
||||||
|
|
||||||
if (!thread->authors)
|
if (! thread->authors)
|
||||||
thread->authors = talloc_strdup(thread, "");
|
thread->authors = talloc_strdup (thread, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up the ugly "Lastname, Firstname" format that some mail systems
|
/* clean up the ugly "Lastname, Firstname" format that some mail systems
|
||||||
|
@ -180,14 +180,14 @@ static char *
|
||||||
_thread_cleanup_author (notmuch_thread_t *thread,
|
_thread_cleanup_author (notmuch_thread_t *thread,
|
||||||
const char *author, const char *from)
|
const char *author, const char *from)
|
||||||
{
|
{
|
||||||
char *clean_author,*test_author;
|
char *clean_author, *test_author;
|
||||||
const char *comma;
|
const char *comma;
|
||||||
char *blank;
|
char *blank;
|
||||||
int fname,lname;
|
int fname, lname;
|
||||||
|
|
||||||
if (author == NULL)
|
if (author == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
clean_author = talloc_strdup(thread, author);
|
clean_author = talloc_strdup (thread, author);
|
||||||
if (clean_author == NULL)
|
if (clean_author == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
/* check if there's a comma in the name and that there's a
|
/* check if there's a comma in the name and that there's a
|
||||||
|
@ -196,34 +196,34 @@ _thread_cleanup_author (notmuch_thread_t *thread,
|
||||||
* one character long ",\0").
|
* one character long ",\0").
|
||||||
* Otherwise just return the copy of the original author name that
|
* Otherwise just return the copy of the original author name that
|
||||||
* we just made*/
|
* we just made*/
|
||||||
comma = strchr(author,',');
|
comma = strchr (author, ',');
|
||||||
if (comma && strlen(comma) > 1) {
|
if (comma && strlen (comma) > 1) {
|
||||||
/* let's assemble what we think is the correct name */
|
/* let's assemble what we think is the correct name */
|
||||||
lname = comma - author;
|
lname = comma - author;
|
||||||
|
|
||||||
/* Skip all the spaces after the comma */
|
/* Skip all the spaces after the comma */
|
||||||
fname = strlen(author) - lname - 1;
|
fname = strlen (author) - lname - 1;
|
||||||
comma += 1;
|
comma += 1;
|
||||||
while (*comma == ' ') {
|
while (*comma == ' ') {
|
||||||
fname -= 1;
|
fname -= 1;
|
||||||
comma += 1;
|
comma += 1;
|
||||||
}
|
}
|
||||||
strncpy(clean_author, comma, fname);
|
strncpy (clean_author, comma, fname);
|
||||||
|
|
||||||
*(clean_author+fname) = ' ';
|
*(clean_author + fname) = ' ';
|
||||||
strncpy(clean_author + fname + 1, author, lname);
|
strncpy (clean_author + fname + 1, author, lname);
|
||||||
*(clean_author+fname+1+lname) = '\0';
|
*(clean_author + fname + 1 + lname) = '\0';
|
||||||
/* make a temporary copy and see if it matches the email */
|
/* make a temporary copy and see if it matches the email */
|
||||||
test_author = talloc_strdup(thread,clean_author);
|
test_author = talloc_strdup (thread, clean_author);
|
||||||
|
|
||||||
blank=strchr(test_author,' ');
|
blank = strchr (test_author, ' ');
|
||||||
while (blank != NULL) {
|
while (blank != NULL) {
|
||||||
*blank = '.';
|
*blank = '.';
|
||||||
blank=strchr(test_author,' ');
|
blank = strchr (test_author, ' ');
|
||||||
}
|
}
|
||||||
if (strcasestr(from, test_author) == NULL)
|
if (strcasestr (from, test_author) == NULL)
|
||||||
/* we didn't identify this as part of the email address
|
/* we didn't identify this as part of the email address
|
||||||
* so let's punt and return the original author */
|
* so let's punt and return the original author */
|
||||||
strcpy (clean_author, author);
|
strcpy (clean_author, author);
|
||||||
}
|
}
|
||||||
return clean_author;
|
return clean_author;
|
||||||
|
@ -251,16 +251,14 @@ _thread_add_message (notmuch_thread_t *thread,
|
||||||
if (omit_exclude != NOTMUCH_EXCLUDE_FALSE) {
|
if (omit_exclude != NOTMUCH_EXCLUDE_FALSE) {
|
||||||
for (tags = notmuch_message_get_tags (message);
|
for (tags = notmuch_message_get_tags (message);
|
||||||
notmuch_tags_valid (tags);
|
notmuch_tags_valid (tags);
|
||||||
notmuch_tags_move_to_next (tags))
|
notmuch_tags_move_to_next (tags)) {
|
||||||
{
|
|
||||||
tag = notmuch_tags_get (tags);
|
tag = notmuch_tags_get (tags);
|
||||||
/* Is message excluded? */
|
/* Is message excluded? */
|
||||||
for (notmuch_string_node_t *term = exclude_terms->head;
|
for (notmuch_string_node_t *term = exclude_terms->head;
|
||||||
term != NULL;
|
term != NULL;
|
||||||
term = term->next)
|
term = term->next) {
|
||||||
{
|
|
||||||
/* Check for an empty string, and then ignore initial 'K'. */
|
/* Check for an empty string, and then ignore initial 'K'. */
|
||||||
if (*(term->string) && strcmp(tag, (term->string + 1)) == 0) {
|
if (*(term->string) && strcmp (tag, (term->string + 1)) == 0) {
|
||||||
message_excluded = true;
|
message_excluded = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -309,8 +307,7 @@ _thread_add_message (notmuch_thread_t *thread,
|
||||||
|
|
||||||
for (tags = notmuch_message_get_tags (message);
|
for (tags = notmuch_message_get_tags (message);
|
||||||
notmuch_tags_valid (tags);
|
notmuch_tags_valid (tags);
|
||||||
notmuch_tags_move_to_next (tags))
|
notmuch_tags_move_to_next (tags)) {
|
||||||
{
|
|
||||||
tag = notmuch_tags_get (tags);
|
tag = notmuch_tags_get (tags);
|
||||||
g_hash_table_insert (thread->tags, xstrdup (tag), NULL);
|
g_hash_table_insert (thread->tags, xstrdup (tag), NULL);
|
||||||
}
|
}
|
||||||
|
@ -338,12 +335,12 @@ _thread_set_subject_from_message (notmuch_thread_t *thread,
|
||||||
|
|
||||||
cleaned_subject = talloc_strndup (thread,
|
cleaned_subject = talloc_strndup (thread,
|
||||||
subject + 4,
|
subject + 4,
|
||||||
strlen(subject) - 4);
|
strlen (subject) - 4);
|
||||||
} else {
|
} else {
|
||||||
cleaned_subject = talloc_strdup (thread, subject);
|
cleaned_subject = talloc_strdup (thread, subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! EMPTY_STRING(cleaned_subject)) {
|
if (! EMPTY_STRING (cleaned_subject)) {
|
||||||
if (thread->subject)
|
if (thread->subject)
|
||||||
talloc_free (thread->subject);
|
talloc_free (thread->subject);
|
||||||
|
|
||||||
|
@ -373,17 +370,17 @@ _thread_add_matched_message (notmuch_thread_t *thread,
|
||||||
|
|
||||||
if (date > thread->newest || ! thread->matched_messages) {
|
if (date > thread->newest || ! thread->matched_messages) {
|
||||||
thread->newest = date;
|
thread->newest = date;
|
||||||
const char *cur_subject = notmuch_thread_get_subject(thread);
|
const char *cur_subject = notmuch_thread_get_subject (thread);
|
||||||
if (sort != NOTMUCH_SORT_OLDEST_FIRST || EMPTY_STRING(cur_subject))
|
if (sort != NOTMUCH_SORT_OLDEST_FIRST || EMPTY_STRING (cur_subject))
|
||||||
_thread_set_subject_from_message (thread, message);
|
_thread_set_subject_from_message (thread, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
|
if (! notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED))
|
||||||
thread->matched_messages++;
|
thread->matched_messages++;
|
||||||
|
|
||||||
if (g_hash_table_lookup_extended (thread->message_hash,
|
if (g_hash_table_lookup_extended (thread->message_hash,
|
||||||
notmuch_message_get_message_id (message), NULL,
|
notmuch_message_get_message_id (message), NULL,
|
||||||
(void **) &hashed_message)) {
|
(void **) &hashed_message)) {
|
||||||
notmuch_message_set_flag (hashed_message,
|
notmuch_message_set_flag (hashed_message,
|
||||||
NOTMUCH_MESSAGE_FLAG_MATCH, 1);
|
NOTMUCH_MESSAGE_FLAG_MATCH, 1);
|
||||||
}
|
}
|
||||||
|
@ -392,15 +389,16 @@ _thread_add_matched_message (notmuch_thread_t *thread,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_parent_via_in_reply_to (notmuch_thread_t *thread, notmuch_message_t *message) {
|
_parent_via_in_reply_to (notmuch_thread_t *thread, notmuch_message_t *message)
|
||||||
|
{
|
||||||
notmuch_message_t *parent;
|
notmuch_message_t *parent;
|
||||||
const char *in_reply_to;
|
const char *in_reply_to;
|
||||||
|
|
||||||
in_reply_to = _notmuch_message_get_in_reply_to (message);
|
in_reply_to = _notmuch_message_get_in_reply_to (message);
|
||||||
THREAD_DEBUG("checking message = %s in_reply_to=%s\n",
|
THREAD_DEBUG ("checking message = %s in_reply_to=%s\n",
|
||||||
notmuch_message_get_message_id (message), in_reply_to);
|
notmuch_message_get_message_id (message), in_reply_to);
|
||||||
|
|
||||||
if (in_reply_to && (! EMPTY_STRING(in_reply_to)) &&
|
if (in_reply_to && (! EMPTY_STRING (in_reply_to)) &&
|
||||||
g_hash_table_lookup_extended (thread->message_hash,
|
g_hash_table_lookup_extended (thread->message_hash,
|
||||||
in_reply_to, NULL,
|
in_reply_to, NULL,
|
||||||
(void **) &parent)) {
|
(void **) &parent)) {
|
||||||
|
@ -420,32 +418,32 @@ _parent_or_toplevel (notmuch_thread_t *thread, notmuch_message_t *message)
|
||||||
const notmuch_string_list_t *references =
|
const notmuch_string_list_t *references =
|
||||||
_notmuch_message_get_references (message);
|
_notmuch_message_get_references (message);
|
||||||
|
|
||||||
THREAD_DEBUG("trying to reparent via references: %s\n",
|
THREAD_DEBUG ("trying to reparent via references: %s\n",
|
||||||
notmuch_message_get_message_id (message));
|
notmuch_message_get_message_id (message));
|
||||||
|
|
||||||
for (notmuch_string_node_t *ref_node = references->head;
|
for (notmuch_string_node_t *ref_node = references->head;
|
||||||
ref_node; ref_node = ref_node->next) {
|
ref_node; ref_node = ref_node->next) {
|
||||||
THREAD_DEBUG("checking reference=%s\n", ref_node->string);
|
THREAD_DEBUG ("checking reference=%s\n", ref_node->string);
|
||||||
if ((g_hash_table_lookup_extended (thread->message_hash,
|
if ((g_hash_table_lookup_extended (thread->message_hash,
|
||||||
ref_node->string, NULL,
|
ref_node->string, NULL,
|
||||||
(void **) &new_parent))) {
|
(void **) &new_parent))) {
|
||||||
size_t new_depth = _notmuch_message_get_thread_depth (new_parent);
|
size_t new_depth = _notmuch_message_get_thread_depth (new_parent);
|
||||||
THREAD_DEBUG("got depth %lu\n", new_depth);
|
THREAD_DEBUG ("got depth %lu\n", new_depth);
|
||||||
if (new_depth > max_depth || !parent) {
|
if (new_depth > max_depth || ! parent) {
|
||||||
THREAD_DEBUG("adding at depth %lu parent=%s\n", new_depth, ref_node->string);
|
THREAD_DEBUG ("adding at depth %lu parent=%s\n", new_depth, ref_node->string);
|
||||||
max_depth = new_depth;
|
max_depth = new_depth;
|
||||||
parent = new_parent;
|
parent = new_parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (parent) {
|
if (parent) {
|
||||||
THREAD_DEBUG("adding reply %s to parent=%s\n",
|
THREAD_DEBUG ("adding reply %s to parent=%s\n",
|
||||||
notmuch_message_get_message_id (message),
|
notmuch_message_get_message_id (message),
|
||||||
notmuch_message_get_message_id (parent));
|
notmuch_message_get_message_id (parent));
|
||||||
_notmuch_message_add_reply (parent, message);
|
_notmuch_message_add_reply (parent, message);
|
||||||
} else {
|
} else {
|
||||||
THREAD_DEBUG("adding as toplevel %s\n",
|
THREAD_DEBUG ("adding as toplevel %s\n",
|
||||||
notmuch_message_get_message_id (message));
|
notmuch_message_get_message_id (message));
|
||||||
_notmuch_message_list_add_message (thread->toplevel_list, message);
|
_notmuch_message_list_add_message (thread->toplevel_list, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,22 +477,21 @@ _resolve_thread_relationships (notmuch_thread_t *thread)
|
||||||
*/
|
*/
|
||||||
if (first_node) {
|
if (first_node) {
|
||||||
message = first_node->message;
|
message = first_node->message;
|
||||||
THREAD_DEBUG("checking first message %s\n",
|
THREAD_DEBUG ("checking first message %s\n",
|
||||||
notmuch_message_get_message_id (message));
|
notmuch_message_get_message_id (message));
|
||||||
|
|
||||||
if (_notmuch_message_list_empty (maybe_toplevel_list) ||
|
if (_notmuch_message_list_empty (maybe_toplevel_list) ||
|
||||||
! _parent_via_in_reply_to (thread, message)) {
|
! _parent_via_in_reply_to (thread, message)) {
|
||||||
|
|
||||||
THREAD_DEBUG("adding first message as toplevel = %s\n",
|
THREAD_DEBUG ("adding first message as toplevel = %s\n",
|
||||||
notmuch_message_get_message_id (message));
|
notmuch_message_get_message_id (message));
|
||||||
_notmuch_message_list_add_message (maybe_toplevel_list, message);
|
_notmuch_message_list_add_message (maybe_toplevel_list, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (notmuch_messages_t *messages = _notmuch_messages_create (maybe_toplevel_list);
|
for (notmuch_messages_t *messages = _notmuch_messages_create (maybe_toplevel_list);
|
||||||
notmuch_messages_valid (messages);
|
notmuch_messages_valid (messages);
|
||||||
notmuch_messages_move_to_next (messages))
|
notmuch_messages_move_to_next (messages)) {
|
||||||
{
|
|
||||||
notmuch_message_t *message = notmuch_messages_get (messages);
|
notmuch_message_t *message = notmuch_messages_get (messages);
|
||||||
_notmuch_message_label_depths (message, 0);
|
_notmuch_message_label_depths (message, 0);
|
||||||
}
|
}
|
||||||
|
@ -616,8 +613,7 @@ _notmuch_thread_create (void *ctx,
|
||||||
|
|
||||||
for (;
|
for (;
|
||||||
notmuch_messages_valid (messages);
|
notmuch_messages_valid (messages);
|
||||||
notmuch_messages_move_to_next (messages))
|
notmuch_messages_move_to_next (messages)) {
|
||||||
{
|
|
||||||
unsigned int doc_id;
|
unsigned int doc_id;
|
||||||
|
|
||||||
message = notmuch_messages_get (messages);
|
message = notmuch_messages_get (messages);
|
||||||
|
|
Loading…
Reference in a new issue