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.
*/
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

View file

@ -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;

View file

@ -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)";

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 */
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;
PyObject *fs, *exc;
PyObject *rv = NULL;
char *input;
OSErr err = noErr;
*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;
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 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 */
int
PyMac_GetOSType(PyObject *v, OSType *pr)

View file

@ -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";;