[Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.149,2.150 unicodeobject.c,2.129,2.130
Andrew I MacIntyre
aimacintyre@users.sourceforge.net
Thu, 28 Feb 2002 03:38:26 -0800
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv6793/dist/src/Objects
Modified Files:
stringobject.c unicodeobject.c
Log Message:
%#x/%#X format conversion cleanup (see patch #450267):
Objects/
stringobject.c
unicodeobject.c
Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.149
retrieving revision 2.150
diff -C2 -d -r2.149 -r2.150
*** stringobject.c 26 Feb 2002 11:36:35 -0000 2.149
--- stringobject.c 28 Feb 2002 11:38:24 -0000 2.150
***************
*** 3070,3082 ****
char fmt[64]; /* plenty big enough! */
long x;
if (!PyArg_Parse(v, "l;int argument required", &x))
return -1;
if (prec < 0)
prec = 1;
! PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%dl%c",
! (flags&F_ALT) ? "#" : "",
! prec, type);
/* buf = '+'/'-'/'0'/'0x' + '[0-9]'*max(prec, len(x in octal))
! worst case buf = '0x' + [0-9]*prec, where prec >= 11 */
if (buflen <= 13 || buflen <= (size_t)2 + (size_t)prec) {
PyErr_SetString(PyExc_OverflowError,
--- 3070,3113 ----
char fmt[64]; /* plenty big enough! */
long x;
+
if (!PyArg_Parse(v, "l;int argument required", &x))
return -1;
if (prec < 0)
prec = 1;
!
! if ((flags & F_ALT) &&
! (type == 'x' || type == 'X')) {
! /* When converting under %#x or %#X, there are a number
! * of issues that cause pain:
! * - when 0 is being converted, the C standard leaves off
! * the '0x' or '0X', which is inconsistent with other
! * %#x/%#X conversions and inconsistent with Python's
! * hex() function
! * - there are platforms that violate the standard and
! * convert 0 with the '0x' or '0X'
! * (Metrowerks, Compaq Tru64)
! * - there are platforms that give '0x' when converting
! * under %#X, but convert 0 in accordance with the
! * standard (OS/2 EMX)
! *
! * We can achieve the desired consistency by inserting our
! * own '0x' or '0X' prefix, and substituting %x/%X in place
! * of %#x/%#X.
! *
! * Note that this is the same approach as used in
! * formatint() in unicodeobject.c
! */
! PyOS_snprintf(fmt, sizeof(fmt), "0%c%%.%dl%c",
! type, prec, type);
! }
! else {
! PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%dl%c",
! (flags&F_ALT) ? "#" : "",
! prec, type);
! }
!
/* buf = '+'/'-'/'0'/'0x' + '[0-9]'*max(prec, len(x in octal))
! * worst case buf = '0x' + [0-9]*prec, where prec >= 11
! */
if (buflen <= 13 || buflen <= (size_t)2 + (size_t)prec) {
PyErr_SetString(PyExc_OverflowError,
***************
*** 3085,3113 ****
}
PyOS_snprintf(buf, buflen, fmt, x);
- /* When converting 0 under %#x or %#X, C leaves off the base marker,
- * but we want it (for consistency with other %#x conversions, and
- * 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') &&
- buf[1] != (char)type) /* this last always true under std C */
- {
- memmove(buf+2, buf, strlen(buf) + 1);
- buf[0] = '0';
- buf[1] = (char)type;
- }
- #if defined(PYOS_OS2) && defined(PYCC_GCC)
- /* unfortunately, the EMX C runtime gives us '0x' as the base
- * marker for %X when we expect/want '0X'
- */
- else if ((flags & F_ALT) && (type == 'X')) {
- assert(buf[1] == 'x');
- buf[1] = (char)type;
- }
- #endif
return strlen(buf);
}
--- 3116,3119 ----
Index: unicodeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v
retrieving revision 2.129
retrieving revision 2.130
diff -C2 -d -r2.129 -r2.130
*** unicodeobject.c 26 Feb 2002 11:36:35 -0000 2.129
--- unicodeobject.c 28 Feb 2002 11:38:24 -0000 2.130
***************
*** 5138,5188 ****
{
/* fmt = '%#.' + `prec` + 'l' + `type`
! worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine)
! + 1 + 1 = 24*/
char fmt[64]; /* plenty big enough! */
long x;
- int use_native_c_format = 1;
x = PyInt_AsLong(v);
if (x == -1 && PyErr_Occurred())
! return -1;
if (prec < 0)
! prec = 1;
/* buf = '+'/'-'/'0'/'0x' + '[0-9]'*max(prec,len(x in octal))
! worst case buf = '0x' + [0-9]*prec, where prec >= 11 */
! if (buflen <= 13 || buflen <= (size_t)2+(size_t)prec) {
PyErr_SetString(PyExc_OverflowError,
! "formatted integer is too long (precision too long?)");
return -1;
}
! /* When converting 0 under %#x or %#X, C leaves off the base marker,
! * but we want it (for consistency with other %#x conversions, and
! * 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 defined(PYOS_OS2) && defined(PYCC_GCC)
! if ((flags & F_ALT) && (type == 'x' || type == 'X')) {
! /* the EMX runtime gives 0x as the base marker when we want 0X
! * so we cover all bets by supplying our own for both cases.
*/
! use_native_c_format = 0;
! PyOS_snprintf(fmt, sizeof(fmt), "0%c%%.%dl%c", type, prec, type);
}
! #else
! if (x == 0 && (flags & F_ALT) && (type == 'x' || type == 'X')) {
! /* Only way to know what the platform does is to try it. */
! PyOS_snprintf(fmt, sizeof(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;
! PyOS_snprintf(fmt, sizeof(fmt), "0%c%%#.%dl%c", type, prec, type);
! }
}
- #endif
- if (use_native_c_format)
- PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%dl%c",
- (flags & F_ALT) ? "#" : "", prec, type);
return usprintf(buf, fmt, x);
}
--- 5138,5193 ----
{
/* fmt = '%#.' + `prec` + 'l' + `type`
! * worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine)
! * + 1 + 1
! * = 24
! */
char fmt[64]; /* plenty big enough! */
long x;
x = PyInt_AsLong(v);
if (x == -1 && PyErr_Occurred())
! return -1;
if (prec < 0)
! prec = 1;
!
/* buf = '+'/'-'/'0'/'0x' + '[0-9]'*max(prec,len(x in octal))
! * worst case buf = '0x' + [0-9]*prec, where prec >= 11
! */
! if (buflen <= 13 || buflen <= (size_t)2 + (size_t)prec) {
PyErr_SetString(PyExc_OverflowError,
! "formatted integer is too long (precision too large?)");
return -1;
}
!
! if ((flags & F_ALT) &&
! (type == 'x' || type == 'X')) {
! /* When converting under %#x or %#X, there are a number
! * of issues that cause pain:
! * - when 0 is being converted, the C standard leaves off
! * the '0x' or '0X', which is inconsistent with other
! * %#x/%#X conversions and inconsistent with Python's
! * hex() function
! * - there are platforms that violate the standard and
! * convert 0 with the '0x' or '0X'
! * (Metrowerks, Compaq Tru64)
! * - there are platforms that give '0x' when converting
! * under %#X, but convert 0 in accordance with the
! * standard (OS/2 EMX)
! *
! * We can achieve the desired consistency by inserting our
! * own '0x' or '0X' prefix, and substituting %x/%X in place
! * of %#x/%#X.
! *
! * Note that this is the same approach as used in
! * formatint() in stringobject.c
*/
! PyOS_snprintf(fmt, sizeof(fmt), "0%c%%.%dl%c",
! type, prec, type);
}
! else {
! PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%dl%c",
! (flags&F_ALT) ? "#" : "",
! prec, type);
}
return usprintf(buf, fmt, x);
}