[PATCH 29/36] lib/config: make values iterators restartable

Subject: [PATCH 29/36] lib/config: make values iterators restartable

Date: Sun, 3 Jan 2021 19:35:40 -0400

To: notmuch@notmuchmail.org

Cc: David Bremner

From: David Bremner


This is relatively cheap, and makes it easier to transform existing
code which uses arrays of pointers to store configuration lists.
---
 lib/config.cc          | 41 ++++++++++++++++++++++++++++++++---------
 lib/notmuch.h          | 12 ++++++++++++
 test/T590-libconfig.sh | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 76 insertions(+), 9 deletions(-)

diff --git a/lib/config.cc b/lib/config.cc
index 47160af1..7a1494be 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -34,6 +34,8 @@ struct _notmuch_config_list {
 struct _notmuch_config_values {
     const char *iterator;
     size_t tok_len;
+    const char *string;
+    void *children; /* talloc_context */
 };
 
 static const char * _notmuch_config_key_to_string (notmuch_config_key_t key);
@@ -256,23 +258,33 @@ _notmuch_config_load_from_database (notmuch_database_t *notmuch)
 notmuch_config_values_t *
 notmuch_config_get_values (notmuch_database_t *notmuch, notmuch_config_key_t key)
 {
-    notmuch_config_values_t *values;
+    notmuch_config_values_t *values = NULL;
+    bool ok = false;
 
-    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;
+	goto DONE;
 
     values = talloc (notmuch, notmuch_config_values_t);
     if (unlikely(! values))
-	return NULL;
+	goto DONE;
+
+    values->children = talloc_new (values);
+
+    values->string = _notmuch_string_map_get (notmuch->config, key_str);
+    if (! values->string)
+	goto DONE;
+
+    values->iterator = strsplit_len (values->string, ';', &(values->tok_len));
+    ok = true;
 
-    values->iterator = strsplit_len (str, ';', &(values->tok_len));
+ DONE:
+    if (!ok) {
+	if (values)
+	    talloc_free(values);
+	return NULL;
+    }
     return values;
 }
 
@@ -289,6 +301,17 @@ notmuch_config_values_get (notmuch_config_values_t *values) {
     return talloc_strndup (values, values->iterator, values->tok_len);
 }
 
+void
+notmuch_config_values_start (notmuch_config_values_t *values) {
+    if (values->children) {
+	talloc_free (values->children);
+    }
+
+    values->children = talloc_new (values);
+
+    values->iterator = strsplit_len (values->string, ';', &(values->tok_len));
+}
+
 void
 notmuch_config_values_move_to_next (notmuch_config_values_t *values) {
     values->iterator += values->tok_len;
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 95b2180f..527dbee6 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -2522,6 +2522,18 @@ notmuch_config_values_get (notmuch_config_values_t *values);
 void
 notmuch_config_values_move_to_next (notmuch_config_values_t *values);
 
+
+/**
+ * reset the 'values' iterator to the first element
+ *
+ * @param[in,out] values iterator
+ *
+ * @since libnotmuch 5.4 (notmuch 0.32)
+ *
+ */
+void
+notmuch_config_values_start (notmuch_config_values_t *values);
+
 /**
  * Destroy a config values iterator, along with any associated
  * resources.
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 24f03ba7..97f8fdc7 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -224,6 +224,38 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 restore_database
 
+test_begin_subtest "notmuch_config_get_values (restart)"
+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));
+    }
+    for (notmuch_config_values_start (values);
+	 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
+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%
-- 
2.29.2
_______________________________________________
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-leave@notmuchmail.org

Thread: