Many changes for Unicode, by Marc-Andre Lemburg.

This commit is contained in:
Guido van Rossum 2000-03-10 22:55:18 +00:00
parent d57fd91488
commit 4c08d554b9
6 changed files with 943 additions and 198 deletions

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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