home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / Python 1.3 / source code / Mac / macgetpath.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-17  |  6.8 KB  |  266 lines  |  [TEXT/R*ch]

  1. #include "Python.h"
  2. #include "osdefs.h"
  3.  
  4. #include "pythonresources.h"
  5.  
  6.  
  7. /* Return the initial python search path.  This is called once from
  8. ** initsys() to initialize sys.path.
  9. **
  10. ** If USE_BUILTIN_PATH is defined the path defined here is used
  11. ** (after prepending the python home dir to each item).
  12. ** If it is not defined the path is gotten from a resource in the
  13. ** Preferences file.
  14. **
  15. ** XXXX This code needs cleaning up. The routines here have moved
  16. ** around quite a bit, and they're pretty messy for that reason.
  17. */
  18.  
  19. #include <Files.h>
  20. #include <Aliases.h>
  21. #include <Folders.h>
  22. #include <Resources.h>
  23. #include <TextUtils.h>
  24. #include <Dialogs.h>
  25.  
  26. #define PYTHONPATH "\
  27. :\n\
  28. :Lib\n\
  29. :Lib:stdwin\n\
  30. :Lib:test\n\
  31. :Lib:mac"
  32.  
  33.  
  34. char *
  35. getpythonpath()
  36. {
  37.     /* Modified by Jack to do something a bit more sensible:
  38.     ** - Prepend the python home-directory (which is obtained from a Preferences
  39.     **   resource)
  40.     ** - Add :
  41.     */
  42.     static char *pythonpath;
  43.     char *curwd;
  44.     char *p, *endp;
  45.     int newlen;
  46.     extern char *PyMac_GetPythonDir();
  47. #ifndef USE_BUILTIN_PATH
  48.     extern char *PyMac_GetPythonPath();
  49. #endif
  50.     
  51.     if ( pythonpath ) return pythonpath;
  52.     curwd = PyMac_GetPythonDir();
  53. #ifndef USE_BUILTIN_PATH
  54.     if ( pythonpath = PyMac_GetPythonPath(curwd) )
  55.         return pythonpath;
  56.     printf("Warning: No pythonpath resource found, using builtin default\n");
  57. #endif
  58.     p = PYTHONPATH;
  59.     endp = p;
  60.     pythonpath = malloc(2);
  61.     if ( pythonpath == NULL ) return PYTHONPATH;
  62.     strcpy(pythonpath, ":");
  63.     while (*endp) {
  64.         endp = strchr(p, '\n');
  65.         if ( endp == NULL )
  66.             endp = p + strlen(p);
  67.         newlen = strlen(pythonpath) + 1 + strlen(curwd) + (endp-p);
  68.         pythonpath = realloc(pythonpath, newlen+1);
  69.         if ( pythonpath == NULL ) return PYTHONPATH;
  70.         strcat(pythonpath, "\n");
  71.         if ( *p == ':' ) {
  72.             p++;
  73.             strcat(pythonpath, curwd);
  74.             strncat(pythonpath, p, (endp-p));
  75.             newlen--;   /* Ok, ok, we've allocated one byte too much */
  76.         } else {
  77.             /* We've allocated too much in this case */
  78.             newlen -= strlen(curwd);
  79.             pythonpath = realloc(pythonpath, newlen+1);
  80.             if ( pythonpath == NULL ) return PYTHONPATH;
  81.             strncat(pythonpath, p, (endp-p));
  82.         }
  83.         pythonpath[newlen] = '\0';
  84.         p = endp + 1;
  85.     }
  86.     return pythonpath;
  87. }
  88.  
  89. /*
  90. ** Open/create the Python Preferences file, return the handle
  91. */
  92. short
  93. PyMac_OpenPrefFile()
  94. {
  95.     AliasHandle handle;
  96.     FSSpec dirspec;
  97.     short prefrh;
  98.     short prefdirRefNum;
  99.     long prefdirDirID;
  100.     short action;
  101.     OSErr err;
  102.  
  103.     if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
  104.                     &prefdirDirID) != noErr ) {
  105.         /* Something wrong with preferences folder */
  106.         (void)StopAlert(NOPREFDIR_ID, NULL);
  107.         exit(1);
  108.     }
  109.     
  110.     (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
  111.     prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
  112.     if ( prefrh < 0 ) {
  113.         action = CautionAlert(NOPREFFILE_ID, NULL);
  114.         if ( action == NOPREFFILE_NO )
  115.             exit(1);
  116.     
  117.         FSpCreateResFile(&dirspec, 'PYTH', 'pref', 0);
  118.         prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
  119.         if ( prefrh == -1 ) {
  120.             /* This "cannot happen":-) */
  121.             printf("Cannot create preferences file, error %d\n", ResError());
  122.             exit(1);
  123.         }
  124.         if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
  125.             printf("Cannot get FSSpec for application, error %d\n", err);
  126.             exit(1);
  127.         }
  128.         dirspec.name[0] = 0;
  129.         if ((err=NewAlias(NULL, &dirspec, &handle)) != 0 ) {
  130.             printf("Cannot make alias to application directory, error %d\n", err);
  131.             exit(1);
  132.         }
  133.         AddResource((Handle)handle, 'alis', PYTHONHOME_ID, "\p");
  134.         UpdateResFile(prefrh);
  135.  
  136.     } else {
  137.         UseResFile(prefrh);
  138.     }
  139.     return prefrh;
  140. }
  141.  
  142. /*
  143. ** Return the name of the Python directory
  144. */
  145. char *
  146. PyMac_GetPythonDir()
  147. {
  148.     static char name[256];
  149.     AliasHandle handle;
  150.     FSSpec dirspec;
  151.     Boolean modified = 0;
  152.     short oldrh, prefrh;
  153.     
  154.     /*
  155.     ** Remember old resource file and try to open preferences file
  156.     ** in the preferences folder.
  157.     */
  158.     oldrh = CurResFile();
  159.     prefrh = PyMac_OpenPrefFile();
  160.     /* So, we've opened our preferences file, we hope. Look for the alias */
  161.     handle = (AliasHandle)Get1Resource('alis', PYTHONHOME_ID);
  162.     if ( handle == NULL ) {
  163.         (void)StopAlert(BADPREFFILE_ID, NULL);
  164.         exit(1);
  165.     }
  166.     /* It exists. Resolve it (possibly updating it) */
  167.     if ( ResolveAlias(NULL, handle, &dirspec, &modified) != noErr ) {
  168.         (void)StopAlert(BADPREFFILE_ID, NULL);
  169.         exit(1);
  170.     }
  171.     if ( modified ) {
  172.            ChangedResource((Handle)handle);
  173.         UpdateResFile(prefrh);
  174.     }
  175.        CloseResFile(prefrh);
  176.     UseResFile(oldrh);
  177.  
  178.        if ( nfullpath(&dirspec, name) == 0 ) {
  179.            strcat(name, ":");
  180.     } else {
  181.          /* If all fails, we return the current directory */
  182.            printf("Python home dir exists but I cannot find the pathname!!\n");
  183.         name[0] = 0;
  184.         (void)getwd(name);
  185.     }
  186.     return name;
  187. }
  188.  
  189. #ifndef USE_BUILTIN_PATH
  190. char *
  191. PyMac_GetPythonPath(dir)
  192. char *dir;
  193. {
  194.     FSSpec dirspec;
  195.     short oldrh, prefrh = -1;
  196.     short prefdirRefNum;
  197.     long prefdirDirID;
  198.     char *rv;
  199.     int i, newlen;
  200.     Str255 pathitem;
  201.     
  202.     /*
  203.     ** Remember old resource file and try to open preferences file
  204.     ** in the preferences folder.
  205.     */
  206.     oldrh = CurResFile();
  207.     if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
  208.                     &prefdirDirID) == noErr ) {
  209.         (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
  210.         prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
  211.     }
  212.     /* At this point, we may or may not have the preferences file open, and it
  213.     ** may or may not contain a sys.path STR# resource. We don't care, if it doesn't
  214.     ** exist we use the one from the application (the default).
  215.     ** We put an initial '\n' in front of the path that we don't return to the caller
  216.     */
  217.     if( (rv = malloc(2)) == NULL )
  218.         goto out;
  219.     strcpy(rv, "\n");
  220.     for(i=1; ; i++) {
  221.         GetIndString(pathitem, PYTHONPATH_ID, i);
  222.         if( pathitem[0] == 0 )
  223.             break;
  224.         if ( pathitem[0] >= 9 && strncmp((char *)pathitem+1, "$(PYTHON)", 9) == 0 ) {
  225.             /* We have to put the directory in place */
  226.             newlen = strlen(rv) + strlen(dir) + (pathitem[0]-9) + 2;
  227.             if( (rv=realloc(rv, newlen)) == NULL)
  228.                 goto out;
  229.             strcat(rv, dir);
  230.             /* Skip a colon at the beginning of the item */
  231.             if ( pathitem[0] > 9 && pathitem[1+9] == ':' ) {
  232.                 memcpy(rv+strlen(rv), pathitem+1+10, pathitem[0]-10);
  233.                 newlen--;
  234.             } else {
  235.                 memcpy(rv+strlen(rv), pathitem+1+9, pathitem[0]-9);
  236.             }
  237.             rv[newlen-2] = '\n';
  238.             rv[newlen-1] = 0;
  239.         } else {
  240.             /* Use as-is */
  241.             newlen = strlen(rv) + (pathitem[0]) + 2;
  242.             if( (rv=realloc(rv, newlen)) == NULL)
  243.                 goto out;
  244.             memcpy(rv+strlen(rv), pathitem+1, pathitem[0]);
  245.             rv[newlen-2] = '\n';
  246.             rv[newlen-1] = 0;
  247.         }
  248.     }
  249.     if( strlen(rv) == 1) {
  250.         free(rv);
  251.         rv = NULL;
  252.     }
  253.     if ( rv ) {
  254.         rv[strlen(rv)-1] = 0;
  255.         rv++;
  256.     }
  257. out:
  258.     if ( prefrh ) {
  259.         CloseResFile(prefrh);
  260.         UseResFile(oldrh);
  261.     }
  262.     return rv;
  263. }
  264. #endif /* !USE_BUILTIN_PATH */
  265.  
  266.