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(const char *addr
, struct memberlist
*mlist
, const 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(const 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
);
107 v
= PyString_FromStringAndSize((char*)addr
, 1);
110 v
= *(PyObject
**)addr
;
116 v
= *(PyObject
**)addr
;
118 PyErr_SetString(PyExc_AttributeError
, l
->name
);
121 #ifdef HAVE_LONG_LONG
123 v
= PyLong_FromLongLong(*(PY_LONG_LONG
*)addr
);
126 v
= PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG
*)addr
);
128 #endif /* HAVE_LONG_LONG */
130 PyErr_SetString(PyExc_SystemError
, "bad memberdescr type");
137 PyMember_Set(char *addr
, struct memberlist
*mlist
, const char *name
, PyObject
*v
)
139 struct memberlist
*l
;
141 for (l
= mlist
; l
->name
!= NULL
; l
++) {
142 if (strcmp(l
->name
, name
) == 0) {
146 copy
.offset
= l
->offset
;
147 copy
.flags
= l
->flags
;
149 return PyMember_SetOne(addr
, ©
, v
);
153 PyErr_SetString(PyExc_AttributeError
, name
);
158 PyMember_SetOne(char *addr
, PyMemberDef
*l
, PyObject
*v
)
162 if ((l
->flags
& READONLY
) || l
->type
== T_STRING
)
164 PyErr_SetString(PyExc_TypeError
, "readonly attribute");
167 if ((l
->flags
& WRITE_RESTRICTED
) && PyEval_GetRestricted()) {
168 PyErr_SetString(PyExc_RuntimeError
, "restricted attribute");
171 if (v
== NULL
&& l
->type
!= T_OBJECT_EX
&& l
->type
!= T_OBJECT
) {
172 PyErr_SetString(PyExc_TypeError
,
173 "can't delete numeric/char attribute");
180 if (!PyInt_Check(v
)) {
184 *(char*)addr
= (char) PyInt_AsLong(v
);
188 if (!PyInt_Check(v
)) {
192 *(short*)addr
= (short) PyInt_AsLong(v
);
196 if (!PyInt_Check(v
)) {
200 *(int*)addr
= (int) PyInt_AsLong(v
);
203 if (!PyInt_Check(v
)) {
207 *(long*)addr
= PyInt_AsLong(v
);
211 *(long*)addr
= PyInt_AsLong(v
);
212 else if (PyLong_Check(v
))
213 *(long*)addr
= PyLong_AsLong(v
);
222 (float) PyInt_AsLong(v
);
223 else if (PyFloat_Check(v
))
225 (float) PyFloat_AsDouble(v
);
233 *(double*)addr
= (double) PyInt_AsLong(v
);
234 else if (PyFloat_Check(v
))
235 *(double*)addr
= PyFloat_AsDouble(v
);
244 oldv
= *(PyObject
**)addr
;
245 *(PyObject
**)addr
= v
;
249 if (PyString_Check(v
) && PyString_Size(v
) == 1) {
250 *(char*)addr
= PyString_AsString(v
)[0];
257 #ifdef HAVE_LONG_LONG
259 if (!PyLong_Check(v
)) {
264 *(PY_LONG_LONG
*)addr
= value
= PyLong_AsLongLong(v
);
265 if ((value
== -1) && PyErr_Occurred()) {
271 if (!PyLong_Check(v
)) {
275 unsigned PY_LONG_LONG value
;
276 *(unsigned PY_LONG_LONG
*)addr
= value
= PyLong_AsUnsignedLongLong(v
);
277 if ((value
== (unsigned PY_LONG_LONG
)-1) &&
283 #endif /* HAVE_LONG_LONG */
285 PyErr_Format(PyExc_SystemError
,
286 "bad memberdescr type for %s", l
->name
);