blob: d257142976ecb7e548798fec17a470dde0730b0a [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 Jansendff77702001-09-05 22:07:52 +000033#ifdef WITHOUT_FRAMEWORKS
Jack Jansen696c9581995-08-14 12:33:20 +000034#include <Memory.h>
35#include <Resources.h>
Guido van Rossumb0f3c821994-08-23 13:34:25 +000036#include <stdio.h>
Jack Jansen696c9581995-08-14 12:33:20 +000037#include <Events.h>
38#include <Windows.h>
Jack Jansen2429c721996-03-07 15:17:11 +000039#include <Fonts.h>
Jack Jansen36b983c1997-09-09 13:53:21 +000040#include <Balloons.h>
Jack Jansen5ded1bf2001-10-30 22:48:36 +000041#include <CFBundle.h>
42#include <CFURL.h>
43#include <CFString.h>
44#include <CFBase.h>
45#include <CFArray.h>
Jack Jansen8f5725a1999-12-07 23:08:10 +000046#include <Gestalt.h>
47#include <Appearance.h>
Jack Jansendff77702001-09-05 22:07:52 +000048#else
49#include <Carbon/Carbon.h>
50#endif /* WITHOUT_FRAMEWORKS */
51
Jack Jansenc76fd391995-02-02 14:27:31 +000052#ifdef __MWERKS__
53#include <SIOUX.h>
Jack Jansen1e8557a1995-11-10 14:51:26 +000054#define USE_SIOUX
Jack Jansen9ae898b2000-07-11 21:16:03 +000055extern int ccommand(char ***);
Jack Jansen8c693211997-01-07 16:19:42 +000056#if __profile__ == 1
57#include <profiler.h>
Jack Jansendff77702001-09-05 22:07:52 +000058#endif /* __profile__ */
59#endif /* __MWERKS__ */
60
Jack Jansenee6eeb12000-06-02 21:28:52 +000061#include <unistd.h>
Jack Jansen5bdbabd2000-07-24 19:52:52 +000062#ifdef USE_MAC_SHARED_LIBRARY
63extern PyMac_AddLibResources(void);
64#endif
Jack Jansenc76fd391995-02-02 14:27:31 +000065
Jack Jansen696c9581995-08-14 12:33:20 +000066#define STARTUP "PythonStartup"
Jack Jansenbac428d1994-12-14 13:47:30 +000067
Jack Jansen65c3ee02000-09-08 10:20:37 +000068#define COPYRIGHT \
69 "Type \"copyright\", \"credits\" or \"license\" for more information."
70
Jack Jansen3f7d2b41996-09-06 22:21:07 +000071short PyMac_AppRefNum; /* RefNum of application resource fork */
Jack Jansen696c9581995-08-14 12:33:20 +000072
Jack Jansen1d2f8631996-08-02 15:16:16 +000073/* For Py_GetArgcArgv(); set by main() */
Jack Jansen696c9581995-08-14 12:33:20 +000074static char **orig_argv;
75static int orig_argc;
76
Jack Jansen8a387142001-02-11 01:08:04 +000077/* A flag which remembers whether the user has acknowledged all the console
78** output (by typing something)
79*/
80#define STATE_UNKNOWN 0
81#define STATE_LASTREAD 1
82#define STATE_LASTWRITE 2
83int console_output_state = STATE_UNKNOWN;
84
Jack Jansendc86f9e2000-10-12 21:23:19 +000085PyMac_PrefRecord PyMac_options;
Jack Jansen0168f271995-10-27 13:32:30 +000086
Jack Jansenace9d952002-08-05 14:13:31 +000087static void PyMac_Main(int, char **, char *); /* Forward */
Jack Jansend88296d2000-07-11 19:51:05 +000088void PyMac_Exit(int); /* Forward */
Jack Jansen76ceece1996-08-19 11:18:24 +000089
Jack Jansen01fbc681996-02-28 15:42:47 +000090/* Initialize the Mac toolbox world */
91
92static void
Jack Jansendff77702001-09-05 22:07:52 +000093init_mac_world(void)
Jack Jansen01fbc681996-02-28 15:42:47 +000094{
Jack Jansen01fbc681996-02-28 15:42:47 +000095 InitCursor();
Jack Jansen01fbc681996-02-28 15:42:47 +000096}
97
Jack Jansen7d5f9e81996-09-07 17:09:31 +000098/*
99** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
100*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000101static void
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000102PyMac_InteractiveOptions(PyMac_PrefRecord *p, int *argcp, char ***argvp)
103{
104 KeyMap rmap;
105 unsigned char *map;
106 short item, type;
107 ControlHandle handle;
108 DialogPtr dialog;
109 Rect rect;
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000110
111 /*
112 ** If the preferences disallows interactive options we return,
113 ** similarly of <option> isn't pressed.
114 */
115 if (p->nointopt) return;
116
117 GetKeys(rmap);
118 map = (unsigned char *)rmap;
119 if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
120 return;
121
122 dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
123 if ( dialog == NULL ) {
124 printf("Option dialog not found - cannot set options\n");
125 return;
126 }
127 SetDialogDefaultItem(dialog, OPT_OK);
128 SetDialogCancelItem(dialog, OPT_CANCEL);
129
130 /* Set default values */
131#define SET_OPT_ITEM(num, var) \
132 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
Jack Jansen08c3be31997-04-08 15:27:00 +0000133 SetControlValue(handle, (short)p->var);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000134
135 SET_OPT_ITEM(OPT_INSPECT, inspect);
136 SET_OPT_ITEM(OPT_VERBOSE, verbose);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000137 /* OPT_VERBOSEVERBOSE is default off */
Jack Jansen36b983c1997-09-09 13:53:21 +0000138 SET_OPT_ITEM(OPT_OPTIMIZE, optimize);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000139 SET_OPT_ITEM(OPT_UNBUFFERED, unbuffered);
140 SET_OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen4a5eb962000-09-22 21:50:11 +0000141 GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
142 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
143 GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
144 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
145 GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
146 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
147 GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
148 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
149/* SET_OPT_ITEM(OPT_KEEPCONSOLE, keep_console); */
Jack Jansen0c6d0372000-05-05 23:11:14 +0000150 SET_OPT_ITEM(OPT_TABWARN, tabwarn);
Jack Jansen36b983c1997-09-09 13:53:21 +0000151 SET_OPT_ITEM(OPT_NOSITE, nosite);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000152 SET_OPT_ITEM(OPT_DIVISIONWARN, divisionwarn);
153 SET_OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000154 /* The rest are not settable interactively */
155
156#undef SET_OPT_ITEM
157
158 while (1) {
159 handle = NULL;
160 ModalDialog(NULL, &item);
161 if ( item == OPT_OK )
162 break;
163 if ( item == OPT_CANCEL ) {
Jack Jansen08c3be31997-04-08 15:27:00 +0000164 DisposeDialog(dialog);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000165 exit(0);
166 }
167 if ( item == OPT_CMDLINE ) {
Jack Jansendff77702001-09-05 22:07:52 +0000168 int old_argc = *argcp;
169 int i;
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000170 int new_argc, newer_argc;
171 char **new_argv, **newer_argv;
172
173 new_argc = ccommand(&new_argv);
174 newer_argc = (new_argc-1) + old_argc;
175 newer_argv = malloc((newer_argc+1)*sizeof(char *));
176 if( !newer_argv )
177 Py_FatalError("Cannot malloc argv\n");
178 for(i=0; i<old_argc; i++)
179 newer_argv[i] = (*argvp)[i];
180 for(i=old_argc; i<=newer_argc; i++) /* Copy the NULL too */
181 newer_argv[i] = new_argv[i-old_argc+1];
182 *argvp = newer_argv;
183 *argcp = newer_argc;
184
185 /* XXXX Is it not safe to use free() here, apparently */
186 }
187#define OPT_ITEM(num, var) \
188 if ( item == (num) ) { \
189 p->var = !p->var; \
190 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
Jack Jansen08c3be31997-04-08 15:27:00 +0000191 SetControlValue(handle, (short)p->var); \
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000192 }
193
194 OPT_ITEM(OPT_INSPECT, inspect);
195 OPT_ITEM(OPT_VERBOSE, verbose);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000196 if ( item == OPT_VERBOSEVERBOSE ) {
197 if ( p->verbose == 2 )
198 p->verbose = 1;
199 else
200 p->verbose = 2;
201 GetDialogItem(dialog, OPT_VERBOSE, &type, (Handle *)&handle, &rect);
202 SetControlValue(handle, 1);
203 }
204 GetDialogItem(dialog, OPT_VERBOSEVERBOSE, &type, (Handle *)&handle, &rect);
205 SetControlValue(handle, p->verbose == 2);
Jack Jansen36b983c1997-09-09 13:53:21 +0000206 OPT_ITEM(OPT_OPTIMIZE, optimize);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000207 OPT_ITEM(OPT_UNBUFFERED, unbuffered);
208 OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen4a5eb962000-09-22 21:50:11 +0000209 if ( item == OPT_KEEPALWAYS ) p->keep_console = POPT_KEEPCONSOLE_ALWAYS;
210 if ( item == OPT_KEEPOUTPUT ) p->keep_console = POPT_KEEPCONSOLE_OUTPUT;
211 if ( item == OPT_KEEPERROR ) p->keep_console = POPT_KEEPCONSOLE_ERROR;
212 if ( item == OPT_KEEPNEVER ) p->keep_console = POPT_KEEPCONSOLE_NEVER;
213 GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
214 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
215 GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
216 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
217 GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
218 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
219 GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
220 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
Jack Jansen0c6d0372000-05-05 23:11:14 +0000221 OPT_ITEM(OPT_TABWARN, tabwarn);
Jack Jansen36b983c1997-09-09 13:53:21 +0000222 OPT_ITEM(OPT_NOSITE, nosite);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000223 OPT_ITEM(OPT_DIVISIONWARN, divisionwarn);
224 OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000225
226#undef OPT_ITEM
227 }
Jack Jansen08c3be31997-04-08 15:27:00 +0000228 DisposeDialog(dialog);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000229}
230
231/*
232** Initialization code, shared by interpreter and applets
233*/
234static void
Jack Jansen52ac0371997-01-15 15:49:08 +0000235init_common(int *argcp, char ***argvp, int embedded)
Jack Jansen01fbc681996-02-28 15:42:47 +0000236{
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000237 /* Remember resource fork refnum, for later */
238 PyMac_AppRefNum = CurResFile();
239
Jack Jansen01fbc681996-02-28 15:42:47 +0000240 /* Initialize toolboxes */
241 init_mac_world();
242
243#ifdef USE_MAC_SHARED_LIBRARY
244 /* Add the shared library to the stack of resource files */
Jack Jansen87c485c1998-07-31 09:38:01 +0000245 (void)PyMac_init_process_location();
Jack Jansen01fbc681996-02-28 15:42:47 +0000246 PyMac_AddLibResources();
247#endif
248
Jack Jansen2d1306b2000-04-07 09:10:49 +0000249#if defined(USE_GUSI)
250 atexit(PyMac_StopGUSISpin);
251#endif
Jack Jansen01fbc681996-02-28 15:42:47 +0000252
253#ifdef USE_SIOUX
254 /* Set various SIOUX flags. Some are changed later based on options */
255 SIOUXSettings.asktosaveonclose = 0;
256 SIOUXSettings.showstatusline = 0;
257 SIOUXSettings.tabspaces = 4;
258#endif
259
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000260 /* Get options from preference file (or from applet resource fork) */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000261 PyMac_options.keep_console = POPT_KEEPCONSOLE_OUTPUT; /* default-default */
Jack Jansendff77702001-09-05 22:07:52 +0000262 PyMac_options.unixnewlines = 1;
Jack Jansendc86f9e2000-10-12 21:23:19 +0000263 PyMac_PreferenceOptions(&PyMac_options);
Jack Jansendff77702001-09-05 22:07:52 +0000264
Jack Jansen52ac0371997-01-15 15:49:08 +0000265 if ( embedded ) {
266 static char *emb_argv[] = {"embedded-python", 0};
267
268 *argcp = 1;
269 *argvp = emb_argv;
270 } else {
Jack Jansen4b517852002-01-02 22:53:38 +0000271 /* Create argc/argv. Do it before we go into the options event loop.
272 ** In MachoPython we skip this step if we already have plausible
273 ** command line arguments.
274 */
Jack Jansen4b517852002-01-02 22:53:38 +0000275 *argcp = PyMac_GetArgv(argvp, PyMac_options.noargs);
Jack Jansenc00df0b2001-01-16 15:54:58 +0000276#ifndef NO_ARGV0_CHDIR
Jack Jansen660bb1d2000-07-18 09:40:39 +0000277 if (*argcp >= 1 && (*argvp)[0] && (*argvp)[0][0]) {
278 /* Workaround for MacOS X, which currently (DP4) doesn't set
279 ** the working folder correctly
280 */
281 char app_wd[256], *p;
282
283 strncpy(app_wd, (*argvp)[0], 256);
Jack Jansen660bb1d2000-07-18 09:40:39 +0000284 p = strrchr(app_wd, ':');
285 if ( p ) *p = 0;
Jack Jansen660bb1d2000-07-18 09:40:39 +0000286 chdir(app_wd);
287 }
288#endif
Jack Jansen52ac0371997-01-15 15:49:08 +0000289 /* Do interactive option setting, if allowed and <option> depressed */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000290 PyMac_InteractiveOptions(&PyMac_options, argcp, argvp);
Jack Jansen52ac0371997-01-15 15:49:08 +0000291 }
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000292
293 /* Copy selected options to where the machine-independent stuff wants it */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000294 Py_VerboseFlag = PyMac_options.verbose;
295/* Py_SuppressPrintingFlag = PyMac_options.suppress_print; */
296 Py_OptimizeFlag = PyMac_options.optimize;
297 Py_DebugFlag = PyMac_options.debugging;
298 Py_NoSiteFlag = PyMac_options.nosite;
299 Py_TabcheckFlag = PyMac_options.tabwarn;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000300 Py_DivisionWarningFlag = PyMac_options.divisionwarn;
Jack Jansendc86f9e2000-10-12 21:23:19 +0000301 if ( PyMac_options.noargs ) {
Jack Jansene3ae0df1997-06-03 15:28:29 +0000302 /* don't process events at all without the scripts permission */
303 PyMacSchedParams scp;
304
305 PyMac_GetSchedParams(&scp);
306 scp.process_events = 0;
307 /* Should we disable command-dot as well? */
308 PyMac_SetSchedParams(&scp);
309 }
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000310
311 /* Set buffering */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000312 if (PyMac_options.unbuffered) {
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000313#ifndef MPW
314 setbuf(stdout, (char *)NULL);
315 setbuf(stderr, (char *)NULL);
316#else
317 /* On MPW (3.2) unbuffered seems to hang */
318 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
319 setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
320#endif
321 }
Jack Jansen8c693211997-01-07 16:19:42 +0000322#if __profile__ == 1
323 /* collectSummary or collectDetailed, timebase, #routines, max stack depth */
Jack Jansene7424871999-09-30 11:20:11 +0000324 ProfilerInit(collectSummary, bestTimeBase, 8000, 250);
Jack Jansen8c693211997-01-07 16:19:42 +0000325#endif
Jack Jansen7330b391997-08-08 14:56:41 +0000326
327 /* Tell the rest of python about our argc/argv */
328 orig_argc = *argcp; /* For Py_GetArgcArgv() */
329 orig_argv = *argvp;
330 Py_SetProgramName((*argvp)[0]);
Jack Jansen01fbc681996-02-28 15:42:47 +0000331}
332
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000333/*
334** Inspection mode after script/applet termination
335*/
336static int
Jack Jansendff77702001-09-05 22:07:52 +0000337run_inspect(void)
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000338{
339 int sts = 0;
340
Jack Jansendc86f9e2000-10-12 21:23:19 +0000341 if (PyMac_options.inspect && isatty((int)fileno(stdin)))
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000342 sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
343 return sts;
344}
Jack Jansen6438e1d2001-09-11 11:29:31 +0000345
Jack Jansen696c9581995-08-14 12:33:20 +0000346#ifdef USE_MAC_APPLET_SUPPORT
347/* Applet support */
348
349/* Run a compiled Python Python script from 'PYC ' resource __main__ */
350static int
Jack Jansendff77702001-09-05 22:07:52 +0000351run_main_resource(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000352{
353 Handle h;
354 long size;
355 PyObject *code;
356 PyObject *result;
357
358 h = GetNamedResource('PYC ', "\p__main__");
359 if (h == NULL) {
360 Alert(NOPYC_ALERT, NULL);
361 return 1;
362 }
363 size = GetResourceSizeOnDisk(h);
364 HLock(h);
365 code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
366 HUnlock(h);
367 ReleaseResource(h);
368 if (code == NULL) {
369 PyErr_Print();
370 return 1;
371 }
372 result = PyImport_ExecCodeModule("__main__", code);
373 Py_DECREF(code);
374 if (result == NULL) {
375 PyErr_Print();
376 return 1;
377 }
378 Py_DECREF(result);
379 return 0;
380}
381
382/* Initialization sequence for applets */
383void
Jack Jansendff77702001-09-05 22:07:52 +0000384PyMac_InitApplet(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000385{
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000386 int argc;
387 char **argv;
Jack Jansen696c9581995-08-14 12:33:20 +0000388 int err;
389
Jack Jansen52ac0371997-01-15 15:49:08 +0000390 init_common(&argc, &argv, 0);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000391
Jack Jansen696c9581995-08-14 12:33:20 +0000392 Py_Initialize();
393 PySys_SetArgv(argc, argv);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000394
Jack Jansen696c9581995-08-14 12:33:20 +0000395 err = run_main_resource();
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000396
397 err = (run_inspect() || err);
398
Jack Jansen696c9581995-08-14 12:33:20 +0000399 fflush(stderr);
400 fflush(stdout);
Jack Jansen0168f271995-10-27 13:32:30 +0000401 PyMac_Exit(err);
Jack Jansen696c9581995-08-14 12:33:20 +0000402 /* XXX Should we bother to Py_Exit(sts)? */
403}
404
Jack Jansen52ac0371997-01-15 15:49:08 +0000405/*
406** Hook for embedding python.
407*/
408void
Jack Jansendff77702001-09-05 22:07:52 +0000409PyMac_Initialize(void)
Jack Jansen52ac0371997-01-15 15:49:08 +0000410{
411 int argc;
412 char **argv;
413
414 init_common(&argc, &argv, 1);
415 Py_Initialize();
416 PySys_SetArgv(argc, argv);
417}
418
Jack Jansen696c9581995-08-14 12:33:20 +0000419#endif /* USE_MAC_APPLET_SUPPORT */
420
421/* For normal application */
422void
Jack Jansendff77702001-09-05 22:07:52 +0000423PyMac_InitApplication(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000424{
425 int argc;
426 char **argv;
Jack Jansena7f4ded2002-05-22 15:02:08 +0000427 OSType filetype;
Jack Jansen696c9581995-08-14 12:33:20 +0000428
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000429 static char scriptpath[1024];
430 char *script = NULL;
431
Jack Jansen52ac0371997-01-15 15:49:08 +0000432 init_common(&argc, &argv, 0);
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000433
Jack Jansen696c9581995-08-14 12:33:20 +0000434 if ( argc > 1 ) {
435 /* We're running a script. Attempt to change current directory */
436 char curwd[256], *endp;
437
438 strcpy(curwd, argv[1]);
439 endp = strrchr(curwd, ':');
440 if ( endp && endp > curwd ) {
441 *endp = '\0';
442
443 chdir(curwd);
444 }
Jack Jansencbed91b2001-08-03 13:31:36 +0000445 /* Check that the first argument is a text file */
Jack Jansena7f4ded2002-05-22 15:02:08 +0000446 filetype = PyMac_getfiletype(argv[1]);
447 if ( filetype != 'TEXT' && filetype != 0 ) {
Jack Jansencbed91b2001-08-03 13:31:36 +0000448 Alert(NOTASCRIPT_ID, NULL);
449 exit(0);
450 }
Jack Jansen696c9581995-08-14 12:33:20 +0000451 }
Jack Jansenace9d952002-08-05 14:13:31 +0000452 PyMac_Main(argc, argv, script);
Jack Jansen696c9581995-08-14 12:33:20 +0000453}
454
Jack Jansen696c9581995-08-14 12:33:20 +0000455/* Main program */
456
Jack Jansen76ceece1996-08-19 11:18:24 +0000457static void
Jack Jansenace9d952002-08-05 14:13:31 +0000458PyMac_Main(int argc, char **argv, char *filename)
Jack Jansen696c9581995-08-14 12:33:20 +0000459{
Jack Jansen696c9581995-08-14 12:33:20 +0000460 int sts;
461 char *command = NULL;
Jack Jansen696c9581995-08-14 12:33:20 +0000462 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000463
Jack Jansen998a40a2001-09-11 13:08:10 +0000464 if ( filename ) {
465 /* Someone else has found our "script" already */
466 argv[0] = filename;
467 } else {
468 filename = argv[1];
469 argv++;
470 argc--;
471 }
Jack Jansen696c9581995-08-14 12:33:20 +0000472
473 if (Py_VerboseFlag ||
Jack Jansendff77702001-09-05 22:07:52 +0000474 (command == NULL && filename == NULL && isatty((int)fileno(fp))))
Jack Jansen0035fb22002-03-29 14:27:06 +0000475 fprintf(stderr, "%s %s on %s\n%s\n",
Jack Jansen0035fb22002-03-29 14:27:06 +0000476 "Python",
Jack Jansen65c3ee02000-09-08 10:20:37 +0000477 Py_GetVersion(), Py_GetPlatform(), COPYRIGHT);
Jack Jansen696c9581995-08-14 12:33:20 +0000478
479 if (filename != NULL) {
Jack Jansen7b8c7542002-04-14 20:12:41 +0000480 if ((fp = fopen(filename, "r" PY_STDIOTEXTMODE)) == NULL) {
Jack Jansen696c9581995-08-14 12:33:20 +0000481 fprintf(stderr, "%s: can't open file '%s'\n",
482 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000483 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000484 }
485 }
486
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000487 /* We initialize the menubar here, hoping SIOUX is initialized by now */
Jack Jansen3469e991996-09-06 00:30:45 +0000488 PyMac_InitMenuBar();
Jack Jansendff77702001-09-05 22:07:52 +0000489
Jack Jansen696c9581995-08-14 12:33:20 +0000490 Py_Initialize();
491
Jack Jansen3e828722003-01-08 16:27:44 +0000492#if 0
493 /* According to Martin v. Loewis this is a bad idea... */
unknownd1054ef2001-07-04 22:37:19 +0000494 PyUnicode_SetDefaultEncoding(PyMac_getscript());
Jack Jansen3e828722003-01-08 16:27:44 +0000495#endif
unknownd1054ef2001-07-04 22:37:19 +0000496
Jack Jansen998a40a2001-09-11 13:08:10 +0000497 PySys_SetArgv(argc, argv);
Jack Jansen696c9581995-08-14 12:33:20 +0000498
499 if (filename == NULL && isatty((int)fileno(fp))) {
Jack Jansen7b8c7542002-04-14 20:12:41 +0000500 FILE *fp = fopen(STARTUP, "r" PY_STDIOTEXTMODE);
Jack Jansen696c9581995-08-14 12:33:20 +0000501 if (fp != NULL) {
502 (void) PyRun_SimpleFile(fp, STARTUP);
503 PyErr_Clear();
504 fclose(fp);
505 }
506 }
507 sts = PyRun_AnyFile(
508 fp, filename == NULL ? "<stdin>" : filename) != 0;
509 if (filename != NULL)
510 fclose(fp);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000511
512 if ( filename != NULL || command != NULL )
513 sts = (run_inspect() || sts);
Jack Jansen696c9581995-08-14 12:33:20 +0000514
515 Py_Exit(sts);
516 /*NOTREACHED*/
517}
518
Jack Jansen0168f271995-10-27 13:32:30 +0000519/*
Jack Jansen8413b472000-10-19 22:02:16 +0000520** Reset the "unseen output" flag
521*/
522void
Jack Jansendff77702001-09-05 22:07:52 +0000523PyMac_OutputSeen(void)
Jack Jansen8413b472000-10-19 22:02:16 +0000524{
Jack Jansen657ba272001-02-17 22:02:07 +0000525 if ( console_output_state == STATE_UNKNOWN )
526 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000527 console_output_state = STATE_LASTREAD;
Jack Jansen8413b472000-10-19 22:02:16 +0000528}
529
530/*
Jack Jansen8a387142001-02-11 01:08:04 +0000531** Set the "unseen output" flag
532*/
533void
Jack Jansendff77702001-09-05 22:07:52 +0000534PyMac_OutputNotSeen(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000535{
Jack Jansen657ba272001-02-17 22:02:07 +0000536 if ( console_output_state == STATE_UNKNOWN )
537 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000538 console_output_state = STATE_LASTWRITE;
539}
Jack Jansen15f1c082001-04-25 22:07:27 +0000540
541/*
542** Override abort() - The default one is not what we want.
543*/
544void
Jack Jansendff77702001-09-05 22:07:52 +0000545abort(void)
Jack Jansen15f1c082001-04-25 22:07:27 +0000546{
547 console_output_state = STATE_LASTWRITE;
548 PyMac_Exit(1);
549}
Jack Jansen8a387142001-02-11 01:08:04 +0000550
551/*
Jack Jansen0168f271995-10-27 13:32:30 +0000552** Terminate application
553*/
Jack Jansen76ceece1996-08-19 11:18:24 +0000554void
Jack Jansendff77702001-09-05 22:07:52 +0000555PyMac_Exit(int status)
Jack Jansen0168f271995-10-27 13:32:30 +0000556{
Jack Jansendff77702001-09-05 22:07:52 +0000557#ifdef USE_SIOUX
Jack Jansen4a5eb962000-09-22 21:50:11 +0000558 int keep = 0;
Jack Jansendff77702001-09-05 22:07:52 +0000559#endif
Jack Jansen8c693211997-01-07 16:19:42 +0000560
561#if __profile__ == 1
562 ProfilerDump("\pPython Profiler Results");
563 ProfilerTerm();
564#endif
Jack Jansen0168f271995-10-27 13:32:30 +0000565
Jack Jansen1e8557a1995-11-10 14:51:26 +0000566#ifdef USE_SIOUX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000567 switch (PyMac_options.keep_console) {
Jack Jansen4a5eb962000-09-22 21:50:11 +0000568 case POPT_KEEPCONSOLE_NEVER:
569 keep = 0;
570 break;
571 case POPT_KEEPCONSOLE_OUTPUT:
Jack Jansen8a387142001-02-11 01:08:04 +0000572 if (console_output_state == STATE_LASTWRITE ||
573 console_output_state == STATE_UNKNOWN )
Jack Jansen4a5eb962000-09-22 21:50:11 +0000574 keep = 1;
575 else
576 keep = 0;
577 break;
578 case POPT_KEEPCONSOLE_ERROR:
579 keep = (status != 0);
580 break;
581 default:
582 keep = 1;
583 }
Jack Jansen1e8557a1995-11-10 14:51:26 +0000584 if (keep) {
585 SIOUXSettings.standalone = 1;
586 SIOUXSettings.autocloseonquit = 0;
Jack Jansen415571c1996-03-25 15:46:03 +0000587 SIOUXSetTitle("\p\307terminated\310");
Jack Jansen15f1c082001-04-25 22:07:27 +0000588 PyMac_RaiseConsoleWindow();
Jack Jansencaa7c461997-06-12 10:49:13 +0000589 PyMac_RestoreMenuBar();
Jack Jansene44545f1997-05-07 15:48:54 +0000590#ifdef USE_MSL
591 /*
592 ** Temporary workaround: autocloseonquit clearing does not
593 ** currently work for the MSL/GUSI combo.
594 */
595 while(getchar() > 0);
596#endif
Jack Jansen1e8557a1995-11-10 14:51:26 +0000597 }
Jack Jansen0168f271995-10-27 13:32:30 +0000598 else
599 SIOUXSettings.autocloseonquit = 1;
Jack Jansenf6865f71996-09-04 15:24:59 +0000600#endif /* USE_SIOUX */
Jack Jansen0168f271995-10-27 13:32:30 +0000601
602 exit(status);
603}
Jack Jansen696c9581995-08-14 12:33:20 +0000604
Jack Jansen696c9581995-08-14 12:33:20 +0000605/* Make the *original* argc/argv available to other modules.
606 This is rare, but it is needed by the secureware extension. */
607
608void
Jack Jansen9ae898b2000-07-11 21:16:03 +0000609Py_GetArgcArgv(int *argc,char ***argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000610{
611 *argc = orig_argc;
612 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000613}
Jack Jansen1d2f8631996-08-02 15:16:16 +0000614
615/* More cruft that shouldn't really be here, used in sysmodule.c */
Jack Jansendff77702001-09-05 22:07:52 +0000616/* Return the program name -- some code out there needs this. */
617char *
618Py_GetProgramFullPath(void)
619{
620 return orig_argv[0];
621}
Jack Jansen1d2f8631996-08-02 15:16:16 +0000622
623char *
Jack Jansendff77702001-09-05 22:07:52 +0000624Py_GetPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000625{
Jack Jansenac625691997-09-08 13:22:22 +0000626 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000627}
628
629char *
Jack Jansendff77702001-09-05 22:07:52 +0000630Py_GetExecPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000631{
Jack Jansenac625691997-09-08 13:22:22 +0000632 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000633}
Jack Jansen8a387142001-02-11 01:08:04 +0000634
635int
Jack Jansendff77702001-09-05 22:07:52 +0000636PyMac_GetDelayConsoleFlag(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000637{
638 return (int)PyMac_options.delayconsole;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000639}
640