Re: [PATCH 5/8] string-list: add pos to iterator callback

2014-07-01 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 When we are running a string-list foreach or filter, the
 callback function sees only the string_list_item, along with
 a void* data pointer provided by the caller. This is
 sufficient for most purposes.

 However, it can also be useful to know the position of the
 item within the string (for example, if the data pointer

s/the string/-list/ (or s//_list/).

 points to a secondary array in which each element
 corresponds to part of the string list). We can help this
 use case by providing the position to each callback.

 Signed-off-by: Jeff King p...@peff.net
 ---
 The diff here is noisy, and I expect in the long run that the one caller
 I add to builtin/tag.c later in the series will eventually stop using
 string_list entirely (in favor of a custom struct), which may leave us
 with no callers that actually use the new field.

 I do think the logic above is sound, though, and it's a potentially
 useful thing. There may be other sites that avoid the for_each wrapper
 in favor of iterating themselves simply _because_ they needed to know
 the position (I would just do the same here, except that my new caller
 wants to use filter_string_list, which is a little more complicated).

While I can buy that some callers would want to learn the pos in the
list, I am not sure if this is a good direction to go.  Primarily, I
am having trouble sifting between want and need.

How often do callers want to do this?  If only narrow specialized
callers want this, is it unreasonable to ask them to add a int ctr
in their cb_data and use pos = ((struct theirs *)cb_data)-ctr++
in their callback instead?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/8] string-list: add pos to iterator callback

2014-07-01 Thread Jeff King
On Tue, Jul 01, 2014 at 10:45:19AM -0700, Junio C Hamano wrote:

 Jeff King p...@peff.net writes:
 
  When we are running a string-list foreach or filter, the
  callback function sees only the string_list_item, along with
  a void* data pointer provided by the caller. This is
  sufficient for most purposes.
 
  However, it can also be useful to know the position of the
  item within the string (for example, if the data pointer
 
 s/the string/-list/ (or s//_list/).

Thanks, yeah.

 While I can buy that some callers would want to learn the pos in the
 list, I am not sure if this is a good direction to go.  Primarily, I
 am having trouble sifting between want and need.
 
 How often do callers want to do this?  If only narrow specialized
 callers want this, is it unreasonable to ask them to add a int ctr
 in their cb_data and use pos = ((struct theirs *)cb_data)-ctr++
 in their callback instead?

Not all that often, I suppose (I only add one caller in this series). I
just found it a little hack-ish to force callers to keep their own
counter when we already have it (especially because it is not too hard
to get it wrong, for example by forgetting to increment the counter in
one code path of the callback).

Here's what the caller would look like without pos (done as a patch on
top of the series, so pos is still there, but no longer used).

diff --git a/builtin/tag.c b/builtin/tag.c
index f17192c..dc6f105 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -151,14 +151,20 @@ static int util_is_not_null(struct string_list_item *it, 
int pos, void *data)
return !!it-util;
 }
 
-static int matches_contains(struct string_list_item *it, int pos, void *data)
+struct contains_callback_data {
+   int ctr;
+   unsigned char *contains;
+};
+
+static int matches_contains(struct string_list_item *it, int pos, void *vdata)
 {
-   unsigned char *contains = data;
-   return contains[pos];
+   struct contains_callback_data *data = vdata;
+   return data-contains[data-ctr++];
 }
 
 static void limit_by_contains(struct string_list *tags, struct commit_list 
*with)
 {
+   struct contains_callback_data cbdata;
struct commit_list *tag_commits = NULL, **tail = tag_commits;
unsigned char *result;
int i;
@@ -180,7 +186,10 @@ static void limit_by_contains(struct string_list *tags, 
struct commit_list *with
 
result = xmalloc(tags-nr);
commit_contains(with, tag_commits, NULL, result);
-   filter_string_list(tags, 1, matches_contains, result);
+
+   cbdata.ctr = 0;
+   cbdata.contains = result;
+   filter_string_list(tags, 1, matches_contains, cbdata);
 
free(result);
free_commit_list(tag_commits);

So I think it's a small change in a lot of places rather than a kind of
ugly change in one spot.

All that being said, I think the real issue here is that I want more
than a string list (I am already using the util field for the sha1, but
this code would be potentially simpler if I could also store the commit
object). In the long run I hope to factor out a ref-listing API that can
be used by tag, branch, and for-each-ref. And then this string-list code
would go away in favor of a more expansive struct. So it may not be
worth worrying about keeping it too clean.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/8] string-list: add pos to iterator callback

2014-06-25 Thread Jeff King
When we are running a string-list foreach or filter, the
callback function sees only the string_list_item, along with
a void* data pointer provided by the caller. This is
sufficient for most purposes.

However, it can also be useful to know the position of the
item within the string (for example, if the data pointer
points to a secondary array in which each element
corresponds to part of the string list). We can help this
use case by providing the position to each callback.

Signed-off-by: Jeff King p...@peff.net
---
The diff here is noisy, and I expect in the long run that the one caller
I add to builtin/tag.c later in the series will eventually stop using
string_list entirely (in favor of a custom struct), which may leave us
with no callers that actually use the new field.

I do think the logic above is sound, though, and it's a potentially
useful thing. There may be other sites that avoid the for_each wrapper
in favor of iterating themselves simply _because_ they needed to know
the position (I would just do the same here, except that my new caller
wants to use filter_string_list, which is a little more complicated).

 builtin/clone.c|  2 +-
 builtin/remote.c   | 12 ++--
 notes.c|  1 +
 setup.c|  1 +
 string-list.c  |  6 +++---
 string-list.h  |  9 +++--
 test-path-utils.c  |  2 +-
 test-string-list.c |  2 +-
 8 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/builtin/clone.c b/builtin/clone.c
index b12989d..89d0709 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -227,7 +227,7 @@ static void strip_trailing_slashes(char *dir)
*end = '\0';
 }
 
-static int add_one_reference(struct string_list_item *item, void *cb_data)
+static int add_one_reference(struct string_list_item *item, int pos, void 
*cb_data)
 {
char *ref_git;
const char *repo;
diff --git a/builtin/remote.c b/builtin/remote.c
index c9102e8..bea0b58 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -925,7 +925,7 @@ struct show_info {
int any_rebase;
 };
 
-static int add_remote_to_show_info(struct string_list_item *item, void 
*cb_data)
+static int add_remote_to_show_info(struct string_list_item *item, int pos, 
void *cb_data)
 {
struct show_info *info = cb_data;
int n = strlen(item-string);
@@ -935,7 +935,7 @@ static int add_remote_to_show_info(struct string_list_item 
*item, void *cb_data)
return 0;
 }
 
-static int show_remote_info_item(struct string_list_item *item, void *cb_data)
+static int show_remote_info_item(struct string_list_item *item, int pos, void 
*cb_data)
 {
struct show_info *info = cb_data;
struct ref_states *states = info-states;
@@ -962,7 +962,7 @@ static int show_remote_info_item(struct string_list_item 
*item, void *cb_data)
return 0;
 }
 
-static int add_local_to_show_info(struct string_list_item *branch_item, void 
*cb_data)
+static int add_local_to_show_info(struct string_list_item *branch_item, int 
pos, void *cb_data)
 {
struct show_info *show_info = cb_data;
struct ref_states *states = show_info-states;
@@ -984,7 +984,7 @@ static int add_local_to_show_info(struct string_list_item 
*branch_item, void *cb
return 0;
 }
 
-static int show_local_info_item(struct string_list_item *item, void *cb_data)
+static int show_local_info_item(struct string_list_item *item, int pos, void 
*cb_data)
 {
struct show_info *show_info = cb_data;
struct branch_info *branch_info = item-util;
@@ -1016,7 +1016,7 @@ static int show_local_info_item(struct string_list_item 
*item, void *cb_data)
return 0;
 }
 
-static int add_push_to_show_info(struct string_list_item *push_item, void 
*cb_data)
+static int add_push_to_show_info(struct string_list_item *push_item, int pos, 
void *cb_data)
 {
struct show_info *show_info = cb_data;
struct push_info *push_info = push_item-util;
@@ -1045,7 +1045,7 @@ static int cmp_string_with_push(const void *va, const 
void *vb)
return cmp ? cmp : strcmp(a_push-dest, b_push-dest);
 }
 
-static int show_push_info_item(struct string_list_item *item, void *cb_data)
+static int show_push_info_item(struct string_list_item *item, int pos, void 
*cb_data)
 {
struct show_info *show_info = cb_data;
struct push_info *push_info = item-util;
diff --git a/notes.c b/notes.c
index 5fe691d..f7a84f9 100644
--- a/notes.c
+++ b/notes.c
@@ -881,6 +881,7 @@ static int string_list_add_note_lines(struct string_list 
*list,
 }
 
 static int string_list_join_lines_helper(struct string_list_item *item,
+int pos,
 void *cb_data)
 {
struct strbuf *buf = cb_data;
diff --git a/setup.c b/setup.c
index 0a22f8b..0fe92fe 100644
--- a/setup.c
+++ b/setup.c
@@ -586,6 +586,7 @@ static dev_t get_device_or_die(const char *path, const char 
*prefix, int prefix_
  * subsequent entries.
  */
 static int