/* Convert a Postgres encoding into Python encoding and decoding functions. * * Set clean_encoding to a clean version of the Postgres encoding name * and pyenc and pydec to python codec functions. * * Return 0 on success, else -1 and set an exception. */ RAISES_NEG static int conn_get_python_codec(const char *encoding, char **clean_encoding, PyObject **pyenc, PyObject **pydec) { int rv = -1; char *pgenc = NULL; PyObject *encname = NULL; PyObject *enc_tmp = NULL, *dec_tmp = NULL; /* get the Python name of the encoding as a C string */ if (!(encname = conn_pgenc_to_pyenc(encoding, &pgenc))) { goto exit; } if (!(encname = psyco_ensure_bytes(encname))) { goto exit; } /* Look up the codec functions */ if (!(enc_tmp = PyCodec_Encoder(Bytes_AS_STRING(encname)))) { goto exit; } if (!(dec_tmp = PyCodec_Decoder(Bytes_AS_STRING(encname)))) { goto exit; } /* success */ *pyenc = enc_tmp; enc_tmp = NULL; *pydec = dec_tmp; dec_tmp = NULL; *clean_encoding = pgenc; pgenc = NULL; rv = 0; exit: Py_XDECREF(enc_tmp); Py_XDECREF(dec_tmp); Py_XDECREF(encname); PyMem_Free(pgenc); return rv; }
RAISES_NEG static int _psyco_conn_parse_onoff(PyObject *pyval) { int rv = -1; Py_INCREF(pyval); /* for ensure_bytes */ if (pyval == Py_None) { rv = STATE_DEFAULT; } else if (PyUnicode_CheckExact(pyval) || Bytes_CheckExact(pyval)) { if (!(pyval = psycopg_ensure_bytes(pyval))) { goto exit; } if (0 == strcasecmp("default", Bytes_AS_STRING(pyval))) { rv = STATE_DEFAULT; } else { PyErr_Format(PyExc_ValueError, "the only string accepted is 'default'; got %s", Bytes_AS_STRING(pyval)); goto exit; } } else { int istrue; if (0 > (istrue = PyObject_IsTrue(pyval))) { goto exit; } rv = istrue ? STATE_ON : STATE_OFF; } exit: Py_XDECREF(pyval); return rv; }
static const char * _psyco_conn_parse_isolevel(connectionObject *self, PyObject *pyval) { const IsolationLevel *isolevel = NULL; Py_INCREF(pyval); /* for ensure_bytes */ /* parse from one of the level constants */ if (PyInt_Check(pyval)) { long level = PyInt_AsLong(pyval); if (level == -1 && PyErr_Occurred()) { goto exit; } if (level < 1 || level > 4) { PyErr_SetString(PyExc_ValueError, "isolation_level must be between 1 and 4"); goto exit; } isolevel = conn_isolevels; while ((++isolevel)->value != level) ; /* continue */ } /* parse from the string -- this includes "default" */ else { isolevel = conn_isolevels; while ((++isolevel)->name) { if (!(pyval = psycopg_ensure_bytes(pyval))) { goto exit; } if (0 == strcasecmp(isolevel->name, Bytes_AS_STRING(pyval))) { break; } } if (!isolevel->name) { char msg[256]; snprintf(msg, sizeof(msg), "bad value for isolation_level: '%s'", Bytes_AS_STRING(pyval)); PyErr_SetString(PyExc_ValueError, msg); } } /* use only supported levels on older PG versions */ if (isolevel && self->server_version < 80000) { if (isolevel->value == ISOLATION_LEVEL_READ_UNCOMMITTED || isolevel->value == ISOLATION_LEVEL_REPEATABLE_READ) { ++isolevel; } } exit: Py_XDECREF(pyval); return isolevel ? isolevel->name : NULL; }
RAISES_NEG static int _psyco_conn_parse_isolevel(PyObject *pyval) { int rv = -1; long level; Py_INCREF(pyval); /* for ensure_bytes */ /* None is default. This is only used when setting the property, because * set_session() has None used as "don't change" */ if (pyval == Py_None) { rv = ISOLATION_LEVEL_DEFAULT; } /* parse from one of the level constants */ else if (PyInt_Check(pyval)) { level = PyInt_AsLong(pyval); if (level == -1 && PyErr_Occurred()) { goto exit; } if (level < 1 || level > 4) { PyErr_SetString(PyExc_ValueError, "isolation_level must be between 1 and 4"); goto exit; } rv = level; } /* parse from the string -- this includes "default" */ else { if (!(pyval = psycopg_ensure_bytes(pyval))) { goto exit; } for (level = 1; level <= 4; level++) { if (0 == strcasecmp(srv_isolevels[level], Bytes_AS_STRING(pyval))) { rv = level; break; } } if (rv < 0 && 0 == strcasecmp("default", Bytes_AS_STRING(pyval))) { rv = ISOLATION_LEVEL_DEFAULT; } if (rv < 0) { PyErr_Format(PyExc_ValueError, "bad value for isolation_level: '%s'", Bytes_AS_STRING(pyval)); goto exit; } } exit: Py_XDECREF(pyval); return rv; }
static PyObject * psyco_parse_dsn(PyObject *self, PyObject *args, PyObject *kwargs) { char *err = NULL; PQconninfoOption *options = NULL; PyObject *res = NULL, *dsn; static char *kwlist[] = {"dsn", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &dsn)) { return NULL; } Py_INCREF(dsn); /* for ensure_bytes */ if (!(dsn = psycopg_ensure_bytes(dsn))) { goto exit; } options = PQconninfoParse(Bytes_AS_STRING(dsn), &err); if (options == NULL) { if (err != NULL) { PyErr_Format(ProgrammingError, "invalid dsn: %s", err); PQfreemem(err); } else { PyErr_SetString(OperationalError, "PQconninfoParse() failed"); } goto exit; } res = psycopg_dict_from_conninfo_options(options, /* include_password = */ 1); exit: PQconninfoFree(options); /* safe on null */ Py_XDECREF(dsn); return res; }
static PyObject * pint_getquoted(pintObject *self, PyObject *args) { PyObject *res = NULL; /* Convert subclass to int to handle IntEnum and other subclasses * whose str() is not the number. */ if (PyLong_CheckExact(self->wrapped) #if PY_MAJOR_VERSION < 2 || PyInt_CheckExact(self->wrapped) #endif ) { res = PyObject_Str(self->wrapped); } else { PyObject *tmp; if (!(tmp = PyObject_CallFunctionObjArgs( (PyObject *)&PyLong_Type, self->wrapped, NULL))) { goto exit; } res = PyObject_Str(tmp); Py_DECREF(tmp); } if (!res) { goto exit; } #if PY_MAJOR_VERSION > 2 /* unicode to bytes in Py3 */ { PyObject *tmp = PyUnicode_AsUTF8String(res); Py_DECREF(res); if (!(res = tmp)) { goto exit; } } #endif if ('-' == Bytes_AS_STRING(res)[0]) { /* Prepend a space in front of negative numbers (ticket #57) */ PyObject *tmp; if (!(tmp = Bytes_FromString(" "))) { Py_DECREF(res); res = NULL; goto exit; } Bytes_ConcatAndDel(&tmp, res); if (!(res = tmp)) { goto exit; } } exit: return res; }
static PyObject * psyco_parse_dsn(PyObject *self, PyObject *args, PyObject *kwargs) { char *err = NULL; PQconninfoOption *options = NULL, *o; PyObject *dict = NULL, *res = NULL, *dsn; static char *kwlist[] = {"dsn", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &dsn)) { return NULL; } Py_INCREF(dsn); /* for ensure_bytes */ if (!(dsn = psycopg_ensure_bytes(dsn))) { goto exit; } options = PQconninfoParse(Bytes_AS_STRING(dsn), &err); if (options == NULL) { if (err != NULL) { PyErr_Format(ProgrammingError, "error parsing the dsn: %s", err); PQfreemem(err); } else { PyErr_SetString(OperationalError, "PQconninfoParse() failed"); } goto exit; } if (!(dict = PyDict_New())) { goto exit; } for (o = options; o->keyword != NULL; o++) { if (o->val != NULL) { PyObject *value; if (!(value = Text_FromUTF8(o->val))) { goto exit; } if (PyDict_SetItemString(dict, o->keyword, value) != 0) { Py_DECREF(value); goto exit; } Py_DECREF(value); } } /* success */ res = dict; dict = NULL; exit: PQconninfoFree(options); /* safe on null */ Py_XDECREF(dict); Py_XDECREF(dsn); return res; }
static PyObject * psyco_quote_ident(PyObject *self, PyObject *args, PyObject *kwargs) { #if PG_VERSION_NUM >= 90000 PyObject *ident = NULL, *obj = NULL, *result = NULL; connectionObject *conn; const char *str; char *quoted = NULL; static char *kwlist[] = {"ident", "scope", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &ident, &obj)) { return NULL; } if (PyObject_TypeCheck(obj, &cursorType)) { conn = ((cursorObject*)obj)->conn; } else if (PyObject_TypeCheck(obj, &connectionType)) { conn = (connectionObject*)obj; } else { PyErr_SetString(PyExc_TypeError, "argument 2 must be a connection or a cursor"); return NULL; } Py_INCREF(ident); /* for ensure_bytes */ if (!(ident = psycopg_ensure_bytes(ident))) { goto exit; } str = Bytes_AS_STRING(ident); quoted = PQescapeIdentifier(conn->pgconn, str, strlen(str)); if (!quoted) { PyErr_NoMemory(); goto exit; } result = conn_text_from_chars(conn, quoted); exit: PQfreemem(quoted); Py_XDECREF(ident); return result; #else PyErr_SetString(NotSupportedError, "PQescapeIdentifier not available in libpq < 9.0"); return NULL; #endif }
RAISES_NEG static int obscure_password(connectionObject *conn) { PQconninfoOption *options; PyObject *d = NULL, *v = NULL, *dsn = NULL; char *tmp; int rv = -1; if (!conn || !conn->dsn) { return 0; } if (!(options = PQconninfoParse(conn->dsn, NULL))) { /* unlikely: the dsn was already tested valid */ return 0; } if (!(d = psycopg_dict_from_conninfo_options( options, /* include_password = */ 1))) { goto exit; } if (NULL == PyDict_GetItemString(d, "password")) { /* the dsn doesn't have a password */ rv = 0; goto exit; } /* scrub the password and put back the connection string together */ if (!(v = Text_FromUTF8("xxx"))) { goto exit; } if (0 > PyDict_SetItemString(d, "password", v)) { goto exit; } if (!(dsn = psycopg_make_dsn(Py_None, d))) { goto exit; } if (!(dsn = psycopg_ensure_bytes(dsn))) { goto exit; } /* Replace the connection string on the connection object */ tmp = conn->dsn; psycopg_strdup(&conn->dsn, Bytes_AS_STRING(dsn), -1); PyMem_Free(tmp); rv = 0; exit: PQconninfoFree(options); Py_XDECREF(v); Py_XDECREF(d); Py_XDECREF(dsn); return rv; }
static PyObject * pfloat_getquoted(pfloatObject *self, PyObject *args) { PyObject *rv; double n = PyFloat_AsDouble(self->wrapped); if (isnan(n)) rv = Bytes_FromString("'NaN'::float"); else if (isinf(n)) { if (n > 0) rv = Bytes_FromString("'Infinity'::float"); else rv = Bytes_FromString("'-Infinity'::float"); } else { if (!(rv = PyObject_Repr(self->wrapped))) { goto exit; } #if PY_MAJOR_VERSION > 2 /* unicode to bytes in Py3 */ { PyObject *tmp = PyUnicode_AsUTF8String(rv); Py_DECREF(rv); if (!(rv = tmp)) { goto exit; } } #endif if ('-' == Bytes_AS_STRING(rv)[0]) { /* Prepend a space in front of negative numbers (ticket #57) */ PyObject *tmp; if (!(tmp = Bytes_FromString(" "))) { Py_DECREF(rv); rv = NULL; goto exit; } Bytes_ConcatAndDel(&tmp, rv); if (!(rv = tmp)) { goto exit; } } } exit: return rv; }
static PyObject * typecast_repr(PyObject *self) { PyObject *name = ((typecastObject *)self)->name; PyObject *rv; Py_INCREF(name); if (!(name = psycopg_ensure_bytes(name))) { return NULL; } rv = PyString_FromFormat("<%s '%s' at %p>", Py_TYPE(self)->tp_name, Bytes_AS_STRING(name), self); Py_DECREF(name); return rv; }
static int _pyobj_read_threaded (SDL_RWops *ops, void* ptr, int size, int num) { _RWWrapper *wrapper = (_RWWrapper *) ops->hidden.unknown.data1; PyObject *result; int retval; PyThreadState* oldstate; if (!wrapper->read) return -1; PyEval_AcquireThread (wrapper->thread); oldstate = PyThreadState_Swap (wrapper->thread); result = PyObject_CallFunction (wrapper->read, "i", size * num); if (!result) { PyErr_Print (); retval = -1; goto end; } if (!Bytes_Check (result)) { Py_DECREF (result); PyErr_Print (); retval = -1; goto end; } retval = Bytes_GET_SIZE (result); memcpy (ptr, Bytes_AS_STRING (result), (size_t) retval); retval /= size; Py_DECREF (result); end: PyThreadState_Swap (oldstate); PyEval_ReleaseThread (wrapper->thread); return retval; }
static PyObject * psyco_quote_ident(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *ident = NULL, *obj = NULL, *result = NULL; connectionObject *conn; char *quoted = NULL; static char *kwlist[] = {"ident", "scope", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &ident, &obj)) { return NULL; } if (PyObject_TypeCheck(obj, &cursorType)) { conn = ((cursorObject*)obj)->conn; } else if (PyObject_TypeCheck(obj, &connectionType)) { conn = (connectionObject*)obj; } else { PyErr_SetString(PyExc_TypeError, "argument 2 must be a connection or a cursor"); return NULL; } Py_INCREF(ident); /* for ensure_bytes */ if (!(ident = psycopg_ensure_bytes(ident))) { goto exit; } if (!(quoted = psycopg_escape_identifier(conn, Bytes_AS_STRING(ident), Bytes_GET_SIZE(ident)))) { goto exit; } result = conn_text_from_chars(conn, quoted); exit: PQfreemem(quoted); Py_XDECREF(ident); return result; }
static int _pyobj_read (SDL_RWops *ops, void* ptr, int size, int num) { _RWWrapper *wrapper = (_RWWrapper *) ops->hidden.unknown.data1; PyObject *result; int retval; if (!wrapper->read) return -1; result = PyObject_CallFunction (wrapper->read, "i", size * num); if (!result) return -1; if (!Bytes_Check (result)) { Py_DECREF (result); return -1; } retval = Bytes_GET_SIZE (result); memcpy (ptr, Bytes_AS_STRING (result), (size_t) retval); retval /= size; Py_DECREF (result); return retval; }
static int _view_kind(PyObject *obj, void *view_kind_vptr) { unsigned long ch; _pc_view_kind_t *view_kind_ptr = (_pc_view_kind_t *)view_kind_vptr; if (PyUnicode_Check(obj)) { if (PyUnicode_GET_SIZE(obj) != 1) { PyErr_SetString(PyExc_TypeError, "expected a length 1 string for argument 3"); return 0; } ch = *PyUnicode_AS_UNICODE(obj); } else if (Bytes_Check(obj)) { if (Bytes_GET_SIZE(obj) != 1) { PyErr_SetString(PyExc_TypeError, "expected a length 1 string for argument 3"); return 0; } ch = *Bytes_AS_STRING(obj); } else { PyErr_Format(PyExc_TypeError, "expected a length one string for argument 3: got '%s'", Py_TYPE(obj)->tp_name); return 0; } switch (ch) { case 'R': case 'r': *view_kind_ptr = VIEWKIND_RED; break; case 'G': case 'g': *view_kind_ptr = VIEWKIND_GREEN; break; case 'B': case 'b': *view_kind_ptr = VIEWKIND_BLUE; break; case 'A': case 'a': *view_kind_ptr = VIEWKIND_ALPHA; break; case 'C': case 'c': *view_kind_ptr = VIEWKIND_COLORKEY; break; case 'P': case 'p': *view_kind_ptr = VIEWKIND_RGB; break; default: PyErr_Format(PyExc_TypeError, "unrecognized view kind '%c' for argument 3", (int)ch); return 0; } return 1; }
static int CPyStreamWrapper_Read (CPyStreamWrapper *wrapper, void *buf, pguint32 offset, pguint32 count, pguint32 *read_) { PyObject *result; pguint32 off, _read = 0; int retval = 1; char *tmp; char *ptr = (char*) buf; if (!wrapper->read || !wrapper->seek || !read_) return 0; if (offset != 0) { /* Move to the correct offset. */ result = PyObject_CallFunction (wrapper->seek, "li", offset, SEEK_SET); if (!result) { PyErr_Print(); retval = 0; goto end; } Py_DECREF (result); } if (count == 0) { /* Just a seek was wanted */ goto end; } result = PyObject_CallFunction (wrapper->read, "l", count); if (!result) { PyErr_Print (); retval = 0; goto end; } if (!Bytes_Check (result)) { Py_DECREF (result); PyErr_Print (); retval = 0; goto end; } _read = (pguint32) Bytes_GET_SIZE (result); tmp = Bytes_AS_STRING (result); off = 0; while ((_read - off) > SIZE_MAX) { memcpy (ptr + off, tmp + off, SIZE_MAX); off += SIZE_MAX; } memcpy (ptr + off, tmp + off, (size_t) (_read - off)); Py_DECREF (result); end: *read_ = _read; return retval; }
PyObject *_PGFT_Render_PixelArray(FreeTypeInstance *ft, PgFontObject *fontobj, const FontRenderMode *mode, PGFT_String *text, int invert, int *_width, int *_height) { FT_Byte *buffer = 0; PyObject *array = 0; FontSurface surf; Layout *font_text; unsigned width; unsigned height; FT_Vector offset; FT_Pos underline_top; FT_Fixed underline_size; int array_size; /* build font text */ font_text = _PGFT_LoadLayout(ft, fontobj, mode, text); if (!font_text) { return 0; } if (font_text->length == 0) { /* Nothing to render */ *_width = 0; *_height = _PGFT_Font_GetHeight(ft, fontobj); return Bytes_FromStringAndSize("", 0); } _PGFT_GetRenderMetrics(mode, font_text, &width, &height, &offset, &underline_top, &underline_size); array_size = width * height; if (array_size == 0) { /* Empty array */ *_width = 0; *_height = height; return Bytes_FromStringAndSize("", 0); } /* Create an uninitialized string whose buffer can be directly set. */ array = Bytes_FromStringAndSize(0, array_size); if (!array) { return 0; } buffer = (FT_Byte *)Bytes_AS_STRING(array); if (invert) { memset(buffer, SDL_ALPHA_OPAQUE, (size_t)array_size); } else { memset(buffer, SDL_ALPHA_TRANSPARENT, (size_t)array_size); } surf.buffer = buffer; surf.width = width; surf.height = height; surf.pitch = (int)surf.width; surf.format = 0; surf.render_gray = __render_glyph_GRAY1; surf.render_mono = __render_glyph_MONO_as_GRAY1; surf.fill = __fill_glyph_GRAY1; render(ft, font_text, mode, invert ? &mono_transparent : &mono_opaque, &surf, width, height, &offset, underline_top, underline_size); *_width = width; *_height = height; return array; }
static PyObject * psyco_encrypt_password(PyObject *self, PyObject *args, PyObject *kwargs) { char *encrypted = NULL; PyObject *password = NULL, *user = NULL; PyObject *scope = Py_None, *algorithm = Py_None; PyObject *res = NULL; connectionObject *conn = NULL; static char *kwlist[] = {"password", "user", "scope", "algorithm", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|OO", kwlist, &password, &user, &scope, &algorithm)) { return NULL; } /* for ensure_bytes */ Py_INCREF(user); Py_INCREF(password); Py_INCREF(algorithm); if (scope != Py_None) { if (PyObject_TypeCheck(scope, &cursorType)) { conn = ((cursorObject*)scope)->conn; } else if (PyObject_TypeCheck(scope, &connectionType)) { conn = (connectionObject*)scope; } else { PyErr_SetString(PyExc_TypeError, "the scope must be a connection or a cursor"); goto exit; } } if (!(user = psycopg_ensure_bytes(user))) { goto exit; } if (!(password = psycopg_ensure_bytes(password))) { goto exit; } if (algorithm != Py_None) { if (!(algorithm = psycopg_ensure_bytes(algorithm))) { goto exit; } } /* If we have to encrypt md5 we can use the libpq < 10 API */ if (algorithm != Py_None && strcmp(Bytes_AS_STRING(algorithm), "md5") == 0) { encrypted = PQencryptPassword( Bytes_AS_STRING(password), Bytes_AS_STRING(user)); } /* If the algorithm is not md5 we have to use the API available from * libpq 10. */ else { #if PG_VERSION_NUM >= 100000 if (!conn) { PyErr_SetString(ProgrammingError, "password encryption (other than 'md5' algorithm)" " requires a connection or cursor"); goto exit; } /* TODO: algo = None will block: forbid on async/green conn? */ encrypted = PQencryptPasswordConn(conn->pgconn, Bytes_AS_STRING(password), Bytes_AS_STRING(user), algorithm != Py_None ? Bytes_AS_STRING(algorithm) : NULL); #else PyErr_SetString(NotSupportedError, "password encryption (other than 'md5' algorithm)" " requires libpq 10"); goto exit; #endif } if (encrypted) { res = Text_FromUTF8(encrypted); } else { const char *msg = PQerrorMessage(conn->pgconn); PyErr_Format(ProgrammingError, "password encryption failed: %s", msg ? msg : "no reason given"); goto exit; } exit: if (encrypted) { PQfreemem(encrypted); } Py_XDECREF(user); Py_XDECREF(password); Py_XDECREF(algorithm); return res; }
PyObject * Bytes_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; PyObject *dict = NULL; if (format == NULL || !Bytes_Check(format) || args == NULL) { PyErr_BadInternalCall(); return NULL; } fmt = Bytes_AS_STRING(format); fmtcnt = Bytes_GET_SIZE(format); reslen = rescnt = fmtcnt + 100; result = Bytes_FromStringAndSize((char *)NULL, reslen); if (result == NULL) return NULL; res = Bytes_AsString(result); if (PyTuple_Check(args)) { arglen = PyTuple_GET_SIZE(args); argidx = 0; } else { arglen = -1; argidx = -2; } if (Py_TYPE(args)->tp_as_mapping && !PyTuple_Check(args) && !PyObject_TypeCheck(args, &Bytes_Type)) dict = args; while (--fmtcnt >= 0) { if (*fmt != '%') { if (--rescnt < 0) { rescnt = fmtcnt + 100; reslen += rescnt; if (_Bytes_Resize(&result, reslen)) return NULL; res = Bytes_AS_STRING(result) + reslen - rescnt; --rescnt; } *res++ = *fmt++; } else { /* Got a format specifier */ Py_ssize_t width = -1; int c = '\0'; PyObject *v = NULL; PyObject *temp = NULL; char *pbuf; Py_ssize_t len; fmt++; if (*fmt == '(') { char *keystart; 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 = Text_FromUTF8AndSize(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) { c = *fmt++; break; } if (fmtcnt < 0) { PyErr_SetString(PyExc_ValueError, "incomplete format"); goto error; } if (c != '%') { v = getnextarg(args, arglen, &argidx); if (v == NULL) goto error; } switch (c) { case '%': pbuf = "%"; len = 1; break; case 's': /* only bytes! */ if (!Bytes_CheckExact(v)) { PyErr_Format(PyExc_ValueError, "only bytes values expected, got %s", Py_TYPE(v)->tp_name); goto error; } temp = v; Py_INCREF(v); pbuf = Bytes_AS_STRING(temp); len = Bytes_GET_SIZE(temp); break; default: PyErr_Format(PyExc_ValueError, "unsupported format character '%c' (0x%x) " "at index " FORMAT_CODE_PY_SSIZE_T, c, c, (Py_ssize_t)(fmt - 1 - Bytes_AsString(format))); goto error; } if (width < len) width = len; if (rescnt < width) { reslen -= rescnt; rescnt = width + fmtcnt + 100; reslen += rescnt; if (reslen < 0) { Py_DECREF(result); Py_XDECREF(temp); return PyErr_NoMemory(); } if (_Bytes_Resize(&result, reslen)) { Py_XDECREF(temp); return NULL; } res = Bytes_AS_STRING(result) + reslen - rescnt; } 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); } if (_Bytes_Resize(&result, reslen - rescnt)) return NULL; return result; error: Py_DECREF(result); if (args_owned) { Py_DECREF(args); } return NULL; }