Re: [PATCH v10 05/13] ref-filter: implement an `align` atom

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Aug 12, 2015 at 12:22 AM, Junio C Hamano <gitster@xxxxxxxxx> wrote:
> Karthik Nayak <karthik.188@xxxxxxxxx> 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
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]