2 /* Map C struct members to Python object attributes */
6 #include "structmember.h"
9 listmembers(struct memberlist
*mlist
)
13 for (n
= 0; mlist
[n
].name
!= NULL
; n
++)
17 for (i
= 0; i
< n
; i
++)
19 PyString_FromString(mlist
[i
].name
));
20 if (PyErr_Occurred()) {
32 PyMember_Get(char *addr
, struct memberlist
*mlist
, char *name
)
36 if (strcmp(name
, "__members__") == 0)
37 return listmembers(mlist
);
38 for (l
= mlist
; l
->name
!= NULL
; l
++) {
39 if (strcmp(l
->name
, name
) == 0) {
43 copy
.offset
= l
->offset
;
44 copy
.flags
= l
->flags
;
46 return PyMember_GetOne(addr
, ©
);
49 PyErr_SetString(PyExc_AttributeError
, name
);
54 PyMember_GetOne(char *addr
, PyMemberDef
*l
)
57 if ((l
->flags
& READ_RESTRICTED
) &&
58 PyEval_GetRestricted()) {
59 PyErr_SetString(PyExc_RuntimeError
, "restricted attribute");
66 (long) (((*(char*)addr
& 0xff) ^ 0x80) - 0x80));
69 v
= PyInt_FromLong((long) *(char*)addr
& 0xff);
72 v
= PyInt_FromLong((long) *(short*)addr
);
75 v
= PyInt_FromLong((long) *(unsigned short*)addr
);
78 v
= PyInt_FromLong((long) *(int*)addr
);
81 v
= PyInt_FromLong((long) *(unsigned int*)addr
);
84 v
= PyInt_FromLong(*(long*)addr
);
87 v
= PyLong_FromDouble((double) *(unsigned long*)addr
);
90 v
= PyFloat_FromDouble((double)*(float*)addr
);
93 v
= PyFloat_FromDouble(*(double*)addr
);
96 if (*(char**)addr
== NULL
) {
101 v
= PyString_FromString(*(char**)addr
);
103 case T_STRING_INPLACE
:
104 v
= PyString_FromString((char*)addr
);
108 if (*(char**)addr
== NULL
) {
113 v
= PyString_FromStringAndSize(
115 **(unsigned char**)addr
);
117 case T_PSTRING_INPLACE
:
118 v
= PyString_FromStringAndSize(
120 *(unsigned char*)addr
);
122 #endif /* macintosh */
124 v
= PyString_FromStringAndSize((char*)addr
, 1);
127 v
= *(PyObject
**)addr
;
133 v
= *(PyObject
**)addr
;
135 PyErr_SetString(PyExc_AttributeError
, l
->name
);
139 PyErr_SetString(PyExc_SystemError
, "bad memberdescr type");
146 PyMember_Set(char *addr
, struct memberlist
*mlist
, char *name
, PyObject
*v
)
148 struct memberlist
*l
;
150 for (l
= mlist
; l
->name
!= NULL
; l
++) {
151 if (strcmp(l
->name
, name
) == 0) {
155 copy
.offset
= l
->offset
;
156 copy
.flags
= l
->flags
;
158 return PyMember_SetOne(addr
, ©
, v
);
162 PyErr_SetString(PyExc_AttributeError
, name
);
167 PyMember_SetOne(char *addr
, PyMemberDef
*l
, PyObject
*v
)
171 if ((l
->flags
& READONLY
) || l
->type
== T_STRING
173 || l
->type
== T_PSTRING
177 PyErr_SetString(PyExc_TypeError
, "readonly attribute");
180 if ((l
->flags
& WRITE_RESTRICTED
) && PyEval_GetRestricted()) {
181 PyErr_SetString(PyExc_RuntimeError
, "restricted attribute");
184 if (v
== NULL
&& l
->type
!= T_OBJECT_EX
&& l
->type
!= T_OBJECT
) {
185 PyErr_SetString(PyExc_TypeError
,
186 "can't delete numeric/char attribute");
193 if (!PyInt_Check(v
)) {
197 *(char*)addr
= (char) PyInt_AsLong(v
);
201 if (!PyInt_Check(v
)) {
205 *(short*)addr
= (short) PyInt_AsLong(v
);
209 if (!PyInt_Check(v
)) {
213 *(int*)addr
= (int) PyInt_AsLong(v
);
216 if (!PyInt_Check(v
)) {
220 *(long*)addr
= PyInt_AsLong(v
);
224 *(long*)addr
= PyInt_AsLong(v
);
225 else if (PyLong_Check(v
))
226 *(long*)addr
= PyLong_AsLong(v
);
235 (float) PyInt_AsLong(v
);
236 else if (PyFloat_Check(v
))
238 (float) PyFloat_AsDouble(v
);
246 *(double*)addr
= (double) PyInt_AsLong(v
);
247 else if (PyFloat_Check(v
))
248 *(double*)addr
= PyFloat_AsDouble(v
);
257 oldv
= *(PyObject
**)addr
;
258 *(PyObject
**)addr
= v
;
262 if (PyString_Check(v
) && PyString_Size(v
) == 1) {
263 *(char*)addr
= PyString_AsString(v
)[0];
271 PyErr_Format(PyExc_SystemError
,
272 "bad memberdescr type for %s", l
->name
);