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 PyErr_SetString(PyExc_SystemError
, "bad memberdescr type");
140 PyMember_Set(char *addr
, struct memberlist
*mlist
, char *name
, PyObject
*v
)
142 struct memberlist
*l
;
144 for (l
= mlist
; l
->name
!= NULL
; l
++) {
145 if (strcmp(l
->name
, name
) == 0) {
149 copy
.offset
= l
->offset
;
150 copy
.flags
= l
->flags
;
152 return PyMember_SetOne(addr
, ©
, v
);
156 PyErr_SetString(PyExc_AttributeError
, name
);
161 PyMember_SetOne(char *addr
, PyMemberDef
*l
, PyObject
*v
)
165 if ((l
->flags
& READONLY
) || l
->type
== T_STRING
167 || l
->type
== T_PSTRING
171 PyErr_SetString(PyExc_TypeError
, "readonly attribute");
174 if ((l
->flags
& WRITE_RESTRICTED
) && PyEval_GetRestricted()) {
175 PyErr_SetString(PyExc_RuntimeError
, "restricted attribute");
178 if (v
== NULL
&& l
->type
!= T_OBJECT
) {
179 PyErr_SetString(PyExc_TypeError
,
180 "can't delete numeric/char attribute");
187 if (!PyInt_Check(v
)) {
191 *(char*)addr
= (char) PyInt_AsLong(v
);
195 if (!PyInt_Check(v
)) {
199 *(short*)addr
= (short) PyInt_AsLong(v
);
203 if (!PyInt_Check(v
)) {
207 *(int*)addr
= (int) PyInt_AsLong(v
);
210 if (!PyInt_Check(v
)) {
214 *(long*)addr
= PyInt_AsLong(v
);
218 *(long*)addr
= PyInt_AsLong(v
);
219 else if (PyLong_Check(v
))
220 *(long*)addr
= PyLong_AsLong(v
);
229 (float) PyInt_AsLong(v
);
230 else if (PyFloat_Check(v
))
232 (float) PyFloat_AsDouble(v
);
240 *(double*)addr
= (double) PyInt_AsLong(v
);
241 else if (PyFloat_Check(v
))
242 *(double*)addr
= PyFloat_AsDouble(v
);
250 oldv
= *(PyObject
**)addr
;
251 *(PyObject
**)addr
= v
;
255 if (PyString_Check(v
) && PyString_Size(v
) == 1) {
256 *(char*)addr
= PyString_AsString(v
)[0];
264 PyErr_SetString(PyExc_SystemError
, "bad memberdescr type");