All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Nieder <jrnieder@gmail.com>
To: Brian Koropoff <bkoropoff@gmail.com>
Cc: dash@vger.kernel.org
Subject: Re: [PATCH 1/2] Fix additional use of 'j' printf length modifier.
Date: Fri, 15 Apr 2011 23:54:35 -0500	[thread overview]
Message-ID: <20110416045435.GA10455@elie> (raw)
In-Reply-To: <1302921279.2620.6.camel@gemini>

Hi,

Brian Koropoff wrote:

> The printf builtin modifies the user's format strings
> by prefixing integer conversion specifications with the
> 'j' (intmax_t) length modifier.  Since this is not portable,
> instead prefix them with the length modifier extracted from
> the PRIdMAX constant.

This assumes PRIdMAX, PRIxMAX, etc all consist of the same prefix
before the standard characters.  Since the most common definitions
are j<usual char>, l<usual char>, q<usual char>, I64<usual char>,
and ll<usual char>, that's probably a safe assumption.  I wonder why
C99 and its predecessors did not use

	printf("%"PRIMAX"x\n", val);

Oh well.  Maybe it would warrant a comment, though?

	/*
	 * Replace a string like
	 *
	 *	%92.3u
	 *	^    ^--- ch
	 *	'-------- str
	 *
	 * with "%92.3" PRIuMAX "".
	 *
	 * Although C99 does not guarantee it, we assume PRIiMAX,
	 * PRIoMAX, PRIuMAX, PRIxMAX, and PRIXMAX are all the same
	 * as PRIdMAX with the final 'd' replaced by the corresponding
	 * character.
	 */

> --- a/src/bltin/printf.c
> +++ b/src/bltin/printf.c
> @@ -317,15 +317,16 @@ static char *
>  mklong(const char *str, const char *ch)
>  {
>  	char *copy;
> -	size_t len;	
> +	size_t len;
> +	size_t pridmax_len = strlen(PRIdMAX);

I think just using strlen(PRIdMAX) as-is would make it clearer that we
are expecting the compiler to inline the "strlen" and provides a
reminder of the value, too (i.e., is it 2 or 3 for "jd"?).

>  
> -	len = ch - str + 3;
> +	len = ch - str + pridmax_len;

This changes the meaning of "len" to no longer be the size of the
buffer.  I suppose that doesn't matter, but...

>  	STARTSTACKSTR(copy);
> -	copy = makestrspace(len, copy);
> -	memcpy(copy, str, len - 3);
> -	copy[len - 3] = 'j';
> -	copy[len - 2] = *ch;
> -	copy[len - 1] = '\0';
> +	copy = makestrspace(len + 1, copy);
> +	memcpy(copy, str, len - pridmax_len);
> +	memcpy(copy + len - pridmax_len, PRIdMAX, pridmax_len - 1);
> +	copy[len - 1] = *ch;
> +	copy[len] = '\0';

... the arithmetic is getting complicated.  I think mempcpy could make
the intention clearer, like so.

	char *p;
	[...]
	len = ch - str + strlen(PRIdMAX) + 1;
	p = copy = makestrspace(len, copy);
	p = mempcpy(p, str, ch - str);
	p = mempcpy(p, PRIdMAX, strlen(PRIdMAX) - 1);
	*p++ = *ch;
	*p++ = '\0';

Like this, maybe (on top, untested)?

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 src/bltin/printf.c |   23 ++++++++++++++++-------
 1 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/bltin/printf.c b/src/bltin/printf.c
index 4ac2ee8..0b4a4e1 100644
--- a/src/bltin/printf.c
+++ b/src/bltin/printf.c
@@ -317,16 +317,25 @@ static char *
 mklong(const char *str, const char *ch)
 {
 	char *copy;
+	char *p;
 	size_t len;
-	size_t pridmax_len = strlen(PRIdMAX);
 
-	len = ch - str + pridmax_len;
+	/*
+	 * Replace a string like "%92.3u" with "%92.3"PRIuMAX.
+	 *
+	 * Although C99 does not guarantee it, we assume PRIiMAX,
+	 * PRIoMAX, PRIuMAX, PRIxMAX, and PRIXMAX are all the same
+	 * as PRIdMAX with the final 'd' replaced by the corresponding
+	 * character.
+	 */
+
+	len = ch - str + strlen(PRIdMAX) + 1;
 	STARTSTACKSTR(copy);
-	copy = makestrspace(len + 1, copy);
-	memcpy(copy, str, len - pridmax_len);
-	memcpy(copy + len - pridmax_len, PRIdMAX, pridmax_len - 1);
-	copy[len - 1] = *ch;
-	copy[len] = '\0';
+	p = copy = makestrspace(len, copy);
+	p = mempcpy(p, str, ch - str);
+	p = mempcpy(p, PRIdMAX, strlen(PRIdMAX) - 1);
+	*p++ = *ch;
+	*p++ = '\0';
 	return (copy);	
 }
 
-- 
1.7.5.rc2


  reply	other threads:[~2011-04-16  4:54 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-16  2:30 Fix for Solaris patch and new HP-UX patch Brian Koropoff
2011-04-16  2:34 ` [PATCH 1/2] Fix additional use of 'j' printf length modifier Brian Koropoff
2011-04-16  4:54   ` Jonathan Nieder [this message]
2011-04-16 18:25     ` Brian Koropoff
2011-07-07  6:41   ` Herbert Xu
2011-07-07  7:12     ` Jonathan Nieder
2011-07-07  7:32       ` Brian Koropoff
2011-07-07  7:44         ` Herbert Xu
2011-04-16  2:34 ` [PATCH 2/2] Port to HP-UX Brian Koropoff

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=20110416045435.GA10455@elie \
    --to=jrnieder@gmail.com \
    --cc=bkoropoff@gmail.com \
    --cc=dash@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.