]> git.cworth.org Git - notmuch/commitdiff
lib/config: add config values iterator
authorDavid Bremner <david@tethera.net>
Sat, 8 Aug 2020 14:16:49 +0000 (11:16 -0300)
committerDavid Bremner <david@tethera.net>
Sat, 6 Feb 2021 23:08:12 +0000 (19:08 -0400)
This is intended to avoid duplicating the string splitting and
traversal code for all clients of the config API.

lib/config.cc
lib/notmuch.h
notmuch.c
test/T590-libconfig.sh

index a6b75913017087c441935b12d1ebef94a7a1ad76..0fe9a26823c3dfa4e1cc9c4369b54c3ccf3ff2c0 100644 (file)
@@ -31,6 +31,11 @@ struct _notmuch_config_list {
     char *current_val;
 };
 
+struct _notmuch_config_values {
+    const char *iterator;
+    size_t tok_len;
+};
+
 static const char * _notmuch_config_key_to_string (notmuch_config_key_t key);
 
 static int
@@ -248,6 +253,53 @@ _notmuch_config_load_from_database (notmuch_database_t *notmuch)
     return status;
 }
 
+notmuch_config_values_t *
+notmuch_config_get_values (notmuch_database_t *notmuch, notmuch_config_key_t key)
+{
+    notmuch_config_values_t *values;
+
+    const char *str;
+    const char *key_str = _notmuch_config_key_to_string (key);
+
+    if (! key_str)
+       return NULL;
+
+    str  = _notmuch_string_map_get (notmuch->config, key_str);
+    if (! str)
+       return NULL;
+
+    values = talloc (notmuch, notmuch_config_values_t);
+    if (unlikely(! values))
+       return NULL;
+
+    values->iterator = strsplit_len (str, ';', &(values->tok_len));
+    return values;
+}
+
+notmuch_bool_t
+notmuch_config_values_valid (notmuch_config_values_t *values) {
+    if (! values)
+       return false;
+
+    return (values->iterator != NULL);
+}
+
+const char *
+notmuch_config_values_get (notmuch_config_values_t *values) {
+    return talloc_strndup (values, values->iterator, values->tok_len);
+}
+
+void
+notmuch_config_values_move_to_next (notmuch_config_values_t *values) {
+    values->iterator += values->tok_len;
+    values->iterator = strsplit_len (values->iterator, ';', &(values->tok_len));
+}
+
+void
+notmuch_config_values_destroy (notmuch_config_values_t *values) {
+    talloc_free (values);
+}
+
 notmuch_status_t
 _notmuch_config_load_from_file (notmuch_database_t *notmuch,
                                GKeyFile *file)
index 5c35b44b812ac678a76892e892a051d58adf7a30..7aeff56743b2e392012d5c4b58dad0f9bad3cce9 100644 (file)
@@ -236,6 +236,7 @@ typedef struct _notmuch_tags notmuch_tags_t;
 typedef struct _notmuch_directory notmuch_directory_t;
 typedef struct _notmuch_filenames notmuch_filenames_t;
 typedef struct _notmuch_config_list notmuch_config_list_t;
+typedef struct _notmuch_config_values notmuch_config_values_t;
 typedef struct _notmuch_indexopts notmuch_indexopts_t;
 #endif /* __DOXYGEN__ */
 
@@ -2456,6 +2457,69 @@ notmuch_config_get (notmuch_database_t *notmuch, notmuch_config_key_t key);
 notmuch_status_t
 notmuch_config_set (notmuch_database_t *notmuch, notmuch_config_key_t key, const char *val);
 
+/**
+ * Returns an iterator for a ';'-delimited list of configuration values
+ *
+ * These values reflect all configuration information given at the
+ * time the database was opened.
+ *
+ * @param[in] notmuch database
+ * @param[in] key configuration key
+ *
+ * @since libnotmuch 5.4 (notmuch 0.32)
+ *
+ * @retval NULL in case of error.
+ */
+notmuch_config_values_t *
+notmuch_config_get_values (notmuch_database_t *notmuch, notmuch_config_key_t key);
+
+/**
+ * Is the given 'config_values' iterator pointing at a valid element.
+ *
+ * @param[in] values iterator
+ *
+ * @since libnotmuch 5.4 (notmuch 0.32)
+ *
+ * @retval FALSE if passed a NULL pointer, or the iterator is exhausted.
+ *
+ */
+notmuch_bool_t
+notmuch_config_values_valid (notmuch_config_values_t *values);
+
+/**
+ * Get the current value from the 'values' iterator
+ *
+ * @param[in] values iterator
+ *
+ * @since libnotmuch 5.4 (notmuch 0.32)
+ *
+ * @retval a string with the same lifetime as the iterator
+ */
+const char *
+notmuch_config_values_get (notmuch_config_values_t *values);
+
+/**
+ * Move the 'values' iterator to the next element
+ *
+ * @param[in,out] values iterator
+ *
+ * @since libnotmuch 5.4 (notmuch 0.32)
+ *
+ */
+void
+notmuch_config_values_move_to_next (notmuch_config_values_t *values);
+
+/**
+ * Destroy a config values iterator, along with any associated
+ * resources.
+ *
+ * @param[in,out] values iterator
+ *
+ * @since libnotmuch 5.4 (notmuch 0.32)
+ */
+void
+notmuch_config_values_destroy (notmuch_config_values_t *values);
+
 /**
  * get the current default indexing options for a given database.
  *
index fd4a7945e7b61ee90589e670261717c352306514..e06490487abd38ea642a6f687d756278125dc5d7 100644 (file)
--- a/notmuch.c
+++ b/notmuch.c
@@ -457,6 +457,7 @@ main (int argc, char *argv[])
     command_t *command;
     const char *config_file_name = NULL;
     notmuch_config_t *config = NULL;
+    notmuch_database_t *notmuch = NULL;
     int opt_index;
     int ret;
 
@@ -500,13 +501,35 @@ main (int argc, char *argv[])
        goto DONE;
     }
 
-    config = notmuch_config_open (local, config_file_name, command->mode);
-    if (! config) {
-       ret = EXIT_FAILURE;
-       goto DONE;
-    }
+    if (command->mode & NOTMUCH_COMMAND_DATABASE_EARLY) {
+       char *status_string = NULL;
+       notmuch_database_mode_t mode;
+       if (command->mode & NOTMUCH_COMMAND_DATABASE_WRITE)
+           mode = NOTMUCH_DATABASE_MODE_READ_WRITE;
+       else
+           mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
+
+       if (notmuch_database_open_with_config (NULL,
+                                              mode,
+                                              config_file_name,
+                                              NULL,
+                                              &notmuch,
+                                              &status_string)) {
+           if (status_string) {
+               fputs (status_string, stderr);
+               free (status_string);
+           }
 
-    ret = (command->function)(config, NULL, argc - opt_index, argv + opt_index);
+           return EXIT_FAILURE;
+       }
+    } else {
+       config = notmuch_config_open (local, config_file_name, command->mode);
+       if (! config) {
+           ret = EXIT_FAILURE;
+           goto DONE;
+       }
+    }
+    ret = (command->function)(config, notmuch, argc - opt_index, argv + opt_index);
 
   DONE:
     if (config)
index 0c148ad9b4af283a1c8f404e0cef5da7cd621018..efbee61d67d7ab393d1f3967d00b72bc6b163926 100755 (executable)
@@ -201,9 +201,55 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 restore_database
 
+test_begin_subtest "notmuch_config_get_values"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
+{
+    notmuch_config_values_t *values;
+    EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, "a;b;c"));
+    for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
+        notmuch_config_values_valid (values);
+        notmuch_config_values_move_to_next (values))
+    {
+         puts (notmuch_config_values_get (values));
+    }
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+a
+b
+c
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
+backup_database
+test_begin_subtest "notmuch_config_get_values, trailing ;"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
+{
+    notmuch_config_values_t *values;
+    EXPECT0(notmuch_config_set (db, NOTMUCH_CONFIG_NEW_TAGS, "a;b;c"));
+    for (values = notmuch_config_get_values (db, NOTMUCH_CONFIG_NEW_TAGS);
+        notmuch_config_values_valid (values);
+        notmuch_config_values_move_to_next (values))
+    {
+         puts (notmuch_config_values_get (values));
+    }
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+a
+b
+c
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
 backup_database
 test_begin_subtest "get config by key"
-notmuch config set test.key1 overridden
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG}
 {
    printf("before = %s\n", notmuch_config_get (db, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS));