blob: bb5f4fb6c50dd7ff81ff1202c8eae1acb93897a6 [file] [log] [blame]
Guido van Rossum22a1d361999-12-20 21:18:49 +00001
2/* Support for dynamic loading of extension modules */
3
4#include "Python.h"
5#include "importdl.h"
6
7#include <Aliases.h>
8#include <CodeFragments.h>
Guido van Rossumb33aa1a2000-04-24 15:08:18 +00009#ifdef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000010#include "TFileSpec.h" /* for Path2FSSpec() */
11#endif
12#include <Files.h>
Jack Jansenfd0226b2000-12-12 22:36:57 +000013#include <TextUtils.h>
Guido van Rossum22a1d361999-12-20 21:18:49 +000014#include "macdefs.h"
15#include "macglue.h"
16
17
18const struct filedescr _PyImport_DynLoadFiletab[] = {
19 {".slb", "rb", C_EXTENSION},
20#ifdef __CFM68K__
21 {".CFM68K.slb", "rb", C_EXTENSION},
22#else
Jack Jansenc7050d92001-01-19 23:34:06 +000023#if TARGET_API_MAC_CARBON
Jack Jansen8eb4b562001-01-15 16:00:40 +000024 {".carbon.slb", "rb", C_EXTENSION},
25#else
Guido van Rossum22a1d361999-12-20 21:18:49 +000026 {".ppc.slb", "rb", C_EXTENSION},
27#endif
Jack Jansen8eb4b562001-01-15 16:00:40 +000028#endif
Guido van Rossum22a1d361999-12-20 21:18:49 +000029 {0, 0}
30};
31
32
Guido van Rossum96a8fb71999-12-22 14:09:35 +000033dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Guido van Rossum22a1d361999-12-20 21:18:49 +000034 const char *pathname, FILE *fp)
35{
36 dl_funcptr p;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000037 char funcname[258];
Guido van Rossum22a1d361999-12-20 21:18:49 +000038
39 /*
40 ** Dynamic loading of CFM shared libraries on the Mac. The
41 ** code has become more convoluted than it was, because we
42 ** want to be able to put multiple modules in a single
43 ** file. For this reason, we have to determine the fragment
44 ** name, and we cannot use the library entry point but we have
45 ** to locate the correct init routine "by hand".
46 */
47 FSSpec libspec;
48 CFragConnectionID connID;
49 Ptr mainAddr;
50 Str255 errMessage;
51 OSErr err;
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000052#ifndef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000053 Boolean isfolder, didsomething;
54#endif
55 char buf[512];
56 Str63 fragname;
57 Ptr symAddr;
58 CFragSymbolClass class;
59
60 /* First resolve any aliases to find the real file */
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000061#ifdef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000062 err = Path2FSSpec(pathname, &libspec);
63#else
Jack Jansenfd0226b2000-12-12 22:36:57 +000064 c2pstrcpy((unsigned char *)buf, pathname);
65 (void)FSMakeFSSpec(0, 0, (unsigned char *)buf, &libspec);
Guido van Rossum22a1d361999-12-20 21:18:49 +000066 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
67#endif
68 if ( err ) {
Jeremy Hylton518ab1c2001-11-28 20:42:20 +000069 PyOS_snprintf(buf, sizeof(buf),
70 "%.200s: %.200s", pathname, PyMac_StrError(err));
Guido van Rossum22a1d361999-12-20 21:18:49 +000071 PyErr_SetString(PyExc_ImportError, buf);
72 return NULL;
73 }
74 /* Next, determine the fragment name,
75 by stripping '.slb' and 'module' */
76 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
77 fragname[0] = libspec.name[0];
78 if( strncmp((char *)(fragname+1+fragname[0]-4),
79 ".slb", 4) == 0 )
80 fragname[0] -= 4;
81 if ( strncmp((char *)(fragname+1+fragname[0]-6),
82 "module", 6) == 0 )
83 fragname[0] -= 6;
84 /* Load the fragment
85 (or return the connID if it is already loaded */
86 err = GetDiskFragment(&libspec, 0, 0, fragname,
87 kLoadCFrag, &connID, &mainAddr,
88 errMessage);
Guido van Rossume817acd2000-02-14 17:58:25 +000089 if ( err == cfragImportTooOldErr || err == cfragImportTooNewErr ) {
90 /*
91 ** Special-case code: if PythonCore is too old or too new this means
92 ** the dynamic module was meant for a different Python.
93 */
94 if (errMessage[0] == 10 && strncmp((char *)errMessage+1, "PythonCore", 10) == 0 ) {
Jeremy Hylton518ab1c2001-11-28 20:42:20 +000095 PyOS_snprintf(buf, sizeof(buf),
96 "Dynamic module was built for %s version of MacPython",
97 (err == cfragImportTooOldErr ? "a newer" : "an older"));
Guido van Rossume817acd2000-02-14 17:58:25 +000098 PyErr_SetString(PyExc_ImportError, buf);
99 return NULL;
100 }
101 }
Guido van Rossum22a1d361999-12-20 21:18:49 +0000102 if ( err ) {
Jeremy Hylton518ab1c2001-11-28 20:42:20 +0000103 PyOS_snprintf(buf, sizeof(buf), "%.*s: %.200s",
Guido van Rossum22a1d361999-12-20 21:18:49 +0000104 errMessage[0], errMessage+1,
105 PyMac_StrError(err));
106 PyErr_SetString(PyExc_ImportError, buf);
107 return NULL;
108 }
109 /* Locate the address of the correct init function */
Jeremy Hylton518ab1c2001-11-28 20:42:20 +0000110 PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +0000111 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
112 if ( err ) {
Jeremy Hylton518ab1c2001-11-28 20:42:20 +0000113 PyOS_snprintf(buf, sizeof(buf), "%s: %.200s",
114 funcname, PyMac_StrError(err));
Guido van Rossum22a1d361999-12-20 21:18:49 +0000115 PyErr_SetString(PyExc_ImportError, buf);
116 return NULL;
117 }
118 p = (dl_funcptr)symAddr;
119
120 return p;
121}