blob: 4bdab5c62b52948dbaa09fe8eead33e84238cb5c [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 *
35getpythonpath()
36{
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 Jansen12fce3e1995-08-14 12:31:44 +0000213
214 /*
215 ** Remember old resource file and try to open preferences file
216 ** in the preferences folder.
217 */
218 oldrh = CurResFile();
219 if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
220 &prefdirDirID) == noErr ) {
221 (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
222 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
223 }
224 /* At this point, we may or may not have the preferences file open, and it
225 ** may or may not contain a sys.path STR# resource. We don't care, if it doesn't
226 ** exist we use the one from the application (the default).
227 ** We put an initial '\n' in front of the path that we don't return to the caller
228 */
229 if( (rv = malloc(2)) == NULL )
230 goto out;
231 strcpy(rv, "\n");
Jack Jansena486a551996-04-04 15:39:18 +0000232 /*
233 ** See whether there's an override.
234 */
235 GetIndString(pathitem, PYTHONPATHOVERRIDE_ID, 1);
236 if ( pathitem[0] )
237 resource_id = PYTHONPATHOVERRIDE_ID;
238 else
239 resource_id = PYTHONPATH_ID;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000240 for(i=1; ; i++) {
Jack Jansena486a551996-04-04 15:39:18 +0000241 GetIndString(pathitem, resource_id, i);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000242 if( pathitem[0] == 0 )
243 break;
244 if ( pathitem[0] >= 9 && strncmp((char *)pathitem+1, "$(PYTHON)", 9) == 0 ) {
245 /* We have to put the directory in place */
246 newlen = strlen(rv) + strlen(dir) + (pathitem[0]-9) + 2;
247 if( (rv=realloc(rv, newlen)) == NULL)
248 goto out;
249 strcat(rv, dir);
250 /* Skip a colon at the beginning of the item */
251 if ( pathitem[0] > 9 && pathitem[1+9] == ':' ) {
252 memcpy(rv+strlen(rv), pathitem+1+10, pathitem[0]-10);
253 newlen--;
254 } else {
255 memcpy(rv+strlen(rv), pathitem+1+9, pathitem[0]-9);
256 }
257 rv[newlen-2] = '\n';
258 rv[newlen-1] = 0;
Jack Jansena486a551996-04-04 15:39:18 +0000259 } else if ( pathitem[0] >= 14 && strncmp((char *)pathitem+1, "$(APPLICATION)", 14) == 0 ) {
260 /* This is the application itself */
261 char fullname[256];
262
263 if ( (err=PyMac_process_location(&dirspec)) != 0 ) {
264 printf("Cannot get FSSpec for application, error %d\n", err);
265 exit(1);
266 }
267 if ( nfullpath(&dirspec, fullname) != 0 ) {
268 printf("Cannot convert application fsspec to path\n");
269 exit(1);
270 }
271 newlen = strlen(rv) + strlen(fullname) + 2;
272 if( (rv=realloc(rv, newlen)) == NULL)
273 goto out;
274 strcpy(rv+strlen(rv), fullname);
275 rv[newlen-2] = '\n';
276 rv[newlen-1] = 0;
277
Jack Jansen12fce3e1995-08-14 12:31:44 +0000278 } else {
279 /* Use as-is */
280 newlen = strlen(rv) + (pathitem[0]) + 2;
281 if( (rv=realloc(rv, newlen)) == NULL)
282 goto out;
283 memcpy(rv+strlen(rv), pathitem+1, pathitem[0]);
284 rv[newlen-2] = '\n';
285 rv[newlen-1] = 0;
286 }
287 }
288 if( strlen(rv) == 1) {
289 free(rv);
290 rv = NULL;
291 }
292 if ( rv ) {
293 rv[strlen(rv)-1] = 0;
294 rv++;
295 }
296out:
297 if ( prefrh ) {
298 CloseResFile(prefrh);
299 UseResFile(oldrh);
300 }
301 return rv;
302}
303#endif /* !USE_BUILTIN_PATH */
304
Jack Jansena4b7e141996-02-21 16:46:57 +0000305void
306PyMac_PreferenceOptions(int *inspect, int *verbose, int *suppress_print,
307 int *unbuffered, int *debugging, int *keep_normal,
308 int *keep_error)
309{
310 short oldrh, prefrh;
311 Handle handle;
312 int size;
313 char *p;
314
315
316 oldrh = CurResFile();
317 prefrh = PyMac_OpenPrefFile();
Jack Jansena486a551996-04-04 15:39:18 +0000318 handle = GetResource('Popt', PYTHONOPTIONSOVERRIDE_ID);
319 if ( handle == NULL )
320 handle = GetResource('Popt', PYTHONOPTIONS_ID);
Jack Jansena4b7e141996-02-21 16:46:57 +0000321 if ( handle == NULL ) {
322 return;
323 }
324 HLock(handle);
325 size = GetHandleSize(handle);
326 p = (char *)*handle;
327
328 if ( size > POPT_INSPECT ) *inspect = p[POPT_INSPECT];
329 if ( size > POPT_VERBOSE ) *verbose = p[POPT_VERBOSE];
330 if ( size > POPT_SUPPRESS ) *suppress_print = p[POPT_SUPPRESS];
331 if ( size > POPT_UNBUFFERED ) *unbuffered = p[POPT_UNBUFFERED];
332 if ( size > POPT_DEBUGGING ) *debugging = p[POPT_DEBUGGING];
333 if ( size > POPT_KEEPNORM ) *keep_normal = p[POPT_KEEPNORM];
334 if ( size > POPT_KEEPERR ) *keep_error = p[POPT_KEEPERR];
335
336 HUnlock(handle);
337
338 CloseResFile(prefrh);
339 UseResFile(oldrh);
340}