database.cc is uncomfortably large, and some of the static data
structures do not need to be shared as much as they are.

This is a somewhat small piece to factor out, but it will turn out to
be helpful to further refactoring.
---
 lib/Makefile.local     |   3 +-
 lib/database-private.h |  14 +++++
 lib/database.cc        | 118 +----------------------------------------
 lib/features.cc        | 114 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 132 insertions(+), 117 deletions(-)
 create mode 100644 lib/features.cc

diff --git a/lib/Makefile.local b/lib/Makefile.local
index a6400126..04418fa8 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -59,7 +59,8 @@ libnotmuch_cxx_srcs =         \
        $(dir)/config.cc        \
        $(dir)/regexp-fields.cc \
        $(dir)/thread.cc \
-       $(dir)/thread-fp.cc
+       $(dir)/thread-fp.cc     \
+       $(dir)/features.cc
 
 libnotmuch_modules := $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o)
 
diff --git a/lib/database-private.h b/lib/database-private.h
index 041602cd..2d220811 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -32,6 +32,8 @@
 
 #include "notmuch-private.h"
 
+#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
+
 #ifdef SILENCE_XAPIAN_DEPRECATION_WARNINGS
 #define XAPIAN_DEPRECATED(D) D
 #endif
@@ -263,4 +265,16 @@ _notmuch_database_find_doc_ids (notmuch_database_t 
*notmuch,
                                const char *value,
                                Xapian::PostingIterator *begin,
                                Xapian::PostingIterator *end);
+
+#define NOTMUCH_DATABASE_VERSION 3
+
+/* features.cc */
+
+_notmuch_features
+_notmuch_database_parse_features (const void *ctx, const char *features, 
unsigned int version,
+                                 char mode, char **incompat_out);
+
+char *
+_notmuch_database_print_features (const void *ctx, unsigned int features);
+
 #endif
diff --git a/lib/database.cc b/lib/database.cc
index 75189685..e08d43ca 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -39,8 +39,6 @@
 
 using namespace std;
 
-#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
-
 typedef struct {
     const char *name;
     const char *prefix;
@@ -458,41 +456,6 @@ _notmuch_database_prefix (notmuch_database_t *notmuch, 
const char *name)
     return NULL;
 }
 
-static const struct {
-    /* NOTMUCH_FEATURE_* value. */
-    _notmuch_features value;
-    /* Feature name as it appears in the database.  This name should
-     * be appropriate for displaying to the user if an older version
-     * of notmuch doesn't support this feature. */
-    const char *name;
-    /* Compatibility flags when this feature is declared. */
-    const char *flags;
-} feature_names[] = {
-    { NOTMUCH_FEATURE_FILE_TERMS,
-      "multiple paths per message", "rw" },
-    { NOTMUCH_FEATURE_DIRECTORY_DOCS,
-      "relative directory paths", "rw" },
-    /* Header values are not required for reading a database because a
-     * reader can just refer to the message file. */
-    { NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES,
-      "from/subject/message-ID in database", "w" },
-    { NOTMUCH_FEATURE_BOOL_FOLDER,
-      "exact folder:/path: search", "rw" },
-    { NOTMUCH_FEATURE_GHOSTS,
-      "mail documents for missing messages", "w" },
-    /* Knowledge of the index mime-types are not required for reading
-     * a database because a reader will just be unable to query
-     * them. */
-    { NOTMUCH_FEATURE_INDEXED_MIMETYPES,
-      "indexed MIME types", "w" },
-    { NOTMUCH_FEATURE_LAST_MOD,
-      "modification tracking", "w" },
-    /* Existing databases will work fine for all queries not involving
-     * 'body:' */
-    { NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY,
-      "index body and headers separately", "w" },
-};
-
 const char *
 notmuch_status_to_string (notmuch_status_t status)
 {
@@ -817,83 +780,6 @@ _notmuch_database_new_revision (notmuch_database_t 
*notmuch)
     return new_revision;
 }
 
-/* Parse a database features string from the given database version.
- * Returns the feature bit set.
- *
- * For version < 3, this ignores the features string and returns a
- * hard-coded set of features.
- *
- * If there are unrecognized features that are required to open the
- * database in mode (which should be 'r' or 'w'), return a
- * comma-separated list of unrecognized but required features in
- * *incompat_out suitable for presenting to the user.  *incompat_out
- * will be allocated from ctx.
- */
-static _notmuch_features
-_parse_features (const void *ctx, const char *features, unsigned int version,
-                char mode, char **incompat_out)
-{
-    _notmuch_features res = static_cast<_notmuch_features>(0);
-    unsigned int namelen, i;
-    size_t llen = 0;
-    const char *flags;
-
-    /* Prior to database version 3, features were implied by the
-     * version number. */
-    if (version == 0)
-       return NOTMUCH_FEATURES_V0;
-    else if (version == 1)
-       return NOTMUCH_FEATURES_V1;
-    else if (version == 2)
-       return NOTMUCH_FEATURES_V2;
-
-    /* Parse the features string */
-    while ((features = strtok_len_c (features + llen, "\n", &llen)) != NULL) {
-       flags = strchr (features, '\t');
-       if (! flags || flags > features + llen)
-           continue;
-       namelen = flags - features;
-
-       for (i = 0; i < ARRAY_SIZE (feature_names); ++i) {
-           if (strlen (feature_names[i].name) == namelen &&
-               strncmp (feature_names[i].name, features, namelen) == 0) {
-               res |= feature_names[i].value;
-               break;
-           }
-       }
-
-       if (i == ARRAY_SIZE (feature_names) && incompat_out) {
-           /* Unrecognized feature */
-           const char *have = strchr (flags, mode);
-           if (have && have < features + llen) {
-               /* This feature is required to access this database in
-                * 'mode', but we don't understand it. */
-               if (! *incompat_out)
-                   *incompat_out = talloc_strdup (ctx, "");
-               *incompat_out = talloc_asprintf_append_buffer (
-                   *incompat_out, "%s%.*s", **incompat_out ? ", " : "",
-                   namelen, features);
-           }
-       }
-    }
-
-    return res;
-}
-
-static char *
-_print_features (const void *ctx, unsigned int features)
-{
-    unsigned int i;
-    char *res = talloc_strdup (ctx, "");
-
-    for (i = 0; i < ARRAY_SIZE (feature_names); ++i)
-       if (features & feature_names[i].value)
-           res = talloc_asprintf_append_buffer (
-               res, "%s\t%s\n", feature_names[i].name, feature_names[i].flags);
-
-    return res;
-}
-
 notmuch_status_t
 notmuch_database_open (const char *path,
                       notmuch_database_mode_t mode,
@@ -1012,7 +898,7 @@ notmuch_database_open_verbose (const char *path,
 
        /* Check features. */
        incompat_features = NULL;
-       notmuch->features = _parse_features (
+       notmuch->features = _notmuch_database_parse_features (
            local, notmuch->xapian_db->get_metadata ("features").c_str (),
            version, mode == NOTMUCH_DATABASE_MODE_READ_WRITE ? 'w' : 'r',
            &incompat_features);
@@ -1674,7 +1560,7 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
     }
 
     status = NOTMUCH_STATUS_SUCCESS;
-    db->set_metadata ("features", _print_features (local, notmuch->features));
+    db->set_metadata ("features", _notmuch_database_print_features (local, 
notmuch->features));
     db->set_metadata ("version", STRINGIFY (NOTMUCH_DATABASE_VERSION));
 
   DONE:
diff --git a/lib/features.cc b/lib/features.cc
new file mode 100644
index 00000000..8def2461
--- /dev/null
+++ b/lib/features.cc
@@ -0,0 +1,114 @@
+#include "database-private.h"
+
+static const struct {
+    /* NOTMUCH_FEATURE_* value. */
+    _notmuch_features value;
+    /* Feature name as it appears in the database.  This name should
+     * be appropriate for displaying to the user if an older version
+     * of notmuch doesn't support this feature. */
+    const char *name;
+    /* Compatibility flags when this feature is declared. */
+    const char *flags;
+} feature_names[] = {
+    { NOTMUCH_FEATURE_FILE_TERMS,
+      "multiple paths per message", "rw" },
+    { NOTMUCH_FEATURE_DIRECTORY_DOCS,
+      "relative directory paths", "rw" },
+    /* Header values are not required for reading a database because a
+     * reader can just refer to the message file. */
+    { NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES,
+      "from/subject/message-ID in database", "w" },
+    { NOTMUCH_FEATURE_BOOL_FOLDER,
+      "exact folder:/path: search", "rw" },
+    { NOTMUCH_FEATURE_GHOSTS,
+      "mail documents for missing messages", "w" },
+    /* Knowledge of the index mime-types are not required for reading
+     * a database because a reader will just be unable to query
+     * them. */
+    { NOTMUCH_FEATURE_INDEXED_MIMETYPES,
+      "indexed MIME types", "w" },
+    { NOTMUCH_FEATURE_LAST_MOD,
+      "modification tracking", "w" },
+    /* Existing databases will work fine for all queries not involving
+     * 'body:' */
+    { NOTMUCH_FEATURE_UNPREFIX_BODY_ONLY,
+      "index body and headers separately", "w" },
+};
+
+char *
+_notmuch_database_print_features (const void *ctx, unsigned int features)
+{
+    unsigned int i;
+    char *res = talloc_strdup (ctx, "");
+
+    for (i = 0; i < ARRAY_SIZE (feature_names); ++i)
+       if (features & feature_names[i].value)
+           res = talloc_asprintf_append_buffer (
+               res, "%s\t%s\n", feature_names[i].name, feature_names[i].flags);
+
+    return res;
+}
+
+
+/* Parse a database features string from the given database version.
+ * Returns the feature bit set.
+ *
+ * For version < 3, this ignores the features string and returns a
+ * hard-coded set of features.
+ *
+ * If there are unrecognized features that are required to open the
+ * database in mode (which should be 'r' or 'w'), return a
+ * comma-separated list of unrecognized but required features in
+ * *incompat_out suitable for presenting to the user.  *incompat_out
+ * will be allocated from ctx.
+ */
+_notmuch_features
+_notmuch_database_parse_features (const void *ctx, const char *features, 
unsigned int version,
+                char mode, char **incompat_out)
+{
+    _notmuch_features res = static_cast<_notmuch_features>(0);
+    unsigned int namelen, i;
+    size_t llen = 0;
+    const char *flags;
+
+    /* Prior to database version 3, features were implied by the
+     * version number. */
+    if (version == 0)
+       return NOTMUCH_FEATURES_V0;
+    else if (version == 1)
+       return NOTMUCH_FEATURES_V1;
+    else if (version == 2)
+       return NOTMUCH_FEATURES_V2;
+
+    /* Parse the features string */
+    while ((features = strtok_len_c (features + llen, "\n", &llen)) != NULL) {
+       flags = strchr (features, '\t');
+       if (! flags || flags > features + llen)
+           continue;
+       namelen = flags - features;
+
+       for (i = 0; i < ARRAY_SIZE (feature_names); ++i) {
+           if (strlen (feature_names[i].name) == namelen &&
+               strncmp (feature_names[i].name, features, namelen) == 0) {
+               res |= feature_names[i].value;
+               break;
+           }
+       }
+
+       if (i == ARRAY_SIZE (feature_names) && incompat_out) {
+           /* Unrecognized feature */
+           const char *have = strchr (flags, mode);
+           if (have && have < features + llen) {
+               /* This feature is required to access this database in
+                * 'mode', but we don't understand it. */
+               if (! *incompat_out)
+                   *incompat_out = talloc_strdup (ctx, "");
+               *incompat_out = talloc_asprintf_append_buffer (
+                   *incompat_out, "%s%.*s", **incompat_out ? ", " : "",
+                   namelen, features);
+           }
+       }
+    }
+
+    return res;
+}
-- 
2.28.0
_______________________________________________
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org

Reply via email to