--- Objects/stringobject2.6b1.c 2008-06-10 14:23:22.000000000 -0700 +++ Objects/stringobject.c 2008-06-21 16:32:31.000000000 -0700 @@ -4,6 +4,7 @@ #include "Python.h" #include +#include /* DBL_DIG */ #ifdef COUNT_ALLOCS int null_strings, one_strings; @@ -200,6 +201,13 @@ This isn't enough for octal. */ n += 20; break; + case 'f': + (void) va_arg(count, double); + /* assume %f produces at most DBL_DIG + digits before and after the decimal + point, plus the latter plus a sign */ + n += DBL_DIG + 2 + DBL_DIG; + break; case 's': s = va_arg(count, char*); n += strlen(s); @@ -239,17 +247,17 @@ for (f = format; *f; f++) { if (*f == '%') { const char* p = f++; - Py_ssize_t i; + Py_ssize_t i, w; + int precision = 0; int longflag = 0; int size_tflag = 0; - /* parse the width.precision part (we're only - interested in the precision value, if any) */ - n = 0; + /* parse the width.precision, if any */ + w = n = 0; while (isdigit(Py_CHARMASK(*f))) - n = (n*10) + *f++ - '0'; + w = (w*10) + *f++ - '0'; if (*f == '.') { + precision = 1; f++; - n = 0; while (isdigit(Py_CHARMASK(*f))) n = (n*10) + *f++ - '0'; } @@ -293,6 +301,16 @@ va_arg(vargs, unsigned int)); s += strlen(s); break; + case 'f': + if (precision) { + if (n > DBL_DIG) + n = DBL_DIG; + sprintf(s, "%.*f", (int)n, va_arg(vargs, double)); + } + else + sprintf(s, "%f", va_arg(vargs, double)); + s += strlen(s); + break; case 'i': sprintf(s, "%i", va_arg(vargs, int)); s += strlen(s); @@ -306,6 +324,8 @@ i = strlen(p); if (n > 0 && i > n) i = n; + else if (w > 0 && i > w) + i = w; Py_MEMCPY(s, p, i); s += i; break; @@ -334,7 +354,7 @@ } end: - _PyString_Resize(&string, s - PyString_AS_STRING(string)); + _PyString_Resize(&string, (Py_ssize_t)(s - PyString_AS_STRING(string))); return string; }