[Python-Dev] PyErr_SafeFormat
Fredrik Lundh
Fredrik Lundh" <effbot@telia.com
Thu, 13 Jul 2000 19:29:30 +0200
greg wrote:
> We don't care about anything except for %d, %s, possibly %c and %x.
how about:
PyObject *
PyErr_SafeFormat(PyObject *exception, const char *format, ...)
{
va_list vargs;
int n;
const char* p;
char* s;
PyObject* string;
/* figure out how large buffer we need */
va_start(vargs, format);
n =3D 0;
for (p =3D format; *p; p++) {
if (*p =3D=3D '%') {
while (*++p && *p !=3D '%' && !isalpha(*p))
;
switch (*p) {
case 'c':
va_arg(vargs, int);
/* fall through... */
case '%':
n++;
break;
case 'd': case 'i': case 'x':
va_arg(vargs, int);
n =3D n + 20;
break;
case 's':
s =3D va_arg(vargs, char*);
n =3D n + strlen(s);
break;
default:
n =3D n + strlen(p);
goto expand;
}
} else
n =3D n + 1;
}
expand:
string =3D PyString_FromStringAndSize(NULL, n);
if (!string)
return NULL;
/* fill it in */
va_start(vargs, format);
s =3D PyString_AsString(string);
p =3D format;
for (p =3D format; *p; p++) {
if (*p =3D=3D '%') {
while (*++p && *p !=3D '%' && !isalpha(*p))
;
switch (*p) {
case 'c':
*s++ =3D va_arg(vargs, int);
break;
case 'd': case 'i':
itoa(va_arg(vargs, int), s, 10);
s =3D s + strlen(s);
break;
case 'x':
itoa(va_arg(vargs, int), s, 16);
s =3D s + strlen(s);
break;
case 's':
strcpy(s, va_arg(vargs, char*));
s =3D s + strlen(s);
break;
case '%':
*s++ =3D '%';
break;
default:
strcpy(s, p-1);
s =3D s + strlen(s);
goto end;
}
} else
*s++ =3D *p;
}
end:
_PyString_Resize(&string, s - PyString_AsString(string));
PyErr_SetObject(exception, string);
Py_XDECREF(string);
return NULL;
}
</F>