blob: c72bc33774e07a4d600b638029b75d397cdbc69f [file] [log] [blame]
Guido van Rossumb0f3c821994-08-23 13:34:25 +00001/***********************************************************
Jack Jansen42218ce1997-01-31 16:15:11 +00002Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
Guido van Rossum99546991995-01-08 14:33:34 +00003The Netherlands.
Guido van Rossumb0f3c821994-08-23 13:34:25 +00004
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 not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Jack Jansen696c9581995-08-14 12:33:20 +000025/* Python interpreter main program */
Guido van Rossumb0f3c821994-08-23 13:34:25 +000026
Jack Jansen696c9581995-08-14 12:33:20 +000027#include "Python.h"
28#include "pythonresources.h"
29#include "import.h"
30#include "marshal.h"
Jack Jansenf6865f71996-09-04 15:24:59 +000031#include "macglue.h"
Guido van Rossumb0f3c821994-08-23 13:34:25 +000032
Jack Jansen696c9581995-08-14 12:33:20 +000033#include <Memory.h>
34#include <Resources.h>
Guido van Rossumb0f3c821994-08-23 13:34:25 +000035#include <stdio.h>
Jack Jansen696c9581995-08-14 12:33:20 +000036#include <Events.h>
37#include <Windows.h>
Jack Jansen2429c721996-03-07 15:17:11 +000038#include <Fonts.h>
Jack Jansen36b983c1997-09-09 13:53:21 +000039#include <Balloons.h>
Jack Jansen8f5725a1999-12-07 23:08:10 +000040#ifdef USE_APPEARANCE
41#include <Gestalt.h>
42#include <Appearance.h>
43#endif /* USE_APPEARANCE */
Jack Jansenc76fd391995-02-02 14:27:31 +000044#ifdef __MWERKS__
45#include <SIOUX.h>
Jack Jansen1e8557a1995-11-10 14:51:26 +000046#define USE_SIOUX
Jack Jansen9ae898b2000-07-11 21:16:03 +000047extern int ccommand(char ***);
Jack Jansen8c693211997-01-07 16:19:42 +000048#if __profile__ == 1
49#include <profiler.h>
50#endif
Jack Jansenc76fd391995-02-02 14:27:31 +000051#endif
Jack Jansenee6eeb12000-06-02 21:28:52 +000052#include <unistd.h>
Jack Jansen5bdbabd2000-07-24 19:52:52 +000053#ifdef USE_MAC_SHARED_LIBRARY
54extern PyMac_AddLibResources(void);
55#endif
Jack Jansen8a387142001-02-11 01:08:04 +000056//#ifdef USE_GUSI
57//#include "GUSISIOUX.h"
58//#endif
Jack Jansenc76fd391995-02-02 14:27:31 +000059
Jack Jansen696c9581995-08-14 12:33:20 +000060#define STARTUP "PythonStartup"
Jack Jansenbac428d1994-12-14 13:47:30 +000061
Jack Jansen65c3ee02000-09-08 10:20:37 +000062#define COPYRIGHT \
63 "Type \"copyright\", \"credits\" or \"license\" for more information."
64
Jack Jansen3f7d2b41996-09-06 22:21:07 +000065short PyMac_AppRefNum; /* RefNum of application resource fork */
Jack Jansen696c9581995-08-14 12:33:20 +000066
Jack Jansen1d2f8631996-08-02 15:16:16 +000067/* For Py_GetArgcArgv(); set by main() */
Jack Jansen696c9581995-08-14 12:33:20 +000068static char **orig_argv;
69static int orig_argc;
70
Jack Jansen8a387142001-02-11 01:08:04 +000071/* A flag which remembers whether the user has acknowledged all the console
72** output (by typing something)
73*/
74#define STATE_UNKNOWN 0
75#define STATE_LASTREAD 1
76#define STATE_LASTWRITE 2
77int console_output_state = STATE_UNKNOWN;
78
Jack Jansendc86f9e2000-10-12 21:23:19 +000079PyMac_PrefRecord PyMac_options;
Jack Jansen0168f271995-10-27 13:32:30 +000080
Jack Jansend88296d2000-07-11 19:51:05 +000081static void Py_Main(int, char **); /* Forward */
82void PyMac_Exit(int); /* Forward */
Jack Jansen76ceece1996-08-19 11:18:24 +000083
Jack Jansen8f5725a1999-12-07 23:08:10 +000084static void init_appearance()
85{
86#ifdef USE_APPEARANCE
87 OSErr err;
88 SInt32 response;
89
90 err = Gestalt(gestaltAppearanceAttr,&response);
91 if ( err ) goto no_appearance;
92 if ( !(response&(1<<gestaltAppearanceExists)) ) goto no_appearance;
93 /* XXXX Should we check the version? Compat-mode? */
94 PyMac_AppearanceCompliant = 1;
95no_appearance:
96 return;
97#endif /* USE_APPEARANCE */
98}
Jack Jansen01fbc681996-02-28 15:42:47 +000099/* Initialize the Mac toolbox world */
100
101static void
102init_mac_world()
103{
Jack Jansen74a1e632000-07-14 22:37:27 +0000104#if !TARGET_API_MAC_CARBON
Jack Jansenee6eeb12000-06-02 21:28:52 +0000105 /* These aren't needed for carbon */
Jack Jansen01fbc681996-02-28 15:42:47 +0000106 MaxApplZone();
107 InitGraf(&qd.thePort);
108 InitFonts();
109 InitWindows();
110 TEInit();
111 InitDialogs((long)0);
112 InitMenus();
Jack Jansenee6eeb12000-06-02 21:28:52 +0000113#endif
Jack Jansen01fbc681996-02-28 15:42:47 +0000114 InitCursor();
Jack Jansen8f5725a1999-12-07 23:08:10 +0000115 init_appearance();
Jack Jansen01fbc681996-02-28 15:42:47 +0000116}
117
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000118/*
119** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
120*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000121static void
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000122PyMac_InteractiveOptions(PyMac_PrefRecord *p, int *argcp, char ***argvp)
123{
124 KeyMap rmap;
125 unsigned char *map;
126 short item, type;
127 ControlHandle handle;
128 DialogPtr dialog;
129 Rect rect;
130 int old_argc = *argcp;
131 int i;
132
133 /*
134 ** If the preferences disallows interactive options we return,
135 ** similarly of <option> isn't pressed.
136 */
137 if (p->nointopt) return;
138
139 GetKeys(rmap);
140 map = (unsigned char *)rmap;
141 if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
142 return;
143
144 dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
145 if ( dialog == NULL ) {
146 printf("Option dialog not found - cannot set options\n");
147 return;
148 }
149 SetDialogDefaultItem(dialog, OPT_OK);
150 SetDialogCancelItem(dialog, OPT_CANCEL);
151
152 /* Set default values */
153#define SET_OPT_ITEM(num, var) \
154 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
Jack Jansen08c3be31997-04-08 15:27:00 +0000155 SetControlValue(handle, (short)p->var);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000156
157 SET_OPT_ITEM(OPT_INSPECT, inspect);
158 SET_OPT_ITEM(OPT_VERBOSE, verbose);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000159 /* OPT_VERBOSEVERBOSE is default off */
Jack Jansen36b983c1997-09-09 13:53:21 +0000160 SET_OPT_ITEM(OPT_OPTIMIZE, optimize);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000161 SET_OPT_ITEM(OPT_UNBUFFERED, unbuffered);
162 SET_OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen4a5eb962000-09-22 21:50:11 +0000163 GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
164 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
165 GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
166 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
167 GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
168 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
169 GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
170 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
171/* SET_OPT_ITEM(OPT_KEEPCONSOLE, keep_console); */
Jack Jansen0c6d0372000-05-05 23:11:14 +0000172 SET_OPT_ITEM(OPT_TABWARN, tabwarn);
Jack Jansen36b983c1997-09-09 13:53:21 +0000173 SET_OPT_ITEM(OPT_NOSITE, nosite);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000174 SET_OPT_ITEM(OPT_DIVISIONWARN, divisionwarn);
175 SET_OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000176 /* The rest are not settable interactively */
177
178#undef SET_OPT_ITEM
179
180 while (1) {
181 handle = NULL;
182 ModalDialog(NULL, &item);
183 if ( item == OPT_OK )
184 break;
185 if ( item == OPT_CANCEL ) {
Jack Jansen08c3be31997-04-08 15:27:00 +0000186 DisposeDialog(dialog);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000187 exit(0);
188 }
Jack Jansen74a1e632000-07-14 22:37:27 +0000189#if !TARGET_API_MAC_CARBON
Jack Jansen36b983c1997-09-09 13:53:21 +0000190 if ( item == OPT_HELP ) {
191 HMSetBalloons(!HMGetBalloons());
192 }
Jack Jansenee6eeb12000-06-02 21:28:52 +0000193#endif
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000194 if ( item == OPT_CMDLINE ) {
195 int new_argc, newer_argc;
196 char **new_argv, **newer_argv;
197
198 new_argc = ccommand(&new_argv);
199 newer_argc = (new_argc-1) + old_argc;
200 newer_argv = malloc((newer_argc+1)*sizeof(char *));
201 if( !newer_argv )
202 Py_FatalError("Cannot malloc argv\n");
203 for(i=0; i<old_argc; i++)
204 newer_argv[i] = (*argvp)[i];
205 for(i=old_argc; i<=newer_argc; i++) /* Copy the NULL too */
206 newer_argv[i] = new_argv[i-old_argc+1];
207 *argvp = newer_argv;
208 *argcp = newer_argc;
209
210 /* XXXX Is it not safe to use free() here, apparently */
211 }
212#define OPT_ITEM(num, var) \
213 if ( item == (num) ) { \
214 p->var = !p->var; \
215 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
Jack Jansen08c3be31997-04-08 15:27:00 +0000216 SetControlValue(handle, (short)p->var); \
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000217 }
218
219 OPT_ITEM(OPT_INSPECT, inspect);
220 OPT_ITEM(OPT_VERBOSE, verbose);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000221 if ( item == OPT_VERBOSEVERBOSE ) {
222 if ( p->verbose == 2 )
223 p->verbose = 1;
224 else
225 p->verbose = 2;
226 GetDialogItem(dialog, OPT_VERBOSE, &type, (Handle *)&handle, &rect);
227 SetControlValue(handle, 1);
228 }
229 GetDialogItem(dialog, OPT_VERBOSEVERBOSE, &type, (Handle *)&handle, &rect);
230 SetControlValue(handle, p->verbose == 2);
Jack Jansen36b983c1997-09-09 13:53:21 +0000231 OPT_ITEM(OPT_OPTIMIZE, optimize);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000232 OPT_ITEM(OPT_UNBUFFERED, unbuffered);
233 OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen4a5eb962000-09-22 21:50:11 +0000234 if ( item == OPT_KEEPALWAYS ) p->keep_console = POPT_KEEPCONSOLE_ALWAYS;
235 if ( item == OPT_KEEPOUTPUT ) p->keep_console = POPT_KEEPCONSOLE_OUTPUT;
236 if ( item == OPT_KEEPERROR ) p->keep_console = POPT_KEEPCONSOLE_ERROR;
237 if ( item == OPT_KEEPNEVER ) p->keep_console = POPT_KEEPCONSOLE_NEVER;
238 GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
239 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
240 GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
241 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
242 GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
243 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
244 GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
245 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
Jack Jansen0c6d0372000-05-05 23:11:14 +0000246 OPT_ITEM(OPT_TABWARN, tabwarn);
Jack Jansen36b983c1997-09-09 13:53:21 +0000247 OPT_ITEM(OPT_NOSITE, nosite);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000248 OPT_ITEM(OPT_DIVISIONWARN, divisionwarn);
249 OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000250
251#undef OPT_ITEM
252 }
Jack Jansen08c3be31997-04-08 15:27:00 +0000253 DisposeDialog(dialog);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000254}
255
256/*
257** Initialization code, shared by interpreter and applets
258*/
259static void
Jack Jansen52ac0371997-01-15 15:49:08 +0000260init_common(int *argcp, char ***argvp, int embedded)
Jack Jansen01fbc681996-02-28 15:42:47 +0000261{
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000262 /* Remember resource fork refnum, for later */
263 PyMac_AppRefNum = CurResFile();
264
Jack Jansen01fbc681996-02-28 15:42:47 +0000265 /* Initialize toolboxes */
266 init_mac_world();
267
268#ifdef USE_MAC_SHARED_LIBRARY
269 /* Add the shared library to the stack of resource files */
Jack Jansen87c485c1998-07-31 09:38:01 +0000270 (void)PyMac_init_process_location();
Jack Jansen01fbc681996-02-28 15:42:47 +0000271 PyMac_AddLibResources();
272#endif
273
Jack Jansen2d1306b2000-04-07 09:10:49 +0000274#if defined(USE_GUSI1)
Jack Jansen01fbc681996-02-28 15:42:47 +0000275 /* Setup GUSI */
276 GUSIDefaultSetup();
Jack Jansenf6865f71996-09-04 15:24:59 +0000277 PyMac_SetGUSISpin();
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000278 PyMac_SetGUSIOptions();
Jack Jansen01fbc681996-02-28 15:42:47 +0000279#endif
Jack Jansen2d1306b2000-04-07 09:10:49 +0000280#if defined(USE_GUSI)
281 atexit(PyMac_StopGUSISpin);
282#endif
Jack Jansen01fbc681996-02-28 15:42:47 +0000283
284#ifdef USE_SIOUX
285 /* Set various SIOUX flags. Some are changed later based on options */
Jack Jansencaa7c461997-06-12 10:49:13 +0000286/* SIOUXSettings.standalone = 0; /* XXXX Attempting to keep sioux from eating events */
Jack Jansen01fbc681996-02-28 15:42:47 +0000287 SIOUXSettings.asktosaveonclose = 0;
288 SIOUXSettings.showstatusline = 0;
289 SIOUXSettings.tabspaces = 4;
290#endif
291
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000292 /* Get options from preference file (or from applet resource fork) */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000293 PyMac_options.keep_console = POPT_KEEPCONSOLE_OUTPUT; /* default-default */
294 PyMac_PreferenceOptions(&PyMac_options);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000295
Jack Jansen52ac0371997-01-15 15:49:08 +0000296 if ( embedded ) {
297 static char *emb_argv[] = {"embedded-python", 0};
298
299 *argcp = 1;
300 *argvp = emb_argv;
301 } else {
302 /* Create argc/argv. Do it before we go into the options event loop. */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000303 *argcp = PyMac_GetArgv(argvp, PyMac_options.noargs);
Jack Jansenc00df0b2001-01-16 15:54:58 +0000304#ifndef NO_ARGV0_CHDIR
Jack Jansen660bb1d2000-07-18 09:40:39 +0000305 if (*argcp >= 1 && (*argvp)[0] && (*argvp)[0][0]) {
306 /* Workaround for MacOS X, which currently (DP4) doesn't set
307 ** the working folder correctly
308 */
309 char app_wd[256], *p;
310
311 strncpy(app_wd, (*argvp)[0], 256);
Jack Jansen660bb1d2000-07-18 09:40:39 +0000312 p = strrchr(app_wd, ':');
313 if ( p ) *p = 0;
Jack Jansen660bb1d2000-07-18 09:40:39 +0000314 chdir(app_wd);
315 }
316#endif
Jack Jansen52ac0371997-01-15 15:49:08 +0000317 /* Do interactive option setting, if allowed and <option> depressed */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000318 PyMac_InteractiveOptions(&PyMac_options, argcp, argvp);
Jack Jansen52ac0371997-01-15 15:49:08 +0000319 }
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000320
321 /* Copy selected options to where the machine-independent stuff wants it */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000322 Py_VerboseFlag = PyMac_options.verbose;
323/* Py_SuppressPrintingFlag = PyMac_options.suppress_print; */
324 Py_OptimizeFlag = PyMac_options.optimize;
325 Py_DebugFlag = PyMac_options.debugging;
326 Py_NoSiteFlag = PyMac_options.nosite;
327 Py_TabcheckFlag = PyMac_options.tabwarn;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000328 Py_DivisionWarningFlag = PyMac_options.divisionwarn;
Jack Jansendc86f9e2000-10-12 21:23:19 +0000329 if ( PyMac_options.noargs ) {
Jack Jansene3ae0df1997-06-03 15:28:29 +0000330 /* don't process events at all without the scripts permission */
331 PyMacSchedParams scp;
332
333 PyMac_GetSchedParams(&scp);
334 scp.process_events = 0;
335 /* Should we disable command-dot as well? */
336 PyMac_SetSchedParams(&scp);
337 }
Jack Jansen36b983c1997-09-09 13:53:21 +0000338 /* XXXX dispatch oldexc and nosite */
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000339
340 /* Set buffering */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000341 if (PyMac_options.unbuffered) {
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000342#ifndef MPW
343 setbuf(stdout, (char *)NULL);
344 setbuf(stderr, (char *)NULL);
345#else
346 /* On MPW (3.2) unbuffered seems to hang */
347 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
348 setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
349#endif
350 }
Jack Jansen8c693211997-01-07 16:19:42 +0000351#if __profile__ == 1
352 /* collectSummary or collectDetailed, timebase, #routines, max stack depth */
Jack Jansene7424871999-09-30 11:20:11 +0000353 ProfilerInit(collectSummary, bestTimeBase, 8000, 250);
Jack Jansen8c693211997-01-07 16:19:42 +0000354#endif
Jack Jansen7330b391997-08-08 14:56:41 +0000355
356 /* Tell the rest of python about our argc/argv */
357 orig_argc = *argcp; /* For Py_GetArgcArgv() */
358 orig_argv = *argvp;
359 Py_SetProgramName((*argvp)[0]);
Jack Jansen01fbc681996-02-28 15:42:47 +0000360}
361
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000362/*
363** Inspection mode after script/applet termination
364*/
365static int
366run_inspect()
367{
368 int sts = 0;
369
Jack Jansendc86f9e2000-10-12 21:23:19 +0000370 if (PyMac_options.inspect && isatty((int)fileno(stdin)))
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000371 sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
372 return sts;
373}
Jack Jansen01fbc681996-02-28 15:42:47 +0000374
Jack Jansen0c6d0372000-05-05 23:11:14 +0000375/*
376** Import the macfsn module, which will override the Standard File
377** calls in the macfs builtin module by Navigation Services versions,
378** if available on this machine.
379*/
380static void
381PyMac_InstallNavServicesForSF()
382{
Jack Jansendc86f9e2000-10-12 21:23:19 +0000383 if ( !PyMac_options.nonavservice ) {
Jack Jansen0c6d0372000-05-05 23:11:14 +0000384 PyObject *m = PyImport_ImportModule("macfsn");
385
386 if ( m == NULL ) {
387 PySys_WriteStderr("'import macfsn' failed; ");
388 if (Py_VerboseFlag) {
389 PySys_WriteStderr("traceback:\n");
390 PyErr_Print();
391 }
392 else {
393 PySys_WriteStderr("use -v for traceback\n");
394 }
395 }
396 }
397}
398
Jack Jansen696c9581995-08-14 12:33:20 +0000399#ifdef USE_MAC_APPLET_SUPPORT
400/* Applet support */
401
402/* Run a compiled Python Python script from 'PYC ' resource __main__ */
403static int
404run_main_resource()
405{
406 Handle h;
407 long size;
408 PyObject *code;
409 PyObject *result;
410
411 h = GetNamedResource('PYC ', "\p__main__");
412 if (h == NULL) {
413 Alert(NOPYC_ALERT, NULL);
414 return 1;
415 }
416 size = GetResourceSizeOnDisk(h);
417 HLock(h);
418 code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
419 HUnlock(h);
420 ReleaseResource(h);
421 if (code == NULL) {
422 PyErr_Print();
423 return 1;
424 }
425 result = PyImport_ExecCodeModule("__main__", code);
426 Py_DECREF(code);
427 if (result == NULL) {
428 PyErr_Print();
429 return 1;
430 }
431 Py_DECREF(result);
432 return 0;
433}
434
435/* Initialization sequence for applets */
436void
437PyMac_InitApplet()
438{
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000439 int argc;
440 char **argv;
Jack Jansen696c9581995-08-14 12:33:20 +0000441 int err;
442
Jack Jansen52ac0371997-01-15 15:49:08 +0000443 init_common(&argc, &argv, 0);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000444
Jack Jansen696c9581995-08-14 12:33:20 +0000445 Py_Initialize();
Jack Jansen0c6d0372000-05-05 23:11:14 +0000446 PyMac_InstallNavServicesForSF();
Jack Jansen696c9581995-08-14 12:33:20 +0000447 PySys_SetArgv(argc, argv);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000448
Jack Jansen696c9581995-08-14 12:33:20 +0000449 err = run_main_resource();
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000450
451 err = (run_inspect() || err);
452
Jack Jansen696c9581995-08-14 12:33:20 +0000453 fflush(stderr);
454 fflush(stdout);
Jack Jansen0168f271995-10-27 13:32:30 +0000455 PyMac_Exit(err);
Jack Jansen696c9581995-08-14 12:33:20 +0000456 /* XXX Should we bother to Py_Exit(sts)? */
457}
458
Jack Jansen52ac0371997-01-15 15:49:08 +0000459/*
460** Hook for embedding python.
461*/
462void
463PyMac_Initialize()
464{
465 int argc;
466 char **argv;
467
468 init_common(&argc, &argv, 1);
469 Py_Initialize();
Jack Jansen0c6d0372000-05-05 23:11:14 +0000470 PyMac_InstallNavServicesForSF();
Jack Jansen52ac0371997-01-15 15:49:08 +0000471 PySys_SetArgv(argc, argv);
472}
473
Jack Jansen696c9581995-08-14 12:33:20 +0000474#endif /* USE_MAC_APPLET_SUPPORT */
475
476/* For normal application */
477void
478PyMac_InitApplication()
479{
480 int argc;
481 char **argv;
482
Jack Jansen52ac0371997-01-15 15:49:08 +0000483 init_common(&argc, &argv, 0);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000484
Jack Jansen696c9581995-08-14 12:33:20 +0000485 if ( argc > 1 ) {
486 /* We're running a script. Attempt to change current directory */
487 char curwd[256], *endp;
488
489 strcpy(curwd, argv[1]);
490 endp = strrchr(curwd, ':');
491 if ( endp && endp > curwd ) {
492 *endp = '\0';
493
494 chdir(curwd);
Jack Jansen2d1306b2000-04-07 09:10:49 +0000495#ifdef USE_GUSI1
Jack Jansen378815c1996-03-06 16:21:34 +0000496 /* Change MacOS's idea of wd too */
497 PyMac_FixGUSIcd();
498#endif
Jack Jansen696c9581995-08-14 12:33:20 +0000499 }
Jack Jansencbed91b2001-08-03 13:31:36 +0000500 /* Check that the first argument is a text file */
501 if ( PyMac_getfiletype(argv[1]) != 'TEXT' ) {
502 Alert(NOTASCRIPT_ID, NULL);
503 exit(0);
504 }
Jack Jansen696c9581995-08-14 12:33:20 +0000505 }
506 Py_Main(argc, argv);
507}
508
Jack Jansen696c9581995-08-14 12:33:20 +0000509/* Main program */
510
Jack Jansen76ceece1996-08-19 11:18:24 +0000511static void
Jack Jansen696c9581995-08-14 12:33:20 +0000512Py_Main(argc, argv)
513 int argc;
514 char **argv;
515{
Jack Jansen696c9581995-08-14 12:33:20 +0000516 int sts;
517 char *command = NULL;
518 char *filename = NULL;
519 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000520
Jack Jansen696c9581995-08-14 12:33:20 +0000521 filename = argv[1];
522
523 if (Py_VerboseFlag ||
524 command == NULL && filename == NULL && isatty((int)fileno(fp)))
Jack Jansen65c3ee02000-09-08 10:20:37 +0000525 fprintf(stderr, "Python %s on %s\n%s\n",
526 Py_GetVersion(), Py_GetPlatform(), COPYRIGHT);
Jack Jansen696c9581995-08-14 12:33:20 +0000527
528 if (filename != NULL) {
529 if ((fp = fopen(filename, "r")) == NULL) {
530 fprintf(stderr, "%s: can't open file '%s'\n",
531 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000532 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000533 }
534 }
535
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000536 /* We initialize the menubar here, hoping SIOUX is initialized by now */
Jack Jansen3469e991996-09-06 00:30:45 +0000537 PyMac_InitMenuBar();
538
Jack Jansen696c9581995-08-14 12:33:20 +0000539 Py_Initialize();
540
unknownd1054ef2001-07-04 22:37:19 +0000541 PyUnicode_SetDefaultEncoding(PyMac_getscript());
542
Jack Jansen0c6d0372000-05-05 23:11:14 +0000543 PyMac_InstallNavServicesForSF();
544
Jack Jansen696c9581995-08-14 12:33:20 +0000545 PySys_SetArgv(argc-1, argv+1);
546
547 if (filename == NULL && isatty((int)fileno(fp))) {
548 FILE *fp = fopen(STARTUP, "r");
549 if (fp != NULL) {
550 (void) PyRun_SimpleFile(fp, STARTUP);
551 PyErr_Clear();
552 fclose(fp);
553 }
554 }
555 sts = PyRun_AnyFile(
556 fp, filename == NULL ? "<stdin>" : filename) != 0;
557 if (filename != NULL)
558 fclose(fp);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000559
560 if ( filename != NULL || command != NULL )
561 sts = (run_inspect() || sts);
Jack Jansen696c9581995-08-14 12:33:20 +0000562
563 Py_Exit(sts);
564 /*NOTREACHED*/
565}
566
Jack Jansen0168f271995-10-27 13:32:30 +0000567/*
Jack Jansen8413b472000-10-19 22:02:16 +0000568** Reset the "unseen output" flag
569*/
570void
571PyMac_OutputSeen()
572{
Jack Jansen657ba272001-02-17 22:02:07 +0000573 if ( console_output_state == STATE_UNKNOWN )
574 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000575 console_output_state = STATE_LASTREAD;
Jack Jansen8413b472000-10-19 22:02:16 +0000576}
577
578/*
Jack Jansen8a387142001-02-11 01:08:04 +0000579** Set the "unseen output" flag
580*/
581void
582PyMac_OutputNotSeen()
583{
Jack Jansen657ba272001-02-17 22:02:07 +0000584 if ( console_output_state == STATE_UNKNOWN )
585 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000586 console_output_state = STATE_LASTWRITE;
587}
Jack Jansen15f1c082001-04-25 22:07:27 +0000588
589/*
590** Override abort() - The default one is not what we want.
591*/
592void
593abort()
594{
595 console_output_state = STATE_LASTWRITE;
596 PyMac_Exit(1);
597}
Jack Jansen8a387142001-02-11 01:08:04 +0000598
599/*
Jack Jansen0168f271995-10-27 13:32:30 +0000600** Terminate application
601*/
Jack Jansen76ceece1996-08-19 11:18:24 +0000602void
Jack Jansen0168f271995-10-27 13:32:30 +0000603PyMac_Exit(status)
604 int status;
605{
Jack Jansen4a5eb962000-09-22 21:50:11 +0000606 int keep = 0;
Jack Jansen8c693211997-01-07 16:19:42 +0000607
608#if __profile__ == 1
609 ProfilerDump("\pPython Profiler Results");
610 ProfilerTerm();
611#endif
Jack Jansen0168f271995-10-27 13:32:30 +0000612
Jack Jansen1e8557a1995-11-10 14:51:26 +0000613#ifdef USE_SIOUX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000614 switch (PyMac_options.keep_console) {
Jack Jansen4a5eb962000-09-22 21:50:11 +0000615 case POPT_KEEPCONSOLE_NEVER:
616 keep = 0;
617 break;
618 case POPT_KEEPCONSOLE_OUTPUT:
Jack Jansen8a387142001-02-11 01:08:04 +0000619 if (console_output_state == STATE_LASTWRITE ||
620 console_output_state == STATE_UNKNOWN )
Jack Jansen4a5eb962000-09-22 21:50:11 +0000621 keep = 1;
622 else
623 keep = 0;
624 break;
625 case POPT_KEEPCONSOLE_ERROR:
626 keep = (status != 0);
627 break;
628 default:
629 keep = 1;
630 }
Jack Jansen1e8557a1995-11-10 14:51:26 +0000631 if (keep) {
632 SIOUXSettings.standalone = 1;
633 SIOUXSettings.autocloseonquit = 0;
Jack Jansen415571c1996-03-25 15:46:03 +0000634 SIOUXSetTitle("\p\307terminated\310");
Jack Jansen15f1c082001-04-25 22:07:27 +0000635 PyMac_RaiseConsoleWindow();
Jack Jansencaa7c461997-06-12 10:49:13 +0000636 PyMac_RestoreMenuBar();
Jack Jansene44545f1997-05-07 15:48:54 +0000637#ifdef USE_MSL
638 /*
639 ** Temporary workaround: autocloseonquit clearing does not
640 ** currently work for the MSL/GUSI combo.
641 */
642 while(getchar() > 0);
643#endif
Jack Jansen1e8557a1995-11-10 14:51:26 +0000644 }
Jack Jansen0168f271995-10-27 13:32:30 +0000645 else
646 SIOUXSettings.autocloseonquit = 1;
Jack Jansenf6865f71996-09-04 15:24:59 +0000647#endif /* USE_SIOUX */
Jack Jansen0168f271995-10-27 13:32:30 +0000648
649 exit(status);
650}
Jack Jansen696c9581995-08-14 12:33:20 +0000651
652/* Return the program name -- some code out there needs this. */
Jack Jansena39f1b01997-05-23 15:35:14 +0000653char *
654Py_GetProgramFullPath()
655{
Jack Jansen7330b391997-08-08 14:56:41 +0000656 return orig_argv[0];
Jack Jansena39f1b01997-05-23 15:35:14 +0000657}
658
Jack Jansen696c9581995-08-14 12:33:20 +0000659
660/* Make the *original* argc/argv available to other modules.
661 This is rare, but it is needed by the secureware extension. */
662
663void
Jack Jansen9ae898b2000-07-11 21:16:03 +0000664Py_GetArgcArgv(int *argc,char ***argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000665{
666 *argc = orig_argc;
667 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000668}
Jack Jansen1d2f8631996-08-02 15:16:16 +0000669
670/* More cruft that shouldn't really be here, used in sysmodule.c */
671
672char *
673Py_GetPrefix()
674{
Jack Jansenac625691997-09-08 13:22:22 +0000675 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000676}
677
678char *
679Py_GetExecPrefix()
680{
Jack Jansenac625691997-09-08 13:22:22 +0000681 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000682}
Jack Jansen8a387142001-02-11 01:08:04 +0000683
684int
685PyMac_GetDelayConsoleFlag()
686{
687 return (int)PyMac_options.delayconsole;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000688}
689
690#ifndef WITHOUT_UNIX_NEWLINES
691/*
692** Experimental feature (for 2.2a2): optionally allow unix newlines
693** as well as Mac newlines on input. We replace a lowlevel
694** MSL routine to accomplish this.
695*/
696void
697__convert_to_newlines(unsigned char * buf, size_t * n_ptr)
698{
699 unsigned char *p;
700 size_t n = *n_ptr;
701
702 for(p=buf; n > 0; p++, n--)
703 if ( *p == '\r' ) *p = '\n';
704 else if ( *p == '\n' && !PyMac_options.unixnewlines )
705 *p = '\r';
706}
707#endif /* WITHOUT_UNIX_NEWLINES */
708