Added 'list_only' option (and modified 'run()' to respect it).
[python/dscho.git] / Python / structmember.c
blobba0772008ab37e97c09a487ee7ab09078d236686
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Map C struct members to Python object attributes */
34 #include "Python.h"
36 #include "structmember.h"
38 static PyObject *
39 listmembers(mlist)
40 struct memberlist *mlist;
42 int i, n;
43 PyObject *v;
44 for (n = 0; mlist[n].name != NULL; n++)
46 v = PyList_New(n);
47 if (v != NULL) {
48 for (i = 0; i < n; i++)
49 PyList_SetItem(v, i,
50 PyString_FromString(mlist[i].name));
51 if (PyErr_Occurred()) {
52 Py_DECREF(v);
53 v = NULL;
55 else {
56 PyList_Sort(v);
59 return v;
62 PyObject *
63 PyMember_Get(addr, mlist, name)
64 char *addr;
65 struct memberlist *mlist;
66 char *name;
68 struct memberlist *l;
70 if (strcmp(name, "__members__") == 0)
71 return listmembers(mlist);
72 for (l = mlist; l->name != NULL; l++) {
73 if (strcmp(l->name, name) == 0) {
74 PyObject *v;
75 addr += l->offset;
76 switch (l->type) {
77 case T_BYTE:
78 v = PyInt_FromLong((long)
79 (((*(char*)addr & 0xff)
80 ^ 0x80) - 0x80));
81 break;
82 case T_UBYTE:
83 v = PyInt_FromLong((long) *(char*)addr & 0xff);
84 break;
85 case T_SHORT:
86 v = PyInt_FromLong((long) *(short*)addr);
87 break;
88 case T_USHORT:
89 v = PyInt_FromLong((long)
90 *(unsigned short*)addr);
91 break;
92 case T_INT:
93 v = PyInt_FromLong((long) *(int*)addr);
94 break;
95 case T_UINT:
96 v = PyInt_FromLong((long)
97 *(unsigned int*)addr);
98 break;
99 case T_LONG:
100 v = PyInt_FromLong(*(long*)addr);
101 break;
102 case T_ULONG:
103 v = PyLong_FromDouble((double)
104 *(unsigned long*)addr);
105 break;
106 case T_FLOAT:
107 v = PyFloat_FromDouble((double)*(float*)addr);
108 break;
109 case T_DOUBLE:
110 v = PyFloat_FromDouble(*(double*)addr);
111 break;
112 case T_STRING:
113 if (*(char**)addr == NULL) {
114 Py_INCREF(Py_None);
115 v = Py_None;
117 else
118 v = PyString_FromString(*(char**)addr);
119 break;
120 case T_STRING_INPLACE:
121 v = PyString_FromString((char*)addr);
122 break;
123 #ifdef macintosh
124 case T_PSTRING:
125 if (*(char**)addr == NULL) {
126 Py_INCREF(Py_None);
127 v = Py_None;
129 else
130 v = PyString_FromStringAndSize(
131 (*(char**)addr)+1,
132 **(unsigned char**)addr);
133 break;
134 case T_PSTRING_INPLACE:
135 v = PyString_FromStringAndSize(
136 ((char*)addr)+1,
137 *(unsigned char*)addr);
138 break;
139 #endif /* macintosh */
140 case T_CHAR:
141 v = PyString_FromStringAndSize((char*)addr, 1);
142 break;
143 case T_OBJECT:
144 v = *(PyObject **)addr;
145 if (v == NULL)
146 v = Py_None;
147 Py_INCREF(v);
148 break;
149 default:
150 PyErr_SetString(PyExc_SystemError,
151 "bad memberlist type");
152 v = NULL;
154 return v;
158 PyErr_SetString(PyExc_AttributeError, name);
159 return NULL;
163 PyMember_Set(addr, mlist, name, v)
164 char *addr;
165 struct memberlist *mlist;
166 char *name;
167 PyObject *v;
169 struct memberlist *l;
170 PyObject *oldv;
172 for (l = mlist; l->name != NULL; l++) {
173 if (strcmp(l->name, name) == 0) {
174 #ifdef macintosh
175 if (l->readonly || l->type == T_STRING ||
176 l->type == T_PSTRING)
178 #else
179 if (l->readonly || l->type == T_STRING ) {
180 #endif /* macintosh */
181 PyErr_SetString(PyExc_TypeError,
182 "readonly attribute");
183 return -1;
185 if (v == NULL && l->type != T_OBJECT) {
186 PyErr_SetString(PyExc_TypeError,
187 "can't delete numeric/char attribute");
188 return -1;
190 addr += l->offset;
191 switch (l->type) {
192 case T_BYTE:
193 case T_UBYTE:
194 if (!PyInt_Check(v)) {
195 PyErr_BadArgument();
196 return -1;
198 *(char*)addr = (char) PyInt_AsLong(v);
199 break;
200 case T_SHORT:
201 case T_USHORT:
202 if (!PyInt_Check(v)) {
203 PyErr_BadArgument();
204 return -1;
206 *(short*)addr = (short) PyInt_AsLong(v);
207 break;
208 case T_UINT:
209 case T_INT:
210 if (!PyInt_Check(v)) {
211 PyErr_BadArgument();
212 return -1;
214 *(int*)addr = (int) PyInt_AsLong(v);
215 break;
216 case T_LONG:
217 if (!PyInt_Check(v)) {
218 PyErr_BadArgument();
219 return -1;
221 *(long*)addr = PyInt_AsLong(v);
222 break;
223 case T_ULONG:
224 if (PyInt_Check(v))
225 *(long*)addr = PyInt_AsLong(v);
226 else if (PyLong_Check(v))
227 *(long*)addr = PyLong_AsLong(v);
228 else {
229 PyErr_BadArgument();
230 return -1;
232 break;
233 case T_FLOAT:
234 if (PyInt_Check(v))
235 *(float*)addr =
236 (float) PyInt_AsLong(v);
237 else if (PyFloat_Check(v))
238 *(float*)addr =
239 (float) PyFloat_AsDouble(v);
240 else {
241 PyErr_BadArgument();
242 return -1;
244 break;
245 case T_DOUBLE:
246 if (PyInt_Check(v))
247 *(double*)addr =
248 (double) PyInt_AsLong(v);
249 else if (PyFloat_Check(v))
250 *(double*)addr = PyFloat_AsDouble(v);
251 else {
252 PyErr_BadArgument();
253 return -1;
255 break;
256 case T_OBJECT:
257 Py_XINCREF(v);
258 oldv = *(PyObject **)addr;
259 *(PyObject **)addr = v;
260 Py_XDECREF(oldv);
261 break;
262 case T_CHAR:
263 if (PyString_Check(v) &&
264 PyString_Size(v) == 1) {
265 *(char*)addr =
266 PyString_AsString(v)[0];
268 else {
269 PyErr_BadArgument();
270 return -1;
272 default:
273 PyErr_SetString(PyExc_SystemError,
274 "bad memberlist type");
275 return -1;
277 return 0;
281 PyErr_SetString(PyExc_AttributeError, name);
282 return -1;