PyErr_Format(): Factor out most of this code into
authorBarry Warsaw <barry@python.org>
Fri, 24 Aug 2001 18:35:23 +0000 (18:35 +0000)
committerBarry Warsaw <barry@python.org>
Fri, 24 Aug 2001 18:35:23 +0000 (18:35 +0000)
    PyString_FromFormat() since it's much more generally useful than
    just for exceptions.

Python/errors.c

index 89d956f9777006ec3952ed7cf969a587ca4349b1..8a4568fc678f7cf8bc9089516bbeac68dbf16835 100644 (file)
@@ -385,128 +385,15 @@ PyObject *
 PyErr_Format(PyObject *exception, const char *format, ...)
 {
        va_list vargs;
-       int n, i;
-       const char* f;
-       char* s;
        PyObject* string;
 
-       /* step 1: figure out how large a buffer we need */
-
-#ifdef HAVE_STDARG_PROTOTYPES
-       va_start(vargs, format);
-#else
-       va_start(vargs);
-#endif
-
-       n = 0;
-       for (f = format; *f; f++) {
-               if (*f == '%') {
-                       const char* p = f;
-                       while (*++f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
-                               ;
-                       switch (*f) {
-                       case 'c':
-                               (void) va_arg(vargs, int);
-                               /* fall through... */
-                       case '%':
-                               n++;
-                               break;
-                       case 'd': case 'i': case 'x':
-                               (void) va_arg(vargs, int);
-                               /* 20 bytes should be enough to hold a 64-bit
-                                  integer */
-                               n = n + 20;
-                               break;
-                       case 's':
-                               s = va_arg(vargs, char*);
-                               n = n + strlen(s);
-                               break;
-                       default:
-                               /* if we stumble upon an unknown
-                                  formatting code, copy the rest of
-                                  the format string to the output
-                                  string. (we cannot just skip the
-                                  code, since there's no way to know
-                                  what's in the argument list) */ 
-                               n = n + strlen(p);
-                               goto expand;
-                       }
-               } else
-                       n = n + 1;
-       }
-       
- expand:
-       
-       string = PyString_FromStringAndSize(NULL, n);
-       if (!string)
-               return NULL;
-       
 #ifdef HAVE_STDARG_PROTOTYPES
        va_start(vargs, format);
 #else
        va_start(vargs);
 #endif
 
-       /* step 2: fill the buffer */
-
-       s = PyString_AsString(string);
-
-       for (f = format; *f; f++) {
-               if (*f == '%') {
-                       const char* p = f++;
-                       /* parse the width.precision part (we're only
-                          interested in the precision value, if any) */
-                       n = 0;
-                       while (isdigit(Py_CHARMASK(*f)))
-                               n = (n*10) + *f++ - '0';
-                       if (*f == '.') {
-                               f++;
-                               n = 0;
-                               while (isdigit(Py_CHARMASK(*f)))
-                                       n = (n*10) + *f++ - '0';
-                       }
-                       while (*f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
-                               f++;
-                       switch (*f) {
-                       case 'c':
-                               *s++ = va_arg(vargs, int);
-                               break;
-                       case 'd': 
-                               sprintf(s, "%d", va_arg(vargs, int));
-                               s = s + strlen(s);
-                               break;
-                       case 'i':
-                               sprintf(s, "%i", va_arg(vargs, int));
-                               s = s + strlen(s);
-                               break;
-                       case 'x':
-                               sprintf(s, "%x", va_arg(vargs, int));
-                               s = s + strlen(s);
-                               break;
-                       case 's':
-                               p = va_arg(vargs, char*);
-                               i = strlen(p);
-                               if (n > 0 && i > n)
-                                       i = n;
-                               memcpy(s, p, i);
-                               s = s + i;
-                               break;
-                       case '%':
-                               *s++ = '%';
-                               break;
-                       default:
-                               strcpy(s, p);
-                               s = s + strlen(s);
-                               goto end;
-                       }
-               } else
-                       *s++ = *f;
-       }
-       
- end:
-       
-       _PyString_Resize(&string, s - PyString_AsString(string));
-       
+       string = PyString_FromFormatV(format, vargs);
        PyErr_SetObject(exception, string);
        Py_XDECREF(string);