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
This commit is contained in:
Raymond Hettinger 2004-11-05 07:02:59 +00:00
parent e0bdaefaf4
commit ec6eb369d5
5 changed files with 189 additions and 188 deletions

View file

@ -13,15 +13,13 @@
/* /*
** Helper routines for error codes and such. ** 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 */ extern PyObject *PyMac_OSErrException; /* Exception for OSErr */
PyObject *PyMac_GetOSErrException(void); /* Initialize & return it */ PyObject *PyMac_GetOSErrException(void); /* Initialize & return it */
PyObject *PyErr_Mac(PyObject *, int); /* Exception with a mac error */ PyObject *PyErr_Mac(PyObject *, int); /* Exception with a mac error */
PyObject *PyMac_Error(OSErr); /* Uses PyMac_GetOSErrException */ PyObject *PyMac_Error(OSErr); /* Uses PyMac_GetOSErrException */
extern OSErr PyMac_GetFullPathname(FSSpec *, char *, int); /* convert fsspec->path */ extern OSErr PyMac_GetFullPathname(FSSpec *, char *, int); /* convert
#ifdef WITH_NEXT_FRAMEWORK fsspec->path */
extern char *PyMac_GetAppletScriptFile(void); /* Return applet script file or NULL */
#endif
/* /*
** These conversion routines are defined in mactoolboxglue.c itself. ** 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 */ int PyMac_GetStr255(PyObject *, Str255); /* argument parser for Str255 */
PyObject *PyMac_BuildStr255(Str255); /* Convert Str255 to PyObject */ 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 */ 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 */ 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 */ int PyMac_GetEventRecord(PyObject *, EventRecord *); /* argument parser for
PyObject *PyMac_BuildEventRecord(EventRecord *); /* Convert EventRecord to PyObject */ EventRecord */
PyObject *PyMac_BuildEventRecord(EventRecord *); /* Convert EventRecord to
PyObject */
int PyMac_GetFixed(PyObject *, Fixed *); /* argument parser for Fixed */ 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 */ 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 ** The rest of the routines are implemented by extension modules. If they are

View file

@ -1253,6 +1253,49 @@ static PyObject *FSSpec_IsAliasFile(FSSpecObject *_self, PyObject *_args)
return _res; 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) static PyObject *FSSpec_as_pathname(FSSpecObject *_self, PyObject *_args)
{ {
PyObject *_res = NULL; PyObject *_res = NULL;
@ -1262,7 +1305,7 @@ static PyObject *FSSpec_as_pathname(FSSpecObject *_self, PyObject *_args)
if (!PyArg_ParseTuple(_args, "")) if (!PyArg_ParseTuple(_args, ""))
return NULL; return NULL;
err = PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf)); err = _PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf));
if ( err ) { if ( err ) {
PyMac_Error(err); PyMac_Error(err);
return NULL; return NULL;

View file

@ -338,11 +338,64 @@ static char geterr_doc[] = "Convert OSErr number to string";
static PyObject * static PyObject *
MacOS_GetErrorString(PyObject *self, PyObject *args) 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 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)"; static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";

View file

@ -28,57 +28,39 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Like strerror() but for Mac OS error numbers */ /* Like strerror() but for Mac OS error numbers */
char *PyMac_StrError(int err) char *
PyMac_StrError(int err)
{ {
static char buf[256]; static char buf[256];
Handle h; PyObject *m;
char *str; PyObject *rv;
static int errors_loaded;
m = PyImport_ImportModule("MacOS");
h = GetResource('Estr', err); if (!m) {
if (!h && !errors_loaded) { if (Py_VerboseFlag)
/* PyErr_Print();
** Attempt to open the resource file containing the PyErr_Clear();
** Estr resources. We ignore all errors. We also try rv = NULL;
** this only once. }
*/ else {
PyObject *m, *rv; rv = PyObject_CallMethod(m, "GetErrorString", "i", err);
errors_loaded = 1; if (!rv)
m = PyImport_ImportModule("macresource");
if (!m) {
if (Py_VerboseFlag)
PyErr_Print();
PyErr_Clear(); PyErr_Clear();
}
if (!rv) {
buf[0] = '\0';
}
else {
char *input = PyString_AsString(rv);
if (!input) {
PyErr_Clear();
buf[0] = '\0';
} else { } else {
rv = PyObject_CallMethod(m, "open_error_resource", ""); strncpy(buf, input, sizeof(buf) - 1);
if (!rv) { buf[sizeof(buf) - 1] = '\0';
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 buf; return buf;
} }
@ -125,124 +107,51 @@ PyMac_Error(OSErr err)
OSErr OSErr
PyMac_GetFullPathname(FSSpec *fss, char *path, int len) PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
{ {
FSRef fsr; PyObject *fs, *exc;
OSErr err; PyObject *rv = NULL;
char *input;
OSErr err = noErr;
*path = '\0'; *path = '\0';
err = FSpMakeFSRef(fss, &fsr);
if ( err == fnfErr ) { fs = PyMac_BuildFSSpec(fss);
/* FSSpecs can point to non-existing files, fsrefs can't. */ if (!fs)
FSSpec fss2; goto error;
int tocopy;
rv = PyObject_CallMethod(fs, "as_pathname", "");
err = FSMakeFSSpec(fss->vRefNum, fss->parID, "", &fss2); if (!rv)
if ( err ) return err; goto error;
err = FSpMakeFSRef(&fss2, &fsr);
if ( err ) return err; input = PyString_AsString(rv);
err = (OSErr)FSRefMakePath(&fsr, path, len-1); if (!input)
if ( err ) return err; goto error;
/* 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 strncpy(path, input, len - 1);
** encodings here. Will have to look this up at some point... path[len - 1] = '\0';
*/
strcat(path, "/"); Py_XDECREF(rv);
tocopy = fss->name[0]; Py_XDECREF(fs);
if ( strlen(path) + tocopy >= len ) return err;
tocopy = len - strlen(path) - 1;
if ( tocopy > 0 ) error:
strncat(path, fss->name+1, tocopy); exc = PyErr_Occurred();
} else { if (exc && PyErr_GivenExceptionMatches(exc,
if ( err ) return err; PyMac_GetOSErrException())) {
err = (OSErr)FSRefMakePath(&fsr, path, len); PyObject *args = PyObject_GetAttrString(exc, "args");
if ( err ) return err; if (args) {
char *ignore;
PyArg_ParseTuple(args, "is", &err, &ignore);
Py_XDECREF(args);
}
} }
return 0; if (err == noErr)
err = -1;
PyErr_Clear();
Py_XDECREF(rv);
Py_XDECREF(fs);
return err;
} }
#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;
}
/*
** 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;
}
return NULL;
}
#endif
/* Convert a 4-char string object argument to an OSType value */ /* Convert a 4-char string object argument to an OSType value */
int int
PyMac_GetOSType(PyObject *v, OSType *pr) PyMac_GetOSType(PyObject *v, OSType *pr)

View file

@ -1193,14 +1193,12 @@ then
fi fi
case "$enable_toolbox_glue" in case "$enable_toolbox_glue" in
yes) yes)
extra_frameworks="-framework CoreServices -framework Foundation"
extra_machdep_objs="Python/mactoolboxglue.o" 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, AC_DEFINE(USE_TOOLBOX_OBJECT_GLUE, 1,
[Define if you want to use MacPython modules on MacOSX in unix-Python.]) [Define if you want to use MacPython modules on MacOSX in unix-Python.])
;; ;;
*) *)
extra_frameworks=""
extra_machdep_objs="" extra_machdep_objs=""
extra_undefs="" extra_undefs=""
;; ;;
@ -1211,12 +1209,11 @@ AC_SUBST(LIBTOOL_CRUFT)
case $ac_sys_system/$ac_sys_release in case $ac_sys_system/$ac_sys_release in
Darwin/1.3*) Darwin/1.3*)
LIBTOOL_CRUFT="-lcc_dynamic -arch_only ppc" 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' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';;
Darwin/*) Darwin/*)
LIBTOOL_CRUFT="-lcc_dynamic -arch_only ppc" 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' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';;
esac esac
@ -1418,22 +1415,20 @@ then
Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";; Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";;
# -u libsys_s pulls in all symbols in libsys # -u libsys_s pulls in all symbols in libsys
Darwin/*) Darwin/*)
# -u __dummy makes the linker aware of the objc runtime # -u _PyMac_Error is needed to pull in the mac toolbox glue,
# in System.framework; otherwise, __objcInit (referenced in # which is
# 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
# not used by the core itself but which needs to be in the core so # not used by the core itself but which needs to be in the core so
# that dynamically loaded extension modules have access to it. # that dynamically loaded extension modules have access to it.
# -prebind is no longer used, because it actually seems to give a # -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 # slowdown in stead of a speedup, maybe due to the large number of
# dynamic loads Python does. # dynamic loads Python does.
LINKFORSHARED="$extra_undefs -framework System"
LINKFORSHARED="$extra_undefs"
if test "$enable_framework" if test "$enable_framework"
then then
LINKFORSHARED="$LINKFORSHARED -Wl,-F. -framework "'$(PYTHONFRAMEWORK)' LINKFORSHARED="$LINKFORSHARED -Wl,-F. -framework "'$(PYTHONFRAMEWORK)'
fi fi
LINKFORSHARED="$LINKFORSHARED $extra_frameworks";; LINKFORSHARED="$LINKFORSHARED";;
OpenUNIX*|UnixWare*) LINKFORSHARED="-Wl,-Bexport";; OpenUNIX*|UnixWare*) LINKFORSHARED="-Wl,-Bexport";;
SCO_SV*) LINKFORSHARED="-Wl,-Bexport";; SCO_SV*) LINKFORSHARED="-Wl,-Bexport";;
ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";; ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";;