blob: e155a6b49f8c6f60ecaf7bfb9a4ba2a68112356e [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum3f5da241990-12-20 15:06:42 +00002/* Map C struct members to Python object attributes */
3
Guido van Rossum79f25d91997-04-29 20:08:16 +00004#include "Python.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +00005
6#include "structmember.h"
7
Guido van Rossum79f25d91997-04-29 20:08:16 +00008static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00009listmembers(struct memberlist *mlist)
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000010{
11 int i, n;
Guido van Rossum79f25d91997-04-29 20:08:16 +000012 PyObject *v;
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000013 for (n = 0; mlist[n].name != NULL; n++)
14 ;
Guido van Rossum79f25d91997-04-29 20:08:16 +000015 v = PyList_New(n);
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000016 if (v != NULL) {
17 for (i = 0; i < n; i++)
Guido van Rossum79f25d91997-04-29 20:08:16 +000018 PyList_SetItem(v, i,
19 PyString_FromString(mlist[i].name));
20 if (PyErr_Occurred()) {
21 Py_DECREF(v);
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000022 v = NULL;
23 }
24 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +000025 PyList_Sort(v);
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000026 }
27 }
28 return v;
29}
30
Guido van Rossum79f25d91997-04-29 20:08:16 +000031PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000032PyMember_Get(char *addr, struct memberlist *mlist, char *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +000033{
34 struct memberlist *l;
35
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000036 if (strcmp(name, "__members__") == 0)
37 return listmembers(mlist);
Guido van Rossum3f5da241990-12-20 15:06:42 +000038 for (l = mlist; l->name != NULL; l++) {
39 if (strcmp(l->name, name) == 0) {
Guido van Rossum79f25d91997-04-29 20:08:16 +000040 PyObject *v;
Guido van Rossum3f5da241990-12-20 15:06:42 +000041 addr += l->offset;
42 switch (l->type) {
Guido van Rossumab2490a1992-06-03 17:07:23 +000043 case T_BYTE:
Guido van Rossum79f25d91997-04-29 20:08:16 +000044 v = PyInt_FromLong((long)
Guido van Rossumab2490a1992-06-03 17:07:23 +000045 (((*(char*)addr & 0xff)
46 ^ 0x80) - 0x80));
47 break;
48 case T_UBYTE:
Guido van Rossum79f25d91997-04-29 20:08:16 +000049 v = PyInt_FromLong((long) *(char*)addr & 0xff);
Guido van Rossumab2490a1992-06-03 17:07:23 +000050 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +000051 case T_SHORT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000052 v = PyInt_FromLong((long) *(short*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000053 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +000054 case T_USHORT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000055 v = PyInt_FromLong((long)
Guido van Rossumab2490a1992-06-03 17:07:23 +000056 *(unsigned short*)addr);
57 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +000058 case T_INT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000059 v = PyInt_FromLong((long) *(int*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000060 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +000061 case T_UINT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000062 v = PyInt_FromLong((long)
63 *(unsigned int*)addr);
Guido van Rossumab2490a1992-06-03 17:07:23 +000064 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +000065 case T_LONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +000066 v = PyInt_FromLong(*(long*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000067 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +000068 case T_ULONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +000069 v = PyLong_FromDouble((double)
Guido van Rossumab2490a1992-06-03 17:07:23 +000070 *(unsigned long*)addr);
71 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +000072 case T_FLOAT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000073 v = PyFloat_FromDouble((double)*(float*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000074 break;
75 case T_DOUBLE:
Guido van Rossum79f25d91997-04-29 20:08:16 +000076 v = PyFloat_FromDouble(*(double*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000077 break;
78 case T_STRING:
79 if (*(char**)addr == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +000080 Py_INCREF(Py_None);
81 v = Py_None;
Guido van Rossum3f5da241990-12-20 15:06:42 +000082 }
83 else
Guido van Rossum79f25d91997-04-29 20:08:16 +000084 v = PyString_FromString(*(char**)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000085 break;
Jack Jansen599f0d11994-12-14 13:04:05 +000086 case T_STRING_INPLACE:
Guido van Rossum79f25d91997-04-29 20:08:16 +000087 v = PyString_FromString((char*)addr);
Jack Jansen599f0d11994-12-14 13:04:05 +000088 break;
89#ifdef macintosh
90 case T_PSTRING:
91 if (*(char**)addr == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +000092 Py_INCREF(Py_None);
93 v = Py_None;
Jack Jansen599f0d11994-12-14 13:04:05 +000094 }
95 else
Guido van Rossum79f25d91997-04-29 20:08:16 +000096 v = PyString_FromStringAndSize(
97 (*(char**)addr)+1,
98 **(unsigned char**)addr);
Jack Jansen599f0d11994-12-14 13:04:05 +000099 break;
100 case T_PSTRING_INPLACE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000101 v = PyString_FromStringAndSize(
102 ((char*)addr)+1,
103 *(unsigned char*)addr);
Jack Jansen599f0d11994-12-14 13:04:05 +0000104 break;
105#endif /* macintosh */
Guido van Rossumab2490a1992-06-03 17:07:23 +0000106 case T_CHAR:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000107 v = PyString_FromStringAndSize((char*)addr, 1);
Guido van Rossumab2490a1992-06-03 17:07:23 +0000108 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000109 case T_OBJECT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000110 v = *(PyObject **)addr;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000111 if (v == NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000112 v = Py_None;
113 Py_INCREF(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000114 break;
115 default:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000116 PyErr_SetString(PyExc_SystemError,
117 "bad memberlist type");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000118 v = NULL;
119 }
120 return v;
121 }
122 }
123
Guido van Rossum79f25d91997-04-29 20:08:16 +0000124 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000125 return NULL;
126}
127
128int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000129PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000130{
131 struct memberlist *l;
Guido van Rossumadf0e431998-05-20 22:25:32 +0000132 PyObject *oldv;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000133
134 for (l = mlist; l->name != NULL; l++) {
135 if (strcmp(l->name, name) == 0) {
Jack Jansen599f0d11994-12-14 13:04:05 +0000136#ifdef macintosh
Guido van Rossum79f25d91997-04-29 20:08:16 +0000137 if (l->readonly || l->type == T_STRING ||
138 l->type == T_PSTRING)
139 {
Jack Jansen599f0d11994-12-14 13:04:05 +0000140#else
141 if (l->readonly || l->type == T_STRING ) {
142#endif /* macintosh */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000143 PyErr_SetString(PyExc_TypeError,
144 "readonly attribute");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000145 return -1;
146 }
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000147 if (v == NULL && l->type != T_OBJECT) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000148 PyErr_SetString(PyExc_TypeError,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000149 "can't delete numeric/char attribute");
150 return -1;
151 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000152 addr += l->offset;
153 switch (l->type) {
Guido van Rossumab2490a1992-06-03 17:07:23 +0000154 case T_BYTE:
155 case T_UBYTE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000156 if (!PyInt_Check(v)) {
157 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000158 return -1;
159 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000160 *(char*)addr = (char) PyInt_AsLong(v);
Guido van Rossumab2490a1992-06-03 17:07:23 +0000161 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000162 case T_SHORT:
Guido van Rossumab2490a1992-06-03 17:07:23 +0000163 case T_USHORT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000164 if (!PyInt_Check(v)) {
165 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000166 return -1;
167 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000168 *(short*)addr = (short) PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000169 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000170 case T_UINT:
Guido van Rossum3f5da241990-12-20 15:06:42 +0000171 case T_INT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000172 if (!PyInt_Check(v)) {
173 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000174 return -1;
175 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000176 *(int*)addr = (int) PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000177 break;
178 case T_LONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000179 if (!PyInt_Check(v)) {
180 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000181 return -1;
182 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000183 *(long*)addr = PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000184 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000185 case T_ULONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000186 if (PyInt_Check(v))
187 *(long*)addr = PyInt_AsLong(v);
188 else if (PyLong_Check(v))
189 *(long*)addr = PyLong_AsLong(v);
Guido van Rossumab2490a1992-06-03 17:07:23 +0000190 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000191 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000192 return -1;
193 }
194 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000195 case T_FLOAT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000196 if (PyInt_Check(v))
Guido van Rossum644a12b1997-04-09 19:24:53 +0000197 *(float*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000198 (float) PyInt_AsLong(v);
199 else if (PyFloat_Check(v))
200 *(float*)addr =
201 (float) PyFloat_AsDouble(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000202 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000203 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000204 return -1;
205 }
206 break;
207 case T_DOUBLE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000208 if (PyInt_Check(v))
Guido van Rossum644a12b1997-04-09 19:24:53 +0000209 *(double*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000210 (double) PyInt_AsLong(v);
211 else if (PyFloat_Check(v))
212 *(double*)addr = PyFloat_AsDouble(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000213 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000214 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000215 return -1;
216 }
217 break;
218 case T_OBJECT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000219 Py_XINCREF(v);
Guido van Rossumadf0e431998-05-20 22:25:32 +0000220 oldv = *(PyObject **)addr;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000221 *(PyObject **)addr = v;
Guido van Rossumadf0e431998-05-20 22:25:32 +0000222 Py_XDECREF(oldv);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000223 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000224 case T_CHAR:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000225 if (PyString_Check(v) &&
226 PyString_Size(v) == 1) {
Guido van Rossumab2490a1992-06-03 17:07:23 +0000227 *(char*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000228 PyString_AsString(v)[0];
Guido van Rossumab2490a1992-06-03 17:07:23 +0000229 }
230 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000231 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000232 return -1;
233 }
Tim Peters547397c2001-01-27 06:20:08 +0000234 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000235 default:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000236 PyErr_SetString(PyExc_SystemError,
237 "bad memberlist type");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000238 return -1;
239 }
240 return 0;
241 }
242 }
243
Guido van Rossum79f25d91997-04-29 20:08:16 +0000244 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum73531a31990-12-20 23:12:40 +0000245 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000246}