A different approach to the problem reported in
Patch #419651: Metrowerks on Mac adds 0x itself C std says %#x and %#X conversion of 0 do not add the 0x/0X base marker. Metrowerks apparently does. Mark Favas reported the same bug under a Compaq compiler on Tru64 Unix, but no other libc broken in this respect is known (known to be OK under MSVC and gcc). So just try the damn thing at runtime and see what the platform does. Note that we've always had bugs here, but never knew it before because a relevant test case didn't exist before 2.1.
This commit is contained in:
parent
3a80c4a29c
commit
b3d8d1f76c
|
@ -2673,9 +2673,15 @@ formatint(char *buf, size_t buflen, int flags,
|
||||||
/* When converting 0 under %#x or %#X, C leaves off the base marker,
|
/* When converting 0 under %#x or %#X, C leaves off the base marker,
|
||||||
* but we want it (for consistency with other %#x conversions, and
|
* but we want it (for consistency with other %#x conversions, and
|
||||||
* for consistency with Python's hex() function).
|
* for consistency with Python's hex() function).
|
||||||
|
* BUG 28-Apr-2001 tim: At least two platform Cs (Metrowerks &
|
||||||
|
* Compaq Tru64) violate the std by converting 0 w/ leading 0x anyway.
|
||||||
|
* So add it only if the platform didn't already.
|
||||||
*/
|
*/
|
||||||
if (x == 0 && (flags & F_ALT) && (type == 'x' || type == 'X')) {
|
if (x == 0 &&
|
||||||
assert(buf[1] != type); /* else this C *is* adding 0x/0X */
|
(flags & F_ALT) &&
|
||||||
|
(type == 'x' || type == 'X') &&
|
||||||
|
buf[1] != (char)type) /* this last always true under std C */
|
||||||
|
{
|
||||||
memmove(buf+2, buf, strlen(buf) + 1);
|
memmove(buf+2, buf, strlen(buf) + 1);
|
||||||
buf[0] = '0';
|
buf[0] = '0';
|
||||||
buf[1] = (char)type;
|
buf[1] = (char)type;
|
||||||
|
|
|
@ -4737,6 +4737,7 @@ formatint(Py_UNICODE *buf,
|
||||||
+ 1 + 1 = 24*/
|
+ 1 + 1 = 24*/
|
||||||
char fmt[64]; /* plenty big enough! */
|
char fmt[64]; /* plenty big enough! */
|
||||||
long x;
|
long x;
|
||||||
|
int use_native_c_format = 1;
|
||||||
|
|
||||||
x = PyInt_AsLong(v);
|
x = PyInt_AsLong(v);
|
||||||
if (x == -1 && PyErr_Occurred())
|
if (x == -1 && PyErr_Occurred())
|
||||||
|
@ -4753,10 +4754,20 @@ formatint(Py_UNICODE *buf,
|
||||||
/* When converting 0 under %#x or %#X, C leaves off the base marker,
|
/* When converting 0 under %#x or %#X, C leaves off the base marker,
|
||||||
* but we want it (for consistency with other %#x conversions, and
|
* but we want it (for consistency with other %#x conversions, and
|
||||||
* for consistency with Python's hex() function).
|
* for consistency with Python's hex() function).
|
||||||
|
* BUG 28-Apr-2001 tim: At least two platform Cs (Metrowerks &
|
||||||
|
* Compaq Tru64) violate the std by converting 0 w/ leading 0x anyway.
|
||||||
|
* So add it only if the platform doesn't already.
|
||||||
*/
|
*/
|
||||||
if (x == 0 && (flags & F_ALT) && (type == 'x' || type == 'X'))
|
if (x == 0 && (flags & F_ALT) && (type == 'x' || type == 'X')) {
|
||||||
sprintf(fmt, "0%c%%%s.%dl%c", type, "#", prec, type);
|
/* Only way to know what the platform does is to try it. */
|
||||||
else
|
sprintf(fmt, type == 'x' ? "%#x" : "%#X", 0);
|
||||||
|
if (fmt[1] != (char)type) {
|
||||||
|
/* Supply our own leading 0x/0X -- needed under std C */
|
||||||
|
use_native_c_format = 0;
|
||||||
|
sprintf(fmt, "0%c%%#.%dl%c", type, prec, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (use_native_c_format)
|
||||||
sprintf(fmt, "%%%s.%dl%c", (flags & F_ALT) ? "#" : "", prec, type);
|
sprintf(fmt, "%%%s.%dl%c", (flags & F_ALT) ? "#" : "", prec, type);
|
||||||
return usprintf(buf, fmt, x);
|
return usprintf(buf, fmt, x);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue