{"thread":{"id":"41433","subject":"[PATCH v6 01/11] ref-filter: use string_list_split over strbuf_split","startedAt":"2016-02-17T18:06:08Z","lastAt":"2016-02-18T14:19:28Z","messageCount":18,"participants":["Karthik Nayak","Eric Sunshine","Jeff King","Junio C Hamano"],"isPatch":true,"patchVersion":6,"patchTotal":11},"messages":[{"id":"278473","messageId":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":null,"subject":"[PATCH v6 00/11] ref-filter: use parsing functions","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:08Z","receivedAt":"2016-02-17T18:06:08Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"This series cleans up populate_value() in ref-filter, by moving out\nthe parsing part of atoms to separate parsing functions. This ensures\nthat parsing is only done once and also improves the modularity of the\ncode.\n\nv1: http://thread.gmane.org/gmane.comp.version-control.git/281180\nv2: http://thread.gmane.org/gmane.comp.version-control.git/282563\nv3: http://thread.gmane.org/gmane.comp.version-control.git/283350\nv4: http://thread.gmane.org/gmane.comp.version-control.git/285158\nv5: http://thread.gmane.org/gmane.comp.version-control.git/286414\n\nChanges:\n* As per Jeff's suggestion ($gmane/286425) we drop creation and\nusage of strbuf_split_str_omit_term() and use string_list_split()\ninstead.\n\nJeff King (1):\n  ref-filter: use string_list_split over strbuf_split\n\nKarthik Nayak (10):\n  ref-filter: bump 'used_atom' and related code to the top\n  ref-filter: introduce struct used_atom\n  ref-filter: introduce parsing functions for each valid atom\n  ref-filter: introduce color_atom_parser()\n  ref-filter: introduce parse_align_position()\n  ref-filter: introduce align_atom_parser()\n  ref-filter: align: introduce long-form syntax\n  ref-filter: introduce remote_ref_atom_parser()\n  ref-filter: introduce contents_atom_parser()\n  ref-filter: introduce objectname_atom_parser()\n\n Documentation/git-for-each-ref.txt |  20 +-\n ref-filter.c                       | 434 +++++++++++++++++++++----------------\n t/t6302-for-each-ref-filter.sh     |  42 ++++\n 3 files changed, 304 insertions(+), 192 deletions(-)\n\nInterdiff:\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 21f4937..d13d002 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -127,18 +127,19 @@ static align_type parse_align_position(const char *s)\n static void align_atom_parser(struct used_atom *atom, const char *arg)\n {\n \tstruct align *align = &atom->u.align;\n-\tstruct strbuf **v, **to_free;\n+\tstruct string_list params = STRING_LIST_INIT_DUP;\n+\tint i;\n \tunsigned int width = ~0U;\n \n \tif (!arg)\n \t\tdie(_(\"expected format: %%(align:<width>,<position>)\"));\n-\tv = to_free = strbuf_split_str_omit_term(arg, ',', 0);\n \n \talign->position = ALIGN_LEFT;\n \n-\twhile (*v) {\n+\tstring_list_split(&params, arg, ',', -1);\n+\tfor (i = 0; i < params.nr; i++) {\n+\t\tconst char *s = params.items[i].string;\n \t\tint position;\n-\t\tconst char *s = v[0]->buf;\n \n \t\tif (skip_prefix(s, \"position=\", &s)) {\n \t\t\tposition = parse_align_position(s);\n@@ -154,13 +155,12 @@ static void align_atom_parser(struct used_atom *atom, const char *arg)\n \t\t\talign->position = position;\n \t\telse\n \t\t\tdie(_(\"unrecognized %%(align) argument: %s\"), s);\n-\t\tv++;\n \t}\n \n \tif (width == ~0U)\n \t\tdie(_(\"positive width expected with the %%(align) atom\"));\n \talign->width = width;\n-\tstrbuf_list_free(to_free);\n+\tstring_list_clear(&params, 0);\n }\n \n static struct {\ndiff --git a/strbuf.c b/strbuf.c\nindex 4a93e2a..bab316d 100644\n--- a/strbuf.c\n+++ b/strbuf.c\n@@ -115,7 +115,7 @@ void strbuf_tolower(struct strbuf *sb)\n }\n \n struct strbuf **strbuf_split_buf(const char *str, size_t slen,\n-\t\t\t\t int terminator, int max, int omit_term)\n+\t\t\t\t int terminator, int max)\n {\n \tstruct strbuf **ret = NULL;\n \tsize_t nr = 0, alloc = 0;\n@@ -123,18 +123,14 @@ struct strbuf **strbuf_split_buf(const char *str, size_t slen,\n \n \twhile (slen) {\n \t\tint len = slen;\n-\t\tint copylen = len;\n-\t\tconst char *end = NULL;\n \t\tif (max <= 0 || nr + 1 < max) {\n-\t\t\tend = memchr(str, terminator, slen);\n-\t\t\tif (end) {\n+\t\t\tconst char *end = memchr(str, terminator, slen);\n+\t\t\tif (end)\n \t\t\t\tlen = end - str + 1;\n-\t\t\t\tcopylen = len - !!omit_term;\n-\t\t\t}\n \t\t}\n \t\tt = xmalloc(sizeof(struct strbuf));\n-\t\tstrbuf_init(t, copylen);\n-\t\tstrbuf_add(t, str, copylen);\n+\t\tstrbuf_init(t, len);\n+\t\tstrbuf_add(t, str, len);\n \t\tALLOC_GROW(ret, nr + 2, alloc);\n \t\tret[nr++] = t;\n \t\tstr += len;\ndiff --git a/strbuf.h b/strbuf.h\nindex 6115e72..f72fd14 100644\n--- a/strbuf.h\n+++ b/strbuf.h\n@@ -466,12 +466,11 @@ static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix)\n /**\n  * Split str (of length slen) at the specified terminator character.\n  * Return a null-terminated array of pointers to strbuf objects\n- * holding the substrings.  If omit_term is true, the terminator will\n- * be stripped from all substrings. Otherwise, substrings will include\n- * the terminator, except for the final substring, if the original\n- * string lacked a terminator.  If max is positive, then split the\n- * string into at most max substrings (with the last substring\n- * containing everything following the (max-1)th terminator\n+ * holding the substrings.  The substrings include the terminator,\n+ * except for the last substring, which might be unterminated if the\n+ * original string did not end with a terminator.  If max is positive,\n+ * then split the string into at most max substrings (with the last\n+ * substring containing everything following the (max-1)th terminator\n  * character).\n  *\n  * The most generic form is `strbuf_split_buf`, which takes an arbitrary\n@@ -482,25 +481,19 @@ static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix)\n  * For lighter-weight alternatives, see string_list_split() and\n  * string_list_split_in_place().\n  */\n-extern struct strbuf **strbuf_split_buf(const char *str, size_t slen,\n-\t\t\t\t\tint terminator, int max, int omit_term);\n-\n-static inline struct strbuf **strbuf_split_str_omit_term(const char *str,\n-\t\t\t\t\t\t\t    int terminator, int max)\n-{\n-\treturn strbuf_split_buf(str, strlen(str), terminator, max, 1);\n-}\n+extern struct strbuf **strbuf_split_buf(const char *, size_t,\n+\t\t\t\t\tint terminator, int max);\n \n static inline struct strbuf **strbuf_split_str(const char *str,\n \t\t\t\t\t       int terminator, int max)\n {\n-\treturn strbuf_split_buf(str, strlen(str), terminator, max, 0);\n+\treturn strbuf_split_buf(str, strlen(str), terminator, max);\n }\n \n static inline struct strbuf **strbuf_split_max(const struct strbuf *sb,\n \t\t\t\t\t\tint terminator, int max)\n {\n-\treturn strbuf_split_buf(sb->buf, sb->len, terminator, max, 0);\n+\treturn strbuf_split_buf(sb->buf, sb->len, terminator, max);\n }\n \n static inline struct strbuf **strbuf_split(const struct strbuf *sb,\n\n\n-- \n2.7.1\n"},{"id":"278472","messageId":"1455732379-22479-2-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","subject":"[PATCH v6 01/11] ref-filter: use string_list_split over strbuf_split","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:09Z","receivedAt":"2016-02-17T18:06:09Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"From: Jeff King <peff@peff.net>\n\nWe don't do any post-processing on the resulting strbufs, so it is\nsimpler to just use string_list_split, which takes care of removing\nthe delimiter for us.\n\nWritten-by: Jeff King <peff@peff.net>\nSigned-off-by: Karthik Nayak <Karthik.188@gmail.com>\n---\n ref-filter.c | 29 +++++++++++------------------\n 1 file changed, 11 insertions(+), 18 deletions(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex f097176..19367ce 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -886,41 +886,34 @@ static void populate_value(struct ref_array_item *ref)\n \t\t\tcontinue;\n \t\t} else if (match_atom_name(name, \"align\", &valp)) {\n \t\t\tstruct align *align = &v->u.align;\n-\t\t\tstruct strbuf **s, **to_free;\n+\t\t\tstruct string_list params = STRING_LIST_INIT_DUP;\n+\t\t\tint i;\n \t\t\tint width = -1;\n \n \t\t\tif (!valp)\n \t\t\t\tdie(_(\"expected format: %%(align:<width>,<position>)\"));\n \n-\t\t\t/*\n-\t\t\t * TODO: Implement a function similar to strbuf_split_str()\n-\t\t\t * which would omit the separator from the end of each value.\n-\t\t\t */\n-\t\t\ts = to_free = strbuf_split_str(valp, ',', 0);\n-\n \t\t\talign->position = ALIGN_LEFT;\n \n-\t\t\twhile (*s) {\n-\t\t\t\t/*  Strip trailing comma */\n-\t\t\t\tif (s[1])\n-\t\t\t\t\tstrbuf_setlen(s[0], s[0]->len - 1);\n-\t\t\t\tif (!strtoul_ui(s[0]->buf, 10, (unsigned int *)&width))\n+\t\t\tstring_list_split(&params, valp, ',', -1);\n+\t\t\tfor (i = 0; i < params.nr; i++) {\n+\t\t\t\tconst char *s = params.items[i].string;\n+\t\t\t\tif (!strtoul_ui(s, 10, (unsigned int *)&width))\n \t\t\t\t\t;\n-\t\t\t\telse if (!strcmp(s[0]->buf, \"left\"))\n+\t\t\t\telse if (!strcmp(s, \"left\"))\n \t\t\t\t\talign->position = ALIGN_LEFT;\n-\t\t\t\telse if (!strcmp(s[0]->buf, \"right\"))\n+\t\t\t\telse if (!strcmp(s, \"right\"))\n \t\t\t\t\talign->position = ALIGN_RIGHT;\n-\t\t\t\telse if (!strcmp(s[0]->buf, \"middle\"))\n+\t\t\t\telse if (!strcmp(s, \"middle\"))\n \t\t\t\t\talign->position = ALIGN_MIDDLE;\n \t\t\t\telse\n-\t\t\t\t\tdie(_(\"improper format entered align:%s\"), s[0]->buf);\n-\t\t\t\ts++;\n+\t\t\t\t\tdie(_(\"improper format entered align:%s\"), s);\n \t\t\t}\n \n \t\t\tif (width < 0)\n \t\t\t\tdie(_(\"positive width expected with the %%(align) atom\"));\n \t\t\talign->width = width;\n-\t\t\tstrbuf_list_free(to_free);\n+\t\t\tstring_list_clear(&params, 0);\n \t\t\tv->handler = align_atom_handler;\n \t\t\tcontinue;\n \t\t} else if (!strcmp(name, \"end\")) {\n-- \n2.7.1\n"},{"id":"278474","messageId":"1455732379-22479-3-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","subject":"[PATCH v6 02/11] ref-filter: bump 'used_atom' and related code to the top","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:10Z","receivedAt":"2016-02-17T18:06:10Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Bump code to the top for usage in further patches.\n\nSigned-off-by: Karthik Nayak <Karthik.188@gmail.com>\n---\n ref-filter.c | 30 +++++++++++++++---------------\n 1 file changed, 15 insertions(+), 15 deletions(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 19367ce..6a73c5b 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -16,6 +16,21 @@\n \n typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;\n \n+/*\n+ * An atom is a valid field atom listed below, possibly prefixed with\n+ * a \"*\" to denote deref_tag().\n+ *\n+ * We parse given format string and sort specifiers, and make a list\n+ * of properties that we need to extract out of objects.  ref_array_item\n+ * structure will hold an array of values extracted that can be\n+ * indexed with the \"atom number\", which is an index into this\n+ * array.\n+ */\n+static const char **used_atom;\n+static cmp_type *used_atom_type;\n+static int used_atom_cnt, need_tagged, need_symref;\n+static int need_color_reset_at_eol;\n+\n static struct {\n \tconst char *name;\n \tcmp_type cmp_type;\n@@ -92,21 +107,6 @@ struct atom_value {\n };\n \n /*\n- * An atom is a valid field atom listed above, possibly prefixed with\n- * a \"*\" to denote deref_tag().\n- *\n- * We parse given format string and sort specifiers, and make a list\n- * of properties that we need to extract out of objects.  ref_array_item\n- * structure will hold an array of values extracted that can be\n- * indexed with the \"atom number\", which is an index into this\n- * array.\n- */\n-static const char **used_atom;\n-static cmp_type *used_atom_type;\n-static int used_atom_cnt, need_tagged, need_symref;\n-static int need_color_reset_at_eol;\n-\n-/*\n  * Used to parse format string and sort specifiers\n  */\n int parse_ref_filter_atom(const char *atom, const char *ep)\n-- \n2.7.1\n"},{"id":"278475","messageId":"1455732379-22479-4-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","subject":"[PATCH v6 03/11] ref-filter: introduce struct used_atom","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:11Z","receivedAt":"2016-02-17T18:06:11Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Introduce the 'used_atom' structure to replace the existing\nimplementation of 'used_atom' (which is a list of atoms). This helps\nus parse atoms beforehand and store required details into the\n'used_atom' for future usage.\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Karthik Nayak <Karthik.188@gmail.com>\n---\n ref-filter.c | 35 ++++++++++++++++++-----------------\n 1 file changed, 18 insertions(+), 17 deletions(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 6a73c5b..8139709 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -26,8 +26,10 @@ typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;\n  * indexed with the \"atom number\", which is an index into this\n  * array.\n  */\n-static const char **used_atom;\n-static cmp_type *used_atom_type;\n+static struct used_atom {\n+\tconst char *name;\n+\tcmp_type type;\n+} *used_atom;\n static int used_atom_cnt, need_tagged, need_symref;\n static int need_color_reset_at_eol;\n \n@@ -122,8 +124,8 @@ int parse_ref_filter_atom(const char *atom, const char *ep)\n \n \t/* Do we have the atom already used elsewhere? */\n \tfor (i = 0; i < used_atom_cnt; i++) {\n-\t\tint len = strlen(used_atom[i]);\n-\t\tif (len == ep - atom && !memcmp(used_atom[i], atom, len))\n+\t\tint len = strlen(used_atom[i].name);\n+\t\tif (len == ep - atom && !memcmp(used_atom[i].name, atom, len))\n \t\t\treturn i;\n \t}\n \n@@ -150,12 +152,11 @@ int parse_ref_filter_atom(const char *atom, const char *ep)\n \tat = used_atom_cnt;\n \tused_atom_cnt++;\n \tREALLOC_ARRAY(used_atom, used_atom_cnt);\n-\tREALLOC_ARRAY(used_atom_type, used_atom_cnt);\n-\tused_atom[at] = xmemdupz(atom, ep - atom);\n-\tused_atom_type[at] = valid_atom[i].cmp_type;\n+\tused_atom[at].name = xmemdupz(atom, ep - atom);\n+\tused_atom[at].type = valid_atom[i].cmp_type;\n \tif (*atom == '*')\n \t\tneed_tagged = 1;\n-\tif (!strcmp(used_atom[at], \"symref\"))\n+\tif (!strcmp(used_atom[at].name, \"symref\"))\n \t\tneed_symref = 1;\n \treturn at;\n }\n@@ -315,7 +316,7 @@ int verify_ref_format(const char *format)\n \t\tat = parse_ref_filter_atom(sp + 2, ep);\n \t\tcp = ep + 1;\n \n-\t\tif (skip_prefix(used_atom[at], \"color:\", &color))\n+\t\tif (skip_prefix(used_atom[at].name, \"color:\", &color))\n \t\t\tneed_color_reset_at_eol = !!strcmp(color, \"reset\");\n \t}\n \treturn 0;\n@@ -359,7 +360,7 @@ static void grab_common_values(struct atom_value *val, int deref, struct object\n \tint i;\n \n \tfor (i = 0; i < used_atom_cnt; i++) {\n-\t\tconst char *name = used_atom[i];\n+\t\tconst char *name = used_atom[i].name;\n \t\tstruct atom_value *v = &val[i];\n \t\tif (!!deref != (*name == '*'))\n \t\t\tcontinue;\n@@ -383,7 +384,7 @@ static void grab_tag_values(struct atom_value *val, int deref, struct object *ob\n \tstruct tag *tag = (struct tag *) obj;\n \n \tfor (i = 0; i < used_atom_cnt; i++) {\n-\t\tconst char *name = used_atom[i];\n+\t\tconst char *name = used_atom[i].name;\n \t\tstruct atom_value *v = &val[i];\n \t\tif (!!deref != (*name == '*'))\n \t\t\tcontinue;\n@@ -405,7 +406,7 @@ static void grab_commit_values(struct atom_value *val, int deref, struct object\n \tstruct commit *commit = (struct commit *) obj;\n \n \tfor (i = 0; i < used_atom_cnt; i++) {\n-\t\tconst char *name = used_atom[i];\n+\t\tconst char *name = used_atom[i].name;\n \t\tstruct atom_value *v = &val[i];\n \t\tif (!!deref != (*name == '*'))\n \t\t\tcontinue;\n@@ -535,7 +536,7 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru\n \tconst char *wholine = NULL;\n \n \tfor (i = 0; i < used_atom_cnt; i++) {\n-\t\tconst char *name = used_atom[i];\n+\t\tconst char *name = used_atom[i].name;\n \t\tstruct atom_value *v = &val[i];\n \t\tif (!!deref != (*name == '*'))\n \t\t\tcontinue;\n@@ -573,7 +574,7 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru\n \tif (!wholine)\n \t\treturn;\n \tfor (i = 0; i < used_atom_cnt; i++) {\n-\t\tconst char *name = used_atom[i];\n+\t\tconst char *name = used_atom[i].name;\n \t\tstruct atom_value *v = &val[i];\n \t\tif (!!deref != (*name == '*'))\n \t\t\tcontinue;\n@@ -663,7 +664,7 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj\n \tunsigned long sublen = 0, bodylen = 0, nonsiglen = 0, siglen = 0;\n \n \tfor (i = 0; i < used_atom_cnt; i++) {\n-\t\tconst char *name = used_atom[i];\n+\t\tconst char *name = used_atom[i].name;\n \t\tstruct atom_value *v = &val[i];\n \t\tconst char *valp = NULL;\n \t\tif (!!deref != (*name == '*'))\n@@ -809,7 +810,7 @@ static void populate_value(struct ref_array_item *ref)\n \n \t/* Fill in specials first */\n \tfor (i = 0; i < used_atom_cnt; i++) {\n-\t\tconst char *name = used_atom[i];\n+\t\tconst char *name = used_atom[i].name;\n \t\tstruct atom_value *v = &ref->value[i];\n \t\tint deref = 0;\n \t\tconst char *refname;\n@@ -1464,7 +1465,7 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru\n {\n \tstruct atom_value *va, *vb;\n \tint cmp;\n-\tcmp_type cmp_type = used_atom_type[s->atom];\n+\tcmp_type cmp_type = used_atom[s->atom].type;\n \n \tget_ref_atom_value(a, s->atom, &va);\n \tget_ref_atom_value(b, s->atom, &vb);\n-- \n2.7.1\n"},{"id":"278477","messageId":"1455732379-22479-5-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","subject":"[PATCH v6 04/11] ref-filter: introduce parsing functions for each valid atom","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:12Z","receivedAt":"2016-02-17T18:06:12Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Parsing atoms is done in populate_value(), this is repetitive and\nhence expensive. Introduce a parsing function which would let us parse\natoms beforehand and store the required details into the 'used_atom'\nstructure for further usage.\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nHelped-by: Ramsay Jones <ramsay@ramsayjones.plus.com>\nHelped-by: Andreas Schwab <schwab@linux-m68k.org>\nSigned-off-by: Karthik Nayak <Karthik.188@gmail.com>\n---\n ref-filter.c | 14 ++++++++++----\n 1 file changed, 10 insertions(+), 4 deletions(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 8139709..8a34ba1 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -36,6 +36,7 @@ static int need_color_reset_at_eol;\n static struct {\n \tconst char *name;\n \tcmp_type cmp_type;\n+\tvoid (*parser)(struct used_atom *atom, const char *arg);\n } valid_atom[] = {\n \t{ \"refname\" },\n \t{ \"objecttype\" },\n@@ -114,6 +115,7 @@ struct atom_value {\n int parse_ref_filter_atom(const char *atom, const char *ep)\n {\n \tconst char *sp;\n+\tconst char *arg;\n \tint i, at;\n \n \tsp = atom;\n@@ -132,16 +134,16 @@ int parse_ref_filter_atom(const char *atom, const char *ep)\n \t/* Is the atom a valid one? */\n \tfor (i = 0; i < ARRAY_SIZE(valid_atom); i++) {\n \t\tint len = strlen(valid_atom[i].name);\n+\n \t\t/*\n \t\t * If the atom name has a colon, strip it and everything after\n \t\t * it off - it specifies the format for this entry, and\n \t\t * shouldn't be used for checking against the valid_atom\n \t\t * table.\n \t\t */\n-\t\tconst char *formatp = strchr(sp, ':');\n-\t\tif (!formatp || ep < formatp)\n-\t\t\tformatp = ep;\n-\t\tif (len == formatp - sp && !memcmp(valid_atom[i].name, sp, len))\n+\t\targ = memchr(sp, ':', ep - sp);\n+\t\tif (len == (arg ? arg : ep) - sp &&\n+\t\t    !memcmp(valid_atom[i].name, sp, len))\n \t\t\tbreak;\n \t}\n \n@@ -154,6 +156,10 @@ int parse_ref_filter_atom(const char *atom, const char *ep)\n \tREALLOC_ARRAY(used_atom, used_atom_cnt);\n \tused_atom[at].name = xmemdupz(atom, ep - atom);\n \tused_atom[at].type = valid_atom[i].cmp_type;\n+\tif (arg)\n+\t\targ = used_atom[at].name + (arg - atom) + 1;\n+\tif (valid_atom[i].parser)\n+\t\tvalid_atom[i].parser(&used_atom[at], arg);\n \tif (*atom == '*')\n \t\tneed_tagged = 1;\n \tif (!strcmp(used_atom[at].name, \"symref\"))\n-- \n2.7.1\n"},{"id":"278476","messageId":"1455732379-22479-6-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","subject":"[PATCH v6 05/11] ref-filter: introduce color_atom_parser()","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:13Z","receivedAt":"2016-02-17T18:06:13Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Introduce color_atom_parser() which will parse a \"color\" atom and\nstore its color in the \"used_atom\" structure for further usage in\npopulate_value().\n\nHelped-by: Ramsay Jones <ramsay@ramsayjones.plus.com>\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Karthik Nayak <Karthik.188@gmail.com>\n---\n ref-filter.c | 25 ++++++++++++++++---------\n 1 file changed, 16 insertions(+), 9 deletions(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 8a34ba1..c90d2f4 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -29,10 +29,21 @@ typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;\n static struct used_atom {\n \tconst char *name;\n \tcmp_type type;\n+\tunion {\n+\t\tchar color[COLOR_MAXLEN];\n+\t} u;\n } *used_atom;\n static int used_atom_cnt, need_tagged, need_symref;\n static int need_color_reset_at_eol;\n \n+static void color_atom_parser(struct used_atom *atom, const char *color_value)\n+{\n+\tif (!color_value)\n+\t\tdie(_(\"expected format: %%(color:<color>)\"));\n+\tif (color_parse(color_value, atom->u.color) < 0)\n+\t\tdie(_(\"unrecognized color: %%(color:%s)\"), color_value);\n+}\n+\n static struct {\n \tconst char *name;\n \tcmp_type cmp_type;\n@@ -70,7 +81,7 @@ static struct {\n \t{ \"symref\" },\n \t{ \"flag\" },\n \t{ \"HEAD\" },\n-\t{ \"color\" },\n+\t{ \"color\", FIELD_STR, color_atom_parser },\n \t{ \"align\" },\n \t{ \"end\" },\n };\n@@ -158,6 +169,7 @@ int parse_ref_filter_atom(const char *atom, const char *ep)\n \tused_atom[at].type = valid_atom[i].cmp_type;\n \tif (arg)\n \t\targ = used_atom[at].name + (arg - atom) + 1;\n+\tmemset(&used_atom[at].u, 0, sizeof(used_atom[at].u));\n \tif (valid_atom[i].parser)\n \t\tvalid_atom[i].parser(&used_atom[at], arg);\n \tif (*atom == '*')\n@@ -816,6 +828,7 @@ static void populate_value(struct ref_array_item *ref)\n \n \t/* Fill in specials first */\n \tfor (i = 0; i < used_atom_cnt; i++) {\n+\t\tstruct used_atom *atom = &used_atom[i];\n \t\tconst char *name = used_atom[i].name;\n \t\tstruct atom_value *v = &ref->value[i];\n \t\tint deref = 0;\n@@ -856,14 +869,8 @@ static void populate_value(struct ref_array_item *ref)\n \t\t\trefname = branch_get_push(branch, NULL);\n \t\t\tif (!refname)\n \t\t\t\tcontinue;\n-\t\t} else if (match_atom_name(name, \"color\", &valp)) {\n-\t\t\tchar color[COLOR_MAXLEN] = \"\";\n-\n-\t\t\tif (!valp)\n-\t\t\t\tdie(_(\"expected format: %%(color:<color>)\"));\n-\t\t\tif (color_parse(valp, color) < 0)\n-\t\t\t\tdie(_(\"unable to parse format\"));\n-\t\t\tv->s = xstrdup(color);\n+\t\t} else if (starts_with(name, \"color:\")) {\n+\t\t\tv->s = atom->u.color;\n \t\t\tcontinue;\n \t\t} else if (!strcmp(name, \"flag\")) {\n \t\t\tchar buf[256], *cp = buf;\n-- \n2.7.1\n"},{"id":"278482","messageId":"1455732379-22479-7-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","subject":"[PATCH v6 06/11] ref-filter: introduce parse_align_position()","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:14Z","receivedAt":"2016-02-17T18:06:14Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":">From populate_value() extract parse_align_position() which given a\nstring would give us the alignment position. This is a preparatory\npatch as to introduce prefixes for the %(align) atom and avoid\nredundancy in the code.\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Karthik Nayak <Karthik.188@gmail.com>\n---\n ref-filter.c | 21 +++++++++++++++------\n 1 file changed, 15 insertions(+), 6 deletions(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex c90d2f4..e8b076d 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -44,6 +44,17 @@ static void color_atom_parser(struct used_atom *atom, const char *color_value)\n \t\tdie(_(\"unrecognized color: %%(color:%s)\"), color_value);\n }\n \n+static align_type parse_align_position(const char *s)\n+{\n+\tif (!strcmp(s, \"right\"))\n+\t\treturn ALIGN_RIGHT;\n+\telse if (!strcmp(s, \"middle\"))\n+\t\treturn ALIGN_MIDDLE;\n+\telse if (!strcmp(s, \"left\"))\n+\t\treturn ALIGN_LEFT;\n+\treturn -1;\n+}\n+\n static struct {\n \tconst char *name;\n \tcmp_type cmp_type;\n@@ -912,14 +923,12 @@ static void populate_value(struct ref_array_item *ref)\n \t\t\tstring_list_split(&params, valp, ',', -1);\n \t\t\tfor (i = 0; i < params.nr; i++) {\n \t\t\t\tconst char *s = params.items[i].string;\n+\t\t\t\tint position;\n+\n \t\t\t\tif (!strtoul_ui(s, 10, (unsigned int *)&width))\n \t\t\t\t\t;\n-\t\t\t\telse if (!strcmp(s, \"left\"))\n-\t\t\t\t\talign->position = ALIGN_LEFT;\n-\t\t\t\telse if (!strcmp(s, \"right\"))\n-\t\t\t\t\talign->position = ALIGN_RIGHT;\n-\t\t\t\telse if (!strcmp(s, \"middle\"))\n-\t\t\t\t\talign->position = ALIGN_MIDDLE;\n+\t\t\t\telse if ((position = parse_align_position(s)) >= 0)\n+\t\t\t\t\talign->position = position;\n \t\t\t\telse\n \t\t\t\t\tdie(_(\"improper format entered align:%s\"), s);\n \t\t\t}\n-- \n2.7.1\n"},{"id":"278479","messageId":"1455732379-22479-8-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","subject":"[PATCH v6 07/11] ref-filter: introduce align_atom_parser()","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:15Z","receivedAt":"2016-02-17T18:06:15Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Introduce align_atom_parser() which will parse an 'align' atom and\nstore the required alignment position and width in the 'used_atom'\nstructure for further usage in populate_value().\n\nSince this patch removes the last usage of match_atom_name(), remove\nthe function from ref-filter.c.\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nHelped-by: Jeff King <peff@peff.net>\nHelped-by: Ramsay Jones <ramsay@ramsayjones.plus.com>\nSigned-off-by: Karthik Nayak <Karthik.188@gmail.com>\n---\n ref-filter.c | 91 ++++++++++++++++++++++++++----------------------------------\n 1 file changed, 40 insertions(+), 51 deletions(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex e8b076d..797f9fe 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -16,6 +16,11 @@\n \n typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;\n \n+struct align {\n+\talign_type position;\n+\tunsigned int width;\n+};\n+\n /*\n  * An atom is a valid field atom listed below, possibly prefixed with\n  * a \"*\" to denote deref_tag().\n@@ -31,6 +36,7 @@ static struct used_atom {\n \tcmp_type type;\n \tunion {\n \t\tchar color[COLOR_MAXLEN];\n+\t\tstruct align align;\n \t} u;\n } *used_atom;\n static int used_atom_cnt, need_tagged, need_symref;\n@@ -55,6 +61,37 @@ static align_type parse_align_position(const char *s)\n \treturn -1;\n }\n \n+static void align_atom_parser(struct used_atom *atom, const char *arg)\n+{\n+\tstruct align *align = &atom->u.align;\n+\tstruct string_list params = STRING_LIST_INIT_DUP;\n+\tint i;\n+\tunsigned int width = ~0U;\n+\n+\tif (!arg)\n+\t\tdie(_(\"expected format: %%(align:<width>,<position>)\"));\n+\n+\talign->position = ALIGN_LEFT;\n+\n+\tstring_list_split(&params, arg, ',', -1);\n+\tfor (i = 0; i < params.nr; i++) {\n+\t\tconst char *s = params.items[i].string;\n+\t\tint position;\n+\n+\t\tif (!strtoul_ui(s, 10, &width))\n+\t\t\t;\n+\t\telse if ((position = parse_align_position(s)) >= 0)\n+\t\t\talign->position = position;\n+\t\telse\n+\t\t\tdie(_(\"unrecognized %%(align) argument: %s\"), s);\n+\t}\n+\n+\tif (width == ~0U)\n+\t\tdie(_(\"positive width expected with the %%(align) atom\"));\n+\talign->width = width;\n+\tstring_list_clear(&params, 0);\n+}\n+\n static struct {\n \tconst char *name;\n \tcmp_type cmp_type;\n@@ -93,17 +130,12 @@ static struct {\n \t{ \"flag\" },\n \t{ \"HEAD\" },\n \t{ \"color\", FIELD_STR, color_atom_parser },\n-\t{ \"align\" },\n+\t{ \"align\", FIELD_STR, align_atom_parser },\n \t{ \"end\" },\n };\n \n #define REF_FORMATTING_STATE_INIT  { 0, NULL }\n \n-struct align {\n-\talign_type position;\n-\tunsigned int width;\n-};\n-\n struct contents {\n \tunsigned int lines;\n \tstruct object_id oid;\n@@ -288,22 +320,6 @@ static void end_atom_handler(struct atom_value *atomv, struct ref_formatting_sta\n \tpop_stack_element(&state->stack);\n }\n \n-static int match_atom_name(const char *name, const char *atom_name, const char **val)\n-{\n-\tconst char *body;\n-\n-\tif (!skip_prefix(name, atom_name, &body))\n-\t\treturn 0; /* doesn't even begin with \"atom_name\" */\n-\tif (!body[0]) {\n-\t\t*val = NULL; /* %(atom_name) and no customization */\n-\t\treturn 1;\n-\t}\n-\tif (body[0] != ':')\n-\t\treturn 0; /* \"atom_namefoo\" is not \"atom_name\" or \"atom_name:...\" */\n-\t*val = body + 1; /* \"atom_name:val\" */\n-\treturn 1;\n-}\n-\n /*\n  * In a format string, find the next occurrence of %(atom).\n  */\n@@ -845,7 +861,6 @@ static void populate_value(struct ref_array_item *ref)\n \t\tint deref = 0;\n \t\tconst char *refname;\n \t\tconst char *formatp;\n-\t\tconst char *valp;\n \t\tstruct branch *branch = NULL;\n \n \t\tv->handler = append_atom;\n@@ -909,34 +924,8 @@ static void populate_value(struct ref_array_item *ref)\n \t\t\telse\n \t\t\t\tv->s = \" \";\n \t\t\tcontinue;\n-\t\t} else if (match_atom_name(name, \"align\", &valp)) {\n-\t\t\tstruct align *align = &v->u.align;\n-\t\t\tstruct string_list params = STRING_LIST_INIT_DUP;\n-\t\t\tint i;\n-\t\t\tint width = -1;\n-\n-\t\t\tif (!valp)\n-\t\t\t\tdie(_(\"expected format: %%(align:<width>,<position>)\"));\n-\n-\t\t\talign->position = ALIGN_LEFT;\n-\n-\t\t\tstring_list_split(&params, valp, ',', -1);\n-\t\t\tfor (i = 0; i < params.nr; i++) {\n-\t\t\t\tconst char *s = params.items[i].string;\n-\t\t\t\tint position;\n-\n-\t\t\t\tif (!strtoul_ui(s, 10, (unsigned int *)&width))\n-\t\t\t\t\t;\n-\t\t\t\telse if ((position = parse_align_position(s)) >= 0)\n-\t\t\t\t\talign->position = position;\n-\t\t\t\telse\n-\t\t\t\t\tdie(_(\"improper format entered align:%s\"), s);\n-\t\t\t}\n-\n-\t\t\tif (width < 0)\n-\t\t\t\tdie(_(\"positive width expected with the %%(align) atom\"));\n-\t\t\talign->width = width;\n-\t\t\tstring_list_clear(&params, 0);\n+\t\t} else if (starts_with(name, \"align\")) {\n+\t\t\tv->u.align = atom->u.align;\n \t\t\tv->handler = align_atom_handler;\n \t\t\tcontinue;\n \t\t} else if (!strcmp(name, \"end\")) {\n-- \n2.7.1\n"},{"id":"278480","messageId":"1455732379-22479-9-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","subject":"[PATCH v6 08/11] ref-filter: align: introduce long-form syntax","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:16Z","receivedAt":"2016-02-17T18:06:16Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Introduce optional prefixes \"width=\" and \"position=\" for the align atom\nso that the atom can be used as \"%(align:width=<width>,position=<position>)\".\n\nAdd Documentation and tests for the same.\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Karthik Nayak <Karthik.188@gmail.com>\n---\n Documentation/git-for-each-ref.txt | 20 ++++++++++--------\n ref-filter.c                       | 10 ++++++++-\n t/t6302-for-each-ref-filter.sh     | 42 ++++++++++++++++++++++++++++++++++++++\n 3 files changed, 63 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt\nindex 2e3e96f..012e8f9 100644\n--- a/Documentation/git-for-each-ref.txt\n+++ b/Documentation/git-for-each-ref.txt\n@@ -133,14 +133,18 @@ color::\n \n align::\n \tLeft-, middle-, or right-align the content between\n-\t%(align:...) and %(end). The \"align:\" is followed by `<width>`\n-\tand `<position>` in any order separated by a comma, where the\n-\t`<position>` is either left, right or middle, default being\n-\tleft and `<width>` is the total length of the content with\n-\talignment. If the contents length is more than the width then\n-\tno alignment is performed. If used with '--quote' everything\n-\tin between %(align:...) and %(end) is quoted, but if nested\n-\tthen only the topmost level performs quoting.\n+\t%(align:...) and %(end). The \"align:\" is followed by\n+\t`width=<width>` and `position=<position>` in any order\n+\tseparated by a comma, where the `<position>` is either left,\n+\tright or middle, default being left and `<width>` is the total\n+\tlength of the content with alignment. For brevity, the\n+\t\"width=\" and/or \"position=\" prefixes may be omitted, and bare\n+\t<width> and <position> used instead.  For instance,\n+\t`%(align:<width>,<position>)`. If the contents length is more\n+\tthan the width then no alignment is performed. If used with\n+\t'--quote' everything in between %(align:...) and %(end) is\n+\tquoted, but if nested then only the topmost level performs\n+\tquoting.\n \n In addition to the above, for commit and tag objects, the header\n field names (`tree`, `parent`, `object`, `type`, and `tag`) can\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 797f9fe..2255dcc 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -78,7 +78,15 @@ static void align_atom_parser(struct used_atom *atom, const char *arg)\n \t\tconst char *s = params.items[i].string;\n \t\tint position;\n \n-\t\tif (!strtoul_ui(s, 10, &width))\n+\t\tif (skip_prefix(s, \"position=\", &s)) {\n+\t\t\tposition = parse_align_position(s);\n+\t\t\tif (position < 0)\n+\t\t\t\tdie(_(\"unrecognized position:%s\"), s);\n+\t\t\talign->position = position;\n+\t\t} else if (skip_prefix(s, \"width=\", &s)) {\n+\t\t\tif (strtoul_ui(s, 10, &width))\n+\t\t\t\tdie(_(\"unrecognized width:%s\"), s);\n+\t\t} else if (!strtoul_ui(s, 10, &width))\n \t\t\t;\n \t\telse if ((position = parse_align_position(s)) >= 0)\n \t\t\talign->position = position;\ndiff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh\nindex fe4796c..bcf472b 100755\n--- a/t/t6302-for-each-ref-filter.sh\n+++ b/t/t6302-for-each-ref-filter.sh\n@@ -133,6 +133,48 @@ test_expect_success 'right alignment' '\n \ttest_cmp expect actual\n '\n \n+cat >expect <<-\\EOF\n+|       refname is refs/heads/master       |refs/heads/master\n+|        refname is refs/heads/side        |refs/heads/side\n+|         refname is refs/odd/spot         |refs/odd/spot\n+|     refname is refs/tags/double-tag      |refs/tags/double-tag\n+|        refname is refs/tags/four         |refs/tags/four\n+|         refname is refs/tags/one         |refs/tags/one\n+|     refname is refs/tags/signed-tag      |refs/tags/signed-tag\n+|        refname is refs/tags/three        |refs/tags/three\n+|         refname is refs/tags/two         |refs/tags/two\n+EOF\n+\n+test_align_permutations() {\n+\twhile read -r option\n+\tdo\n+\t\ttest_expect_success \"align:$option\" '\n+\t\t\tgit for-each-ref --format=\"|%(align:$option)refname is %(refname)%(end)|%(refname)\" >actual &&\n+\t\t\ttest_cmp expect actual\n+\t\t'\n+\tdone\n+}\n+\n+test_align_permutations <<-\\EOF\n+\tmiddle,42\n+\t42,middle\n+\tposition=middle,42\n+\t42,position=middle\n+\tmiddle,width=42\n+\twidth=42,middle\n+\tposition=middle,width=42\n+\twidth=42,position=middle\n+EOF\n+\n+# Last one wins (silently) when multiple arguments of the same type are given\n+\n+test_align_permutations <<-\\EOF\n+\t32,width=42,middle\n+\twidth=30,42,middle\n+\twidth=42,position=right,middle\n+\t42,right,position=middle\n+EOF\n+\n # Individual atoms inside %(align:...) and %(end) must not be quoted.\n \n test_expect_success 'alignment with format quote' \"\n-- \n2.7.1\n"},{"id":"278478","messageId":"1455732379-22479-10-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","subject":"[PATCH v6 09/11] ref-filter: introduce remote_ref_atom_parser()","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:17Z","receivedAt":"2016-02-17T18:06:17Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Introduce remote_ref_atom_parser() which will parse the '%(upstream)'\nand '%(push)' atoms and store information into the 'used_atom'\nstructure based on the modifiers used along with the corresponding\natom.\n\nHelped-by: Ramsay Jones <ramsay@ramsayjones.plus.com>\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Karthik Nayak <Karthik.188@gmail.com>\n---\n ref-filter.c | 103 +++++++++++++++++++++++++++++++++++------------------------\n 1 file changed, 61 insertions(+), 42 deletions(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 2255dcc..7df5085 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -37,6 +37,8 @@ static struct used_atom {\n \tunion {\n \t\tchar color[COLOR_MAXLEN];\n \t\tstruct align align;\n+\t\tenum { RR_NORMAL, RR_SHORTEN, RR_TRACK, RR_TRACKSHORT }\n+\t\t\tremote_ref;\n \t} u;\n } *used_atom;\n static int used_atom_cnt, need_tagged, need_symref;\n@@ -50,6 +52,20 @@ static void color_atom_parser(struct used_atom *atom, const char *color_value)\n \t\tdie(_(\"unrecognized color: %%(color:%s)\"), color_value);\n }\n \n+static void remote_ref_atom_parser(struct used_atom *atom, const char *arg)\n+{\n+\tif (!arg)\n+\t\tatom->u.remote_ref = RR_NORMAL;\n+\telse if (!strcmp(arg, \"short\"))\n+\t\tatom->u.remote_ref = RR_SHORTEN;\n+\telse if (!strcmp(arg, \"track\"))\n+\t\tatom->u.remote_ref = RR_TRACK;\n+\telse if (!strcmp(arg, \"trackshort\"))\n+\t\tatom->u.remote_ref = RR_TRACKSHORT;\n+\telse\n+\t\tdie(_(\"unrecognized format: %%(%s)\"), atom->name);\n+}\n+\n static align_type parse_align_position(const char *s)\n {\n \tif (!strcmp(s, \"right\"))\n@@ -132,8 +148,8 @@ static struct {\n \t{ \"subject\" },\n \t{ \"body\" },\n \t{ \"contents\" },\n-\t{ \"upstream\" },\n-\t{ \"push\" },\n+\t{ \"upstream\", FIELD_STR, remote_ref_atom_parser },\n+\t{ \"push\", FIELD_STR, remote_ref_atom_parser },\n \t{ \"symref\" },\n \t{ \"flag\" },\n \t{ \"HEAD\" },\n@@ -840,6 +856,43 @@ static const char *strip_ref_components(const char *refname, const char *nr_arg)\n \treturn start;\n }\n \n+static void fill_remote_ref_details(struct used_atom *atom, const char *refname,\n+\t\t\t\t    struct branch *branch, const char **s)\n+{\n+\tint num_ours, num_theirs;\n+\tif (atom->u.remote_ref == RR_SHORTEN)\n+\t\t*s = shorten_unambiguous_ref(refname, warn_ambiguous_refs);\n+\telse if (atom->u.remote_ref == RR_TRACK) {\n+\t\tif (stat_tracking_info(branch, &num_ours,\n+\t\t\t\t       &num_theirs, NULL))\n+\t\t\treturn;\n+\n+\t\tif (!num_ours && !num_theirs)\n+\t\t\t*s = \"\";\n+\t\telse if (!num_ours)\n+\t\t\t*s = xstrfmt(\"[behind %d]\", num_theirs);\n+\t\telse if (!num_theirs)\n+\t\t\t*s = xstrfmt(\"[ahead %d]\", num_ours);\n+\t\telse\n+\t\t\t*s = xstrfmt(\"[ahead %d, behind %d]\",\n+\t\t\t\t     num_ours, num_theirs);\n+\t} else if (atom->u.remote_ref == RR_TRACKSHORT) {\n+\t\tif (stat_tracking_info(branch, &num_ours,\n+\t\t\t\t       &num_theirs, NULL))\n+\t\t\treturn;\n+\n+\t\tif (!num_ours && !num_theirs)\n+\t\t\t*s = \"=\";\n+\t\telse if (!num_ours)\n+\t\t\t*s = \"<\";\n+\t\telse if (!num_theirs)\n+\t\t\t*s = \">\";\n+\t\telse\n+\t\t\t*s = \"<>\";\n+\t} else /* RR_NORMAL */\n+\t\t*s = refname;\n+}\n+\n /*\n  * Parse the object referred by ref, and grab needed value.\n  */\n@@ -891,8 +944,9 @@ static void populate_value(struct ref_array_item *ref)\n \t\t\tbranch = branch_get(branch_name);\n \n \t\t\trefname = branch_get_upstream(branch, NULL);\n-\t\t\tif (!refname)\n-\t\t\t\tcontinue;\n+\t\t\tif (refname)\n+\t\t\t\tfill_remote_ref_details(atom, refname, branch, &v->s);\n+\t\t\tcontinue;\n \t\t} else if (starts_with(name, \"push\")) {\n \t\t\tconst char *branch_name;\n \t\t\tif (!skip_prefix(ref->refname, \"refs/heads/\",\n@@ -903,6 +957,8 @@ static void populate_value(struct ref_array_item *ref)\n \t\t\trefname = branch_get_push(branch, NULL);\n \t\t\tif (!refname)\n \t\t\t\tcontinue;\n+\t\t\tfill_remote_ref_details(atom, refname, branch, &v->s);\n+\t\t\tcontinue;\n \t\t} else if (starts_with(name, \"color:\")) {\n \t\t\tv->s = atom->u.color;\n \t\t\tcontinue;\n@@ -944,7 +1000,6 @@ static void populate_value(struct ref_array_item *ref)\n \n \t\tformatp = strchr(name, ':');\n \t\tif (formatp) {\n-\t\t\tint num_ours, num_theirs;\n \t\t\tconst char *arg;\n \n \t\t\tformatp++;\n@@ -953,43 +1008,7 @@ static void populate_value(struct ref_array_item *ref)\n \t\t\t\t\t\t      warn_ambiguous_refs);\n \t\t\telse if (skip_prefix(formatp, \"strip=\", &arg))\n \t\t\t\trefname = strip_ref_components(refname, arg);\n-\t\t\telse if (!strcmp(formatp, \"track\") &&\n-\t\t\t\t (starts_with(name, \"upstream\") ||\n-\t\t\t\t  starts_with(name, \"push\"))) {\n-\n-\t\t\t\tif (stat_tracking_info(branch, &num_ours,\n-\t\t\t\t\t\t       &num_theirs, NULL))\n-\t\t\t\t\tcontinue;\n-\n-\t\t\t\tif (!num_ours && !num_theirs)\n-\t\t\t\t\tv->s = \"\";\n-\t\t\t\telse if (!num_ours)\n-\t\t\t\t\tv->s = xstrfmt(\"[behind %d]\", num_theirs);\n-\t\t\t\telse if (!num_theirs)\n-\t\t\t\t\tv->s = xstrfmt(\"[ahead %d]\", num_ours);\n-\t\t\t\telse\n-\t\t\t\t\tv->s = xstrfmt(\"[ahead %d, behind %d]\",\n-\t\t\t\t\t\t       num_ours, num_theirs);\n-\t\t\t\tcontinue;\n-\t\t\t} else if (!strcmp(formatp, \"trackshort\") &&\n-\t\t\t\t   (starts_with(name, \"upstream\") ||\n-\t\t\t\t    starts_with(name, \"push\"))) {\n-\t\t\t\tassert(branch);\n-\n-\t\t\t\tif (stat_tracking_info(branch, &num_ours,\n-\t\t\t\t\t\t\t&num_theirs, NULL))\n-\t\t\t\t\tcontinue;\n-\n-\t\t\t\tif (!num_ours && !num_theirs)\n-\t\t\t\t\tv->s = \"=\";\n-\t\t\t\telse if (!num_ours)\n-\t\t\t\t\tv->s = \"<\";\n-\t\t\t\telse if (!num_theirs)\n-\t\t\t\t\tv->s = \">\";\n-\t\t\t\telse\n-\t\t\t\t\tv->s = \"<>\";\n-\t\t\t\tcontinue;\n-\t\t\t} else\n+\t\t\telse\n \t\t\t\tdie(\"unknown %.*s format %s\",\n \t\t\t\t    (int)(formatp - name), name, formatp);\n \t\t}\n-- \n2.7.1\n"},{"id":"278481","messageId":"1455732379-22479-11-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","subject":"[PATCH v6 10/11] ref-filter: introduce contents_atom_parser()","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:18Z","receivedAt":"2016-02-17T18:06:18Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Introduce contents_atom_parser() which will parse the '%(contents)'\natom and store information into the 'used_atom' structure based on the\nmodifiers used along with the atom. Also introduce body_atom_parser()\nand subject_atom_parser() for parsing atoms '%(body)' and '%(subject)'\nrespectively.\n\nHelped-by: Ramsay Jones <ramsay@ramsayjones.plus.com>\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Karthik Nayak <Karthik.188@gmail.com>\n---\n ref-filter.c | 79 ++++++++++++++++++++++++++++++++++++++----------------------\n 1 file changed, 50 insertions(+), 29 deletions(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 7df5085..d2946ea 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -39,6 +39,10 @@ static struct used_atom {\n \t\tstruct align align;\n \t\tenum { RR_NORMAL, RR_SHORTEN, RR_TRACK, RR_TRACKSHORT }\n \t\t\tremote_ref;\n+\t\tstruct {\n+\t\t\tenum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, C_SUB } option;\n+\t\t\tunsigned int nlines;\n+\t\t} contents;\n \t} u;\n } *used_atom;\n static int used_atom_cnt, need_tagged, need_symref;\n@@ -66,6 +70,38 @@ static void remote_ref_atom_parser(struct used_atom *atom, const char *arg)\n \t\tdie(_(\"unrecognized format: %%(%s)\"), atom->name);\n }\n \n+static void body_atom_parser(struct used_atom *atom, const char *arg)\n+{\n+\tif (arg)\n+\t\tdie(\"%%(body) does not take arguments\");\n+\tatom->u.contents.option = C_BODY_DEP;\n+}\n+\n+static void subject_atom_parser(struct used_atom *atom, const char *arg)\n+{\n+\tif (arg)\n+\t\tdie(\"%%(subject) does not take arguments\");\n+\tatom->u.contents.option = C_SUB;\n+}\n+\n+static void contents_atom_parser(struct used_atom *atom, const char *arg)\n+{\n+\tif (!arg)\n+\t\tatom->u.contents.option = C_BARE;\n+\telse if (!strcmp(arg, \"body\"))\n+\t\tatom->u.contents.option = C_BODY;\n+\telse if (!strcmp(arg, \"signature\"))\n+\t\tatom->u.contents.option = C_SIG;\n+\telse if (!strcmp(arg, \"subject\"))\n+\t\tatom->u.contents.option = C_SUB;\n+\telse if (skip_prefix(arg, \"lines=\", &arg)) {\n+\t\tatom->u.contents.option = C_LINES;\n+\t\tif (strtoul_ui(arg, 10, &atom->u.contents.nlines))\n+\t\t\tdie(_(\"positive value expected contents:lines=%s\"), arg);\n+\t} else\n+\t\tdie(_(\"unrecognized %%(contents) argument: %s\"), arg);\n+}\n+\n static align_type parse_align_position(const char *s)\n {\n \tif (!strcmp(s, \"right\"))\n@@ -145,9 +181,9 @@ static struct {\n \t{ \"taggerdate\", FIELD_TIME },\n \t{ \"creator\" },\n \t{ \"creatordate\", FIELD_TIME },\n-\t{ \"subject\" },\n-\t{ \"body\" },\n-\t{ \"contents\" },\n+\t{ \"subject\", FIELD_STR, subject_atom_parser },\n+\t{ \"body\", FIELD_STR, body_atom_parser },\n+\t{ \"contents\", FIELD_STR, contents_atom_parser },\n \t{ \"upstream\", FIELD_STR, remote_ref_atom_parser },\n \t{ \"push\", FIELD_STR, remote_ref_atom_parser },\n \t{ \"symref\" },\n@@ -160,11 +196,6 @@ static struct {\n \n #define REF_FORMATTING_STATE_INIT  { 0, NULL }\n \n-struct contents {\n-\tunsigned int lines;\n-\tstruct object_id oid;\n-};\n-\n struct ref_formatting_stack {\n \tstruct ref_formatting_stack *prev;\n \tstruct strbuf output;\n@@ -181,7 +212,6 @@ struct atom_value {\n \tconst char *s;\n \tunion {\n \t\tstruct align align;\n-\t\tstruct contents contents;\n \t} u;\n \tvoid (*handler)(struct atom_value *atomv, struct ref_formatting_state *state);\n \tunsigned long ul; /* used for sorting when not FIELD_STR */\n@@ -733,20 +763,16 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj\n \tunsigned long sublen = 0, bodylen = 0, nonsiglen = 0, siglen = 0;\n \n \tfor (i = 0; i < used_atom_cnt; i++) {\n-\t\tconst char *name = used_atom[i].name;\n+\t\tstruct used_atom *atom = &used_atom[i];\n+\t\tconst char *name = atom->name;\n \t\tstruct atom_value *v = &val[i];\n-\t\tconst char *valp = NULL;\n \t\tif (!!deref != (*name == '*'))\n \t\t\tcontinue;\n \t\tif (deref)\n \t\t\tname++;\n \t\tif (strcmp(name, \"subject\") &&\n \t\t    strcmp(name, \"body\") &&\n-\t\t    strcmp(name, \"contents\") &&\n-\t\t    strcmp(name, \"contents:subject\") &&\n-\t\t    strcmp(name, \"contents:body\") &&\n-\t\t    strcmp(name, \"contents:signature\") &&\n-\t\t    !starts_with(name, \"contents:lines=\"))\n+\t\t    !starts_with(name, \"contents\"))\n \t\t\tcontinue;\n \t\tif (!subpos)\n \t\t\tfind_subpos(buf, sz,\n@@ -754,28 +780,23 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj\n \t\t\t\t    &bodypos, &bodylen, &nonsiglen,\n \t\t\t\t    &sigpos, &siglen);\n \n-\t\tif (!strcmp(name, \"subject\"))\n-\t\t\tv->s = copy_subject(subpos, sublen);\n-\t\telse if (!strcmp(name, \"contents:subject\"))\n+\t\tif (atom->u.contents.option == C_SUB)\n \t\t\tv->s = copy_subject(subpos, sublen);\n-\t\telse if (!strcmp(name, \"body\"))\n+\t\telse if (atom->u.contents.option == C_BODY_DEP)\n \t\t\tv->s = xmemdupz(bodypos, bodylen);\n-\t\telse if (!strcmp(name, \"contents:body\"))\n+\t\telse if (atom->u.contents.option == C_BODY)\n \t\t\tv->s = xmemdupz(bodypos, nonsiglen);\n-\t\telse if (!strcmp(name, \"contents:signature\"))\n+\t\telse if (atom->u.contents.option == C_SIG)\n \t\t\tv->s = xmemdupz(sigpos, siglen);\n-\t\telse if (!strcmp(name, \"contents\"))\n-\t\t\tv->s = xstrdup(subpos);\n-\t\telse if (skip_prefix(name, \"contents:lines=\", &valp)) {\n+\t\telse if (atom->u.contents.option == C_LINES) {\n \t\t\tstruct strbuf s = STRBUF_INIT;\n \t\t\tconst char *contents_end = bodylen + bodypos - siglen;\n \n-\t\t\tif (strtoul_ui(valp, 10, &v->u.contents.lines))\n-\t\t\t\tdie(_(\"positive value expected contents:lines=%s\"), valp);\n \t\t\t/*  Size is the length of the message after removing the signature */\n-\t\t\tappend_lines(&s, subpos, contents_end - subpos, v->u.contents.lines);\n+\t\t\tappend_lines(&s, subpos, contents_end - subpos, atom->u.contents.nlines);\n \t\t\tv->s = strbuf_detach(&s, NULL);\n-\t\t}\n+\t\t} else if (atom->u.contents.option == C_BARE)\n+\t\t\tv->s = xstrdup(subpos);\n \t}\n }\n \n-- \n2.7.1\n"},{"id":"278483","messageId":"1455732379-22479-12-git-send-email-Karthik.188@gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-1-git-send-email-Karthik.188@gmail.com","subject":"[PATCH v6 11/11] ref-filter: introduce objectname_atom_parser()","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-17T18:06:19Z","receivedAt":"2016-02-17T18:06:19Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Introduce objectname_atom_parser() which will parse the\n'%(objectname)' atom and store information into the 'used_atom'\nstructure based on the modifiers used along with the atom.\n\nHelped-by: Ramsay Jones <ramsay@ramsayjones.plus.com>\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nSigned-off-by: Karthik Nayak <Karthik.188@gmail.com>\n---\n ref-filter.c | 35 ++++++++++++++++++++++++-----------\n 1 file changed, 24 insertions(+), 11 deletions(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex d2946ea..d13d002 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -43,6 +43,7 @@ static struct used_atom {\n \t\t\tenum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, C_SUB } option;\n \t\t\tunsigned int nlines;\n \t\t} contents;\n+\t\tenum { O_FULL, O_SHORT } objectname;\n \t} u;\n } *used_atom;\n static int used_atom_cnt, need_tagged, need_symref;\n@@ -102,6 +103,16 @@ static void contents_atom_parser(struct used_atom *atom, const char *arg)\n \t\tdie(_(\"unrecognized %%(contents) argument: %s\"), arg);\n }\n \n+static void objectname_atom_parser(struct used_atom *atom, const char *arg)\n+{\n+\tif (!arg)\n+\t\tatom->u.objectname = O_FULL;\n+\telse if (!strcmp(arg, \"short\"))\n+\t\tatom->u.objectname = O_SHORT;\n+\telse\n+\t\tdie(_(\"unrecognized %%(objectname) argument: %s\"), arg);\n+}\n+\n static align_type parse_align_position(const char *s)\n {\n \tif (!strcmp(s, \"right\"))\n@@ -160,7 +171,7 @@ static struct {\n \t{ \"refname\" },\n \t{ \"objecttype\" },\n \t{ \"objectsize\", FIELD_ULONG },\n-\t{ \"objectname\" },\n+\t{ \"objectname\", FIELD_STR, objectname_atom_parser },\n \t{ \"tree\" },\n \t{ \"parent\" },\n \t{ \"numparent\", FIELD_ULONG },\n@@ -440,15 +451,17 @@ static void *get_obj(const unsigned char *sha1, struct object **obj, unsigned lo\n }\n \n static int grab_objectname(const char *name, const unsigned char *sha1,\n-\t\t\t    struct atom_value *v)\n+\t\t\t   struct atom_value *v, struct used_atom *atom)\n {\n-\tif (!strcmp(name, \"objectname\")) {\n-\t\tv->s = xstrdup(sha1_to_hex(sha1));\n-\t\treturn 1;\n-\t}\n-\tif (!strcmp(name, \"objectname:short\")) {\n-\t\tv->s = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));\n-\t\treturn 1;\n+\tif (starts_with(name, \"objectname\")) {\n+\t\tif (atom->u.objectname == O_SHORT) {\n+\t\t\tv->s = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));\n+\t\t\treturn 1;\n+\t\t} else if (atom->u.objectname == O_FULL) {\n+\t\t\tv->s = xstrdup(sha1_to_hex(sha1));\n+\t\t\treturn 1;\n+\t\t} else\n+\t\t\tdie(\"BUG: unknown %%(objectname) option\");\n \t}\n \treturn 0;\n }\n@@ -472,7 +485,7 @@ static void grab_common_values(struct atom_value *val, int deref, struct object\n \t\t\tv->s = xstrfmt(\"%lu\", sz);\n \t\t}\n \t\telse if (deref)\n-\t\t\tgrab_objectname(name, obj->oid.hash, v);\n+\t\t\tgrab_objectname(name, obj->oid.hash, v, &used_atom[i]);\n \t}\n }\n \n@@ -996,7 +1009,7 @@ static void populate_value(struct ref_array_item *ref)\n \t\t\t\tv->s = xstrdup(buf + 1);\n \t\t\t}\n \t\t\tcontinue;\n-\t\t} else if (!deref && grab_objectname(name, ref->objectname, v)) {\n+\t\t} else if (!deref && grab_objectname(name, ref->objectname, v, atom)) {\n \t\t\tcontinue;\n \t\t} else if (!strcmp(name, \"HEAD\")) {\n \t\t\tconst char *head;\n-- \n2.7.1\n"},{"id":"278512","messageId":"CAPig+cRTtXPjvCL3a-2Y+sKBPY1fKNO39VYnzFQ7Ed3dJn+w8w@mail.gmail.com","threadId":"41433","inReplyTo":"1455732379-22479-2-git-send-email-Karthik.188@gmail.com","subject":"Re: [PATCH v6 01/11] ref-filter: use string_list_split over strbuf_split","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-02-17T22:11:50Z","receivedAt":"2016-02-17T22:11:50Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Feb 17, 2016 at 1:06 PM, Karthik Nayak <karthik.188@gmail.com> wrote:\n> From: Jeff King <peff@peff.net>\n>\n> We don't do any post-processing on the resulting strbufs, so it is\n> simpler to just use string_list_split, which takes care of removing\n> the delimiter for us.\n>\n> Written-by: Jeff King <peff@peff.net>\n\nPerhaps Peff can give his sign-off...\n\n> Signed-off-by: Karthik Nayak <Karthik.188@gmail.com>\n> ---\n>  ref-filter.c | 29 +++++++++++------------------\n>  1 file changed, 11 insertions(+), 18 deletions(-)\n>\n> diff --git a/ref-filter.c b/ref-filter.c\n> index f097176..19367ce 100644\n> --- a/ref-filter.c\n> +++ b/ref-filter.c\n> @@ -886,41 +886,34 @@ static void populate_value(struct ref_array_item *ref)\n>                         continue;\n>                 } else if (match_atom_name(name, \"align\", &valp)) {\n>                         struct align *align = &v->u.align;\n> -                       struct strbuf **s, **to_free;\n> +                       struct string_list params = STRING_LIST_INIT_DUP;\n> +                       int i;\n>                         int width = -1;\n>\n>                         if (!valp)\n>                                 die(_(\"expected format: %%(align:<width>,<position>)\"));\n>\n> -                       /*\n> -                        * TODO: Implement a function similar to strbuf_split_str()\n> -                        * which would omit the separator from the end of each value.\n> -                        */\n> -                       s = to_free = strbuf_split_str(valp, ',', 0);\n> -\n>                         align->position = ALIGN_LEFT;\n>\n> -                       while (*s) {\n> -                               /*  Strip trailing comma */\n> -                               if (s[1])\n> -                                       strbuf_setlen(s[0], s[0]->len - 1);\n> -                               if (!strtoul_ui(s[0]->buf, 10, (unsigned int *)&width))\n> +                       string_list_split(&params, valp, ',', -1);\n> +                       for (i = 0; i < params.nr; i++) {\n> +                               const char *s = params.items[i].string;\n> +                               if (!strtoul_ui(s, 10, (unsigned int *)&width))\n>                                         ;\n> -                               else if (!strcmp(s[0]->buf, \"left\"))\n> +                               else if (!strcmp(s, \"left\"))\n>                                         align->position = ALIGN_LEFT;\n> -                               else if (!strcmp(s[0]->buf, \"right\"))\n> +                               else if (!strcmp(s, \"right\"))\n>                                         align->position = ALIGN_RIGHT;\n> -                               else if (!strcmp(s[0]->buf, \"middle\"))\n> +                               else if (!strcmp(s, \"middle\"))\n>                                         align->position = ALIGN_MIDDLE;\n>                                 else\n> -                                       die(_(\"improper format entered align:%s\"), s[0]->buf);\n> -                               s++;\n> +                                       die(_(\"improper format entered align:%s\"), s);\n>                         }\n>\n>                         if (width < 0)\n>                                 die(_(\"positive width expected with the %%(align) atom\"));\n>                         align->width = width;\n> -                       strbuf_list_free(to_free);\n> +                       string_list_clear(&params, 0);\n>                         v->handler = align_atom_handler;\n>                         continue;\n>                 } else if (!strcmp(name, \"end\")) {\n> --\n> 2.7.1\n"},{"id":"278513","messageId":"20160217221430.GA24899@sigill.intra.peff.net","threadId":"41433","inReplyTo":"CAPig+cRTtXPjvCL3a-2Y+sKBPY1fKNO39VYnzFQ7Ed3dJn+w8w@mail.gmail.com","subject":"Re: [PATCH v6 01/11] ref-filter: use string_list_split over strbuf_split","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-17T22:14:30Z","receivedAt":"2016-02-17T22:14:30Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Feb 17, 2016 at 05:11:50PM -0500, Eric Sunshine wrote:\n\n> On Wed, Feb 17, 2016 at 1:06 PM, Karthik Nayak <karthik.188@gmail.com> wrote:\n> > From: Jeff King <peff@peff.net>\n> >\n> > We don't do any post-processing on the resulting strbufs, so it is\n> > simpler to just use string_list_split, which takes care of removing\n> > the delimiter for us.\n> >\n> > Written-by: Jeff King <peff@peff.net>\n> \n> Perhaps Peff can give his sign-off...\n\nAh, right. I usually sign-off when sending to the list, so the version\nhe pulled from GitHub didn't have it.\n\nDefinitely:\n\n  Signed-off-by: Jeff King <peff@peff.net>\n\nAnd I don't think \"Written-by\" was doing much here, anyway; I am already\nthe author by the From header at the top. :)\n\n-Peff\n\n> \n> > Signed-off-by: Karthik Nayak <Karthik.188@gmail.com>\n> > ---\n> >  ref-filter.c | 29 +++++++++++------------------\n> >  1 file changed, 11 insertions(+), 18 deletions(-)\n> >\n> > diff --git a/ref-filter.c b/ref-filter.c\n> > index f097176..19367ce 100644\n> > --- a/ref-filter.c\n> > +++ b/ref-filter.c\n> > @@ -886,41 +886,34 @@ static void populate_value(struct ref_array_item *ref)\n> >                         continue;\n> >                 } else if (match_atom_name(name, \"align\", &valp)) {\n> >                         struct align *align = &v->u.align;\n> > -                       struct strbuf **s, **to_free;\n> > +                       struct string_list params = STRING_LIST_INIT_DUP;\n> > +                       int i;\n> >                         int width = -1;\n> >\n> >                         if (!valp)\n> >                                 die(_(\"expected format: %%(align:<width>,<position>)\"));\n> >\n> > -                       /*\n> > -                        * TODO: Implement a function similar to strbuf_split_str()\n> > -                        * which would omit the separator from the end of each value.\n> > -                        */\n> > -                       s = to_free = strbuf_split_str(valp, ',', 0);\n> > -\n> >                         align->position = ALIGN_LEFT;\n> >\n> > -                       while (*s) {\n> > -                               /*  Strip trailing comma */\n> > -                               if (s[1])\n> > -                                       strbuf_setlen(s[0], s[0]->len - 1);\n> > -                               if (!strtoul_ui(s[0]->buf, 10, (unsigned int *)&width))\n> > +                       string_list_split(&params, valp, ',', -1);\n> > +                       for (i = 0; i < params.nr; i++) {\n> > +                               const char *s = params.items[i].string;\n> > +                               if (!strtoul_ui(s, 10, (unsigned int *)&width))\n> >                                         ;\n> > -                               else if (!strcmp(s[0]->buf, \"left\"))\n> > +                               else if (!strcmp(s, \"left\"))\n> >                                         align->position = ALIGN_LEFT;\n> > -                               else if (!strcmp(s[0]->buf, \"right\"))\n> > +                               else if (!strcmp(s, \"right\"))\n> >                                         align->position = ALIGN_RIGHT;\n> > -                               else if (!strcmp(s[0]->buf, \"middle\"))\n> > +                               else if (!strcmp(s, \"middle\"))\n> >                                         align->position = ALIGN_MIDDLE;\n> >                                 else\n> > -                                       die(_(\"improper format entered align:%s\"), s[0]->buf);\n> > -                               s++;\n> > +                                       die(_(\"improper format entered align:%s\"), s);\n> >                         }\n> >\n> >                         if (width < 0)\n> >                                 die(_(\"positive width expected with the %%(align) atom\"));\n> >                         align->width = width;\n> > -                       strbuf_list_free(to_free);\n> > +                       string_list_clear(&params, 0);\n> >                         v->handler = align_atom_handler;\n> >                         continue;\n> >                 } else if (!strcmp(name, \"end\")) {\n> > --\n> > 2.7.1\n"},{"id":"278514","messageId":"xmqq1t8bhtdw.fsf@gitster.mtv.corp.google.com","threadId":"41433","inReplyTo":"20160217221430.GA24899@sigill.intra.peff.net","subject":"Re: [PATCH v6 01/11] ref-filter: use string_list_split over strbuf_split","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-02-17T22:19:39Z","receivedAt":"2016-02-17T22:19:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Wed, Feb 17, 2016 at 05:11:50PM -0500, Eric Sunshine wrote:\n>\n>> On Wed, Feb 17, 2016 at 1:06 PM, Karthik Nayak <karthik.188@gmail.com> wrote:\n>> > From: Jeff King <peff@peff.net>\n>> >\n>> > We don't do any post-processing on the resulting strbufs, so it is\n>> > simpler to just use string_list_split, which takes care of removing\n>> > the delimiter for us.\n>> >\n>> > Written-by: Jeff King <peff@peff.net>\n>> \n>> Perhaps Peff can give his sign-off...\n>\n> Ah, right. I usually sign-off when sending to the list, so the version\n> he pulled from GitHub didn't have it.\n>\n> Definitely:\n>\n>   Signed-off-by: Jeff King <peff@peff.net>\n>\n> And I don't think \"Written-by\" was doing much here, anyway; I am already\n> the author by the From header at the top. :)\n\n;-).\n\nSo, is everybody happy with this round?\n\nWith another series on top for the \"conditional\" stuff, I guess we\nare ready to do the formatting for \"git branch --list\", which would\nbe a big step forward.\n\nThanks.\n"},{"id":"278515","messageId":"CAPig+cS8sJn9tV2kW=ASN2wTtKiK-H5oa8bThiiGfu_vMv7DoQ@mail.gmail.com","threadId":"41433","inReplyTo":"xmqq1t8bhtdw.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v6 01/11] ref-filter: use string_list_split over strbuf_split","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-02-17T22:21:38Z","receivedAt":"2016-02-17T22:21:38Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Feb 17, 2016 at 5:19 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Jeff King <peff@peff.net> writes:\n>> On Wed, Feb 17, 2016 at 05:11:50PM -0500, Eric Sunshine wrote:\n>>> On Wed, Feb 17, 2016 at 1:06 PM, Karthik Nayak <karthik.188@gmail.com> wrote:\n>>> > From: Jeff King <peff@peff.net>\n>>> >\n>>> > We don't do any post-processing on the resulting strbufs, so it is\n>>> > simpler to just use string_list_split, which takes care of removing\n>>> > the delimiter for us.\n>>> >\n>>> > Written-by: Jeff King <peff@peff.net>\n>>>\n>>> Perhaps Peff can give his sign-off...\n>>\n>> Ah, right. I usually sign-off when sending to the list, so the version\n>> he pulled from GitHub didn't have it.\n>>\n>> Definitely:\n>>\n>>   Signed-off-by: Jeff King <peff@peff.net>\n>>\n>> And I don't think \"Written-by\" was doing much here, anyway; I am already\n>> the author by the From header at the top. :)\n>\n> ;-).\n>\n> So, is everybody happy with this round?\n\nYes, v6 looks good to me and is:\n\nReviewed-by: Eric Sunshine <sunshine@sunshineco.com>\n"},{"id":"278516","messageId":"20160217222607.GA25424@sigill.intra.peff.net","threadId":"41433","inReplyTo":"xmqq1t8bhtdw.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v6 01/11] ref-filter: use string_list_split over strbuf_split","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-02-17T22:26:08Z","receivedAt":"2016-02-17T22:26:08Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Feb 17, 2016 at 02:19:39PM -0800, Junio C Hamano wrote:\n\n> So, is everybody happy with this round?\n> \n> With another series on top for the \"conditional\" stuff, I guess we\n> are ready to do the formatting for \"git branch --list\", which would\n> be a big step forward.\n\nI have not looked with nearly as close an eye as Eric, but I did not see\nanything objectionable (and I trust the reviews that have led us up to\nv6 in the first place).\n\nThanks, Karthik, for your continued work on this (and to reviewers, of\ncourse :) ).\n\n-Peff\n"},{"id":"278562","messageId":"CAOLa=ZR3XRuYBG4Pm0okS6TG3k9tEGwc-EvKq1As0CLCU4i3rQ@mail.gmail.com","threadId":"41433","inReplyTo":"xmqq1t8bhtdw.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v6 01/11] ref-filter: use string_list_split over strbuf_split","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2016-02-18T14:19:28Z","receivedAt":"2016-02-18T14:19:28Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"On Thu, Feb 18, 2016 at 3:49 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Jeff King <peff@peff.net> writes:\n>\n>> On Wed, Feb 17, 2016 at 05:11:50PM -0500, Eric Sunshine wrote:\n>>\n>>> On Wed, Feb 17, 2016 at 1:06 PM, Karthik Nayak <karthik.188@gmail.com> wrote:\n>>> > From: Jeff King <peff@peff.net>\n>>> >\n>>> > We don't do any post-processing on the resulting strbufs, so it is\n>>> > simpler to just use string_list_split, which takes care of removing\n>>> > the delimiter for us.\n>>> >\n>>> > Written-by: Jeff King <peff@peff.net>\n>>>\n>>> Perhaps Peff can give his sign-off...\n>>\n>> Ah, right. I usually sign-off when sending to the list, so the version\n>> he pulled from GitHub didn't have it.\n>>\n>> Definitely:\n>>\n>>   Signed-off-by: Jeff King <peff@peff.net>\n>>\n>> And I don't think \"Written-by\" was doing much here, anyway; I am already\n>> the author by the From header at the top. :)\n>\n> ;-).\n>\n> So, is everybody happy with this round?\n>\n> With another series on top for the \"conditional\" stuff, I guess we\n> are ready to do the formatting for \"git branch --list\", which would\n> be a big step forward.\n>\n> Thanks.\n\nYes, I'll be sending that soon :D\n\n> Yes, v6 looks good to me and is:\n>\n> Reviewed-by: Eric Sunshine <sunshine@sunshineco.com>\n\n> I have not looked with nearly as close an eye as Eric, but I did not see\n> anything objectionable (and I trust the reviews that have led us up to\n> v6 in the first place).\n>\n> Thanks, Karthik, for your continued work on this (and to reviewers, of\n> course :) ).\n>\n> -Peff\n\nThanks to everyone who helped, especially reviewers for going through such\nlong patch series.\n\n-- \nRegards,\nKarthik Nayak\n"}]}