Py_UNICODE *uni2; /* startpos for collecting untranslatable chars */ const Py_UNICODE *collstart = p; const Py_UNICODE *collend = p+1; const Py_UNICODE *coll; /* find all untranslatable characters */ while (collend < endp) { if (charmaptranslate_lookup(*collend, mapping, &x)) goto onError; Py_XDECREF(x); if (x!=Py_None) break; ++collend; } /* cache callback name lookup * (if not done yet, i.e. it's the first error) */ if (known_errorHandler==-1) { if ((errors==NULL) || (!strcmp(errors, "strict"))) known_errorHandler = 1; else if (!strcmp(errors, "replace")) known_errorHandler = 2; else if (!strcmp(errors, "ignore")) known_errorHandler = 3; else if (!strcmp(errors, "xmlcharrefreplace")) known_errorHandler = 4; else known_errorHandler = 0; } switch (known_errorHandler) { case 1: /* strict */ raise_translate_exception(&exc, startp, size, collstart-startp, collend-startp, reason); goto onError; case 2: /* replace */ /* No need to check for space, this is a 1:1 replacement */ for (coll = collstart; coll<collend; ++coll) *str++ = '?'; /* fall through */ case 3: /* ignore */ p = collend; break; case 4: /* xmlcharrefreplace */ /* generate replacement (temporarily (mis)uses p) */ for (p = collstart; p < collend; ++p) { char buffer[2+29+1+1]; char *cp; sprintf(buffer, "&#%d;", (int)*p); if (charmaptranslate_makespace(&res, &str, (str-PyUnicode_AS_UNICODE(res))+strlen(buffer)+(endp-collend))) goto onError; for (cp = buffer; *cp; ++cp) *str++ = *cp; } p = collend; break; default: repunicode = unicode_translate_call_errorhandler(errors, &errorHandler, reason, startp, size, &exc, collstart-startp, collend-startp, &newpos); if (repunicode == NULL) goto onError; /* generate replacement */ repsize = PyUnicode_GET_SIZE(repunicode); if (charmaptranslate_makespace(&res, &str, (str-PyUnicode_AS_UNICODE(res))+repsize+(endp-collend))) { Py_DECREF(repunicode); goto onError; } for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2) *str++ = *uni2; p = startp + newpos; Py_DECREF(repunicode); } } } /* Resize if we allocated to much */ respos = str-PyUnicode_AS_UNICODE(res); if (respos<PyUnicode_GET_SIZE(res)) { if (_PyUnicode_Resize(&res, respos) < 0) goto onError; } Py_XDECREF(exc); Py_XDECREF(errorHandler); return res; onError: Py_XDECREF(res); Py_XDECREF(exc); Py_XDECREF(errorHandler); return NULL;} PyObject *PyUnicode_Translate(PyObject *str, PyObject *mapping, const char *errors){ PyObject *result; str = PyUnicode_FromObject(str); if (str == NULL) goto onError; result = PyUnicode_TranslateCharmap(PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str), mapping, errors); Py_DECREF(str); return result; onError: Py_XDECREF(str); return NULL;} /* --- Decimal Encoder ---------------------------------------------------- */ int PyUnicode_EncodeDecimal(Py_UNICODE *s, Py_ssize_t length, char *output, const char *errors){ Py_UNICODE *p, *end; PyObject *errorHandler = NULL; PyObject *exc = NULL; const char *encoding = "decimal"; const char *reason = "invalid decimal Unicode string"; /* the following variable is used for caching string comparisons * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */ int known_errorHandler = -1; if (output == NULL) { PyErr_BadArgument(); return -1; } p = s; end = s + length; while (p < end) { register Py_UNICODE ch = *p; int decimal; PyObject *repunicode; Py_ssize_t repsize; Py_ssize_t newpos; Py_UNICODE *uni2; Py_UNICODE *collstart; Py_UNICODE *collend; if (Py_UNICODE_ISSPACE(ch)) { *output++ = ' '; ++p; continue; } decimal = Py_UNICODE_TODECIMAL(ch); if (decimal >= 0) { *output++ = '0' + decimal; ++p; continue; } if (0 < ch && ch < 256) { *output++ = (char)ch; ++p; continue; } /* All other characters are considered unencodable */ collstart = p; collend = p+1; while (collend < end) { if ((0 < *collend && *collend < 256) || !Py_UNICODE_ISSPACE(*collend) || Py_UNICODE_TODECIMAL(*collend)) break; } /* cache callback name lookup * (if not done yet, i.e. it's the first error) */ if (known_errorHandler==-1) { if ((errors==NULL) || (!strcmp(errors, "strict"))) known_errorHandler = 1; else if (!strcmp(errors, "replace")) known_errorHandler = 2; else if (!strcmp(errors, "ignore")) known_errorHandler = 3; else if (!strcmp(errors, "xmlcharrefreplace")) known_errorHandler = 4; else known_errorHandler = 0; } switch (known_errorHandler) { case 1: /* strict */ raise_encode_exception(&exc, encoding, s, length, collstart-s, collend-s, reason); goto onError; case 2: /* replace */ for (p = collstart; p < collend; ++p) *output++ = '?'; /* fall through */ case 3: /* ignore */ p = collend; break; case 4: /* xmlcharrefreplace */ /* generate replacement (temporarily (mis)uses p) */ for (p = collstart; p < collend; ++p) output += sprintf(output, "&#%d;", (int)*p); p = collend; break; default: repunicode = unicode_encode_call_errorhandler(errors, &errorHandler, encoding, reason, s, length, &exc, collstart-s, collend-s, &newpos); if (repunicode == NULL) goto onError; /* generate replacement */ repsize = PyUnicode_GET_SIZE(repunicode); for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2) { Py_UNICODE ch = *uni2; if (Py_UNICODE_ISSPACE(ch)) *output++ = ' '; else { decimal = Py_UNICODE_TODECIMAL(ch); if (decimal >= 0) *output++ = '0' + decimal; else if (0 < ch && ch < 256) *output++ = (char)ch; else { Py_DECREF(repunicode); raise_encode_exception(&exc, encoding, s, length, collstart-s, collend-s, reason); goto onError; } } } p = s + newpos; Py_DECREF(repunicode); } } /* 0-terminate the output string */ *output++ = '\0'; Py_XDECREF(exc); Py_XDECREF(errorHandler); return 0; onError: Py_XDECREF(exc); Py_XDECREF(errorHandler); return -1;} /* --- Helpers ------------------------------------------------------------ */ #define STRINGLIB_CHAR Py_UNICODE #define STRINGLIB_LEN PyUnicode_GET_SIZE#define STRINGLIB_NEW PyUnicode_FromUnicode#define STRINGLIB_STR PyUnicode_AS_UNICODE Py_LOCAL_INLINE(int)STRINGLIB_CMP(const Py_UNICODE* str, const Py_UNICODE* other, Py_ssize_t len){ if (str[0] != other[0]) return 1; return memcmp((void*) str, (void*) other, len * sizeof(Py_UNICODE));} #define STRINGLIB_EMPTY unicode_empty #include "stringlib/fastsearch.h" #include "stringlib/count.h"#include "stringlib/find.h"#include "stringlib/partition.h" /* helper macro to fixup start/end slice values */#define FIX_START_END(obj) \ if (start < 0) \ start += (obj)->length; \ if (start < 0) \ start = 0; \ if (end > (obj)->length) \ end = (obj)->length; \ if (end < 0) \ end += (obj)->length; \ if (end < 0) \ end = 0; Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end){ Py_ssize_t result; PyUnicodeObject* str_obj; PyUnicodeObject* sub_obj; str_obj = (PyUnicodeObject*) PyUnicode_FromObject(str); if (!str_obj) return -1; sub_obj = (PyUnicodeObject*) PyUnicode_FromObject(substr); if (!sub_obj) { Py_DECREF(str_obj); return -1; } FIX_START_END(str_obj); result = stringlib_count( str_obj->str + start, end - start, sub_obj->str, sub_obj->length ); Py_DECREF(sub_obj); Py_DECREF(str_obj); return result;} Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *sub, Py_ssize_t start, Py_ssize_t end, int direction){ Py_ssize_t result; str = PyUnicode_FromObject(str); if (!str) return -2; sub = PyUnicode_FromObject(sub); if (!sub) { Py_DECREF(str); return -2; } if (direction > 0) result = stringlib_find_slice( PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str), PyUnicode_AS_UNICODE(sub), PyUnicode_GET_SIZE(sub), start, end ); else result = stringlib_rfind_slice( PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str), PyUnicode_AS_UNICODE(sub), PyUnicode_GET_SIZE(sub), start, end ); Py_DECREF(str); Py_DECREF(sub); return result;} staticint tailmatch(PyUnicodeObject *self, PyUnicodeObject *substring, Py_ssize_t start, Py_ssize_t end, int direction){ if (substring->length == 0) return 1; FIX_START_END(self); end -= substring->length; if (end < start) return 0; if (direction > 0) { if (Py_UNICODE_MATCH(self, end, substring)) return 1; } else { if (Py_UNICODE_MATCH(self, start, substring)) return 1; } return 0;} Py_ssize_t PyUnicode_Tailmatch(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction){ Py_ssize_t result; str = PyUnicode_FromObject(str); if (str == NULL) return -1; substr = PyUnicode_FromObject(substr); if (substr == NULL) { Py_DECREF(str); return -1; } result = tailmatch((PyUnicodeObject *)str, (PyUnicodeObject *)substr, start, end, direction); Py_DECREF(str); Py_DECREF(substr); return result;} /* Apply fixfct filter to the Unicode object self and return a reference to the modified object */ staticPyObject *fixup(PyUnicodeObject *self, int (*fixfct)(PyUnicodeObject *s)){ PyUnicodeObject *u; u = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, self->length); if (u == NULL) return NULL; Py_UNICODE_COPY(u->str, self->str, self->length); if (!fixfct(u) && PyUnicode_CheckExact(self)) { /* fixfct should return TRUE if it modified the buffer. If FALSE, return a reference to the original buffer instead (to save space, not time) */ Py_INCREF(self); Py_DECREF(u); return (PyObject*) self; } return (PyObject*) u;} staticint fixupper(PyUnicodeObject *self){ Py_ssize_t len = self->length; Py_UNICODE *s = self->str; int status = 0; while (len-- > 0) { register Py_UNICODE ch; ch = Py_UNICODE_TOUPPER(*s); if (ch != *s) { status = 1; *s = ch; } s++; } return status;} staticint fixlower(PyUnicodeObject *self){ Py_ssize_t len = self->length; Py_UNICODE *s = self->str; int status = 0; while (len-- > 0) { register Py_UNICODE ch; ch = Py_UNICODE_TOLOWER(*s); if (ch != *s) { status = 1; *s = ch; } s++; } return status;} staticint fixswapcase(PyUnicodeObject *self){ Py_ssize_t len = self->length; Py_UNICODE *s = self->str; int status = 0; while (len-- > 0) { if (Py_UNICODE_ISUPPER(*s)) { *s = Py_UNICODE_TOLOWER(*s); status = 1; } else if (Py_UNICODE_ISLOWER(*s)) { *s = Py_UNICODE_TOUPPER(*s); status = 1; } s++; } return status;} staticint fixcapitalize(PyUnicodeObject *self){ Py_ssize_t len = self->length; Py_UNICODE *s = self->str; int status = 0; if (len == 0) return 0; if (Py_UNICODE_ISLOWER(*s)) { *s = Py_UNICODE_TOUPPER(*s);Lines 4001–4500 of 8067. Previous lines Load more
Py_UNICODE *uni2; /* startpos for collecting untranslatable chars */ const Py_UNICODE *collstart = p; const Py_UNICODE *collend = p+1; const Py_UNICODE *coll; /* find all untranslatable characters */ while (collend < endp) { if (charmaptranslate_lookup(*collend, mapping, &x)) goto onError; Py_XDECREF(x); if (x!=Py_None) break; ++collend; } /* cache callback name lookup * (if not done yet, i.e. it's the first error) */ if (known_errorHandler==-1) { if ((errors==NULL) || (!strcmp(errors, "strict"))) known_errorHandler = 1; else if (!strcmp(errors, "replace")) known_errorHandler = 2; else if (!strcmp(errors, "ignore")) known_errorHandler = 3; else if (!strcmp(errors, "xmlcharrefreplace")) known_errorHandler = 4; else known_errorHandler = 0; } switch (known_errorHandler) { case 1: /* strict */ raise_translate_exception(&exc, startp, size, collstart-startp, collend-startp, reason); goto onError; case 2: /* replace */ /* No need to check for space, this is a 1:1 replacement */ for (coll = collstart; coll<collend; ++coll) *str++ = '?'; /* fall through */ case 3: /* ignore */ p = collend; break; case 4: /* xmlcharrefreplace */ /* generate replacement (temporarily (mis)uses p) */ for (p = collstart; p < collend; ++p) { char buffer[2+29+1+1]; char *cp; sprintf(buffer, "&#%d;", (int)*p); if (charmaptranslate_makespace(&res, &str, (str-PyUnicode_AS_UNICODE(res))+strlen(buffer)+(endp-collend))) goto onError; for (cp = buffer; *cp; ++cp) *str++ = *cp; } p = collend; break; default: repunicode = unicode_translate_call_errorhandler(errors, &errorHandler, reason, startp, size, &exc, collstart-startp, collend-startp, &newpos); if (repunicode == NULL) goto onError; /* generate replacement */ repsize = PyUnicode_GET_SIZE(repunicode); if (charmaptranslate_makespace(&res, &str, (str-PyUnicode_AS_UNICODE(res))+repsize+(endp-collend))) { Py_DECREF(repunicode); goto onError; } for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2) *str++ = *uni2; p = startp + newpos; Py_DECREF(repunicode); } } } /* Resize if we allocated to much */ respos = str-PyUnicode_AS_UNICODE(res); if (respos<PyUnicode_GET_SIZE(res)) { if (_PyUnicode_Resize(&res, respos) < 0) goto onError; } Py_XDECREF(exc); Py_XDECREF(errorHandler); return res; onError: Py_XDECREF(res); Py_XDECREF(exc); Py_XDECREF(errorHandler); return NULL; } PyObject *PyUnicode_Translate(PyObject *str, PyObject *mapping, const char *errors) { PyObject *result; str = PyUnicode_FromObject(str); if (str == NULL) goto onError; result = PyUnicode_TranslateCharmap(PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str), mapping, errors); Py_DECREF(str); return result; onError: Py_XDECREF(str); return NULL; } /* --- Decimal Encoder ---------------------------------------------------- */ int PyUnicode_EncodeDecimal(Py_UNICODE *s, Py_ssize_t length, char *output, const char *errors) { Py_UNICODE *p, *end; PyObject *errorHandler = NULL; PyObject *exc = NULL; const char *encoding = "decimal"; const char *reason = "invalid decimal Unicode string"; /* the following variable is used for caching string comparisons * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */ int known_errorHandler = -1; if (output == NULL) { PyErr_BadArgument(); return -1; } p = s; end = s + length; while (p < end) { register Py_UNICODE ch = *p; int decimal; PyObject *repunicode; Py_ssize_t repsize; Py_ssize_t newpos; Py_UNICODE *uni2; Py_UNICODE *collstart; Py_UNICODE *collend; if (Py_UNICODE_ISSPACE(ch)) { *output++ = ' '; ++p; continue; } decimal = Py_UNICODE_TODECIMAL(ch); if (decimal >= 0) { *output++ = '0' + decimal; ++p; continue; } if (0 < ch && ch < 256) { *output++ = (char)ch; ++p; continue; } /* All other characters are considered unencodable */ collstart = p; collend = p+1; while (collend < end) { if ((0 < *collend && *collend < 256) || !Py_UNICODE_ISSPACE(*collend) || Py_UNICODE_TODECIMAL(*collend)) break; } /* cache callback name lookup * (if not done yet, i.e. it's the first error) */ if (known_errorHandler==-1) { if ((errors==NULL) || (!strcmp(errors, "strict"))) known_errorHandler = 1; else if (!strcmp(errors, "replace")) known_errorHandler = 2; else if (!strcmp(errors, "ignore")) known_errorHandler = 3; else if (!strcmp(errors, "xmlcharrefreplace")) known_errorHandler = 4; else known_errorHandler = 0; } switch (known_errorHandler) { case 1: /* strict */ raise_encode_exception(&exc, encoding, s, length, collstart-s, collend-s, reason); goto onError; case 2: /* replace */ for (p = collstart; p < collend; ++p) *output++ = '?'; /* fall through */ case 3: /* ignore */ p = collend; break; case 4: /* xmlcharrefreplace */ /* generate replacement (temporarily (mis)uses p) */ for (p = collstart; p < collend; ++p) output += sprintf(output, "&#%d;", (int)*p); p = collend; break; default: repunicode = unicode_encode_call_errorhandler(errors, &errorHandler, encoding, reason, s, length, &exc, collstart-s, collend-s, &newpos); if (repunicode == NULL) goto onError; /* generate replacement */ repsize = PyUnicode_GET_SIZE(repunicode); for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2) { Py_UNICODE ch = *uni2; if (Py_UNICODE_ISSPACE(ch)) *output++ = ' '; else { decimal = Py_UNICODE_TODECIMAL(ch); if (decimal >= 0) *output++ = '0' + decimal; else if (0 < ch && ch < 256) *output++ = (char)ch; else { Py_DECREF(repunicode); raise_encode_exception(&exc, encoding, s, length, collstart-s, collend-s, reason); goto onError; } } } p = s + newpos; Py_DECREF(repunicode); } } /* 0-terminate the output string */ *output++ = '\0'; Py_XDECREF(exc); Py_XDECREF(errorHandler); return 0; onError: Py_XDECREF(exc); Py_XDECREF(errorHandler); return -1; } /* --- Helpers ------------------------------------------------------------ */ #define STRINGLIB_CHAR Py_UNICODE #define STRINGLIB_LEN PyUnicode_GET_SIZE #define STRINGLIB_NEW PyUnicode_FromUnicode #define STRINGLIB_STR PyUnicode_AS_UNICODE Py_LOCAL_INLINE(int) STRINGLIB_CMP(const Py_UNICODE* str, const Py_UNICODE* other, Py_ssize_t len) { if (str[0] != other[0]) return 1; return memcmp((void*) str, (void*) other, len * sizeof(Py_UNICODE)); } #define STRINGLIB_EMPTY unicode_empty #include "stringlib/fastsearch.h" #include "stringlib/count.h" #include "stringlib/find.h" #include "stringlib/partition.h" /* helper macro to fixup start/end slice values */ #define FIX_START_END(obj) \ if (start < 0) \ start += (obj)->length; \ if (start < 0) \ start = 0; \ if (end > (obj)->length) \ end = (obj)->length; \ if (end < 0) \ end += (obj)->length; \ if (end < 0) \ end = 0; Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end) { Py_ssize_t result; PyUnicodeObject* str_obj; PyUnicodeObject* sub_obj; str_obj = (PyUnicodeObject*) PyUnicode_FromObject(str); if (!str_obj) return -1; sub_obj = (PyUnicodeObject*) PyUnicode_FromObject(substr); if (!sub_obj) { Py_DECREF(str_obj); return -1; } FIX_START_END(str_obj); result = stringlib_count( str_obj->str + start, end - start, sub_obj->str, sub_obj->length ); Py_DECREF(sub_obj); Py_DECREF(str_obj); return result; } Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *sub, Py_ssize_t start, Py_ssize_t end, int direction) { Py_ssize_t result; str = PyUnicode_FromObject(str); if (!str) return -2; sub = PyUnicode_FromObject(sub); if (!sub) { Py_DECREF(str); return -2; } if (direction > 0) result = stringlib_find_slice( PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str), PyUnicode_AS_UNICODE(sub), PyUnicode_GET_SIZE(sub), start, end ); else result = stringlib_rfind_slice( PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str), PyUnicode_AS_UNICODE(sub), PyUnicode_GET_SIZE(sub), start, end ); Py_DECREF(str); Py_DECREF(sub); return result; } static int tailmatch(PyUnicodeObject *self, PyUnicodeObject *substring, Py_ssize_t start, Py_ssize_t end, int direction) { if (substring->length == 0) return 1; FIX_START_END(self); end -= substring->length; if (end < start) return 0; if (direction > 0) { if (Py_UNICODE_MATCH(self, end, substring)) return 1; } else { if (Py_UNICODE_MATCH(self, start, substring)) return 1; } return 0; } Py_ssize_t PyUnicode_Tailmatch(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) { Py_ssize_t result; str = PyUnicode_FromObject(str); if (str == NULL) return -1; substr = PyUnicode_FromObject(substr); if (substr == NULL) { Py_DECREF(str); return -1; } result = tailmatch((PyUnicodeObject *)str, (PyUnicodeObject *)substr, start, end, direction); Py_DECREF(str); Py_DECREF(substr); return result; } /* Apply fixfct filter to the Unicode object self and return a reference to the modified object */ static PyObject *fixup(PyUnicodeObject *self, int (*fixfct)(PyUnicodeObject *s)) { PyUnicodeObject *u; u = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, self->length); if (u == NULL) return NULL; Py_UNICODE_COPY(u->str, self->str, self->length); if (!fixfct(u) && PyUnicode_CheckExact(self)) { /* fixfct should return TRUE if it modified the buffer. If FALSE, return a reference to the original buffer instead (to save space, not time) */ Py_INCREF(self); Py_DECREF(u); return (PyObject*) self; } return (PyObject*) u; } static int fixupper(PyUnicodeObject *self) { Py_ssize_t len = self->length; Py_UNICODE *s = self->str; int status = 0; while (len-- > 0) { register Py_UNICODE ch; ch = Py_UNICODE_TOUPPER(*s); if (ch != *s) { status = 1; *s = ch; } s++; } return status; } static int fixlower(PyUnicodeObject *self) { Py_ssize_t len = self->length; Py_UNICODE *s = self->str; int status = 0; while (len-- > 0) { register Py_UNICODE ch; ch = Py_UNICODE_TOLOWER(*s); if (ch != *s) { status = 1; *s = ch; } s++; } return status; } static int fixswapcase(PyUnicodeObject *self) { Py_ssize_t len = self->length; Py_UNICODE *s = self->str; int status = 0; while (len-- > 0) { if (Py_UNICODE_ISUPPER(*s)) { *s = Py_UNICODE_TOLOWER(*s); status = 1; } else if (Py_UNICODE_ISLOWER(*s)) { *s = Py_UNICODE_TOUPPER(*s); status = 1; } s++; } return status; } static int fixcapitalize(PyUnicodeObject *self) { Py_ssize_t len = self->length; Py_UNICODE *s = self->str; int status = 0; if (len == 0) return 0; if (Py_UNICODE_ISLOWER(*s)) { *s = Py_UNICODE_TOUPPER(*s);