blob: ed6c491f93599c4440675c011ef761bd0032cbad [file] [log] [blame]
Jack Jansen42218ce1997-01-31 16:15:11 +00001/***********************************************************
2Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
Jack Jansen12fce3e1995-08-14 12:31:44 +000032#include "Python.h"
33#include "osdefs.h"
Jack Jansen3f7d2b41996-09-06 22:21:07 +000034#include "macglue.h"
Jack Jansen12fce3e1995-08-14 12:31:44 +000035#include "pythonresources.h"
36
37
38/* Return the initial python search path. This is called once from
39** initsys() to initialize sys.path.
40**
41** If USE_BUILTIN_PATH is defined the path defined here is used
42** (after prepending the python home dir to each item).
43** If it is not defined the path is gotten from a resource in the
44** Preferences file.
45**
46** XXXX This code needs cleaning up. The routines here have moved
47** around quite a bit, and they're pretty messy for that reason.
48*/
49
50#include <Files.h>
51#include <Aliases.h>
52#include <Folders.h>
53#include <Resources.h>
54#include <TextUtils.h>
Jack Jansenb39be211995-09-01 11:48:10 +000055#include <Dialogs.h>
Jack Jansen12fce3e1995-08-14 12:31:44 +000056
Jack Jansen3f7d2b41996-09-06 22:21:07 +000057#ifdef USE_GUSI
58#include <GUSI.h>
59#endif
60
Jack Jansen12fce3e1995-08-14 12:31:44 +000061#define PYTHONPATH "\
62:\n\
63:Lib\n\
64:Lib:stdwin\n\
65:Lib:test\n\
66:Lib:mac"
67
Jack Jansen83c74df1996-10-22 15:25:42 +000068static void
69getpreffilefss(FSSpec *fssp)
70{
71 static int diditbefore=0;
72 static FSSpec fss;
73 short prefdirRefNum;
74 long prefdirDirID;
75 Handle namehandle;
76
77 if ( !diditbefore ) {
78 if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
79 &prefdirDirID) != noErr ) {
80 /* Something wrong with preferences folder */
81 (void)StopAlert(NOPREFDIR_ID, NULL);
82 exit(1);
83 }
84
85 if ( (namehandle=GetNamedResource('STR ', PREFFILENAME_NAME)) == NULL ) {
86 (void)StopAlert(NOPREFNAME_ID, NULL);
87 exit(1);
88 }
89
90 HLock(namehandle);
91 (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, (unsigned char *)*namehandle, &fss);
92 HUnlock(namehandle);
93 ReleaseResource(namehandle);
94 diditbefore = 1;
95 }
96 *fssp = fss;
97}
Jack Jansen12fce3e1995-08-14 12:31:44 +000098
99char *
Jack Jansena547dca1996-07-10 15:48:25 +0000100Py_GetPath()
Jack Jansen12fce3e1995-08-14 12:31:44 +0000101{
102 /* Modified by Jack to do something a bit more sensible:
103 ** - Prepend the python home-directory (which is obtained from a Preferences
104 ** resource)
105 ** - Add :
106 */
107 static char *pythonpath;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000108 char *p, *endp;
109 int newlen;
Jack Jansen83c74df1996-10-22 15:25:42 +0000110 char *curwd;
Jack Jansen01fbc681996-02-28 15:42:47 +0000111 staticforward char *PyMac_GetPythonDir();
Jack Jansen12fce3e1995-08-14 12:31:44 +0000112#ifndef USE_BUILTIN_PATH
Jack Jansen01fbc681996-02-28 15:42:47 +0000113 staticforward char *PyMac_GetPythonPath();
Jack Jansen12fce3e1995-08-14 12:31:44 +0000114#endif
115
116 if ( pythonpath ) return pythonpath;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000117#ifndef USE_BUILTIN_PATH
Jack Jansen83c74df1996-10-22 15:25:42 +0000118 if ( pythonpath = PyMac_GetPythonPath() )
Jack Jansen12fce3e1995-08-14 12:31:44 +0000119 return pythonpath;
120 printf("Warning: No pythonpath resource found, using builtin default\n");
121#endif
Jack Jansen83c74df1996-10-22 15:25:42 +0000122 curwd = PyMac_GetPythonDir();
Jack Jansen12fce3e1995-08-14 12:31:44 +0000123 p = PYTHONPATH;
124 endp = p;
125 pythonpath = malloc(2);
126 if ( pythonpath == NULL ) return PYTHONPATH;
127 strcpy(pythonpath, ":");
128 while (*endp) {
129 endp = strchr(p, '\n');
130 if ( endp == NULL )
131 endp = p + strlen(p);
132 newlen = strlen(pythonpath) + 1 + strlen(curwd) + (endp-p);
133 pythonpath = realloc(pythonpath, newlen+1);
134 if ( pythonpath == NULL ) return PYTHONPATH;
135 strcat(pythonpath, "\n");
136 if ( *p == ':' ) {
137 p++;
138 strcat(pythonpath, curwd);
139 strncat(pythonpath, p, (endp-p));
140 newlen--; /* Ok, ok, we've allocated one byte too much */
141 } else {
142 /* We've allocated too much in this case */
143 newlen -= strlen(curwd);
144 pythonpath = realloc(pythonpath, newlen+1);
145 if ( pythonpath == NULL ) return PYTHONPATH;
146 strncat(pythonpath, p, (endp-p));
147 }
148 pythonpath[newlen] = '\0';
149 p = endp + 1;
150 }
151 return pythonpath;
152}
153
Jack Jansen83c74df1996-10-22 15:25:42 +0000154
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000155/*
156** Open/create the Python Preferences file, return the handle
157*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000158static short
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000159PyMac_OpenPrefFile()
160{
161 AliasHandle handle;
162 FSSpec dirspec;
163 short prefrh;
Jack Jansenb39be211995-09-01 11:48:10 +0000164 OSErr err;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000165
Jack Jansen83c74df1996-10-22 15:25:42 +0000166 getpreffilefss(&dirspec);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000167 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
168 if ( prefrh < 0 ) {
Jack Jansen83c74df1996-10-22 15:25:42 +0000169#if 0
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000170 action = CautionAlert(NOPREFFILE_ID, NULL);
171 if ( action == NOPREFFILE_NO )
172 exit(1);
Jack Jansen83c74df1996-10-22 15:25:42 +0000173#endif
Jack Jansen532e3c21996-02-21 15:36:26 +0000174 FSpCreateResFile(&dirspec, 'Pyth', 'pref', 0);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000175 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
176 if ( prefrh == -1 ) {
177 /* This "cannot happen":-) */
Jack Jansenb39be211995-09-01 11:48:10 +0000178 printf("Cannot create preferences file, error %d\n", ResError());
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000179 exit(1);
180 }
Jack Jansen26ee1261996-11-09 18:45:18 +0000181 if ( (err=PyMac_init_process_location()) != 0 ) {
182 printf("Cannot get application location, error %d\n", err);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000183 exit(1);
184 }
Jack Jansen26ee1261996-11-09 18:45:18 +0000185 dirspec = PyMac_ApplicationFSSpec;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000186 dirspec.name[0] = 0;
Jack Jansenb39be211995-09-01 11:48:10 +0000187 if ((err=NewAlias(NULL, &dirspec, &handle)) != 0 ) {
188 printf("Cannot make alias to application directory, error %d\n", err);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000189 exit(1);
190 }
191 AddResource((Handle)handle, 'alis', PYTHONHOME_ID, "\p");
192 UpdateResFile(prefrh);
193
194 } else {
195 UseResFile(prefrh);
196 }
197 return prefrh;
198}
Jack Jansen12fce3e1995-08-14 12:31:44 +0000199
200/*
201** Return the name of the Python directory
202*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000203static char *
Jack Jansen12fce3e1995-08-14 12:31:44 +0000204PyMac_GetPythonDir()
205{
Jack Jansen83c74df1996-10-22 15:25:42 +0000206 static int diditbefore = 0;
207 static char name[256] = {':', '\0'};
Jack Jansen12fce3e1995-08-14 12:31:44 +0000208 AliasHandle handle;
209 FSSpec dirspec;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000210 Boolean modified = 0;
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000211 short oldrh, prefrh = -1, homerh;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000212
Jack Jansen83c74df1996-10-22 15:25:42 +0000213 if ( diditbefore )
214 return name;
215
Jack Jansen12fce3e1995-08-14 12:31:44 +0000216 oldrh = CurResFile();
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000217
218 /* First look for an override in the application file */
219 UseResFile(PyMac_AppRefNum);
220 handle = (AliasHandle)Get1Resource('alis', PYTHONHOMEOVERRIDE_ID);
Jack Jansena486a551996-04-04 15:39:18 +0000221 if ( handle != NULL ) {
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000222 homerh = PyMac_AppRefNum;
223 } else {
224 /* Try to open preferences file in the preferences folder. */
Jack Jansena486a551996-04-04 15:39:18 +0000225 prefrh = PyMac_OpenPrefFile();
Jack Jansena486a551996-04-04 15:39:18 +0000226 handle = (AliasHandle)Get1Resource('alis', PYTHONHOME_ID);
227 if ( handle == NULL ) {
228 (void)StopAlert(BADPREFFILE_ID, NULL);
Jack Jansen83c74df1996-10-22 15:25:42 +0000229 diditbefore=1;
230 return ":";
Jack Jansena486a551996-04-04 15:39:18 +0000231 }
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000232 homerh = prefrh;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000233 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000234 /* It exists. Resolve it (possibly updating it) */
235 if ( ResolveAlias(NULL, handle, &dirspec, &modified) != noErr ) {
236 (void)StopAlert(BADPREFFILE_ID, NULL);
Jack Jansen83c74df1996-10-22 15:25:42 +0000237 diditbefore=1;
238 return ":";
Jack Jansen12fce3e1995-08-14 12:31:44 +0000239 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000240 if ( modified ) {
241 ChangedResource((Handle)handle);
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000242 UpdateResFile(homerh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000243 }
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000244 if ( prefrh != -1 ) CloseResFile(prefrh);
245 UseResFile(oldrh);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000246
Jack Jansen26ee1261996-11-09 18:45:18 +0000247 if ( PyMac_GetFullPath(&dirspec, name) == 0 ) {
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000248 strcat(name, ":");
249 } else {
250 /* If all fails, we return the current directory */
251 printf("Python home dir exists but I cannot find the pathname!!\n");
Jack Jansen12fce3e1995-08-14 12:31:44 +0000252 name[0] = 0;
253 (void)getwd(name);
254 }
Jack Jansen83c74df1996-10-22 15:25:42 +0000255 diditbefore = 1;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000256 return name;
257}
258
259#ifndef USE_BUILTIN_PATH
Jack Jansen01fbc681996-02-28 15:42:47 +0000260static char *
Jack Jansen83c74df1996-10-22 15:25:42 +0000261PyMac_GetPythonPath()
Jack Jansen12fce3e1995-08-14 12:31:44 +0000262{
Jack Jansen12fce3e1995-08-14 12:31:44 +0000263 short oldrh, prefrh = -1;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000264 char *rv;
265 int i, newlen;
266 Str255 pathitem;
Jack Jansena486a551996-04-04 15:39:18 +0000267 int resource_id;
268 OSErr err;
Jack Jansenf12e7091996-09-05 15:19:24 +0000269 Handle h;
270
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000271 oldrh = CurResFile();
Jack Jansenf12e7091996-09-05 15:19:24 +0000272 /*
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000273 ** This is a bit tricky. We check here whether the application file
Jack Jansenf12e7091996-09-05 15:19:24 +0000274 ** contains an override. This is to forestall us finding another STR# resource
275 ** with "our" id and using that for path initialization
276 */
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000277 UseResFile(PyMac_AppRefNum);
Jack Jansenf12e7091996-09-05 15:19:24 +0000278 SetResLoad(0);
279 if ( (h=Get1Resource('STR#', PYTHONPATHOVERRIDE_ID)) ) {
280 ReleaseResource(h);
281 resource_id = PYTHONPATHOVERRIDE_ID;
282 } else {
283 resource_id = PYTHONPATH_ID;
284 }
285 SetResLoad(1);
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000286 UseResFile(oldrh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000287
Jack Jansen83c74df1996-10-22 15:25:42 +0000288 /* Open the preferences file only if there is no override */
289 if ( resource_id != PYTHONPATHOVERRIDE_ID )
290 prefrh = PyMac_OpenPrefFile();
Jack Jansen12fce3e1995-08-14 12:31:44 +0000291 /* At this point, we may or may not have the preferences file open, and it
292 ** may or may not contain a sys.path STR# resource. We don't care, if it doesn't
293 ** exist we use the one from the application (the default).
294 ** We put an initial '\n' in front of the path that we don't return to the caller
295 */
296 if( (rv = malloc(2)) == NULL )
297 goto out;
298 strcpy(rv, "\n");
Jack Jansenf12e7091996-09-05 15:19:24 +0000299
Jack Jansen12fce3e1995-08-14 12:31:44 +0000300 for(i=1; ; i++) {
Jack Jansena486a551996-04-04 15:39:18 +0000301 GetIndString(pathitem, resource_id, i);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000302 if( pathitem[0] == 0 )
303 break;
304 if ( pathitem[0] >= 9 && strncmp((char *)pathitem+1, "$(PYTHON)", 9) == 0 ) {
305 /* We have to put the directory in place */
Jack Jansen83c74df1996-10-22 15:25:42 +0000306 char *dir = PyMac_GetPythonDir();
307
Jack Jansen12fce3e1995-08-14 12:31:44 +0000308 newlen = strlen(rv) + strlen(dir) + (pathitem[0]-9) + 2;
309 if( (rv=realloc(rv, newlen)) == NULL)
310 goto out;
311 strcat(rv, dir);
312 /* Skip a colon at the beginning of the item */
313 if ( pathitem[0] > 9 && pathitem[1+9] == ':' ) {
314 memcpy(rv+strlen(rv), pathitem+1+10, pathitem[0]-10);
315 newlen--;
316 } else {
317 memcpy(rv+strlen(rv), pathitem+1+9, pathitem[0]-9);
318 }
319 rv[newlen-2] = '\n';
320 rv[newlen-1] = 0;
Jack Jansena486a551996-04-04 15:39:18 +0000321 } else if ( pathitem[0] >= 14 && strncmp((char *)pathitem+1, "$(APPLICATION)", 14) == 0 ) {
322 /* This is the application itself */
Jack Jansena486a551996-04-04 15:39:18 +0000323
Jack Jansen26ee1261996-11-09 18:45:18 +0000324 if ( (err=PyMac_init_process_location()) != 0 ) {
325 printf("Cannot get application location, error %d\n", err);
Jack Jansena486a551996-04-04 15:39:18 +0000326 exit(1);
327 }
Jack Jansen26ee1261996-11-09 18:45:18 +0000328
329 newlen = strlen(rv) + strlen(PyMac_ApplicationPath) + 2;
Jack Jansena486a551996-04-04 15:39:18 +0000330 if( (rv=realloc(rv, newlen)) == NULL)
331 goto out;
Jack Jansen26ee1261996-11-09 18:45:18 +0000332 strcpy(rv+strlen(rv), PyMac_ApplicationPath);
Jack Jansena486a551996-04-04 15:39:18 +0000333 rv[newlen-2] = '\n';
334 rv[newlen-1] = 0;
335
Jack Jansen12fce3e1995-08-14 12:31:44 +0000336 } else {
337 /* Use as-is */
338 newlen = strlen(rv) + (pathitem[0]) + 2;
339 if( (rv=realloc(rv, newlen)) == NULL)
340 goto out;
341 memcpy(rv+strlen(rv), pathitem+1, pathitem[0]);
342 rv[newlen-2] = '\n';
343 rv[newlen-1] = 0;
344 }
345 }
346 if( strlen(rv) == 1) {
347 free(rv);
348 rv = NULL;
349 }
350 if ( rv ) {
351 rv[strlen(rv)-1] = 0;
352 rv++;
353 }
354out:
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000355 if ( prefrh != -1) CloseResFile(prefrh);
356 UseResFile(oldrh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000357 return rv;
358}
359#endif /* !USE_BUILTIN_PATH */
360
Jack Jansena4b7e141996-02-21 16:46:57 +0000361void
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000362PyMac_PreferenceOptions(PyMac_PrefRecord *pr)
Jack Jansena4b7e141996-02-21 16:46:57 +0000363{
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000364 short oldrh, prefrh = -1;
Jack Jansena4b7e141996-02-21 16:46:57 +0000365 Handle handle;
366 int size;
367 char *p;
368
369
370 oldrh = CurResFile();
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000371
372 /* Attempt to load overrides from application */
373 UseResFile(PyMac_AppRefNum);
374 handle = Get1Resource('Popt', PYTHONOPTIONSOVERRIDE_ID);
375 UseResFile(oldrh);
376
377 /* Otherwise get options from prefs file or any other open resource file */
378 if ( handle == NULL ) {
379 prefrh = PyMac_OpenPrefFile();
Jack Jansena486a551996-04-04 15:39:18 +0000380 handle = GetResource('Popt', PYTHONOPTIONS_ID);
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000381 }
Jack Jansena4b7e141996-02-21 16:46:57 +0000382 if ( handle == NULL ) {
383 return;
384 }
385 HLock(handle);
386 size = GetHandleSize(handle);
387 p = (char *)*handle;
388
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000389 if ( size > POPT_INSPECT ) pr->inspect = p[POPT_INSPECT];
390 if ( size > POPT_VERBOSE ) pr->verbose = p[POPT_VERBOSE];
391 if ( size > POPT_SUPPRESS ) pr->suppress_print = p[POPT_SUPPRESS];
392 if ( size > POPT_UNBUFFERED ) pr->unbuffered = p[POPT_UNBUFFERED];
393 if ( size > POPT_DEBUGGING ) pr->debugging = p[POPT_DEBUGGING];
394 if ( size > POPT_KEEPNORM ) pr->keep_normal = p[POPT_KEEPNORM];
395 if ( size > POPT_KEEPERR ) pr->keep_error = p[POPT_KEEPERR];
396 if ( size > POPT_NOINTOPT ) pr->nointopt = p[POPT_NOINTOPT];
397 if ( size > POPT_NOARGS ) pr->noargs = p[POPT_NOARGS];
Jack Jansena4b7e141996-02-21 16:46:57 +0000398
399 HUnlock(handle);
400
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000401 if ( prefrh != -1) CloseResFile(prefrh);
Jack Jansena4b7e141996-02-21 16:46:57 +0000402 UseResFile(oldrh);
403}
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000404
405#ifdef USE_GUSI
406void
407PyMac_SetGUSIOptions()
408{
409 Handle h;
410 short oldrh, prefrh = -1;
411
412 oldrh = CurResFile();
413
414 /* Try override from the application resource fork */
415 UseResFile(PyMac_AppRefNum);
416 h = Get1Resource('GU\267I', GUSIOPTIONSOVERRIDE_ID);
417 UseResFile(oldrh);
418
419 /* If that didn't work try nonoverride from anywhere */
420 if ( h == NULL ) {
421 prefrh = PyMac_OpenPrefFile();
422 h = GetResource('GU\267I', GUSIOPTIONS_ID);
423 }
424 if ( h ) GUSILoadConfiguration(h);
425 if ( prefrh != -1) CloseResFile(prefrh);
426 UseResFile(oldrh);
427}
428#endif /* USE_GUSI */