blob: 0e3341dfe5f32acae3b4d54bf020417bfee30d75 [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 *
Jack Jansena547dca1996-07-10 15:48:25 +000035Py_GetPath()
Jack Jansen12fce3e1995-08-14 12:31:44 +000036{
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;
Jack Jansen01fbc681996-02-28 15:42:47 +000046 staticforward char *PyMac_GetPythonDir();
Jack Jansen12fce3e1995-08-14 12:31:44 +000047#ifndef USE_BUILTIN_PATH
Jack Jansen01fbc681996-02-28 15:42:47 +000048 staticforward char *PyMac_GetPythonPath();
Jack Jansen12fce3e1995-08-14 12:31:44 +000049#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*/
Jack Jansen01fbc681996-02-28 15:42:47 +000092static short
Jack Jansen41fa7ea1995-08-31 13:59:36 +000093PyMac_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
Jack Jansen532e3c21996-02-21 15:36:26 +0000117 FSpCreateResFile(&dirspec, 'Pyth', 'pref', 0);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000118 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*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000145static char *
Jack Jansen12fce3e1995-08-14 12:31:44 +0000146PyMac_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
Jack Jansen12fce3e1995-08-14 12:31:44 +0000154 oldrh = CurResFile();
Jack Jansena486a551996-04-04 15:39:18 +0000155 /*
156 ** First look for an override of the preferences file
157 */
158 handle = (AliasHandle)GetResource('alis', PYTHONHOMEOVERRIDE_ID);
159 if ( handle != NULL ) {
160 prefrh = oldrh;
161 } else {
162 /*
163 ** Remember old resource file and try to open preferences file
164 ** in the preferences folder.
165 */
166 prefrh = PyMac_OpenPrefFile();
167 /* So, we've opened our preferences file, we hope. Look for the alias */
168 handle = (AliasHandle)Get1Resource('alis', PYTHONHOME_ID);
169 if ( handle == NULL ) {
170 (void)StopAlert(BADPREFFILE_ID, NULL);
171 exit(1);
172 }
Jack Jansen12fce3e1995-08-14 12:31:44 +0000173 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000174 /* It exists. Resolve it (possibly updating it) */
175 if ( ResolveAlias(NULL, handle, &dirspec, &modified) != noErr ) {
176 (void)StopAlert(BADPREFFILE_ID, NULL);
177 exit(1);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000178 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000179 if ( modified ) {
180 ChangedResource((Handle)handle);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000181 UpdateResFile(prefrh);
182 }
Jack Jansena486a551996-04-04 15:39:18 +0000183 if ( prefrh != oldrh ) {
184 CloseResFile(prefrh);
185 UseResFile(oldrh);
186 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000187
188 if ( nfullpath(&dirspec, name) == 0 ) {
189 strcat(name, ":");
190 } else {
191 /* If all fails, we return the current directory */
192 printf("Python home dir exists but I cannot find the pathname!!\n");
Jack Jansen12fce3e1995-08-14 12:31:44 +0000193 name[0] = 0;
194 (void)getwd(name);
195 }
196 return name;
197}
198
199#ifndef USE_BUILTIN_PATH
Jack Jansen01fbc681996-02-28 15:42:47 +0000200static char *
Jack Jansen12fce3e1995-08-14 12:31:44 +0000201PyMac_GetPythonPath(dir)
202char *dir;
203{
204 FSSpec dirspec;
205 short oldrh, prefrh = -1;
206 short prefdirRefNum;
207 long prefdirDirID;
208 char *rv;
209 int i, newlen;
210 Str255 pathitem;
Jack Jansena486a551996-04-04 15:39:18 +0000211 int resource_id;
212 OSErr err;
Jack Jansenf12e7091996-09-05 15:19:24 +0000213 Handle h;
214
215 /*
216 ** This is a bit tricky. We check here whether the current resource file
217 ** contains an override. This is to forestall us finding another STR# resource
218 ** with "our" id and using that for path initialization
219 */
220 SetResLoad(0);
221 if ( (h=Get1Resource('STR#', PYTHONPATHOVERRIDE_ID)) ) {
222 ReleaseResource(h);
223 resource_id = PYTHONPATHOVERRIDE_ID;
224 } else {
225 resource_id = PYTHONPATH_ID;
226 }
227 SetResLoad(1);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000228
229 /*
230 ** Remember old resource file and try to open preferences file
231 ** in the preferences folder.
232 */
233 oldrh = CurResFile();
234 if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
235 &prefdirDirID) == noErr ) {
236 (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
237 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
238 }
239 /* At this point, we may or may not have the preferences file open, and it
240 ** may or may not contain a sys.path STR# resource. We don't care, if it doesn't
241 ** exist we use the one from the application (the default).
242 ** We put an initial '\n' in front of the path that we don't return to the caller
243 */
244 if( (rv = malloc(2)) == NULL )
245 goto out;
246 strcpy(rv, "\n");
Jack Jansenf12e7091996-09-05 15:19:24 +0000247
Jack Jansen12fce3e1995-08-14 12:31:44 +0000248 for(i=1; ; i++) {
Jack Jansena486a551996-04-04 15:39:18 +0000249 GetIndString(pathitem, resource_id, i);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000250 if( pathitem[0] == 0 )
251 break;
252 if ( pathitem[0] >= 9 && strncmp((char *)pathitem+1, "$(PYTHON)", 9) == 0 ) {
253 /* We have to put the directory in place */
254 newlen = strlen(rv) + strlen(dir) + (pathitem[0]-9) + 2;
255 if( (rv=realloc(rv, newlen)) == NULL)
256 goto out;
257 strcat(rv, dir);
258 /* Skip a colon at the beginning of the item */
259 if ( pathitem[0] > 9 && pathitem[1+9] == ':' ) {
260 memcpy(rv+strlen(rv), pathitem+1+10, pathitem[0]-10);
261 newlen--;
262 } else {
263 memcpy(rv+strlen(rv), pathitem+1+9, pathitem[0]-9);
264 }
265 rv[newlen-2] = '\n';
266 rv[newlen-1] = 0;
Jack Jansena486a551996-04-04 15:39:18 +0000267 } else if ( pathitem[0] >= 14 && strncmp((char *)pathitem+1, "$(APPLICATION)", 14) == 0 ) {
268 /* This is the application itself */
269 char fullname[256];
270
271 if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
272 printf("Cannot get FSSpec for application, error %d\n", err);
273 exit(1);
274 }
275 if ( nfullpath(&dirspec, fullname) != 0 ) {
276 printf("Cannot convert application fsspec to path\n");
277 exit(1);
278 }
279 newlen = strlen(rv) + strlen(fullname) + 2;
280 if( (rv=realloc(rv, newlen)) == NULL)
281 goto out;
282 strcpy(rv+strlen(rv), fullname);
283 rv[newlen-2] = '\n';
284 rv[newlen-1] = 0;
285
Jack Jansen12fce3e1995-08-14 12:31:44 +0000286 } else {
287 /* Use as-is */
288 newlen = strlen(rv) + (pathitem[0]) + 2;
289 if( (rv=realloc(rv, newlen)) == NULL)
290 goto out;
291 memcpy(rv+strlen(rv), pathitem+1, pathitem[0]);
292 rv[newlen-2] = '\n';
293 rv[newlen-1] = 0;
294 }
295 }
296 if( strlen(rv) == 1) {
297 free(rv);
298 rv = NULL;
299 }
300 if ( rv ) {
301 rv[strlen(rv)-1] = 0;
302 rv++;
303 }
304out:
305 if ( prefrh ) {
306 CloseResFile(prefrh);
307 UseResFile(oldrh);
308 }
309 return rv;
310}
311#endif /* !USE_BUILTIN_PATH */
312
Jack Jansena4b7e141996-02-21 16:46:57 +0000313void
314PyMac_PreferenceOptions(int *inspect, int *verbose, int *suppress_print,
315 int *unbuffered, int *debugging, int *keep_normal,
316 int *keep_error)
317{
318 short oldrh, prefrh;
319 Handle handle;
320 int size;
321 char *p;
322
323
324 oldrh = CurResFile();
325 prefrh = PyMac_OpenPrefFile();
Jack Jansena486a551996-04-04 15:39:18 +0000326 handle = GetResource('Popt', PYTHONOPTIONSOVERRIDE_ID);
327 if ( handle == NULL )
328 handle = GetResource('Popt', PYTHONOPTIONS_ID);
Jack Jansena4b7e141996-02-21 16:46:57 +0000329 if ( handle == NULL ) {
330 return;
331 }
332 HLock(handle);
333 size = GetHandleSize(handle);
334 p = (char *)*handle;
335
336 if ( size > POPT_INSPECT ) *inspect = p[POPT_INSPECT];
337 if ( size > POPT_VERBOSE ) *verbose = p[POPT_VERBOSE];
338 if ( size > POPT_SUPPRESS ) *suppress_print = p[POPT_SUPPRESS];
339 if ( size > POPT_UNBUFFERED ) *unbuffered = p[POPT_UNBUFFERED];
340 if ( size > POPT_DEBUGGING ) *debugging = p[POPT_DEBUGGING];
341 if ( size > POPT_KEEPNORM ) *keep_normal = p[POPT_KEEPNORM];
342 if ( size > POPT_KEEPERR ) *keep_error = p[POPT_KEEPERR];
343
344 HUnlock(handle);
345
346 CloseResFile(prefrh);
347 UseResFile(oldrh);
348}