blob: 891ffa0c6d887ec2f9e9d568b0b6d7da68556eb7 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009******************************************************************/
10
Guido van Rossum3f5da241990-12-20 15:06:42 +000011/* Map C struct members to Python object attributes */
12
Guido van Rossum79f25d91997-04-29 20:08:16 +000013#include "Python.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000014
15#include "structmember.h"
16
Guido van Rossum79f25d91997-04-29 20:08:16 +000017static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000018listmembers(struct memberlist *mlist)
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000019{
20 int i, n;
Guido van Rossum79f25d91997-04-29 20:08:16 +000021 PyObject *v;
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000022 for (n = 0; mlist[n].name != NULL; n++)
23 ;
Guido van Rossum79f25d91997-04-29 20:08:16 +000024 v = PyList_New(n);
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000025 if (v != NULL) {
26 for (i = 0; i < n; i++)
Guido van Rossum79f25d91997-04-29 20:08:16 +000027 PyList_SetItem(v, i,
28 PyString_FromString(mlist[i].name));
29 if (PyErr_Occurred()) {
30 Py_DECREF(v);
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000031 v = NULL;
32 }
33 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +000034 PyList_Sort(v);
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000035 }
36 }
37 return v;
38}
39
Guido van Rossum79f25d91997-04-29 20:08:16 +000040PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000041PyMember_Get(char *addr, struct memberlist *mlist, char *name)
Guido van Rossum3f5da241990-12-20 15:06:42 +000042{
43 struct memberlist *l;
44
Guido van Rossum2f1d87e1991-10-20 20:24:14 +000045 if (strcmp(name, "__members__") == 0)
46 return listmembers(mlist);
Guido van Rossum3f5da241990-12-20 15:06:42 +000047 for (l = mlist; l->name != NULL; l++) {
48 if (strcmp(l->name, name) == 0) {
Guido van Rossum79f25d91997-04-29 20:08:16 +000049 PyObject *v;
Guido van Rossum3f5da241990-12-20 15:06:42 +000050 addr += l->offset;
51 switch (l->type) {
Guido van Rossumab2490a1992-06-03 17:07:23 +000052 case T_BYTE:
Guido van Rossum79f25d91997-04-29 20:08:16 +000053 v = PyInt_FromLong((long)
Guido van Rossumab2490a1992-06-03 17:07:23 +000054 (((*(char*)addr & 0xff)
55 ^ 0x80) - 0x80));
56 break;
57 case T_UBYTE:
Guido van Rossum79f25d91997-04-29 20:08:16 +000058 v = PyInt_FromLong((long) *(char*)addr & 0xff);
Guido van Rossumab2490a1992-06-03 17:07:23 +000059 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +000060 case T_SHORT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000061 v = PyInt_FromLong((long) *(short*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000062 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +000063 case T_USHORT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000064 v = PyInt_FromLong((long)
Guido van Rossumab2490a1992-06-03 17:07:23 +000065 *(unsigned short*)addr);
66 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +000067 case T_INT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000068 v = PyInt_FromLong((long) *(int*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000069 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +000070 case T_UINT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000071 v = PyInt_FromLong((long)
72 *(unsigned int*)addr);
Guido van Rossumab2490a1992-06-03 17:07:23 +000073 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +000074 case T_LONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +000075 v = PyInt_FromLong(*(long*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000076 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +000077 case T_ULONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +000078 v = PyLong_FromDouble((double)
Guido van Rossumab2490a1992-06-03 17:07:23 +000079 *(unsigned long*)addr);
80 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +000081 case T_FLOAT:
Guido van Rossum79f25d91997-04-29 20:08:16 +000082 v = PyFloat_FromDouble((double)*(float*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000083 break;
84 case T_DOUBLE:
Guido van Rossum79f25d91997-04-29 20:08:16 +000085 v = PyFloat_FromDouble(*(double*)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000086 break;
87 case T_STRING:
88 if (*(char**)addr == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +000089 Py_INCREF(Py_None);
90 v = Py_None;
Guido van Rossum3f5da241990-12-20 15:06:42 +000091 }
92 else
Guido van Rossum79f25d91997-04-29 20:08:16 +000093 v = PyString_FromString(*(char**)addr);
Guido van Rossum3f5da241990-12-20 15:06:42 +000094 break;
Jack Jansen599f0d11994-12-14 13:04:05 +000095 case T_STRING_INPLACE:
Guido van Rossum79f25d91997-04-29 20:08:16 +000096 v = PyString_FromString((char*)addr);
Jack Jansen599f0d11994-12-14 13:04:05 +000097 break;
98#ifdef macintosh
99 case T_PSTRING:
100 if (*(char**)addr == NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000101 Py_INCREF(Py_None);
102 v = Py_None;
Jack Jansen599f0d11994-12-14 13:04:05 +0000103 }
104 else
Guido van Rossum79f25d91997-04-29 20:08:16 +0000105 v = PyString_FromStringAndSize(
106 (*(char**)addr)+1,
107 **(unsigned char**)addr);
Jack Jansen599f0d11994-12-14 13:04:05 +0000108 break;
109 case T_PSTRING_INPLACE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000110 v = PyString_FromStringAndSize(
111 ((char*)addr)+1,
112 *(unsigned char*)addr);
Jack Jansen599f0d11994-12-14 13:04:05 +0000113 break;
114#endif /* macintosh */
Guido van Rossumab2490a1992-06-03 17:07:23 +0000115 case T_CHAR:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000116 v = PyString_FromStringAndSize((char*)addr, 1);
Guido van Rossumab2490a1992-06-03 17:07:23 +0000117 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000118 case T_OBJECT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000119 v = *(PyObject **)addr;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000120 if (v == NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000121 v = Py_None;
122 Py_INCREF(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000123 break;
124 default:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000125 PyErr_SetString(PyExc_SystemError,
126 "bad memberlist type");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000127 v = NULL;
128 }
129 return v;
130 }
131 }
132
Guido van Rossum79f25d91997-04-29 20:08:16 +0000133 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000134 return NULL;
135}
136
137int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000138PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000139{
140 struct memberlist *l;
Guido van Rossumadf0e431998-05-20 22:25:32 +0000141 PyObject *oldv;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000142
143 for (l = mlist; l->name != NULL; l++) {
144 if (strcmp(l->name, name) == 0) {
Jack Jansen599f0d11994-12-14 13:04:05 +0000145#ifdef macintosh
Guido van Rossum79f25d91997-04-29 20:08:16 +0000146 if (l->readonly || l->type == T_STRING ||
147 l->type == T_PSTRING)
148 {
Jack Jansen599f0d11994-12-14 13:04:05 +0000149#else
150 if (l->readonly || l->type == T_STRING ) {
151#endif /* macintosh */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000152 PyErr_SetString(PyExc_TypeError,
153 "readonly attribute");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000154 return -1;
155 }
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000156 if (v == NULL && l->type != T_OBJECT) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000157 PyErr_SetString(PyExc_TypeError,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000158 "can't delete numeric/char attribute");
159 return -1;
160 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000161 addr += l->offset;
162 switch (l->type) {
Guido van Rossumab2490a1992-06-03 17:07:23 +0000163 case T_BYTE:
164 case T_UBYTE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000165 if (!PyInt_Check(v)) {
166 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000167 return -1;
168 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000169 *(char*)addr = (char) PyInt_AsLong(v);
Guido van Rossumab2490a1992-06-03 17:07:23 +0000170 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000171 case T_SHORT:
Guido van Rossumab2490a1992-06-03 17:07:23 +0000172 case T_USHORT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000173 if (!PyInt_Check(v)) {
174 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000175 return -1;
176 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000177 *(short*)addr = (short) PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000178 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000179 case T_UINT:
Guido van Rossum3f5da241990-12-20 15:06:42 +0000180 case T_INT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000181 if (!PyInt_Check(v)) {
182 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000183 return -1;
184 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000185 *(int*)addr = (int) PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000186 break;
187 case T_LONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000188 if (!PyInt_Check(v)) {
189 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000190 return -1;
191 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000192 *(long*)addr = PyInt_AsLong(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000193 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000194 case T_ULONG:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000195 if (PyInt_Check(v))
196 *(long*)addr = PyInt_AsLong(v);
197 else if (PyLong_Check(v))
198 *(long*)addr = PyLong_AsLong(v);
Guido van Rossumab2490a1992-06-03 17:07:23 +0000199 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000200 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000201 return -1;
202 }
203 break;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000204 case T_FLOAT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000205 if (PyInt_Check(v))
Guido van Rossum644a12b1997-04-09 19:24:53 +0000206 *(float*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000207 (float) PyInt_AsLong(v);
208 else if (PyFloat_Check(v))
209 *(float*)addr =
210 (float) PyFloat_AsDouble(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000211 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000212 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000213 return -1;
214 }
215 break;
216 case T_DOUBLE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000217 if (PyInt_Check(v))
Guido van Rossum644a12b1997-04-09 19:24:53 +0000218 *(double*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000219 (double) PyInt_AsLong(v);
220 else if (PyFloat_Check(v))
221 *(double*)addr = PyFloat_AsDouble(v);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000222 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000223 PyErr_BadArgument();
Guido van Rossum3f5da241990-12-20 15:06:42 +0000224 return -1;
225 }
226 break;
227 case T_OBJECT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000228 Py_XINCREF(v);
Guido van Rossumadf0e431998-05-20 22:25:32 +0000229 oldv = *(PyObject **)addr;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000230 *(PyObject **)addr = v;
Guido van Rossumadf0e431998-05-20 22:25:32 +0000231 Py_XDECREF(oldv);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000232 break;
Guido van Rossumab2490a1992-06-03 17:07:23 +0000233 case T_CHAR:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000234 if (PyString_Check(v) &&
235 PyString_Size(v) == 1) {
Guido van Rossumab2490a1992-06-03 17:07:23 +0000236 *(char*)addr =
Guido van Rossum79f25d91997-04-29 20:08:16 +0000237 PyString_AsString(v)[0];
Guido van Rossumab2490a1992-06-03 17:07:23 +0000238 }
239 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000240 PyErr_BadArgument();
Guido van Rossumab2490a1992-06-03 17:07:23 +0000241 return -1;
242 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000243 default:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000244 PyErr_SetString(PyExc_SystemError,
245 "bad memberlist type");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000246 return -1;
247 }
248 return 0;
249 }
250 }
251
Guido van Rossum79f25d91997-04-29 20:08:16 +0000252 PyErr_SetString(PyExc_AttributeError, name);
Guido van Rossum73531a31990-12-20 23:12:40 +0000253 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000254}