blob: 7fcf7c8fea5126e42f573a513e3775ecf77cd7f2 [file] [log] [blame]
Guido van Rossum22a1d361999-12-20 21:18:49 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007Copyright (c) 2000, BeOpen.com.
8Copyright (c) 1995-2000, Corporation for National Research Initiatives.
9Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
10All rights reserved.
Guido van Rossum22a1d361999-12-20 21:18:49 +000011
Guido van Rossumfd71b9e2000-06-30 23:50:40 +000012See the file "Misc/COPYRIGHT" for information on usage and
13redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum22a1d361999-12-20 21:18:49 +000014
15******************************************************************/
16
17/* Support for dynamic loading of extension modules */
18
19#include "Python.h"
20#include "importdl.h"
21
22#include <Aliases.h>
23#include <CodeFragments.h>
24#ifdef SYMANTEC__CFM68K__ /* Really an older version of Universal Headers */
25#define CFragConnectionID ConnectionID
26#define kLoadCFrag 0x01
27#endif
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000028#ifdef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000029#include "TFileSpec.h" /* for Path2FSSpec() */
30#endif
31#include <Files.h>
32#include "macdefs.h"
33#include "macglue.h"
34
35
36const struct filedescr _PyImport_DynLoadFiletab[] = {
37 {".slb", "rb", C_EXTENSION},
38#ifdef __CFM68K__
39 {".CFM68K.slb", "rb", C_EXTENSION},
40#else
41 {".ppc.slb", "rb", C_EXTENSION},
42#endif
43 {0, 0}
44};
45
46
Guido van Rossum96a8fb71999-12-22 14:09:35 +000047dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
Guido van Rossum22a1d361999-12-20 21:18:49 +000048 const char *pathname, FILE *fp)
49{
50 dl_funcptr p;
Guido van Rossum96a8fb71999-12-22 14:09:35 +000051 char funcname[258];
Guido van Rossum22a1d361999-12-20 21:18:49 +000052
53 /*
54 ** Dynamic loading of CFM shared libraries on the Mac. The
55 ** code has become more convoluted than it was, because we
56 ** want to be able to put multiple modules in a single
57 ** file. For this reason, we have to determine the fragment
58 ** name, and we cannot use the library entry point but we have
59 ** to locate the correct init routine "by hand".
60 */
61 FSSpec libspec;
62 CFragConnectionID connID;
63 Ptr mainAddr;
64 Str255 errMessage;
65 OSErr err;
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000066#ifndef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000067 Boolean isfolder, didsomething;
68#endif
69 char buf[512];
70 Str63 fragname;
71 Ptr symAddr;
72 CFragSymbolClass class;
73
74 /* First resolve any aliases to find the real file */
Guido van Rossumb33aa1a2000-04-24 15:08:18 +000075#ifdef USE_GUSI1
Guido van Rossum22a1d361999-12-20 21:18:49 +000076 err = Path2FSSpec(pathname, &libspec);
77#else
78 (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec);
79 err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
80#endif
81 if ( err ) {
82 sprintf(buf, "%.255s: %.200s",
83 pathname, PyMac_StrError(err));
84 PyErr_SetString(PyExc_ImportError, buf);
85 return NULL;
86 }
87 /* Next, determine the fragment name,
88 by stripping '.slb' and 'module' */
89 memcpy(fragname+1, libspec.name+1, libspec.name[0]);
90 fragname[0] = libspec.name[0];
91 if( strncmp((char *)(fragname+1+fragname[0]-4),
92 ".slb", 4) == 0 )
93 fragname[0] -= 4;
94 if ( strncmp((char *)(fragname+1+fragname[0]-6),
95 "module", 6) == 0 )
96 fragname[0] -= 6;
97 /* Load the fragment
98 (or return the connID if it is already loaded */
99 err = GetDiskFragment(&libspec, 0, 0, fragname,
100 kLoadCFrag, &connID, &mainAddr,
101 errMessage);
Guido van Rossume817acd2000-02-14 17:58:25 +0000102 if ( err == cfragImportTooOldErr || err == cfragImportTooNewErr ) {
103 /*
104 ** Special-case code: if PythonCore is too old or too new this means
105 ** the dynamic module was meant for a different Python.
106 */
107 if (errMessage[0] == 10 && strncmp((char *)errMessage+1, "PythonCore", 10) == 0 ) {
108 sprintf(buf, "Dynamic module was built for %s version of MacPython",
109 (err == cfragImportTooOldErr ? "a newer" : "an older"));
110 PyErr_SetString(PyExc_ImportError, buf);
111 return NULL;
112 }
113 }
Guido van Rossum22a1d361999-12-20 21:18:49 +0000114 if ( err ) {
115 sprintf(buf, "%.*s: %.200s",
116 errMessage[0], errMessage+1,
117 PyMac_StrError(err));
118 PyErr_SetString(PyExc_ImportError, buf);
119 return NULL;
120 }
121 /* Locate the address of the correct init function */
Guido van Rossum96a8fb71999-12-22 14:09:35 +0000122 sprintf(funcname, "init%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +0000123 err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
124 if ( err ) {
125 sprintf(buf, "%s: %.200s",
126 funcname, PyMac_StrError(err));
127 PyErr_SetString(PyExc_ImportError, buf);
128 return NULL;
129 }
130 p = (dl_funcptr)symAddr;
131
132 return p;
133}