2017-07-19 1:35 GMT+08:00 Junio C Hamano <gitster@xxxxxxxxx>: > Jiang Xin <worldhello.net@xxxxxxxxx> writes: > >>> Two potential issues are: >>> >>> - After this patch, there still are quite a many >>> >>> printf("time is %"PRItime" ...\n", timestamp) >>> >>> so the burden on the programmers having to remember when it is >>> required to use format_raw_time() becomes unclear, and makes the >>> change/churn larger when an existing message needs to be marked >>> for translation. >>> >>> - The static struct strbuf here is a cheap way to avoid leaks, but >>> at the same time it is unfriendly to threaded code. We could >>> instead do: >>> >>> void append_PRItime(struct strbuf *buf, timestamp_t time); >>> >>> to fix that trivially, but the damage to the caller obviously is >>> much larger going this way. >>> >> >> I wonder if we can replace the original %lu for timestamp with PRIuMAX >> instead. PRIuMAX works fine with gettext utils. > > I think the question can better be answered if we know how gettext > tools special case PRIuMAX. One thing that may be problematic is > that timestamp can later become a signed type and use of one level > of redirection in the current code via PRItime and via timestamp_t > is a good way to keep such a transition much easier. Reverting it > to use PRIuMAX would make such a transition much harder. Gettext handles macros such as PRIuMAX in commit 8b45c5df1 ("Add support for ISO C 99 <inttypes.h> format string directive macros.", 2002-07-23 12:33:13 +0000). Macros such as PRIuMAX are hard coded, and we can not hack gettext easily and directly. For example, some code in commit 8b45c5df1 (see: See: http://git.savannah.gnu.org/cgit/gettext.git/commit/?id=8b45c5df18e1976a1275297db73978bfe6144c7e): +/* 8a. Convert ISO C 99 section 7.8.1 format string directives to string + literal placeholders. */ + +/* Test for an ISO C 99 section 7.8.1 format string directive. */ +static bool +is_inttypes_macro (name) + const char *name; +{ + /* Syntax: + P R I { d | i | o | u | x | X } + { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR } */ + if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I') + { + name += 3; + if (name[0] == 'd' || name[0] == 'i' || name[0] == 'o' || name[0] == 'u' + || name[0] == 'x' || name[0] == 'X') + { + name += 1; + if (name[0] == 'M' && name[1] == 'A' && name[2] == 'X' + && name[3] == '\0') + return true; + if (name[0] == 'P' && name[1] == 'T' && name[2] == 'R' + && name[3] == '\0') + return true; + if (name[0] == 'L' && name[1] == 'E' && name[2] == 'A' + && name[3] == 'S' && name[4] == 'T') + name += 5; + else if (name[0] == 'F' && name[1] == 'A' && name[2] == 'S' + && name[3] == 'T') + name += 4; + if (name[0] == '8' && name[1] == '\0') + return true; + if (name[0] == '1' && name[1] == '6' && name[2] == '\0') + return true; + if (name[0] == '3' && name[1] == '2' && name[2] == '\0') + return true; + if (name[0] == '6' && name[1] == '4' && name[2] == '\0') + return true; + } + } + return false; +} + if (*format == '<') { - if (*format == 'h') + spec.c99_directives = + (const char **) + xrealloc (spec.c99_directives, + 2 * (spec.c99_directives_count + 1) + * sizeof (const char *)); + spec.c99_directives[2 * spec.c99_directives_count] = format; + + format++; + /* Parse ISO C 99 section 7.8.1 format string directive. + Syntax: + P R I { d | i | o | u | x | X } + { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR } */ + if (*format != 'P') + goto bad_format; + format++; + if (*format != 'R') + goto bad_format; + format++; + if (*format != 'I') + goto bad_format; + format++; + + switch (*format) + { + case 'i': case 'd': + type = FAT_INTEGER; + break; + case 'u': case 'o': case 'x': case 'X': + type = FAT_INTEGER | FAT_UNSIGNED; + break; + default: + goto bad_format; + } + format++; + + if (format[0] == 'M' && format[1] == 'A' && format[2] == 'X') + { + type |= FAT_SIZE_INTMAX_T; + format += 3; + } + else if (format[0] == 'P' && format[1] == 'T' && format[2] == 'R') -- Jiang Xin