blob: a7c1366eb837c0a11d2a3fed1dc6ca3d6679d763 [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
Jack Jansen83c74df1996-10-22 15:25:42 +000037static void
38getpreffilefss(FSSpec *fssp)
39{
40 static int diditbefore=0;
41 static FSSpec fss;
42 short prefdirRefNum;
43 long prefdirDirID;
44 Handle namehandle;
45
46 if ( !diditbefore ) {
47 if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
48 &prefdirDirID) != noErr ) {
49 /* Something wrong with preferences folder */
50 (void)StopAlert(NOPREFDIR_ID, NULL);
51 exit(1);
52 }
53
54 if ( (namehandle=GetNamedResource('STR ', PREFFILENAME_NAME)) == NULL ) {
55 (void)StopAlert(NOPREFNAME_ID, NULL);
56 exit(1);
57 }
58
59 HLock(namehandle);
60 (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, (unsigned char *)*namehandle, &fss);
61 HUnlock(namehandle);
62 ReleaseResource(namehandle);
63 diditbefore = 1;
64 }
65 *fssp = fss;
66}
Jack Jansen12fce3e1995-08-14 12:31:44 +000067
68char *
Jack Jansena547dca1996-07-10 15:48:25 +000069Py_GetPath()
Jack Jansen12fce3e1995-08-14 12:31:44 +000070{
71 /* Modified by Jack to do something a bit more sensible:
72 ** - Prepend the python home-directory (which is obtained from a Preferences
73 ** resource)
74 ** - Add :
75 */
76 static char *pythonpath;
Jack Jansen12fce3e1995-08-14 12:31:44 +000077 char *p, *endp;
78 int newlen;
Jack Jansen83c74df1996-10-22 15:25:42 +000079 char *curwd;
Jack Jansen01fbc681996-02-28 15:42:47 +000080 staticforward char *PyMac_GetPythonDir();
Jack Jansen12fce3e1995-08-14 12:31:44 +000081#ifndef USE_BUILTIN_PATH
Jack Jansen01fbc681996-02-28 15:42:47 +000082 staticforward char *PyMac_GetPythonPath();
Jack Jansen12fce3e1995-08-14 12:31:44 +000083#endif
84
85 if ( pythonpath ) return pythonpath;
Jack Jansen12fce3e1995-08-14 12:31:44 +000086#ifndef USE_BUILTIN_PATH
Jack Jansen83c74df1996-10-22 15:25:42 +000087 if ( pythonpath = PyMac_GetPythonPath() )
Jack Jansen12fce3e1995-08-14 12:31:44 +000088 return pythonpath;
89 printf("Warning: No pythonpath resource found, using builtin default\n");
90#endif
Jack Jansen83c74df1996-10-22 15:25:42 +000091 curwd = PyMac_GetPythonDir();
Jack Jansen12fce3e1995-08-14 12:31:44 +000092 p = PYTHONPATH;
93 endp = p;
94 pythonpath = malloc(2);
95 if ( pythonpath == NULL ) return PYTHONPATH;
96 strcpy(pythonpath, ":");
97 while (*endp) {
98 endp = strchr(p, '\n');
99 if ( endp == NULL )
100 endp = p + strlen(p);
101 newlen = strlen(pythonpath) + 1 + strlen(curwd) + (endp-p);
102 pythonpath = realloc(pythonpath, newlen+1);
103 if ( pythonpath == NULL ) return PYTHONPATH;
104 strcat(pythonpath, "\n");
105 if ( *p == ':' ) {
106 p++;
107 strcat(pythonpath, curwd);
108 strncat(pythonpath, p, (endp-p));
109 newlen--; /* Ok, ok, we've allocated one byte too much */
110 } else {
111 /* We've allocated too much in this case */
112 newlen -= strlen(curwd);
113 pythonpath = realloc(pythonpath, newlen+1);
114 if ( pythonpath == NULL ) return PYTHONPATH;
115 strncat(pythonpath, p, (endp-p));
116 }
117 pythonpath[newlen] = '\0';
118 p = endp + 1;
119 }
120 return pythonpath;
121}
122
Jack Jansen83c74df1996-10-22 15:25:42 +0000123
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000124/*
125** Open/create the Python Preferences file, return the handle
126*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000127static short
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000128PyMac_OpenPrefFile()
129{
130 AliasHandle handle;
131 FSSpec dirspec;
132 short prefrh;
Jack Jansenb39be211995-09-01 11:48:10 +0000133 OSErr err;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000134
Jack Jansen83c74df1996-10-22 15:25:42 +0000135 getpreffilefss(&dirspec);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000136 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
137 if ( prefrh < 0 ) {
Jack Jansen83c74df1996-10-22 15:25:42 +0000138#if 0
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000139 action = CautionAlert(NOPREFFILE_ID, NULL);
140 if ( action == NOPREFFILE_NO )
141 exit(1);
Jack Jansen83c74df1996-10-22 15:25:42 +0000142#endif
Jack Jansen532e3c21996-02-21 15:36:26 +0000143 FSpCreateResFile(&dirspec, 'Pyth', 'pref', 0);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000144 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
145 if ( prefrh == -1 ) {
146 /* This "cannot happen":-) */
Jack Jansenb39be211995-09-01 11:48:10 +0000147 printf("Cannot create preferences file, error %d\n", ResError());
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000148 exit(1);
149 }
Jack Jansenb39be211995-09-01 11:48:10 +0000150 if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
151 printf("Cannot get FSSpec for application, error %d\n", err);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000152 exit(1);
153 }
154 dirspec.name[0] = 0;
Jack Jansenb39be211995-09-01 11:48:10 +0000155 if ((err=NewAlias(NULL, &dirspec, &handle)) != 0 ) {
156 printf("Cannot make alias to application directory, error %d\n", err);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000157 exit(1);
158 }
159 AddResource((Handle)handle, 'alis', PYTHONHOME_ID, "\p");
160 UpdateResFile(prefrh);
161
162 } else {
163 UseResFile(prefrh);
164 }
165 return prefrh;
166}
Jack Jansen12fce3e1995-08-14 12:31:44 +0000167
168/*
169** Return the name of the Python directory
170*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000171static char *
Jack Jansen12fce3e1995-08-14 12:31:44 +0000172PyMac_GetPythonDir()
173{
Jack Jansen83c74df1996-10-22 15:25:42 +0000174 static int diditbefore = 0;
175 static char name[256] = {':', '\0'};
Jack Jansen12fce3e1995-08-14 12:31:44 +0000176 AliasHandle handle;
177 FSSpec dirspec;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000178 Boolean modified = 0;
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000179 short oldrh, prefrh = -1, homerh;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000180
Jack Jansen83c74df1996-10-22 15:25:42 +0000181 if ( diditbefore )
182 return name;
183
Jack Jansen12fce3e1995-08-14 12:31:44 +0000184 oldrh = CurResFile();
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000185
186 /* First look for an override in the application file */
187 UseResFile(PyMac_AppRefNum);
188 handle = (AliasHandle)Get1Resource('alis', PYTHONHOMEOVERRIDE_ID);
Jack Jansena486a551996-04-04 15:39:18 +0000189 if ( handle != NULL ) {
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000190 homerh = PyMac_AppRefNum;
191 } else {
192 /* Try to open preferences file in the preferences folder. */
Jack Jansena486a551996-04-04 15:39:18 +0000193 prefrh = PyMac_OpenPrefFile();
Jack Jansena486a551996-04-04 15:39:18 +0000194 handle = (AliasHandle)Get1Resource('alis', PYTHONHOME_ID);
195 if ( handle == NULL ) {
196 (void)StopAlert(BADPREFFILE_ID, NULL);
Jack Jansen83c74df1996-10-22 15:25:42 +0000197 diditbefore=1;
198 return ":";
Jack Jansena486a551996-04-04 15:39:18 +0000199 }
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000200 homerh = prefrh;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000201 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000202 /* It exists. Resolve it (possibly updating it) */
203 if ( ResolveAlias(NULL, handle, &dirspec, &modified) != noErr ) {
204 (void)StopAlert(BADPREFFILE_ID, NULL);
Jack Jansen83c74df1996-10-22 15:25:42 +0000205 diditbefore=1;
206 return ":";
Jack Jansen12fce3e1995-08-14 12:31:44 +0000207 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000208 if ( modified ) {
209 ChangedResource((Handle)handle);
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000210 UpdateResFile(homerh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000211 }
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000212 if ( prefrh != -1 ) CloseResFile(prefrh);
213 UseResFile(oldrh);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000214
215 if ( nfullpath(&dirspec, name) == 0 ) {
216 strcat(name, ":");
217 } else {
218 /* If all fails, we return the current directory */
219 printf("Python home dir exists but I cannot find the pathname!!\n");
Jack Jansen12fce3e1995-08-14 12:31:44 +0000220 name[0] = 0;
221 (void)getwd(name);
222 }
Jack Jansen83c74df1996-10-22 15:25:42 +0000223 diditbefore = 1;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000224 return name;
225}
226
227#ifndef USE_BUILTIN_PATH
Jack Jansen01fbc681996-02-28 15:42:47 +0000228static char *
Jack Jansen83c74df1996-10-22 15:25:42 +0000229PyMac_GetPythonPath()
Jack Jansen12fce3e1995-08-14 12:31:44 +0000230{
231 FSSpec dirspec;
232 short oldrh, prefrh = -1;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000233 char *rv;
234 int i, newlen;
235 Str255 pathitem;
Jack Jansena486a551996-04-04 15:39:18 +0000236 int resource_id;
237 OSErr err;
Jack Jansenf12e7091996-09-05 15:19:24 +0000238 Handle h;
239
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000240 oldrh = CurResFile();
Jack Jansenf12e7091996-09-05 15:19:24 +0000241 /*
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000242 ** This is a bit tricky. We check here whether the application file
Jack Jansenf12e7091996-09-05 15:19:24 +0000243 ** contains an override. This is to forestall us finding another STR# resource
244 ** with "our" id and using that for path initialization
245 */
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000246 UseResFile(PyMac_AppRefNum);
Jack Jansenf12e7091996-09-05 15:19:24 +0000247 SetResLoad(0);
248 if ( (h=Get1Resource('STR#', PYTHONPATHOVERRIDE_ID)) ) {
249 ReleaseResource(h);
250 resource_id = PYTHONPATHOVERRIDE_ID;
251 } else {
252 resource_id = PYTHONPATH_ID;
253 }
254 SetResLoad(1);
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000255 UseResFile(oldrh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000256
Jack Jansen83c74df1996-10-22 15:25:42 +0000257 /* Open the preferences file only if there is no override */
258 if ( resource_id != PYTHONPATHOVERRIDE_ID )
259 prefrh = PyMac_OpenPrefFile();
Jack Jansen12fce3e1995-08-14 12:31:44 +0000260 /* At this point, we may or may not have the preferences file open, and it
261 ** may or may not contain a sys.path STR# resource. We don't care, if it doesn't
262 ** exist we use the one from the application (the default).
263 ** We put an initial '\n' in front of the path that we don't return to the caller
264 */
265 if( (rv = malloc(2)) == NULL )
266 goto out;
267 strcpy(rv, "\n");
Jack Jansenf12e7091996-09-05 15:19:24 +0000268
Jack Jansen12fce3e1995-08-14 12:31:44 +0000269 for(i=1; ; i++) {
Jack Jansena486a551996-04-04 15:39:18 +0000270 GetIndString(pathitem, resource_id, i);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000271 if( pathitem[0] == 0 )
272 break;
273 if ( pathitem[0] >= 9 && strncmp((char *)pathitem+1, "$(PYTHON)", 9) == 0 ) {
274 /* We have to put the directory in place */
Jack Jansen83c74df1996-10-22 15:25:42 +0000275 char *dir = PyMac_GetPythonDir();
276
Jack Jansen12fce3e1995-08-14 12:31:44 +0000277 newlen = strlen(rv) + strlen(dir) + (pathitem[0]-9) + 2;
278 if( (rv=realloc(rv, newlen)) == NULL)
279 goto out;
280 strcat(rv, dir);
281 /* Skip a colon at the beginning of the item */
282 if ( pathitem[0] > 9 && pathitem[1+9] == ':' ) {
283 memcpy(rv+strlen(rv), pathitem+1+10, pathitem[0]-10);
284 newlen--;
285 } else {
286 memcpy(rv+strlen(rv), pathitem+1+9, pathitem[0]-9);
287 }
288 rv[newlen-2] = '\n';
289 rv[newlen-1] = 0;
Jack Jansena486a551996-04-04 15:39:18 +0000290 } else if ( pathitem[0] >= 14 && strncmp((char *)pathitem+1, "$(APPLICATION)", 14) == 0 ) {
291 /* This is the application itself */
292 char fullname[256];
293
294 if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
295 printf("Cannot get FSSpec for application, error %d\n", err);
296 exit(1);
297 }
298 if ( nfullpath(&dirspec, fullname) != 0 ) {
299 printf("Cannot convert application fsspec to path\n");
300 exit(1);
301 }
302 newlen = strlen(rv) + strlen(fullname) + 2;
303 if( (rv=realloc(rv, newlen)) == NULL)
304 goto out;
305 strcpy(rv+strlen(rv), fullname);
306 rv[newlen-2] = '\n';
307 rv[newlen-1] = 0;
308
Jack Jansen12fce3e1995-08-14 12:31:44 +0000309 } else {
310 /* Use as-is */
311 newlen = strlen(rv) + (pathitem[0]) + 2;
312 if( (rv=realloc(rv, newlen)) == NULL)
313 goto out;
314 memcpy(rv+strlen(rv), pathitem+1, pathitem[0]);
315 rv[newlen-2] = '\n';
316 rv[newlen-1] = 0;
317 }
318 }
319 if( strlen(rv) == 1) {
320 free(rv);
321 rv = NULL;
322 }
323 if ( rv ) {
324 rv[strlen(rv)-1] = 0;
325 rv++;
326 }
327out:
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000328 if ( prefrh != -1) CloseResFile(prefrh);
329 UseResFile(oldrh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000330 return rv;
331}
332#endif /* !USE_BUILTIN_PATH */
333
Jack Jansena4b7e141996-02-21 16:46:57 +0000334void
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000335PyMac_PreferenceOptions(PyMac_PrefRecord *pr)
Jack Jansena4b7e141996-02-21 16:46:57 +0000336{
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000337 short oldrh, prefrh = -1;
Jack Jansena4b7e141996-02-21 16:46:57 +0000338 Handle handle;
339 int size;
340 char *p;
341
342
343 oldrh = CurResFile();
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000344
345 /* Attempt to load overrides from application */
346 UseResFile(PyMac_AppRefNum);
347 handle = Get1Resource('Popt', PYTHONOPTIONSOVERRIDE_ID);
348 UseResFile(oldrh);
349
350 /* Otherwise get options from prefs file or any other open resource file */
351 if ( handle == NULL ) {
352 prefrh = PyMac_OpenPrefFile();
Jack Jansena486a551996-04-04 15:39:18 +0000353 handle = GetResource('Popt', PYTHONOPTIONS_ID);
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000354 }
Jack Jansena4b7e141996-02-21 16:46:57 +0000355 if ( handle == NULL ) {
356 return;
357 }
358 HLock(handle);
359 size = GetHandleSize(handle);
360 p = (char *)*handle;
361
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000362 if ( size > POPT_INSPECT ) pr->inspect = p[POPT_INSPECT];
363 if ( size > POPT_VERBOSE ) pr->verbose = p[POPT_VERBOSE];
364 if ( size > POPT_SUPPRESS ) pr->suppress_print = p[POPT_SUPPRESS];
365 if ( size > POPT_UNBUFFERED ) pr->unbuffered = p[POPT_UNBUFFERED];
366 if ( size > POPT_DEBUGGING ) pr->debugging = p[POPT_DEBUGGING];
367 if ( size > POPT_KEEPNORM ) pr->keep_normal = p[POPT_KEEPNORM];
368 if ( size > POPT_KEEPERR ) pr->keep_error = p[POPT_KEEPERR];
369 if ( size > POPT_NOINTOPT ) pr->nointopt = p[POPT_NOINTOPT];
370 if ( size > POPT_NOARGS ) pr->noargs = p[POPT_NOARGS];
Jack Jansena4b7e141996-02-21 16:46:57 +0000371
372 HUnlock(handle);
373
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000374 if ( prefrh != -1) CloseResFile(prefrh);
Jack Jansena4b7e141996-02-21 16:46:57 +0000375 UseResFile(oldrh);
376}
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000377
378#ifdef USE_GUSI
379void
380PyMac_SetGUSIOptions()
381{
382 Handle h;
383 short oldrh, prefrh = -1;
384
385 oldrh = CurResFile();
386
387 /* Try override from the application resource fork */
388 UseResFile(PyMac_AppRefNum);
389 h = Get1Resource('GU\267I', GUSIOPTIONSOVERRIDE_ID);
390 UseResFile(oldrh);
391
392 /* If that didn't work try nonoverride from anywhere */
393 if ( h == NULL ) {
394 prefrh = PyMac_OpenPrefFile();
395 h = GetResource('GU\267I', GUSIOPTIONS_ID);
396 }
397 if ( h ) GUSILoadConfiguration(h);
398 if ( prefrh != -1) CloseResFile(prefrh);
399 UseResFile(oldrh);
400}
401#endif /* USE_GUSI */