sha1_array: let callbacks interrupt iteration
authorJeff King <peff@peff.net>
Mon, 26 Sep 2016 12:00:29 +0000 (08:00 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 26 Sep 2016 18:46:41 +0000 (11:46 -0700)
The callbacks for iterating a sha1_array must have a void
return. This is unlike our usual for_each semantics, where
a callback may interrupt iteration and have its value
propagated. Let's switch it to the usual form, which will
enable its use in more places (e.g., where we are replacing
an existing iteration with a different data structure).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/technical/api-sha1-array.txt
builtin/cat-file.c
builtin/receive-pack.c
sha1-array.c
sha1-array.h
submodule.c
t/helper/test-sha1-array.c
index 3e75497a37d696d534c16ff0270a808b57ac9180..dcc52943a5da7dbbfe8d42cdcc7d593ec1ba1416 100644 (file)
@@ -38,16 +38,20 @@ Functions
 `sha1_array_for_each_unique`::
        Efficiently iterate over each unique element of the list,
        executing the callback function for each one. If the array is
-       not sorted, this function has the side effect of sorting it.
+       not sorted, this function has the side effect of sorting it. If
+       the callback returns a non-zero value, the iteration ends
+       immediately and the callback's return is propagated; otherwise,
+       0 is returned.
 
 Examples
 --------
 
 -----------------------------------------
-void print_callback(const unsigned char sha1[20],
+int print_callback(const unsigned char sha1[20],
                    void *data)
 {
        printf("%s\n", sha1_to_hex(sha1));
+       return 0; /* always continue */
 }
 
 void some_func(void)
index 94e67ebb7eec087390cfecc5c4371a974401d602..cca97a86c0b1d1029936184f72ed6a20e97da759 100644 (file)
@@ -401,11 +401,12 @@ struct object_cb_data {
        struct expand_data *expand;
 };
 
-static void batch_object_cb(const unsigned char sha1[20], void *vdata)
+static int batch_object_cb(const unsigned char sha1[20], void *vdata)
 {
        struct object_cb_data *data = vdata;
        hashcpy(data->expand->oid.hash, sha1);
        batch_object_write(NULL, data->opt, data->expand);
+       return 0;
 }
 
 static int batch_loose_object(const unsigned char *sha1,
index 896b16f2cceba73a44529f3b3d4f6ecdc33e892c..f7cd1802524e2ba41a41d6479e69534dc042b404 100644 (file)
@@ -268,9 +268,10 @@ static int show_ref_cb(const char *path_full, const struct object_id *oid,
        return 0;
 }
 
-static void show_one_alternate_sha1(const unsigned char sha1[20], void *unused)
+static int show_one_alternate_sha1(const unsigned char sha1[20], void *unused)
 {
        show_ref(".have", sha1);
+       return 0;
 }
 
 static void collect_one_alternate_ref(const struct ref *ref, void *data)
index 6f4a2246c9a912d06cf1a6995e07bf2008ec749d..af1d7d560d303f6a04ff1029909782c7969a655c 100644 (file)
@@ -42,7 +42,7 @@ void sha1_array_clear(struct sha1_array *array)
        array->sorted = 0;
 }
 
-void sha1_array_for_each_unique(struct sha1_array *array,
+int sha1_array_for_each_unique(struct sha1_array *array,
                                for_each_sha1_fn fn,
                                void *data)
 {
@@ -52,8 +52,12 @@ void sha1_array_for_each_unique(struct sha1_array *array,
                sha1_array_sort(array);
 
        for (i = 0; i < array->nr; i++) {
+               int ret;
                if (i > 0 && !hashcmp(array->sha1[i], array->sha1[i-1]))
                        continue;
-               fn(array->sha1[i], data);
+               ret = fn(array->sha1[i], data);
+               if (ret)
+                       return ret;
        }
+       return 0;
 }
index 72bb33bec6c173633c2b5cd04db57b562fa23a9e..b3230be0dd6eedf871c5c337a79333a7ebf33cb7 100644 (file)
@@ -14,10 +14,10 @@ void sha1_array_append(struct sha1_array *array, const unsigned char *sha1);
 int sha1_array_lookup(struct sha1_array *array, const unsigned char *sha1);
 void sha1_array_clear(struct sha1_array *array);
 
-typedef void (*for_each_sha1_fn)(const unsigned char sha1[20],
-                                void *data);
-void sha1_array_for_each_unique(struct sha1_array *array,
-                               for_each_sha1_fn fn,
+typedef int (*for_each_sha1_fn)(const unsigned char sha1[20],
                                void *data);
+int sha1_array_for_each_unique(struct sha1_array *array,
+                              for_each_sha1_fn fn,
+                              void *data);
 
 #endif /* SHA1_ARRAY_H */
index 0ef2ff4321d1723d05e9328e564313437ec8476e..aba94dd07dbd5c8d1e9cad5b3980bb4a9759e6cf 100644 (file)
@@ -728,9 +728,10 @@ void check_for_new_submodule_commits(unsigned char new_sha1[20])
        sha1_array_append(&ref_tips_after_fetch, new_sha1);
 }
 
-static void add_sha1_to_argv(const unsigned char sha1[20], void *data)
+static int add_sha1_to_argv(const unsigned char sha1[20], void *data)
 {
        argv_array_push(data, sha1_to_hex(sha1));
+       return 0;
 }
 
 static void calculate_changed_submodule_paths(void)
index 09f77909716326bdb76a79d3c32d10b74702e1d5..f7a53c4ad64c18903f53c5bd1d4766f54bc22e49 100644 (file)
@@ -1,9 +1,10 @@
 #include "cache.h"
 #include "sha1-array.h"
 
-static void print_sha1(const unsigned char sha1[20], void *data)
+static int print_sha1(const unsigned char sha1[20], void *data)
 {
        puts(sha1_to_hex(sha1));
+       return 0;
 }
 
 int cmd_main(int argc, const char **argv)