File: | Modules/_ctypes/callproc.c |
Location: | line 824, column 20 |
Description: | Dereference of undefined pointer value |
1 | /* | ||
2 | * History: First version dated from 3/97, derived from my SCMLIB version | ||
3 | * for win16. | ||
4 | */ | ||
5 | /* | ||
6 | * Related Work: | ||
7 | * - calldll http://www.nightmare.com/software.html | ||
8 | * - libffi http://sourceware.cygnus.com/libffi/ | ||
9 | * - ffcall http://clisp.cons.org/~haible/packages-ffcall.html | ||
10 | * and, of course, Don Beaudry's MESS package, but this is more ctypes | ||
11 | * related. | ||
12 | */ | ||
13 | |||
14 | |||
15 | /* | ||
16 | How are functions called, and how are parameters converted to C ? | ||
17 | |||
18 | 1. _ctypes.c::PyCFuncPtr_call receives an argument tuple 'inargs' and a | ||
19 | keyword dictionary 'kwds'. | ||
20 | |||
21 | 2. After several checks, _build_callargs() is called which returns another | ||
22 | tuple 'callargs'. This may be the same tuple as 'inargs', a slice of | ||
23 | 'inargs', or a completely fresh tuple, depending on several things (is is a | ||
24 | COM method, are 'paramflags' available). | ||
25 | |||
26 | 3. _build_callargs also calculates bitarrays containing indexes into | ||
27 | the callargs tuple, specifying how to build the return value(s) of | ||
28 | the function. | ||
29 | |||
30 | 4. _ctypes_callproc is then called with the 'callargs' tuple. _ctypes_callproc first | ||
31 | allocates two arrays. The first is an array of 'struct argument' items, the | ||
32 | second array has 'void *' entried. | ||
33 | |||
34 | 5. If 'converters' are present (converters is a sequence of argtypes' | ||
35 | from_param methods), for each item in 'callargs' converter is called and the | ||
36 | result passed to ConvParam. If 'converters' are not present, each argument | ||
37 | is directly passed to ConvParm. | ||
38 | |||
39 | 6. For each arg, ConvParam stores the contained C data (or a pointer to it, | ||
40 | for structures) into the 'struct argument' array. | ||
41 | |||
42 | 7. Finally, a loop fills the 'void *' array so that each item points to the | ||
43 | data contained in or pointed to by the 'struct argument' array. | ||
44 | |||
45 | 8. The 'void *' argument array is what _call_function_pointer | ||
46 | expects. _call_function_pointer then has very little to do - only some | ||
47 | libffi specific stuff, then it calls ffi_call. | ||
48 | |||
49 | So, there are 4 data structures holding processed arguments: | ||
50 | - the inargs tuple (in PyCFuncPtr_call) | ||
51 | - the callargs tuple (in PyCFuncPtr_call) | ||
52 | - the 'struct argguments' array | ||
53 | - the 'void *' array | ||
54 | |||
55 | */ | ||
56 | |||
57 | #include "Python.h" | ||
58 | #include "structmember.h" | ||
59 | |||
60 | #ifdef MS_WIN32 | ||
61 | #include <windows.h> | ||
62 | #include <tchar.h> | ||
63 | #else | ||
64 | #include "ctypes_dlfcn.h" | ||
65 | #endif | ||
66 | |||
67 | #ifdef MS_WIN32 | ||
68 | #include <malloc.h> | ||
69 | #endif | ||
70 | |||
71 | #include <ffi.h> | ||
72 | #include "ctypes.h" | ||
73 | |||
74 | #if defined(_DEBUG) || defined(__MINGW32__) | ||
75 | /* Don't use structured exception handling on Windows if this is defined. | ||
76 | MingW, AFAIK, doesn't support it. | ||
77 | */ | ||
78 | #define DONT_USE_SEH | ||
79 | #endif | ||
80 | |||
81 | #define CTYPES_CAPSULE_NAME_PYMEM"_ctypes pymem" "_ctypes pymem" | ||
82 | |||
83 | static void pymem_destructor(PyObject *ptr) | ||
84 | { | ||
85 | void *p = PyCapsule_GetPointer(ptr, CTYPES_CAPSULE_NAME_PYMEM"_ctypes pymem"); | ||
86 | if (p) { | ||
87 | PyMem_Free(p); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | ctypes maintains thread-local storage that has space for two error numbers: | ||
93 | private copies of the system 'errno' value and, on Windows, the system error code | ||
94 | accessed by the GetLastError() and SetLastError() api functions. | ||
95 | |||
96 | Foreign functions created with CDLL(..., use_errno=True), when called, swap | ||
97 | the system 'errno' value with the private copy just before the actual | ||
98 | function call, and swapped again immediately afterwards. The 'use_errno' | ||
99 | parameter defaults to False, in this case 'ctypes_errno' is not touched. | ||
100 | |||
101 | On Windows, foreign functions created with CDLL(..., use_last_error=True) or | ||
102 | WinDLL(..., use_last_error=True) swap the system LastError value with the | ||
103 | ctypes private copy. | ||
104 | |||
105 | The values are also swapped immeditately before and after ctypes callback | ||
106 | functions are called, if the callbacks are constructed using the new | ||
107 | optional use_errno parameter set to True: CFUNCTYPE(..., use_errno=TRUE) or | ||
108 | WINFUNCTYPE(..., use_errno=True). | ||
109 | |||
110 | New ctypes functions are provided to access the ctypes private copies from | ||
111 | Python: | ||
112 | |||
113 | - ctypes.set_errno(value) and ctypes.set_last_error(value) store 'value' in | ||
114 | the private copy and returns the previous value. | ||
115 | |||
116 | - ctypes.get_errno() and ctypes.get_last_error() returns the current ctypes | ||
117 | private copies value. | ||
118 | */ | ||
119 | |||
120 | /* | ||
121 | This function creates and returns a thread-local Python object that has | ||
122 | space to store two integer error numbers; once created the Python object is | ||
123 | kept alive in the thread state dictionary as long as the thread itself. | ||
124 | */ | ||
125 | PyObject * | ||
126 | _ctypes_get_errobj(int **pspace) | ||
127 | { | ||
128 | PyObject *dict = PyThreadState_GetDict(); | ||
129 | PyObject *errobj; | ||
130 | static PyObject *error_object_name; | ||
131 | if (dict == 0) { | ||
132 | PyErr_SetString(PyExc_RuntimeError, | ||
133 | "cannot get thread state"); | ||
134 | return NULL((void*)0); | ||
135 | } | ||
136 | if (error_object_name == NULL((void*)0)) { | ||
137 | error_object_name = PyUnicode_InternFromString("ctypes.error_object"); | ||
138 | if (error_object_name == NULL((void*)0)) | ||
139 | return NULL((void*)0); | ||
140 | } | ||
141 | errobj = PyDict_GetItem(dict, error_object_name); | ||
142 | if (errobj) { | ||
143 | if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM"_ctypes pymem")) { | ||
144 | PyErr_SetString(PyExc_RuntimeError, | ||
145 | "ctypes.error_object is an invalid capsule"); | ||
146 | return NULL((void*)0); | ||
147 | } | ||
148 | Py_INCREF(errobj)( _Py_RefTotal++ , ((PyObject*)(errobj))->ob_refcnt++); | ||
149 | } | ||
150 | else { | ||
151 | void *space = PyMem_Malloc(sizeof(int) * 2); | ||
152 | if (space == NULL((void*)0)) | ||
153 | return NULL((void*)0); | ||
154 | memset(space, 0, sizeof(int) * 2)((__builtin_object_size (space, 0) != (size_t) -1) ? __builtin___memset_chk (space, 0, sizeof(int) * 2, __builtin_object_size (space, 0) ) : __inline_memset_chk (space, 0, sizeof(int) * 2)); | ||
155 | errobj = PyCapsule_New(space, CTYPES_CAPSULE_NAME_PYMEM"_ctypes pymem", pymem_destructor); | ||
156 | if (errobj == NULL((void*)0)) | ||
157 | return NULL((void*)0); | ||
158 | if (-1 == PyDict_SetItem(dict, error_object_name, | ||
159 | errobj)) { | ||
160 | Py_DECREF(errobj)do { if (_Py_RefTotal-- , --((PyObject*)(errobj))->ob_refcnt != 0) { if (((PyObject*)errobj)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 160, (PyObject *)(errobj)); } else _Py_Dealloc((PyObject *) (errobj)); } while (0); | ||
161 | return NULL((void*)0); | ||
162 | } | ||
163 | } | ||
164 | *pspace = (int *)PyCapsule_GetPointer(errobj, CTYPES_CAPSULE_NAME_PYMEM"_ctypes pymem"); | ||
165 | return errobj; | ||
166 | } | ||
167 | |||
168 | static PyObject * | ||
169 | get_error_internal(PyObject *self, PyObject *args, int index) | ||
170 | { | ||
171 | int *space; | ||
172 | PyObject *errobj = _ctypes_get_errobj(&space); | ||
173 | PyObject *result; | ||
174 | |||
175 | if (errobj == NULL((void*)0)) | ||
176 | return NULL((void*)0); | ||
177 | result = PyLong_FromLong(space[index]); | ||
178 | Py_DECREF(errobj)do { if (_Py_RefTotal-- , --((PyObject*)(errobj))->ob_refcnt != 0) { if (((PyObject*)errobj)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 178, (PyObject *)(errobj)); } else _Py_Dealloc((PyObject *) (errobj)); } while (0); | ||
179 | return result; | ||
180 | } | ||
181 | |||
182 | static PyObject * | ||
183 | set_error_internal(PyObject *self, PyObject *args, int index) | ||
184 | { | ||
185 | int new_errno, old_errno; | ||
186 | PyObject *errobj; | ||
187 | int *space; | ||
188 | |||
189 | if (!PyArg_ParseTuple(args, "i", &new_errno)) | ||
190 | return NULL((void*)0); | ||
191 | errobj = _ctypes_get_errobj(&space); | ||
192 | if (errobj == NULL((void*)0)) | ||
193 | return NULL((void*)0); | ||
194 | old_errno = space[index]; | ||
195 | space[index] = new_errno; | ||
196 | Py_DECREF(errobj)do { if (_Py_RefTotal-- , --((PyObject*)(errobj))->ob_refcnt != 0) { if (((PyObject*)errobj)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 196, (PyObject *)(errobj)); } else _Py_Dealloc((PyObject *) (errobj)); } while (0); | ||
197 | return PyLong_FromLong(old_errno); | ||
198 | } | ||
199 | |||
200 | static PyObject * | ||
201 | get_errno(PyObject *self, PyObject *args) | ||
202 | { | ||
203 | return get_error_internal(self, args, 0); | ||
204 | } | ||
205 | |||
206 | static PyObject * | ||
207 | set_errno(PyObject *self, PyObject *args) | ||
208 | { | ||
209 | return set_error_internal(self, args, 0); | ||
210 | } | ||
211 | |||
212 | #ifdef MS_WIN32 | ||
213 | |||
214 | static PyObject * | ||
215 | get_last_error(PyObject *self, PyObject *args) | ||
216 | { | ||
217 | return get_error_internal(self, args, 1); | ||
218 | } | ||
219 | |||
220 | static PyObject * | ||
221 | set_last_error(PyObject *self, PyObject *args) | ||
222 | { | ||
223 | return set_error_internal(self, args, 1); | ||
224 | } | ||
225 | |||
226 | PyObject *ComError; | ||
227 | |||
228 | static WCHAR *FormatError(DWORD code) | ||
229 | { | ||
230 | WCHAR *lpMsgBuf; | ||
231 | DWORD n; | ||
232 | n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, | ||
233 | NULL((void*)0), | ||
234 | code, | ||
235 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ | ||
236 | (LPWSTR) &lpMsgBuf, | ||
237 | 0, | ||
238 | NULL((void*)0)); | ||
239 | if (n) { | ||
240 | while (iswspace(lpMsgBuf[n-1])) | ||
241 | --n; | ||
242 | lpMsgBuf[n] = L'\0'; /* rstrip() */ | ||
243 | } | ||
244 | return lpMsgBuf; | ||
245 | } | ||
246 | |||
247 | #ifndef DONT_USE_SEH | ||
248 | static void SetException(DWORD code, EXCEPTION_RECORD *pr) | ||
249 | { | ||
250 | /* The 'code' is a normal win32 error code so it could be handled by | ||
251 | PyErr_SetFromWindowsErr(). However, for some errors, we have additional | ||
252 | information not included in the error code. We handle those here and | ||
253 | delegate all others to the generic function. */ | ||
254 | switch (code) { | ||
255 | case EXCEPTION_ACCESS_VIOLATION: | ||
256 | /* The thread attempted to read from or write | ||
257 | to a virtual address for which it does not | ||
258 | have the appropriate access. */ | ||
259 | if (pr->ExceptionInformation[0] == 0) | ||
260 | PyErr_Format(PyExc_WindowsError, | ||
261 | "exception: access violation reading %p", | ||
262 | pr->ExceptionInformation[1]); | ||
263 | else | ||
264 | PyErr_Format(PyExc_WindowsError, | ||
265 | "exception: access violation writing %p", | ||
266 | pr->ExceptionInformation[1]); | ||
267 | break; | ||
268 | |||
269 | case EXCEPTION_BREAKPOINT: | ||
270 | /* A breakpoint was encountered. */ | ||
271 | PyErr_SetString(PyExc_WindowsError, | ||
272 | "exception: breakpoint encountered"); | ||
273 | break; | ||
274 | |||
275 | case EXCEPTION_DATATYPE_MISALIGNMENT: | ||
276 | /* The thread attempted to read or write data that is | ||
277 | misaligned on hardware that does not provide | ||
278 | alignment. For example, 16-bit values must be | ||
279 | aligned on 2-byte boundaries, 32-bit values on | ||
280 | 4-byte boundaries, and so on. */ | ||
281 | PyErr_SetString(PyExc_WindowsError, | ||
282 | "exception: datatype misalignment"); | ||
283 | break; | ||
284 | |||
285 | case EXCEPTION_SINGLE_STEP: | ||
286 | /* A trace trap or other single-instruction mechanism | ||
287 | signaled that one instruction has been executed. */ | ||
288 | PyErr_SetString(PyExc_WindowsError, | ||
289 | "exception: single step"); | ||
290 | break; | ||
291 | |||
292 | case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: | ||
293 | /* The thread attempted to access an array element | ||
294 | that is out of bounds, and the underlying hardware | ||
295 | supports bounds checking. */ | ||
296 | PyErr_SetString(PyExc_WindowsError, | ||
297 | "exception: array bounds exceeded"); | ||
298 | break; | ||
299 | |||
300 | case EXCEPTION_FLT_DENORMAL_OPERAND: | ||
301 | /* One of the operands in a floating-point operation | ||
302 | is denormal. A denormal value is one that is too | ||
303 | small to represent as a standard floating-point | ||
304 | value. */ | ||
305 | PyErr_SetString(PyExc_WindowsError, | ||
306 | "exception: floating-point operand denormal"); | ||
307 | break; | ||
308 | |||
309 | case EXCEPTION_FLT_DIVIDE_BY_ZERO: | ||
310 | /* The thread attempted to divide a floating-point | ||
311 | value by a floating-point divisor of zero. */ | ||
312 | PyErr_SetString(PyExc_WindowsError, | ||
313 | "exception: float divide by zero"); | ||
314 | break; | ||
315 | |||
316 | case EXCEPTION_FLT_INEXACT_RESULT: | ||
317 | /* The result of a floating-point operation cannot be | ||
318 | represented exactly as a decimal fraction. */ | ||
319 | PyErr_SetString(PyExc_WindowsError, | ||
320 | "exception: float inexact"); | ||
321 | break; | ||
322 | |||
323 | case EXCEPTION_FLT_INVALID_OPERATION: | ||
324 | /* This exception represents any floating-point | ||
325 | exception not included in this list. */ | ||
326 | PyErr_SetString(PyExc_WindowsError, | ||
327 | "exception: float invalid operation"); | ||
328 | break; | ||
329 | |||
330 | case EXCEPTION_FLT_OVERFLOW: | ||
331 | /* The exponent of a floating-point operation is | ||
332 | greater than the magnitude allowed by the | ||
333 | corresponding type. */ | ||
334 | PyErr_SetString(PyExc_WindowsError, | ||
335 | "exception: float overflow"); | ||
336 | break; | ||
337 | |||
338 | case EXCEPTION_FLT_STACK_CHECK: | ||
339 | /* The stack overflowed or underflowed as the result | ||
340 | of a floating-point operation. */ | ||
341 | PyErr_SetString(PyExc_WindowsError, | ||
342 | "exception: stack over/underflow"); | ||
343 | break; | ||
344 | |||
345 | case EXCEPTION_STACK_OVERFLOW: | ||
346 | /* The stack overflowed or underflowed as the result | ||
347 | of a floating-point operation. */ | ||
348 | PyErr_SetString(PyExc_WindowsError, | ||
349 | "exception: stack overflow"); | ||
350 | break; | ||
351 | |||
352 | case EXCEPTION_FLT_UNDERFLOW: | ||
353 | /* The exponent of a floating-point operation is less | ||
354 | than the magnitude allowed by the corresponding | ||
355 | type. */ | ||
356 | PyErr_SetString(PyExc_WindowsError, | ||
357 | "exception: float underflow"); | ||
358 | break; | ||
359 | |||
360 | case EXCEPTION_INT_DIVIDE_BY_ZERO: | ||
361 | /* The thread attempted to divide an integer value by | ||
362 | an integer divisor of zero. */ | ||
363 | PyErr_SetString(PyExc_WindowsError, | ||
364 | "exception: integer divide by zero"); | ||
365 | break; | ||
366 | |||
367 | case EXCEPTION_INT_OVERFLOW: | ||
368 | /* The result of an integer operation caused a carry | ||
369 | out of the most significant bit of the result. */ | ||
370 | PyErr_SetString(PyExc_WindowsError, | ||
371 | "exception: integer overflow"); | ||
372 | break; | ||
373 | |||
374 | case EXCEPTION_PRIV_INSTRUCTION: | ||
375 | /* The thread attempted to execute an instruction | ||
376 | whose operation is not allowed in the current | ||
377 | machine mode. */ | ||
378 | PyErr_SetString(PyExc_WindowsError, | ||
379 | "exception: priviledged instruction"); | ||
380 | break; | ||
381 | |||
382 | case EXCEPTION_NONCONTINUABLE_EXCEPTION: | ||
383 | /* The thread attempted to continue execution after a | ||
384 | noncontinuable exception occurred. */ | ||
385 | PyErr_SetString(PyExc_WindowsError, | ||
386 | "exception: nocontinuable"); | ||
387 | break; | ||
388 | |||
389 | default: | ||
390 | PyErr_SetFromWindowsErr(code); | ||
391 | break; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | static DWORD HandleException(EXCEPTION_POINTERS *ptrs, | ||
396 | DWORD *pdw, EXCEPTION_RECORD *record) | ||
397 | { | ||
398 | *pdw = ptrs->ExceptionRecord->ExceptionCode; | ||
399 | *record = *ptrs->ExceptionRecord; | ||
400 | return EXCEPTION_EXECUTE_HANDLER; | ||
401 | } | ||
402 | #endif | ||
403 | |||
404 | static PyObject * | ||
405 | check_hresult(PyObject *self, PyObject *args) | ||
406 | { | ||
407 | HRESULT hr; | ||
408 | if (!PyArg_ParseTuple(args, "i", &hr)) | ||
409 | return NULL((void*)0); | ||
410 | if (FAILED(hr)) | ||
411 | return PyErr_SetFromWindowsErr(hr); | ||
412 | return PyLong_FromLong(hr); | ||
413 | } | ||
414 | |||
415 | #endif | ||
416 | |||
417 | /**************************************************************/ | ||
418 | |||
419 | PyCArgObject * | ||
420 | PyCArgObject_new(void) | ||
421 | { | ||
422 | PyCArgObject *p; | ||
423 | p = PyObject_New(PyCArgObject, &PyCArg_Type)( (PyCArgObject *) _PyObject_New(&PyCArg_Type) ); | ||
424 | if (p == NULL((void*)0)) | ||
425 | return NULL((void*)0); | ||
426 | p->pffi_type = NULL((void*)0); | ||
427 | p->tag = '\0'; | ||
428 | p->obj = NULL((void*)0); | ||
429 | memset(&p->value, 0, sizeof(p->value))((__builtin_object_size (&p->value, 0) != (size_t) -1) ? __builtin___memset_chk (&p->value, 0, sizeof(p-> value), __builtin_object_size (&p->value, 0)) : __inline_memset_chk (&p->value, 0, sizeof(p->value))); | ||
430 | return p; | ||
431 | } | ||
432 | |||
433 | static void | ||
434 | PyCArg_dealloc(PyCArgObject *self) | ||
435 | { | ||
436 | Py_XDECREF(self->obj)do { if ((self->obj) == ((void*)0)) ; else do { if (_Py_RefTotal -- , --((PyObject*)(self->obj))->ob_refcnt != 0) { if ( ((PyObject*)self->obj)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 436, (PyObject *)(self->obj)); } else _Py_Dealloc((PyObject *)(self->obj)); } while (0); } while (0); | ||
437 | PyObject_Del_PyObject_DebugFree(self); | ||
438 | } | ||
439 | |||
440 | static PyObject * | ||
441 | PyCArg_repr(PyCArgObject *self) | ||
442 | { | ||
443 | char buffer[256]; | ||
444 | switch(self->tag) { | ||
445 | case 'b': | ||
446 | case 'B': | ||
447 | sprintf(buffer, "<cparam '%c' (%d)>",__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%d)>", self->tag, self-> value.b) | ||
448 | self->tag, self->value.b)__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%d)>", self->tag, self-> value.b); | ||
449 | break; | ||
450 | case 'h': | ||
451 | case 'H': | ||
452 | sprintf(buffer, "<cparam '%c' (%d)>",__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%d)>", self->tag, self-> value.h) | ||
453 | self->tag, self->value.h)__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%d)>", self->tag, self-> value.h); | ||
454 | break; | ||
455 | case 'i': | ||
456 | case 'I': | ||
457 | sprintf(buffer, "<cparam '%c' (%d)>",__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%d)>", self->tag, self-> value.i) | ||
458 | self->tag, self->value.i)__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%d)>", self->tag, self-> value.i); | ||
459 | break; | ||
460 | case 'l': | ||
461 | case 'L': | ||
462 | sprintf(buffer, "<cparam '%c' (%ld)>",__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%ld)>", self->tag, self-> value.l) | ||
463 | self->tag, self->value.l)__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%ld)>", self->tag, self-> value.l); | ||
464 | break; | ||
465 | |||
466 | #ifdef HAVE_LONG_LONG1 | ||
467 | case 'q': | ||
468 | case 'Q': | ||
469 | sprintf(buffer,__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), ifdef MS_WIN32 "<cparam '%c' (%I64d)>",else "<cparam '%c' (%qd)>",endif self->tag, self->value .q) | ||
470 | #ifdef MS_WIN32__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), ifdef MS_WIN32 "<cparam '%c' (%I64d)>",else "<cparam '%c' (%qd)>",endif self->tag, self->value .q) | ||
471 | "<cparam '%c' (%I64d)>",__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), ifdef MS_WIN32 "<cparam '%c' (%I64d)>",else "<cparam '%c' (%qd)>",endif self->tag, self->value .q) | ||
472 | #else__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), ifdef MS_WIN32 "<cparam '%c' (%I64d)>",else "<cparam '%c' (%qd)>",endif self->tag, self->value .q) | ||
473 | "<cparam '%c' (%qd)>",__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), ifdef MS_WIN32 "<cparam '%c' (%I64d)>",else "<cparam '%c' (%qd)>",endif self->tag, self->value .q) | ||
474 | #endif__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), ifdef MS_WIN32 "<cparam '%c' (%I64d)>",else "<cparam '%c' (%qd)>",endif self->tag, self->value .q) | ||
475 | self->tag, self->value.q)__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), ifdef MS_WIN32 "<cparam '%c' (%I64d)>",else "<cparam '%c' (%qd)>",endif self->tag, self->value .q); | ||
476 | break; | ||
477 | #endif | ||
478 | case 'd': | ||
479 | sprintf(buffer, "<cparam '%c' (%f)>",__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%f)>", self->tag, self-> value.d) | ||
480 | self->tag, self->value.d)__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%f)>", self->tag, self-> value.d); | ||
481 | break; | ||
482 | case 'f': | ||
483 | sprintf(buffer, "<cparam '%c' (%f)>",__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%f)>", self->tag, self-> value.f) | ||
484 | self->tag, self->value.f)__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%f)>", self->tag, self-> value.f); | ||
485 | break; | ||
486 | |||
487 | case 'c': | ||
488 | sprintf(buffer, "<cparam '%c' (%c)>",__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%c)>", self->tag, self-> value.c) | ||
489 | self->tag, self->value.c)__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%c)>", self->tag, self-> value.c); | ||
490 | break; | ||
491 | |||
492 | /* Hm, are these 'z' and 'Z' codes useful at all? | ||
493 | Shouldn't they be replaced by the functionality of c_string | ||
494 | and c_wstring ? | ||
495 | */ | ||
496 | case 'z': | ||
497 | case 'Z': | ||
498 | case 'P': | ||
499 | sprintf(buffer, "<cparam '%c' (%p)>",__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%p)>", self->tag, self-> value.p) | ||
500 | self->tag, self->value.p)__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' (%p)>", self->tag, self-> value.p); | ||
501 | break; | ||
502 | |||
503 | default: | ||
504 | sprintf(buffer, "<cparam '%c' at %p>",__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' at %p>", self->tag, self) | ||
505 | self->tag, self)__builtin___sprintf_chk (buffer, 0, __builtin_object_size (buffer , 2 > 1), "<cparam '%c' at %p>", self->tag, self); | ||
506 | break; | ||
507 | } | ||
508 | return PyUnicode_FromStringPyUnicodeUCS2_FromString(buffer); | ||
509 | } | ||
510 | |||
511 | static PyMemberDef PyCArgType_members[] = { | ||
512 | { "_obj", T_OBJECT6, | ||
513 | offsetof(PyCArgObject, obj)__builtin_offsetof(PyCArgObject, obj), READONLY1, | ||
514 | "the wrapped object" }, | ||
515 | { NULL((void*)0) }, | ||
516 | }; | ||
517 | |||
518 | PyTypeObject PyCArg_Type = { | ||
519 | PyVarObject_HEAD_INIT(NULL, 0){ { 0, 0, 1, ((void*)0) }, 0 }, | ||
520 | "CArgObject", | ||
521 | sizeof(PyCArgObject), | ||
522 | 0, | ||
523 | (destructor)PyCArg_dealloc, /* tp_dealloc */ | ||
524 | 0, /* tp_print */ | ||
525 | 0, /* tp_getattr */ | ||
526 | 0, /* tp_setattr */ | ||
527 | 0, /* tp_reserved */ | ||
528 | (reprfunc)PyCArg_repr, /* tp_repr */ | ||
529 | 0, /* tp_as_number */ | ||
530 | 0, /* tp_as_sequence */ | ||
531 | 0, /* tp_as_mapping */ | ||
532 | 0, /* tp_hash */ | ||
533 | 0, /* tp_call */ | ||
534 | 0, /* tp_str */ | ||
535 | 0, /* tp_getattro */ | ||
536 | 0, /* tp_setattro */ | ||
537 | 0, /* tp_as_buffer */ | ||
538 | Py_TPFLAGS_DEFAULT( 0 | (1L<<18) | 0), /* tp_flags */ | ||
539 | 0, /* tp_doc */ | ||
540 | 0, /* tp_traverse */ | ||
541 | 0, /* tp_clear */ | ||
542 | 0, /* tp_richcompare */ | ||
543 | 0, /* tp_weaklistoffset */ | ||
544 | 0, /* tp_iter */ | ||
545 | 0, /* tp_iternext */ | ||
546 | 0, /* tp_methods */ | ||
547 | PyCArgType_members, /* tp_members */ | ||
548 | }; | ||
549 | |||
550 | /****************************************************************/ | ||
551 | /* | ||
552 | * Convert a PyObject * into a parameter suitable to pass to an | ||
553 | * C function call. | ||
554 | * | ||
555 | * 1. Python integers are converted to C int and passed by value. | ||
556 | * Py_None is converted to a C NULL pointer. | ||
557 | * | ||
558 | * 2. 3-tuples are expected to have a format character in the first | ||
559 | * item, which must be 'i', 'f', 'd', 'q', or 'P'. | ||
560 | * The second item will have to be an integer, float, double, long long | ||
561 | * or integer (denoting an address void *), will be converted to the | ||
562 | * corresponding C data type and passed by value. | ||
563 | * | ||
564 | * 3. Other Python objects are tested for an '_as_parameter_' attribute. | ||
565 | * The value of this attribute must be an integer which will be passed | ||
566 | * by value, or a 2-tuple or 3-tuple which will be used according | ||
567 | * to point 2 above. The third item (if any), is ignored. It is normally | ||
568 | * used to keep the object alive where this parameter refers to. | ||
569 | * XXX This convention is dangerous - you can construct arbitrary tuples | ||
570 | * in Python and pass them. Would it be safer to use a custom container | ||
571 | * datatype instead of a tuple? | ||
572 | * | ||
573 | * 4. Other Python objects cannot be passed as parameters - an exception is raised. | ||
574 | * | ||
575 | * 5. ConvParam will store the converted result in a struct containing format | ||
576 | * and value. | ||
577 | */ | ||
578 | |||
579 | union result { | ||
580 | char c; | ||
581 | char b; | ||
582 | short h; | ||
583 | int i; | ||
584 | long l; | ||
585 | #ifdef HAVE_LONG_LONG1 | ||
586 | PY_LONG_LONGlong long q; | ||
587 | #endif | ||
588 | long double D; | ||
589 | double d; | ||
590 | float f; | ||
591 | void *p; | ||
592 | }; | ||
593 | |||
594 | struct argument { | ||
595 | ffi_type *ffi_type; | ||
596 | PyObject *keep; | ||
597 | union result value; | ||
598 | }; | ||
599 | |||
600 | /* | ||
601 | * Convert a single Python object into a PyCArgObject and return it. | ||
602 | */ | ||
603 | static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) | ||
604 | { | ||
605 | StgDictObject *dict; | ||
606 | pa->keep = NULL((void*)0); /* so we cannot forget it later */ | ||
607 | |||
608 | dict = PyObject_stgdict(obj); | ||
609 | if (dict) { | ||
610 | PyCArgObject *carg; | ||
611 | assert(dict->paramfunc)(__builtin_expect(!(dict->paramfunc), 0) ? __assert_rtn(__func__ , "/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 611, "dict->paramfunc") : (void)0); | ||
612 | /* If it has an stgdict, it is a CDataObject */ | ||
613 | carg = dict->paramfunc((CDataObject *)obj); | ||
614 | pa->ffi_type = carg->pffi_type; | ||
615 | memcpy(&pa->value, &carg->value, sizeof(pa->value))((__builtin_object_size (&pa->value, 0) != (size_t) -1 ) ? __builtin___memcpy_chk (&pa->value, &carg-> value, sizeof(pa->value), __builtin_object_size (&pa-> value, 0)) : __inline_memcpy_chk (&pa->value, &carg ->value, sizeof(pa->value))); | ||
616 | pa->keep = (PyObject *)carg; | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | if (PyCArg_CheckExact(obj)((obj)->ob_type == &PyCArg_Type)) { | ||
621 | PyCArgObject *carg = (PyCArgObject *)obj; | ||
622 | pa->ffi_type = carg->pffi_type; | ||
623 | Py_INCREF(obj)( _Py_RefTotal++ , ((PyObject*)(obj))->ob_refcnt++); | ||
624 | pa->keep = obj; | ||
625 | memcpy(&pa->value, &carg->value, sizeof(pa->value))((__builtin_object_size (&pa->value, 0) != (size_t) -1 ) ? __builtin___memcpy_chk (&pa->value, &carg-> value, sizeof(pa->value), __builtin_object_size (&pa-> value, 0)) : __inline_memcpy_chk (&pa->value, &carg ->value, sizeof(pa->value))); | ||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | /* check for None, integer, string or unicode and use directly if successful */ | ||
630 | if (obj == Py_None(&_Py_NoneStruct)) { | ||
631 | pa->ffi_type = &ffi_type_pointer; | ||
632 | pa->value.p = NULL((void*)0); | ||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | if (PyLong_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1L<< 24))) != 0)) { | ||
637 | pa->ffi_type = &ffi_type_sintffi_type_sint32; | ||
638 | pa->value.i = (long)PyLong_AsUnsignedLong(obj); | ||
639 | if (pa->value.i == -1 && PyErr_Occurred()) { | ||
640 | PyErr_Clear(); | ||
641 | pa->value.i = PyLong_AsLong(obj); | ||
642 | if (pa->value.i == -1 && PyErr_Occurred()) { | ||
643 | PyErr_SetString(PyExc_OverflowError, | ||
644 | "long int too long to convert"); | ||
645 | return -1; | ||
646 | } | ||
647 | } | ||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | if (PyBytes_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1L<< 27))) != 0)) { | ||
652 | pa->ffi_type = &ffi_type_pointer; | ||
653 | pa->value.p = PyBytes_AsString(obj); | ||
654 | Py_INCREF(obj)( _Py_RefTotal++ , ((PyObject*)(obj))->ob_refcnt++); | ||
655 | pa->keep = obj; | ||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | #ifdef CTYPES_UNICODE | ||
660 | if (PyUnicode_Check(obj)((((((PyObject*)(obj))->ob_type))->tp_flags & ((1L<< 28))) != 0)) { | ||
661 | #if Py_UNICODE_SIZE2 == SIZEOF_WCHAR_T4 | ||
662 | pa->ffi_type = &ffi_type_pointer; | ||
663 | pa->value.p = PyUnicode_AS_UNICODE(obj)((__builtin_expect(!(((((((PyObject*)(obj))->ob_type))-> tp_flags & ((1L<<28))) != 0)), 0) ? __assert_rtn(__func__ , "/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 663, "PyUnicode_Check(obj)") : (void)0),(((PyUnicodeObject * )(obj))->str)); | ||
664 | Py_INCREF(obj)( _Py_RefTotal++ , ((PyObject*)(obj))->ob_refcnt++); | ||
665 | pa->keep = obj; | ||
666 | return 0; | ||
667 | #else | ||
668 | pa->ffi_type = &ffi_type_pointer; | ||
669 | pa->value.p = PyUnicode_AsWideCharStringPyUnicodeUCS2_AsWideCharString(obj, NULL((void*)0)); | ||
670 | if (pa->value.p == NULL((void*)0)) | ||
671 | return -1; | ||
672 | pa->keep = PyCapsule_New(pa->value.p, CTYPES_CAPSULE_NAME_PYMEM"_ctypes pymem", pymem_destructor); | ||
673 | if (!pa->keep) { | ||
674 | PyMem_Free(pa->value.p); | ||
675 | return -1; | ||
676 | } | ||
677 | return 0; | ||
678 | #endif | ||
679 | } | ||
680 | #endif | ||
681 | |||
682 | { | ||
683 | PyObject *arg; | ||
684 | arg = PyObject_GetAttrString(obj, "_as_parameter_"); | ||
685 | /* Which types should we exactly allow here? | ||
686 | integers are required for using Python classes | ||
687 | as parameters (they have to expose the '_as_parameter_' | ||
688 | attribute) | ||
689 | */ | ||
690 | if (arg) { | ||
691 | int result; | ||
692 | result = ConvParam(arg, index, pa); | ||
693 | Py_DECREF(arg)do { if (_Py_RefTotal-- , --((PyObject*)(arg))->ob_refcnt != 0) { if (((PyObject*)arg)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 693, (PyObject *)(arg)); } else _Py_Dealloc((PyObject *)(arg )); } while (0); | ||
694 | return result; | ||
695 | } | ||
696 | PyErr_Format(PyExc_TypeError, | ||
697 | "Don't know how to convert parameter %d", | ||
698 | Py_SAFE_DOWNCAST(index, Py_ssize_t, int)((__builtin_expect(!((Py_ssize_t)(int)(index) == (index)), 0) ? __assert_rtn(__func__, "/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 698, "(Py_ssize_t)(int)(index) == (index)") : (void)0), (int )(index))); | ||
699 | return -1; | ||
700 | } | ||
701 | } | ||
702 | |||
703 | |||
704 | ffi_type *_ctypes_get_ffi_type(PyObject *obj) | ||
705 | { | ||
706 | StgDictObject *dict; | ||
707 | if (obj == NULL((void*)0)) | ||
708 | return &ffi_type_sintffi_type_sint32; | ||
709 | dict = PyType_stgdict(obj); | ||
710 | if (dict == NULL((void*)0)) | ||
711 | return &ffi_type_sintffi_type_sint32; | ||
712 | #if defined(MS_WIN32) && !defined(_WIN32_WCE) | ||
713 | /* This little trick works correctly with MSVC. | ||
714 | It returns small structures in registers | ||
715 | */ | ||
716 | if (dict->ffi_type_pointer.type == FFI_TYPE_STRUCT13) { | ||
717 | if (dict->ffi_type_pointer.size <= 4) | ||
718 | return &ffi_type_sint32; | ||
719 | else if (dict->ffi_type_pointer.size <= 8) | ||
720 | return &ffi_type_sint64; | ||
721 | } | ||
722 | #endif | ||
723 | return &dict->ffi_type_pointer; | ||
724 | } | ||
725 | |||
726 | |||
727 | /* | ||
728 | * libffi uses: | ||
729 | * | ||
730 | * ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, | ||
731 | * unsigned int nargs, | ||
732 | * ffi_type *rtype, | ||
733 | * ffi_type **atypes); | ||
734 | * | ||
735 | * and then | ||
736 | * | ||
737 | * void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues); | ||
738 | */ | ||
739 | static int _call_function_pointer(int flags, | ||
740 | PPROC pProc, | ||
741 | void **avalues, | ||
742 | ffi_type **atypes, | ||
743 | ffi_type *restype, | ||
744 | void *resmem, | ||
745 | int argcount) | ||
746 | { | ||
747 | #ifdef WITH_THREAD1 | ||
748 | PyThreadState *_save = NULL((void*)0); /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */ | ||
749 | #endif | ||
750 | PyObject *error_object = NULL((void*)0); | ||
751 | int *space; | ||
752 | ffi_cif cif; | ||
753 | int cc; | ||
754 | #ifdef MS_WIN32 | ||
755 | int delta; | ||
756 | #ifndef DONT_USE_SEH | ||
757 | DWORD dwExceptionCode = 0; | ||
758 | EXCEPTION_RECORD record; | ||
759 | #endif | ||
760 | #endif | ||
761 | /* XXX check before here */ | ||
762 | if (restype == NULL((void*)0)) { | ||
| |||
763 | PyErr_SetString(PyExc_RuntimeError, | ||
764 | "No ffi_type for result"); | ||
765 | return -1; | ||
766 | } | ||
767 | |||
768 | cc = FFI_DEFAULT_ABI; | ||
769 | #if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(_WIN32_WCE) | ||
770 | if ((flags & FUNCFLAG_CDECL0x1) == 0) | ||
771 | cc = FFI_STDCALL; | ||
772 | #endif | ||
773 | if (FFI_OK != ffi_prep_cif(&cif, | ||
| |||
774 | cc, | ||
775 | argcount, | ||
776 | restype, | ||
777 | atypes)) { | ||
778 | PyErr_SetString(PyExc_RuntimeError, | ||
779 | "ffi_prep_cif failed"); | ||
780 | return -1; | ||
781 | } | ||
782 | |||
783 | if (flags & (FUNCFLAG_USE_ERRNO0x8 | FUNCFLAG_USE_LASTERROR0x10)) { | ||
| |||
784 | error_object = _ctypes_get_errobj(&space); | ||
785 | if (error_object == NULL((void*)0)) | ||
786 | return -1; | ||
787 | } | ||
788 | #ifdef WITH_THREAD1 | ||
789 | if ((flags & FUNCFLAG_PYTHONAPI0x4) == 0) | ||
| |||
790 | Py_UNBLOCK_THREADS_save = PyEval_SaveThread(); | ||
791 | #endif | ||
792 | if (flags & FUNCFLAG_USE_ERRNO0x8) { | ||
| |||
793 | int temp = space[0]; | ||
794 | space[0] = errno(*__error()); | ||
795 | errno(*__error()) = temp; | ||
796 | } | ||
797 | #ifdef MS_WIN32 | ||
798 | if (flags & FUNCFLAG_USE_LASTERROR0x10) { | ||
799 | int temp = space[1]; | ||
800 | space[1] = GetLastError(); | ||
801 | SetLastError(temp); | ||
802 | } | ||
803 | #ifndef DONT_USE_SEH | ||
804 | __try { | ||
805 | #endif | ||
806 | delta = | ||
807 | #endif | ||
808 | ffi_call(&cif, (void *)pProc, resmem, avalues); | ||
809 | #ifdef MS_WIN32 | ||
810 | #ifndef DONT_USE_SEH | ||
811 | } | ||
812 | __except (HandleException(GetExceptionInformation(), | ||
813 | &dwExceptionCode, &record)) { | ||
814 | ; | ||
815 | } | ||
816 | #endif | ||
817 | if (flags & FUNCFLAG_USE_LASTERROR0x10) { | ||
818 | int temp = space[1]; | ||
819 | space[1] = GetLastError(); | ||
820 | SetLastError(temp); | ||
821 | } | ||
822 | #endif | ||
823 | if (flags & FUNCFLAG_USE_ERRNO0x8) { | ||
| |||
824 | int temp = space[0]; | ||
| |||
825 | space[0] = errno(*__error()); | ||
826 | errno(*__error()) = temp; | ||
827 | } | ||
828 | Py_XDECREF(error_object)do { if ((error_object) == ((void*)0)) ; else do { if (_Py_RefTotal -- , --((PyObject*)(error_object))->ob_refcnt != 0) { if ( ((PyObject*)error_object)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 828, (PyObject *)(error_object)); } else _Py_Dealloc((PyObject *)(error_object)); } while (0); } while (0); | ||
829 | #ifdef WITH_THREAD1 | ||
830 | if ((flags & FUNCFLAG_PYTHONAPI0x4) == 0) | ||
831 | Py_BLOCK_THREADSPyEval_RestoreThread(_save); | ||
832 | #endif | ||
833 | #ifdef MS_WIN32 | ||
834 | #ifndef DONT_USE_SEH | ||
835 | if (dwExceptionCode) { | ||
836 | SetException(dwExceptionCode, &record); | ||
837 | return -1; | ||
838 | } | ||
839 | #endif | ||
840 | #ifdef MS_WIN64 | ||
841 | if (delta != 0) { | ||
842 | PyErr_Format(PyExc_RuntimeError, | ||
843 | "ffi_call failed with code %d", | ||
844 | delta); | ||
845 | return -1; | ||
846 | } | ||
847 | #else | ||
848 | if (delta < 0) { | ||
849 | if (flags & FUNCFLAG_CDECL0x1) | ||
850 | PyErr_Format(PyExc_ValueError, | ||
851 | "Procedure called with not enough " | ||
852 | "arguments (%d bytes missing) " | ||
853 | "or wrong calling convention", | ||
854 | -delta); | ||
855 | else | ||
856 | PyErr_Format(PyExc_ValueError, | ||
857 | "Procedure probably called with not enough " | ||
858 | "arguments (%d bytes missing)", | ||
859 | -delta); | ||
860 | return -1; | ||
861 | } else if (delta > 0) { | ||
862 | PyErr_Format(PyExc_ValueError, | ||
863 | "Procedure probably called with too many " | ||
864 | "arguments (%d bytes in excess)", | ||
865 | delta); | ||
866 | return -1; | ||
867 | } | ||
868 | #endif | ||
869 | #endif | ||
870 | if ((flags & FUNCFLAG_PYTHONAPI0x4) && PyErr_Occurred()) | ||
871 | return -1; | ||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | /* | ||
876 | * Convert the C value in result into a Python object, depending on restype. | ||
877 | * | ||
878 | * - If restype is NULL, return a Python integer. | ||
879 | * - If restype is None, return None. | ||
880 | * - If restype is a simple ctypes type (c_int, c_void_p), call the type's getfunc, | ||
881 | * pass the result to checker and return the result. | ||
882 | * - If restype is another ctypes type, return an instance of that. | ||
883 | * - Otherwise, call restype and return the result. | ||
884 | */ | ||
885 | static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker) | ||
886 | { | ||
887 | StgDictObject *dict; | ||
888 | PyObject *retval, *v; | ||
889 | |||
890 | if (restype == NULL((void*)0)) | ||
891 | return PyLong_FromLong(*(int *)result); | ||
892 | |||
893 | if (restype == Py_None(&_Py_NoneStruct)) { | ||
894 | Py_INCREF(Py_None)( _Py_RefTotal++ , ((PyObject*)((&_Py_NoneStruct)))->ob_refcnt ++); | ||
895 | return Py_None(&_Py_NoneStruct); | ||
896 | } | ||
897 | |||
898 | dict = PyType_stgdict(restype); | ||
899 | if (dict == NULL((void*)0)) | ||
900 | return PyObject_CallFunction(restype, "i", *(int *)result); | ||
901 | |||
902 | if (dict->getfunc && !_ctypes_simple_instance(restype)) { | ||
903 | retval = dict->getfunc(result, dict->size); | ||
904 | /* If restype is py_object (detected by comparing getfunc with | ||
905 | O_get), we have to call Py_DECREF because O_get has already | ||
906 | called Py_INCREF. | ||
907 | */ | ||
908 | if (dict->getfunc == _ctypes_get_fielddesc("O")->getfunc) { | ||
909 | Py_DECREF(retval)do { if (_Py_RefTotal-- , --((PyObject*)(retval))->ob_refcnt != 0) { if (((PyObject*)retval)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 909, (PyObject *)(retval)); } else _Py_Dealloc((PyObject *) (retval)); } while (0); | ||
910 | } | ||
911 | } else | ||
912 | retval = PyCData_FromBaseObj(restype, NULL((void*)0), 0, result); | ||
913 | |||
914 | if (!checker || !retval) | ||
915 | return retval; | ||
916 | |||
917 | v = PyObject_CallFunctionObjArgs(checker, retval, NULL((void*)0)); | ||
918 | if (v == NULL((void*)0)) | ||
919 | _ctypes_add_traceback("GetResult", "_ctypes/callproc.c", __LINE__919-2); | ||
920 | Py_DECREF(retval)do { if (_Py_RefTotal-- , --((PyObject*)(retval))->ob_refcnt != 0) { if (((PyObject*)retval)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 920, (PyObject *)(retval)); } else _Py_Dealloc((PyObject *) (retval)); } while (0); | ||
921 | return v; | ||
922 | } | ||
923 | |||
924 | /* | ||
925 | * Raise a new exception 'exc_class', adding additional text to the original | ||
926 | * exception string. | ||
927 | */ | ||
928 | void _ctypes_extend_error(PyObject *exc_class, char *fmt, ...) | ||
929 | { | ||
930 | va_list vargs; | ||
931 | PyObject *tp, *v, *tb, *s, *cls_str, *msg_str; | ||
932 | |||
933 | va_start(vargs, fmt)__builtin_va_start(vargs, fmt); | ||
934 | s = PyUnicode_FromFormatVPyUnicodeUCS2_FromFormatV(fmt, vargs); | ||
935 | va_end(vargs)__builtin_va_end(vargs); | ||
936 | if (!s) | ||
937 | return; | ||
938 | |||
939 | PyErr_Fetch(&tp, &v, &tb); | ||
940 | PyErr_NormalizeException(&tp, &v, &tb); | ||
941 | cls_str = PyObject_Str(tp); | ||
942 | if (cls_str) { | ||
943 | PyUnicode_AppendAndDelPyUnicodeUCS2_AppendAndDel(&s, cls_str); | ||
944 | PyUnicode_AppendAndDelPyUnicodeUCS2_AppendAndDel(&s, PyUnicode_FromStringPyUnicodeUCS2_FromString(": ")); | ||
945 | if (s == NULL((void*)0)) | ||
946 | goto error; | ||
947 | } else | ||
948 | PyErr_Clear(); | ||
949 | msg_str = PyObject_Str(v); | ||
950 | if (msg_str) | ||
951 | PyUnicode_AppendAndDelPyUnicodeUCS2_AppendAndDel(&s, msg_str); | ||
952 | else { | ||
953 | PyErr_Clear(); | ||
954 | PyUnicode_AppendAndDelPyUnicodeUCS2_AppendAndDel(&s, PyUnicode_FromStringPyUnicodeUCS2_FromString("???")); | ||
955 | if (s == NULL((void*)0)) | ||
956 | goto error; | ||
957 | } | ||
958 | PyErr_SetObject(exc_class, s); | ||
959 | error: | ||
960 | Py_XDECREF(tp)do { if ((tp) == ((void*)0)) ; else do { if (_Py_RefTotal-- , --((PyObject*)(tp))->ob_refcnt != 0) { if (((PyObject*)tp )->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 960, (PyObject *)(tp)); } else _Py_Dealloc((PyObject *)(tp) ); } while (0); } while (0); | ||
961 | Py_XDECREF(v)do { if ((v) == ((void*)0)) ; else do { if (_Py_RefTotal-- , -- ((PyObject*)(v))->ob_refcnt != 0) { if (((PyObject*)v)-> ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 961, (PyObject *)(v)); } else _Py_Dealloc((PyObject *)(v)); } while (0); } while (0); | ||
962 | Py_XDECREF(tb)do { if ((tb) == ((void*)0)) ; else do { if (_Py_RefTotal-- , --((PyObject*)(tb))->ob_refcnt != 0) { if (((PyObject*)tb )->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 962, (PyObject *)(tb)); } else _Py_Dealloc((PyObject *)(tb) ); } while (0); } while (0); | ||
963 | Py_XDECREF(s)do { if ((s) == ((void*)0)) ; else do { if (_Py_RefTotal-- , -- ((PyObject*)(s))->ob_refcnt != 0) { if (((PyObject*)s)-> ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 963, (PyObject *)(s)); } else _Py_Dealloc((PyObject *)(s)); } while (0); } while (0); | ||
964 | } | ||
965 | |||
966 | |||
967 | #ifdef MS_WIN32 | ||
968 | |||
969 | static PyObject * | ||
970 | GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk) | ||
971 | { | ||
972 | HRESULT hr; | ||
973 | ISupportErrorInfo *psei = NULL((void*)0); | ||
974 | IErrorInfo *pei = NULL((void*)0); | ||
975 | BSTR descr=NULL((void*)0), helpfile=NULL((void*)0), source=NULL((void*)0); | ||
976 | GUID guid; | ||
977 | DWORD helpcontext=0; | ||
978 | LPOLESTR progid; | ||
979 | PyObject *obj; | ||
980 | LPOLESTR text; | ||
981 | |||
982 | /* We absolutely have to release the GIL during COM method calls, | ||
983 | otherwise we may get a deadlock! | ||
984 | */ | ||
985 | #ifdef WITH_THREAD1 | ||
986 | Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread(); | ||
987 | #endif | ||
988 | |||
989 | hr = pIunk->lpVtbl->QueryInterface(pIunk, &IID_ISupportErrorInfo, (void **)&psei); | ||
990 | if (FAILED(hr)) | ||
991 | goto failed; | ||
992 | |||
993 | hr = psei->lpVtbl->InterfaceSupportsErrorInfo(psei, riid); | ||
994 | psei->lpVtbl->Release(psei); | ||
995 | if (FAILED(hr)) | ||
996 | goto failed; | ||
997 | |||
998 | hr = GetErrorInfo(0, &pei); | ||
999 | if (hr != S_OK) | ||
1000 | goto failed; | ||
1001 | |||
1002 | pei->lpVtbl->GetDescription(pei, &descr); | ||
1003 | pei->lpVtbl->GetGUID(pei, &guid); | ||
1004 | pei->lpVtbl->GetHelpContext(pei, &helpcontext); | ||
1005 | pei->lpVtbl->GetHelpFile(pei, &helpfile); | ||
1006 | pei->lpVtbl->GetSource(pei, &source); | ||
1007 | |||
1008 | pei->lpVtbl->Release(pei); | ||
1009 | |||
1010 | failed: | ||
1011 | #ifdef WITH_THREAD1 | ||
1012 | Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); } | ||
1013 | #endif | ||
1014 | |||
1015 | progid = NULL((void*)0); | ||
1016 | ProgIDFromCLSID(&guid, &progid); | ||
1017 | |||
1018 | text = FormatError(errcode); | ||
1019 | obj = Py_BuildValue( | ||
1020 | "iu(uuuiu)", | ||
1021 | errcode, | ||
1022 | text, | ||
1023 | descr, source, helpfile, helpcontext, | ||
1024 | progid); | ||
1025 | if (obj) { | ||
1026 | PyErr_SetObject(ComError, obj); | ||
1027 | Py_DECREF(obj)do { if (_Py_RefTotal-- , --((PyObject*)(obj))->ob_refcnt != 0) { if (((PyObject*)obj)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1027, (PyObject *)(obj)); } else _Py_Dealloc((PyObject *)(obj )); } while (0); | ||
1028 | } | ||
1029 | LocalFree(text); | ||
1030 | |||
1031 | if (descr) | ||
1032 | SysFreeString(descr); | ||
1033 | if (helpfile) | ||
1034 | SysFreeString(helpfile); | ||
1035 | if (source) | ||
1036 | SysFreeString(source); | ||
1037 | |||
1038 | return NULL((void*)0); | ||
1039 | } | ||
1040 | #endif | ||
1041 | |||
1042 | /* | ||
1043 | * Requirements, must be ensured by the caller: | ||
1044 | * - argtuple is tuple of arguments | ||
1045 | * - argtypes is either NULL, or a tuple of the same size as argtuple | ||
1046 | * | ||
1047 | * - XXX various requirements for restype, not yet collected | ||
1048 | */ | ||
1049 | PyObject *_ctypes_callproc(PPROC pProc, | ||
1050 | PyObject *argtuple, | ||
1051 | #ifdef MS_WIN32 | ||
1052 | IUnknown *pIunk, | ||
1053 | GUID *iid, | ||
1054 | #endif | ||
1055 | int flags, | ||
1056 | PyObject *argtypes, /* misleading name: This is a tuple of | ||
1057 | methods, not types: the .from_param | ||
1058 | class methods of the types */ | ||
1059 | PyObject *restype, | ||
1060 | PyObject *checker) | ||
1061 | { | ||
1062 | Py_ssize_t i, n, argcount, argtype_count; | ||
1063 | void *resbuf; | ||
1064 | struct argument *args, *pa; | ||
1065 | ffi_type **atypes; | ||
1066 | ffi_type *rtype; | ||
1067 | void **avalues; | ||
1068 | PyObject *retval = NULL((void*)0); | ||
1069 | |||
1070 | n = argcount = PyTuple_GET_SIZE(argtuple)(((PyVarObject*)(argtuple))->ob_size); | ||
1071 | #ifdef MS_WIN32 | ||
1072 | /* an optional COM object this pointer */ | ||
1073 | if (pIunk) | ||
1074 | ++argcount; | ||
1075 | #endif | ||
1076 | |||
1077 | args = (struct argument *)alloca(sizeof(struct argument) * argcount)__builtin_alloca(sizeof(struct argument) * argcount); | ||
1078 | if (!args) { | ||
1079 | PyErr_NoMemory(); | ||
1080 | return NULL((void*)0); | ||
1081 | } | ||
1082 | memset(args, 0, sizeof(struct argument) * argcount)((__builtin_object_size (args, 0) != (size_t) -1) ? __builtin___memset_chk (args, 0, sizeof(struct argument) * argcount, __builtin_object_size (args, 0)) : __inline_memset_chk (args, 0, sizeof(struct argument ) * argcount)); | ||
1083 | argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes)(((PyVarObject*)(argtypes))->ob_size) : 0; | ||
1084 | #ifdef MS_WIN32 | ||
1085 | if (pIunk) { | ||
1086 | args[0].ffi_type = &ffi_type_pointer; | ||
1087 | args[0].value.p = pIunk; | ||
1088 | pa = &args[1]; | ||
1089 | } else | ||
1090 | #endif | ||
1091 | pa = &args[0]; | ||
1092 | |||
1093 | /* Convert the arguments */ | ||
1094 | for (i = 0; i < n; ++i, ++pa) { | ||
1095 | PyObject *converter; | ||
1096 | PyObject *arg; | ||
1097 | int err; | ||
1098 | |||
1099 | arg = PyTuple_GET_ITEM(argtuple, i)(((PyTupleObject *)(argtuple))->ob_item[i]); /* borrowed ref */ | ||
1100 | /* For cdecl functions, we allow more actual arguments | ||
1101 | than the length of the argtypes tuple. | ||
1102 | This is checked in _ctypes::PyCFuncPtr_Call | ||
1103 | */ | ||
1104 | if (argtypes && argtype_count > i) { | ||
1105 | PyObject *v; | ||
1106 | converter = PyTuple_GET_ITEM(argtypes, i)(((PyTupleObject *)(argtypes))->ob_item[i]); | ||
1107 | v = PyObject_CallFunctionObjArgs(converter, | ||
1108 | arg, | ||
1109 | NULL((void*)0)); | ||
1110 | if (v == NULL((void*)0)) { | ||
1111 | _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1); | ||
1112 | goto cleanup; | ||
1113 | } | ||
1114 | |||
1115 | err = ConvParam(v, i+1, pa); | ||
1116 | Py_DECREF(v)do { if (_Py_RefTotal-- , --((PyObject*)(v))->ob_refcnt != 0) { if (((PyObject*)v)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1116, (PyObject *)(v)); } else _Py_Dealloc((PyObject *)(v)) ; } while (0); | ||
1117 | if (-1 == err) { | ||
1118 | _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1); | ||
1119 | goto cleanup; | ||
1120 | } | ||
1121 | } else { | ||
1122 | err = ConvParam(arg, i+1, pa); | ||
1123 | if (-1 == err) { | ||
1124 | _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1); | ||
1125 | goto cleanup; /* leaking ? */ | ||
1126 | } | ||
1127 | } | ||
1128 | } | ||
1129 | |||
1130 | rtype = _ctypes_get_ffi_type(restype); | ||
1131 | resbuf = alloca(max(rtype->size, sizeof(ffi_arg)))__builtin_alloca(((rtype->size) > (sizeof(ffi_arg)) ? ( rtype->size) : (sizeof(ffi_arg)))); | ||
1132 | |||
1133 | avalues = (void **)alloca(sizeof(void *) * argcount)__builtin_alloca(sizeof(void *) * argcount); | ||
1134 | atypes = (ffi_type **)alloca(sizeof(ffi_type *) * argcount)__builtin_alloca(sizeof(ffi_type *) * argcount); | ||
1135 | if (!resbuf || !avalues || !atypes) { | ||
1136 | PyErr_NoMemory(); | ||
1137 | goto cleanup; | ||
1138 | } | ||
1139 | for (i = 0; i < argcount; ++i) { | ||
1140 | atypes[i] = args[i].ffi_type; | ||
1141 | if (atypes[i]->type == FFI_TYPE_STRUCT13 | ||
1142 | #ifdef _WIN64 | ||
1143 | && atypes[i]->size <= sizeof(void *) | ||
1144 | #endif | ||
1145 | ) | ||
1146 | avalues[i] = (void *)args[i].value.p; | ||
1147 | else | ||
1148 | avalues[i] = (void *)&args[i].value; | ||
1149 | } | ||
1150 | |||
1151 | if (-1 == _call_function_pointer(flags, pProc, avalues, atypes, | ||
1152 | rtype, resbuf, | ||
1153 | Py_SAFE_DOWNCAST(argcount,((__builtin_expect(!((Py_ssize_t)(int)(argcount) == (argcount )), 0) ? __assert_rtn(__func__, "/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1155, "( Py_ssize_t)( int)(argcount) == (argcount)") : (void )0), (int)(argcount)) | ||
1154 | Py_ssize_t,((__builtin_expect(!((Py_ssize_t)(int)(argcount) == (argcount )), 0) ? __assert_rtn(__func__, "/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1155, "( Py_ssize_t)( int)(argcount) == (argcount)") : (void )0), (int)(argcount)) | ||
1155 | int)((__builtin_expect(!((Py_ssize_t)(int)(argcount) == (argcount )), 0) ? __assert_rtn(__func__, "/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1155, "( Py_ssize_t)( int)(argcount) == (argcount)") : (void )0), (int)(argcount)))) | ||
1156 | goto cleanup; | ||
1157 | |||
1158 | #ifdef WORDS_BIGENDIAN | ||
1159 | /* libffi returns the result in a buffer with sizeof(ffi_arg). This | ||
1160 | causes problems on big endian machines, since the result buffer | ||
1161 | address cannot simply be used as result pointer, instead we must | ||
1162 | adjust the pointer value: | ||
1163 | */ | ||
1164 | /* | ||
1165 | XXX I should find out and clarify why this is needed at all, | ||
1166 | especially why adjusting for ffi_type_float must be avoided on | ||
1167 | 64-bit platforms. | ||
1168 | */ | ||
1169 | if (rtype->type != FFI_TYPE_FLOAT2 | ||
1170 | && rtype->type != FFI_TYPE_STRUCT13 | ||
1171 | && rtype->size < sizeof(ffi_arg)) | ||
1172 | resbuf = (char *)resbuf + sizeof(ffi_arg) - rtype->size; | ||
1173 | #endif | ||
1174 | |||
1175 | #ifdef MS_WIN32 | ||
1176 | if (iid && pIunk) { | ||
1177 | if (*(int *)resbuf & 0x80000000) | ||
1178 | retval = GetComError(*(HRESULT *)resbuf, iid, pIunk); | ||
1179 | else | ||
1180 | retval = PyLong_FromLong(*(int *)resbuf); | ||
1181 | } else if (flags & FUNCFLAG_HRESULT0x2) { | ||
1182 | if (*(int *)resbuf & 0x80000000) | ||
1183 | retval = PyErr_SetFromWindowsErr(*(int *)resbuf); | ||
1184 | else | ||
1185 | retval = PyLong_FromLong(*(int *)resbuf); | ||
1186 | } else | ||
1187 | #endif | ||
1188 | retval = GetResult(restype, resbuf, checker); | ||
1189 | cleanup: | ||
1190 | for (i = 0; i < argcount; ++i) | ||
1191 | Py_XDECREF(args[i].keep)do { if ((args[i].keep) == ((void*)0)) ; else do { if (_Py_RefTotal -- , --((PyObject*)(args[i].keep))->ob_refcnt != 0) { if ( ((PyObject*)args[i].keep)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1191, (PyObject *)(args[i].keep)); } else _Py_Dealloc((PyObject *)(args[i].keep)); } while (0); } while (0); | ||
1192 | return retval; | ||
1193 | } | ||
1194 | |||
1195 | static int | ||
1196 | _parse_voidp(PyObject *obj, void **address) | ||
1197 | { | ||
1198 | *address = PyLong_AsVoidPtr(obj); | ||
1199 | if (*address == NULL((void*)0)) | ||
1200 | return 0; | ||
1201 | return 1; | ||
1202 | } | ||
1203 | |||
1204 | #ifdef MS_WIN32 | ||
1205 | |||
1206 | static char format_error_doc[] = | ||
1207 | "FormatError([integer]) -> string\n\ | ||
1208 | \n\ | ||
1209 | Convert a win32 error code into a string. If the error code is not\n\ | ||
1210 | given, the return value of a call to GetLastError() is used.\n"; | ||
1211 | static PyObject *format_error(PyObject *self, PyObject *args) | ||
1212 | { | ||
1213 | PyObject *result; | ||
1214 | wchar_t *lpMsgBuf; | ||
1215 | DWORD code = 0; | ||
1216 | if (!PyArg_ParseTuple(args, "|i:FormatError", &code)) | ||
1217 | return NULL((void*)0); | ||
1218 | if (code == 0) | ||
1219 | code = GetLastError(); | ||
1220 | lpMsgBuf = FormatError(code); | ||
1221 | if (lpMsgBuf) { | ||
1222 | result = PyUnicode_FromWideCharPyUnicodeUCS2_FromWideChar(lpMsgBuf, wcslen(lpMsgBuf)); | ||
1223 | LocalFree(lpMsgBuf); | ||
1224 | } else { | ||
1225 | result = PyUnicode_FromStringPyUnicodeUCS2_FromString("<no description>"); | ||
1226 | } | ||
1227 | return result; | ||
1228 | } | ||
1229 | |||
1230 | static char load_library_doc[] = | ||
1231 | "LoadLibrary(name) -> handle\n\ | ||
1232 | \n\ | ||
1233 | Load an executable (usually a DLL), and return a handle to it.\n\ | ||
1234 | The handle may be used to locate exported functions in this\n\ | ||
1235 | module.\n"; | ||
1236 | static PyObject *load_library(PyObject *self, PyObject *args) | ||
1237 | { | ||
1238 | WCHAR *name; | ||
1239 | PyObject *nameobj; | ||
1240 | PyObject *ignored; | ||
1241 | HMODULE hMod; | ||
1242 | if (!PyArg_ParseTuple(args, "O|O:LoadLibrary", &nameobj, &ignored)) | ||
1243 | return NULL((void*)0); | ||
1244 | |||
1245 | name = PyUnicode_AsUnicodePyUnicodeUCS2_AsUnicode(nameobj); | ||
1246 | if (!name) | ||
1247 | return NULL((void*)0); | ||
1248 | |||
1249 | hMod = LoadLibraryW(name); | ||
1250 | if (!hMod) | ||
1251 | return PyErr_SetFromWindowsErr(GetLastError()); | ||
1252 | #ifdef _WIN64 | ||
1253 | return PyLong_FromVoidPtr(hMod); | ||
1254 | #else | ||
1255 | return Py_BuildValue("i", hMod); | ||
1256 | #endif | ||
1257 | } | ||
1258 | |||
1259 | static char free_library_doc[] = | ||
1260 | "FreeLibrary(handle) -> void\n\ | ||
1261 | \n\ | ||
1262 | Free the handle of an executable previously loaded by LoadLibrary.\n"; | ||
1263 | static PyObject *free_library(PyObject *self, PyObject *args) | ||
1264 | { | ||
1265 | void *hMod; | ||
1266 | if (!PyArg_ParseTuple(args, "O&:FreeLibrary", &_parse_voidp, &hMod)) | ||
1267 | return NULL((void*)0); | ||
1268 | if (!FreeLibrary((HMODULE)hMod)) | ||
1269 | return PyErr_SetFromWindowsErr(GetLastError()); | ||
1270 | Py_INCREF(Py_None)( _Py_RefTotal++ , ((PyObject*)((&_Py_NoneStruct)))->ob_refcnt ++); | ||
1271 | return Py_None(&_Py_NoneStruct); | ||
1272 | } | ||
1273 | |||
1274 | /* obsolete, should be removed */ | ||
1275 | /* Only used by sample code (in samples\Windows\COM.py) */ | ||
1276 | static PyObject * | ||
1277 | call_commethod(PyObject *self, PyObject *args) | ||
1278 | { | ||
1279 | IUnknown *pIunk; | ||
1280 | int index; | ||
1281 | PyObject *arguments; | ||
1282 | PPROC *lpVtbl; | ||
1283 | PyObject *result; | ||
1284 | CDataObject *pcom; | ||
1285 | PyObject *argtypes = NULL((void*)0); | ||
1286 | |||
1287 | if (!PyArg_ParseTuple(args, | ||
1288 | "OiO!|O!", | ||
1289 | &pcom, &index, | ||
1290 | &PyTuple_Type, &arguments, | ||
1291 | &PyTuple_Type, &argtypes)) | ||
1292 | return NULL((void*)0); | ||
1293 | |||
1294 | if (argtypes && (PyTuple_GET_SIZE(arguments)(((PyVarObject*)(arguments))->ob_size) != PyTuple_GET_SIZE(argtypes)(((PyVarObject*)(argtypes))->ob_size))) { | ||
1295 | PyErr_Format(PyExc_TypeError, | ||
1296 | "Method takes %d arguments (%d given)", | ||
1297 | PyTuple_GET_SIZE(argtypes)(((PyVarObject*)(argtypes))->ob_size), PyTuple_GET_SIZE(arguments)(((PyVarObject*)(arguments))->ob_size)); | ||
1298 | return NULL((void*)0); | ||
1299 | } | ||
1300 | |||
1301 | if (!CDataObject_Check(pcom)((((PyObject*)(pcom))->ob_type) == (&PyCData_Type) || PyType_IsSubtype ((((PyObject*)(pcom))->ob_type), (&PyCData_Type))) || (pcom->b_size != sizeof(void *))) { | ||
1302 | PyErr_Format(PyExc_TypeError, | ||
1303 | "COM Pointer expected instead of %s instance", | ||
1304 | Py_TYPE(pcom)(((PyObject*)(pcom))->ob_type)->tp_name); | ||
1305 | return NULL((void*)0); | ||
1306 | } | ||
1307 | |||
1308 | if ((*(void **)(pcom->b_ptr)) == NULL((void*)0)) { | ||
1309 | PyErr_SetString(PyExc_ValueError, | ||
1310 | "The COM 'this' pointer is NULL"); | ||
1311 | return NULL((void*)0); | ||
1312 | } | ||
1313 | |||
1314 | pIunk = (IUnknown *)(*(void **)(pcom->b_ptr)); | ||
1315 | lpVtbl = (PPROC *)(pIunk->lpVtbl); | ||
1316 | |||
1317 | result = _ctypes_callproc(lpVtbl[index], | ||
1318 | arguments, | ||
1319 | #ifdef MS_WIN32 | ||
1320 | pIunk, | ||
1321 | NULL((void*)0), | ||
1322 | #endif | ||
1323 | FUNCFLAG_HRESULT0x2, /* flags */ | ||
1324 | argtypes, /* self->argtypes */ | ||
1325 | NULL((void*)0), /* self->restype */ | ||
1326 | NULL((void*)0)); /* checker */ | ||
1327 | return result; | ||
1328 | } | ||
1329 | |||
1330 | static char copy_com_pointer_doc[] = | ||
1331 | "CopyComPointer(src, dst) -> HRESULT value\n"; | ||
1332 | |||
1333 | static PyObject * | ||
1334 | copy_com_pointer(PyObject *self, PyObject *args) | ||
1335 | { | ||
1336 | PyObject *p1, *p2, *r = NULL((void*)0); | ||
1337 | struct argument a, b; | ||
1338 | IUnknown *src, **pdst; | ||
1339 | if (!PyArg_ParseTuple(args, "OO:CopyComPointer", &p1, &p2)) | ||
1340 | return NULL((void*)0); | ||
1341 | a.keep = b.keep = NULL((void*)0); | ||
1342 | |||
1343 | if (-1 == ConvParam(p1, 0, &a) || -1 == ConvParam(p2, 1, &b)) | ||
1344 | goto done; | ||
1345 | src = (IUnknown *)a.value.p; | ||
1346 | pdst = (IUnknown **)b.value.p; | ||
1347 | |||
1348 | if (pdst == NULL((void*)0)) | ||
1349 | r = PyLong_FromLong(E_POINTER); | ||
1350 | else { | ||
1351 | if (src) | ||
1352 | src->lpVtbl->AddRef(src); | ||
1353 | *pdst = src; | ||
1354 | r = PyLong_FromLong(S_OK); | ||
1355 | } | ||
1356 | done: | ||
1357 | Py_XDECREF(a.keep)do { if ((a.keep) == ((void*)0)) ; else do { if (_Py_RefTotal -- , --((PyObject*)(a.keep))->ob_refcnt != 0) { if (((PyObject *)a.keep)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1357, (PyObject *)(a.keep)); } else _Py_Dealloc((PyObject * )(a.keep)); } while (0); } while (0); | ||
1358 | Py_XDECREF(b.keep)do { if ((b.keep) == ((void*)0)) ; else do { if (_Py_RefTotal -- , --((PyObject*)(b.keep))->ob_refcnt != 0) { if (((PyObject *)b.keep)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1358, (PyObject *)(b.keep)); } else _Py_Dealloc((PyObject * )(b.keep)); } while (0); } while (0); | ||
1359 | return r; | ||
1360 | } | ||
1361 | #else | ||
1362 | |||
1363 | static PyObject *py_dl_open(PyObject *self, PyObject *args) | ||
1364 | { | ||
1365 | PyObject *name, *name2; | ||
1366 | char *name_str; | ||
1367 | void * handle; | ||
1368 | #ifdef RTLD_LOCAL0x4 | ||
1369 | int mode = RTLD_NOW0x2 | RTLD_LOCAL0x4; | ||
1370 | #else | ||
1371 | /* cygwin doesn't define RTLD_LOCAL */ | ||
1372 | int mode = RTLD_NOW0x2; | ||
1373 | #endif | ||
1374 | if (!PyArg_ParseTuple(args, "O|i:dlopen", &name, &mode)) | ||
1375 | return NULL((void*)0); | ||
1376 | mode |= RTLD_NOW0x2; | ||
1377 | if (name != Py_None(&_Py_NoneStruct)) { | ||
1378 | if (PyUnicode_FSConverterPyUnicodeUCS2_FSConverter(name, &name2) == 0) | ||
1379 | return NULL((void*)0); | ||
1380 | if (PyBytes_Check(name2)((((((PyObject*)(name2))->ob_type))->tp_flags & ((1L <<27))) != 0)) | ||
1381 | name_str = PyBytes_AS_STRING(name2)((__builtin_expect(!(((((((PyObject*)(name2))->ob_type))-> tp_flags & ((1L<<27))) != 0)), 0) ? __assert_rtn(__func__ , "/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1381, "PyBytes_Check(name2)") : (void)0), (((PyBytesObject * )(name2))->ob_sval)); | ||
1382 | else | ||
1383 | name_str = PyByteArray_AS_STRING(name2)((__builtin_expect(!(((((PyObject*)(name2))->ob_type) == ( &PyByteArray_Type) || PyType_IsSubtype((((PyObject*)(name2 ))->ob_type), (&PyByteArray_Type)))), 0) ? __assert_rtn (__func__, "/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1383, "PyByteArray_Check(name2)") : (void)0), (((PyVarObject *)(name2))->ob_size) ? ((PyByteArrayObject *)(name2))-> ob_bytes : _PyByteArray_empty_string); | ||
1384 | } else { | ||
1385 | name_str = NULL((void*)0); | ||
1386 | name2 = NULL((void*)0); | ||
1387 | } | ||
1388 | handle = ctypes_dlopendlopen(name_str, mode); | ||
1389 | Py_XDECREF(name2)do { if ((name2) == ((void*)0)) ; else do { if (_Py_RefTotal-- , --((PyObject*)(name2))->ob_refcnt != 0) { if (((PyObject *)name2)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1389, (PyObject *)(name2)); } else _Py_Dealloc((PyObject *) (name2)); } while (0); } while (0); | ||
1390 | if (!handle) { | ||
1391 | char *errmsg = ctypes_dlerrordlerror(); | ||
1392 | if (!errmsg) | ||
1393 | errmsg = "dlopen() error"; | ||
1394 | PyErr_SetString(PyExc_OSError, | ||
1395 | errmsg); | ||
1396 | return NULL((void*)0); | ||
1397 | } | ||
1398 | return PyLong_FromVoidPtr(handle); | ||
1399 | } | ||
1400 | |||
1401 | static PyObject *py_dl_close(PyObject *self, PyObject *args) | ||
1402 | { | ||
1403 | void *handle; | ||
1404 | |||
1405 | if (!PyArg_ParseTuple(args, "O&:dlclose", &_parse_voidp, &handle)) | ||
1406 | return NULL((void*)0); | ||
1407 | if (dlclose(handle)) { | ||
1408 | PyErr_SetString(PyExc_OSError, | ||
1409 | ctypes_dlerrordlerror()); | ||
1410 | return NULL((void*)0); | ||
1411 | } | ||
1412 | Py_INCREF(Py_None)( _Py_RefTotal++ , ((PyObject*)((&_Py_NoneStruct)))->ob_refcnt ++); | ||
1413 | return Py_None(&_Py_NoneStruct); | ||
1414 | } | ||
1415 | |||
1416 | static PyObject *py_dl_sym(PyObject *self, PyObject *args) | ||
1417 | { | ||
1418 | char *name; | ||
1419 | void *handle; | ||
1420 | void *ptr; | ||
1421 | |||
1422 | if (!PyArg_ParseTuple(args, "O&s:dlsym", | ||
1423 | &_parse_voidp, &handle, &name)) | ||
1424 | return NULL((void*)0); | ||
1425 | ptr = ctypes_dlsymdlsym((void*)handle, name); | ||
1426 | if (!ptr) { | ||
1427 | PyErr_SetString(PyExc_OSError, | ||
1428 | ctypes_dlerrordlerror()); | ||
1429 | return NULL((void*)0); | ||
1430 | } | ||
1431 | return PyLong_FromVoidPtr(ptr); | ||
1432 | } | ||
1433 | #endif | ||
1434 | |||
1435 | /* | ||
1436 | * Only for debugging so far: So that we can call CFunction instances | ||
1437 | * | ||
1438 | * XXX Needs to accept more arguments: flags, argtypes, restype | ||
1439 | */ | ||
1440 | static PyObject * | ||
1441 | call_function(PyObject *self, PyObject *args) | ||
1442 | { | ||
1443 | void *func; | ||
1444 | PyObject *arguments; | ||
1445 | PyObject *result; | ||
1446 | |||
1447 | if (!PyArg_ParseTuple(args, | ||
1448 | "O&O!", | ||
1449 | &_parse_voidp, &func, | ||
1450 | &PyTuple_Type, &arguments)) | ||
1451 | return NULL((void*)0); | ||
1452 | |||
1453 | result = _ctypes_callproc((PPROC)func, | ||
1454 | arguments, | ||
1455 | #ifdef MS_WIN32 | ||
1456 | NULL((void*)0), | ||
1457 | NULL((void*)0), | ||
1458 | #endif | ||
1459 | 0, /* flags */ | ||
1460 | NULL((void*)0), /* self->argtypes */ | ||
1461 | NULL((void*)0), /* self->restype */ | ||
1462 | NULL((void*)0)); /* checker */ | ||
1463 | return result; | ||
1464 | } | ||
1465 | |||
1466 | /* | ||
1467 | * Only for debugging so far: So that we can call CFunction instances | ||
1468 | * | ||
1469 | * XXX Needs to accept more arguments: flags, argtypes, restype | ||
1470 | */ | ||
1471 | static PyObject * | ||
1472 | call_cdeclfunction(PyObject *self, PyObject *args) | ||
1473 | { | ||
1474 | void *func; | ||
1475 | PyObject *arguments; | ||
1476 | PyObject *result; | ||
1477 | |||
1478 | if (!PyArg_ParseTuple(args, | ||
1479 | "O&O!", | ||
1480 | &_parse_voidp, &func, | ||
1481 | &PyTuple_Type, &arguments)) | ||
1482 | return NULL((void*)0); | ||
1483 | |||
1484 | result = _ctypes_callproc((PPROC)func, | ||
1485 | arguments, | ||
1486 | #ifdef MS_WIN32 | ||
1487 | NULL((void*)0), | ||
1488 | NULL((void*)0), | ||
1489 | #endif | ||
1490 | FUNCFLAG_CDECL0x1, /* flags */ | ||
1491 | NULL((void*)0), /* self->argtypes */ | ||
1492 | NULL((void*)0), /* self->restype */ | ||
1493 | NULL((void*)0)); /* checker */ | ||
1494 | return result; | ||
1495 | } | ||
1496 | |||
1497 | /***************************************************************** | ||
1498 | * functions | ||
1499 | */ | ||
1500 | static char sizeof_doc[] = | ||
1501 | "sizeof(C type) -> integer\n" | ||
1502 | "sizeof(C instance) -> integer\n" | ||
1503 | "Return the size in bytes of a C instance"; | ||
1504 | |||
1505 | static PyObject * | ||
1506 | sizeof_func(PyObject *self, PyObject *obj) | ||
1507 | { | ||
1508 | StgDictObject *dict; | ||
1509 | |||
1510 | dict = PyType_stgdict(obj); | ||
1511 | if (dict) | ||
1512 | return PyLong_FromSsize_t(dict->size); | ||
1513 | |||
1514 | if (CDataObject_Check(obj)((((PyObject*)(obj))->ob_type) == (&PyCData_Type) || PyType_IsSubtype ((((PyObject*)(obj))->ob_type), (&PyCData_Type)))) | ||
1515 | return PyLong_FromSsize_t(((CDataObject *)obj)->b_size); | ||
1516 | PyErr_SetString(PyExc_TypeError, | ||
1517 | "this type has no size"); | ||
1518 | return NULL((void*)0); | ||
1519 | } | ||
1520 | |||
1521 | static char alignment_doc[] = | ||
1522 | "alignment(C type) -> integer\n" | ||
1523 | "alignment(C instance) -> integer\n" | ||
1524 | "Return the alignment requirements of a C instance"; | ||
1525 | |||
1526 | static PyObject * | ||
1527 | align_func(PyObject *self, PyObject *obj) | ||
1528 | { | ||
1529 | StgDictObject *dict; | ||
1530 | |||
1531 | dict = PyType_stgdict(obj); | ||
1532 | if (dict) | ||
1533 | return PyLong_FromSsize_t(dict->align); | ||
1534 | |||
1535 | dict = PyObject_stgdict(obj); | ||
1536 | if (dict) | ||
1537 | return PyLong_FromSsize_t(dict->align); | ||
1538 | |||
1539 | PyErr_SetString(PyExc_TypeError, | ||
1540 | "no alignment info"); | ||
1541 | return NULL((void*)0); | ||
1542 | } | ||
1543 | |||
1544 | static char byref_doc[] = | ||
1545 | "byref(C instance[, offset=0]) -> byref-object\n" | ||
1546 | "Return a pointer lookalike to a C instance, only usable\n" | ||
1547 | "as function argument"; | ||
1548 | |||
1549 | /* | ||
1550 | * We must return something which can be converted to a parameter, | ||
1551 | * but still has a reference to self. | ||
1552 | */ | ||
1553 | static PyObject * | ||
1554 | byref(PyObject *self, PyObject *args) | ||
1555 | { | ||
1556 | PyCArgObject *parg; | ||
1557 | PyObject *obj; | ||
1558 | PyObject *pyoffset = NULL((void*)0); | ||
1559 | Py_ssize_t offset = 0; | ||
1560 | |||
1561 | if (!PyArg_UnpackTuple(args, "byref", 1, 2, | ||
1562 | &obj, &pyoffset)) | ||
1563 | return NULL((void*)0); | ||
1564 | if (pyoffset) { | ||
1565 | offset = PyNumber_AsSsize_t(pyoffset, NULL((void*)0)); | ||
1566 | if (offset == -1 && PyErr_Occurred()) | ||
1567 | return NULL((void*)0); | ||
1568 | } | ||
1569 | if (!CDataObject_Check(obj)((((PyObject*)(obj))->ob_type) == (&PyCData_Type) || PyType_IsSubtype ((((PyObject*)(obj))->ob_type), (&PyCData_Type)))) { | ||
1570 | PyErr_Format(PyExc_TypeError, | ||
1571 | "byref() argument must be a ctypes instance, not '%s'", | ||
1572 | Py_TYPE(obj)(((PyObject*)(obj))->ob_type)->tp_name); | ||
1573 | return NULL((void*)0); | ||
1574 | } | ||
1575 | |||
1576 | parg = PyCArgObject_new(); | ||
1577 | if (parg == NULL((void*)0)) | ||
1578 | return NULL((void*)0); | ||
1579 | |||
1580 | parg->tag = 'P'; | ||
1581 | parg->pffi_type = &ffi_type_pointer; | ||
1582 | Py_INCREF(obj)( _Py_RefTotal++ , ((PyObject*)(obj))->ob_refcnt++); | ||
1583 | parg->obj = obj; | ||
1584 | parg->value.p = (char *)((CDataObject *)obj)->b_ptr + offset; | ||
1585 | return (PyObject *)parg; | ||
1586 | } | ||
1587 | |||
1588 | static char addressof_doc[] = | ||
1589 | "addressof(C instance) -> integer\n" | ||
1590 | "Return the address of the C instance internal buffer"; | ||
1591 | |||
1592 | static PyObject * | ||
1593 | addressof(PyObject *self, PyObject *obj) | ||
1594 | { | ||
1595 | if (CDataObject_Check(obj)((((PyObject*)(obj))->ob_type) == (&PyCData_Type) || PyType_IsSubtype ((((PyObject*)(obj))->ob_type), (&PyCData_Type)))) | ||
1596 | return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr); | ||
1597 | PyErr_SetString(PyExc_TypeError, | ||
1598 | "invalid type"); | ||
1599 | return NULL((void*)0); | ||
1600 | } | ||
1601 | |||
1602 | static int | ||
1603 | converter(PyObject *obj, void **address) | ||
1604 | { | ||
1605 | *address = PyLong_AsVoidPtr(obj); | ||
1606 | return *address != NULL((void*)0); | ||
1607 | } | ||
1608 | |||
1609 | static PyObject * | ||
1610 | My_PyObj_FromPtr(PyObject *self, PyObject *args) | ||
1611 | { | ||
1612 | PyObject *ob; | ||
1613 | if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob)) | ||
1614 | return NULL((void*)0); | ||
1615 | Py_INCREF(ob)( _Py_RefTotal++ , ((PyObject*)(ob))->ob_refcnt++); | ||
1616 | return ob; | ||
1617 | } | ||
1618 | |||
1619 | static PyObject * | ||
1620 | My_Py_INCREF(PyObject *self, PyObject *arg) | ||
1621 | { | ||
1622 | Py_INCREF(arg)( _Py_RefTotal++ , ((PyObject*)(arg))->ob_refcnt++); /* that's what this function is for */ | ||
1623 | Py_INCREF(arg)( _Py_RefTotal++ , ((PyObject*)(arg))->ob_refcnt++); /* that for returning it */ | ||
1624 | return arg; | ||
1625 | } | ||
1626 | |||
1627 | static PyObject * | ||
1628 | My_Py_DECREF(PyObject *self, PyObject *arg) | ||
1629 | { | ||
1630 | Py_DECREF(arg)do { if (_Py_RefTotal-- , --((PyObject*)(arg))->ob_refcnt != 0) { if (((PyObject*)arg)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1630, (PyObject *)(arg)); } else _Py_Dealloc((PyObject *)(arg )); } while (0); /* that's what this function is for */ | ||
1631 | Py_INCREF(arg)( _Py_RefTotal++ , ((PyObject*)(arg))->ob_refcnt++); /* that's for returning it */ | ||
1632 | return arg; | ||
1633 | } | ||
1634 | |||
1635 | static PyObject * | ||
1636 | resize(PyObject *self, PyObject *args) | ||
1637 | { | ||
1638 | CDataObject *obj; | ||
1639 | StgDictObject *dict; | ||
1640 | Py_ssize_t size; | ||
1641 | |||
1642 | if (!PyArg_ParseTuple(args, | ||
1643 | "On:resize", | ||
1644 | &obj, &size)) | ||
1645 | return NULL((void*)0); | ||
1646 | |||
1647 | dict = PyObject_stgdict((PyObject *)obj); | ||
1648 | if (dict == NULL((void*)0)) { | ||
1649 | PyErr_SetString(PyExc_TypeError, | ||
1650 | "excepted ctypes instance"); | ||
1651 | return NULL((void*)0); | ||
1652 | } | ||
1653 | if (size < dict->size) { | ||
1654 | PyErr_Format(PyExc_ValueError, | ||
1655 | "minimum size is %zd", | ||
1656 | dict->size); | ||
1657 | return NULL((void*)0); | ||
1658 | } | ||
1659 | if (obj->b_needsfree == 0) { | ||
1660 | PyErr_Format(PyExc_ValueError, | ||
1661 | "Memory cannot be resized because this object doesn't own it"); | ||
1662 | return NULL((void*)0); | ||
1663 | } | ||
1664 | if (size <= sizeof(obj->b_value)) { | ||
1665 | /* internal default buffer is large enough */ | ||
1666 | obj->b_size = size; | ||
1667 | goto done; | ||
1668 | } | ||
1669 | if (obj->b_size <= sizeof(obj->b_value)) { | ||
1670 | /* We are currently using the objects default buffer, but it | ||
1671 | isn't large enough any more. */ | ||
1672 | void *ptr = PyMem_Malloc(size); | ||
1673 | if (ptr == NULL((void*)0)) | ||
1674 | return PyErr_NoMemory(); | ||
1675 | memset(ptr, 0, size)((__builtin_object_size (ptr, 0) != (size_t) -1) ? __builtin___memset_chk (ptr, 0, size, __builtin_object_size (ptr, 0)) : __inline_memset_chk (ptr, 0, size)); | ||
1676 | memmove(ptr, obj->b_ptr, obj->b_size)((__builtin_object_size (ptr, 0) != (size_t) -1) ? __builtin___memmove_chk (ptr, obj->b_ptr, obj->b_size, __builtin_object_size ( ptr, 0)) : __inline_memmove_chk (ptr, obj->b_ptr, obj-> b_size)); | ||
1677 | obj->b_ptr = ptr; | ||
1678 | obj->b_size = size; | ||
1679 | } else { | ||
1680 | void * ptr = PyMem_Realloc(obj->b_ptr, size); | ||
1681 | if (ptr == NULL((void*)0)) | ||
1682 | return PyErr_NoMemory(); | ||
1683 | obj->b_ptr = ptr; | ||
1684 | obj->b_size = size; | ||
1685 | } | ||
1686 | done: | ||
1687 | Py_INCREF(Py_None)( _Py_RefTotal++ , ((PyObject*)((&_Py_NoneStruct)))->ob_refcnt ++); | ||
1688 | return Py_None(&_Py_NoneStruct); | ||
1689 | } | ||
1690 | |||
1691 | static PyObject * | ||
1692 | unpickle(PyObject *self, PyObject *args) | ||
1693 | { | ||
1694 | PyObject *typ; | ||
1695 | PyObject *state; | ||
1696 | PyObject *result; | ||
1697 | PyObject *tmp; | ||
1698 | |||
1699 | if (!PyArg_ParseTuple(args, "OO", &typ, &state)) | ||
1700 | return NULL((void*)0); | ||
1701 | result = PyObject_CallMethod(typ, "__new__", "O", typ); | ||
1702 | if (result == NULL((void*)0)) | ||
1703 | return NULL((void*)0); | ||
1704 | tmp = PyObject_CallMethod(result, "__setstate__", "O", state); | ||
1705 | if (tmp == NULL((void*)0)) { | ||
1706 | Py_DECREF(result)do { if (_Py_RefTotal-- , --((PyObject*)(result))->ob_refcnt != 0) { if (((PyObject*)result)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1706, (PyObject *)(result)); } else _Py_Dealloc((PyObject * )(result)); } while (0); | ||
1707 | return NULL((void*)0); | ||
1708 | } | ||
1709 | Py_DECREF(tmp)do { if (_Py_RefTotal-- , --((PyObject*)(tmp))->ob_refcnt != 0) { if (((PyObject*)tmp)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1709, (PyObject *)(tmp)); } else _Py_Dealloc((PyObject *)(tmp )); } while (0); | ||
1710 | return result; | ||
1711 | } | ||
1712 | |||
1713 | static PyObject * | ||
1714 | POINTER(PyObject *self, PyObject *cls) | ||
1715 | { | ||
1716 | PyObject *result; | ||
1717 | PyTypeObject *typ; | ||
1718 | PyObject *key; | ||
1719 | char *buf; | ||
1720 | |||
1721 | result = PyDict_GetItem(_ctypes_ptrtype_cache, cls); | ||
1722 | if (result) { | ||
1723 | Py_INCREF(result)( _Py_RefTotal++ , ((PyObject*)(result))->ob_refcnt++); | ||
1724 | return result; | ||
1725 | } | ||
1726 | if (PyUnicode_CheckExact(cls)((((PyObject*)(cls))->ob_type) == &PyUnicode_Type)) { | ||
1727 | char *name = _PyUnicode_AsString(cls); | ||
1728 | buf = alloca(strlen(name) + 3 + 1)__builtin_alloca(strlen(name) + 3 + 1); | ||
1729 | sprintf(buf, "LP_%s", name)__builtin___sprintf_chk (buf, 0, __builtin_object_size (buf, 2 > 1), "LP_%s", name); | ||
1730 | result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type)(((PyObject*)(&PyCPointer_Type))->ob_type), | ||
1731 | "s(O){}", | ||
1732 | buf, | ||
1733 | &PyCPointer_Type); | ||
1734 | if (result == NULL((void*)0)) | ||
1735 | return result; | ||
1736 | key = PyLong_FromVoidPtr(result); | ||
1737 | } else if (PyType_Check(cls)((((((PyObject*)(cls))->ob_type))->tp_flags & ((1L<< 31))) != 0)) { | ||
1738 | typ = (PyTypeObject *)cls; | ||
1739 | buf = alloca(strlen(typ->tp_name) + 3 + 1)__builtin_alloca(strlen(typ->tp_name) + 3 + 1); | ||
1740 | sprintf(buf, "LP_%s", typ->tp_name)__builtin___sprintf_chk (buf, 0, __builtin_object_size (buf, 2 > 1), "LP_%s", typ->tp_name); | ||
1741 | result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type)(((PyObject*)(&PyCPointer_Type))->ob_type), | ||
1742 | "s(O){sO}", | ||
1743 | buf, | ||
1744 | &PyCPointer_Type, | ||
1745 | "_type_", cls); | ||
1746 | if (result == NULL((void*)0)) | ||
1747 | return result; | ||
1748 | Py_INCREF(cls)( _Py_RefTotal++ , ((PyObject*)(cls))->ob_refcnt++); | ||
1749 | key = cls; | ||
1750 | } else { | ||
1751 | PyErr_SetString(PyExc_TypeError, "must be a ctypes type"); | ||
1752 | return NULL((void*)0); | ||
1753 | } | ||
1754 | if (-1 == PyDict_SetItem(_ctypes_ptrtype_cache, key, result)) { | ||
1755 | Py_DECREF(result)do { if (_Py_RefTotal-- , --((PyObject*)(result))->ob_refcnt != 0) { if (((PyObject*)result)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1755, (PyObject *)(result)); } else _Py_Dealloc((PyObject * )(result)); } while (0); | ||
1756 | Py_DECREF(key)do { if (_Py_RefTotal-- , --((PyObject*)(key))->ob_refcnt != 0) { if (((PyObject*)key)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1756, (PyObject *)(key)); } else _Py_Dealloc((PyObject *)(key )); } while (0); | ||
1757 | return NULL((void*)0); | ||
1758 | } | ||
1759 | Py_DECREF(key)do { if (_Py_RefTotal-- , --((PyObject*)(key))->ob_refcnt != 0) { if (((PyObject*)key)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1759, (PyObject *)(key)); } else _Py_Dealloc((PyObject *)(key )); } while (0); | ||
1760 | return result; | ||
1761 | } | ||
1762 | |||
1763 | static PyObject * | ||
1764 | pointer(PyObject *self, PyObject *arg) | ||
1765 | { | ||
1766 | PyObject *result; | ||
1767 | PyObject *typ; | ||
1768 | |||
1769 | typ = PyDict_GetItem(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg)(((PyObject*)(arg))->ob_type)); | ||
1770 | if (typ) | ||
1771 | return PyObject_CallFunctionObjArgs(typ, arg, NULL((void*)0)); | ||
1772 | typ = POINTER(NULL((void*)0), (PyObject *)Py_TYPE(arg)(((PyObject*)(arg))->ob_type)); | ||
1773 | if (typ == NULL((void*)0)) | ||
1774 | return NULL((void*)0); | ||
1775 | result = PyObject_CallFunctionObjArgs(typ, arg, NULL((void*)0)); | ||
1776 | Py_DECREF(typ)do { if (_Py_RefTotal-- , --((PyObject*)(typ))->ob_refcnt != 0) { if (((PyObject*)typ)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1776, (PyObject *)(typ)); } else _Py_Dealloc((PyObject *)(typ )); } while (0); | ||
1777 | return result; | ||
1778 | } | ||
1779 | |||
1780 | static PyObject * | ||
1781 | buffer_info(PyObject *self, PyObject *arg) | ||
1782 | { | ||
1783 | StgDictObject *dict = PyType_stgdict(arg); | ||
1784 | PyObject *shape; | ||
1785 | Py_ssize_t i; | ||
1786 | |||
1787 | if (dict == NULL((void*)0)) | ||
1788 | dict = PyObject_stgdict(arg); | ||
1789 | if (dict == NULL((void*)0)) { | ||
1790 | PyErr_SetString(PyExc_TypeError, | ||
1791 | "not a ctypes type or object"); | ||
1792 | return NULL((void*)0); | ||
1793 | } | ||
1794 | shape = PyTuple_New(dict->ndim); | ||
1795 | if (shape == NULL((void*)0)) | ||
1796 | return NULL((void*)0); | ||
1797 | for (i = 0; i < (int)dict->ndim; ++i) | ||
1798 | PyTuple_SET_ITEM(shape, i, PyLong_FromSsize_t(dict->shape[i]))(((PyTupleObject *)(shape))->ob_item[i] = PyLong_FromSsize_t (dict->shape[i])); | ||
1799 | |||
1800 | if (PyErr_Occurred()) { | ||
1801 | Py_DECREF(shape)do { if (_Py_RefTotal-- , --((PyObject*)(shape))->ob_refcnt != 0) { if (((PyObject*)shape)->ob_refcnt < 0) _Py_NegativeRefcount ("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callproc.c" , 1801, (PyObject *)(shape)); } else _Py_Dealloc((PyObject *) (shape)); } while (0); | ||
1802 | return NULL((void*)0); | ||
1803 | } | ||
1804 | return Py_BuildValue("siN", dict->format, dict->ndim, shape); | ||
1805 | } | ||
1806 | |||
1807 | PyMethodDef _ctypes_module_methods[] = { | ||
1808 | {"get_errno", get_errno, METH_NOARGS0x0004}, | ||
1809 | {"set_errno", set_errno, METH_VARARGS0x0001}, | ||
1810 | {"POINTER", POINTER, METH_O0x0008 }, | ||
1811 | {"pointer", pointer, METH_O0x0008 }, | ||
1812 | {"_unpickle", unpickle, METH_VARARGS0x0001 }, | ||
1813 | {"buffer_info", buffer_info, METH_O0x0008, "Return buffer interface information"}, | ||
1814 | {"resize", resize, METH_VARARGS0x0001, "Resize the memory buffer of a ctypes instance"}, | ||
1815 | #ifdef MS_WIN32 | ||
1816 | {"get_last_error", get_last_error, METH_NOARGS0x0004}, | ||
1817 | {"set_last_error", set_last_error, METH_VARARGS0x0001}, | ||
1818 | {"CopyComPointer", copy_com_pointer, METH_VARARGS0x0001, copy_com_pointer_doc}, | ||
1819 | {"FormatError", format_error, METH_VARARGS0x0001, format_error_doc}, | ||
1820 | {"LoadLibrary", load_library, METH_VARARGS0x0001, load_library_doc}, | ||
1821 | {"FreeLibrary", free_library, METH_VARARGS0x0001, free_library_doc}, | ||
1822 | {"call_commethod", call_commethod, METH_VARARGS0x0001 }, | ||
1823 | {"_check_HRESULT", check_hresult, METH_VARARGS0x0001}, | ||
1824 | #else | ||
1825 | {"dlopen", py_dl_open, METH_VARARGS0x0001, | ||
1826 | "dlopen(name, flag={RTLD_GLOBAL|RTLD_LOCAL}) open a shared library"}, | ||
1827 | {"dlclose", py_dl_close, METH_VARARGS0x0001, "dlclose a library"}, | ||
1828 | {"dlsym", py_dl_sym, METH_VARARGS0x0001, "find symbol in shared library"}, | ||
1829 | #endif | ||
1830 | {"alignment", align_func, METH_O0x0008, alignment_doc}, | ||
1831 | {"sizeof", sizeof_func, METH_O0x0008, sizeof_doc}, | ||
1832 | {"byref", byref, METH_VARARGS0x0001, byref_doc}, | ||
1833 | {"addressof", addressof, METH_O0x0008, addressof_doc}, | ||
1834 | {"call_function", call_function, METH_VARARGS0x0001 }, | ||
1835 | {"call_cdeclfunction", call_cdeclfunction, METH_VARARGS0x0001 }, | ||
1836 | {"PyObj_FromPtr", My_PyObj_FromPtr, METH_VARARGS0x0001 }, | ||
1837 | {"Py_INCREF", My_Py_INCREF, METH_O0x0008 }, | ||
1838 | {"Py_DECREF", My_Py_DECREF, METH_O0x0008 }, | ||
1839 | {NULL((void*)0), NULL((void*)0)} /* Sentinel */ | ||
1840 | }; | ||
1841 | |||
1842 | /* | ||
1843 | Local Variables: | ||
1844 | compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~" | ||
1845 | End: | ||
1846 | */ |