blob: 2a291a8e7c0e41d8a8acb355dd13777caaeed8e0 [file] [log] [blame]
Guido van Rossum22a1d361999-12-20 21:18:49 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum22a1d361999-12-20 21:18:49 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum22a1d361999-12-20 21:18:49 +00009******************************************************************/
10
11/* Support for dynamic loading of extension modules */
12
13#include "Python.h"
14#include "importdl.h"
15
16#include <Aliases.h>
17#include <CodeFragments.h>
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000018#ifdef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000019#include "TFileSpec.h" /* for Path2FSSpec() */
20#endif
21#include <Files.h>
22#include "macdefs.h"
23#include "macglue.h"
24
25
26const struct filedescr _PyImport_DynLoadFiletab[] = {
27 {".slb", "rb", C_EXTENSION},
28#ifdef __CFM68K__
29 {".CFM68K.slb", "rb", C_EXTENSION},
30#else
31 {".ppc.slb", "rb", C_EXTENSION},
32#endif
33 {0, 0}
34};
35
36
Guido van Rossum96a8fb71999-12-22 14:09:35 +000037dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Guido van Rossum22a1d361999-12-20 21:18:49 +000038 const char *pathname, FILE *fp)
39{
40 dl_funcptr p;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000041 char funcname[258];
Guido van Rossum22a1d361999-12-20 21:18:49 +000042
43 /*
44 ** Dynamic loading of CFM shared libraries on the Mac. The
45 ** code has become more convoluted than it was, because we
46 ** want to be able to put multiple modules in a single
47 ** file. For this reason, we have to determine the fragment
48 ** name, and we cannot use the library entry point but we have
49 ** to locate the correct init routine "by hand".
50 */
51 FSSpec libspec;
52 CFragConnectionID connID;
53 Ptr mainAddr;
54 Str255 errMessage;
55 OSErr err;
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000056#ifndef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000057 Boolean isfolder, didsomething;
58#endif
59 char buf[512];
60 Str63 fragname;
61 Ptr symAddr;
62 CFragSymbolClass class;
63
64 /* First resolve any aliases to find the real file */
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000065#ifdef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000066 err = Path2FSSpec(pathname, &libspec);
67#else
68 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
69 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
70#endif
71 if ( err ) {
72 sprintf(buf, "%.255s: %.200s",
73 pathname, PyMac_StrError(err));
74 PyErr_SetString(PyExc_ImportError, buf);
75 return NULL;
76 }
77 /* Next, determine the fragment name,
78 by stripping '.slb' and 'module' */
79 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
80 fragname[0] = libspec.name[0];
81 if( strncmp((char *)(fragname+1+fragname[0]-4),
82 ".slb", 4) == 0 )
83 fragname[0] -= 4;
84 if ( strncmp((char *)(fragname+1+fragname[0]-6),
85 "module", 6) == 0 )
86 fragname[0] -= 6;
87 /* Load the fragment
88 (or return the connID if it is already loaded */
89 err = GetDiskFragment(&libspec, 0, 0, fragname,
90 kLoadCFrag, &connID, &mainAddr,
91 errMessage);
Guido van Rossume817acd2000-02-14 17:58:25 +000092 if ( err == cfragImportTooOldErr || err == cfragImportTooNewErr ) {
93 /*
94 ** Special-case code: if PythonCore is too old or too new this means
95 ** the dynamic module was meant for a different Python.
96 */
97 if (errMessage[0] == 10 && strncmp((char *)errMessage+1, "PythonCore", 10) == 0 ) {
98 sprintf(buf, "Dynamic module was built for %s version of MacPython",
99 (err == cfragImportTooOldErr ? "a newer" : "an older"));
100 PyErr_SetString(PyExc_ImportError, buf);
101 return NULL;
102 }
103 }
Guido van Rossum22a1d361999-12-20 21:18:49 +0000104 if ( err ) {
105 sprintf(buf, "%.*s: %.200s",
106 errMessage[0], errMessage+1,
107 PyMac_StrError(err));
108 PyErr_SetString(PyExc_ImportError, buf);
109 return NULL;
110 }
111 /* Locate the address of the correct init function */
Guido van Rossum96a8fb71999-12-22 14:09:35 +0000112 sprintf(funcname, "init%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +0000113 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
114 if ( err ) {
115 sprintf(buf, "%s: %.200s",
116 funcname, PyMac_StrError(err));
117 PyErr_SetString(PyExc_ImportError, buf);
118 return NULL;
119 }
120 p = (dl_funcptr)symAddr;
121
122 return p;
123}