/* stringlib: repr() implementation */ #ifndef STRINGLIB_FASTSEARCH_H #error must include "stringlib/fastsearch.h" before including this module #endif static void STRINGLIB(repr)(PyObject *unicode, Py_UCS4 quote, STRINGLIB_CHAR *odata) { Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode); const void *idata = PyUnicode_DATA(unicode); int ikind = PyUnicode_KIND(unicode); *odata++ = quote; for (Py_ssize_t i = 0; i < isize; i++) { Py_UCS4 ch = PyUnicode_READ(ikind, idata, i); /* Escape quotes and backslashes */ if ((ch == quote) || (ch == '\\')) { *odata++ = '\\'; *odata++ = ch; continue; } /* Map special whitespace to '\t', \n', '\r' */ if (ch == '\t') { *odata++ = '\\'; *odata++ = 't'; } else if (ch == '\n') { *odata++ = '\\'; *odata++ = 'n'; } else if (ch == '\r') { *odata++ = '\\'; *odata++ = 'r'; } /* Map non-printable US ASCII to '\xhh' */ else if (ch < ' ' || ch == 0x7F) { *odata++ = '\\'; *odata++ = 'x'; *odata++ = Py_hexdigits[(ch >> 4) & 0x000F]; *odata++ = Py_hexdigits[ch & 0x000F]; } /* Copy ASCII characters as-is */ else if (ch < 0x7F) { *odata++ = ch; } /* Non-ASCII characters */ else { /* Map Unicode whitespace and control characters (categories Z* and C* except ASCII space) */ if (!Py_UNICODE_ISPRINTABLE(ch)) { *odata++ = '\\'; /* Map 8-bit characters to '\xhh' */ if (ch <= 0xff) { *odata++ = 'x'; *odata++ = Py_hexdigits[(ch >> 4) & 0x000F]; *odata++ = Py_hexdigits[ch & 0x000F]; } /* Map 16-bit characters to '\uxxxx' */ else if (ch <= 0xffff) { *odata++ = 'u'; *odata++ = Py_hexdigits[(ch >> 12) & 0xF]; *odata++ = Py_hexdigits[(ch >> 8) & 0xF]; *odata++ = Py_hexdigits[(ch >> 4) & 0xF]; *odata++ = Py_hexdigits[ch & 0xF]; } /* Map 21-bit characters to '\U00xxxxxx' */ else { *odata++ = 'U'; *odata++ = Py_hexdigits[(ch >> 28) & 0xF]; *odata++ = Py_hexdigits[(ch >> 24) & 0xF]; *odata++ = Py_hexdigits[(ch >> 20) & 0xF]; *odata++ = Py_hexdigits[(ch >> 16) & 0xF]; *odata++ = Py_hexdigits[(ch >> 12) & 0xF]; *odata++ = Py_hexdigits[(ch >> 8) & 0xF]; *odata++ = Py_hexdigits[(ch >> 4) & 0xF]; *odata++ = Py_hexdigits[ch & 0xF]; } } /* Copy characters as-is */ else { *odata++ = ch; } } } *odata = quote; }