From: David Bremner <david@tethera.net>
To: notmuch@notmuchmail.org
Cc: David Bremner <david@tethera.net>
Subject: [PATCH 12/36] lib/config: add config values iterator
Date: Sun, 3 Jan 2021 19:35:23 -0400 [thread overview]
Message-ID: <20210103233547.122707-13-david@tethera.net> (raw)
In-Reply-To: <20210103233547.122707-1-david@tethera.net>
This is intended to avoid duplicating the string splitting and
traversal code for all clients of the config API.
---
lib/config.cc | 52 ++++++++++++++++++++++++++++++++++
lib/notmuch.h | 64 ++++++++++++++++++++++++++++++++++++++++++
notmuch.c | 35 +++++++++++++++++++----
test/T590-libconfig.sh | 48 ++++++++++++++++++++++++++++++-
4 files changed, 192 insertions(+), 7 deletions(-)
diff --git a/lib/config.cc b/lib/config.cc
index f6d9bf44..4500fe1a 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -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)
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 5c35b44b..7aeff567 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -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.
*
diff --git a/notmuch.c b/notmuch.c
index fd4a7945..e0649048 100644
--- 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,
+ ¬much,
+ &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)
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 0c7398a2..6eaec101 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -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));
--
2.29.2
next prev parent reply other threads:[~2021-01-03 23:38 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-03 23:35 v3 merged config David Bremner
2021-01-03 23:35 ` [PATCH 01/36] test/T750-gzip: don't compress the xapian database David Bremner
2021-01-10 15:28 ` Tomi Ollila
2021-01-11 0:57 ` David Bremner
2021-01-11 17:40 ` Tomi Ollila
2021-01-03 23:35 ` [PATCH 02/36] test/T391-python-cffi David Bremner
2021-01-10 15:33 ` Tomi Ollila
2021-01-15 11:51 ` David Bremner
2021-01-15 11:53 ` David Bremner
2021-01-15 17:07 ` Tomi Ollila
2021-01-03 23:35 ` [PATCH 03/36] lib: add _notmuch_string_map_set David Bremner
2021-01-03 23:35 ` [PATCH 04/36] lib: cache configuration information from database David Bremner
2021-01-03 23:35 ` [PATCH 05/36] lib: add stub for notmuch_database_open_with_config David Bremner
2021-01-03 23:35 ` [PATCH 06/36] lib/open: add support for config profiles and default locations David Bremner
2021-01-03 23:35 ` [PATCH 07/36] CLI: generalize notmuch_config_mode_t David Bremner
2021-01-03 23:35 ` [PATCH 08/36] lib/config: add notmuch_config_key_{get,set} David Bremner
2021-01-03 23:35 ` [PATCH 09/36] lib/open: load default values for known configuration keys David Bremner
2021-01-03 23:35 ` [PATCH 10/36] CLI: add (unused) database argument to subcommands David Bremner
2021-01-03 23:35 ` [PATCH 11/36] util: add strsplit_len: simplified strtok with delimiter escaping David Bremner
2021-01-03 23:35 ` David Bremner [this message]
2021-01-03 23:35 ` [PATCH 13/36] CLI/count: switch to new configuration framework David Bremner
2021-01-03 23:35 ` [PATCH 14/36] cli/dump: convert to new config framework David Bremner
2021-01-03 23:35 ` [PATCH 15/36] lib: add notmuch_config_get_bool David Bremner
2021-01-03 23:35 ` [PATCH 16/36] CLI/restore: convert to new config framework David Bremner
2021-01-03 23:35 ` [PATCH 17/36] CLI/insert: " David Bremner
2021-01-03 23:35 ` [PATCH 18/36] cli/reindex: convert " David Bremner
2021-01-03 23:35 ` [PATCH 19/36] CLI/reply: convert to " David Bremner
2021-01-03 23:35 ` [PATCH 20/36] CLI/{search,address}: convert to new configuration framework David Bremner
2021-01-03 23:35 ` [PATCH 21/36] cli/config: add accessor for config file name David Bremner
2021-01-03 23:35 ` [PATCH 22/36] CLI/show: mostly switch show to new config framework David Bremner
2021-01-03 23:35 ` [PATCH 23/36] cli/tag: convert " David Bremner
2021-01-03 23:35 ` [PATCH 24/36] lib/config: add _notmuch_config_cache David Bremner
2021-01-03 23:35 ` [PATCH 25/36] lib: split notmuch_database_compact David Bremner
2021-01-03 23:35 ` [PATCH 26/36] cli/compact: convert to new configuration framework David Bremner
2021-01-03 23:35 ` [PATCH 27/36] bindings/notmuch2: add missing crypto error status codes David Bremner
2021-01-03 23:35 ` [PATCH 28/36] lib/config: add NOTMUCH_CONFIG_NEW_IGNORE David Bremner
2021-01-03 23:35 ` [PATCH 29/36] lib/config: make values iterators restartable David Bremner
2021-01-03 23:35 ` [PATCH 30/36] lib/open: factor out first part of open David Bremner
2021-01-03 23:35 ` [PATCH 31/36] lib: add NOTMUCH_STATUS_NO_CONFIG David Bremner
2021-01-03 23:35 ` [PATCH 32/36] lib/database: move n_d_create* to open.cc David Bremner
2021-01-03 23:35 ` [PATCH 33/36] lib: add NOTMUCH_STATUS_DATABASE_EXISTS David Bremner
2021-01-03 23:35 ` [PATCH 34/36] lib: introduce notmuch_database_create_with_config David Bremner
2021-01-03 23:35 ` [PATCH 35/36] cli/new: refactor database upgrade code David Bremner
2021-01-03 23:35 ` [PATCH 36/36] cli/new: convert to new config framework David Bremner
2021-01-06 2:48 ` v3 merged config David Bremner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://notmuchmail.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210103233547.122707-13-david@tethera.net \
--to=david@tethera.net \
--cc=notmuch@notmuchmail.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhetil.org/notmuch.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).