cpython/Python/structmember.c

258 lines
5.3 KiB
C
Raw Normal View History

1991-02-19 08:39:46 -04:00
1990-12-20 11:06:42 -04:00
/* Map C struct members to Python object attributes */
#include "Python.h"
1990-12-20 11:06:42 -04:00
#include "structmember.h"
static PyObject *
listmembers(struct memberlist *mlist)
1991-10-20 17:24:14 -03:00
{
int i, n;
PyObject *v;
1991-10-20 17:24:14 -03:00
for (n = 0; mlist[n].name != NULL; n++)
;
v = PyList_New(n);
1991-10-20 17:24:14 -03:00
if (v != NULL) {
for (i = 0; i < n; i++)
PyList_SetItem(v, i,
PyString_FromString(mlist[i].name));
if (PyErr_Occurred()) {
Py_DECREF(v);
1991-10-20 17:24:14 -03:00
v = NULL;
}
else {
PyList_Sort(v);
1991-10-20 17:24:14 -03:00
}
}
return v;
}
PyObject *
PyMember_Get(char *addr, struct memberlist *mlist, char *name)
1990-12-20 11:06:42 -04:00
{
struct memberlist *l;
1991-10-20 17:24:14 -03:00
if (strcmp(name, "__members__") == 0)
return listmembers(mlist);
1990-12-20 11:06:42 -04:00
for (l = mlist; l->name != NULL; l++) {
if (strcmp(l->name, name) == 0) {
PyObject *v;
if ((l->flags & READ_RESTRICTED) &&
PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
"restricted attribute");
return NULL;
}
1990-12-20 11:06:42 -04:00
addr += l->offset;
switch (l->type) {
case T_BYTE:
v = PyInt_FromLong((long)
(((*(char*)addr & 0xff)
^ 0x80) - 0x80));
break;
case T_UBYTE:
v = PyInt_FromLong((long) *(char*)addr & 0xff);
break;
1990-12-20 11:06:42 -04:00
case T_SHORT:
v = PyInt_FromLong((long) *(short*)addr);
1990-12-20 11:06:42 -04:00
break;
case T_USHORT:
v = PyInt_FromLong((long)
*(unsigned short*)addr);
break;
1990-12-20 11:06:42 -04:00
case T_INT:
v = PyInt_FromLong((long) *(int*)addr);
1990-12-20 11:06:42 -04:00
break;
case T_UINT:
v = PyInt_FromLong((long)
*(unsigned int*)addr);
break;
1990-12-20 11:06:42 -04:00
case T_LONG:
v = PyInt_FromLong(*(long*)addr);
1990-12-20 11:06:42 -04:00
break;
case T_ULONG:
v = PyLong_FromDouble((double)
*(unsigned long*)addr);
break;
1990-12-20 11:06:42 -04:00
case T_FLOAT:
v = PyFloat_FromDouble((double)*(float*)addr);
1990-12-20 11:06:42 -04:00
break;
case T_DOUBLE:
v = PyFloat_FromDouble(*(double*)addr);
1990-12-20 11:06:42 -04:00
break;
case T_STRING:
if (*(char**)addr == NULL) {
Py_INCREF(Py_None);
v = Py_None;
1990-12-20 11:06:42 -04:00
}
else
v = PyString_FromString(*(char**)addr);
1990-12-20 11:06:42 -04:00
break;
case T_STRING_INPLACE:
v = PyString_FromString((char*)addr);
break;
#ifdef macintosh
case T_PSTRING:
if (*(char**)addr == NULL) {
Py_INCREF(Py_None);
v = Py_None;
}
else
v = PyString_FromStringAndSize(
(*(char**)addr)+1,
**(unsigned char**)addr);
break;
case T_PSTRING_INPLACE:
v = PyString_FromStringAndSize(
((char*)addr)+1,
*(unsigned char*)addr);
break;
#endif /* macintosh */
case T_CHAR:
v = PyString_FromStringAndSize((char*)addr, 1);
break;
1990-12-20 11:06:42 -04:00
case T_OBJECT:
v = *(PyObject **)addr;
1990-12-20 11:06:42 -04:00
if (v == NULL)
v = Py_None;
Py_INCREF(v);
1990-12-20 11:06:42 -04:00
break;
default:
PyErr_SetString(PyExc_SystemError,
"bad memberlist type");
1990-12-20 11:06:42 -04:00
v = NULL;
}
return v;
}
}
PyErr_SetString(PyExc_AttributeError, name);
1990-12-20 11:06:42 -04:00
return NULL;
}
int
PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
1990-12-20 11:06:42 -04:00
{
struct memberlist *l;
PyObject *oldv;
1990-12-20 11:06:42 -04:00
for (l = mlist; l->name != NULL; l++) {
if (strcmp(l->name, name) == 0) {
if ((l->flags & READONLY) || l->type == T_STRING
#ifdef macintosh
|| l->type == T_PSTRING
#endif
)
{
PyErr_SetString(PyExc_TypeError,
"readonly attribute");
1990-12-20 11:06:42 -04:00
return -1;
}
if ((l->flags & WRITE_RESTRICTED) &&
PyEval_GetRestricted()) {
PyErr_SetString(PyExc_RuntimeError,
"restricted attribute");
return -1;
1990-12-20 11:06:42 -04:00
}
1994-08-30 05:27:36 -03:00
if (v == NULL && l->type != T_OBJECT) {
PyErr_SetString(PyExc_TypeError,
1994-08-30 05:27:36 -03:00
"can't delete numeric/char attribute");
return -1;
}
1990-12-20 11:06:42 -04:00
addr += l->offset;
switch (l->type) {
case T_BYTE:
case T_UBYTE:
if (!PyInt_Check(v)) {
PyErr_BadArgument();
return -1;
}
*(char*)addr = (char) PyInt_AsLong(v);
break;
1990-12-20 11:06:42 -04:00
case T_SHORT:
case T_USHORT:
if (!PyInt_Check(v)) {
PyErr_BadArgument();
1990-12-20 11:06:42 -04:00
return -1;
}
*(short*)addr = (short) PyInt_AsLong(v);
1990-12-20 11:06:42 -04:00
break;
case T_UINT:
1990-12-20 11:06:42 -04:00
case T_INT:
if (!PyInt_Check(v)) {
PyErr_BadArgument();
1990-12-20 11:06:42 -04:00
return -1;
}
*(int*)addr = (int) PyInt_AsLong(v);
1990-12-20 11:06:42 -04:00
break;
case T_LONG:
if (!PyInt_Check(v)) {
PyErr_BadArgument();
1990-12-20 11:06:42 -04:00
return -1;
}
*(long*)addr = PyInt_AsLong(v);
1990-12-20 11:06:42 -04:00
break;
case T_ULONG:
if (PyInt_Check(v))
*(long*)addr = PyInt_AsLong(v);
else if (PyLong_Check(v))
*(long*)addr = PyLong_AsLong(v);
else {
PyErr_BadArgument();
return -1;
}
break;
1990-12-20 11:06:42 -04:00
case T_FLOAT:
if (PyInt_Check(v))
*(float*)addr =
(float) PyInt_AsLong(v);
else if (PyFloat_Check(v))
*(float*)addr =
(float) PyFloat_AsDouble(v);
1990-12-20 11:06:42 -04:00
else {
PyErr_BadArgument();
1990-12-20 11:06:42 -04:00
return -1;
}
break;
case T_DOUBLE:
if (PyInt_Check(v))
*(double*)addr =
(double) PyInt_AsLong(v);
else if (PyFloat_Check(v))
*(double*)addr = PyFloat_AsDouble(v);
1990-12-20 11:06:42 -04:00
else {
PyErr_BadArgument();
1990-12-20 11:06:42 -04:00
return -1;
}
break;
case T_OBJECT:
Py_XINCREF(v);
oldv = *(PyObject **)addr;
*(PyObject **)addr = v;
Py_XDECREF(oldv);
1990-12-20 11:06:42 -04:00
break;
case T_CHAR:
if (PyString_Check(v) &&
PyString_Size(v) == 1) {
*(char*)addr =
PyString_AsString(v)[0];
}
else {
PyErr_BadArgument();
return -1;
}
break;
1990-12-20 11:06:42 -04:00
default:
PyErr_SetString(PyExc_SystemError,
"bad memberlist type");
1990-12-20 11:06:42 -04:00
return -1;
}
return 0;
}
}
PyErr_SetString(PyExc_AttributeError, name);
1990-12-20 19:12:40 -04:00
return -1;
1990-12-20 11:06:42 -04:00
}