1 /***********************************************************
2 Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
36 #include "pythonresources.h"
41 #ifdef TARGET_API_MAC_OSX
42 #define PATHNAMELEN 1024
44 #define PATHNAMELEN 256
47 /* Return the initial python search path. This is called once from
48 ** initsys() to initialize sys.path.
50 ** If USE_BUILTIN_PATH is defined the path defined here is used
51 ** (after prepending the python home dir to each item).
52 ** If it is not defined the path is gotten from a resource in the
55 ** XXXX This code needs cleaning up. The routines here have moved
56 ** around quite a bit, and they're pretty messy for that reason.
62 #include <Resources.h>
63 #include <TextUtils.h>
70 #ifndef USE_BUILTIN_PATH
71 staticforward
char *PyMac_GetPythonPath();
82 getpreffilefss(FSSpec
*fssp
)
84 static int diditbefore
=0;
94 if ( (namehandle
=GetNamedResource('STR ', PREFFILENAME_NAME
)) == NULL
) {
95 (void)StopAlert(NOPREFNAME_ID
, NULL
);
99 if ( **namehandle
== '\0' ) {
100 /* Empty string means don't use preferences file */
103 /* There is a filename, construct the fsspec */
104 if ( FindFolder(kOnSystemDisk
, 'pref', kDontCreateFolder
, &prefdirRefNum
,
105 &prefdirDirID
) != noErr
) {
106 /* Something wrong with preferences folder */
107 (void)StopAlert(NOPREFDIR_ID
, NULL
);
110 /* make fsspec for the "Python" folder inside the prefs folder */
111 err
= FSMakeFSSpec(prefdirRefNum
, prefdirDirID
, "\pPython", &fss
);
113 /* it doesn't exist: create it */
114 err
= FSpDirCreate(&fss
, smSystemScript
, &pyprefdirDirID
);
116 /* it does exist, now find out the dirID of the Python prefs folder, brrr. */
118 info
.dirInfo
.ioVRefNum
= fss
.vRefNum
;
119 info
.dirInfo
.ioDrDirID
= fss
.parID
;
120 info
.dirInfo
.ioNamePtr
= fss
.name
;
121 info
.dirInfo
.ioFDirIndex
= 0;
122 info
.dirInfo
.ioACUser
= 0;
123 err
= PBGetCatInfo(&info
, 0);
125 pyprefdirDirID
= info
.dirInfo
.ioDrDirID
;
129 (void)StopAlert(NOPREFDIR_ID
, NULL
);
133 err
= FSMakeFSSpec(fss
.vRefNum
, pyprefdirDirID
, (unsigned char *)*namehandle
, &fss
);
135 if (err
!= noErr
&& err
!= fnfErr
) {
136 (void)StopAlert(NOPREFDIR_ID
, NULL
);
140 ReleaseResource(namehandle
);
150 /* Modified by Jack to do something a bit more sensible:
151 ** - Prepend the python home-directory (which is obtained from a Preferences
155 static char *pythonpath
;
160 if ( pythonpath
) return pythonpath
;
161 #ifndef USE_BUILTIN_PATH
162 if ( pythonpath
= PyMac_GetPythonPath() )
164 printf("Warning: No pythonpath resource found, using builtin default\n");
166 curwd
= PyMac_GetPythonDir();
169 pythonpath
= malloc(2);
170 if ( pythonpath
== NULL
) return PYTHONPATH
;
171 strcpy(pythonpath
, ":");
173 endp
= strchr(p
, '\n');
175 endp
= p
+ strlen(p
);
176 newlen
= strlen(pythonpath
) + 1 + strlen(curwd
) + (endp
-p
);
177 pythonpath
= realloc(pythonpath
, newlen
+1);
178 if ( pythonpath
== NULL
) return PYTHONPATH
;
179 strcat(pythonpath
, "\n");
182 strcat(pythonpath
, curwd
);
183 strncat(pythonpath
, p
, (endp
-p
));
184 newlen
--; /* Ok, ok, we've allocated one byte too much */
186 /* We've allocated too much in this case */
187 newlen
-= strlen(curwd
);
188 pythonpath
= realloc(pythonpath
, newlen
+1);
189 if ( pythonpath
== NULL
) return PYTHONPATH
;
190 strncat(pythonpath
, p
, (endp
-p
));
192 pythonpath
[newlen
] = '\0';
200 ** Open/create the Python Preferences file, return the handle
210 if ( !getpreffilefss(&dirspec
))
212 prefrh
= FSpOpenResFile(&dirspec
, fsRdWrShPerm
);
215 action
= CautionAlert(NOPREFFILE_ID
, NULL
);
216 if ( action
== NOPREFFILE_NO
)
219 FSpCreateResFile(&dirspec
, 'Pyth', 'pref', 0);
220 prefrh
= FSpOpenResFile(&dirspec
, fsRdWrShPerm
);
221 if ( prefrh
== -1 ) {
222 /* This "cannot happen":-) */
223 printf("Cannot create preferences file, error %d\n", ResError());
226 if ( (err
=PyMac_init_process_location()) != 0 ) {
227 printf("Cannot get application location, error %d\n", err
);
230 dirspec
= PyMac_ApplicationFSSpec
;
232 if ((err
=NewAlias(NULL
, &dirspec
, &handle
)) != 0 ) {
233 printf("Cannot make alias to application directory, error %d\n", err
);
236 AddResource((Handle
)handle
, 'alis', PYTHONHOME_ID
, "\p");
237 UpdateResFile(prefrh
);
246 ** Return the name of the Python directory
251 static int diditbefore
= 0;
252 static char name
[PATHNAMELEN
] = {':', '\0'};
255 Boolean modified
= 0;
256 short oldrh
, prefrh
= -1, homerh
;
261 oldrh
= CurResFile();
263 /* First look for an override in the application file */
264 UseResFile(PyMac_AppRefNum
);
265 handle
= (AliasHandle
)Get1Resource('alis', PYTHONHOMEOVERRIDE_ID
);
267 if ( handle
!= NULL
) {
268 homerh
= PyMac_AppRefNum
;
270 /* Try to open preferences file in the preferences folder. */
271 prefrh
= PyMac_OpenPrefFile();
272 handle
= (AliasHandle
)Get1Resource('alis', PYTHONHOME_ID
);
273 if ( handle
== NULL
) {
274 /* (void)StopAlert(BADPREFFILE_ID, NULL); */
280 /* It exists. Resolve it (possibly updating it) */
281 if ( ResolveAlias(NULL
, handle
, &dirspec
, &modified
) != noErr
) {
282 (void)StopAlert(BADPREFFILE_ID
, NULL
);
287 ChangedResource((Handle
)handle
);
288 UpdateResFile(homerh
);
290 if ( prefrh
!= -1 ) CloseResFile(prefrh
);
293 if ( PyMac_GetFullPathname(&dirspec
, name
, PATHNAMELEN
) == 0 ) {
296 /* If all fails, we return the current directory */
297 printf("Python home dir exists but I cannot find the pathname!!\n");
299 (void)getcwd(name
, sizeof(name
));
305 #ifndef USE_BUILTIN_PATH
307 PyMac_GetPythonPath(void)
309 short oldrh
, prefrh
= -1;
317 oldrh
= CurResFile();
319 ** This is a bit tricky. We check here whether the application file
320 ** contains an override. This is to forestall us finding another STR# resource
321 ** with "our" id and using that for path initialization
323 UseResFile(PyMac_AppRefNum
);
325 if ( (h
=Get1Resource('STR#', PYTHONPATHOVERRIDE_ID
)) ) {
327 resource_id
= PYTHONPATHOVERRIDE_ID
;
329 resource_id
= PYTHONPATH_ID
;
334 /* Open the preferences file only if there is no override */
335 if ( resource_id
!= PYTHONPATHOVERRIDE_ID
)
336 prefrh
= PyMac_OpenPrefFile();
337 /* At this point, we may or may not have the preferences file open, and it
338 ** may or may not contain a sys.path STR# resource. We don't care, if it doesn't
339 ** exist we use the one from the application (the default).
340 ** We put an initial '\n' in front of the path that we don't return to the caller
342 if( (rv
= malloc(2)) == NULL
)
347 GetIndString(pathitem
, resource_id
, i
);
348 if( pathitem
[0] == 0 )
350 if ( pathitem
[0] >= 9 && strncmp((char *)pathitem
+1, "$(PYTHON)", 9) == 0 ) {
351 /* We have to put the directory in place */
352 char *dir
= PyMac_GetPythonDir();
354 newlen
= strlen(rv
) + strlen(dir
) + (pathitem
[0]-9) + 2;
355 if( (rv
=realloc(rv
, newlen
)) == NULL
)
358 /* Skip a colon at the beginning of the item */
359 if ( pathitem
[0] > 9 && pathitem
[1+9] == ':' ) {
360 memcpy(rv
+strlen(rv
), pathitem
+1+10, pathitem
[0]-10);
363 memcpy(rv
+strlen(rv
), pathitem
+1+9, pathitem
[0]-9);
367 } else if ( pathitem
[0] >= 14 && strncmp((char *)pathitem
+1, "$(APPLICATION)", 14) == 0 ) {
368 /* This is the application itself */
370 if ( (err
=PyMac_init_process_location()) != 0 ) {
371 printf("Cannot get application location, error %d\n", err
);
375 newlen
= strlen(rv
) + strlen(PyMac_ApplicationPath
) + 2;
376 if( (rv
=realloc(rv
, newlen
)) == NULL
)
378 strcpy(rv
+strlen(rv
), PyMac_ApplicationPath
);
384 newlen
= strlen(rv
) + (pathitem
[0]) + 2;
385 if( (rv
=realloc(rv
, newlen
)) == NULL
)
387 memcpy(rv
+strlen(rv
), pathitem
+1, pathitem
[0]);
392 if( strlen(rv
) == 1) {
397 rv
[strlen(rv
)-1] = 0;
401 if ( prefrh
!= -1) CloseResFile(prefrh
);
405 #endif /* !USE_BUILTIN_PATH */
408 PyMac_PreferenceOptions(PyMac_PrefRecord
*pr
)
410 short oldrh
, prefrh
= -1;
417 oldrh
= CurResFile();
419 /* Attempt to load overrides from application */
420 UseResFile(PyMac_AppRefNum
);
421 handle
= Get1Resource('Popt', PYTHONOPTIONSOVERRIDE_ID
);
424 /* Otherwise get options from prefs file or any other open resource file */
425 if ( handle
== NULL
) {
426 prefrh
= PyMac_OpenPrefFile();
427 handle
= GetResource('Popt', PYTHONOPTIONS_ID
);
429 if ( handle
== NULL
) {
433 size
= GetHandleSize(handle
);
434 p
= (PyMac_PrefRecord
*)*handle
;
435 if ( p
->version
== POPT_VERSION_CURRENT
&& size
== sizeof(PyMac_PrefRecord
) ) {
438 action
= CautionAlert(BADPREFERENCES_ID
, NULL
);
439 if ( action
== BADPREF_DELETE
) {
442 RemoveResource(handle
);
443 if ( (err
=ResError()) ) printf("RemoveResource: %d\n", err
);
444 if ( prefrh
!= -1 ) {
445 UpdateResFile(prefrh
);
446 if ( (err
=ResError()) ) printf("UpdateResFile: %d\n", err
);
448 } else if ( action
== BADPREF_QUIT
)
453 if ( prefrh
!= -1) CloseResFile(prefrh
);
459 PyMac_SetGUSIOptions()
462 short oldrh
, prefrh
= -1;
464 oldrh
= CurResFile();
466 /* Try override from the application resource fork */
467 UseResFile(PyMac_AppRefNum
);
468 h
= Get1Resource('GU\267I', GUSIOPTIONSOVERRIDE_ID
);
471 /* If that didn't work try nonoverride from anywhere */
473 prefrh
= PyMac_OpenPrefFile();
474 h
= GetResource('GU\267I', GUSIOPTIONS_ID
);
476 if ( h
) GUSILoadConfiguration(h
);
477 if ( prefrh
!= -1) CloseResFile(prefrh
);
480 #endif /* USE_GUSI1 */