mirror of https://github.com/python/cpython.git
Many changes for Unicode, by Marc-Andre Lemburg.
This commit is contained in:
parent
d57fd91488
commit
4c08d554b9
|
@ -199,6 +199,114 @@ PyObject_DelItem(o, key)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int PyObject_AsCharBuffer(PyObject *obj,
|
||||
const char **buffer,
|
||||
int *buffer_len)
|
||||
{
|
||||
PyBufferProcs *pb;
|
||||
const char *pp;
|
||||
int len;
|
||||
|
||||
if (obj == NULL || buffer == NULL || buffer_len == NULL) {
|
||||
null_error();
|
||||
return -1;
|
||||
}
|
||||
pb = obj->ob_type->tp_as_buffer;
|
||||
if ( pb == NULL ||
|
||||
pb->bf_getcharbuffer == NULL ||
|
||||
pb->bf_getsegcount == NULL ) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"expected a character buffer object");
|
||||
goto onError;
|
||||
}
|
||||
if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"expected a single-segment buffer object");
|
||||
goto onError;
|
||||
}
|
||||
len = (*pb->bf_getcharbuffer)(obj,0,&pp);
|
||||
if (len < 0)
|
||||
goto onError;
|
||||
*buffer = pp;
|
||||
*buffer_len = len;
|
||||
return 0;
|
||||
|
||||
onError:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int PyObject_AsReadBuffer(PyObject *obj,
|
||||
const void **buffer,
|
||||
int *buffer_len)
|
||||
{
|
||||
PyBufferProcs *pb;
|
||||
void *pp;
|
||||
int len;
|
||||
|
||||
if (obj == NULL || buffer == NULL || buffer_len == NULL) {
|
||||
null_error();
|
||||
return -1;
|
||||
}
|
||||
pb = obj->ob_type->tp_as_buffer;
|
||||
if ( pb == NULL ||
|
||||
pb->bf_getreadbuffer == NULL ||
|
||||
pb->bf_getsegcount == NULL ) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"expected a readable buffer object");
|
||||
goto onError;
|
||||
}
|
||||
if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"expected a single-segment buffer object");
|
||||
goto onError;
|
||||
}
|
||||
len = (*pb->bf_getreadbuffer)(obj,0,&pp);
|
||||
if (len < 0)
|
||||
goto onError;
|
||||
*buffer = pp;
|
||||
*buffer_len = len;
|
||||
return 0;
|
||||
|
||||
onError:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int PyObject_AsWriteBuffer(PyObject *obj,
|
||||
void **buffer,
|
||||
int *buffer_len)
|
||||
{
|
||||
PyBufferProcs *pb;
|
||||
void*pp;
|
||||
int len;
|
||||
|
||||
if (obj == NULL || buffer == NULL || buffer_len == NULL) {
|
||||
null_error();
|
||||
return -1;
|
||||
}
|
||||
pb = obj->ob_type->tp_as_buffer;
|
||||
if ( pb == NULL ||
|
||||
pb->bf_getwritebuffer == NULL ||
|
||||
pb->bf_getsegcount == NULL ) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"expected a writeable buffer object");
|
||||
goto onError;
|
||||
}
|
||||
if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"expected a single-segment buffer object");
|
||||
goto onError;
|
||||
}
|
||||
len = (*pb->bf_getwritebuffer)(obj,0,&pp);
|
||||
if (len < 0)
|
||||
goto onError;
|
||||
*buffer = pp;
|
||||
*buffer_len = len;
|
||||
return 0;
|
||||
|
||||
onError:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Operations on numbers */
|
||||
|
||||
int
|
||||
|
@ -447,6 +555,8 @@ PyNumber_Remainder(v, w)
|
|||
{
|
||||
if (PyString_Check(v))
|
||||
return PyString_Format(v, w);
|
||||
else if (PyUnicode_Check(v))
|
||||
return PyUnicode_Format(v, w);
|
||||
BINOP(v, w, "__mod__", "__rmod__", PyNumber_Remainder);
|
||||
if (v->ob_type->tp_as_number != NULL) {
|
||||
PyObject *x = NULL;
|
||||
|
@ -621,6 +731,8 @@ PyNumber_Int(o)
|
|||
PyObject *o;
|
||||
{
|
||||
PyNumberMethods *m;
|
||||
const char *buffer;
|
||||
int buffer_len;
|
||||
|
||||
if (o == NULL)
|
||||
return null_error();
|
||||
|
@ -629,6 +741,8 @@ PyNumber_Int(o)
|
|||
m = o->ob_type->tp_as_number;
|
||||
if (m && m->nb_int)
|
||||
return m->nb_int(o);
|
||||
if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
|
||||
return PyInt_FromString((char*)buffer, NULL, 10);
|
||||
|
||||
return type_error("object can't be converted to int");
|
||||
}
|
||||
|
@ -655,17 +769,19 @@ PyNumber_Int(o)
|
|||
* calls PyLong_FromString().
|
||||
*/
|
||||
static PyObject *
|
||||
long_from_string(v)
|
||||
PyObject *v;
|
||||
long_from_string(s, len)
|
||||
const char *s;
|
||||
int len;
|
||||
{
|
||||
char *s, *end;
|
||||
const char *start;
|
||||
char *end;
|
||||
PyObject *x;
|
||||
char buffer[256]; /* For errors */
|
||||
|
||||
s = PyString_AS_STRING(v);
|
||||
start = s;
|
||||
while (*s && isspace(Py_CHARMASK(*s)))
|
||||
s++;
|
||||
x = PyLong_FromString(s, &end, 10);
|
||||
x = PyLong_FromString((char*)s, &end, 10);
|
||||
if (x == NULL) {
|
||||
if (PyErr_ExceptionMatches(PyExc_ValueError))
|
||||
goto bad;
|
||||
|
@ -680,7 +796,7 @@ long_from_string(v)
|
|||
Py_XDECREF(x);
|
||||
return NULL;
|
||||
}
|
||||
else if (end != PyString_AS_STRING(v) + PyString_GET_SIZE(v)) {
|
||||
else if (end != start + len) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"null byte in argument for long()");
|
||||
return NULL;
|
||||
|
@ -693,6 +809,8 @@ PyNumber_Long(o)
|
|||
PyObject *o;
|
||||
{
|
||||
PyNumberMethods *m;
|
||||
const char *buffer;
|
||||
int buffer_len;
|
||||
|
||||
if (o == NULL)
|
||||
return null_error();
|
||||
|
@ -701,10 +819,13 @@ PyNumber_Long(o)
|
|||
* doesn't do. In particular long('9.5') must raise an
|
||||
* exception, not truncate the float.
|
||||
*/
|
||||
return long_from_string(o);
|
||||
return long_from_string(PyString_AS_STRING(o),
|
||||
PyString_GET_SIZE(o));
|
||||
m = o->ob_type->tp_as_number;
|
||||
if (m && m->nb_long)
|
||||
return m->nb_long(o);
|
||||
if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
|
||||
return long_from_string(buffer, buffer_len);
|
||||
|
||||
return type_error("object can't be converted to long");
|
||||
}
|
||||
|
@ -717,13 +838,12 @@ PyNumber_Float(o)
|
|||
|
||||
if (o == NULL)
|
||||
return null_error();
|
||||
if (PyString_Check(o))
|
||||
return PyFloat_FromString(o, NULL);
|
||||
m = o->ob_type->tp_as_number;
|
||||
if (m && m->nb_float)
|
||||
return m->nb_float(o);
|
||||
|
||||
return type_error("object can't be converted to float");
|
||||
if (!PyString_Check(o)) {
|
||||
m = o->ob_type->tp_as_number;
|
||||
if (m && m->nb_float)
|
||||
return m->nb_float(o);
|
||||
}
|
||||
return PyFloat_FromString(o, NULL);
|
||||
}
|
||||
|
||||
/* Operations on sequences */
|
||||
|
|
|
@ -75,6 +75,8 @@ typedef struct {
|
|||
PyObject *f_mode;
|
||||
int (*f_close) Py_PROTO((FILE *));
|
||||
int f_softspace; /* Flag used by 'print' command */
|
||||
int f_binary; /* Flag which indicates whether the file is open
|
||||
open in binary (1) or test (0) mode */
|
||||
} PyFileObject;
|
||||
|
||||
FILE *
|
||||
|
@ -112,6 +114,10 @@ PyFile_FromFile(fp, name, mode, close)
|
|||
f->f_mode = PyString_FromString(mode);
|
||||
f->f_close = close;
|
||||
f->f_softspace = 0;
|
||||
if (strchr(mode,'b') != NULL)
|
||||
f->f_binary = 1;
|
||||
else
|
||||
f->f_binary = 0;
|
||||
if (f->f_name == NULL || f->f_mode == NULL) {
|
||||
Py_DECREF(f);
|
||||
return NULL;
|
||||
|
@ -863,7 +869,7 @@ file_write(f, args)
|
|||
int n, n2;
|
||||
if (f->f_fp == NULL)
|
||||
return err_closed();
|
||||
if (!PyArg_Parse(args, "s#", &s, &n))
|
||||
if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
|
||||
return NULL;
|
||||
f->f_softspace = 0;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
|
|
|
@ -155,15 +155,22 @@ PyFloat_FromString(v, pend)
|
|||
char **pend;
|
||||
{
|
||||
extern double strtod Py_PROTO((const char *, char **));
|
||||
char *s, *last, *end;
|
||||
const char *s, *last, *end;
|
||||
double x;
|
||||
char buffer[256]; /* For errors */
|
||||
int len;
|
||||
|
||||
if (!PyString_Check(v))
|
||||
if (PyString_Check(v)) {
|
||||
s = PyString_AS_STRING(v);
|
||||
len = PyString_GET_SIZE(v);
|
||||
}
|
||||
else if (PyObject_AsCharBuffer(v, &s, &len)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"float() needs a string argument");
|
||||
return NULL;
|
||||
s = PyString_AS_STRING(v);
|
||||
}
|
||||
|
||||
last = s + PyString_GET_SIZE(v);
|
||||
last = s + len;
|
||||
while (*s && isspace(Py_CHARMASK(*s)))
|
||||
s++;
|
||||
if (s[0] == '\0') {
|
||||
|
@ -172,7 +179,7 @@ PyFloat_FromString(v, pend)
|
|||
}
|
||||
errno = 0;
|
||||
PyFPE_START_PROTECT("PyFloat_FromString", return 0)
|
||||
x = strtod(s, &end);
|
||||
x = strtod((char *)s, (char **)&end);
|
||||
PyFPE_END_PROTECT(x)
|
||||
/* Believe it or not, Solaris 2.6 can move end *beyond* the null
|
||||
byte at the end of the string, when the input is inf(inity) */
|
||||
|
@ -185,7 +192,7 @@ PyFloat_FromString(v, pend)
|
|||
PyErr_SetString(PyExc_ValueError, buffer);
|
||||
return NULL;
|
||||
}
|
||||
else if (end != PyString_AS_STRING(v) + PyString_GET_SIZE(v)) {
|
||||
else if (end != last) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"null byte in argument for float()");
|
||||
return NULL;
|
||||
|
@ -196,7 +203,7 @@ PyFloat_FromString(v, pend)
|
|||
return NULL;
|
||||
}
|
||||
if (pend)
|
||||
*pend = end;
|
||||
*pend = (char *)end;
|
||||
return PyFloat_FromDouble(x);
|
||||
}
|
||||
|
||||
|
@ -785,7 +792,7 @@ PyFloat_Fini()
|
|||
PyFloat_AsString(buf, p);
|
||||
fprintf(stderr,
|
||||
"# <float at %lx, refcnt=%d, val=%s>\n",
|
||||
p, p->ob_refcnt, buf);
|
||||
(long)p, p->ob_refcnt, buf);
|
||||
}
|
||||
}
|
||||
list = list->next;
|
||||
|
|
|
@ -942,7 +942,7 @@ PyInt_Fini()
|
|||
if (PyInt_Check(p) && p->ob_refcnt != 0)
|
||||
fprintf(stderr,
|
||||
"# <int at %lx, refcnt=%d, val=%ld>\n",
|
||||
p, p->ob_refcnt, p->ob_ival);
|
||||
(long)p, p->ob_refcnt, p->ob_ival);
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
|
|
|
@ -189,11 +189,6 @@ PyObject_Print(op, fp, flags)
|
|||
s = PyObject_Repr(op);
|
||||
if (s == NULL)
|
||||
ret = -1;
|
||||
else if (!PyString_Check(s)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"repr not string");
|
||||
ret = -1;
|
||||
}
|
||||
else {
|
||||
ret = PyObject_Print(s, fp,
|
||||
Py_PRINT_RAW);
|
||||
|
@ -234,14 +229,28 @@ PyObject_Repr(v)
|
|||
v->ob_type->tp_name, (long)v);
|
||||
return PyString_FromString(buf);
|
||||
}
|
||||
else
|
||||
return (*v->ob_type->tp_repr)(v);
|
||||
else {
|
||||
PyObject *res;
|
||||
res = (*v->ob_type->tp_repr)(v);
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
if (!PyString_Check(res)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"__repr__ returned non-string (type %s)",
|
||||
res->ob_type->tp_name);
|
||||
Py_DECREF(res);
|
||||
return NULL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyObject_Str(v)
|
||||
PyObject *v;
|
||||
{
|
||||
PyObject *res;
|
||||
|
||||
if (v == NULL)
|
||||
return PyString_FromString("<NULL>");
|
||||
else if (PyString_Check(v)) {
|
||||
|
@ -249,10 +258,9 @@ PyObject_Str(v)
|
|||
return v;
|
||||
}
|
||||
else if (v->ob_type->tp_str != NULL)
|
||||
return (*v->ob_type->tp_str)(v);
|
||||
res = (*v->ob_type->tp_str)(v);
|
||||
else {
|
||||
PyObject *func;
|
||||
PyObject *res;
|
||||
if (!PyInstance_Check(v) ||
|
||||
(func = PyObject_GetAttrString(v, "__str__")) == NULL) {
|
||||
PyErr_Clear();
|
||||
|
@ -260,8 +268,17 @@ PyObject_Str(v)
|
|||
}
|
||||
res = PyEval_CallObject(func, (PyObject *)NULL);
|
||||
Py_DECREF(func);
|
||||
return res;
|
||||
}
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
if (!PyString_Check(res)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"__str__ returned non-string (type %s)",
|
||||
res->ob_type->tp_name);
|
||||
Py_DECREF(res);
|
||||
return NULL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
@ -330,6 +347,8 @@ PyObject_Compare(v, w)
|
|||
return cmp;
|
||||
}
|
||||
}
|
||||
else if (PyUnicode_Check(v) || PyUnicode_Check(w))
|
||||
return PyUnicode_Compare(v, w);
|
||||
else if (vtp->tp_as_number != NULL)
|
||||
vname = "";
|
||||
else if (wtp->tp_as_number != NULL)
|
||||
|
@ -652,7 +671,7 @@ _Py_ForgetReference(op)
|
|||
register PyObject *op;
|
||||
{
|
||||
#ifdef SLOW_UNREF_CHECK
|
||||
register PyObject *p;
|
||||
register PyObject *p;
|
||||
#endif
|
||||
if (op->ob_refcnt < 0)
|
||||
Py_FatalError("UNREF negative refcnt");
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue