blob: 697895672dfd6b9ee9671daa46251ea2550024bc [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>
18#ifdef SYMANTEC__CFM68K__ /* Really an older version of Universal Headers */
19#define CFragConnectionID ConnectionID
20#define kLoadCFrag 0x01
21#endif
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000022#ifdef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000023#include "TFileSpec.h" /* for Path2FSSpec() */
24#endif
25#include <Files.h>
26#include "macdefs.h"
27#include "macglue.h"
28
29
30const struct filedescr _PyImport_DynLoadFiletab[] = {
31 {".slb", "rb", C_EXTENSION},
32#ifdef __CFM68K__
33 {".CFM68K.slb", "rb", C_EXTENSION},
34#else
35 {".ppc.slb", "rb", C_EXTENSION},
36#endif
37 {0, 0}
38};
39
40
Guido van Rossum96a8fb71999-12-22 14:09:35 +000041dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Guido van Rossum22a1d361999-12-20 21:18:49 +000042 const char *pathname, FILE *fp)
43{
44 dl_funcptr p;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000045 char funcname[258];
Guido van Rossum22a1d361999-12-20 21:18:49 +000046
47 /*
48 ** Dynamic loading of CFM shared libraries on the Mac. The
49 ** code has become more convoluted than it was, because we
50 ** want to be able to put multiple modules in a single
51 ** file. For this reason, we have to determine the fragment
52 ** name, and we cannot use the library entry point but we have
53 ** to locate the correct init routine "by hand".
54 */
55 FSSpec libspec;
56 CFragConnectionID connID;
57 Ptr mainAddr;
58 Str255 errMessage;
59 OSErr err;
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000060#ifndef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000061 Boolean isfolder, didsomething;
62#endif
63 char buf[512];
64 Str63 fragname;
65 Ptr symAddr;
66 CFragSymbolClass class;
67
68 /* First resolve any aliases to find the real file */
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000069#ifdef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000070 err = Path2FSSpec(pathname, &libspec);
71#else
72 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
73 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
74#endif
75 if ( err ) {
76 sprintf(buf, "%.255s: %.200s",
77 pathname, PyMac_StrError(err));
78 PyErr_SetString(PyExc_ImportError, buf);
79 return NULL;
80 }
81 /* Next, determine the fragment name,
82 by stripping '.slb' and 'module' */
83 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
84 fragname[0] = libspec.name[0];
85 if( strncmp((char *)(fragname+1+fragname[0]-4),
86 ".slb", 4) == 0 )
87 fragname[0] -= 4;
88 if ( strncmp((char *)(fragname+1+fragname[0]-6),
89 "module", 6) == 0 )
90 fragname[0] -= 6;
91 /* Load the fragment
92 (or return the connID if it is already loaded */
93 err = GetDiskFragment(&libspec, 0, 0, fragname,
94 kLoadCFrag, &connID, &mainAddr,
95 errMessage);
Guido van Rossume817acd2000-02-14 17:58:25 +000096 if ( err == cfragImportTooOldErr || err == cfragImportTooNewErr ) {
97 /*
98 ** Special-case code: if PythonCore is too old or too new this means
99 ** the dynamic module was meant for a different Python.
100 */
101 if (errMessage[0] == 10 && strncmp((char *)errMessage+1, "PythonCore", 10) == 0 ) {
102 sprintf(buf, "Dynamic module was built for %s version of MacPython",
103 (err == cfragImportTooOldErr ? "a newer" : "an older"));
104 PyErr_SetString(PyExc_ImportError, buf);
105 return NULL;
106 }
107 }
Guido van Rossum22a1d361999-12-20 21:18:49 +0000108 if ( err ) {
109 sprintf(buf, "%.*s: %.200s",
110 errMessage[0], errMessage+1,
111 PyMac_StrError(err));
112 PyErr_SetString(PyExc_ImportError, buf);
113 return NULL;
114 }
115 /* Locate the address of the correct init function */
Guido van Rossum96a8fb71999-12-22 14:09:35 +0000116 sprintf(funcname, "init%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +0000117 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
118 if ( err ) {
119 sprintf(buf, "%s: %.200s",
120 funcname, PyMac_StrError(err));
121 PyErr_SetString(PyExc_ImportError, buf);
122 return NULL;
123 }
124 p = (dl_funcptr)symAddr;
125
126 return p;
127}