blob: 5c2cafda1d9ed5651f1be0c04cba90f1e281feac [file] [log] [blame]
Jack Jansen12fce3e1995-08-14 12:31:44 +00001#include "Python.h"
2#include "osdefs.h"
Jack Jansen3f7d2b41996-09-06 22:21:07 +00003#include "macglue.h"
Jack Jansen12fce3e1995-08-14 12:31:44 +00004#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
Jack Jansen3f7d2b41996-09-06 22:21:07 +000026#ifdef USE_GUSI
27#include <GUSI.h>
28#endif
29
Jack Jansen12fce3e1995-08-14 12:31:44 +000030#define PYTHONPATH "\
31:\n\
32:Lib\n\
33:Lib:stdwin\n\
34:Lib:test\n\
35:Lib:mac"
36
37
38char *
Jack Jansena547dca1996-07-10 15:48:25 +000039Py_GetPath()
Jack Jansen12fce3e1995-08-14 12:31:44 +000040{
41 /* Modified by Jack to do something a bit more sensible:
42 ** - Prepend the python home-directory (which is obtained from a Preferences
43 ** resource)
44 ** - Add :
45 */
46 static char *pythonpath;
47 char *curwd;
48 char *p, *endp;
49 int newlen;
Jack Jansen01fbc681996-02-28 15:42:47 +000050 staticforward char *PyMac_GetPythonDir();
Jack Jansen12fce3e1995-08-14 12:31:44 +000051#ifndef USE_BUILTIN_PATH
Jack Jansen01fbc681996-02-28 15:42:47 +000052 staticforward char *PyMac_GetPythonPath();
Jack Jansen12fce3e1995-08-14 12:31:44 +000053#endif
54
55 if ( pythonpath ) return pythonpath;
56 curwd = PyMac_GetPythonDir();
57#ifndef USE_BUILTIN_PATH
58 if ( pythonpath = PyMac_GetPythonPath(curwd) )
59 return pythonpath;
60 printf("Warning: No pythonpath resource found, using builtin default\n");
61#endif
62 p = PYTHONPATH;
63 endp = p;
64 pythonpath = malloc(2);
65 if ( pythonpath == NULL ) return PYTHONPATH;
66 strcpy(pythonpath, ":");
67 while (*endp) {
68 endp = strchr(p, '\n');
69 if ( endp == NULL )
70 endp = p + strlen(p);
71 newlen = strlen(pythonpath) + 1 + strlen(curwd) + (endp-p);
72 pythonpath = realloc(pythonpath, newlen+1);
73 if ( pythonpath == NULL ) return PYTHONPATH;
74 strcat(pythonpath, "\n");
75 if ( *p == ':' ) {
76 p++;
77 strcat(pythonpath, curwd);
78 strncat(pythonpath, p, (endp-p));
79 newlen--; /* Ok, ok, we've allocated one byte too much */
80 } else {
81 /* We've allocated too much in this case */
82 newlen -= strlen(curwd);
83 pythonpath = realloc(pythonpath, newlen+1);
84 if ( pythonpath == NULL ) return PYTHONPATH;
85 strncat(pythonpath, p, (endp-p));
86 }
87 pythonpath[newlen] = '\0';
88 p = endp + 1;
89 }
90 return pythonpath;
91}
92
Jack Jansen41fa7ea1995-08-31 13:59:36 +000093/*
94** Open/create the Python Preferences file, return the handle
95*/
Jack Jansen01fbc681996-02-28 15:42:47 +000096static short
Jack Jansen41fa7ea1995-08-31 13:59:36 +000097PyMac_OpenPrefFile()
98{
99 AliasHandle handle;
100 FSSpec dirspec;
101 short prefrh;
102 short prefdirRefNum;
103 long prefdirDirID;
104 short action;
Jack Jansenb39be211995-09-01 11:48:10 +0000105 OSErr err;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000106
107 if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
108 &prefdirDirID) != noErr ) {
109 /* Something wrong with preferences folder */
110 (void)StopAlert(NOPREFDIR_ID, NULL);
111 exit(1);
112 }
113
114 (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
115 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
116 if ( prefrh < 0 ) {
117 action = CautionAlert(NOPREFFILE_ID, NULL);
118 if ( action == NOPREFFILE_NO )
119 exit(1);
120
Jack Jansen532e3c21996-02-21 15:36:26 +0000121 FSpCreateResFile(&dirspec, 'Pyth', 'pref', 0);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000122 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
123 if ( prefrh == -1 ) {
124 /* This "cannot happen":-) */
Jack Jansenb39be211995-09-01 11:48:10 +0000125 printf("Cannot create preferences file, error %d\n", ResError());
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000126 exit(1);
127 }
Jack Jansenb39be211995-09-01 11:48:10 +0000128 if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
129 printf("Cannot get FSSpec for application, error %d\n", err);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000130 exit(1);
131 }
132 dirspec.name[0] = 0;
Jack Jansenb39be211995-09-01 11:48:10 +0000133 if ((err=NewAlias(NULL, &dirspec, &handle)) != 0 ) {
134 printf("Cannot make alias to application directory, error %d\n", err);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000135 exit(1);
136 }
137 AddResource((Handle)handle, 'alis', PYTHONHOME_ID, "\p");
138 UpdateResFile(prefrh);
139
140 } else {
141 UseResFile(prefrh);
142 }
143 return prefrh;
144}
Jack Jansen12fce3e1995-08-14 12:31:44 +0000145
146/*
147** Return the name of the Python directory
148*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000149static char *
Jack Jansen12fce3e1995-08-14 12:31:44 +0000150PyMac_GetPythonDir()
151{
Jack Jansen12fce3e1995-08-14 12:31:44 +0000152 static char name[256];
153 AliasHandle handle;
154 FSSpec dirspec;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000155 Boolean modified = 0;
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000156 short oldrh, prefrh = -1, homerh;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000157
Jack Jansen12fce3e1995-08-14 12:31:44 +0000158 oldrh = CurResFile();
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000159
160 /* First look for an override in the application file */
161 UseResFile(PyMac_AppRefNum);
162 handle = (AliasHandle)Get1Resource('alis', PYTHONHOMEOVERRIDE_ID);
Jack Jansena486a551996-04-04 15:39:18 +0000163 if ( handle != NULL ) {
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000164 homerh = PyMac_AppRefNum;
165 } else {
166 /* Try to open preferences file in the preferences folder. */
Jack Jansena486a551996-04-04 15:39:18 +0000167 prefrh = PyMac_OpenPrefFile();
Jack Jansena486a551996-04-04 15:39:18 +0000168 handle = (AliasHandle)Get1Resource('alis', PYTHONHOME_ID);
169 if ( handle == NULL ) {
170 (void)StopAlert(BADPREFFILE_ID, NULL);
171 exit(1);
172 }
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000173 homerh = prefrh;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000174 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000175 /* It exists. Resolve it (possibly updating it) */
176 if ( ResolveAlias(NULL, handle, &dirspec, &modified) != noErr ) {
177 (void)StopAlert(BADPREFFILE_ID, NULL);
178 exit(1);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000179 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000180 if ( modified ) {
181 ChangedResource((Handle)handle);
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000182 UpdateResFile(homerh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000183 }
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000184 if ( prefrh != -1 ) CloseResFile(prefrh);
185 UseResFile(oldrh);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000186
187 if ( nfullpath(&dirspec, name) == 0 ) {
188 strcat(name, ":");
189 } else {
190 /* If all fails, we return the current directory */
191 printf("Python home dir exists but I cannot find the pathname!!\n");
Jack Jansen12fce3e1995-08-14 12:31:44 +0000192 name[0] = 0;
193 (void)getwd(name);
194 }
195 return name;
196}
197
198#ifndef USE_BUILTIN_PATH
Jack Jansen01fbc681996-02-28 15:42:47 +0000199static char *
Jack Jansen12fce3e1995-08-14 12:31:44 +0000200PyMac_GetPythonPath(dir)
201char *dir;
202{
203 FSSpec dirspec;
204 short oldrh, prefrh = -1;
205 short prefdirRefNum;
206 long prefdirDirID;
207 char *rv;
208 int i, newlen;
209 Str255 pathitem;
Jack Jansena486a551996-04-04 15:39:18 +0000210 int resource_id;
211 OSErr err;
Jack Jansenf12e7091996-09-05 15:19:24 +0000212 Handle h;
213
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000214 oldrh = CurResFile();
Jack Jansenf12e7091996-09-05 15:19:24 +0000215 /*
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000216 ** This is a bit tricky. We check here whether the application file
Jack Jansenf12e7091996-09-05 15:19:24 +0000217 ** contains an override. This is to forestall us finding another STR# resource
218 ** with "our" id and using that for path initialization
219 */
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000220 UseResFile(PyMac_AppRefNum);
Jack Jansenf12e7091996-09-05 15:19:24 +0000221 SetResLoad(0);
222 if ( (h=Get1Resource('STR#', PYTHONPATHOVERRIDE_ID)) ) {
223 ReleaseResource(h);
224 resource_id = PYTHONPATHOVERRIDE_ID;
225 } else {
226 resource_id = PYTHONPATH_ID;
227 }
228 SetResLoad(1);
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000229 UseResFile(oldrh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000230
231 /*
232 ** Remember old resource file and try to open preferences file
233 ** in the preferences folder.
234 */
Jack Jansen12fce3e1995-08-14 12:31:44 +0000235 if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
236 &prefdirDirID) == noErr ) {
237 (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
238 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
239 }
240 /* At this point, we may or may not have the preferences file open, and it
241 ** may or may not contain a sys.path STR# resource. We don't care, if it doesn't
242 ** exist we use the one from the application (the default).
243 ** We put an initial '\n' in front of the path that we don't return to the caller
244 */
245 if( (rv = malloc(2)) == NULL )
246 goto out;
247 strcpy(rv, "\n");
Jack Jansenf12e7091996-09-05 15:19:24 +0000248
Jack Jansen12fce3e1995-08-14 12:31:44 +0000249 for(i=1; ; i++) {
Jack Jansena486a551996-04-04 15:39:18 +0000250 GetIndString(pathitem, resource_id, i);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000251 if( pathitem[0] == 0 )
252 break;
253 if ( pathitem[0] >= 9 && strncmp((char *)pathitem+1, "$(PYTHON)", 9) == 0 ) {
254 /* We have to put the directory in place */
255 newlen = strlen(rv) + strlen(dir) + (pathitem[0]-9) + 2;
256 if( (rv=realloc(rv, newlen)) == NULL)
257 goto out;
258 strcat(rv, dir);
259 /* Skip a colon at the beginning of the item */
260 if ( pathitem[0] > 9 && pathitem[1+9] == ':' ) {
261 memcpy(rv+strlen(rv), pathitem+1+10, pathitem[0]-10);
262 newlen--;
263 } else {
264 memcpy(rv+strlen(rv), pathitem+1+9, pathitem[0]-9);
265 }
266 rv[newlen-2] = '\n';
267 rv[newlen-1] = 0;
Jack Jansena486a551996-04-04 15:39:18 +0000268 } else if ( pathitem[0] >= 14 && strncmp((char *)pathitem+1, "$(APPLICATION)", 14) == 0 ) {
269 /* This is the application itself */
270 char fullname[256];
271
272 if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
273 printf("Cannot get FSSpec for application, error %d\n", err);
274 exit(1);
275 }
276 if ( nfullpath(&dirspec, fullname) != 0 ) {
277 printf("Cannot convert application fsspec to path\n");
278 exit(1);
279 }
280 newlen = strlen(rv) + strlen(fullname) + 2;
281 if( (rv=realloc(rv, newlen)) == NULL)
282 goto out;
283 strcpy(rv+strlen(rv), fullname);
284 rv[newlen-2] = '\n';
285 rv[newlen-1] = 0;
286
Jack Jansen12fce3e1995-08-14 12:31:44 +0000287 } else {
288 /* Use as-is */
289 newlen = strlen(rv) + (pathitem[0]) + 2;
290 if( (rv=realloc(rv, newlen)) == NULL)
291 goto out;
292 memcpy(rv+strlen(rv), pathitem+1, pathitem[0]);
293 rv[newlen-2] = '\n';
294 rv[newlen-1] = 0;
295 }
296 }
297 if( strlen(rv) == 1) {
298 free(rv);
299 rv = NULL;
300 }
301 if ( rv ) {
302 rv[strlen(rv)-1] = 0;
303 rv++;
304 }
305out:
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000306 if ( prefrh != -1) CloseResFile(prefrh);
307 UseResFile(oldrh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000308 return rv;
309}
310#endif /* !USE_BUILTIN_PATH */
311
Jack Jansena4b7e141996-02-21 16:46:57 +0000312void
313PyMac_PreferenceOptions(int *inspect, int *verbose, int *suppress_print,
314 int *unbuffered, int *debugging, int *keep_normal,
315 int *keep_error)
316{
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000317 short oldrh, prefrh = -1;
Jack Jansena4b7e141996-02-21 16:46:57 +0000318 Handle handle;
319 int size;
320 char *p;
321
322
323 oldrh = CurResFile();
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000324
325 /* Attempt to load overrides from application */
326 UseResFile(PyMac_AppRefNum);
327 handle = Get1Resource('Popt', PYTHONOPTIONSOVERRIDE_ID);
328 UseResFile(oldrh);
329
330 /* Otherwise get options from prefs file or any other open resource file */
331 if ( handle == NULL ) {
332 prefrh = PyMac_OpenPrefFile();
Jack Jansena486a551996-04-04 15:39:18 +0000333 handle = GetResource('Popt', PYTHONOPTIONS_ID);
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000334 }
Jack Jansena4b7e141996-02-21 16:46:57 +0000335 if ( handle == NULL ) {
336 return;
337 }
338 HLock(handle);
339 size = GetHandleSize(handle);
340 p = (char *)*handle;
341
342 if ( size > POPT_INSPECT ) *inspect = p[POPT_INSPECT];
343 if ( size > POPT_VERBOSE ) *verbose = p[POPT_VERBOSE];
344 if ( size > POPT_SUPPRESS ) *suppress_print = p[POPT_SUPPRESS];
345 if ( size > POPT_UNBUFFERED ) *unbuffered = p[POPT_UNBUFFERED];
346 if ( size > POPT_DEBUGGING ) *debugging = p[POPT_DEBUGGING];
347 if ( size > POPT_KEEPNORM ) *keep_normal = p[POPT_KEEPNORM];
348 if ( size > POPT_KEEPERR ) *keep_error = p[POPT_KEEPERR];
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000349 /* The rest are not implemented yet */
Jack Jansena4b7e141996-02-21 16:46:57 +0000350
351 HUnlock(handle);
352
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000353 if ( prefrh != -1) CloseResFile(prefrh);
Jack Jansena4b7e141996-02-21 16:46:57 +0000354 UseResFile(oldrh);
355}
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000356
357#ifdef USE_GUSI
358void
359PyMac_SetGUSIOptions()
360{
361 Handle h;
362 short oldrh, prefrh = -1;
363
364 oldrh = CurResFile();
365
366 /* Try override from the application resource fork */
367 UseResFile(PyMac_AppRefNum);
368 h = Get1Resource('GU\267I', GUSIOPTIONSOVERRIDE_ID);
369 UseResFile(oldrh);
370
371 /* If that didn't work try nonoverride from anywhere */
372 if ( h == NULL ) {
373 prefrh = PyMac_OpenPrefFile();
374 h = GetResource('GU\267I', GUSIOPTIONS_ID);
375 }
376 if ( h ) GUSILoadConfiguration(h);
377 if ( prefrh != -1) CloseResFile(prefrh);
378 UseResFile(oldrh);
379}
380#endif /* USE_GUSI */