blob: 4d9b8da227caeed7ca94794d5be6c56c16b4e59f [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>
24
25#define PYTHONPATH "\
26:\n\
27:Lib\n\
28:Lib:stdwin\n\
29:Lib:test\n\
30:Lib:mac"
31
32
33char *
34getpythonpath()
35{
36 /* Modified by Jack to do something a bit more sensible:
37 ** - Prepend the python home-directory (which is obtained from a Preferences
38 ** resource)
39 ** - Add :
40 */
41 static char *pythonpath;
42 char *curwd;
43 char *p, *endp;
44 int newlen;
45 extern char *PyMac_GetPythonDir();
46#ifndef USE_BUILTIN_PATH
47 extern char *PyMac_GetPythonPath();
48#endif
49
50 if ( pythonpath ) return pythonpath;
51 curwd = PyMac_GetPythonDir();
52#ifndef USE_BUILTIN_PATH
53 if ( pythonpath = PyMac_GetPythonPath(curwd) )
54 return pythonpath;
55 printf("Warning: No pythonpath resource found, using builtin default\n");
56#endif
57 p = PYTHONPATH;
58 endp = p;
59 pythonpath = malloc(2);
60 if ( pythonpath == NULL ) return PYTHONPATH;
61 strcpy(pythonpath, ":");
62 while (*endp) {
63 endp = strchr(p, '\n');
64 if ( endp == NULL )
65 endp = p + strlen(p);
66 newlen = strlen(pythonpath) + 1 + strlen(curwd) + (endp-p);
67 pythonpath = realloc(pythonpath, newlen+1);
68 if ( pythonpath == NULL ) return PYTHONPATH;
69 strcat(pythonpath, "\n");
70 if ( *p == ':' ) {
71 p++;
72 strcat(pythonpath, curwd);
73 strncat(pythonpath, p, (endp-p));
74 newlen--; /* Ok, ok, we've allocated one byte too much */
75 } else {
76 /* We've allocated too much in this case */
77 newlen -= strlen(curwd);
78 pythonpath = realloc(pythonpath, newlen+1);
79 if ( pythonpath == NULL ) return PYTHONPATH;
80 strncat(pythonpath, p, (endp-p));
81 }
82 pythonpath[newlen] = '\0';
83 p = endp + 1;
84 }
85 return pythonpath;
86}
87
Jack Jansen41fa7ea1995-08-31 13:59:36 +000088/*
89** Open/create the Python Preferences file, return the handle
90*/
91short
92PyMac_OpenPrefFile()
93{
94 AliasHandle handle;
95 FSSpec dirspec;
96 short prefrh;
97 short prefdirRefNum;
98 long prefdirDirID;
99 short action;
100
101 if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
102 &prefdirDirID) != noErr ) {
103 /* Something wrong with preferences folder */
104 (void)StopAlert(NOPREFDIR_ID, NULL);
105 exit(1);
106 }
107
108 (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
109 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
110 if ( prefrh < 0 ) {
111 action = CautionAlert(NOPREFFILE_ID, NULL);
112 if ( action == NOPREFFILE_NO )
113 exit(1);
114
115 FSpCreateResFile(&dirspec, 'PYTH', 'pref', 0);
116 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
117 if ( prefrh == -1 ) {
118 /* This "cannot happen":-) */
119 printf("Cannot create preferences file!!\n");
120 exit(1);
121 }
122 if ( PyMac_process_location(&dirspec) != 0 ) {
123 printf("Cannot get FSSpec for application!!\n");
124 exit(1);
125 }
126 dirspec.name[0] = 0;
127 if (NewAlias(NULL, &dirspec, &handle) != 0 ) {
128 printf("Cannot make alias to application directory!!\n");
129 exit(1);
130 }
131 AddResource((Handle)handle, 'alis', PYTHONHOME_ID, "\p");
132 UpdateResFile(prefrh);
133
134 } else {
135 UseResFile(prefrh);
136 }
137 return prefrh;
138}
Jack Jansen12fce3e1995-08-14 12:31:44 +0000139
140/*
141** Return the name of the Python directory
142*/
143char *
144PyMac_GetPythonDir()
145{
Jack Jansen12fce3e1995-08-14 12:31:44 +0000146 static char name[256];
147 AliasHandle handle;
148 FSSpec dirspec;
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000149 Boolean modified = 0;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000150 short oldrh, prefrh;
Jack Jansen12fce3e1995-08-14 12:31:44 +0000151
152 /*
153 ** Remember old resource file and try to open preferences file
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000154 ** in the preferences folder.
Jack Jansen12fce3e1995-08-14 12:31:44 +0000155 */
156 oldrh = CurResFile();
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000157 prefrh = PyMac_OpenPrefFile();
Jack Jansen12fce3e1995-08-14 12:31:44 +0000158 /* So, we've opened our preferences file, we hope. Look for the alias */
159 handle = (AliasHandle)Get1Resource('alis', PYTHONHOME_ID);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000160 if ( handle == NULL ) {
161 (void)StopAlert(BADPREFFILE_ID, NULL);
162 exit(1);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000163 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000164 /* It exists. Resolve it (possibly updating it) */
165 if ( ResolveAlias(NULL, handle, &dirspec, &modified) != noErr ) {
166 (void)StopAlert(BADPREFFILE_ID, NULL);
167 exit(1);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000168 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000169 if ( modified ) {
170 ChangedResource((Handle)handle);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000171 UpdateResFile(prefrh);
172 }
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000173 CloseResFile(prefrh);
Jack Jansen12fce3e1995-08-14 12:31:44 +0000174 UseResFile(oldrh);
Jack Jansen41fa7ea1995-08-31 13:59:36 +0000175
176 if ( nfullpath(&dirspec, name) == 0 ) {
177 strcat(name, ":");
178 } else {
179 /* If all fails, we return the current directory */
180 printf("Python home dir exists but I cannot find the pathname!!\n");
Jack Jansen12fce3e1995-08-14 12:31:44 +0000181 name[0] = 0;
182 (void)getwd(name);
183 }
184 return name;
185}
186
187#ifndef USE_BUILTIN_PATH
188char *
189PyMac_GetPythonPath(dir)
190char *dir;
191{
192 FSSpec dirspec;
193 short oldrh, prefrh = -1;
194 short prefdirRefNum;
195 long prefdirDirID;
196 char *rv;
197 int i, newlen;
198 Str255 pathitem;
199
200 /*
201 ** Remember old resource file and try to open preferences file
202 ** in the preferences folder.
203 */
204 oldrh = CurResFile();
205 if ( FindFolder(kOnSystemDisk, 'pref', kDontCreateFolder, &prefdirRefNum,
206 &prefdirDirID) == noErr ) {
207 (void)FSMakeFSSpec(prefdirRefNum, prefdirDirID, "\pPython Preferences", &dirspec);
208 prefrh = FSpOpenResFile(&dirspec, fsRdWrShPerm);
209 }
210 /* At this point, we may or may not have the preferences file open, and it
211 ** may or may not contain a sys.path STR# resource. We don't care, if it doesn't
212 ** exist we use the one from the application (the default).
213 ** We put an initial '\n' in front of the path that we don't return to the caller
214 */
215 if( (rv = malloc(2)) == NULL )
216 goto out;
217 strcpy(rv, "\n");
218 for(i=1; ; i++) {
219 GetIndString(pathitem, PYTHONPATH_ID, i);
220 if( pathitem[0] == 0 )
221 break;
222 if ( pathitem[0] >= 9 && strncmp((char *)pathitem+1, "$(PYTHON)", 9) == 0 ) {
223 /* We have to put the directory in place */
224 newlen = strlen(rv) + strlen(dir) + (pathitem[0]-9) + 2;
225 if( (rv=realloc(rv, newlen)) == NULL)
226 goto out;
227 strcat(rv, dir);
228 /* Skip a colon at the beginning of the item */
229 if ( pathitem[0] > 9 && pathitem[1+9] == ':' ) {
230 memcpy(rv+strlen(rv), pathitem+1+10, pathitem[0]-10);
231 newlen--;
232 } else {
233 memcpy(rv+strlen(rv), pathitem+1+9, pathitem[0]-9);
234 }
235 rv[newlen-2] = '\n';
236 rv[newlen-1] = 0;
237 } else {
238 /* Use as-is */
239 newlen = strlen(rv) + (pathitem[0]) + 2;
240 if( (rv=realloc(rv, newlen)) == NULL)
241 goto out;
242 memcpy(rv+strlen(rv), pathitem+1, pathitem[0]);
243 rv[newlen-2] = '\n';
244 rv[newlen-1] = 0;
245 }
246 }
247 if( strlen(rv) == 1) {
248 free(rv);
249 rv = NULL;
250 }
251 if ( rv ) {
252 rv[strlen(rv)-1] = 0;
253 rv++;
254 }
255out:
256 if ( prefrh ) {
257 CloseResFile(prefrh);
258 UseResFile(oldrh);
259 }
260 return rv;
261}
262#endif /* !USE_BUILTIN_PATH */
263