|  | 
 | /* Support for dynamic loading of extension modules */ | 
 |  | 
 | #include "Python.h" | 
 | #include "importdl.h" | 
 |  | 
 | #include <Aliases.h> | 
 | #include <CodeFragments.h> | 
 | #ifdef USE_GUSI1 | 
 | #include "TFileSpec.h"		/* for Path2FSSpec() */ | 
 | #endif | 
 | #include <Files.h> | 
 | #include <TextUtils.h> | 
 | #include "macdefs.h" | 
 | #include "macglue.h" | 
 |  | 
 |  | 
 | const struct filedescr _PyImport_DynLoadFiletab[] = { | 
 | 	{".slb", "rb", C_EXTENSION}, | 
 | #ifdef __CFM68K__ | 
 | 	{".CFM68K.slb", "rb", C_EXTENSION}, | 
 | #else | 
 | #if TARGET_API_MAC_CARBON | 
 | 	{".carbon.slb", "rb", C_EXTENSION}, | 
 | #else | 
 | 	{".ppc.slb", "rb", C_EXTENSION}, | 
 | #endif | 
 | #endif | 
 | 	{0, 0} | 
 | }; | 
 |  | 
 |  | 
 | dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, | 
 | 				    const char *pathname, FILE *fp) | 
 | { | 
 | 	dl_funcptr p; | 
 | 	char funcname[258]; | 
 |  | 
 | 	/* | 
 | 	** Dynamic loading of CFM shared libraries on the Mac.  The | 
 | 	** code has become more convoluted than it was, because we | 
 | 	** want to be able to put multiple modules in a single | 
 | 	** file. For this reason, we have to determine the fragment | 
 | 	** name, and we cannot use the library entry point but we have | 
 | 	** to locate the correct init routine "by hand". | 
 | 	*/ | 
 | 	FSSpec libspec; | 
 | 	CFragConnectionID connID; | 
 | 	Ptr mainAddr; | 
 | 	Str255 errMessage; | 
 | 	OSErr err; | 
 | #ifndef USE_GUSI1 | 
 | 	Boolean isfolder, didsomething; | 
 | #endif | 
 | 	char buf[512]; | 
 | 	Str63 fragname; | 
 | 	Ptr symAddr; | 
 | 	CFragSymbolClass class; | 
 | 		 | 
 | 	/* First resolve any aliases to find the real file */ | 
 | #ifdef USE_GUSI1 | 
 | 	err = Path2FSSpec(pathname, &libspec); | 
 | #else | 
 | 	c2pstrcpy((unsigned char *)buf, pathname); | 
 | 	(void)FSMakeFSSpec(0, 0, (unsigned char *)buf, &libspec); | 
 | 	err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething); | 
 | #endif | 
 | 	if ( err ) { | 
 | 		sprintf(buf, "%.200s: %.200s", pathname, PyMac_StrError(err)); | 
 | 		PyErr_SetString(PyExc_ImportError, buf); | 
 | 		return NULL; | 
 | 	} | 
 | 	/* Next, determine the fragment name, | 
 | 	   by stripping '.slb' and 'module' */ | 
 | 	memcpy(fragname+1, libspec.name+1, libspec.name[0]); | 
 | 	fragname[0] = libspec.name[0]; | 
 | 	if( strncmp((char *)(fragname+1+fragname[0]-4), | 
 | 		    ".slb", 4) == 0 ) | 
 | 		fragname[0] -= 4; | 
 | 	if ( strncmp((char *)(fragname+1+fragname[0]-6), | 
 | 		     "module", 6) == 0 ) | 
 | 		fragname[0] -= 6; | 
 | 	/* Load the fragment | 
 | 	   (or return the connID if it is already loaded */ | 
 | 	err = GetDiskFragment(&libspec, 0, 0, fragname,  | 
 | 			      kLoadCFrag, &connID, &mainAddr, | 
 | 			      errMessage); | 
 | 	if ( err == cfragImportTooOldErr || err == cfragImportTooNewErr ) { | 
 | 		/* | 
 | 		** Special-case code: if PythonCore is too old or too new this means | 
 | 		** the dynamic module was meant for a different Python. | 
 | 		*/ | 
 | 		if (errMessage[0] == 10 && strncmp((char *)errMessage+1, "PythonCore", 10) == 0 ) { | 
 | 			sprintf(buf, "Dynamic module was built for %s version of MacPython", | 
 | 				(err == cfragImportTooOldErr ? "a newer" : "an older")); | 
 | 			PyErr_SetString(PyExc_ImportError, buf); | 
 | 			return NULL; | 
 | 		} | 
 | 	} | 
 | 	if ( err ) { | 
 | 		sprintf(buf, "%.*s: %.200s", | 
 | 			errMessage[0], errMessage+1, | 
 | 			PyMac_StrError(err)); | 
 | 		PyErr_SetString(PyExc_ImportError, buf); | 
 | 		return NULL; | 
 | 	} | 
 | 	/* Locate the address of the correct init function */ | 
 | 	sprintf(funcname, "init%.200s", shortname); | 
 | 	err = FindSymbol(connID, Pstring(funcname), &symAddr, &class); | 
 | 	if ( err ) { | 
 | 		sprintf(buf, "%s: %.200s", | 
 | 			funcname, PyMac_StrError(err)); | 
 | 		PyErr_SetString(PyExc_ImportError, buf); | 
 | 		return NULL; | 
 | 	} | 
 | 	p = (dl_funcptr)symAddr; | 
 |  | 
 | 	return p; | 
 | } |