Commit dba4dc72 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Copy in CPython's PyString_Repr

Probably more compatible, but also much faster.

Also, set str_cls->tp_repr.
parent d5932147
...@@ -1293,63 +1293,68 @@ static bool _needs_escaping[256] ...@@ -1293,63 +1293,68 @@ static bool _needs_escaping[256]
static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but clang will complain static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but clang will complain
extern "C" PyObject* PyString_Repr(PyObject* obj, int smartquotes) noexcept { extern "C" PyObject* PyString_Repr(PyObject* obj, int smartquotes) noexcept {
BoxedString* self = (BoxedString*)obj; BoxedString* op = (BoxedString*)obj;
assert(PyString_Check(self)); size_t newsize = 2 + 4 * Py_SIZE(op);
PyObject* v;
std::ostringstream os(""); if (newsize > PY_SSIZE_T_MAX || newsize / 4 != Py_SIZE(op)) {
PyErr_SetString(PyExc_OverflowError, "string is too large to make repr");
llvm::StringRef s(self->s()); return NULL;
char quote = '\'';
if (smartquotes && s.find('\'', 0) != std::string::npos && s.find('\"', 0) == std::string::npos) {
quote = '\"';
} }
os << quote; v = PyString_FromStringAndSize((char*)NULL, newsize);
for (int i = 0; i < s.size(); i++) { if (v == NULL) {
char c = s[i]; return NULL;
if ((c == '\'' && quote == '\"') || !_needs_escaping[c & 0xff]) { } else {
os << c; Py_ssize_t i;
} else { char c;
char special = 0; char* p;
switch (c) { int quote;
case '\t':
special = 't'; /* figure out which quote to use; single is preferred */
break; quote = '\'';
case '\n': if (smartquotes && memchr(op->data(), '\'', Py_SIZE(op)) && !memchr(op->data(), '"', Py_SIZE(op)))
special = 'n'; quote = '"';
break;
case '\r': p = PyString_AS_STRING(v);
special = 'r'; *p++ = quote;
break; for (i = 0; i < Py_SIZE(op); i++) {
case '\'': /* There's at least enough room for a hex escape
special = '\''; * and a closing quote. */
break; assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
case '\"': c = op->data()[i];
special = '\"'; if (c == quote || c == '\\')
break; *p++ = '\\', *p++ = c;
case '\\': else if (c == '\t')
special = '\\'; *p++ = '\\', *p++ = 't';
break; else if (c == '\n')
} *p++ = '\\', *p++ = 'n';
if (special) { else if (c == '\r')
os << '\\'; *p++ = '\\', *p++ = 'r';
os << special; else if (c < ' ' || c >= 0x7f) {
} else { /* For performance, we don't want to call
os << '\\'; * PyOS_snprintf here (extra layers of
os << 'x'; * function call). */
os << _hex[(c & 0xff) / 16]; sprintf(p, "\\x%02x", c & 0xff);
os << _hex[(c & 0xff) % 16]; p += 4;
} } else
*p++ = c;
} }
assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
*p++ = quote;
*p = '\0';
if (_PyString_Resize(&v, (p - PyString_AS_STRING(v))))
return NULL;
return v;
} }
os << quote;
return boxString(os.str());
} }
extern "C" Box* strRepr(BoxedString* self) { extern "C" Box* strRepr(BoxedString* self) {
return PyString_Repr(self, 1 /* smartquotes */); return PyString_Repr(self, 1 /* smartquotes */);
} }
extern "C" Box* str_repr(Box* self) noexcept {
return PyString_Repr(self, 1 /* smartquotes */);
}
/* Unescape a backslash-escaped string. If unicode is non-zero, /* Unescape a backslash-escaped string. If unicode is non-zero,
the string is a u-literal. If recode_encoding is non-zero, the string is a u-literal. If recode_encoding is non-zero,
the string is UTF-8 encoded and should be re-encoded in the the string is UTF-8 encoded and should be re-encoded in the
...@@ -2882,6 +2887,7 @@ void setupStr() { ...@@ -2882,6 +2887,7 @@ void setupStr() {
add_operators(str_cls); add_operators(str_cls);
str_cls->freeze(); str_cls->freeze();
str_cls->tp_repr = str_repr;
str_cls->tp_iter = (decltype(str_cls->tp_iter))strIter; str_cls->tp_iter = (decltype(str_cls->tp_iter))strIter;
str_cls->tp_hash = (hashfunc)str_hash; str_cls->tp_hash = (hashfunc)str_hash;
str_cls->tp_as_sequence->sq_length = str_length; str_cls->tp_as_sequence->sq_length = str_length;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment