blob: 02464c611f0a2c0cc848e7c25d542682baecaccb [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6d023c91995-01-04 19:12:13 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum3f5da241990-12-20 15:06:42 +000032/* Map C struct members to Python object attributes */
33
Guido van Rossum79f25d91997-04-29 20:08:16 +000034#include "Python.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000035
36#include "structmember.h"
37
Guido van Rossum79f25d91997-04-29 20:08:16 +000038static PyObject *
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000039listmembers(mlist)
40 struct memberlist *mlist;
41{
42 int i, n;
Guido van Rossum79f25d91997-04-29 20:08:16 +000043 PyObject *v;
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000044 for (n = 0; mlist[n].name != NULL; n++)
45 ;
Guido van Rossum79f25d91997-04-29 20:08:16 +000046 v = PyList_New(n);
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000047 if (v != NULL) {
48 for (i = 0; i < n; i++)
Guido van Rossum79f25d91997-04-29 20:08:16 +000049 PyList_SetItem(v, i,
50 PyString_FromString(mlist[i].name));
51 if (PyErr_Occurred()) {
52 Py_DECREF(v);
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000053 v = NULL;
54 }
55 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +000056 PyList_Sort(v);
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000057 }
58 }
59 return v;
60}
61
Guido van Rossum79f25d91997-04-29 20:08:16 +000062PyObject *
63PyMember_Get(addr, mlist, name)
Guido van Rossum3f5da241990-12-20 15:06:42 +000064 char *addr;
65 struct memberlist *mlist;
66 char *name;
67{
68 struct memberlist *l;
69
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000070 if (strcmp(name, "__members__") == 0)
71 return listmembers(mlist);
Guido van Rossum3f5da241990-12-20 15:06:42 +000072 for (l = mlist; l->name != NULL; l++) {
73 if (strcmp(l->name, name) == 0) {
Guido van Rossum79f25d91997-04-29 20:08:16 +000074 PyObject *v;
Guido van Rossum3f5da241990-12-20 15:06:42 +000075 addr += l->offset;
76 switch (l->type) {
Guido van Rossumab2490a1992-06-03 17:07:23 +000077 case T_BYTE:
Guido van Rossum79f25d91997-04-29 20:08:16 +000078 v = PyInt_FromLong((long)
Guido van Rossumab2490a1992-06-03 17:07:23 +000079 (((*(char*)addr & 0xff)
80 ^ 0x80) - 0x80));
81 break;
82 case T_UBYTE:
Guido van Rossum79f25d91997-04-29 20:08:16 +000083 v = PyInt_FromLong((long) *(char*)addr & 0xff);
Guido van Rossumab2490a1992-06-03 17:07:23 +000084 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +000085 case T_SHORT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000086 v = PyInt_FromLong((long) *(short*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000087 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +000088 case T_USHORT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000089 v = PyInt_FromLong((long)
Guido van Rossumab2490a1992-06-03 17:07:23 +000090 *(unsigned short*)addr);
91 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +000092 case T_INT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000093 v = PyInt_FromLong((long) *(int*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000094 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +000095 case T_UINT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000096 v = PyInt_FromLong((long)
97 *(unsigned int*)addr);
Guido van Rossumab2490a1992-06-03 17:07:23 +000098 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +000099 case T_LONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000100 v = PyInt_FromLong(*(long*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000101 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000102 case T_ULONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000103 v = PyLong_FromDouble((double)
Guido van Rossumab2490a1992-06-03 17:07:23 +0000104 *(unsigned long*)addr);
105 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000106 case T_FLOAT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000107 v = PyFloat_FromDouble((double)*(float*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000108 break;
109 case T_DOUBLE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000110 v = PyFloat_FromDouble(*(double*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000111 break;
112 case T_STRING:
113 if (*(char**)addr == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000114 Py_INCREF(Py_None);
115 v = Py_None;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000116 }
117 else
Guido van Rossum79f25d91997-04-29 20:08:16 +0000118 v = PyString_FromString(*(char**)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000119 break;
Jack Jansen599f0d11994-12-14 13:04:05 +0000120 case T_STRING_INPLACE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000121 v = PyString_FromString((char*)addr);
Jack Jansen599f0d11994-12-14 13:04:05 +0000122 break;
123#ifdef macintosh
124 case T_PSTRING:
125 if (*(char**)addr == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000126 Py_INCREF(Py_None);
127 v = Py_None;
Jack Jansen599f0d11994-12-14 13:04:05 +0000128 }
129 else
Guido van Rossum79f25d91997-04-29 20:08:16 +0000130 v = PyString_FromStringAndSize(
131 (*(char**)addr)+1,
132 **(unsigned char**)addr);
Jack Jansen599f0d11994-12-14 13:04:05 +0000133 break;
134 case T_PSTRING_INPLACE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000135 v = PyString_FromStringAndSize(
136 ((char*)addr)+1,
137 *(unsigned char*)addr);
Jack Jansen599f0d11994-12-14 13:04:05 +0000138 break;
139#endif /* macintosh */
Guido van Rossumab2490a1992-06-03 17:07:23 +0000140 case T_CHAR:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000141 v = PyString_FromStringAndSize((char*)addr, 1);
Guido van Rossumab2490a1992-06-03 17:07:23 +0000142 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000143 case T_OBJECT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000144 v = *(PyObject **)addr;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000145 if (v == NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000146 v = Py_None;
147 Py_INCREF(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000148 break;
149 default:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000150 PyErr_SetString(PyExc_SystemError,
151 "bad memberlist type");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000152 v = NULL;
153 }
154 return v;
155 }
156 }
157
Guido van Rossum79f25d91997-04-29 20:08:16 +0000158 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000159 return NULL;
160}
161
162int
Guido van Rossum79f25d91997-04-29 20:08:16 +0000163PyMember_Set(addr, mlist, name, v)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000164 char *addr;
165 struct memberlist *mlist;
166 char *name;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000167 PyObject *v;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000168{
169 struct memberlist *l;
170
171 for (l = mlist; l->name != NULL; l++) {
172 if (strcmp(l->name, name) == 0) {
Jack Jansen599f0d11994-12-14 13:04:05 +0000173#ifdef macintosh
Guido van Rossum79f25d91997-04-29 20:08:16 +0000174 if (l->readonly || l->type == T_STRING ||
175 l->type == T_PSTRING)
176 {
Jack Jansen599f0d11994-12-14 13:04:05 +0000177#else
178 if (l->readonly || l->type == T_STRING ) {
179#endif /* macintosh */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000180 PyErr_SetString(PyExc_TypeError,
181 "readonly attribute");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000182 return -1;
183 }
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000184 if (v == NULL && l->type != T_OBJECT) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000185 PyErr_SetString(PyExc_TypeError,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000186 "can't delete numeric/char attribute");
187 return -1;
188 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000189 addr += l->offset;
190 switch (l->type) {
Guido van Rossumab2490a1992-06-03 17:07:23 +0000191 case T_BYTE:
192 case T_UBYTE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000193 if (!PyInt_Check(v)) {
194 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000195 return -1;
196 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000197 *(char*)addr = (char) PyInt_AsLong(v);
Guido van Rossumab2490a1992-06-03 17:07:23 +0000198 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000199 case T_SHORT:
Guido van Rossumab2490a1992-06-03 17:07:23 +0000200 case T_USHORT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000201 if (!PyInt_Check(v)) {
202 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000203 return -1;
204 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000205 *(short*)addr = (short) PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000206 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000207 case T_UINT:
Guido van Rossum3f5da241990-12-20 15:06:42 +0000208 case T_INT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000209 if (!PyInt_Check(v)) {
210 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000211 return -1;
212 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000213 *(int*)addr = (int) PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000214 break;
215 case T_LONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000216 if (!PyInt_Check(v)) {
217 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000218 return -1;
219 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000220 *(long*)addr = PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000221 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000222 case T_ULONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000223 if (PyInt_Check(v))
224 *(long*)addr = PyInt_AsLong(v);
225 else if (PyLong_Check(v))
226 *(long*)addr = PyLong_AsLong(v);
Guido van Rossumab2490a1992-06-03 17:07:23 +0000227 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000228 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000229 return -1;
230 }
231 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000232 case T_FLOAT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000233 if (PyInt_Check(v))
Guido van Rossum644a12b1997-04-09 19:24:53 +0000234 *(float*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000235 (float) PyInt_AsLong(v);
236 else if (PyFloat_Check(v))
237 *(float*)addr =
238 (float) PyFloat_AsDouble(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000239 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000240 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000241 return -1;
242 }
243 break;
244 case T_DOUBLE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000245 if (PyInt_Check(v))
Guido van Rossum644a12b1997-04-09 19:24:53 +0000246 *(double*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000247 (double) PyInt_AsLong(v);
248 else if (PyFloat_Check(v))
249 *(double*)addr = PyFloat_AsDouble(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000250 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000251 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000252 return -1;
253 }
254 break;
255 case T_OBJECT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000256 Py_XDECREF(*(PyObject **)addr);
257 Py_XINCREF(v);
258 *(PyObject **)addr = v;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000259 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000260 case T_CHAR:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000261 if (PyString_Check(v) &&
262 PyString_Size(v) == 1) {
Guido van Rossumab2490a1992-06-03 17:07:23 +0000263 *(char*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000264 PyString_AsString(v)[0];
Guido van Rossumab2490a1992-06-03 17:07:23 +0000265 }
266 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000267 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000268 return -1;
269 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000270 default:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000271 PyErr_SetString(PyExc_SystemError,
272 "bad memberlist type");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000273 return -1;
274 }
275 return 0;
276 }
277 }
278
Guido van Rossum79f25d91997-04-29 20:08:16 +0000279 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum73531a31990-12-20 23:12:40 +0000280 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000281}