From 16ddcd403bdd74f47f3ae1a7e58a01e36e54a7d7 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 26 Sep 2016 08:00:29 -0400 Subject: [PATCH] sha1_array: let callbacks interrupt iteration 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 Signed-off-by: Junio C Hamano --- Documentation/technical/api-sha1-array.txt | 8 ++++++-- builtin/cat-file.c | 3 ++- builtin/receive-pack.c | 3 ++- sha1-array.c | 8 ++++++-- sha1-array.h | 8 ++++---- submodule.c | 3 ++- t/helper/test-sha1-array.c | 3 ++- 7 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Documentation/technical/api-sha1-array.txt b/Documentation/technical/api-sha1-array.txt index 3e75497a37d..dcc52943a5d 100644 --- a/Documentation/technical/api-sha1-array.txt +++ b/Documentation/technical/api-sha1-array.txt @@ -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) diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 94e67ebb7ee..cca97a86c0b 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -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, diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 896b16f2cce..f7cd1802524 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -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) diff --git a/sha1-array.c b/sha1-array.c index 6f4a2246c9a..af1d7d560d3 100644 --- a/sha1-array.c +++ b/sha1-array.c @@ -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; } diff --git a/sha1-array.h b/sha1-array.h index 72bb33bec6c..b3230be0dd6 100644 --- a/sha1-array.h +++ b/sha1-array.h @@ -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 */ diff --git a/submodule.c b/submodule.c index 0ef2ff4321d..aba94dd07db 100644 --- a/submodule.c +++ b/submodule.c @@ -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) diff --git a/t/helper/test-sha1-array.c b/t/helper/test-sha1-array.c index 09f77909716..f7a53c4ad64 100644 --- a/t/helper/test-sha1-array.c +++ b/t/helper/test-sha1-array.c @@ -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)