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

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

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 11, 2015, 18:52 UTC
Message-ID
<xmqqy4hhr72q.fsf@gitster.dls.corp.google.com>
In-Reply-To
<1439129506-9989-6-git-send-email-Karthik.188@gmail.com>
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.

Show 17 quoted lines
> @@ -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.

Show 8 quoted lines
> @@ -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.

Show 16 quoted lines
> @@ -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.

Show 15 quoted lines
> +		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.

Previous: Karthik NayakNext: Karthik Nayak
Message 23 of 40 in “port tag.c to use ref-filter APIs”
  1. 00/13 port tag.c to use ref-filter APIsKarthik Nayak, Aug 9, 2015
  2. 01/13 ref-filter: move `struct atom_value` to ref-filter.cKarthik Nayak, Aug 9, 2015
  3. 02/13 ref-filter: print output to strbuf for formattingKarthik Nayak, Aug 9, 2015
  4. Junio C HamanoAug 11, 2015
  5. Karthik NayakAug 12, 2015
  6. Junio C HamanoAug 12, 2015
  7. Karthik NayakAug 12, 2015
  8. Junio C HamanoAug 11, 2015
  9. Karthik NayakAug 12, 2015
  10. 03/13 ref-filter: introduce ref_formatting_stateKarthik Nayak, Aug 9, 2015
  11. Junio C HamanoAug 11, 2015
  12. Karthik NayakAug 12, 2015
  13. 04/13 utf8: add function to align a string into given strbufKarthik Nayak, Aug 9, 2015
  14. Junio C HamanoAug 11, 2015
  15. Karthik NayakAug 12, 2015
  16. Junio C HamanoAug 12, 2015
  17. Karthik NayakAug 12, 2015
  18. Eric SunshineAug 13, 2015
  19. Karthik NayakAug 13, 2015
  20. Junio C HamanoAug 14, 2015
  21. Duy NguyenAug 15, 2015
  22. 05/13 ref-filter: implement an `align` atomKarthik Nayak, Aug 9, 2015
  23. Junio C HamanoAug 11, 2015
  24. Karthik NayakAug 12, 2015
  25. Junio C HamanoAug 12, 2015
  26. Karthik NayakAug 12, 2015
  27. Junio C HamanoAug 12, 2015
  28. Karthik NayakAug 14, 2015
  29. Junio C HamanoAug 14, 2015
  30. Eric SunshineAug 13, 2015
  31. Karthik NayakAug 13, 2015
  32. 06/13 ref-filter: add option to filter only tagsKarthik Nayak, Aug 9, 2015
  33. 07/13 ref-filter: support printing N lines from tag annotationKarthik Nayak, Aug 9, 2015
  34. 08/13 ref-filter: add support to sort by versionKarthik Nayak, Aug 9, 2015
  35. 09/13 ref-filter: add option to match literal patternKarthik Nayak, Aug 9, 2015
  36. 10/13 tag.c: use 'ref-filter' data structuresKarthik Nayak, Aug 9, 2015
  37. 10/13 tag.c: use 'ref-filter' data structuresKarthik Nayak, Aug 9, 2015
  38. 11/13 tag.c: use 'ref-filter' APIsKarthik Nayak, Aug 9, 2015
  39. 12/13 tag.c: implement '--format' optionKarthik Nayak, Aug 9, 2015
  40. 13/13 tag.c: implement '--merged' and '--no-merged' optionsKarthik Nayak, Aug 9, 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.