mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-05 12:53:16 +08:00
PR 32507, PRIx64 in error messages on 32-bit mingw
People, including me, had forgotten that the bfd_error_handler just handled standard printf format strings, not MSC %I64 and suchlike. Using PRIx64 and similar in errors does not work if the host compiler headers define those formats as the Microsoft %I64 variety. (We handled %ll OK, editing it to %I64 on such hosts.) PR 32507 * bfd.c (_bfd_doprnt, _bfd_doprnt_scan): Handle %I64 and %I32 in input strings if the host defines PRId64 as "I64d". Edit %ll to %I64 on detecting PRId64 as "I64d" rather than on a preprocessor define.
This commit is contained in:
parent
5e04003fac
commit
b38cf91f23
60
bfd/bfd.c
60
bfd/bfd.c
@ -1090,8 +1090,14 @@ _bfd_doprnt (bfd_print_callback print, void *stream, const char *format,
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
/* There is a clash between Microsoft's non-standard I64
|
||||
and I32 integer length modifiers and glibc's
|
||||
non-standard I flag. */
|
||||
const char *printf_flag_chars
|
||||
= sizeof PRId64 == sizeof "I64d" ? "-+ #0'" : "-+ #0'I";
|
||||
|
||||
/* Move past flags. */
|
||||
while (strchr ("-+ #0'I", *ptr))
|
||||
while (strchr (printf_flag_chars, *ptr))
|
||||
*sptr++ = *ptr++;
|
||||
|
||||
if (*ptr == '*')
|
||||
@ -1141,6 +1147,22 @@ _bfd_doprnt (bfd_print_callback print, void *stream, const char *format,
|
||||
while (ISDIGIT (*ptr))
|
||||
*sptr++ = *ptr++;
|
||||
}
|
||||
if (sizeof PRId64 == sizeof "I64d" && *ptr =='I')
|
||||
{
|
||||
if (ptr[1] == '6' && ptr[2] == '4')
|
||||
{
|
||||
wide_width = 3;
|
||||
*sptr++ = *ptr++;
|
||||
*sptr++ = *ptr++;
|
||||
*sptr++ = *ptr++;
|
||||
}
|
||||
else if (ptr[1] == '3' && ptr[2] == '2')
|
||||
{
|
||||
*sptr++ = *ptr++;
|
||||
*sptr++ = *ptr++;
|
||||
*sptr++ = *ptr++;
|
||||
}
|
||||
}
|
||||
while (strchr ("hlL", *ptr))
|
||||
{
|
||||
switch (*ptr)
|
||||
@ -1192,14 +1214,17 @@ _bfd_doprnt (bfd_print_callback print, void *stream, const char *format,
|
||||
PRINT_TYPE (long, l);
|
||||
break;
|
||||
case 2:
|
||||
if (sizeof PRId64 == sizeof "I64d")
|
||||
{
|
||||
/* Convert any %ll to %I64. */
|
||||
sptr[-3] = 'I';
|
||||
sptr[-2] = '6';
|
||||
sptr[-1] = '4';
|
||||
*sptr++ = ptr[-1];
|
||||
*sptr = '\0';
|
||||
}
|
||||
/* Fall through. */
|
||||
default:
|
||||
#if defined (__MSVCRT__)
|
||||
sptr[-3] = 'I';
|
||||
sptr[-2] = '6';
|
||||
sptr[-1] = '4';
|
||||
*sptr++ = ptr[-1];
|
||||
*sptr = '\0';
|
||||
#endif
|
||||
PRINT_TYPE (long long, ll);
|
||||
break;
|
||||
}
|
||||
@ -1322,8 +1347,14 @@ _bfd_doprnt_scan (const char *format, va_list ap, union _bfd_doprnt_args *args)
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
/* There is a clash between Microsoft's non-standard I64
|
||||
and I32 integer length modifiers and glibc's
|
||||
non-standard I flag. */
|
||||
const char *printf_flag_chars
|
||||
= sizeof PRId64 == sizeof "I64d" ? "-+ #0'" : "-+ #0'I";
|
||||
|
||||
/* Move past flags. */
|
||||
while (strchr ("-+ #0'I", *ptr))
|
||||
while (strchr (printf_flag_chars, *ptr))
|
||||
ptr++;
|
||||
|
||||
if (*ptr == '*')
|
||||
@ -1372,6 +1403,17 @@ _bfd_doprnt_scan (const char *format, va_list ap, union _bfd_doprnt_args *args)
|
||||
while (ISDIGIT (*ptr))
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (sizeof PRId64 == sizeof "I64d" && *ptr =='I')
|
||||
{
|
||||
if (ptr[1] == '6' && ptr[2] == '4')
|
||||
{
|
||||
wide_width = 3;
|
||||
ptr += 3;
|
||||
}
|
||||
else if (ptr[1] == '3' && ptr[2] == '2')
|
||||
ptr += 3;
|
||||
}
|
||||
while (strchr ("hlL", *ptr))
|
||||
{
|
||||
switch (*ptr)
|
||||
|
Loading…
Reference in New Issue
Block a user