git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v9 0/11] Port tag.c over to use ref-filter APIs

From
Karthik Nayak <karthik.188@gmail.com>
Date
Aug 4, 2015, 12:39 UTC
Message-ID
<CAOLa=ZSBMk9y1VGTVKSVsGMdYuPtjhPADciVUaEVwESRdSvWZg@mail.gmail.com>

This is part of my GSoC project to unify git tag -l, git branch -l, git for-each-ref. This patch series is continued from: Git (next) https://github.com/git/git/commit/bf5418f49ff0cebc6e5ce04ad1417e1a47c81b61

This series consists of porting tag.c over to using the ref-filter APIs

Version 8 can be found here: http://thread.gmane.org/gmane.comp.version-control.git/274990

Changes:
* align now excepts strings till a %(end) is met.
* implement the current strbuf within ref_formatting_change
* change the strbuf name from format to final.
Interdiff:
diff --git a/Documentation/git-for-each-ref.txt
b/Documentation/git-for-each-ref.txt
index e89b9b0..6b6eb93 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -128,11 +128,12 @@ color::
        are described in `color.branch.*`.

 align::
-       Align succeeding atoms to the right, left or middle. Followed
-       by `:<type>,<paddinglength>`, where the `<type>` is either
-       left, right or middle and `<paddinglength>` is the total
-       length of the padding to be performed. If the atom length is
-       more than the padding length then no padding is performed.
+       Align any string with or without %(atom) before the %(end)
+       atom to the right, left or middle. Followed by
+       `:<type>,<paddinglength>`, where the `<type>` is either left,
+       right or middle and `<paddinglength>` is the total length of
+       the padding to be performed. If the string length is more than
+       the padding length then no padding is performed.

 In addition to the above, for commit and tag objects, the header
 field names (`tree`, `parent`, `object`, `type`, and `tag`) can
diff --git a/ref-filter.c b/ref-filter.c
index afeab37..de84dd4 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -57,6 +57,7 @@ static struct {
        { "HEAD" },
        { "color" },
        { "align" },
+       { "end" },
 };

 /*
@@ -708,6 +709,11 @@ static void populate_value(struct ref_array_item *ref)
                        if (strtoul_ui(valp, 10, &align->align_value))
                                die(_("align: positive value expected"));
                        v->align = align;
+                       v->modifier_atom = 1;
+                       continue;
+               } else if (starts_with(name, "end")) {
+                       v->end = 1;
+                       v->modifier_atom = 1;
                        continue;
                } else
                        continue;
@@ -1247,24 +1253,23 @@ void ref_array_sort(struct ref_sorting
*sorting, struct ref_array *array)
        qsort(array->items, array->nr, sizeof(struct ref_array_item
*), compare_refs);
 }

-static void print_value(struct atom_value *v, struct
ref_formatting_state *state,
-                       struct strbuf *output)
+static void print_value(struct atom_value *v, struct
ref_formatting_state *state)
 {
        switch (state->quote_style) {
        case QUOTE_NONE:
-               strbuf_addstr(output, v->s);
+               strbuf_addstr(state->output, v->s);
                break;
        case QUOTE_SHELL:
-               sq_quote_buf(output, v->s);
+               sq_quote_buf(state->output, v->s);
                break;
        case QUOTE_PERL:
-               perl_quote_buf(output, v->s);
+               perl_quote_buf(state->output, v->s);
                break;
        case QUOTE_PYTHON:
-               python_quote_buf(output, v->s);
+               python_quote_buf(state->output, v->s);
                break;
        case QUOTE_TCL:
-               tcl_quote_buf(output, v->s);
+               tcl_quote_buf(state->output, v->s);
                break;
        }
 }
@@ -1287,7 +1292,7 @@ static int hex2(const char *cp)
                return -1;
 }

-static void emit(const char *cp, const char *ep, struct strbuf *output)
+static void emit(const char *cp, const char *ep, struct
ref_formatting_state *state)
 {
        while (*cp && (!ep || cp < ep)) {
                if (*cp == '%') {
@@ -1296,13 +1301,13 @@ static void emit(const char *cp, const char
*ep, struct strbuf *output)
                        else {
                                int ch = hex2(cp + 1);
                                if (0 <= ch) {
-                                       strbuf_addch(output, ch);
+                                       strbuf_addch(state->output, ch);
                                        cp += 3;
                                        continue;
                                }
                        }
                }
-               strbuf_addch(output, *cp);
+               strbuf_addch(state->output, *cp);
                cp++;
        }
 }
@@ -1313,12 +1318,14 @@ static void process_formatting_state(struct
atom_value *atomv, struct ref_format
                state->align = atomv->align;
                atomv->align = NULL;
        }
+       if (atomv->end)
+               state->end = 1;
 }

-static void apply_formatting_state(struct ref_formatting_state
*state, struct strbuf *value,
-                                  struct strbuf *format)
+static void apply_formatting_state(struct ref_formatting_state
*state, struct strbuf *final)
 {
-       if (state->align) {
+       if (state->align && state->end) {
+               struct strbuf *value = state->output;
                int len = 0, buf_len = value->len;
                struct align *align = state->align;

@@ -1331,26 +1338,26 @@ static void apply_formatting_state(struct
ref_formatting_state *state, struct st

                if (align->align_value < buf_len) {
                        state->align = NULL;
-                       strbuf_addbuf(format, value);
+                       strbuf_addbuf(final, value);
                        strbuf_release(value);
                        return;
                }

                if (align->align_type == ALIGN_LEFT)
-                       strbuf_addf(format, "%-*s", len +
align->align_value, value->buf);
+                       strbuf_addf(final, "%-*s", len +
align->align_value, value->buf);
                else if (align->align_type == ALIGN_MIDDLE) {
                        int right = (align->align_value - buf_len)/2;
-                       strbuf_addf(format, "%*s%-*s",
align->align_value - right + len,
+                       strbuf_addf(final, "%*s%-*s",
align->align_value - right + len,
                                    value->buf, right, "");
                } else if (align->align_type == ALIGN_RIGHT)
-                       strbuf_addf(format, "%*s", align->align_value,
value->buf);
+                       strbuf_addf(final, "%*s", align->align_value,
value->buf);
                strbuf_release(value);
                state->align = NULL;
                return;
-       }
-       strbuf_addbuf(format, value);
-       strbuf_release(value);
-
+       } else if (state->align)
+               return;
+       strbuf_addbuf(final, state->output);
+       strbuf_release(state->output);
 }

 /*
@@ -1407,27 +1414,34 @@ void show_ref_array_item(struct ref_array_item
*info, const char *format,

        memset(&state, 0, sizeof(state));
        state.quote_style = quote_style;
+       state.output = &value;

        for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) {
                struct atom_value *atomv = NULL;

                ep = strchr(sp, ')');
                if (cp < sp) {
-                       emit(cp, sp, &value);
-                       apply_formatting_state(&state, &value, &final_buf);
+                       emit(cp, sp, &state);
+                       apply_formatting_state(&state, &final_buf);
                }
                get_ref_atom_value(info, parse_ref_filter_atom(sp + 2,
ep), &atomv);
-               if (atomv->align)
+               if (atomv->modifier_atom)
                        process_formatting_state(atomv, &state);
                else {
-                       print_value(atomv, &state, &value);
-                       apply_formatting_state(&state, &value, &final_buf);
+                       print_value(atomv, &state);
+                       apply_formatting_state(&state, &final_buf);
+               }
+               if (atomv->end) {
+                       print_value(atomv, &state);
+                       apply_formatting_state(&state, &final_buf);
                }
        }
+       if (state.align)
+               die(_("format: align used without an `end` atom"));
        if (*cp) {
                sp = cp + strlen(cp);
-               emit(cp, sp, &value);
-               apply_formatting_state(&state, &value, &final_buf);
+               emit(cp, sp, &state);
+               apply_formatting_state(&state, &final_buf);
        }
        if (need_color_reset_at_eol) {
                struct atom_value resetv;
@@ -1436,8 +1450,8 @@ void show_ref_array_item(struct ref_array_item
*info, const char *format,
                if (color_parse("reset", color) < 0)
                        die("BUG: couldn't parse 'reset' as a color");
                resetv.s = color;
-               print_value(&resetv, &state, &value);
-               apply_formatting_state(&state, &value, &final_buf);
+               print_value(&resetv, &state);
+               apply_formatting_state(&state, &final_buf);
        }

        for (i = 0; i < final_buf.len; i++)
diff --git a/ref-filter.h b/ref-filter.h
index b3b9cd8..5be3e35 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -23,8 +23,9 @@

 struct ref_formatting_state {
        int quote_style;
+       struct strbuf *output;
        struct align *align;
-       struct strbuf *sb;
+       unsigned int end : 1;
 };
struct align {
@@ -36,6 +37,8 @@ struct atom_value {
        const char *s;
        struct align *align;
        unsigned long ul; /* used for sorting when not FIELD_STR */
+       unsigned int modifier_atom : 1,
+               end : 1;
 };

 struct ref_sorting {

diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh
index 7332bea..272a7e4 100755
--- a/t/t6302-for-each-ref-filter.sh
+++ b/t/t6302-for-each-ref-filter.sh
@@ -83,81 +83,49 @@ test_expect_success 'filtering with --contains' '

 test_expect_success 'left alignment' '
        cat >expect <<-\EOF &&
-       refs/heads/master   |refs/heads/master
-       refs/heads/side     |refs/heads/side
-       refs/odd/spot       |refs/odd/spot
-       refs/tags/double-tag|refs/tags/double-tag
-       refs/tags/four      |refs/tags/four
-       refs/tags/one       |refs/tags/one
-       refs/tags/signed-tag|refs/tags/signed-tag
-       refs/tags/three     |refs/tags/three
-       refs/tags/two       |refs/tags/two
+       refname is refs/heads/master  |refs/heads/master
+       refname is refs/heads/side    |refs/heads/side
+       refname is refs/odd/spot      |refs/odd/spot
+       refname is refs/tags/double-tag|refs/tags/double-tag
+       refname is refs/tags/four     |refs/tags/four
+       refname is refs/tags/one      |refs/tags/one
+       refname is refs/tags/signed-tag|refs/tags/signed-tag
+       refname is refs/tags/three    |refs/tags/three
+       refname is refs/tags/two      |refs/tags/two
        EOF
-       git for-each-ref
--format="%(align:left,20)%(refname)|%(refname)" >actual &&
+       git for-each-ref --format="%(align:left,30)refname is
%(refname)%(end)|%(refname)" >actual &&
        test_cmp expect actual
 '

 test_expect_success 'middle alignment' '

        cat >expect <<-\EOF &&
-       |  refs/heads/master |refs/heads/master
-       |   refs/heads/side  |refs/heads/side
-       |    refs/odd/spot   |refs/odd/spot
-       |refs/tags/double-tag|refs/tags/double-tag
-       |   refs/tags/four   |refs/tags/four
-       |    refs/tags/one   |refs/tags/one
-       |refs/tags/signed-tag|refs/tags/signed-tag
-       |   refs/tags/three  |refs/tags/three
-       |    refs/tags/two   |refs/tags/two
+       | refname is refs/heads/master |refs/heads/master
+       |  refname is refs/heads/side  |refs/heads/side
+       |   refname is refs/odd/spot   |refs/odd/spot
+       |refname is refs/tags/double-tag|refs/tags/double-tag
+       |   refname is refs/tags/four  |refs/tags/four
+       |   refname is refs/tags/one   |refs/tags/one
+       |refname is refs/tags/signed-tag|refs/tags/signed-tag
+       |  refname is refs/tags/three  |refs/tags/three
+       |   refname is refs/tags/two   |refs/tags/two
        EOF
-       git for-each-ref
--format="|%(align:middle,20)%(refname)|%(refname)" >actual &&
+       git for-each-ref --format="|%(align:middle,30)refname is
%(refname)%(end)|%(refname)" >actual &&
        test_cmp expect actual
 '

 test_expect_success 'right alignment' '
        cat >expect <<-\EOF &&
-       |   refs/heads/master|refs/heads/master
-       |     refs/heads/side|refs/heads/side
-       |       refs/odd/spot|refs/odd/spot
-       |refs/tags/double-tag|refs/tags/double-tag
-       |      refs/tags/four|refs/tags/four
-       |       refs/tags/one|refs/tags/one
-       |refs/tags/signed-tag|refs/tags/signed-tag
-       |     refs/tags/three|refs/tags/three
-       |       refs/tags/two|refs/tags/two
+       |  refname is refs/heads/master|refs/heads/master
+       |    refname is refs/heads/side|refs/heads/side
+       |      refname is refs/odd/spot|refs/odd/spot
+       |refname is refs/tags/double-tag|refs/tags/double-tag
+       |     refname is refs/tags/four|refs/tags/four
+       |      refname is refs/tags/one|refs/tags/one
+       |refname is refs/tags/signed-tag|refs/tags/signed-tag
+       |    refname is refs/tags/three|refs/tags/three
+       |      refname is refs/tags/two|refs/tags/two
        EOF
-       git for-each-ref
--format="|%(align:right,20)%(refname)|%(refname)" >actual &&
-       test_cmp expect actual
-'
-
-test_expect_success 'alignment value lesser than atom value' '
-       cat >expect <<-\EOF &&
-       |refs/heads/master|
-       |refs/heads/side|
-       |  refs/odd/spot|
-       |refs/tags/double-tag|
-       | refs/tags/four|
-       |  refs/tags/one|
-       |refs/tags/signed-tag|
-       |refs/tags/three|
-       |  refs/tags/two|
-       EOF
-       git for-each-ref --format="|%(align:right,15)%(refname)|" >actual &&
-       test_cmp expect actual
-'
-
-test_expect_success 'non atom alignment' '
-       cat >expect <<-\EOF &&
-       |    |master  |  refs/heads/master|  refs/heads/master
-       |    |side  |  refs/heads/side|  refs/heads/side
-       |    |odd/spot  |  refs/odd/spot|  refs/odd/spot
-       |    |double-tag  |  refs/tags/double-tag|  refs/tags/double-tag
-       |    |four  |  refs/tags/four|  refs/tags/four
-       |    |one  |  refs/tags/one|  refs/tags/one
-       |    |signed-tag  |  refs/tags/signed-tag|  refs/tags/signed-tag
-       |    |three  |  refs/tags/three|  refs/tags/three
-       |    |two  |  refs/tags/two|  refs/tags/two
-       EOF
-       git for-each-ref
--format="|%(align:right,5)|%(refname:short)%(align:middle,5)|%(refname)%(align:left,3)|%(refname)"
>actual &&
+       git for-each-ref --format="|%(align:right,30)refname is
%(refname)%(end)|%(refname)" >actual &&
        test_cmp expect actual
 '
-- 
Regards,
Karthik Nayak
Next: Karthik Nayak
Message 1 of 21 in “Port tag.c over to use ref-filter APIs”
  1. 0/11 Port tag.c over to use ref-filter APIsKarthik Nayak, Aug 4, 2015
  2. 01/11 ref-filter: print output to strbuf for formattingKarthik Nayak, Aug 4, 2015
  3. 02/11 ref-filter: introduce ref_formatting_stateKarthik Nayak, Aug 4, 2015
  4. Eric SunshineAug 7, 2015
  5. Karthik NayakAug 7, 2015
  6. Eric SunshineAug 7, 2015
  7. Karthik NayakAug 7, 2015
  8. Eric SunshineAug 7, 2015
  9. Karthik NayakAug 7, 2015
  10. Eric SunshineAug 7, 2015
  11. 03/11 ref-filter: implement an `align` atomKarthik Nayak, Aug 4, 2015
  12. 04/11 ref-filter: add option to filter only tagsKarthik Nayak, Aug 4, 2015
  13. 05/11 ref-filter: support printing N lines from tag annotationKarthik Nayak, Aug 4, 2015
  14. 06/11 ref-filter: add support to sort by versionKarthik Nayak, Aug 4, 2015
  15. 07/11 ref-filter: add option to match literal patternKarthik Nayak, Aug 4, 2015
  16. 08/11 tag.c: use 'ref-filter' data structuresKarthik Nayak, Aug 4, 2015
  17. 09/11 tag.c: use 'ref-filter' APIsKarthik Nayak, Aug 4, 2015
  18. 10/11 tag.c: implement '--format' optionKarthik Nayak, Aug 4, 2015
  19. 11/11 tag.c: implement '--merged' and '--no-merged' optionsKarthik Nayak, Aug 4, 2015
  20. Eric SunshineAug 6, 2015
  21. Karthik NayakAug 7, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.