git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Marco Costalba <mcostalba@gmail.com>
Cc: gitster@pobox.com, git@vger.kernel.org
Subject: Re: [PATCH RESEND] Avoid a useless prefix lookup in strbuf_expand()
Date: Sun, 03 Feb 2008 13:53:32 -0800	[thread overview]
Message-ID: <7vsl09u2oz.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <1201950593-6119-1-git-send-email-mcostalba@gmail.com> (Marco Costalba's message of "Sat, 2 Feb 2008 12:09:53 +0100")

Marco Costalba <mcostalba@gmail.com> writes:

> diff --git a/pretty.c b/pretty.c
> index b987ff2..64ead65 100644
> --- a/pretty.c
> +++ b/pretty.c
> @@ -282,16 +282,18 @@ static char *logmsg_reencode(const struct commit *commit,
>  	return out;
>  }
>  
> -static void format_person_part(struct strbuf *sb, char part,
> +/* returns placeholder length or 0 if placeholder is not known */

That "return placeholder length" is a bit confusing, and I suspect
the reason may be because the interface is misdesigned.

This function gets only a single character "part" and adds the
matching information to sb if found, otherwise it doesn't, so
the only possible return values are 0 or 2.

Wouldn't it be much cleaner if this returned a bool that says "I
found and substituted that 'part' you asked me to handle"?

> +static size_t format_person_part(struct strbuf *sb, char part,
>                                 const char *msg, int len)
>  {
> -	int start, end, tz = 0;
> -	unsigned long date;
> +	int start, end, tz = 0, end_of_data;
> +	unsigned long date = 0;
>  	char *ep;
>  
> -	/* parse name */
> +	/* advance 'end' to point to email start delimiter */
>  	for (end = 0; end < len && msg[end] != '<'; end++)
>  		; /* do nothing */
> +
>  	/*
>  	 * If it does not even have a '<' and '>', that is
>  	 * quite a bogus commit author and we discard it;
> @@ -301,65 +303,72 @@ static void format_person_part(struct strbuf *sb, char part,
>  	 * which means start (beginning of email address) must
>  	 * be strictly below len.
>  	 */
> -	start = end + 1;
> -	if (start >= len - 1)
> -		return;
> -	while (end > 0 && isspace(msg[end - 1]))
> -		end--;

The comment you can see in the context seems to refer to the
logic implemented by the part you are rewriting.  Don't you need
to update it?  Also the ealier part of the same comment talks
about safety against a malformed input and explains the "return;"
you are removing here.  It is not clear where that logic has
gone...

> +	end_of_data = (end >= len - 1);
> +

The variable name "end_of_data" is unclear.  What does this
boolean mean?  The line is without address and timestamp?
The item you are parsing is not properly terminated?

>  	if (part == 'n') {	/* name */
> -		strbuf_add(sb, msg, end);
> -		return;
> +		if (!end_of_data) {
> +			while (end > 0 && isspace(msg[end - 1]))
> +				end--;
> +			strbuf_add(sb, msg, end);
> +		}
> +		return 2;
>  	}
> +	start = ++end; /* save email start position */

What happens if end_of_data was already true in this case, I
have to wonder...  Language lawyers may point out that the
result of ++end would be undefined, which I do not personally
care about in this case, but this feels dirty if not wrong.

> @@ -451,23 +460,23 @@ static void format_commit_item(struct strbuf *sb, const char *placeholder,
>  	/* these are independent of the commit */
>  	switch (placeholder[0]) {
>  	case 'C':
> -		switch (placeholder[3]) {
> -		case 'd':	/* red */
> +		if (!prefixcmp(placeholder + 1, "red")) {
>  			strbuf_addstr(sb, "\033[31m");
> -			return;
> -		case 'e':	/* green */
> +			return 4;
> +		} else if (!prefixcmp(placeholder + 1, "green")) {
>  			strbuf_addstr(sb, "\033[32m");
> -			return;
> -		case 'u':	/* blue */
> +			return 6;
> +		} else if (!prefixcmp(placeholder + 1, "blue")) {
>  			strbuf_addstr(sb, "\033[34m");
> -			return;
> -		case 's':	/* reset color */
> +			return 5;
> +		} else if (!prefixcmp(placeholder + 1, "reset")) {
>  			strbuf_addstr(sb, "\033[m");
> -			return;
> -		}
> +			return 6;
> +		} else
> +			return 0;

While these look much cleaner than using the magic "check the
third letter that happens to be unique" hack, the return values
can easily go out-of-sync.  I'd suggest to have a static array
of color names you support and iterate over it.

> @@ -528,66 +537,33 @@ static void format_commit_item(struct strbuf *sb, const char *placeholder,
>  ...
>  void format_commit_message(const struct commit *commit,
>                             const void *format, struct strbuf *sb)
>  {
> -	const char *placeholders[] = {
> -		"H",		/* commit hash */
> ...
> -		"n",		/* newline */
> -		"m",		/* left/right/bottom */
> -		NULL
> -	};
>  	struct format_commit_context context;
>  
>  	memset(&context, 0, sizeof(context));
>  	context.commit = commit;
> -	strbuf_expand(sb, format, placeholders, format_commit_item, &context);
> +	strbuf_expand(sb, format, format_commit_item, &context);
>  }

This is much nicer.  We reduced duplicated data from our code.

  reply	other threads:[~2008-02-03 21:54 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-02 11:09 [PATCH RESEND] Avoid a useless prefix lookup in strbuf_expand() Marco Costalba
2008-02-03 21:53 ` Junio C Hamano [this message]
2008-02-03 22:22   ` Marco Costalba
2008-02-05  7:00 ` Junio C Hamano
2008-02-05 13:17   ` Marco Costalba

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=7vsl09u2oz.fsf@gitster.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=mcostalba@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).