klibc-bot for Harald van Dijk
2020-Mar-28 21:48 UTC
[klibc] [klibc:update-dash] dash: [BUILTIN] Use PRIdMAX instead of %j in printf
Commit-ID: a436ea0721c8d7ff6d0d9e4d46d8ae4655e8a73a Gitweb: http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=a436ea0721c8d7ff6d0d9e4d46d8ae4655e8a73a Author: Harald van Dijk <harald at gigawatt.nl> AuthorDate: Fri, 23 Aug 2013 20:30:28 +1000 Committer: Ben Hutchings <ben at decadent.org.uk> CommitDate: Sat, 28 Mar 2020 21:42:54 +0000 [klibc] dash: [BUILTIN] Use PRIdMAX instead of %j in printf [ dash commit 5464ae7d9e226586b79527cb445d892177b70271 ] On 12/03/2012 05:59 PM, Harald van Dijk wrote:> On 12/03/2012 08:42 AM, Roy wrote: >> MSYS libc does not support %j[dXx] format, only %ll[dXx] is supported. >> >> diff --git a/src/bltin/printf.c b/src/bltin/printf.c >> index 893295c..12ce660 100644 >> --- a/src/bltin/printf.c >> +++ b/src/bltin/printf.c >> @@ -319,11 +319,12 @@ mklong(const char *str, const char *ch) >> char *copy; >> size_t len; >> >> - len = ch - str + 3; >> + len = ch - str + 4; >> STARTSTACKSTR(copy); >> copy = makestrspace(len, copy); >> - memcpy(copy, str, len - 3); >> - copy[len - 3] = 'j'; >> + memcpy(copy, str, len - 4); >> + copy[len - 4] = 'l'; >> + copy[len - 3] = 'l'; >> copy[len - 2] = *ch; >> copy[len - 1] = '\0'; >> return (copy); > > The calling code uses the result to print intmax_t and uintmax_t values. > Printing intmax_t values with %lld is wrong, this will only work if > intmax_t is really a typedef for long long (which may be true on your > system, but is not required by the standard). > > The other patch that Jonathan linked to should work just fine.Here's a slightly tweaked version of that patch. Regardless of whether PRIdMAX is defined as "jd" or as "lld", the use of memcpy here, first copying "jd"/"lld" and the null byte, and only changing the 'd' after that, surprisingly results in slightly shorter object code than the original byte-by-byte approach, even though memcpy is fully inlined. Perhaps that could be a reason for applying this, even if the original reason for it, making the code work on not-quite-conforming systems, isn't good enough to get it in dash. Tested with normal glibc, and with glibc hacked to not provide PRIdMAX. Reviewed-by: Jonathan Nieder <jrnieder at gmail.com> Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au> Signed-off-by: Ben Hutchings <ben at decadent.org.uk> --- usr/dash/bltin/printf.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/usr/dash/bltin/printf.c b/usr/dash/bltin/printf.c index dcff0992..add89095 100644 --- a/usr/dash/bltin/printf.c +++ b/usr/dash/bltin/printf.c @@ -320,16 +320,24 @@ out: static char * mklong(const char *str, const char *ch) { + /* + * 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. + */ + char *copy; size_t len; - len = ch - str + 3; + len = ch - str + sizeof(PRIdMAX); STARTSTACKSTR(copy); copy = makestrspace(len, copy); - memcpy(copy, str, len - 3); - copy[len - 3] = 'j'; + memcpy(copy, str, len - sizeof(PRIdMAX)); + memcpy(copy + len - sizeof(PRIdMAX), PRIdMAX, sizeof(PRIdMAX)); copy[len - 2] = *ch; - copy[len - 1] = '\0'; return (copy); }
Possibly Parallel Threads
- [klibc:update-dash] [BUILTIN] Use PRIdMAX instead of %j in printf
- [klibc:update-dash] [BUILTIN] Remove getintmax in printf
- [klibc:update-dash] dash: [BUILTIN] Remove getintmax in printf
- [klibc:update-dash] dash: Fix some cosmetic differences from upstream dash
- [klibc:update-dash] dash: Fix some cosmetic differences from upstream dash