cinap_lenrekadd hg and python4bb9e2215 years agoHistory
5009 lines · 120.0 KB · C
RawDownload
    if (!PyString_Check(v)) {        PyErr_Format(PyExc_TypeError,                     "encoder did not return a string object (type=%.400s)",                     v->ob_type->tp_name);        Py_DECREF(v);        goto onError;    }     return v;  onError:    return NULL;} static voidstring_dealloc(PyObject *op){	switch (PyString_CHECK_INTERNED(op)) {		case SSTATE_NOT_INTERNED:			break; 		case SSTATE_INTERNED_MORTAL:			/* revive dead object temporarily for DelItem */			op->ob_refcnt = 3;			if (PyDict_DelItem(interned, op) != 0)				Py_FatalError(					"deletion of interned string failed");			break; 		case SSTATE_INTERNED_IMMORTAL:			Py_FatalError("Immortal interned string died."); 		default:			Py_FatalError("Inconsistent interned string state.");	}	op->ob_type->tp_free(op);} /* 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 UTF-8 encoded and should be re-encoded in the   specified encoding.  */ PyObject *PyString_DecodeEscape(const char *s,				Py_ssize_t len,				const char *errors,				Py_ssize_t unicode,				const char *recode_encoding){	int c;	char *p, *buf;	const char *end;	PyObject *v;	Py_ssize_t newlen = recode_encoding ? 4*len:len;	v = PyString_FromStringAndSize((char *)NULL, newlen);	if (v == NULL)		return NULL;	p = buf = PyString_AsString(v);	end = s + len;	while (s < end) {		if (*s != '\\') {		  non_esc:#ifdef Py_USING_UNICODE			if (recode_encoding && (*s & 0x80)) {				PyObject *u, *w;				char *r;				const char* t;				Py_ssize_t rn;				t = s;				/* Decode non-ASCII bytes as UTF-8. */				while (t < end && (*t & 0x80)) t++;				u = PyUnicode_DecodeUTF8(s, t - s, errors);				if(!u) goto failed; 				/* Recode them in target encoding. */				w = PyUnicode_AsEncodedString(					u, recode_encoding, errors);				Py_DECREF(u);				if (!w)	goto failed; 				/* Append bytes to output buffer. */				assert(PyString_Check(w));				r = PyString_AS_STRING(w);				rn = PyString_GET_SIZE(w);				Py_MEMCPY(p, r, rn);				p += rn;				Py_DECREF(w);				s = t;			} else {				*p++ = *s++;			}#else			*p++ = *s++;#endif			continue;		}		s++;                if (s==end) {			PyErr_SetString(PyExc_ValueError,					"Trailing \\ in string");			goto failed;		}		switch (*s++) {		/* XXX This assumes ASCII! */		case '\n': break;		case '\\': *p++ = '\\'; break;		case '\'': *p++ = '\''; break;		case '\"': *p++ = '\"'; break;		case 'b': *p++ = '\b'; break;		case 'f': *p++ = '\014'; break; /* FF */		case 't': *p++ = '\t'; break;		case 'n': *p++ = '\n'; break;		case 'r': *p++ = '\r'; break;		case 'v': *p++ = '\013'; break; /* VT */		case 'a': *p++ = '\007'; break; /* BEL, not classic C */		case '0': case '1': case '2': case '3':		case '4': case '5': case '6': case '7':			c = s[-1] - '0';			if ('0' <= *s && *s <= '7') {				c = (c<<3) + *s++ - '0';				if ('0' <= *s && *s <= '7')					c = (c<<3) + *s++ - '0';			}			*p++ = c;			break;		case 'x':			if (isxdigit(Py_CHARMASK(s[0]))			    && isxdigit(Py_CHARMASK(s[1]))) {				unsigned int x = 0;				c = Py_CHARMASK(*s);				s++;				if (isdigit(c))					x = c - '0';				else if (islower(c))					x = 10 + c - 'a';				else					x = 10 + c - 'A';				x = x << 4;				c = Py_CHARMASK(*s);				s++;				if (isdigit(c))					x += c - '0';				else if (islower(c))					x += 10 + c - 'a';				else					x += 10 + c - 'A';				*p++ = x;				break;			}			if (!errors || strcmp(errors, "strict") == 0) {				PyErr_SetString(PyExc_ValueError,						"invalid \\x escape");				goto failed;			}			if (strcmp(errors, "replace") == 0) {				*p++ = '?';			} else if (strcmp(errors, "ignore") == 0)				/* do nothing */;			else {				PyErr_Format(PyExc_ValueError,					     "decoding error; "					     "unknown error handling code: %.400s",					     errors);				goto failed;			}#ifndef Py_USING_UNICODE		case 'u':		case 'U':		case 'N':			if (unicode) {				PyErr_SetString(PyExc_ValueError,					  "Unicode escapes not legal "					  "when Unicode disabled");				goto failed;			}#endif		default:			*p++ = '\\';			s--;			goto non_esc; /* an arbitry number of unescaped					 UTF-8 bytes may follow. */		}	}	if (p-buf < newlen)		_PyString_Resize(&v, p - buf);	return v;  failed:	Py_DECREF(v);	return NULL;} /* -------------------------------------------------------------------- *//* object api */ static Py_ssize_tstring_getsize(register PyObject *op){    	char *s;    	Py_ssize_t len;	if (PyString_AsStringAndSize(op, &s, &len))		return -1;	return len;} static /*const*/ char *string_getbuffer(register PyObject *op){    	char *s;    	Py_ssize_t len;	if (PyString_AsStringAndSize(op, &s, &len))		return NULL;	return s;} Py_ssize_tPyString_Size(register PyObject *op){	if (!PyString_Check(op))		return string_getsize(op);	return ((PyStringObject *)op) -> ob_size;} /*const*/ char *PyString_AsString(register PyObject *op){	if (!PyString_Check(op))		return string_getbuffer(op);	return ((PyStringObject *)op) -> ob_sval;} intPyString_AsStringAndSize(register PyObject *obj,			 register char **s,			 register Py_ssize_t *len){	if (s == NULL) {		PyErr_BadInternalCall();		return -1;	} 	if (!PyString_Check(obj)) {#ifdef Py_USING_UNICODE		if (PyUnicode_Check(obj)) {			obj = _PyUnicode_AsDefaultEncodedString(obj, NULL);			if (obj == NULL)				return -1;		}		else#endif		{			PyErr_Format(PyExc_TypeError,				     "expected string or Unicode object, "				     "%.200s found", obj->ob_type->tp_name);			return -1;		}	} 	*s = PyString_AS_STRING(obj);	if (len != NULL)		*len = PyString_GET_SIZE(obj);	else if (strlen(*s) != (size_t)PyString_GET_SIZE(obj)) {		PyErr_SetString(PyExc_TypeError,				"expected string without null bytes");		return -1;	}	return 0;} /* -------------------------------------------------------------------- *//* Methods */ #define STRINGLIB_CHAR char #define STRINGLIB_CMP memcmp#define STRINGLIB_LEN PyString_GET_SIZE#define STRINGLIB_NEW PyString_FromStringAndSize#define STRINGLIB_STR PyString_AS_STRING #define STRINGLIB_EMPTY nullstring #include "stringlib/fastsearch.h" #include "stringlib/count.h"#include "stringlib/find.h"#include "stringlib/partition.h"  static intstring_print(PyStringObject *op, FILE *fp, int flags){	Py_ssize_t i;	char c;	int quote; 	/* XXX Ought to check for interrupts when writing long strings */	if (! PyString_CheckExact(op)) {		int ret;		/* A str subclass may have its own __str__ method. */		op = (PyStringObject *) PyObject_Str((PyObject *)op);		if (op == NULL)			return -1;		ret = string_print(op, fp, flags);		Py_DECREF(op);		return ret;	}	if (flags & Py_PRINT_RAW) {		char *data = op->ob_sval;		Py_ssize_t size = op->ob_size;		while (size > INT_MAX) {			/* Very long strings cannot be written atomically.			 * But don't write exactly INT_MAX bytes at a time			 * to avoid memory aligment issues.			 */			const int chunk_size = INT_MAX & ~0x3FFF;			fwrite(data, 1, chunk_size, fp);			data += chunk_size;			size -= chunk_size;		}#ifdef __VMS                if (size) fwrite(data, (int)size, 1, fp);#else                fwrite(data, 1, (int)size, fp);#endif		return 0;	} 	/* figure out which quote to use; single is preferred */	quote = '\'';	if (memchr(op->ob_sval, '\'', op->ob_size) &&	    !memchr(op->ob_sval, '"', op->ob_size))		quote = '"'; 	fputc(quote, fp);	for (i = 0; i < op->ob_size; i++) {		c = op->ob_sval[i];		if (c == quote || c == '\\')			fprintf(fp, "\\%c", c);                else if (c == '\t')                        fprintf(fp, "\\t");                else if (c == '\n')                        fprintf(fp, "\\n");                else if (c == '\r')                        fprintf(fp, "\\r");		else if (c < ' ' || c >= 0x7f)			fprintf(fp, "\\x%02x", c & 0xff);		else			fputc(c, fp);	}	fputc(quote, fp);	return 0;} PyObject *PyString_Repr(PyObject *obj, int smartquotes){	register PyStringObject* op = (PyStringObject*) obj;	size_t newsize = 2 + 4 * op->ob_size;	PyObject *v;	if (newsize > PY_SSIZE_T_MAX || newsize / 4 != op->ob_size) {		PyErr_SetString(PyExc_OverflowError,			"string is too large to make repr");	}	v = PyString_FromStringAndSize((char *)NULL, newsize);	if (v == NULL) {		return NULL;	}	else {		register Py_ssize_t i;		register char c;		register char *p;		int quote; 		/* figure out which quote to use; single is preferred */		quote = '\'';		if (smartquotes &&		    memchr(op->ob_sval, '\'', op->ob_size) &&		    !memchr(op->ob_sval, '"', op->ob_size))			quote = '"'; 		p = PyString_AS_STRING(v);		*p++ = quote;		for (i = 0; i < op->ob_size; i++) {			/* There's at least enough room for a hex escape			   and a closing quote. */			assert(newsize - (p - PyString_AS_STRING(v)) >= 5);			c = op->ob_sval[i];			if (c == quote || c == '\\')				*p++ = '\\', *p++ = c;			else if (c == '\t')				*p++ = '\\', *p++ = 't';			else if (c == '\n')				*p++ = '\\', *p++ = 'n';			else if (c == '\r')				*p++ = '\\', *p++ = 'r';			else if (c < ' ' || c >= 0x7f) {				/* For performance, we don't want to call				   PyOS_snprintf here (extra layers of				   function call). */				sprintf(p, "\\x%02x", c & 0xff);                                p += 4;			}			else				*p++ = c;		}		assert(newsize - (p - PyString_AS_STRING(v)) >= 1);		*p++ = quote;		*p = '\0';		_PyString_Resize(			&v, (p - PyString_AS_STRING(v)));		return v;	}} static PyObject *string_repr(PyObject *op){	return PyString_Repr(op, 1);} static PyObject *string_str(PyObject *s){	assert(PyString_Check(s));	if (PyString_CheckExact(s)) {		Py_INCREF(s);		return s;	}	else {		/* Subtype -- return genuine string with the same value. */		PyStringObject *t = (PyStringObject *) s;		return PyString_FromStringAndSize(t->ob_sval, t->ob_size);	}} static Py_ssize_tstring_length(PyStringObject *a){	return a->ob_size;} static PyObject *string_concat(register PyStringObject *a, register PyObject *bb){	register Py_ssize_t size;	register PyStringObject *op;	if (!PyString_Check(bb)) {#ifdef Py_USING_UNICODE		if (PyUnicode_Check(bb))		    return PyUnicode_Concat((PyObject *)a, bb);#endif		PyErr_Format(PyExc_TypeError,			     "cannot concatenate 'str' and '%.200s' objects",			     bb->ob_type->tp_name);		return NULL;	}#define b ((PyStringObject *)bb)	/* Optimize cases with empty left or right operand */	if ((a->ob_size == 0 || b->ob_size == 0) &&	    PyString_CheckExact(a) && PyString_CheckExact(b)) {		if (a->ob_size == 0) {			Py_INCREF(bb);			return bb;		}		Py_INCREF(a);		return (PyObject *)a;	}	size = a->ob_size + b->ob_size;	if (size < 0) {		PyErr_SetString(PyExc_OverflowError,				"strings are too large to concat");		return NULL;	}	  	/* Inline PyObject_NewVar */	op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);	if (op == NULL)		return PyErr_NoMemory();	PyObject_INIT_VAR(op, &PyString_Type, size);	op->ob_shash = -1;	op->ob_sstate = SSTATE_NOT_INTERNED;	Py_MEMCPY(op->ob_sval, a->ob_sval, a->ob_size);	Py_MEMCPY(op->ob_sval + a->ob_size, b->ob_sval, b->ob_size);	op->ob_sval[size] = '\0';	return (PyObject *) op;#undef b} static PyObject *string_repeat(register PyStringObject *a, register Py_ssize_t n){	register Py_ssize_t i;	register Py_ssize_t j;	register Py_ssize_t size;	register PyStringObject *op;	size_t nbytes;	if (n < 0)		n = 0;	/* watch out for overflows:  the size can overflow int,	 * and the # of bytes needed can overflow size_t	 */

Lines 501–1000 of 5009. Previous lines