blob: d97dd4eb0162d7f59ad021d77797e73ebc3fd151 [file] [log] [blame]
Jack Jansen12fce3e1995-08-14 12:31:44 +00001#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>
Jack Jansenb39be211995-09-01 11:48:10 +000024#include <Dialogs.h>
Jack Jansen12fce3e1995-08-14 12:31:44 +000025
26#define PYTHONPATH "\
27:\n\
28:Lib\n\
29:Lib:stdwin\n\
30:Lib:test\n\
31:Lib:mac"
32
33
34char *
35getpythonpath()
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
Jack Jansen41fa7ea1995-08-31 13:59:36 +000089/*
90** Open/create the Python Preferences file, return the handle
91*/
92short
93PyMac_OpenPrefFile()
94{
95 AliasHandle handle;
96 FSSpec dirspec;
97 short prefrh;
98 short prefdirRefNum;
99 long prefdirDirID;
100 short action;
Jack Jansenb39be211995-09-01 11:48:10 +0000101 OSErr err;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000102
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":-) */
Jack Jansenb39be211995-09-01 11:48:10 +0000121 printf("Cannot create preferences file, error %d\n", ResError());
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000122 exit(1);
123 }
Jack Jansenb39be211995-09-01 11:48:10 +0000124 if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
125 printf("Cannot get FSSpec for application, error %d\n", err);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000126 exit(1);
127 }
128 dirspec.name[0] = 0;
Jack Jansenb39be211995-09-01 11:48:10 +0000129 if ((err=NewAlias(NULL, &dirspec, &handle)) != 0 ) {
130 printf("Cannot make alias to application directory, error %d\n", err);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000131 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}
Jack Jansen12fce3e1995-08-14 12:31:44 +0000141
142/*
143** Return the name of the Python directory
144*/
145char *
146PyMac_GetPythonDir()
147{
Jack Jansen12fce3e1995-08-14 12:31:44 +0000148 static char name[256];
149 AliasHandle handle;
150 FSSpec dirspec;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000151 Boolean modified = 0;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000152 short oldrh, prefrh;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000153
154 /*
155 ** Remember old resource file and try to open preferences file
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000156 ** in the preferences folder.
Jack Jansen12fce3e1995-08-14 12:31:44 +0000157 */
158 oldrh = CurResFile();
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000159 prefrh = PyMac_OpenPrefFile();
Jack Jansen12fce3e1995-08-14 12:31:44 +0000160 /* So, we've opened our preferences file, we hope. Look for the alias */
161 handle = (AliasHandle)Get1Resource('alis', PYTHONHOME_ID);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000162 if ( handle == NULL ) {
163 (void)StopAlert(BADPREFFILE_ID, NULL);
164 exit(1);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000165 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000166 /* It exists. Resolve it (possibly updating it) */
167 if ( ResolveAlias(NULL, handle, &dirspec, &modified) != noErr ) {
168 (void)StopAlert(BADPREFFILE_ID, NULL);
169 exit(1);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000170 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000171 if ( modified ) {
172 ChangedResource((Handle)handle);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000173 UpdateResFile(prefrh);
174 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000175 CloseResFile(prefrh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000176 UseResFile(oldrh);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000177
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");
Jack Jansen12fce3e1995-08-14 12:31:44 +0000183 name[0] = 0;
184 (void)getwd(name);
185 }
186 return name;
187}
188
189#ifndef USE_BUILTIN_PATH
190char *
191PyMac_GetPythonPath(dir)
192char *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 }
257out:
258 if ( prefrh ) {
259 CloseResFile(prefrh);
260 UseResFile(oldrh);
261 }
262 return rv;
263}
264#endif /* !USE_BUILTIN_PATH */
265