]> git.notmuchmail.org Git - notmuch/blobdiff - lib/notmuch-private.h
emacs: Add new option notmuch-search-hide-excluded
[notmuch] / lib / notmuch-private.h
index 6063262a1e3a5e0f67b7d35844ba08b730c6a3e5..367e23e610d0220df108eed1cc078694b10bfea9 100644 (file)
@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see http://www.gnu.org/licenses/ .
+ * along with this program.  If not, see https://www.gnu.org/licenses/ .
  *
  * Author: Carl Worth <cworth@cworth.org>
  */
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE /* For getline and asprintf */
 #endif
+#include <stdbool.h>
 #include <stdio.h>
 
 #include "compat.h"
 
 #include "notmuch.h"
 
+#include "xutil.h"
+#include "error_util.h"
+#include "string-util.h"
+#include "crypto.h"
+#include "repair.h"
+
 NOTMUCH_BEGIN_DECLS
 
 #include <stdlib.h>
@@ -46,20 +53,13 @@ NOTMUCH_BEGIN_DECLS
 
 #include <talloc.h>
 
-#include <gmime/gmime.h>
-
-#include "xutil.h"
-#include "error_util.h"
-#include "string-util.h"
-
-#pragma GCC visibility push(hidden)
-
 #ifdef DEBUG
 # define DEBUG_DATABASE_SANITY 1
+# define DEBUG_THREADING 1
 # define DEBUG_QUERY 1
 #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) \
     strncmp ((var), (literal), sizeof (literal) - 1)
@@ -68,19 +68,13 @@ NOTMUCH_BEGIN_DECLS
 #define _NOTMUCH_VALID_BIT(bit) \
     ((bit) >= 0 && ((unsigned long) bit) < CHAR_BIT * sizeof (unsigned long long))
 #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) \
-    (_NOTMUCH_VALID_BIT(bit) ? (*(valp) |= (1ull << (bit))) : *(valp))
+    (_NOTMUCH_VALID_BIT (bit) ? (*(valp) |= (1ull << (bit))) : *(valp))
 #define NOTMUCH_CLEAR_BIT(valp,  bit) \
-    (_NOTMUCH_VALID_BIT(bit) ? (*(valp) &= ~(1ull << (bit))) : *(valp))
-
-#define unused(x) x __attribute__ ((unused))
+    (_NOTMUCH_VALID_BIT (bit) ? (*(valp) &= ~(1ull << (bit))) : *(valp))
 
-#ifdef __cplusplus
-# define visible __attribute__((visibility("default")))
-#else
-# define visible
-#endif
+#define unused(x) x ## _unused __attribute__ ((unused))
 
 /* Thanks to Andrew Tridgell's (SAMBA's) talloc for this definition of
  * unlikely. The talloc source code comes to us via the GNU LGPL v. 3.
@@ -88,12 +82,12 @@ NOTMUCH_BEGIN_DECLS
 /* these macros gain us a few percent of speed on gcc */
 #if (__GNUC__ >= 3)
 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
  as its first argument */
* as its first argument */
 #ifndef likely
-#define likely(x)   __builtin_expect(!!(x), 1)
+#define likely(x)   __builtin_expect (! ! (x), 1)
 #endif
 #ifndef unlikely
-#define unlikely(x) __builtin_expect(!!(x), 0)
+#define unlikely(x) __builtin_expect (! ! (x), 0)
 #endif
 #else
 #ifndef likely
@@ -127,20 +121,37 @@ typedef enum {
  */
 #define NOTMUCH_MESSAGE_ID_MAX (200 - sizeof (NOTMUCH_METADATA_THREAD_ID_PREFIX))
 
-typedef enum _notmuch_private_status {
+typedef enum {
     /* First, copy all the public status values. */
-    NOTMUCH_PRIVATE_STATUS_SUCCESS = NOTMUCH_STATUS_SUCCESS,
-    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_XAPIAN_EXCEPTION = NOTMUCH_STATUS_XAPIAN_EXCEPTION,
-    NOTMUCH_PRIVATE_STATUS_FILE_NOT_EMAIL = NOTMUCH_STATUS_FILE_NOT_EMAIL,
-    NOTMUCH_PRIVATE_STATUS_NULL_POINTER = NOTMUCH_STATUS_NULL_POINTER,
-    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_SUCCESS                     = NOTMUCH_STATUS_SUCCESS,
+    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_XAPIAN_EXCEPTION            = NOTMUCH_STATUS_XAPIAN_EXCEPTION,
+    NOTMUCH_PRIVATE_STATUS_FILE_ERROR                  = NOTMUCH_STATUS_FILE_ERROR,
+    NOTMUCH_PRIVATE_STATUS_FILE_NOT_EMAIL              = NOTMUCH_STATUS_FILE_NOT_EMAIL,
+    NOTMUCH_PRIVATE_STATUS_NULL_POINTER                        = NOTMUCH_STATUS_NULL_POINTER,
+    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_ATOMIC           = NOTMUCH_STATUS_UNBALANCED_ATOMIC,
+    NOTMUCH_PRIVATE_STATUS_UNSUPPORTED_OPERATION       = NOTMUCH_STATUS_UNSUPPORTED_OPERATION,
+    NOTMUCH_PRIVATE_STATUS_UPGRADE_REQUIRED            = NOTMUCH_STATUS_UPGRADE_REQUIRED,
+    NOTMUCH_PRIVATE_STATUS_PATH_ERROR                  = NOTMUCH_STATUS_PATH_ERROR,
+    NOTMUCH_PRIVATE_STATUS_IGNORED                     = NOTMUCH_STATUS_IGNORED,
+    NOTMUCH_PRIVATE_STATUS_ILLEGAL_ARGUMENT            = NOTMUCH_STATUS_ILLEGAL_ARGUMENT,
+    NOTMUCH_PRIVATE_STATUS_MALFORMED_CRYPTO_PROTOCOL           = NOTMUCH_STATUS_MALFORMED_CRYPTO_PROTOCOL,
+    NOTMUCH_PRIVATE_STATUS_FAILED_CRYPTO_CONTEXT_CREATION      = NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION,
+    NOTMUCH_PRIVATE_STATUS_UNKNOWN_CRYPTO_PROTOCOL             = NOTMUCH_STATUS_UNKNOWN_CRYPTO_PROTOCOL,
+    NOTMUCH_PRIVATE_STATUS_NO_CONFIG                           = NOTMUCH_STATUS_NO_CONFIG,
+    NOTMUCH_PRIVATE_STATUS_NO_DATABASE                         = NOTMUCH_STATUS_NO_DATABASE,
+    NOTMUCH_PRIVATE_STATUS_DATABASE_EXISTS                     = NOTMUCH_STATUS_DATABASE_EXISTS,
+    NOTMUCH_PRIVATE_STATUS_NO_MAIL_ROOT                                = NOTMUCH_STATUS_NO_MAIL_ROOT,
+    NOTMUCH_PRIVATE_STATUS_BAD_QUERY_SYNTAX                    = NOTMUCH_STATUS_BAD_QUERY_SYNTAX,
+    NOTMUCH_PRIVATE_STATUS_CLOSED_DATABASE                     = NOTMUCH_STATUS_CLOSED_DATABASE,
 
     /* 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_BAD_PREFIX,
 
     NOTMUCH_PRIVATE_STATUS_LAST_STATUS
 } notmuch_private_status_t;
@@ -154,24 +165,24 @@ typedef enum _notmuch_private_status {
  * Note that the function _internal_error does not return. Evaluating
  * to NOTMUCH_STATUS_SUCCESS is done purely to appease the compiler.
  */
-#define COERCE_STATUS(private_status, format, ...)                     \
-    ((private_status >= (notmuch_private_status_t) NOTMUCH_STATUS_LAST_STATUS)\
-     ?                                                                 \
-     _internal_error (format " (%s).\n",                               \
-                     ##__VA_ARGS__,                                    \
-                     __location__),                                    \
-     (notmuch_status_t) NOTMUCH_PRIVATE_STATUS_SUCCESS                 \
-     :                                                                 \
+#define COERCE_STATUS(private_status, format, ...)                      \
+    ((private_status >= (notmuch_private_status_t) NOTMUCH_STATUS_LAST_STATUS) \
+     ?                                                                  \
+     _internal_error (format " (%s).\n",                                \
+                     ##__VA_ARGS__,                                    \
+                     __location__),                                    \
+     (notmuch_status_t) NOTMUCH_PRIVATE_STATUS_SUCCESS                  \
+     :                                                                  \
      (notmuch_status_t) private_status)
 
 /* Flags shared by various lookup functions. */
-typedef enum _notmuch_find_flags {
+typedef enum {
     /* Lookup without creating any documents.  This is the default
      * behavior. */
     NOTMUCH_FIND_LOOKUP = 0,
     /* If set, create the necessary document (or documents) if they
      * are missing.  Requires a read/write database. */
-    NOTMUCH_FIND_CREATE = 1<<0,
+    NOTMUCH_FIND_CREATE = 1 << 0,
 } notmuch_find_flags_t;
 
 typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;
@@ -186,6 +197,11 @@ typedef struct _notmuch_doc_id_set notmuch_doc_id_set_t;
 const char *
 _find_prefix (const char *name);
 
+/* Lookup a prefix value by name, including possibly user defined prefixes
+ */
+const char *
+_notmuch_database_prefix (notmuch_database_t *notmuch, const char *name);
+
 char *
 _notmuch_message_id_compressed (void *ctx, const char *message_id);
 
@@ -196,6 +212,10 @@ void
 _notmuch_database_log (notmuch_database_t *notmuch,
                       const char *format, ...);
 
+void
+_notmuch_database_log_append (notmuch_database_t *notmuch,
+                             const char *format, ...);
+
 unsigned long
 _notmuch_database_new_revision (notmuch_database_t *notmuch);
 
@@ -239,17 +259,24 @@ _notmuch_database_filename_to_direntry (void *ctx,
                                        notmuch_find_flags_t flags,
                                        char **direntry);
 
+bool
+_notmuch_database_indexable_as_text (notmuch_database_t *notmuch,
+                                    const char *mime_string);
+
 /* directory.cc */
 
 notmuch_directory_t *
-_notmuch_directory_create (notmuch_database_t *notmuch,
-                          const char *path,
-                          notmuch_find_flags_t flags,
-                          notmuch_status_t *status_ret);
+_notmuch_directory_find_or_create (notmuch_database_t *notmuch,
+                                  const char *path,
+                                  notmuch_find_flags_t flags,
+                                  notmuch_status_t *status_ret);
 
 unsigned int
 _notmuch_directory_get_document_id (notmuch_directory_t *directory);
 
+notmuch_database_mode_t
+_notmuch_database_mode (notmuch_database_t *notmuch);
+
 /* message.cc */
 
 notmuch_message_t *
@@ -283,7 +310,7 @@ notmuch_private_status_t
 _notmuch_message_has_term (notmuch_message_t *message,
                           const char *prefix_name,
                           const char *value,
-                          notmuch_bool_t *result);
+                          bool *result);
 
 notmuch_private_status_t
 _notmuch_message_gen_terms (notmuch_message_t *message,
@@ -317,6 +344,10 @@ _notmuch_message_set_header_values (notmuch_message_t *message,
                                    const char *from,
                                    const char *subject);
 
+void
+_notmuch_message_update_subject (notmuch_message_t *message,
+                                const char *subject);
+
 void
 _notmuch_message_upgrade_last_mod (notmuch_message_t *message);
 
@@ -424,14 +455,39 @@ _notmuch_message_file_get_mime_message (notmuch_message_file_t *message,
  */
 const char *
 _notmuch_message_file_get_header (notmuch_message_file_t *message,
-                                const char *header);
+                                 const char *header);
+
+notmuch_status_t
+_notmuch_message_file_get_headers (notmuch_message_file_t *message_file,
+                                  const char **from_out,
+                                  const char **subject_out,
+                                  const char **to_out,
+                                  const char **date_out,
+                                  char **message_id_out);
 
+const char *
+_notmuch_message_file_get_filename (notmuch_message_file_t *message);
+
+/* add-message.cc */
+notmuch_status_t
+_notmuch_database_link_message_to_parents (notmuch_database_t *notmuch,
+                                          notmuch_message_t *message,
+                                          notmuch_message_file_t *message_file,
+                                          const char **thread_id);
 /* index.cc */
 
+void
+_notmuch_filter_init ();
+
 notmuch_status_t
 _notmuch_message_index_file (notmuch_message_t *message,
+                            notmuch_indexopts_t *indexopts,
                             notmuch_message_file_t *message_file);
 
+/* init.cc */
+void
+_notmuch_init ();
+
 /* messages.c */
 
 typedef struct _notmuch_message_node {
@@ -448,8 +504,8 @@ typedef struct _notmuch_message_list {
  * somewhere with some nasty C++ objects in it. We'll try to maintain
  * ignorance of that here. (See notmuch_mset_messages_t in query.cc)
  */
-struct visible _notmuch_messages {
-    notmuch_bool_t is_of_list_type;
+struct _notmuch_messages {
+    bool is_of_list_type;
     notmuch_doc_id_set_t *excluded_doc_ids;
     notmuch_message_node_t *iterator;
 };
@@ -457,6 +513,9 @@ struct visible _notmuch_messages {
 notmuch_message_list_t *
 _notmuch_message_list_create (const void *ctx);
 
+bool
+_notmuch_message_list_empty (notmuch_message_list_t *list);
+
 void
 _notmuch_message_list_add_message (notmuch_message_list_t *list,
                                   notmuch_message_t *message);
@@ -464,9 +523,12 @@ _notmuch_message_list_add_message (notmuch_message_list_t *list,
 notmuch_messages_t *
 _notmuch_messages_create (notmuch_message_list_t *list);
 
+bool
+_notmuch_messages_has_next (notmuch_messages_t *messages);
+
 /* query.cc */
 
-notmuch_bool_t
+bool
 _notmuch_mset_messages_valid (notmuch_messages_t *messages);
 
 notmuch_message_t *
@@ -475,7 +537,7 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages);
 void
 _notmuch_mset_messages_move_to_next (notmuch_messages_t *messages);
 
-notmuch_bool_t
+bool
 _notmuch_doc_id_set_contains (notmuch_doc_id_set_t *doc_ids,
                              unsigned int doc_id);
 
@@ -493,14 +555,52 @@ notmuch_status_t
 _notmuch_query_count_documents (notmuch_query_t *query,
                                const char *type,
                                unsigned *count_out);
+/* message-id.c */
+
+/* Parse an RFC 822 message-id, discarding whitespace, any RFC 822
+ * comments, and the '<' and '>' delimiters.
+ *
+ * If not NULL, then *next will be made to point to the first character
+ * not parsed, (possibly pointing to the final '\0' terminator.
+ *
+ * Returns a newly talloc'ed string belonging to 'ctx'.
+ *
+ * Returns NULL if there is any error parsing the message-id. */
+char *
+_notmuch_message_id_parse (void *ctx, const char *message_id, const char **next);
+
+/* Parse a message-id, discarding leading and trailing whitespace, and
+ * '<' and '>' delimiters.
+ *
+ * Apply a probably-stricter-than RFC definition of what is allowed in
+ * a message-id. In particular, forbid whitespace.
+ *
+ * Returns a newly talloc'ed string belonging to 'ctx'.
+ *
+ * Returns NULL if there is any error parsing the message-id.
+ */
+
+char *
+_notmuch_message_id_parse_strict (void *ctx, const char *message_id);
+
 
 /* message.cc */
 
 void
 _notmuch_message_add_reply (notmuch_message_t *message,
                            notmuch_message_t *reply);
-notmuch_database_t *
-_notmuch_message_database (notmuch_message_t *message);
+
+void
+_notmuch_message_remove_unprefixed_terms (notmuch_message_t *message);
+
+size_t _notmuch_message_get_thread_depth (notmuch_message_t *message);
+
+void
+_notmuch_message_label_depths (notmuch_message_t *message,
+                              size_t depth);
+
+notmuch_message_list_t *
+_notmuch_message_sort_subtrees (void *ctx, notmuch_message_list_t *list);
 
 /* sha1.c */
 
@@ -517,7 +617,7 @@ typedef struct _notmuch_string_node {
     struct _notmuch_string_node *next;
 } notmuch_string_node_t;
 
-typedef struct visible _notmuch_string_list {
+typedef struct _notmuch_string_list {
     int length;
     notmuch_string_node_t *head;
     notmuch_string_node_t **tail;
@@ -526,6 +626,12 @@ typedef struct visible _notmuch_string_list {
 notmuch_string_list_t *
 _notmuch_string_list_create (const void *ctx);
 
+/*
+ * return the number of strings in 'list'
+ */
+int
+_notmuch_string_list_length (notmuch_string_list_t *list);
+
 /* Add 'string' to 'list'.
  *
  * The list will create its own talloced copy of 'string'.
@@ -537,6 +643,52 @@ _notmuch_string_list_append (notmuch_string_list_t *list,
 void
 _notmuch_string_list_sort (notmuch_string_list_t *list);
 
+const notmuch_string_list_t *
+_notmuch_message_get_references (notmuch_message_t *message);
+
+/* string-map.c */
+typedef struct _notmuch_string_map notmuch_string_map_t;
+typedef struct _notmuch_string_map_iterator notmuch_string_map_iterator_t;
+notmuch_string_map_t *
+_notmuch_string_map_create (const void *ctx);
+
+void
+_notmuch_string_map_append (notmuch_string_map_t *map,
+                           const char *key,
+                           const char *value);
+
+void
+_notmuch_string_map_set (notmuch_string_map_t *map,
+                        const char *key,
+                        const char *value);
+
+const char *
+_notmuch_string_map_get (notmuch_string_map_t *map, const char *key);
+
+notmuch_string_map_iterator_t *
+_notmuch_string_map_iterator_create (notmuch_string_map_t *map, const char *key,
+                                    bool exact);
+
+bool
+_notmuch_string_map_iterator_valid (notmuch_string_map_iterator_t *iter);
+
+void
+_notmuch_string_map_iterator_move_to_next (notmuch_string_map_iterator_t *iter);
+
+const char *
+_notmuch_string_map_iterator_key (notmuch_string_map_iterator_t *iterator);
+
+const char *
+_notmuch_string_map_iterator_value (notmuch_string_map_iterator_t *iterator);
+
+void
+_notmuch_string_map_iterator_destroy (notmuch_string_map_iterator_t *iterator);
+
+/* Create an iterator for user headers. Destroy with
+ * _notmuch_string_map_iterator_destroy. Actually in database.cc*/
+notmuch_string_map_iterator_t *
+_notmuch_database_user_headers (notmuch_database_t *notmuch);
+
 /* tags.c */
 
 notmuch_tags_t *
@@ -561,6 +713,32 @@ _notmuch_thread_create (void *ctx,
                        notmuch_exclude_t omit_exclude,
                        notmuch_sort_t sort);
 
+/* indexopts.c */
+
+struct _notmuch_indexopts;
+
+#define CONFIG_HEADER_PREFIX "index.header."
+
+#define EMPTY_STRING(s) ((s)[0] == '\0')
+
+/* config.cc */
+notmuch_status_t
+_notmuch_config_load_from_database (notmuch_database_t *db);
+
+notmuch_status_t
+_notmuch_config_load_from_file (notmuch_database_t *db, GKeyFile *file, char **status_string);
+
+notmuch_status_t
+_notmuch_config_load_defaults (notmuch_database_t *db);
+
+void
+_notmuch_config_cache (notmuch_database_t *db, notmuch_config_key_t key, const char *val);
+
+/* open.cc */
+notmuch_status_t
+_notmuch_choose_xapian_path (void *ctx, const char *database_path, const char **xapian_path,
+                            char **message);
+
 NOTMUCH_END_DECLS
 
 #ifdef __cplusplus
@@ -570,7 +748,7 @@ NOTMUCH_END_DECLS
  * template function for this to maintain type safety, and redefine
  * talloc_steal to use it.
  */
-#if !(__GNUC__ >= 3)
+#if ! (__GNUC__ >= 3)
 template <class T> T *
 _notmuch_talloc_steal (const void *new_ctx, const T *ptr)
 {
@@ -579,8 +757,12 @@ _notmuch_talloc_steal (const void *new_ctx, const T *ptr)
 #undef talloc_steal
 #define talloc_steal _notmuch_talloc_steal
 #endif
-#endif
 
-#pragma GCC visibility pop
+#if __cplusplus >= 201703L || __cppcheck__
+#define NODISCARD [[nodiscard]]
+#else
+#define NODISCARD /**/
+#endif
+#endif
 
 #endif