home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Python / dynload_mac.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  3.1 KB  |  115 lines

  1.  
  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>
  9. #ifdef USE_GUSI1
  10. #include "TFileSpec.h"        /* for Path2FSSpec() */
  11. #endif
  12. #include <Files.h>
  13. #include "macdefs.h"
  14. #include "macglue.h"
  15.  
  16.  
  17. const 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.  
  28. dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
  29.                     const char *pathname, FILE *fp)
  30. {
  31.     dl_funcptr p;
  32.     char funcname[258];
  33.  
  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;
  47. #ifndef USE_GUSI1
  48.     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 */
  56. #ifdef USE_GUSI1
  57.     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);
  83.     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.     }
  95.     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 */
  103.     sprintf(funcname, "init%.200s", shortname);
  104.     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. }
  115.