sizeof(PyStringObject), sizeof(char), string_dealloc, /* tp_dealloc */ (printfunc)string_print, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ string_repr, /* tp_repr */ &string_as_number, /* tp_as_number */ &string_as_sequence, /* tp_as_sequence */ &string_as_mapping, /* tp_as_mapping */ (hashfunc)string_hash, /* tp_hash */ 0, /* tp_call */ string_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ &string_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | Py_TPFLAGS_BASETYPE, /* tp_flags */ string_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ (richcmpfunc)string_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ string_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ &PyBaseString_Type, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ string_new, /* tp_new */ PyObject_Del, /* tp_free */}; voidPyString_Concat(register PyObject **pv, register PyObject *w){ register PyObject *v; if (*pv == NULL) return; if (w == NULL || !PyString_Check(*pv)) { Py_DECREF(*pv); *pv = NULL; return; } v = string_concat((PyStringObject *) *pv, w); Py_DECREF(*pv); *pv = v;} voidPyString_ConcatAndDel(register PyObject **pv, register PyObject *w){ PyString_Concat(pv, w); Py_XDECREF(w);} /* The following function breaks the notion that strings are immutable: it changes the size of a string. We get away with this only if there is only one module referencing the object. You can also think of it as creating a new string object and destroying the old one, only more efficiently. In any case, don't use this if the string may already be known to some other part of the code... Note that if there's not enough memory to resize the string, the original string object at *pv is deallocated, *pv is set to NULL, an "out of memory" exception is set, and -1 is returned. Else (on success) 0 is returned, and the value in *pv may or may not be the same as on input. As always, an extra byte is allocated for a trailing \0 byte (newsize does *not* include that), and a trailing \0 byte is stored.*/ int_PyString_Resize(PyObject **pv, Py_ssize_t newsize){ register PyObject *v; register PyStringObject *sv; v = *pv; if (!PyString_Check(v) || v->ob_refcnt != 1 || newsize < 0 || PyString_CHECK_INTERNED(v)) { *pv = 0; Py_DECREF(v); PyErr_BadInternalCall(); return -1; } /* XXX UNREF/NEWREF interface should be more symmetrical */ _Py_DEC_REFTOTAL; _Py_ForgetReference(v); *pv = (PyObject *) PyObject_REALLOC((char *)v, sizeof(PyStringObject) + newsize); if (*pv == NULL) { PyObject_Del(v); PyErr_NoMemory(); return -1; } _Py_NewReference(*pv); sv = (PyStringObject *) *pv; sv->ob_size = newsize; sv->ob_sval[newsize] = '\0'; sv->ob_shash = -1; /* invalidate cached hash value */ return 0;} /* Helpers for formatstring */ Py_LOCAL_INLINE(PyObject *)getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx){ Py_ssize_t argidx = *p_argidx; if (argidx < arglen) { (*p_argidx)++; if (arglen < 0) return args; else return PyTuple_GetItem(args, argidx); } PyErr_SetString(PyExc_TypeError, "not enough arguments for format string"); return NULL;} /* Format codes * F_LJUST '-' * F_SIGN '+' * F_BLANK ' ' * F_ALT '#' * F_ZERO '0' */#define F_LJUST (1<<0)#define F_SIGN (1<<1)#define F_BLANK (1<<2)#define F_ALT (1<<3)#define F_ZERO (1<<4) Py_LOCAL_INLINE(int)formatfloat(char *buf, size_t buflen, int flags, int prec, int type, PyObject *v){ /* fmt = '%#.' + `prec` + `type` worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/ char fmt[20]; double x; x = PyFloat_AsDouble(v); if (x == -1.0 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "float argument required"); return -1; } if (prec < 0) prec = 6; if (type == 'f' && fabs(x)/1e25 >= 1e25) type = 'g'; /* Worst case length calc to ensure no buffer overrun: 'g' formats: fmt = %#.<prec>g buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp for any double rep.) len = 1 + prec + 1 + 2 + 5 = 9 + prec 'f' formats: buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) len = 1 + 50 + 1 + prec = 52 + prec If prec=0 the effective precision is 1 (the leading digit is always given), therefore increase the length by one. */ if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) || (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) { PyErr_SetString(PyExc_OverflowError, "formatted float is too long (precision too large?)"); return -1; } PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", (flags&F_ALT) ? "#" : "", prec, type); PyOS_ascii_formatd(buf, buflen, fmt, x); return (int)strlen(buf);} /* _PyString_FormatLong emulates the format codes d, u, o, x and X, and * the F_ALT flag, for Python's long (unbounded) ints. It's not used for * Python's regular ints. * Return value: a new PyString*, or NULL if error. * . *pbuf is set to point into it, * *plen set to the # of chars following that. * Caller must decref it when done using pbuf. * The string starting at *pbuf is of the form * "-"? ("0x" | "0X")? digit+ * "0x"/"0X" are present only for x and X conversions, with F_ALT * set in flags. The case of hex digits will be correct, * There will be at least prec digits, zero-filled on the left if * necessary to get that many. * val object to be converted * flags bitmask of format flags; only F_ALT is looked at * prec minimum number of digits; 0-fill on left if needed * type a character in [duoxX]; u acts the same as d * * CAUTION: o, x and X conversions on regular ints can never * produce a '-' sign, but can for Python's unbounded ints. */PyObject*_PyString_FormatLong(PyObject *val, int flags, int prec, int type, char **pbuf, int *plen){ PyObject *result = NULL; char *buf; Py_ssize_t i; int sign; /* 1 if '-', else 0 */ int len; /* number of characters */ Py_ssize_t llen; int numdigits; /* len == numnondigits + numdigits */ int numnondigits = 0; switch (type) { case 'd': case 'u': result = val->ob_type->tp_str(val); break; case 'o': result = val->ob_type->tp_as_number->nb_oct(val); break; case 'x': case 'X': numnondigits = 2; result = val->ob_type->tp_as_number->nb_hex(val); break; default: assert(!"'type' not in [duoxX]"); } if (!result) return NULL; buf = PyString_AsString(result); if (!buf) { Py_DECREF(result); return NULL; } /* To modify the string in-place, there can only be one reference. */ if (result->ob_refcnt != 1) { PyErr_BadInternalCall(); return NULL; } llen = PyString_Size(result); if (llen > INT_MAX) { PyErr_SetString(PyExc_ValueError, "string too large in _PyString_FormatLong"); return NULL; } len = (int)llen; if (buf[len-1] == 'L') { --len; buf[len] = '\0'; } sign = buf[0] == '-'; numnondigits += sign; numdigits = len - numnondigits; assert(numdigits > 0); /* Get rid of base marker unless F_ALT */ if ((flags & F_ALT) == 0) { /* Need to skip 0x, 0X or 0. */ int skipped = 0; switch (type) { case 'o': assert(buf[sign] == '0'); /* If 0 is only digit, leave it alone. */ if (numdigits > 1) { skipped = 1; --numdigits; } break; case 'x': case 'X': assert(buf[sign] == '0'); assert(buf[sign + 1] == 'x'); skipped = 2; numnondigits -= 2; break; } if (skipped) { buf += skipped; len -= skipped; if (sign) buf[0] = '-'; } assert(len == numnondigits + numdigits); assert(numdigits > 0); } /* Fill with leading zeroes to meet minimum width. */ if (prec > numdigits) { PyObject *r1 = PyString_FromStringAndSize(NULL, numnondigits + prec); char *b1; if (!r1) { Py_DECREF(result); return NULL; } b1 = PyString_AS_STRING(r1); for (i = 0; i < numnondigits; ++i) *b1++ = *buf++; for (i = 0; i < prec - numdigits; i++) *b1++ = '0'; for (i = 0; i < numdigits; i++) *b1++ = *buf++; *b1 = '\0'; Py_DECREF(result); result = r1; buf = PyString_AS_STRING(result); len = numnondigits + prec; } /* Fix up case for hex conversions. */ if (type == 'X') { /* Need to convert all lower case letters to upper case. and need to convert 0x to 0X (and -0x to -0X). */ for (i = 0; i < len; i++) if (buf[i] >= 'a' && buf[i] <= 'x') buf[i] -= 'a'-'A'; } *pbuf = buf; *plen = len; return result;} Py_LOCAL_INLINE(int)formatint(char *buf, size_t buflen, int flags, int prec, int type, PyObject *v){ /* 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! */ char *sign; long x; x = PyInt_AsLong(v); if (x == -1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "int argument required"); return -1; } if (x < 0 && type == 'u') { type = 'd'; } if (x < 0 && (type == 'x' || type == 'X' || type == 'o')) sign = "-"; else sign = ""; 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), "%s0%c%%.%dl%c", sign, type, prec, type); } else { PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c", sign, (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 <= 14 || buflen <= (size_t)3 + (size_t)prec) { PyErr_SetString(PyExc_OverflowError, "formatted integer is too long (precision too large?)"); return -1; } if (sign[0]) PyOS_snprintf(buf, buflen, fmt, -x); else PyOS_snprintf(buf, buflen, fmt, x); return (int)strlen(buf);} Py_LOCAL_INLINE(int)formatchar(char *buf, size_t buflen, PyObject *v){ /* presume that the buffer is at least 2 characters long */ if (PyString_Check(v)) { if (!PyArg_Parse(v, "c;%c requires int or char", &buf[0])) return -1; } else { if (!PyArg_Parse(v, "b;%c requires int or char", &buf[0])) return -1; } buf[1] = '\0'; return 1;} /* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) FORMATBUFLEN is the length of the buffer in which the floats, ints, & chars are formatted. XXX This is a magic number. Each formatting routine does bounds checking to ensure no overflow, but a better solution may be to malloc a buffer of appropriate size for each format. For now, the current solution is sufficient.*/#define FORMATBUFLEN (size_t)120 PyObject *PyString_Format(PyObject *format, PyObject *args){ char *fmt, *res; Py_ssize_t arglen, argidx; Py_ssize_t reslen, rescnt, fmtcnt; int args_owned = 0; PyObject *result, *orig_args;#ifdef Py_USING_UNICODE PyObject *v, *w;#endif PyObject *dict = NULL; if (format == NULL || !PyString_Check(format) || args == NULL) { PyErr_BadInternalCall(); return NULL; } orig_args = args; fmt = PyString_AS_STRING(format); fmtcnt = PyString_GET_SIZE(format); reslen = rescnt = fmtcnt + 100; result = PyString_FromStringAndSize((char *)NULL, reslen); if (result == NULL) return NULL; res = PyString_AsString(result); if (PyTuple_Check(args)) { arglen = PyTuple_GET_SIZE(args); argidx = 0; } else { arglen = -1; argidx = -2; } if (args->ob_type->tp_as_mapping && !PyTuple_Check(args) && !PyObject_TypeCheck(args, &PyBaseString_Type)) dict = args; while (--fmtcnt >= 0) { if (*fmt != '%') { if (--rescnt < 0) { rescnt = fmtcnt + 100; reslen += rescnt; if (_PyString_Resize(&result, reslen) < 0) return NULL; res = PyString_AS_STRING(result) + reslen - rescnt; --rescnt; } *res++ = *fmt++; } else { /* Got a format specifier */ int flags = 0; Py_ssize_t width = -1; int prec = -1; int c = '\0'; int fill; PyObject *v = NULL; PyObject *temp = NULL; char *pbuf; int sign; Py_ssize_t len; char formatbuf[FORMATBUFLEN]; /* For format{float,int,char}() */#ifdef Py_USING_UNICODE char *fmt_start = fmt; Py_ssize_t argidx_start = argidx;#endif fmt++; if (*fmt == '(') { char *keystart;Lines 4001–4500 of 5009. Previous lines Load more
sizeof(PyStringObject), sizeof(char), string_dealloc, /* tp_dealloc */ (printfunc)string_print, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ string_repr, /* tp_repr */ &string_as_number, /* tp_as_number */ &string_as_sequence, /* tp_as_sequence */ &string_as_mapping, /* tp_as_mapping */ (hashfunc)string_hash, /* tp_hash */ 0, /* tp_call */ string_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ &string_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | Py_TPFLAGS_BASETYPE, /* tp_flags */ string_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ (richcmpfunc)string_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ string_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ &PyBaseString_Type, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ string_new, /* tp_new */ PyObject_Del, /* tp_free */ }; void PyString_Concat(register PyObject **pv, register PyObject *w) { register PyObject *v; if (*pv == NULL) return; if (w == NULL || !PyString_Check(*pv)) { Py_DECREF(*pv); *pv = NULL; return; } v = string_concat((PyStringObject *) *pv, w); Py_DECREF(*pv); *pv = v; } void PyString_ConcatAndDel(register PyObject **pv, register PyObject *w) { PyString_Concat(pv, w); Py_XDECREF(w); } /* The following function breaks the notion that strings are immutable: it changes the size of a string. We get away with this only if there is only one module referencing the object. You can also think of it as creating a new string object and destroying the old one, only more efficiently. In any case, don't use this if the string may already be known to some other part of the code... Note that if there's not enough memory to resize the string, the original string object at *pv is deallocated, *pv is set to NULL, an "out of memory" exception is set, and -1 is returned. Else (on success) 0 is returned, and the value in *pv may or may not be the same as on input. As always, an extra byte is allocated for a trailing \0 byte (newsize does *not* include that), and a trailing \0 byte is stored. */ int _PyString_Resize(PyObject **pv, Py_ssize_t newsize) { register PyObject *v; register PyStringObject *sv; v = *pv; if (!PyString_Check(v) || v->ob_refcnt != 1 || newsize < 0 || PyString_CHECK_INTERNED(v)) { *pv = 0; Py_DECREF(v); PyErr_BadInternalCall(); return -1; } /* XXX UNREF/NEWREF interface should be more symmetrical */ _Py_DEC_REFTOTAL; _Py_ForgetReference(v); *pv = (PyObject *) PyObject_REALLOC((char *)v, sizeof(PyStringObject) + newsize); if (*pv == NULL) { PyObject_Del(v); PyErr_NoMemory(); return -1; } _Py_NewReference(*pv); sv = (PyStringObject *) *pv; sv->ob_size = newsize; sv->ob_sval[newsize] = '\0'; sv->ob_shash = -1; /* invalidate cached hash value */ return 0; } /* Helpers for formatstring */ Py_LOCAL_INLINE(PyObject *) getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx) { Py_ssize_t argidx = *p_argidx; if (argidx < arglen) { (*p_argidx)++; if (arglen < 0) return args; else return PyTuple_GetItem(args, argidx); } PyErr_SetString(PyExc_TypeError, "not enough arguments for format string"); return NULL; } /* Format codes * F_LJUST '-' * F_SIGN '+' * F_BLANK ' ' * F_ALT '#' * F_ZERO '0' */ #define F_LJUST (1<<0) #define F_SIGN (1<<1) #define F_BLANK (1<<2) #define F_ALT (1<<3) #define F_ZERO (1<<4) Py_LOCAL_INLINE(int) formatfloat(char *buf, size_t buflen, int flags, int prec, int type, PyObject *v) { /* fmt = '%#.' + `prec` + `type` worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/ char fmt[20]; double x; x = PyFloat_AsDouble(v); if (x == -1.0 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "float argument required"); return -1; } if (prec < 0) prec = 6; if (type == 'f' && fabs(x)/1e25 >= 1e25) type = 'g'; /* Worst case length calc to ensure no buffer overrun: 'g' formats: fmt = %#.<prec>g buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp for any double rep.) len = 1 + prec + 1 + 2 + 5 = 9 + prec 'f' formats: buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) len = 1 + 50 + 1 + prec = 52 + prec If prec=0 the effective precision is 1 (the leading digit is always given), therefore increase the length by one. */ if ((type == 'g' && buflen <= (size_t)10 + (size_t)prec) || (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) { PyErr_SetString(PyExc_OverflowError, "formatted float is too long (precision too large?)"); return -1; } PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", (flags&F_ALT) ? "#" : "", prec, type); PyOS_ascii_formatd(buf, buflen, fmt, x); return (int)strlen(buf); } /* _PyString_FormatLong emulates the format codes d, u, o, x and X, and * the F_ALT flag, for Python's long (unbounded) ints. It's not used for * Python's regular ints. * Return value: a new PyString*, or NULL if error. * . *pbuf is set to point into it, * *plen set to the # of chars following that. * Caller must decref it when done using pbuf. * The string starting at *pbuf is of the form * "-"? ("0x" | "0X")? digit+ * "0x"/"0X" are present only for x and X conversions, with F_ALT * set in flags. The case of hex digits will be correct, * There will be at least prec digits, zero-filled on the left if * necessary to get that many. * val object to be converted * flags bitmask of format flags; only F_ALT is looked at * prec minimum number of digits; 0-fill on left if needed * type a character in [duoxX]; u acts the same as d * * CAUTION: o, x and X conversions on regular ints can never * produce a '-' sign, but can for Python's unbounded ints. */ PyObject* _PyString_FormatLong(PyObject *val, int flags, int prec, int type, char **pbuf, int *plen) { PyObject *result = NULL; char *buf; Py_ssize_t i; int sign; /* 1 if '-', else 0 */ int len; /* number of characters */ Py_ssize_t llen; int numdigits; /* len == numnondigits + numdigits */ int numnondigits = 0; switch (type) { case 'd': case 'u': result = val->ob_type->tp_str(val); break; case 'o': result = val->ob_type->tp_as_number->nb_oct(val); break; case 'x': case 'X': numnondigits = 2; result = val->ob_type->tp_as_number->nb_hex(val); break; default: assert(!"'type' not in [duoxX]"); } if (!result) return NULL; buf = PyString_AsString(result); if (!buf) { Py_DECREF(result); return NULL; } /* To modify the string in-place, there can only be one reference. */ if (result->ob_refcnt != 1) { PyErr_BadInternalCall(); return NULL; } llen = PyString_Size(result); if (llen > INT_MAX) { PyErr_SetString(PyExc_ValueError, "string too large in _PyString_FormatLong"); return NULL; } len = (int)llen; if (buf[len-1] == 'L') { --len; buf[len] = '\0'; } sign = buf[0] == '-'; numnondigits += sign; numdigits = len - numnondigits; assert(numdigits > 0); /* Get rid of base marker unless F_ALT */ if ((flags & F_ALT) == 0) { /* Need to skip 0x, 0X or 0. */ int skipped = 0; switch (type) { case 'o': assert(buf[sign] == '0'); /* If 0 is only digit, leave it alone. */ if (numdigits > 1) { skipped = 1; --numdigits; } break; case 'x': case 'X': assert(buf[sign] == '0'); assert(buf[sign + 1] == 'x'); skipped = 2; numnondigits -= 2; break; } if (skipped) { buf += skipped; len -= skipped; if (sign) buf[0] = '-'; } assert(len == numnondigits + numdigits); assert(numdigits > 0); } /* Fill with leading zeroes to meet minimum width. */ if (prec > numdigits) { PyObject *r1 = PyString_FromStringAndSize(NULL, numnondigits + prec); char *b1; if (!r1) { Py_DECREF(result); return NULL; } b1 = PyString_AS_STRING(r1); for (i = 0; i < numnondigits; ++i) *b1++ = *buf++; for (i = 0; i < prec - numdigits; i++) *b1++ = '0'; for (i = 0; i < numdigits; i++) *b1++ = *buf++; *b1 = '\0'; Py_DECREF(result); result = r1; buf = PyString_AS_STRING(result); len = numnondigits + prec; } /* Fix up case for hex conversions. */ if (type == 'X') { /* Need to convert all lower case letters to upper case. and need to convert 0x to 0X (and -0x to -0X). */ for (i = 0; i < len; i++) if (buf[i] >= 'a' && buf[i] <= 'x') buf[i] -= 'a'-'A'; } *pbuf = buf; *plen = len; return result; } Py_LOCAL_INLINE(int) formatint(char *buf, size_t buflen, int flags, int prec, int type, PyObject *v) { /* 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! */ char *sign; long x; x = PyInt_AsLong(v); if (x == -1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "int argument required"); return -1; } if (x < 0 && type == 'u') { type = 'd'; } if (x < 0 && (type == 'x' || type == 'X' || type == 'o')) sign = "-"; else sign = ""; 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), "%s0%c%%.%dl%c", sign, type, prec, type); } else { PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c", sign, (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 <= 14 || buflen <= (size_t)3 + (size_t)prec) { PyErr_SetString(PyExc_OverflowError, "formatted integer is too long (precision too large?)"); return -1; } if (sign[0]) PyOS_snprintf(buf, buflen, fmt, -x); else PyOS_snprintf(buf, buflen, fmt, x); return (int)strlen(buf); } Py_LOCAL_INLINE(int) formatchar(char *buf, size_t buflen, PyObject *v) { /* presume that the buffer is at least 2 characters long */ if (PyString_Check(v)) { if (!PyArg_Parse(v, "c;%c requires int or char", &buf[0])) return -1; } else { if (!PyArg_Parse(v, "b;%c requires int or char", &buf[0])) return -1; } buf[1] = '\0'; return 1; } /* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) FORMATBUFLEN is the length of the buffer in which the floats, ints, & chars are formatted. XXX This is a magic number. Each formatting routine does bounds checking to ensure no overflow, but a better solution may be to malloc a buffer of appropriate size for each format. For now, the current solution is sufficient. */ #define FORMATBUFLEN (size_t)120 PyObject * PyString_Format(PyObject *format, PyObject *args) { char *fmt, *res; Py_ssize_t arglen, argidx; Py_ssize_t reslen, rescnt, fmtcnt; int args_owned = 0; PyObject *result, *orig_args; #ifdef Py_USING_UNICODE PyObject *v, *w; #endif PyObject *dict = NULL; if (format == NULL || !PyString_Check(format) || args == NULL) { PyErr_BadInternalCall(); return NULL; } orig_args = args; fmt = PyString_AS_STRING(format); fmtcnt = PyString_GET_SIZE(format); reslen = rescnt = fmtcnt + 100; result = PyString_FromStringAndSize((char *)NULL, reslen); if (result == NULL) return NULL; res = PyString_AsString(result); if (PyTuple_Check(args)) { arglen = PyTuple_GET_SIZE(args); argidx = 0; } else { arglen = -1; argidx = -2; } if (args->ob_type->tp_as_mapping && !PyTuple_Check(args) && !PyObject_TypeCheck(args, &PyBaseString_Type)) dict = args; while (--fmtcnt >= 0) { if (*fmt != '%') { if (--rescnt < 0) { rescnt = fmtcnt + 100; reslen += rescnt; if (_PyString_Resize(&result, reslen) < 0) return NULL; res = PyString_AS_STRING(result) + reslen - rescnt; --rescnt; } *res++ = *fmt++; } else { /* Got a format specifier */ int flags = 0; Py_ssize_t width = -1; int prec = -1; int c = '\0'; int fill; PyObject *v = NULL; PyObject *temp = NULL; char *pbuf; int sign; Py_ssize_t len; char formatbuf[FORMATBUFLEN]; /* For format{float,int,char}() */ #ifdef Py_USING_UNICODE char *fmt_start = fmt; Py_ssize_t argidx_start = argidx; #endif fmt++; if (*fmt == '(') { char *keystart;