[Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.124,2.125
Barry Warsaw
bwarsaw@users.sourceforge.net
Fri, 24 Aug 2001 11:32:08 -0700
- Previous message: [Python-checkins] CVS: python/dist/src/Include stringobject.h,2.28,2.29
- Next message: [Python-checkins] CVS: python/dist/src/Objects bufferobject.c,2.14,2.15 cellobject.c,1.3,1.4 classobject.c,2.140,2.141 descrobject.c,2.7,2.8 fileobject.c,2.118,2.119 funcobject.c,2.40,2.41 methodobject.c,2.37,2.38 moduleobject.c,2.35,2.36 object.c,2.139,2.140 rangeobject.c,2.28,2.29 typeobject.c,2.45,2.46
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv13719/Objects
Modified Files:
stringobject.c
Log Message:
PyString_FromFormat() and PyString_FromFormatV(): Largely ripped from
PyErr_Format() these new C API methods can be used instead of
sprintf()'s into hardcoded char* buffers. This allows us to fix
many situation where long package, module, or class names get
truncated in reprs.
PyString_FromFormat() is the varargs variety.
PyString_FromFormatV() is the va_list variety
Original PyErr_Format() code was modified to allow %p and %ld
expansions.
Many reprs were converted to this, checkins coming soo. Not
changed: complex_repr(), float_repr(), float_print(), float_str(),
int_repr(). There may be other candidates not yet converted.
Closes patch #454743.
Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.124
retrieving revision 2.125
diff -C2 -d -r2.124 -r2.125
*** stringobject.c 2001/08/17 18:39:25 2.124
--- stringobject.c 2001/08/24 18:32:06 2.125
***************
*** 148,151 ****
--- 148,306 ----
}
+ PyObject *
+ PyString_FromFormatV(const char *format, va_list vargs)
+ {
+ va_list count = vargs;
+ int n = 0;
+ const char* f;
+ char *s;
+ PyObject* string;
+
+ /* step 1: figure out how large a buffer we need */
+ for (f = format; *f; f++) {
+ if (*f == '%') {
+ const char* p = f;
+ while (*++f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
+ ;
+
+ /* skip the 'l' in %ld, since it doesn't change the
+ width. although only %d is supported (see
+ "expand" section below), others can be easily
+ add */
+ if (*f == 'l' && *(f+1) == 'd')
+ ++f;
+
+ switch (*f) {
+ case 'c':
+ (void)va_arg(count, int);
+ /* fall through... */
+ case '%':
+ n++;
+ break;
+ case 'd': case 'i': case 'x':
+ (void) va_arg(count, int);
+ /* 20 bytes should be enough to hold a 64-bit
+ integer */
+ n += 20;
+ break;
+ case 's':
+ s = va_arg(count, char*);
+ n += strlen(s);
+ break;
+ case 'p':
+ (void) va_arg(count, int);
+ /* maximum 64-bit pointer representation:
+ * 0xffffffffffffffff
+ * so 19 characters is enough.
+ */
+ n += 19;
+ 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 += strlen(p);
+ goto expand;
+ }
+ } else
+ n++;
+ }
+ expand:
+ /* step 2: fill the buffer */
+ string = PyString_FromStringAndSize(NULL, n);
+ if (!string)
+ return NULL;
+
+ s = PyString_AsString(string);
+
+ for (f = format; *f; f++) {
+ if (*f == '%') {
+ const char* p = f++;
+ int i, longflag = 0;
+ /* 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++;
+ /* handle the long flag, but only for %ld. others
+ can be added when necessary. */
+ if (*f == 'l' && *(f+1) == 'd') {
+ longflag = 1;
+ ++f;
+ }
+
+ switch (*f) {
+ case 'c':
+ *s++ = va_arg(vargs, int);
+ break;
+ case 'd':
+ if (longflag)
+ sprintf(s, "%ld", va_arg(vargs, long));
+ else
+ sprintf(s, "%d", va_arg(vargs, int));
+ s += strlen(s);
+ break;
+ case 'i':
+ sprintf(s, "%i", va_arg(vargs, int));
+ s += strlen(s);
+ break;
+ case 'x':
+ sprintf(s, "%x", va_arg(vargs, int));
+ 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 += i;
+ break;
+ case 'p':
+ sprintf(s, "%p", va_arg(vargs, void*));
+ s += strlen(s);
+ break;
+ case '%':
+ *s++ = '%';
+ break;
+ default:
+ strcpy(s, p);
+ s += strlen(s);
+ goto end;
+ }
+ } else
+ *s++ = *f;
+ }
+
+ end:
+ _PyString_Resize(&string, s - PyString_AsString(string));
+ return string;
+ }
+
+ PyObject *
+ PyString_FromFormat(const char *format, ...)
+ {
+ va_list vargs;
+
+ #ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+ #else
+ va_start(vargs);
+ #endif
+ return PyString_FromFormatV(format, vargs);
+ }
+
+
PyObject *PyString_Decode(const char *s,
int size,
- Previous message: [Python-checkins] CVS: python/dist/src/Include stringobject.h,2.28,2.29
- Next message: [Python-checkins] CVS: python/dist/src/Objects bufferobject.c,2.14,2.15 cellobject.c,1.3,1.4 classobject.c,2.140,2.141 descrobject.c,2.7,2.8 fileobject.c,2.118,2.119 funcobject.c,2.40,2.41 methodobject.c,2.37,2.38 moduleobject.c,2.35,2.36 object.c,2.139,2.140 rangeobject.c,2.28,2.29 typeobject.c,2.45,2.46
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]