Fix argument order in pure python version of nsmallest() and nlargest().
[python/dscho.git] / Python / mactoolboxglue.c
blob406b00238f0cf05b243c249fc0c1b05831b4ecc2
1 /***********************************************************
2 Copyright 1991-1997 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 not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
26 #include "Python.h"
27 #include "pymactoolbox.h"
30 /* Like strerror() but for Mac OS error numbers */
31 char *
32 PyMac_StrError(int err)
34 static char buf[256];
35 PyObject *m;
36 PyObject *rv;
38 m = PyImport_ImportModule("MacOS");
39 if (!m) {
40 if (Py_VerboseFlag)
41 PyErr_Print();
42 PyErr_Clear();
43 rv = NULL;
45 else {
46 rv = PyObject_CallMethod(m, "GetErrorString", "i", err);
47 if (!rv)
48 PyErr_Clear();
50 if (!rv) {
51 buf[0] = '\0';
53 else {
54 char *input = PyString_AsString(rv);
55 if (!input) {
56 PyErr_Clear();
57 buf[0] = '\0';
58 } else {
59 strncpy(buf, input, sizeof(buf) - 1);
60 buf[sizeof(buf) - 1] = '\0';
64 return buf;
67 /* Exception object shared by all Mac specific modules for Mac OS errors */
68 PyObject *PyMac_OSErrException;
70 /* Initialize and return PyMac_OSErrException */
71 PyObject *
72 PyMac_GetOSErrException(void)
74 if (PyMac_OSErrException == NULL)
75 PyMac_OSErrException = PyErr_NewException("MacOS.Error", NULL, NULL);
76 return PyMac_OSErrException;
79 /* Set a MAC-specific error from errno, and return NULL; return None if no error */
80 PyObject *
81 PyErr_Mac(PyObject *eobj, int err)
83 char *msg;
84 PyObject *v;
86 if (err == 0 && !PyErr_Occurred()) {
87 Py_INCREF(Py_None);
88 return Py_None;
90 if (err == -1 && PyErr_Occurred())
91 return NULL;
92 msg = PyMac_StrError(err);
93 v = Py_BuildValue("(is)", err, msg);
94 PyErr_SetObject(eobj, v);
95 Py_DECREF(v);
96 return NULL;
99 /* Call PyErr_Mac with PyMac_OSErrException */
100 PyObject *
101 PyMac_Error(OSErr err)
103 return PyErr_Mac(PyMac_GetOSErrException(), err);
107 OSErr
108 PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
110 PyObject *fs, *exc;
111 PyObject *rv = NULL;
112 char *input;
113 OSErr err = noErr;
115 *path = '\0';
117 fs = PyMac_BuildFSSpec(fss);
118 if (!fs)
119 goto error;
121 rv = PyObject_CallMethod(fs, "as_pathname", "");
122 if (!rv)
123 goto error;
125 input = PyString_AsString(rv);
126 if (!input)
127 goto error;
129 strncpy(path, input, len - 1);
130 path[len - 1] = '\0';
132 Py_XDECREF(rv);
133 Py_XDECREF(fs);
134 return err;
136 error:
137 exc = PyErr_Occurred();
138 if (exc && PyErr_GivenExceptionMatches(exc,
139 PyMac_GetOSErrException())) {
140 PyObject *args = PyObject_GetAttrString(exc, "args");
141 if (args) {
142 char *ignore;
143 PyArg_ParseTuple(args, "is", &err, &ignore);
144 Py_XDECREF(args);
147 if (err == noErr)
148 err = -1;
149 PyErr_Clear();
150 Py_XDECREF(rv);
151 Py_XDECREF(fs);
152 return err;
155 /* Convert a 4-char string object argument to an OSType value */
157 PyMac_GetOSType(PyObject *v, OSType *pr)
159 if (!PyString_Check(v) || PyString_Size(v) != 4) {
160 PyErr_SetString(PyExc_TypeError,
161 "OSType arg must be string of 4 chars");
162 return 0;
164 memcpy((char *)pr, PyString_AsString(v), 4);
165 return 1;
168 /* Convert an OSType value to a 4-char string object */
169 PyObject *
170 PyMac_BuildOSType(OSType t)
172 return PyString_FromStringAndSize((char *)&t, 4);
175 /* Convert an NumVersion value to a 4-element tuple */
176 PyObject *
177 PyMac_BuildNumVersion(NumVersion t)
179 return Py_BuildValue("(hhhh)", t.majorRev, t.minorAndBugRev, t.stage, t.nonRelRev);
183 /* Convert a Python string object to a Str255 */
185 PyMac_GetStr255(PyObject *v, Str255 pbuf)
187 int len;
188 if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
189 PyErr_SetString(PyExc_TypeError,
190 "Str255 arg must be string of at most 255 chars");
191 return 0;
193 pbuf[0] = len;
194 memcpy((char *)(pbuf+1), PyString_AsString(v), len);
195 return 1;
198 /* Convert a Str255 to a Python string object */
199 PyObject *
200 PyMac_BuildStr255(Str255 s)
202 if ( s == NULL ) {
203 PyErr_SetString(PyExc_SystemError, "Str255 pointer is NULL");
204 return NULL;
206 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
209 PyObject *
210 PyMac_BuildOptStr255(Str255 s)
212 if ( s == NULL ) {
213 Py_INCREF(Py_None);
214 return Py_None;
216 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
221 /* Convert a Python object to a Rect.
222 The object must be a (left, top, right, bottom) tuple.
223 (This differs from the order in the struct but is consistent with
224 the arguments to SetRect(), and also with STDWIN). */
226 PyMac_GetRect(PyObject *v, Rect *r)
228 return PyArg_Parse(v, "(hhhh)", &r->left, &r->top, &r->right, &r->bottom);
231 /* Convert a Rect to a Python object */
232 PyObject *
233 PyMac_BuildRect(Rect *r)
235 return Py_BuildValue("(hhhh)", r->left, r->top, r->right, r->bottom);
239 /* Convert a Python object to a Point.
240 The object must be a (h, v) tuple.
241 (This differs from the order in the struct but is consistent with
242 the arguments to SetPoint(), and also with STDWIN). */
244 PyMac_GetPoint(PyObject *v, Point *p)
246 return PyArg_Parse(v, "(hh)", &p->h, &p->v);
249 /* Convert a Point to a Python object */
250 PyObject *
251 PyMac_BuildPoint(Point p)
253 return Py_BuildValue("(hh)", p.h, p.v);
257 /* Convert a Python object to an EventRecord.
258 The object must be a (what, message, when, (v, h), modifiers) tuple. */
260 PyMac_GetEventRecord(PyObject *v, EventRecord *e)
262 return PyArg_Parse(v, "(Hkk(hh)H)",
263 &e->what,
264 &e->message,
265 &e->when,
266 &e->where.h,
267 &e->where.v,
268 &e->modifiers);
271 /* Convert a Rect to an EventRecord object */
272 PyObject *
273 PyMac_BuildEventRecord(EventRecord *e)
275 return Py_BuildValue("(hll(hh)h)",
276 e->what,
277 e->message,
278 e->when,
279 e->where.h,
280 e->where.v,
281 e->modifiers);
284 /* Convert Python object to Fixed */
286 PyMac_GetFixed(PyObject *v, Fixed *f)
288 double d;
290 if( !PyArg_Parse(v, "d", &d))
291 return 0;
292 *f = (Fixed)(d * 0x10000);
293 return 1;
296 /* Convert a Fixed to a Python object */
297 PyObject *
298 PyMac_BuildFixed(Fixed f)
300 double d;
302 d = f;
303 d = d / 0x10000;
304 return Py_BuildValue("d", d);
307 /* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
309 PyMac_Getwide(PyObject *v, wide *rv)
311 if (PyInt_Check(v)) {
312 rv->hi = 0;
313 rv->lo = PyInt_AsLong(v);
314 if( rv->lo & 0x80000000 )
315 rv->hi = -1;
316 return 1;
318 return PyArg_Parse(v, "(kk)", &rv->hi, &rv->lo);
322 PyObject *
323 PyMac_Buildwide(wide *w)
325 if ( (w->hi == 0 && (w->lo & 0x80000000) == 0) ||
326 (w->hi == -1 && (w->lo & 0x80000000) ) )
327 return PyInt_FromLong(w->lo);
328 return Py_BuildValue("(ll)", w->hi, w->lo);
331 #ifdef USE_TOOLBOX_OBJECT_GLUE
333 ** Glue together the toolbox objects.
335 ** Because toolbox modules interdepend on each other, they use each others
336 ** object types, on MacOSX/MachO this leads to the situation that they
337 ** cannot be dynamically loaded (or they would all have to be lumped into
338 ** a single .so, but this would be bad for extensibility).
340 ** This file defines wrappers for all the _New and _Convert functions,
341 ** which are the Py_BuildValue and PyArg_ParseTuple helpers. The wrappers
342 ** check an indirection function pointer, and if it isn't filled in yet
343 ** they import the appropriate module, whose init routine should fill in
344 ** the pointer.
347 #define GLUE_NEW(object, routinename, module) \
348 PyObject *(*PyMacGluePtr_##routinename)(object); \
350 PyObject *routinename(object cobj) { \
351 if (!PyMacGluePtr_##routinename) { \
352 if (!PyImport_ImportModule(module)) return NULL; \
353 if (!PyMacGluePtr_##routinename) { \
354 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
355 return NULL; \
358 return (*PyMacGluePtr_##routinename)(cobj); \
361 #define GLUE_CONVERT(object, routinename, module) \
362 int (*PyMacGluePtr_##routinename)(PyObject *, object *); \
364 int routinename(PyObject *pyobj, object *cobj) { \
365 if (!PyMacGluePtr_##routinename) { \
366 if (!PyImport_ImportModule(module)) return NULL; \
367 if (!PyMacGluePtr_##routinename) { \
368 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
369 return NULL; \
372 return (*PyMacGluePtr_##routinename)(pyobj, cobj); \
375 GLUE_NEW(FSSpec *, PyMac_BuildFSSpec, "Carbon.File")
376 GLUE_CONVERT(FSSpec, PyMac_GetFSSpec, "Carbon.File")
377 GLUE_NEW(FSRef *, PyMac_BuildFSRef, "Carbon.File")
378 GLUE_CONVERT(FSRef, PyMac_GetFSRef, "Carbon.File")
380 GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */
381 GLUE_NEW(AppleEvent *, AEDesc_NewBorrowed, "Carbon.AE")
382 GLUE_CONVERT(AppleEvent, AEDesc_Convert, "Carbon.AE")
384 GLUE_NEW(Component, CmpObj_New, "Carbon.Cm")
385 GLUE_CONVERT(Component, CmpObj_Convert, "Carbon.Cm")
386 GLUE_NEW(ComponentInstance, CmpInstObj_New, "Carbon.Cm")
387 GLUE_CONVERT(ComponentInstance, CmpInstObj_Convert, "Carbon.Cm")
389 GLUE_NEW(ControlHandle, CtlObj_New, "Carbon.Ctl")
390 GLUE_CONVERT(ControlHandle, CtlObj_Convert, "Carbon.Ctl")
392 GLUE_NEW(DialogPtr, DlgObj_New, "Carbon.Dlg")
393 GLUE_CONVERT(DialogPtr, DlgObj_Convert, "Carbon.Dlg")
394 GLUE_NEW(DialogPtr, DlgObj_WhichDialog, "Carbon.Dlg")
396 GLUE_NEW(DragReference, DragObj_New, "Carbon.Drag")
397 GLUE_CONVERT(DragReference, DragObj_Convert, "Carbon.Drag")
399 GLUE_NEW(ListHandle, ListObj_New, "Carbon.List")
400 GLUE_CONVERT(ListHandle, ListObj_Convert, "Carbon.List")
402 GLUE_NEW(MenuHandle, MenuObj_New, "Carbon.Menu")
403 GLUE_CONVERT(MenuHandle, MenuObj_Convert, "Carbon.Menu")
405 GLUE_NEW(GrafPtr, GrafObj_New, "Carbon.Qd")
406 GLUE_CONVERT(GrafPtr, GrafObj_Convert, "Carbon.Qd")
407 GLUE_NEW(BitMapPtr, BMObj_New, "Carbon.Qd")
408 GLUE_CONVERT(BitMapPtr, BMObj_Convert, "Carbon.Qd")
409 GLUE_NEW(RGBColor *, QdRGB_New, "Carbon.Qd") /* XXXX Why? */
410 GLUE_CONVERT(RGBColor, QdRGB_Convert, "Carbon.Qd")
412 GLUE_NEW(GWorldPtr, GWorldObj_New, "Carbon.Qdoffs")
413 GLUE_CONVERT(GWorldPtr, GWorldObj_Convert, "Carbon.Qdoffs")
415 GLUE_NEW(Track, TrackObj_New, "Carbon.Qt")
416 GLUE_CONVERT(Track, TrackObj_Convert, "Carbon.Qt")
417 GLUE_NEW(Movie, MovieObj_New, "Carbon.Qt")
418 GLUE_CONVERT(Movie, MovieObj_Convert, "Carbon.Qt")
419 GLUE_NEW(MovieController, MovieCtlObj_New, "Carbon.Qt")
420 GLUE_CONVERT(MovieController, MovieCtlObj_Convert, "Carbon.Qt")
421 GLUE_NEW(TimeBase, TimeBaseObj_New, "Carbon.Qt")
422 GLUE_CONVERT(TimeBase, TimeBaseObj_Convert, "Carbon.Qt")
423 GLUE_NEW(UserData, UserDataObj_New, "Carbon.Qt")
424 GLUE_CONVERT(UserData, UserDataObj_Convert, "Carbon.Qt")
425 GLUE_NEW(Media, MediaObj_New, "Carbon.Qt")
426 GLUE_CONVERT(Media, MediaObj_Convert, "Carbon.Qt")
428 GLUE_NEW(Handle, ResObj_New, "Carbon.Res")
429 GLUE_CONVERT(Handle, ResObj_Convert, "Carbon.Res")
430 GLUE_NEW(Handle, OptResObj_New, "Carbon.Res")
431 GLUE_CONVERT(Handle, OptResObj_Convert, "Carbon.Res")
433 GLUE_NEW(TEHandle, TEObj_New, "Carbon.TE")
434 GLUE_CONVERT(TEHandle, TEObj_Convert, "Carbon.TE")
436 GLUE_NEW(WindowPtr, WinObj_New, "Carbon.Win")
437 GLUE_CONVERT(WindowPtr, WinObj_Convert, "Carbon.Win")
438 GLUE_NEW(WindowPtr, WinObj_WhichWindow, "Carbon.Win")
440 GLUE_CONVERT(CFTypeRef, CFObj_Convert, "Carbon.CF")
441 GLUE_NEW(CFTypeRef, CFObj_New, "Carbon.CF")
443 GLUE_CONVERT(CFTypeRef, CFTypeRefObj_Convert, "Carbon.CF")
444 GLUE_NEW(CFTypeRef, CFTypeRefObj_New, "Carbon.CF")
446 GLUE_CONVERT(CFStringRef, CFStringRefObj_Convert, "Carbon.CF")
447 GLUE_NEW(CFStringRef, CFStringRefObj_New, "Carbon.CF")
448 GLUE_CONVERT(CFMutableStringRef, CFMutableStringRefObj_Convert, "Carbon.CF")
449 GLUE_NEW(CFMutableStringRef, CFMutableStringRefObj_New, "Carbon.CF")
451 GLUE_CONVERT(CFArrayRef, CFArrayRefObj_Convert, "Carbon.CF")
452 GLUE_NEW(CFArrayRef, CFArrayRefObj_New, "Carbon.CF")
453 GLUE_CONVERT(CFMutableArrayRef, CFMutableArrayRefObj_Convert, "Carbon.CF")
454 GLUE_NEW(CFMutableArrayRef, CFMutableArrayRefObj_New, "Carbon.CF")
456 GLUE_CONVERT(CFDictionaryRef, CFDictionaryRefObj_Convert, "Carbon.CF")
457 GLUE_NEW(CFDictionaryRef, CFDictionaryRefObj_New, "Carbon.CF")
458 GLUE_CONVERT(CFMutableDictionaryRef, CFMutableDictionaryRefObj_Convert, "Carbon.CF")
459 GLUE_NEW(CFMutableDictionaryRef, CFMutableDictionaryRefObj_New, "Carbon.CF")
461 GLUE_CONVERT(CFURLRef, CFURLRefObj_Convert, "Carbon.CF")
462 GLUE_CONVERT(CFURLRef, OptionalCFURLRefObj_Convert, "Carbon.CF")
463 GLUE_NEW(CFURLRef, CFURLRefObj_New, "Carbon.CF")
465 #endif /* USE_TOOLBOX_OBJECT_GLUE */