History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Python/structmember.c (1 of 3706 files). Show all

Unified · Split

sys/src/cmd/python/Python/structmember.c+312−0
@@ -0,0 +1,312 @@
1+
2+/* Map C struct members to Python object attributes */
3+
4+#include "Python.h"
5+
6+#include "structmember.h"
7+
8+static PyObject *
9+listmembers(struct memberlist *mlist)
10+{
11+ int i, n;
12+ PyObject *v;
13+ for (n = 0; mlist[n].name != NULL; n++)
14+ ;
15+ v = PyList_New(n);
16+ if (v != NULL) {
17+ for (i = 0; i < n; i++)
18+ PyList_SetItem(v, i,
19+ PyString_FromString(mlist[i].name));
20+ if (PyErr_Occurred()) {
21+ Py_DECREF(v);
22+ v = NULL;
23+ }
24+ else {
25+ PyList_Sort(v);
26+ }
27+ }
28+ return v;
29+}
30+
31+PyObject *
32+PyMember_Get(const char *addr, struct memberlist *mlist, const char *name)
33+{
34+ struct memberlist *l;
35+
36+ if (strcmp(name, "__members__") == 0)
37+ return listmembers(mlist);
38+ for (l = mlist; l->name != NULL; l++) {
39+ if (strcmp(l->name, name) == 0) {
40+ PyMemberDef copy;
41+ copy.name = l->name;
42+ copy.type = l->type;
43+ copy.offset = l->offset;
44+ copy.flags = l->flags;
45+ copy.doc = NULL;
46+ return PyMember_GetOne(addr, &copy);
47+ }
48+ }
49+ PyErr_SetString(PyExc_AttributeError, name);
50+ return NULL;
51+}
52+
53+PyObject *
54+PyMember_GetOne(const char *addr, PyMemberDef *l)
55+{
56+ PyObject *v;
57+ if ((l->flags & READ_RESTRICTED) &&
58+ PyEval_GetRestricted()) {
59+ PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
60+ return NULL;
61+ }
62+ addr += l->offset;
63+ switch (l->type) {
64+ case T_BYTE:
65+ v = PyInt_FromLong(*(char*)addr);
66+ break;
67+ case T_UBYTE:
68+ v = PyLong_FromUnsignedLong(*(unsigned char*)addr);
69+ break;
70+ case T_SHORT:
71+ v = PyInt_FromLong(*(short*)addr);
72+ break;
73+ case T_USHORT:
74+ v = PyLong_FromUnsignedLong(*(unsigned short*)addr);
75+ break;
76+ case T_INT:
77+ v = PyInt_FromLong(*(int*)addr);
78+ break;
79+ case T_UINT:
80+ v = PyLong_FromUnsignedLong(*(unsigned int*)addr);
81+ break;
82+ case T_LONG:
83+ v = PyInt_FromLong(*(long*)addr);
84+ break;
85+ case T_ULONG:
86+ v = PyLong_FromUnsignedLong(*(unsigned long*)addr);
87+ break;
88+ case T_FLOAT:
89+ v = PyFloat_FromDouble((double)*(float*)addr);
90+ break;
91+ case T_DOUBLE:
92+ v = PyFloat_FromDouble(*(double*)addr);
93+ break;
94+ case T_STRING:
95+ if (*(char**)addr == NULL) {
96+ Py_INCREF(Py_None);
97+ v = Py_None;
98+ }
99+ else
100+ v = PyString_FromString(*(char**)addr);
101+ break;
102+ case T_STRING_INPLACE:
103+ v = PyString_FromString((char*)addr);
104+ break;
105+ case T_CHAR:
106+ v = PyString_FromStringAndSize((char*)addr, 1);
107+ break;
108+ case T_OBJECT:
109+ v = *(PyObject **)addr;
110+ if (v == NULL)
111+ v = Py_None;
112+ Py_INCREF(v);
113+ break;
114+ case T_OBJECT_EX:
115+ v = *(PyObject **)addr;
116+ if (v == NULL)
117+ PyErr_SetString(PyExc_AttributeError, l->name);
118+ Py_XINCREF(v);
119+ break;
120+#ifdef HAVE_LONG_LONG
121+ case T_LONGLONG:
122+ v = PyLong_FromLongLong(*(PY_LONG_LONG *)addr);
123+ break;
124+ case T_ULONGLONG:
125+ v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr);
126+ break;
127+#endif /* HAVE_LONG_LONG */
128+ default:
129+ PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
130+ v = NULL;
131+ }
132+ return v;
133+}
134+
135+int
136+PyMember_Set(char *addr, struct memberlist *mlist, const char *name, PyObject *v)
137+{
138+ struct memberlist *l;
139+
140+ for (l = mlist; l->name != NULL; l++) {
141+ if (strcmp(l->name, name) == 0) {
142+ PyMemberDef copy;
143+ copy.name = l->name;
144+ copy.type = l->type;
145+ copy.offset = l->offset;
146+ copy.flags = l->flags;
147+ copy.doc = NULL;
148+ return PyMember_SetOne(addr, &copy, v);
149+ }
150+ }
151+
152+ PyErr_SetString(PyExc_AttributeError, name);
153+ return -1;
154+}
155+
156+int
157+PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
158+{
159+ PyObject *oldv;
160+
161+ if ((l->flags & READONLY) || l->type == T_STRING)
162+ {
163+ PyErr_SetString(PyExc_TypeError, "readonly attribute");
164+ return -1;
165+ }
166+ if ((l->flags & WRITE_RESTRICTED) && PyEval_GetRestricted()) {
167+ PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
168+ return -1;
169+ }
170+ if (v == NULL && l->type != T_OBJECT_EX && l->type != T_OBJECT) {
171+ PyErr_SetString(PyExc_TypeError,
172+ "can't delete numeric/char attribute");
173+ return -1;
174+ }
175+ addr += l->offset;
176+ switch (l->type) {
177+ case T_BYTE:{
178+ long long_val;
179+ long_val = PyInt_AsLong(v);
180+ if ((long_val == -1) && PyErr_Occurred())
181+ return -1;
182+ *(char*)addr = (char)long_val;
183+ break;
184+ }
185+ case T_UBYTE:{
186+ long long_val;
187+ long_val = PyInt_AsLong(v);
188+ if ((long_val == -1) && PyErr_Occurred())
189+ return -1;
190+ *(unsigned char*)addr = (unsigned char)long_val;
191+ break;
192+ }
193+ case T_SHORT:{
194+ long long_val;
195+ long_val = PyInt_AsLong(v);
196+ if ((long_val == -1) && PyErr_Occurred())
197+ return -1;
198+ *(short*)addr = (short)long_val;
199+ break;
200+ }
201+ case T_USHORT:{
202+ long long_val;
203+ long_val = PyInt_AsLong(v);
204+ if ((long_val == -1) && PyErr_Occurred())
205+ return -1;
206+ *(unsigned short*)addr = (unsigned short)long_val;
207+ break;
208+ }
209+ case T_INT:{
210+ long long_val;
211+ long_val = PyInt_AsLong(v);
212+ if ((long_val == -1) && PyErr_Occurred())
213+ return -1;
214+ *(int *)addr = (int)long_val;
215+ break;
216+ }
217+ case T_UINT:{
218+ unsigned long ulong_val;
219+ ulong_val = PyLong_AsUnsignedLong(v);
220+ if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
221+ /* XXX: For compatibility, accept negative int values
222+ as well. */
223+ PyErr_Clear();
224+ ulong_val = PyLong_AsLong(v);
225+ if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
226+ return -1;
227+ }
228+ *(unsigned int *)addr = (unsigned int)ulong_val;
229+ break;
230+ }
231+ case T_LONG:{
232+ *(long*)addr = PyLong_AsLong(v);
233+ if ((*(long*)addr == -1) && PyErr_Occurred())
234+ return -1;
235+ break;
236+ }
237+ case T_ULONG:{
238+ *(unsigned long*)addr = PyLong_AsUnsignedLong(v);
239+ if ((*(unsigned long*)addr == (unsigned long)-1)
240+ && PyErr_Occurred()) {
241+ /* XXX: For compatibility, accept negative int values
242+ as well. */
243+ PyErr_Clear();
244+ *(unsigned long*)addr = PyLong_AsLong(v);
245+ if ((*(unsigned long*)addr == (unsigned int)-1) && PyErr_Occurred())
246+ return -1;
247+ }
248+ break;
249+ }
250+ case T_FLOAT:{
251+ double double_val;
252+ double_val = PyFloat_AsDouble(v);
253+ if ((double_val == -1) && PyErr_Occurred())
254+ return -1;
255+ *(float*)addr = (float)double_val;
256+ break;
257+ }
258+ case T_DOUBLE:
259+ *(double*)addr = PyFloat_AsDouble(v);
260+ if ((*(double*)addr == -1) && PyErr_Occurred())
261+ return -1;
262+ break;
263+ case T_OBJECT:
264+ case T_OBJECT_EX:
265+ Py_XINCREF(v);
266+ oldv = *(PyObject **)addr;
267+ *(PyObject **)addr = v;
268+ Py_XDECREF(oldv);
269+ break;
270+ case T_CHAR:
271+ if (PyString_Check(v) && PyString_Size(v) == 1) {
272+ *(char*)addr = PyString_AsString(v)[0];
273+ }
274+ else {
275+ PyErr_BadArgument();
276+ return -1;
277+ }
278+ break;
279+#ifdef HAVE_LONG_LONG
280+ case T_LONGLONG:
281+ if (!PyLong_Check(v)) {
282+ PyErr_BadArgument();
283+ return -1;
284+ } else {
285+ PY_LONG_LONG value;
286+ *(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v);
287+ if ((value == -1) && PyErr_Occurred()) {
288+ return -1;
289+ }
290+ }
291+ break;
292+ case T_ULONGLONG:
293+ if (!PyLong_Check(v)) {
294+ PyErr_BadArgument();
295+ return -1;
296+ } else {
297+ unsigned PY_LONG_LONG value;
298+ *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v);
299+ if ((value == (unsigned PY_LONG_LONG)-1) &&
300+ PyErr_Occurred()) {
301+ return -1;
302+ }
303+ }
304+ break;
305+#endif /* HAVE_LONG_LONG */
306+ default:
307+ PyErr_Format(PyExc_SystemError,
308+ "bad memberdescr type for %s", l->name);
309+ return -1;
310+ }
311+ return 0;
312+}