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