blob: 11eea575fe8262bb912d547c5816fd867c608b75 [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 Jansen26ee1261996-11-09 18:45:18 +0000150 if ( (err=PyMac_init_process_location()) != 0 ) {
151 printf("Cannot get application location, error %d\n", err);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000152 exit(1);
153 }
Jack Jansen26ee1261996-11-09 18:45:18 +0000154 dirspec = PyMac_ApplicationFSSpec;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000155 dirspec.name[0] = 0;
Jack Jansenb39be211995-09-01 11:48:10 +0000156 if ((err=NewAlias(NULL, &dirspec, &handle)) != 0 ) {
157 printf("Cannot make alias to application directory, error %d\n", err);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000158 exit(1);
159 }
160 AddResource((Handle)handle, 'alis', PYTHONHOME_ID, "\p");
161 UpdateResFile(prefrh);
162
163 } else {
164 UseResFile(prefrh);
165 }
166 return prefrh;
167}
Jack Jansen12fce3e1995-08-14 12:31:44 +0000168
169/*
170** Return the name of the Python directory
171*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000172static char *
Jack Jansen12fce3e1995-08-14 12:31:44 +0000173PyMac_GetPythonDir()
174{
Jack Jansen83c74df1996-10-22 15:25:42 +0000175 static int diditbefore = 0;
176 static char name[256] = {':', '\0'};
Jack Jansen12fce3e1995-08-14 12:31:44 +0000177 AliasHandle handle;
178 FSSpec dirspec;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000179 Boolean modified = 0;
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000180 short oldrh, prefrh = -1, homerh;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000181
Jack Jansen83c74df1996-10-22 15:25:42 +0000182 if ( diditbefore )
183 return name;
184
Jack Jansen12fce3e1995-08-14 12:31:44 +0000185 oldrh = CurResFile();
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000186
187 /* First look for an override in the application file */
188 UseResFile(PyMac_AppRefNum);
189 handle = (AliasHandle)Get1Resource('alis', PYTHONHOMEOVERRIDE_ID);
Jack Jansena486a551996-04-04 15:39:18 +0000190 if ( handle != NULL ) {
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000191 homerh = PyMac_AppRefNum;
192 } else {
193 /* Try to open preferences file in the preferences folder. */
Jack Jansena486a551996-04-04 15:39:18 +0000194 prefrh = PyMac_OpenPrefFile();
Jack Jansena486a551996-04-04 15:39:18 +0000195 handle = (AliasHandle)Get1Resource('alis', PYTHONHOME_ID);
196 if ( handle == NULL ) {
197 (void)StopAlert(BADPREFFILE_ID, NULL);
Jack Jansen83c74df1996-10-22 15:25:42 +0000198 diditbefore=1;
199 return ":";
Jack Jansena486a551996-04-04 15:39:18 +0000200 }
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000201 homerh = prefrh;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000202 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000203 /* It exists. Resolve it (possibly updating it) */
204 if ( ResolveAlias(NULL, handle, &dirspec, &modified) != noErr ) {
205 (void)StopAlert(BADPREFFILE_ID, NULL);
Jack Jansen83c74df1996-10-22 15:25:42 +0000206 diditbefore=1;
207 return ":";
Jack Jansen12fce3e1995-08-14 12:31:44 +0000208 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000209 if ( modified ) {
210 ChangedResource((Handle)handle);
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000211 UpdateResFile(homerh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000212 }
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000213 if ( prefrh != -1 ) CloseResFile(prefrh);
214 UseResFile(oldrh);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000215
Jack Jansen26ee1261996-11-09 18:45:18 +0000216 if ( PyMac_GetFullPath(&dirspec, name) == 0 ) {
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000217 strcat(name, ":");
218 } else {
219 /* If all fails, we return the current directory */
220 printf("Python home dir exists but I cannot find the pathname!!\n");
Jack Jansen12fce3e1995-08-14 12:31:44 +0000221 name[0] = 0;
222 (void)getwd(name);
223 }
Jack Jansen83c74df1996-10-22 15:25:42 +0000224 diditbefore = 1;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000225 return name;
226}
227
228#ifndef USE_BUILTIN_PATH
Jack Jansen01fbc681996-02-28 15:42:47 +0000229static char *
Jack Jansen83c74df1996-10-22 15:25:42 +0000230PyMac_GetPythonPath()
Jack Jansen12fce3e1995-08-14 12:31:44 +0000231{
Jack Jansen12fce3e1995-08-14 12:31:44 +0000232 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 */
Jack Jansena486a551996-04-04 15:39:18 +0000292
Jack Jansen26ee1261996-11-09 18:45:18 +0000293 if ( (err=PyMac_init_process_location()) != 0 ) {
294 printf("Cannot get application location, error %d\n", err);
Jack Jansena486a551996-04-04 15:39:18 +0000295 exit(1);
296 }
Jack Jansen26ee1261996-11-09 18:45:18 +0000297
298 newlen = strlen(rv) + strlen(PyMac_ApplicationPath) + 2;
Jack Jansena486a551996-04-04 15:39:18 +0000299 if( (rv=realloc(rv, newlen)) == NULL)
300 goto out;
Jack Jansen26ee1261996-11-09 18:45:18 +0000301 strcpy(rv+strlen(rv), PyMac_ApplicationPath);
Jack Jansena486a551996-04-04 15:39:18 +0000302 rv[newlen-2] = '\n';
303 rv[newlen-1] = 0;
304
Jack Jansen12fce3e1995-08-14 12:31:44 +0000305 } else {
306 /* Use as-is */
307 newlen = strlen(rv) + (pathitem[0]) + 2;
308 if( (rv=realloc(rv, newlen)) == NULL)
309 goto out;
310 memcpy(rv+strlen(rv), pathitem+1, pathitem[0]);
311 rv[newlen-2] = '\n';
312 rv[newlen-1] = 0;
313 }
314 }
315 if( strlen(rv) == 1) {
316 free(rv);
317 rv = NULL;
318 }
319 if ( rv ) {
320 rv[strlen(rv)-1] = 0;
321 rv++;
322 }
323out:
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000324 if ( prefrh != -1) CloseResFile(prefrh);
325 UseResFile(oldrh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000326 return rv;
327}
328#endif /* !USE_BUILTIN_PATH */
329
Jack Jansena4b7e141996-02-21 16:46:57 +0000330void
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000331PyMac_PreferenceOptions(PyMac_PrefRecord *pr)
Jack Jansena4b7e141996-02-21 16:46:57 +0000332{
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000333 short oldrh, prefrh = -1;
Jack Jansena4b7e141996-02-21 16:46:57 +0000334 Handle handle;
335 int size;
336 char *p;
337
338
339 oldrh = CurResFile();
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000340
341 /* Attempt to load overrides from application */
342 UseResFile(PyMac_AppRefNum);
343 handle = Get1Resource('Popt', PYTHONOPTIONSOVERRIDE_ID);
344 UseResFile(oldrh);
345
346 /* Otherwise get options from prefs file or any other open resource file */
347 if ( handle == NULL ) {
348 prefrh = PyMac_OpenPrefFile();
Jack Jansena486a551996-04-04 15:39:18 +0000349 handle = GetResource('Popt', PYTHONOPTIONS_ID);
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000350 }
Jack Jansena4b7e141996-02-21 16:46:57 +0000351 if ( handle == NULL ) {
352 return;
353 }
354 HLock(handle);
355 size = GetHandleSize(handle);
356 p = (char *)*handle;
357
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000358 if ( size > POPT_INSPECT ) pr->inspect = p[POPT_INSPECT];
359 if ( size > POPT_VERBOSE ) pr->verbose = p[POPT_VERBOSE];
360 if ( size > POPT_SUPPRESS ) pr->suppress_print = p[POPT_SUPPRESS];
361 if ( size > POPT_UNBUFFERED ) pr->unbuffered = p[POPT_UNBUFFERED];
362 if ( size > POPT_DEBUGGING ) pr->debugging = p[POPT_DEBUGGING];
363 if ( size > POPT_KEEPNORM ) pr->keep_normal = p[POPT_KEEPNORM];
364 if ( size > POPT_KEEPERR ) pr->keep_error = p[POPT_KEEPERR];
365 if ( size > POPT_NOINTOPT ) pr->nointopt = p[POPT_NOINTOPT];
366 if ( size > POPT_NOARGS ) pr->noargs = p[POPT_NOARGS];
Jack Jansena4b7e141996-02-21 16:46:57 +0000367
368 HUnlock(handle);
369
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000370 if ( prefrh != -1) CloseResFile(prefrh);
Jack Jansena4b7e141996-02-21 16:46:57 +0000371 UseResFile(oldrh);
372}
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000373
374#ifdef USE_GUSI
375void
376PyMac_SetGUSIOptions()
377{
378 Handle h;
379 short oldrh, prefrh = -1;
380
381 oldrh = CurResFile();
382
383 /* Try override from the application resource fork */
384 UseResFile(PyMac_AppRefNum);
385 h = Get1Resource('GU\267I', GUSIOPTIONSOVERRIDE_ID);
386 UseResFile(oldrh);
387
388 /* If that didn't work try nonoverride from anywhere */
389 if ( h == NULL ) {
390 prefrh = PyMac_OpenPrefFile();
391 h = GetResource('GU\267I', GUSIOPTIONS_ID);
392 }
393 if ( h ) GUSILoadConfiguration(h);
394 if ( prefrh != -1) CloseResFile(prefrh);
395 UseResFile(oldrh);
396}
397#endif /* USE_GUSI */