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