blob: ba0772008ab37e97c09a487ee7ab09078d236686 [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;
Guido van Rossumadf0e431998-05-20 22:25:32 +0000170 PyObject *oldv;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000171
172 for (l = mlist; l->name != NULL; l++) {
173 if (strcmp(l->name, name) == 0) {
Jack Jansen599f0d11994-12-14 13:04:05 +0000174#ifdef macintosh
Guido van Rossum79f25d91997-04-29 20:08:16 +0000175 if (l->readonly || l->type == T_STRING ||
176 l->type == T_PSTRING)
177 {
Jack Jansen599f0d11994-12-14 13:04:05 +0000178#else
179 if (l->readonly || l->type == T_STRING ) {
180#endif /* macintosh */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000181 PyErr_SetString(PyExc_TypeError,
182 "readonly attribute");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000183 return -1;
184 }
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000185 if (v == NULL && l->type != T_OBJECT) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000186 PyErr_SetString(PyExc_TypeError,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000187 "can't delete numeric/char attribute");
188 return -1;
189 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000190 addr += l->offset;
191 switch (l->type) {
Guido van Rossumab2490a1992-06-03 17:07:23 +0000192 case T_BYTE:
193 case T_UBYTE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000194 if (!PyInt_Check(v)) {
195 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000196 return -1;
197 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000198 *(char*)addr = (char) PyInt_AsLong(v);
Guido van Rossumab2490a1992-06-03 17:07:23 +0000199 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000200 case T_SHORT:
Guido van Rossumab2490a1992-06-03 17:07:23 +0000201 case T_USHORT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000202 if (!PyInt_Check(v)) {
203 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000204 return -1;
205 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000206 *(short*)addr = (short) PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000207 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000208 case T_UINT:
Guido van Rossum3f5da241990-12-20 15:06:42 +0000209 case T_INT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000210 if (!PyInt_Check(v)) {
211 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000212 return -1;
213 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000214 *(int*)addr = (int) PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000215 break;
216 case T_LONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000217 if (!PyInt_Check(v)) {
218 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000219 return -1;
220 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000221 *(long*)addr = PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000222 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000223 case T_ULONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000224 if (PyInt_Check(v))
225 *(long*)addr = PyInt_AsLong(v);
226 else if (PyLong_Check(v))
227 *(long*)addr = PyLong_AsLong(v);
Guido van Rossumab2490a1992-06-03 17:07:23 +0000228 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000229 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000230 return -1;
231 }
232 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000233 case T_FLOAT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000234 if (PyInt_Check(v))
Guido van Rossum644a12b1997-04-09 19:24:53 +0000235 *(float*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000236 (float) PyInt_AsLong(v);
237 else if (PyFloat_Check(v))
238 *(float*)addr =
239 (float) PyFloat_AsDouble(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000240 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000241 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000242 return -1;
243 }
244 break;
245 case T_DOUBLE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000246 if (PyInt_Check(v))
Guido van Rossum644a12b1997-04-09 19:24:53 +0000247 *(double*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000248 (double) PyInt_AsLong(v);
249 else if (PyFloat_Check(v))
250 *(double*)addr = PyFloat_AsDouble(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000251 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000252 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000253 return -1;
254 }
255 break;
256 case T_OBJECT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000257 Py_XINCREF(v);
Guido van Rossumadf0e431998-05-20 22:25:32 +0000258 oldv = *(PyObject **)addr;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000259 *(PyObject **)addr = v;
Guido van Rossumadf0e431998-05-20 22:25:32 +0000260 Py_XDECREF(oldv);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000261 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000262 case T_CHAR:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000263 if (PyString_Check(v) &&
264 PyString_Size(v) == 1) {
Guido van Rossumab2490a1992-06-03 17:07:23 +0000265 *(char*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000266 PyString_AsString(v)[0];
Guido van Rossumab2490a1992-06-03 17:07:23 +0000267 }
268 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000269 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000270 return -1;
271 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000272 default:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000273 PyErr_SetString(PyExc_SystemError,
274 "bad memberlist type");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000275 return -1;
276 }
277 return 0;
278 }
279 }
280
Guido van Rossum79f25d91997-04-29 20:08:16 +0000281 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum73531a31990-12-20 23:12:40 +0000282 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000283}