From ec6eb369d518994e9616e0515056ac0f2cff00a6 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 5 Nov 2004 07:02:59 +0000 Subject: SF patch #1035255: Remove CoreServices / CoreFoundation dependencies in core (Contributed by Bob Ippolito.) This patch trims down the Python core on Darwin by making it independent of CoreFoundation and CoreServices. It does this by: Changed linker flags in configure/configure.in Removed the unused PyMac_GetAppletScriptFile Moved the implementation of PyMac_StrError to the MacOS module Moved the implementation of PyMac_GetFullPathname to the Carbon.File module --- Include/pymactoolbox.h | 27 ++--- Mac/Modules/file/_Filemodule.c | 45 ++++++++- Mac/Modules/macosmodule.c | 59 ++++++++++- Python/mactoolboxglue.c | 225 ++++++++++++----------------------------- configure.in | 19 ++-- 5 files changed, 188 insertions(+), 187 deletions(-) diff --git a/Include/pymactoolbox.h b/Include/pymactoolbox.h index 403ddf5..92799e9 100644 --- a/Include/pymactoolbox.h +++ b/Include/pymactoolbox.h @@ -13,15 +13,13 @@ /* ** Helper routines for error codes and such. */ -char *PyMac_StrError(int); /* strerror with mac errors */ +char *PyMac_StrError(int); /* strerror with mac errors */ extern PyObject *PyMac_OSErrException; /* Exception for OSErr */ PyObject *PyMac_GetOSErrException(void); /* Initialize & return it */ PyObject *PyErr_Mac(PyObject *, int); /* Exception with a mac error */ -PyObject *PyMac_Error(OSErr); /* Uses PyMac_GetOSErrException */ -extern OSErr PyMac_GetFullPathname(FSSpec *, char *, int); /* convert fsspec->path */ -#ifdef WITH_NEXT_FRAMEWORK -extern char *PyMac_GetAppletScriptFile(void); /* Return applet script file or NULL */ -#endif +PyObject *PyMac_Error(OSErr); /* Uses PyMac_GetOSErrException */ +extern OSErr PyMac_GetFullPathname(FSSpec *, char *, int); /* convert + fsspec->path */ /* ** These conversion routines are defined in mactoolboxglue.c itself. */ @@ -32,21 +30,24 @@ PyObject *PyMac_BuildNumVersion(NumVersion);/* Convert NumVersion to PyObject */ int PyMac_GetStr255(PyObject *, Str255); /* argument parser for Str255 */ PyObject *PyMac_BuildStr255(Str255); /* Convert Str255 to PyObject */ -PyObject *PyMac_BuildOptStr255(Str255); /* Convert Str255 to PyObject, NULL to None */ +PyObject *PyMac_BuildOptStr255(Str255); /* Convert Str255 to PyObject, + NULL to None */ int PyMac_GetRect(PyObject *, Rect *); /* argument parser for Rect */ -PyObject *PyMac_BuildRect(Rect *); /* Convert Rect to PyObject */ +PyObject *PyMac_BuildRect(Rect *); /* Convert Rect to PyObject */ int PyMac_GetPoint(PyObject *, Point *); /* argument parser for Point */ -PyObject *PyMac_BuildPoint(Point); /* Convert Point to PyObject */ +PyObject *PyMac_BuildPoint(Point); /* Convert Point to PyObject */ -int PyMac_GetEventRecord(PyObject *, EventRecord *); /* argument parser for EventRecord */ -PyObject *PyMac_BuildEventRecord(EventRecord *); /* Convert EventRecord to PyObject */ +int PyMac_GetEventRecord(PyObject *, EventRecord *); /* argument parser for + EventRecord */ +PyObject *PyMac_BuildEventRecord(EventRecord *); /* Convert EventRecord to + PyObject */ int PyMac_GetFixed(PyObject *, Fixed *); /* argument parser for Fixed */ -PyObject *PyMac_BuildFixed(Fixed); /* Convert Fixed to PyObject */ +PyObject *PyMac_BuildFixed(Fixed); /* Convert Fixed to PyObject */ int PyMac_Getwide(PyObject *, wide *); /* argument parser for wide */ -PyObject *PyMac_Buildwide(wide *); /* Convert wide to PyObject */ +PyObject *PyMac_Buildwide(wide *); /* Convert wide to PyObject */ /* ** The rest of the routines are implemented by extension modules. If they are diff --git a/Mac/Modules/file/_Filemodule.c b/Mac/Modules/file/_Filemodule.c index 79929c5..c1b4310 100644 --- a/Mac/Modules/file/_Filemodule.c +++ b/Mac/Modules/file/_Filemodule.c @@ -1253,6 +1253,49 @@ static PyObject *FSSpec_IsAliasFile(FSSpecObject *_self, PyObject *_args) return _res; } +static OSErr +_PyMac_GetFullPathname(FSSpec *fss, char *path, int len) +{ + FSRef fsr; + OSErr err; + + *path = '\0'; + err = FSpMakeFSRef(fss, &fsr); + if (err == fnfErr) { + /* FSSpecs can point to non-existing files, fsrefs can't. */ + FSSpec fss2; + int tocopy; + + err = FSMakeFSSpec(fss->vRefNum, fss->parID, "", &fss2); + if (err) + return err; + err = FSpMakeFSRef(&fss2, &fsr); + if (err) + return err; + err = (OSErr)FSRefMakePath(&fsr, path, len-1); + if (err) + return err; + /* This part is not 100% safe: we append the filename part, but + ** I'm not sure that we don't run afoul of the various 8bit + ** encodings here. Will have to look this up at some point... + */ + strcat(path, "/"); + tocopy = fss->name[0]; + if ((strlen(path) + tocopy) >= len) + tocopy = len - strlen(path) - 1; + if (tocopy > 0) + strncat(path, fss->name+1, tocopy); + } + else { + if (err) + return err; + err = (OSErr)FSRefMakePath(&fsr, path, len); + if (err) + return err; + } + return 0; +} + static PyObject *FSSpec_as_pathname(FSSpecObject *_self, PyObject *_args) { PyObject *_res = NULL; @@ -1262,7 +1305,7 @@ static PyObject *FSSpec_as_pathname(FSSpecObject *_self, PyObject *_args) if (!PyArg_ParseTuple(_args, "")) return NULL; - err = PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf)); + err = _PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf)); if ( err ) { PyMac_Error(err); return NULL; diff --git a/Mac/Modules/macosmodule.c b/Mac/Modules/macosmodule.c index 298aa0c..ed86fd0 100644 --- a/Mac/Modules/macosmodule.c +++ b/Mac/Modules/macosmodule.c @@ -338,11 +338,64 @@ static char geterr_doc[] = "Convert OSErr number to string"; static PyObject * MacOS_GetErrorString(PyObject *self, PyObject *args) { - int errn; + int err; + char buf[256]; + Handle h; + char *str; + static int errors_loaded; - if (!PyArg_ParseTuple(args, "i", &errn)) + if (!PyArg_ParseTuple(args, "i", &err)) return NULL; - return Py_BuildValue("s", PyMac_StrError(errn)); + + h = GetResource('Estr', err); + if (!h && !errors_loaded) { + /* + ** Attempt to open the resource file containing the + ** Estr resources. We ignore all errors. We also try + ** this only once. + */ + PyObject *m, *rv; + errors_loaded = 1; + + m = PyImport_ImportModule("macresource"); + if (!m) { + if (Py_VerboseFlag) + PyErr_Print(); + PyErr_Clear(); + } + else { + rv = PyObject_CallMethod(m, "open_error_resource", ""); + if (!rv) { + if (Py_VerboseFlag) + PyErr_Print(); + PyErr_Clear(); + } + else { + Py_DECREF(rv); + /* And try again... */ + h = GetResource('Estr', err); + } + } + } + /* + ** Whether the code above succeeded or not, we won't try + ** again. + */ + errors_loaded = 1; + + if (h) { + HLock(h); + str = (char *)*h; + memcpy(buf, str+1, (unsigned char)str[0]); + buf[(unsigned char)str[0]] = '\0'; + HUnlock(h); + ReleaseResource(h); + } + else { + PyOS_snprintf(buf, sizeof(buf), "Mac OS error code %d", err); + } + + return Py_BuildValue("s", buf); } static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)"; diff --git a/Python/mactoolboxglue.c b/Python/mactoolboxglue.c index ba15062..406b002 100644 --- a/Python/mactoolboxglue.c +++ b/Python/mactoolboxglue.c @@ -28,57 +28,39 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* Like strerror() but for Mac OS error numbers */ -char *PyMac_StrError(int err) +char * +PyMac_StrError(int err) { static char buf[256]; - Handle h; - char *str; - static int errors_loaded; - - h = GetResource('Estr', err); - if (!h && !errors_loaded) { - /* - ** Attempt to open the resource file containing the - ** Estr resources. We ignore all errors. We also try - ** this only once. - */ - PyObject *m, *rv; - errors_loaded = 1; - - m = PyImport_ImportModule("macresource"); - if (!m) { - if (Py_VerboseFlag) - PyErr_Print(); + PyObject *m; + PyObject *rv; + + m = PyImport_ImportModule("MacOS"); + if (!m) { + if (Py_VerboseFlag) + PyErr_Print(); + PyErr_Clear(); + rv = NULL; + } + else { + rv = PyObject_CallMethod(m, "GetErrorString", "i", err); + if (!rv) PyErr_Clear(); + } + if (!rv) { + buf[0] = '\0'; + } + else { + char *input = PyString_AsString(rv); + if (!input) { + PyErr_Clear(); + buf[0] = '\0'; } else { - rv = PyObject_CallMethod(m, "open_error_resource", ""); - if (!rv) { - if (Py_VerboseFlag) - PyErr_Print(); - PyErr_Clear(); - } else { - Py_DECREF(rv); - /* And try again... */ - h = GetResource('Estr', err); - } + strncpy(buf, input, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; } } - /* - ** Whether the code above succeeded or not, we won't try - ** again. - */ - errors_loaded = 1; - - if ( h ) { - HLock(h); - str = (char *)*h; - memcpy(buf, str+1, (unsigned char)str[0]); - buf[(unsigned char)str[0]] = '\0'; - HUnlock(h); - ReleaseResource(h); - } else { - PyOS_snprintf(buf, sizeof(buf), "Mac OS error code %d", err); - } + return buf; } @@ -125,124 +107,51 @@ PyMac_Error(OSErr err) OSErr PyMac_GetFullPathname(FSSpec *fss, char *path, int len) { - FSRef fsr; - OSErr err; - - *path = '\0'; - err = FSpMakeFSRef(fss, &fsr); - if ( err == fnfErr ) { - /* FSSpecs can point to non-existing files, fsrefs can't. */ - FSSpec fss2; - int tocopy; - - err = FSMakeFSSpec(fss->vRefNum, fss->parID, "", &fss2); - if ( err ) return err; - err = FSpMakeFSRef(&fss2, &fsr); - if ( err ) return err; - err = (OSErr)FSRefMakePath(&fsr, path, len-1); - if ( err ) return err; - /* This part is not 100% safe: we append the filename part, but - ** I'm not sure that we don't run afoul of the various 8bit - ** encodings here. Will have to look this up at some point... - */ - strcat(path, "/"); - tocopy = fss->name[0]; - if ( strlen(path) + tocopy >= len ) - tocopy = len - strlen(path) - 1; - if ( tocopy > 0 ) - strncat(path, fss->name+1, tocopy); - } else { - if ( err ) return err; - err = (OSErr)FSRefMakePath(&fsr, path, len); - if ( err ) return err; - } - return 0; -} - + PyObject *fs, *exc; + PyObject *rv = NULL; + char *input; + OSErr err = noErr; -#ifdef WITH_NEXT_FRAMEWORK -/* -** In a bundle, find a file "resourceName" of type "resourceType". Return the -** full pathname in "resourceURLCstr". -*/ -static int -locateResourcePy(CFStringRef resourceType, CFStringRef resourceName, char *resourceURLCStr, int length) -{ - CFBundleRef mainBundle = NULL; - CFURLRef URL, absoluteURL; - CFStringRef filenameString, filepathString; - CFIndex size, i; - CFArrayRef arrayRef = NULL; - int success = 0; - - CFURLPathStyle thePathStyle = kCFURLPOSIXPathStyle; - - /* Get a reference to our main bundle */ - mainBundle = CFBundleGetMainBundle(); - - /* If we are running inside a bundle, look through it. Otherwise, do nothing. */ - if (mainBundle) { - - /* Look for py files in the main bundle by type */ - arrayRef = CFBundleCopyResourceURLsOfType( mainBundle, - resourceType, - NULL ); - - /* See if there are any filename matches */ - size = CFArrayGetCount(arrayRef); - for (i = 0; i < size; i++) { - URL = CFArrayGetValueAtIndex(arrayRef, i); - filenameString = CFURLCopyLastPathComponent(URL); - if (CFStringCompare(filenameString, resourceName, 0) == kCFCompareEqualTo) { - /* We found a match, get the file's full path */ - absoluteURL = CFURLCopyAbsoluteURL(URL); - filepathString = CFURLCopyFileSystemPath(absoluteURL, thePathStyle); - CFRelease(absoluteURL); - - /* Copy the full path into the caller's character buffer */ - success = CFStringGetCString(filepathString, resourceURLCStr, length, - kCFStringEncodingMacRoman); - - CFRelease(filepathString); - } - CFRelease(filenameString); - } - CFRelease(arrayRef); - } - return success; -} + *path = '\0'; -/* -** iff we are running in a .app framework then we could be -** the main program for an applet. In that case, return the -** script filename for the applet. -** Otherwise return NULL. -*/ -char * -PyMac_GetAppletScriptFile(void) -{ - static char scriptpath[1024]; - - /* First we see whether we have __rawmain__.py and run that if it - ** is there. This is used for applets that want sys.argv to be - ** unix-like: __rawmain__ will construct it (from the initial appleevent) - ** and then call __main__.py. - */ - if (locateResourcePy(CFSTR("py"), CFSTR("__rawmain__.py"), scriptpath, 1024)) { - return scriptpath; - } else if (locateResourcePy(CFSTR("pyc"), CFSTR("__rawmain__.pyc"), scriptpath, 1024)) { - return scriptpath; - } else if (locateResourcePy(CFSTR("py"), CFSTR("__main__.py"), scriptpath, 1024)) { - return scriptpath; - } else if (locateResourcePy(CFSTR("pyc"), CFSTR("__main__.pyc"), scriptpath, 1024)) { - return scriptpath; + fs = PyMac_BuildFSSpec(fss); + if (!fs) + goto error; + + rv = PyObject_CallMethod(fs, "as_pathname", ""); + if (!rv) + goto error; + + input = PyString_AsString(rv); + if (!input) + goto error; + + strncpy(path, input, len - 1); + path[len - 1] = '\0'; + + Py_XDECREF(rv); + Py_XDECREF(fs); + return err; + + error: + exc = PyErr_Occurred(); + if (exc && PyErr_GivenExceptionMatches(exc, + PyMac_GetOSErrException())) { + PyObject *args = PyObject_GetAttrString(exc, "args"); + if (args) { + char *ignore; + PyArg_ParseTuple(args, "is", &err, &ignore); + Py_XDECREF(args); + } } - return NULL; + if (err == noErr) + err = -1; + PyErr_Clear(); + Py_XDECREF(rv); + Py_XDECREF(fs); + return err; } -#endif - - /* Convert a 4-char string object argument to an OSType value */ int PyMac_GetOSType(PyObject *v, OSType *pr) diff --git a/configure.in b/configure.in index cc98881..d563640 100644 --- a/configure.in +++ b/configure.in @@ -1193,14 +1193,12 @@ then fi case "$enable_toolbox_glue" in yes) - extra_frameworks="-framework CoreServices -framework Foundation" extra_machdep_objs="Python/mactoolboxglue.o" - extra_undefs="-u __dummy -u _PyMac_Error" + extra_undefs="-u _PyMac_Error" AC_DEFINE(USE_TOOLBOX_OBJECT_GLUE, 1, [Define if you want to use MacPython modules on MacOSX in unix-Python.]) ;; *) - extra_frameworks="" extra_machdep_objs="" extra_undefs="" ;; @@ -1211,12 +1209,11 @@ AC_SUBST(LIBTOOL_CRUFT) case $ac_sys_system/$ac_sys_release in Darwin/1.3*) LIBTOOL_CRUFT="-lcc_dynamic -arch_only ppc" - LIBTOOL_CRUFT="$LIBTOOL_CRUFT $extra_frameworks" LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; Darwin/*) LIBTOOL_CRUFT="-lcc_dynamic -arch_only ppc" - LIBTOOL_CRUFT="$LIBTOOL_CRUFT $extra_frameworks" + LIBTOOL_CRUFT="$LIBTOOL_CRUFT" LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; esac @@ -1418,22 +1415,20 @@ then Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";; # -u libsys_s pulls in all symbols in libsys Darwin/*) - # -u __dummy makes the linker aware of the objc runtime - # in System.framework; otherwise, __objcInit (referenced in - # crt1.o) gets erroneously defined as common, which breaks dynamic - # loading of any modules which reference it in System.framework. - # -u _PyMac_Error is needed to pull in the mac toolbox glue, which is + # -u _PyMac_Error is needed to pull in the mac toolbox glue, + # which is # not used by the core itself but which needs to be in the core so # that dynamically loaded extension modules have access to it. # -prebind is no longer used, because it actually seems to give a # slowdown in stead of a speedup, maybe due to the large number of # dynamic loads Python does. - LINKFORSHARED="$extra_undefs -framework System" + + LINKFORSHARED="$extra_undefs" if test "$enable_framework" then LINKFORSHARED="$LINKFORSHARED -Wl,-F. -framework "'$(PYTHONFRAMEWORK)' fi - LINKFORSHARED="$LINKFORSHARED $extra_frameworks";; + LINKFORSHARED="$LINKFORSHARED";; OpenUNIX*|UnixWare*) LINKFORSHARED="-Wl,-Bexport";; SCO_SV*) LINKFORSHARED="-Wl,-Bexport";; ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";; -- cgit v0.12