blob: 8f057e747489cfed6509b7251e2cdf61afd3270a [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>
13#include "macdefs.h"
14#include "macglue.h"
15
16
17const struct filedescr _PyImport_DynLoadFiletab[] = {
18 {".slb", "rb", C_EXTENSION},
19#ifdef __CFM68K__
20 {".CFM68K.slb", "rb", C_EXTENSION},
21#else
22 {".ppc.slb", "rb", C_EXTENSION},
23#endif
24 {0, 0}
25};
26
27
Guido van Rossum96a8fb71999-12-22 14:09:35 +000028dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Guido van Rossum22a1d361999-12-20 21:18:49 +000029 const char *pathname, FILE *fp)
30{
31 dl_funcptr p;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000032 char funcname[258];
Guido van Rossum22a1d361999-12-20 21:18:49 +000033
34 /*
35 ** Dynamic loading of CFM shared libraries on the Mac. The
36 ** code has become more convoluted than it was, because we
37 ** want to be able to put multiple modules in a single
38 ** file. For this reason, we have to determine the fragment
39 ** name, and we cannot use the library entry point but we have
40 ** to locate the correct init routine "by hand".
41 */
42 FSSpec libspec;
43 CFragConnectionID connID;
44 Ptr mainAddr;
45 Str255 errMessage;
46 OSErr err;
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000047#ifndef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000048 Boolean isfolder, didsomething;
49#endif
50 char buf[512];
51 Str63 fragname;
52 Ptr symAddr;
53 CFragSymbolClass class;
54
55 /* First resolve any aliases to find the real file */
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000056#ifdef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000057 err = Path2FSSpec(pathname, &libspec);
58#else
59 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
60 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
61#endif
62 if ( err ) {
63 sprintf(buf, "%.255s: %.200s",
64 pathname, PyMac_StrError(err));
65 PyErr_SetString(PyExc_ImportError, buf);
66 return NULL;
67 }
68 /* Next, determine the fragment name,
69 by stripping '.slb' and 'module' */
70 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
71 fragname[0] = libspec.name[0];
72 if( strncmp((char *)(fragname+1+fragname[0]-4),
73 ".slb", 4) == 0 )
74 fragname[0] -= 4;
75 if ( strncmp((char *)(fragname+1+fragname[0]-6),
76 "module", 6) == 0 )
77 fragname[0] -= 6;
78 /* Load the fragment
79 (or return the connID if it is already loaded */
80 err = GetDiskFragment(&libspec, 0, 0, fragname,
81 kLoadCFrag, &connID, &mainAddr,
82 errMessage);
Guido van Rossume817acd2000-02-14 17:58:25 +000083 if ( err == cfragImportTooOldErr || err == cfragImportTooNewErr ) {
84 /*
85 ** Special-case code: if PythonCore is too old or too new this means
86 ** the dynamic module was meant for a different Python.
87 */
88 if (errMessage[0] == 10 && strncmp((char *)errMessage+1, "PythonCore", 10) == 0 ) {
89 sprintf(buf, "Dynamic module was built for %s version of MacPython",
90 (err == cfragImportTooOldErr ? "a newer" : "an older"));
91 PyErr_SetString(PyExc_ImportError, buf);
92 return NULL;
93 }
94 }
Guido van Rossum22a1d361999-12-20 21:18:49 +000095 if ( err ) {
96 sprintf(buf, "%.*s: %.200s",
97 errMessage[0], errMessage+1,
98 PyMac_StrError(err));
99 PyErr_SetString(PyExc_ImportError, buf);
100 return NULL;
101 }
102 /* Locate the address of the correct init function */
Guido van Rossum96a8fb71999-12-22 14:09:35 +0000103 sprintf(funcname, "init%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +0000104 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
105 if ( err ) {
106 sprintf(buf, "%s: %.200s",
107 funcname, PyMac_StrError(err));
108 PyErr_SetString(PyExc_ImportError, buf);
109 return NULL;
110 }
111 p = (dl_funcptr)symAddr;
112
113 return p;
114}