Py_ssize_t keylen; PyObject *key; int pcount = 1; if (dict == NULL) { PyErr_SetString(PyExc_TypeError, "format requires a mapping"); goto error; } ++fmt; --fmtcnt; keystart = fmt; /* Skip over balanced parentheses */ while (pcount > 0 && --fmtcnt >= 0) { if (*fmt == ')') --pcount; else if (*fmt == '(') ++pcount; fmt++; } keylen = fmt - keystart - 1; if (fmtcnt < 0 || pcount > 0) { PyErr_SetString(PyExc_ValueError, "incomplete format key"); goto error; } key = PyString_FromStringAndSize(keystart, keylen); if (key == NULL) goto error; if (args_owned) { Py_DECREF(args); args_owned = 0; } args = PyObject_GetItem(dict, key); Py_DECREF(key); if (args == NULL) { goto error; } args_owned = 1; arglen = -1; argidx = -2; } while (--fmtcnt >= 0) { switch (c = *fmt++) { case '-': flags |= F_LJUST; continue; case '+': flags |= F_SIGN; continue; case ' ': flags |= F_BLANK; continue; case '#': flags |= F_ALT; continue; case '0': flags |= F_ZERO; continue; } break; } if (c == '*') { v = getnextarg(args, arglen, &argidx); if (v == NULL) goto error; if (!PyInt_Check(v)) { PyErr_SetString(PyExc_TypeError, "* wants int"); goto error; } width = PyInt_AsLong(v); if (width < 0) { flags |= F_LJUST; width = -width; } if (--fmtcnt >= 0) c = *fmt++; } else if (c >= 0 && isdigit(c)) { width = c - '0'; while (--fmtcnt >= 0) { c = Py_CHARMASK(*fmt++); if (!isdigit(c)) break; if ((width*10) / 10 != width) { PyErr_SetString( PyExc_ValueError, "width too big"); goto error; } width = width*10 + (c - '0'); } } if (c == '.') { prec = 0; if (--fmtcnt >= 0) c = *fmt++; if (c == '*') { v = getnextarg(args, arglen, &argidx); if (v == NULL) goto error; if (!PyInt_Check(v)) { PyErr_SetString( PyExc_TypeError, "* wants int"); goto error; } prec = PyInt_AsLong(v); if (prec < 0) prec = 0; if (--fmtcnt >= 0) c = *fmt++; } else if (c >= 0 && isdigit(c)) { prec = c - '0'; while (--fmtcnt >= 0) { c = Py_CHARMASK(*fmt++); if (!isdigit(c)) break; if ((prec*10) / 10 != prec) { PyErr_SetString( PyExc_ValueError, "prec too big"); goto error; } prec = prec*10 + (c - '0'); } } } /* prec */ if (fmtcnt >= 0) { if (c == 'h' || c == 'l' || c == 'L') { if (--fmtcnt >= 0) c = *fmt++; } } if (fmtcnt < 0) { PyErr_SetString(PyExc_ValueError, "incomplete format"); goto error; } if (c != '%') { v = getnextarg(args, arglen, &argidx); if (v == NULL) goto error; } sign = 0; fill = ' '; switch (c) { case '%': pbuf = "%"; len = 1; break; case 's':#ifdef Py_USING_UNICODE if (PyUnicode_Check(v)) { fmt = fmt_start; argidx = argidx_start; goto unicode; }#endif temp = _PyObject_Str(v);#ifdef Py_USING_UNICODE if (temp != NULL && PyUnicode_Check(temp)) { Py_DECREF(temp); fmt = fmt_start; argidx = argidx_start; goto unicode; }#endif /* Fall through */ case 'r': if (c == 'r') temp = PyObject_Repr(v); if (temp == NULL) goto error; if (!PyString_Check(temp)) { PyErr_SetString(PyExc_TypeError, "%s argument has non-string str()"); Py_DECREF(temp); goto error; } pbuf = PyString_AS_STRING(temp); len = PyString_GET_SIZE(temp); if (prec >= 0 && len > prec) len = prec; break; case 'i': case 'd': case 'u': case 'o': case 'x': case 'X': if (c == 'i') c = 'd'; if (PyLong_Check(v)) { int ilen; temp = _PyString_FormatLong(v, flags, prec, c, &pbuf, &ilen); len = ilen; if (!temp) goto error; sign = 1; } else { pbuf = formatbuf; len = formatint(pbuf, sizeof(formatbuf), flags, prec, c, v); if (len < 0) goto error; sign = 1; } if (flags & F_ZERO) fill = '0'; break; case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': if (c == 'F') c = 'f'; pbuf = formatbuf; len = formatfloat(pbuf, sizeof(formatbuf), flags, prec, c, v); if (len < 0) goto error; sign = 1; if (flags & F_ZERO) fill = '0'; break; case 'c':#ifdef Py_USING_UNICODE if (PyUnicode_Check(v)) { fmt = fmt_start; argidx = argidx_start; goto unicode; }#endif pbuf = formatbuf; len = formatchar(pbuf, sizeof(formatbuf), v); if (len < 0) goto error; break; default: PyErr_Format(PyExc_ValueError, "unsupported format character '%c' (0x%x) " "at index %zd", c, c, (Py_ssize_t)(fmt - 1 - PyString_AsString(format))); goto error; } if (sign) { if (*pbuf == '-' || *pbuf == '+') { sign = *pbuf++; len--; } else if (flags & F_SIGN) sign = '+'; else if (flags & F_BLANK) sign = ' '; else sign = 0; } if (width < len) width = len; if (rescnt - (sign != 0) < width) { reslen -= rescnt; rescnt = width + fmtcnt + 100; reslen += rescnt; if (reslen < 0) { Py_DECREF(result); Py_XDECREF(temp); return PyErr_NoMemory(); } if (_PyString_Resize(&result, reslen) < 0) { Py_XDECREF(temp); return NULL; } res = PyString_AS_STRING(result) + reslen - rescnt; } if (sign) { if (fill != ' ') *res++ = sign; rescnt--; if (width > len) width--; } if ((flags & F_ALT) && (c == 'x' || c == 'X')) { assert(pbuf[0] == '0'); assert(pbuf[1] == c); if (fill != ' ') { *res++ = *pbuf++; *res++ = *pbuf++; } rescnt -= 2; width -= 2; if (width < 0) width = 0; len -= 2; } if (width > len && !(flags & F_LJUST)) { do { --rescnt; *res++ = fill; } while (--width > len); } if (fill == ' ') { if (sign) *res++ = sign; if ((flags & F_ALT) && (c == 'x' || c == 'X')) { assert(pbuf[0] == '0'); assert(pbuf[1] == c); *res++ = *pbuf++; *res++ = *pbuf++; } } Py_MEMCPY(res, pbuf, len); res += len; rescnt -= len; while (--width >= len) { --rescnt; *res++ = ' '; } if (dict && (argidx < arglen) && c != '%') { PyErr_SetString(PyExc_TypeError, "not all arguments converted during string formatting"); Py_XDECREF(temp); goto error; } Py_XDECREF(temp); } /* '%' */ } /* until end */ if (argidx < arglen && !dict) { PyErr_SetString(PyExc_TypeError, "not all arguments converted during string formatting"); goto error; } if (args_owned) { Py_DECREF(args); } _PyString_Resize(&result, reslen - rescnt); return result; #ifdef Py_USING_UNICODE unicode: if (args_owned) { Py_DECREF(args); args_owned = 0; } /* Fiddle args right (remove the first argidx arguments) */ if (PyTuple_Check(orig_args) && argidx > 0) { PyObject *v; Py_ssize_t n = PyTuple_GET_SIZE(orig_args) - argidx; v = PyTuple_New(n); if (v == NULL) goto error; while (--n >= 0) { PyObject *w = PyTuple_GET_ITEM(orig_args, n + argidx); Py_INCREF(w); PyTuple_SET_ITEM(v, n, w); } args = v; } else { Py_INCREF(orig_args); args = orig_args; } args_owned = 1; /* Take what we have of the result and let the Unicode formatting function format the rest of the input. */ rescnt = res - PyString_AS_STRING(result); if (_PyString_Resize(&result, rescnt)) goto error; fmtcnt = PyString_GET_SIZE(format) - \ (fmt - PyString_AS_STRING(format)); format = PyUnicode_Decode(fmt, fmtcnt, NULL, NULL); if (format == NULL) goto error; v = PyUnicode_Format(format, args); Py_DECREF(format); if (v == NULL) goto error; /* Paste what we have (result) to what the Unicode formatting function returned (v) and return the result (or error) */ w = PyUnicode_Concat(result, v); Py_DECREF(result); Py_DECREF(v); Py_DECREF(args); return w;#endif /* Py_USING_UNICODE */ error: Py_DECREF(result); if (args_owned) { Py_DECREF(args); } return NULL;} voidPyString_InternInPlace(PyObject **p){ register PyStringObject *s = (PyStringObject *)(*p); PyObject *t; if (s == NULL || !PyString_Check(s)) Py_FatalError("PyString_InternInPlace: strings only please!"); /* If it's a string subclass, we don't really know what putting it in the interned dict might do. */ if (!PyString_CheckExact(s)) return; if (PyString_CHECK_INTERNED(s)) return; if (interned == NULL) { interned = PyDict_New(); if (interned == NULL) { PyErr_Clear(); /* Don't leave an exception */ return; } } t = PyDict_GetItem(interned, (PyObject *)s); if (t) { Py_INCREF(t); Py_DECREF(*p); *p = t; return; } if (PyDict_SetItem(interned, (PyObject *)s, (PyObject *)s) < 0) { PyErr_Clear(); return; } /* The two references in interned are not counted by refcnt. The string deallocator will take care of this */ s->ob_refcnt -= 2; PyString_CHECK_INTERNED(s) = SSTATE_INTERNED_MORTAL;} voidPyString_InternImmortal(PyObject **p){ PyString_InternInPlace(p); if (PyString_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) { PyString_CHECK_INTERNED(*p) = SSTATE_INTERNED_IMMORTAL; Py_INCREF(*p); }} PyObject *PyString_InternFromString(const char *cp){ PyObject *s = PyString_FromString(cp); if (s == NULL) return NULL; PyString_InternInPlace(&s); return s;} voidPyString_Fini(void){ int i; for (i = 0; i < UCHAR_MAX + 1; i++) { Py_XDECREF(characters[i]); characters[i] = NULL; } Py_XDECREF(nullstring); nullstring = NULL;} void _Py_ReleaseInternedStrings(void){ PyObject *keys; PyStringObject *s; Py_ssize_t i, n; if (interned == NULL || !PyDict_Check(interned)) return; keys = PyDict_Keys(interned); if (keys == NULL || !PyList_Check(keys)) { PyErr_Clear(); return; } /* Since _Py_ReleaseInternedStrings() is intended to help a leak detector, interned strings are not forcibly deallocated; rather, we give them their stolen references back, and then clear and DECREF the interned dict. */ fprintf(stderr, "releasing interned strings\n"); n = PyList_GET_SIZE(keys); for (i = 0; i < n; i++) { s = (PyStringObject *) PyList_GET_ITEM(keys, i); switch (s->ob_sstate) { case SSTATE_NOT_INTERNED: /* XXX Shouldn't happen */ break; case SSTATE_INTERNED_IMMORTAL: s->ob_refcnt += 1; break; case SSTATE_INTERNED_MORTAL: s->ob_refcnt += 2; break; default:Lines 4501–5000 of 5009. Previous lines Load more
Py_ssize_t keylen; PyObject *key; int pcount = 1; if (dict == NULL) { PyErr_SetString(PyExc_TypeError, "format requires a mapping"); goto error; } ++fmt; --fmtcnt; keystart = fmt; /* Skip over balanced parentheses */ while (pcount > 0 && --fmtcnt >= 0) { if (*fmt == ')') --pcount; else if (*fmt == '(') ++pcount; fmt++; } keylen = fmt - keystart - 1; if (fmtcnt < 0 || pcount > 0) { PyErr_SetString(PyExc_ValueError, "incomplete format key"); goto error; } key = PyString_FromStringAndSize(keystart, keylen); if (key == NULL) goto error; if (args_owned) { Py_DECREF(args); args_owned = 0; } args = PyObject_GetItem(dict, key); Py_DECREF(key); if (args == NULL) { goto error; } args_owned = 1; arglen = -1; argidx = -2; } while (--fmtcnt >= 0) { switch (c = *fmt++) { case '-': flags |= F_LJUST; continue; case '+': flags |= F_SIGN; continue; case ' ': flags |= F_BLANK; continue; case '#': flags |= F_ALT; continue; case '0': flags |= F_ZERO; continue; } break; } if (c == '*') { v = getnextarg(args, arglen, &argidx); if (v == NULL) goto error; if (!PyInt_Check(v)) { PyErr_SetString(PyExc_TypeError, "* wants int"); goto error; } width = PyInt_AsLong(v); if (width < 0) { flags |= F_LJUST; width = -width; } if (--fmtcnt >= 0) c = *fmt++; } else if (c >= 0 && isdigit(c)) { width = c - '0'; while (--fmtcnt >= 0) { c = Py_CHARMASK(*fmt++); if (!isdigit(c)) break; if ((width*10) / 10 != width) { PyErr_SetString( PyExc_ValueError, "width too big"); goto error; } width = width*10 + (c - '0'); } } if (c == '.') { prec = 0; if (--fmtcnt >= 0) c = *fmt++; if (c == '*') { v = getnextarg(args, arglen, &argidx); if (v == NULL) goto error; if (!PyInt_Check(v)) { PyErr_SetString( PyExc_TypeError, "* wants int"); goto error; } prec = PyInt_AsLong(v); if (prec < 0) prec = 0; if (--fmtcnt >= 0) c = *fmt++; } else if (c >= 0 && isdigit(c)) { prec = c - '0'; while (--fmtcnt >= 0) { c = Py_CHARMASK(*fmt++); if (!isdigit(c)) break; if ((prec*10) / 10 != prec) { PyErr_SetString( PyExc_ValueError, "prec too big"); goto error; } prec = prec*10 + (c - '0'); } } } /* prec */ if (fmtcnt >= 0) { if (c == 'h' || c == 'l' || c == 'L') { if (--fmtcnt >= 0) c = *fmt++; } } if (fmtcnt < 0) { PyErr_SetString(PyExc_ValueError, "incomplete format"); goto error; } if (c != '%') { v = getnextarg(args, arglen, &argidx); if (v == NULL) goto error; } sign = 0; fill = ' '; switch (c) { case '%': pbuf = "%"; len = 1; break; case 's': #ifdef Py_USING_UNICODE if (PyUnicode_Check(v)) { fmt = fmt_start; argidx = argidx_start; goto unicode; } #endif temp = _PyObject_Str(v); #ifdef Py_USING_UNICODE if (temp != NULL && PyUnicode_Check(temp)) { Py_DECREF(temp); fmt = fmt_start; argidx = argidx_start; goto unicode; } #endif /* Fall through */ case 'r': if (c == 'r') temp = PyObject_Repr(v); if (temp == NULL) goto error; if (!PyString_Check(temp)) { PyErr_SetString(PyExc_TypeError, "%s argument has non-string str()"); Py_DECREF(temp); goto error; } pbuf = PyString_AS_STRING(temp); len = PyString_GET_SIZE(temp); if (prec >= 0 && len > prec) len = prec; break; case 'i': case 'd': case 'u': case 'o': case 'x': case 'X': if (c == 'i') c = 'd'; if (PyLong_Check(v)) { int ilen; temp = _PyString_FormatLong(v, flags, prec, c, &pbuf, &ilen); len = ilen; if (!temp) goto error; sign = 1; } else { pbuf = formatbuf; len = formatint(pbuf, sizeof(formatbuf), flags, prec, c, v); if (len < 0) goto error; sign = 1; } if (flags & F_ZERO) fill = '0'; break; case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': if (c == 'F') c = 'f'; pbuf = formatbuf; len = formatfloat(pbuf, sizeof(formatbuf), flags, prec, c, v); if (len < 0) goto error; sign = 1; if (flags & F_ZERO) fill = '0'; break; case 'c': #ifdef Py_USING_UNICODE if (PyUnicode_Check(v)) { fmt = fmt_start; argidx = argidx_start; goto unicode; } #endif pbuf = formatbuf; len = formatchar(pbuf, sizeof(formatbuf), v); if (len < 0) goto error; break; default: PyErr_Format(PyExc_ValueError, "unsupported format character '%c' (0x%x) " "at index %zd", c, c, (Py_ssize_t)(fmt - 1 - PyString_AsString(format))); goto error; } if (sign) { if (*pbuf == '-' || *pbuf == '+') { sign = *pbuf++; len--; } else if (flags & F_SIGN) sign = '+'; else if (flags & F_BLANK) sign = ' '; else sign = 0; } if (width < len) width = len; if (rescnt - (sign != 0) < width) { reslen -= rescnt; rescnt = width + fmtcnt + 100; reslen += rescnt; if (reslen < 0) { Py_DECREF(result); Py_XDECREF(temp); return PyErr_NoMemory(); } if (_PyString_Resize(&result, reslen) < 0) { Py_XDECREF(temp); return NULL; } res = PyString_AS_STRING(result) + reslen - rescnt; } if (sign) { if (fill != ' ') *res++ = sign; rescnt--; if (width > len) width--; } if ((flags & F_ALT) && (c == 'x' || c == 'X')) { assert(pbuf[0] == '0'); assert(pbuf[1] == c); if (fill != ' ') { *res++ = *pbuf++; *res++ = *pbuf++; } rescnt -= 2; width -= 2; if (width < 0) width = 0; len -= 2; } if (width > len && !(flags & F_LJUST)) { do { --rescnt; *res++ = fill; } while (--width > len); } if (fill == ' ') { if (sign) *res++ = sign; if ((flags & F_ALT) && (c == 'x' || c == 'X')) { assert(pbuf[0] == '0'); assert(pbuf[1] == c); *res++ = *pbuf++; *res++ = *pbuf++; } } Py_MEMCPY(res, pbuf, len); res += len; rescnt -= len; while (--width >= len) { --rescnt; *res++ = ' '; } if (dict && (argidx < arglen) && c != '%') { PyErr_SetString(PyExc_TypeError, "not all arguments converted during string formatting"); Py_XDECREF(temp); goto error; } Py_XDECREF(temp); } /* '%' */ } /* until end */ if (argidx < arglen && !dict) { PyErr_SetString(PyExc_TypeError, "not all arguments converted during string formatting"); goto error; } if (args_owned) { Py_DECREF(args); } _PyString_Resize(&result, reslen - rescnt); return result; #ifdef Py_USING_UNICODE unicode: if (args_owned) { Py_DECREF(args); args_owned = 0; } /* Fiddle args right (remove the first argidx arguments) */ if (PyTuple_Check(orig_args) && argidx > 0) { PyObject *v; Py_ssize_t n = PyTuple_GET_SIZE(orig_args) - argidx; v = PyTuple_New(n); if (v == NULL) goto error; while (--n >= 0) { PyObject *w = PyTuple_GET_ITEM(orig_args, n + argidx); Py_INCREF(w); PyTuple_SET_ITEM(v, n, w); } args = v; } else { Py_INCREF(orig_args); args = orig_args; } args_owned = 1; /* Take what we have of the result and let the Unicode formatting function format the rest of the input. */ rescnt = res - PyString_AS_STRING(result); if (_PyString_Resize(&result, rescnt)) goto error; fmtcnt = PyString_GET_SIZE(format) - \ (fmt - PyString_AS_STRING(format)); format = PyUnicode_Decode(fmt, fmtcnt, NULL, NULL); if (format == NULL) goto error; v = PyUnicode_Format(format, args); Py_DECREF(format); if (v == NULL) goto error; /* Paste what we have (result) to what the Unicode formatting function returned (v) and return the result (or error) */ w = PyUnicode_Concat(result, v); Py_DECREF(result); Py_DECREF(v); Py_DECREF(args); return w; #endif /* Py_USING_UNICODE */ error: Py_DECREF(result); if (args_owned) { Py_DECREF(args); } return NULL; } void PyString_InternInPlace(PyObject **p) { register PyStringObject *s = (PyStringObject *)(*p); PyObject *t; if (s == NULL || !PyString_Check(s)) Py_FatalError("PyString_InternInPlace: strings only please!"); /* If it's a string subclass, we don't really know what putting it in the interned dict might do. */ if (!PyString_CheckExact(s)) return; if (PyString_CHECK_INTERNED(s)) return; if (interned == NULL) { interned = PyDict_New(); if (interned == NULL) { PyErr_Clear(); /* Don't leave an exception */ return; } } t = PyDict_GetItem(interned, (PyObject *)s); if (t) { Py_INCREF(t); Py_DECREF(*p); *p = t; return; } if (PyDict_SetItem(interned, (PyObject *)s, (PyObject *)s) < 0) { PyErr_Clear(); return; } /* The two references in interned are not counted by refcnt. The string deallocator will take care of this */ s->ob_refcnt -= 2; PyString_CHECK_INTERNED(s) = SSTATE_INTERNED_MORTAL; } void PyString_InternImmortal(PyObject **p) { PyString_InternInPlace(p); if (PyString_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) { PyString_CHECK_INTERNED(*p) = SSTATE_INTERNED_IMMORTAL; Py_INCREF(*p); } } PyObject * PyString_InternFromString(const char *cp) { PyObject *s = PyString_FromString(cp); if (s == NULL) return NULL; PyString_InternInPlace(&s); return s; } void PyString_Fini(void) { int i; for (i = 0; i < UCHAR_MAX + 1; i++) { Py_XDECREF(characters[i]); characters[i] = NULL; } Py_XDECREF(nullstring); nullstring = NULL; } void _Py_ReleaseInternedStrings(void) { PyObject *keys; PyStringObject *s; Py_ssize_t i, n; if (interned == NULL || !PyDict_Check(interned)) return; keys = PyDict_Keys(interned); if (keys == NULL || !PyList_Check(keys)) { PyErr_Clear(); return; } /* Since _Py_ReleaseInternedStrings() is intended to help a leak detector, interned strings are not forcibly deallocated; rather, we give them their stolen references back, and then clear and DECREF the interned dict. */ fprintf(stderr, "releasing interned strings\n"); n = PyList_GET_SIZE(keys); for (i = 0; i < n; i++) { s = (PyStringObject *) PyList_GET_ITEM(keys, i); switch (s->ob_sstate) { case SSTATE_NOT_INTERNED: /* XXX Shouldn't happen */ break; case SSTATE_INTERNED_IMMORTAL: s->ob_refcnt += 1; break; case SSTATE_INTERNED_MORTAL: s->ob_refcnt += 2; break; default: