git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Karthik Nayak <karthik.188@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: Git <git@vger.kernel.org>,
	Christian Couder <christian.couder@gmail.com>,
	Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
Subject: Re: [PATCH v10 05/13] ref-filter: implement an `align` atom
Date: Wed, 12 Aug 2015 21:54:29 +0530	[thread overview]
Message-ID: <CAOLa=ZTnS0kL=CK8Lx-brO0tryB5YzOFUpapsM4LMW-m2Yf9pw@mail.gmail.com> (raw)
In-Reply-To: <xmqqy4hhr72q.fsf@gitster.dls.corp.google.com>

On Wed, Aug 12, 2015 at 12:22 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Karthik Nayak <karthik.188@gmail.com> writes:
>
>>  struct atom_value{
>
> Obviously not a problem with this step, but you need a SP before the
> open brace.
>

Will add.

>> @@ -692,6 +704,26 @@ static void populate_value(struct ref_array_item *ref)
>>                       else
>>                               v->s = " ";
>>                       continue;
>> +             } else if (skip_prefix(name, "align:", &valp)) {
>> +                     struct align *align = xmalloc(sizeof(struct align));
>> +
>> +                     if (skip_prefix(valp, "left,", &valp))
>> +                             align->position = ALIGN_LEFT;
>> +                     else if (skip_prefix(valp, "right,", &valp))
>> +                             align->position = ALIGN_RIGHT;
>> +                     else if (skip_prefix(valp, "middle,", &valp))
>> +                             align->position = ALIGN_MIDDLE;
>> +                     else
>> +                             die(_("improper format entered align:%s"), valp);
>> +                     if (strtoul_ui(valp, 10, &align->width))
>> +                             die(_("positive width expected align:%s"), valp);
>
> Minor nits on the design.  %(align:<width>[,<position>]) would let
> us write %(align:16)...%(end) and use the "default position", which
> may be beneficial if one kind of alignment is prevalent (I guess all
> the internal users left-align?)  %(align:<position>,<width>) forces
> users to spell both out all the time.
>

Isn't that better? I mean It sets a format which the others eventually
can follow
%(atom:suboption,value).
For example: %(objectname:abbrev,size)
Changing this would cause inconsistency according to me.

>> @@ -1198,7 +1230,9 @@ void ref_array_sort(struct ref_sorting *sorting, struct ref_array *array)
>>
>>  struct ref_formatting_state {
>>       struct strbuf output;
>> +     struct align *align;
>>       int quote_style;
>> +     unsigned int end : 1;
>>  };
>
> Mental note: it is not clear why you need 'end' field in the state.
> Perhaps it is an indication that the division of labor is poorly
> designed between the helper that updates the formatting state and
> the other helper that reflects the formatting state to the final
> string.
>

This goes with what you've said below!

>> @@ -1262,12 +1296,31 @@ static void append_non_atom(const char *cp, const char *ep, struct ref_formattin
>>
>>  static void set_formatting_state(struct atom_value *atomv, struct ref_formatting_state *state)
>>  {
>> -     /* Based on the atomv values, the formatting state is set */
>> +     if (atomv->align) {
>> +             state->align = atomv->align;
>> +             atomv->align = NULL;
>> +     }
>> +     if (atomv->end)
>> +             state->end = 1;
>> +}
>> +
>> +static int align_ref_strbuf(struct ref_formatting_state *state, struct strbuf *final)
>> +{
>> +     if (state->align && state->end) {
>
> ... and I think that is what I see.  If this function knows that we
> are processing %(end), i.e. perform-state-formatting is called for
> each atom and receives atomv, there wouldn't have to be a code like
> this.
>

Agreed, your suggestion below eradicates this

>> +             struct align *align = state->align;
>> +             strbuf_utf8_align(final, align->position, align->width, state->output.buf);
>> +             strbuf_reset(&state->output);
>> +             state->align = NULL;
>> +             return 1;
>> +     } else if (state->align)
>> +             return 1;
>> +     return 0;
>>  }
>>
>>  static void perform_state_formatting(struct ref_formatting_state *state, struct strbuf *final)
>>  {
>> -     /* More formatting options to be eventually added */
>> +     if (align_ref_strbuf(state, final))
>> +             return;
>
> At the design level, I have a strong suspicion that it is a wrong
> way to go.  It piles more "if (this state bit was left by the
> previous atom) then do this" on this function and will make an
> unmanageable mess.

Hmm, yeah makes sense.

>
> You have a dictionary of all possible atoms somewhere.  Why not hook
> a pointer to the "handler" function (or two) to each element in it,
> instead of duplicating "this one is special" information down to
> individual atom instantiations (i.e. atomv) as atomv.modifier_atom
> bit, an dstructure the caller more like this?
>
>         get_ref_atom_value(info, parse_ref_filter_atom, &atomv);
>         if (atomv->pre_handler)
>                 atomv->pre_handler(atomv, &state);
>         format_quote_value(atomv, &state);
>         if (atomv->post_handler)
>                 atomv->post_handler(atomv, &state);
>
> Actually, each atom could just have a single handler; an atom like
> %(refname:short) whose sole effect is to append atomv->s to the
> state buffer can point a function to do so in its handler.
>
> On the other hand, align atom's handler would push a new state on
> the stack, marking that it is the one to handle diverted output.
>
>         align_atom_handler(atomv, state)
>         {
>                 struct format_state *new = push_new_state(state);
>                 strbuf_init(&new->output);
>                 new->atend = align_handler;
>                 new->return_to = atomv; /* or whatever that holds width,pos */
>         }
>
> Then end atom's handler would pop the state from the stack, and the
> processing to be done
>
>         end_atom_handler(atomv, state)
>         {
>                 state->atend(state);
>                 pop_state(state);
>         }
>
> and the called align_handler would be something like:
>
>         align_handler(state)
>         {
>                 struct strbuf aligned = STRBUF_INIT;
>                 struct format_state *return_to = state->prev;
>                 struct atom_value *atomv = state->return_to;
>
>                 strbuf_utf8_align(&aligned,
>                         atomv->align.pos, atomv->align.width,
>                         state->output.buf);
>                 strbuf_addbuf(&return_to->output, &aligned);
>                 strbuf_release(&aligned);
>         }
>
> With an arrangement like that, the body of the loop in
> show_ref_array_item() could be as simple and regular as:
>
>         get_ref_atom_value(info, parse_ref_filter_atom, &atomv);
>         atomv->handler(atomv, &state);
>
> without any new "ah, this %(end) is special so we need a new
> mechanism to pass information between set_formatting_state and
> perform_formatting" logic introduced every time you add new things.
>

This I agree is a way better scheme, This could also eventually help cleanup
populate_value() which is a huge function at the moment.

I like your suggestion, I'll work on this, Thanks a lot :)

-- 
Regards,
Karthik Nayak

  reply	other threads:[~2015-08-12 16:25 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-09 14:11 [PATCH v10 00/13] port tag.c to use ref-filter APIs Karthik Nayak
2015-08-09 14:11 ` [PATCH v10 01/13] ref-filter: move `struct atom_value` to ref-filter.c Karthik Nayak
2015-08-09 14:11 ` [PATCH v10 02/13] ref-filter: print output to strbuf for formatting Karthik Nayak
2015-08-11 17:56   ` Junio C Hamano
2015-08-12 13:22     ` Karthik Nayak
2015-08-12 16:29       ` Junio C Hamano
2015-08-12 16:56         ` Karthik Nayak
2015-08-11 18:00   ` Junio C Hamano
2015-08-12 13:22     ` Karthik Nayak
2015-08-09 14:11 ` [PATCH v10 03/13] ref-filter: introduce ref_formatting_state Karthik Nayak
2015-08-11 18:13   ` Junio C Hamano
2015-08-12 13:26     ` Karthik Nayak
2015-08-09 14:11 ` [PATCH v10 04/13] utf8: add function to align a string into given strbuf Karthik Nayak
2015-08-11 18:22   ` Junio C Hamano
2015-08-12 13:41     ` Karthik Nayak
2015-08-12 16:40       ` Junio C Hamano
2015-08-12 17:10         ` Karthik Nayak
2015-08-13 19:08   ` Eric Sunshine
2015-08-13 20:55     ` Karthik Nayak
2015-08-14 16:06     ` Junio C Hamano
2015-08-15  8:27   ` Duy Nguyen
2015-08-09 14:11 ` [PATCH v10 05/13] ref-filter: implement an `align` atom Karthik Nayak
2015-08-11 18:52   ` Junio C Hamano
2015-08-12 16:24     ` Karthik Nayak [this message]
2015-08-12 17:13       ` Junio C Hamano
2015-08-12 20:07         ` Karthik Nayak
2015-08-12 20:24           ` Junio C Hamano
2015-08-14 15:46             ` Karthik Nayak
2015-08-14 17:42               ` Junio C Hamano
2015-08-13 18:26   ` Eric Sunshine
2015-08-13 20:29     ` Karthik Nayak
2015-08-09 14:11 ` [PATCH v10 06/13] ref-filter: add option to filter only tags Karthik Nayak
2015-08-09 14:11 ` [PATCH v10 07/13] ref-filter: support printing N lines from tag annotation Karthik Nayak
2015-08-09 14:11 ` [PATCH v10 08/13] ref-filter: add support to sort by version Karthik Nayak
2015-08-09 14:11 ` [PATCH v10 09/13] ref-filter: add option to match literal pattern Karthik Nayak
2015-08-09 14:11 ` [PATCH v10 10/13] tag.c: use 'ref-filter' data structures Karthik Nayak
2015-08-09 14:17 ` Karthik Nayak
2015-08-09 14:32 ` [PATCH v10 11/13] tag.c: use 'ref-filter' APIs Karthik Nayak
2015-08-09 14:32 ` [PATCH v10 12/13] tag.c: implement '--format' option Karthik Nayak
2015-08-09 14:32 ` [PATCH v10 13/13] tag.c: implement '--merged' and '--no-merged' options Karthik Nayak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAOLa=ZTnS0kL=CK8Lx-brO0tryB5YzOFUpapsM4LMW-m2Yf9pw@mail.gmail.com' \
    --to=karthik.188@gmail.com \
    --cc=Matthieu.Moy@grenoble-inp.fr \
    --cc=christian.couder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).