git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Karthik Nayak <karthik.188@gmail.com>
Cc: git@vger.kernel.org, christian.couder@gmail.com,
	Matthieu.Moy@grenoble-inp.fr
Subject: Re: [PATCH v10 05/13] ref-filter: implement an `align` atom
Date: Tue, 11 Aug 2015 11:52:29 -0700	[thread overview]
Message-ID: <xmqqy4hhr72q.fsf@gitster.dls.corp.google.com> (raw)
In-Reply-To: <1439129506-9989-6-git-send-email-Karthik.188@gmail.com> (Karthik Nayak's message of "Sun, 9 Aug 2015 19:41:38 +0530")

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.

> @@ -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.

> @@ -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.

> @@ -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.

> +		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.

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.

  reply	other threads:[~2015-08-11 18:52 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 [this message]
2015-08-12 16:24     ` Karthik Nayak
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=xmqqy4hhr72q.fsf@gitster.dls.corp.google.com \
    --to=gitster@pobox.com \
    --cc=Matthieu.Moy@grenoble-inp.fr \
    --cc=christian.couder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=karthik.188@gmail.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).