| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Support for dynamic loading of extension modules */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | #include "importdl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <Aliases.h>
 | 
					
						
							|  |  |  | #include <CodeFragments.h>
 | 
					
						
							| 
									
										
										
										
											2000-04-24 15:08:18 +00:00
										 |  |  | #ifdef USE_GUSI1
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | #include "TFileSpec.h"		/* for Path2FSSpec() */
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #include <Files.h>
 | 
					
						
							| 
									
										
										
										
											2000-12-12 22:36:57 +00:00
										 |  |  | #include <TextUtils.h>
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | #include "macdefs.h"
 | 
					
						
							|  |  |  | #include "macglue.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const struct filedescr _PyImport_DynLoadFiletab[] = { | 
					
						
							|  |  |  | 	{".slb", "rb", C_EXTENSION}, | 
					
						
							|  |  |  | #ifdef __CFM68K__
 | 
					
						
							|  |  |  | 	{".CFM68K.slb", "rb", C_EXTENSION}, | 
					
						
							| 
									
										
										
										
											2001-01-15 16:00:40 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2001-01-19 23:34:06 +00:00
										 |  |  | #if TARGET_API_MAC_CARBON
 | 
					
						
							| 
									
										
										
										
											2001-01-15 16:00:40 +00:00
										 |  |  | 	{".carbon.slb", "rb", C_EXTENSION}, | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	{".ppc.slb", "rb", C_EXTENSION}, | 
					
						
							| 
									
										
										
										
											2001-01-15 16:00:40 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	{0, 0} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-12-22 14:09:35 +00:00
										 |  |  | dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 				    const char *pathname, FILE *fp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	dl_funcptr p; | 
					
						
							| 
									
										
										
										
											1999-12-22 14:09:35 +00:00
										 |  |  | 	char funcname[258]; | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	** 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; | 
					
						
							| 
									
										
										
										
											2000-04-24 15:08:18 +00:00
										 |  |  | #ifndef USE_GUSI1
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	Boolean isfolder, didsomething; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	char buf[512]; | 
					
						
							|  |  |  | 	Str63 fragname; | 
					
						
							|  |  |  | 	Ptr symAddr; | 
					
						
							|  |  |  | 	CFragSymbolClass class; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	/* First resolve any aliases to find the real file */ | 
					
						
							| 
									
										
										
										
											2000-04-24 15:08:18 +00:00
										 |  |  | #ifdef USE_GUSI1
 | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	err = Path2FSSpec(pathname, &libspec); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2000-12-12 22:36:57 +00:00
										 |  |  | 	c2pstrcpy((unsigned char *)buf, pathname); | 
					
						
							|  |  |  | 	(void)FSMakeFSSpec(0, 0, (unsigned char *)buf, &libspec); | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	if ( err ) { | 
					
						
							| 
									
										
										
										
											2001-11-28 20:42:20 +00:00
										 |  |  | 		PyOS_snprintf(buf, sizeof(buf), | 
					
						
							|  |  |  | 			      "%.200s: %.200s", pathname, PyMac_StrError(err)); | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 		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); | 
					
						
							| 
									
										
										
										
											2000-02-14 17:58:25 +00:00
										 |  |  | 	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 ) { | 
					
						
							| 
									
										
										
										
											2001-11-28 20:42:20 +00:00
										 |  |  | 			PyOS_snprintf(buf, sizeof(buf), | 
					
						
							|  |  |  | 		      "Dynamic module was built for %s version of MacPython", | 
					
						
							|  |  |  | 		      (err == cfragImportTooOldErr ? "a newer" : "an older")); | 
					
						
							| 
									
										
										
										
											2000-02-14 17:58:25 +00:00
										 |  |  | 			PyErr_SetString(PyExc_ImportError, buf); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	if ( err ) { | 
					
						
							| 
									
										
										
										
											2001-11-28 20:42:20 +00:00
										 |  |  | 		PyOS_snprintf(buf, sizeof(buf), "%.*s: %.200s", | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 			errMessage[0], errMessage+1, | 
					
						
							|  |  |  | 			PyMac_StrError(err)); | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_ImportError, buf); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* Locate the address of the correct init function */ | 
					
						
							| 
									
										
										
										
											2001-11-28 20:42:20 +00:00
										 |  |  | 	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname); | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 	err = FindSymbol(connID, Pstring(funcname), &symAddr, &class); | 
					
						
							|  |  |  | 	if ( err ) { | 
					
						
							| 
									
										
										
										
											2001-11-28 20:42:20 +00:00
										 |  |  | 		PyOS_snprintf(buf, sizeof(buf), "%s: %.200s", | 
					
						
							|  |  |  | 			      funcname, PyMac_StrError(err)); | 
					
						
							| 
									
										
										
										
											1999-12-20 21:18:49 +00:00
										 |  |  | 		PyErr_SetString(PyExc_ImportError, buf); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	p = (dl_funcptr)symAddr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return p; | 
					
						
							|  |  |  | } |