blob: cb6b3312416e82c897077fa2fb1c784dd2d9584a [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#if TARGET_API_MAC_CARBON
42#include <CFBundle.h>
43#include <CFURL.h>
44#include <CFString.h>
45#include <CFBase.h>
46#include <CFArray.h>
47#endif /* TARGET_API_MAC_CARBON */
Jack Jansen8f5725a1999-12-07 23:08:10 +000048#ifdef USE_APPEARANCE
49#include <Gestalt.h>
50#include <Appearance.h>
51#endif /* USE_APPEARANCE */
Jack Jansendff77702001-09-05 22:07:52 +000052#else
53#include <Carbon/Carbon.h>
54#endif /* WITHOUT_FRAMEWORKS */
55
Jack Jansenc76fd391995-02-02 14:27:31 +000056#ifdef __MWERKS__
57#include <SIOUX.h>
Jack Jansen1e8557a1995-11-10 14:51:26 +000058#define USE_SIOUX
Jack Jansen9ae898b2000-07-11 21:16:03 +000059extern int ccommand(char ***);
Jack Jansen8c693211997-01-07 16:19:42 +000060#if __profile__ == 1
61#include <profiler.h>
Jack Jansendff77702001-09-05 22:07:52 +000062#endif /* __profile__ */
63#endif /* __MWERKS__ */
64
Jack Jansenee6eeb12000-06-02 21:28:52 +000065#include <unistd.h>
Jack Jansen5bdbabd2000-07-24 19:52:52 +000066#ifdef USE_MAC_SHARED_LIBRARY
67extern PyMac_AddLibResources(void);
68#endif
Jack Jansenc76fd391995-02-02 14:27:31 +000069
Jack Jansen696c9581995-08-14 12:33:20 +000070#define STARTUP "PythonStartup"
Jack Jansenbac428d1994-12-14 13:47:30 +000071
Jack Jansen65c3ee02000-09-08 10:20:37 +000072#define COPYRIGHT \
73 "Type \"copyright\", \"credits\" or \"license\" for more information."
74
Jack Jansen3f7d2b41996-09-06 22:21:07 +000075short PyMac_AppRefNum; /* RefNum of application resource fork */
Jack Jansen696c9581995-08-14 12:33:20 +000076
Jack Jansen1d2f8631996-08-02 15:16:16 +000077/* For Py_GetArgcArgv(); set by main() */
Jack Jansen696c9581995-08-14 12:33:20 +000078static char **orig_argv;
79static int orig_argc;
80
Jack Jansen8a387142001-02-11 01:08:04 +000081/* A flag which remembers whether the user has acknowledged all the console
82** output (by typing something)
83*/
84#define STATE_UNKNOWN 0
85#define STATE_LASTREAD 1
86#define STATE_LASTWRITE 2
87int console_output_state = STATE_UNKNOWN;
88
Jack Jansendc86f9e2000-10-12 21:23:19 +000089PyMac_PrefRecord PyMac_options;
Jack Jansen0168f271995-10-27 13:32:30 +000090
Jack Jansen998a40a2001-09-11 13:08:10 +000091static void Py_Main(int, char **, char *); /* Forward */
Jack Jansend88296d2000-07-11 19:51:05 +000092void PyMac_Exit(int); /* Forward */
Jack Jansen76ceece1996-08-19 11:18:24 +000093
Jack Jansendff77702001-09-05 22:07:52 +000094static void init_appearance(void)
Jack Jansen8f5725a1999-12-07 23:08:10 +000095{
96#ifdef USE_APPEARANCE
97 OSErr err;
98 SInt32 response;
99
100 err = Gestalt(gestaltAppearanceAttr,&response);
101 if ( err ) goto no_appearance;
102 if ( !(response&(1<<gestaltAppearanceExists)) ) goto no_appearance;
103 /* XXXX Should we check the version? Compat-mode? */
104 PyMac_AppearanceCompliant = 1;
105no_appearance:
106 return;
107#endif /* USE_APPEARANCE */
108}
Jack Jansen01fbc681996-02-28 15:42:47 +0000109/* Initialize the Mac toolbox world */
110
111static void
Jack Jansendff77702001-09-05 22:07:52 +0000112init_mac_world(void)
Jack Jansen01fbc681996-02-28 15:42:47 +0000113{
Jack Jansen74a1e632000-07-14 22:37:27 +0000114#if !TARGET_API_MAC_CARBON
Jack Jansenee6eeb12000-06-02 21:28:52 +0000115 /* These aren't needed for carbon */
Jack Jansen01fbc681996-02-28 15:42:47 +0000116 MaxApplZone();
117 InitGraf(&qd.thePort);
118 InitFonts();
119 InitWindows();
120 TEInit();
121 InitDialogs((long)0);
122 InitMenus();
Jack Jansenee6eeb12000-06-02 21:28:52 +0000123#endif
Jack Jansen01fbc681996-02-28 15:42:47 +0000124 InitCursor();
Jack Jansen8f5725a1999-12-07 23:08:10 +0000125 init_appearance();
Jack Jansen01fbc681996-02-28 15:42:47 +0000126}
127
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000128/*
129** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
130*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000131static void
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000132PyMac_InteractiveOptions(PyMac_PrefRecord *p, int *argcp, char ***argvp)
133{
134 KeyMap rmap;
135 unsigned char *map;
136 short item, type;
137 ControlHandle handle;
138 DialogPtr dialog;
139 Rect rect;
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000140
141 /*
142 ** If the preferences disallows interactive options we return,
143 ** similarly of <option> isn't pressed.
144 */
145 if (p->nointopt) return;
146
147 GetKeys(rmap);
148 map = (unsigned char *)rmap;
149 if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
150 return;
151
152 dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
153 if ( dialog == NULL ) {
154 printf("Option dialog not found - cannot set options\n");
155 return;
156 }
157 SetDialogDefaultItem(dialog, OPT_OK);
158 SetDialogCancelItem(dialog, OPT_CANCEL);
159
160 /* Set default values */
161#define SET_OPT_ITEM(num, var) \
162 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
Jack Jansen08c3be31997-04-08 15:27:00 +0000163 SetControlValue(handle, (short)p->var);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000164
165 SET_OPT_ITEM(OPT_INSPECT, inspect);
166 SET_OPT_ITEM(OPT_VERBOSE, verbose);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000167 /* OPT_VERBOSEVERBOSE is default off */
Jack Jansen36b983c1997-09-09 13:53:21 +0000168 SET_OPT_ITEM(OPT_OPTIMIZE, optimize);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000169 SET_OPT_ITEM(OPT_UNBUFFERED, unbuffered);
170 SET_OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen4a5eb962000-09-22 21:50:11 +0000171 GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
172 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
173 GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
174 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
175 GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
176 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
177 GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
178 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
179/* SET_OPT_ITEM(OPT_KEEPCONSOLE, keep_console); */
Jack Jansen0c6d0372000-05-05 23:11:14 +0000180 SET_OPT_ITEM(OPT_TABWARN, tabwarn);
Jack Jansen36b983c1997-09-09 13:53:21 +0000181 SET_OPT_ITEM(OPT_NOSITE, nosite);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000182 SET_OPT_ITEM(OPT_DIVISIONWARN, divisionwarn);
183 SET_OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000184 /* The rest are not settable interactively */
185
186#undef SET_OPT_ITEM
187
188 while (1) {
189 handle = NULL;
190 ModalDialog(NULL, &item);
191 if ( item == OPT_OK )
192 break;
193 if ( item == OPT_CANCEL ) {
Jack Jansen08c3be31997-04-08 15:27:00 +0000194 DisposeDialog(dialog);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000195 exit(0);
196 }
Jack Jansen74a1e632000-07-14 22:37:27 +0000197#if !TARGET_API_MAC_CARBON
Jack Jansen36b983c1997-09-09 13:53:21 +0000198 if ( item == OPT_HELP ) {
199 HMSetBalloons(!HMGetBalloons());
200 }
Jack Jansenee6eeb12000-06-02 21:28:52 +0000201#endif
Jack Jansendff77702001-09-05 22:07:52 +0000202#if !TARGET_API_MAC_OSX
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000203 if ( item == OPT_CMDLINE ) {
Jack Jansendff77702001-09-05 22:07:52 +0000204 int old_argc = *argcp;
205 int i;
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000206 int new_argc, newer_argc;
207 char **new_argv, **newer_argv;
208
209 new_argc = ccommand(&new_argv);
210 newer_argc = (new_argc-1) + old_argc;
211 newer_argv = malloc((newer_argc+1)*sizeof(char *));
212 if( !newer_argv )
213 Py_FatalError("Cannot malloc argv\n");
214 for(i=0; i<old_argc; i++)
215 newer_argv[i] = (*argvp)[i];
216 for(i=old_argc; i<=newer_argc; i++) /* Copy the NULL too */
217 newer_argv[i] = new_argv[i-old_argc+1];
218 *argvp = newer_argv;
219 *argcp = newer_argc;
220
221 /* XXXX Is it not safe to use free() here, apparently */
222 }
Jack Jansendff77702001-09-05 22:07:52 +0000223#endif /* !TARGET_API_MAC_OSX */
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000224#define OPT_ITEM(num, var) \
225 if ( item == (num) ) { \
226 p->var = !p->var; \
227 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
Jack Jansen08c3be31997-04-08 15:27:00 +0000228 SetControlValue(handle, (short)p->var); \
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000229 }
230
231 OPT_ITEM(OPT_INSPECT, inspect);
232 OPT_ITEM(OPT_VERBOSE, verbose);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000233 if ( item == OPT_VERBOSEVERBOSE ) {
234 if ( p->verbose == 2 )
235 p->verbose = 1;
236 else
237 p->verbose = 2;
238 GetDialogItem(dialog, OPT_VERBOSE, &type, (Handle *)&handle, &rect);
239 SetControlValue(handle, 1);
240 }
241 GetDialogItem(dialog, OPT_VERBOSEVERBOSE, &type, (Handle *)&handle, &rect);
242 SetControlValue(handle, p->verbose == 2);
Jack Jansen36b983c1997-09-09 13:53:21 +0000243 OPT_ITEM(OPT_OPTIMIZE, optimize);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000244 OPT_ITEM(OPT_UNBUFFERED, unbuffered);
245 OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen4a5eb962000-09-22 21:50:11 +0000246 if ( item == OPT_KEEPALWAYS ) p->keep_console = POPT_KEEPCONSOLE_ALWAYS;
247 if ( item == OPT_KEEPOUTPUT ) p->keep_console = POPT_KEEPCONSOLE_OUTPUT;
248 if ( item == OPT_KEEPERROR ) p->keep_console = POPT_KEEPCONSOLE_ERROR;
249 if ( item == OPT_KEEPNEVER ) p->keep_console = POPT_KEEPCONSOLE_NEVER;
250 GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
251 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
252 GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
253 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
254 GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
255 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
256 GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
257 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
Jack Jansen0c6d0372000-05-05 23:11:14 +0000258 OPT_ITEM(OPT_TABWARN, tabwarn);
Jack Jansen36b983c1997-09-09 13:53:21 +0000259 OPT_ITEM(OPT_NOSITE, nosite);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000260 OPT_ITEM(OPT_DIVISIONWARN, divisionwarn);
261 OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000262
263#undef OPT_ITEM
264 }
Jack Jansen08c3be31997-04-08 15:27:00 +0000265 DisposeDialog(dialog);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000266}
267
268/*
269** Initialization code, shared by interpreter and applets
270*/
271static void
Jack Jansen52ac0371997-01-15 15:49:08 +0000272init_common(int *argcp, char ***argvp, int embedded)
Jack Jansen01fbc681996-02-28 15:42:47 +0000273{
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000274 /* Remember resource fork refnum, for later */
275 PyMac_AppRefNum = CurResFile();
276
Jack Jansen01fbc681996-02-28 15:42:47 +0000277 /* Initialize toolboxes */
278 init_mac_world();
279
280#ifdef USE_MAC_SHARED_LIBRARY
281 /* Add the shared library to the stack of resource files */
Jack Jansen87c485c1998-07-31 09:38:01 +0000282 (void)PyMac_init_process_location();
Jack Jansen01fbc681996-02-28 15:42:47 +0000283 PyMac_AddLibResources();
284#endif
285
Jack Jansen2d1306b2000-04-07 09:10:49 +0000286#if defined(USE_GUSI1)
Jack Jansen01fbc681996-02-28 15:42:47 +0000287 /* Setup GUSI */
288 GUSIDefaultSetup();
Jack Jansenf6865f71996-09-04 15:24:59 +0000289 PyMac_SetGUSISpin();
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000290 PyMac_SetGUSIOptions();
Jack Jansen01fbc681996-02-28 15:42:47 +0000291#endif
Jack Jansen2d1306b2000-04-07 09:10:49 +0000292#if defined(USE_GUSI)
293 atexit(PyMac_StopGUSISpin);
294#endif
Jack Jansen01fbc681996-02-28 15:42:47 +0000295
296#ifdef USE_SIOUX
297 /* Set various SIOUX flags. Some are changed later based on options */
Jack Jansendff77702001-09-05 22:07:52 +0000298#if 0
299 SIOUXSettings.standalone = 0; /* XXXX Attempting to keep sioux from eating events */
300#endif
Jack Jansen01fbc681996-02-28 15:42:47 +0000301 SIOUXSettings.asktosaveonclose = 0;
302 SIOUXSettings.showstatusline = 0;
303 SIOUXSettings.tabspaces = 4;
304#endif
305
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000306 /* Get options from preference file (or from applet resource fork) */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000307 PyMac_options.keep_console = POPT_KEEPCONSOLE_OUTPUT; /* default-default */
Jack Jansendff77702001-09-05 22:07:52 +0000308 PyMac_options.unixnewlines = 1;
309#if !TARGET_API_MAC_OSX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000310 PyMac_PreferenceOptions(&PyMac_options);
Jack Jansendff77702001-09-05 22:07:52 +0000311#endif
312
Jack Jansen52ac0371997-01-15 15:49:08 +0000313 if ( embedded ) {
314 static char *emb_argv[] = {"embedded-python", 0};
315
316 *argcp = 1;
317 *argvp = emb_argv;
318 } else {
Jack Jansen4b517852002-01-02 22:53:38 +0000319 /* Create argc/argv. Do it before we go into the options event loop.
320 ** In MachoPython we skip this step if we already have plausible
321 ** command line arguments.
322 */
323#if TARGET_API_MAC_OSX
324 if (*argcp == 2 && strncmp((*argvp)[1], "-psn_", 5) == 0)
325#endif
326 *argcp = PyMac_GetArgv(argvp, PyMac_options.noargs);
Jack Jansendff77702001-09-05 22:07:52 +0000327#if !TARGET_API_MAC_OSX
Jack Jansenc00df0b2001-01-16 15:54:58 +0000328#ifndef NO_ARGV0_CHDIR
Jack Jansen660bb1d2000-07-18 09:40:39 +0000329 if (*argcp >= 1 && (*argvp)[0] && (*argvp)[0][0]) {
330 /* Workaround for MacOS X, which currently (DP4) doesn't set
331 ** the working folder correctly
332 */
333 char app_wd[256], *p;
334
335 strncpy(app_wd, (*argvp)[0], 256);
Jack Jansen660bb1d2000-07-18 09:40:39 +0000336 p = strrchr(app_wd, ':');
337 if ( p ) *p = 0;
Jack Jansen660bb1d2000-07-18 09:40:39 +0000338 chdir(app_wd);
339 }
340#endif
Jack Jansendff77702001-09-05 22:07:52 +0000341#endif
Jack Jansen52ac0371997-01-15 15:49:08 +0000342 /* Do interactive option setting, if allowed and <option> depressed */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000343 PyMac_InteractiveOptions(&PyMac_options, argcp, argvp);
Jack Jansen52ac0371997-01-15 15:49:08 +0000344 }
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000345
346 /* Copy selected options to where the machine-independent stuff wants it */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000347 Py_VerboseFlag = PyMac_options.verbose;
348/* Py_SuppressPrintingFlag = PyMac_options.suppress_print; */
349 Py_OptimizeFlag = PyMac_options.optimize;
350 Py_DebugFlag = PyMac_options.debugging;
351 Py_NoSiteFlag = PyMac_options.nosite;
352 Py_TabcheckFlag = PyMac_options.tabwarn;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000353 Py_DivisionWarningFlag = PyMac_options.divisionwarn;
Jack Jansendff77702001-09-05 22:07:52 +0000354#if !TARGET_API_MAC_OSX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000355 if ( PyMac_options.noargs ) {
Jack Jansene3ae0df1997-06-03 15:28:29 +0000356 /* don't process events at all without the scripts permission */
357 PyMacSchedParams scp;
358
359 PyMac_GetSchedParams(&scp);
360 scp.process_events = 0;
361 /* Should we disable command-dot as well? */
362 PyMac_SetSchedParams(&scp);
363 }
Jack Jansendff77702001-09-05 22:07:52 +0000364#endif /* !TARGET_API_MAC_OSX */
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000365
366 /* Set buffering */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000367 if (PyMac_options.unbuffered) {
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000368#ifndef MPW
369 setbuf(stdout, (char *)NULL);
370 setbuf(stderr, (char *)NULL);
371#else
372 /* On MPW (3.2) unbuffered seems to hang */
373 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
374 setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
375#endif
376 }
Jack Jansen8c693211997-01-07 16:19:42 +0000377#if __profile__ == 1
378 /* collectSummary or collectDetailed, timebase, #routines, max stack depth */
Jack Jansene7424871999-09-30 11:20:11 +0000379 ProfilerInit(collectSummary, bestTimeBase, 8000, 250);
Jack Jansen8c693211997-01-07 16:19:42 +0000380#endif
Jack Jansen7330b391997-08-08 14:56:41 +0000381
382 /* Tell the rest of python about our argc/argv */
383 orig_argc = *argcp; /* For Py_GetArgcArgv() */
384 orig_argv = *argvp;
385 Py_SetProgramName((*argvp)[0]);
Jack Jansen01fbc681996-02-28 15:42:47 +0000386}
387
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000388/*
389** Inspection mode after script/applet termination
390*/
391static int
Jack Jansendff77702001-09-05 22:07:52 +0000392run_inspect(void)
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000393{
394 int sts = 0;
395
Jack Jansendc86f9e2000-10-12 21:23:19 +0000396 if (PyMac_options.inspect && isatty((int)fileno(stdin)))
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000397 sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
398 return sts;
399}
Jack Jansen6438e1d2001-09-11 11:29:31 +0000400
Jack Jansen696c9581995-08-14 12:33:20 +0000401#ifdef USE_MAC_APPLET_SUPPORT
402/* Applet support */
403
404/* Run a compiled Python Python script from 'PYC ' resource __main__ */
405static int
Jack Jansendff77702001-09-05 22:07:52 +0000406run_main_resource(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000407{
408 Handle h;
409 long size;
410 PyObject *code;
411 PyObject *result;
412
413 h = GetNamedResource('PYC ', "\p__main__");
414 if (h == NULL) {
415 Alert(NOPYC_ALERT, NULL);
416 return 1;
417 }
418 size = GetResourceSizeOnDisk(h);
419 HLock(h);
420 code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
421 HUnlock(h);
422 ReleaseResource(h);
423 if (code == NULL) {
424 PyErr_Print();
425 return 1;
426 }
427 result = PyImport_ExecCodeModule("__main__", code);
428 Py_DECREF(code);
429 if (result == NULL) {
430 PyErr_Print();
431 return 1;
432 }
433 Py_DECREF(result);
434 return 0;
435}
436
437/* Initialization sequence for applets */
438void
Jack Jansendff77702001-09-05 22:07:52 +0000439PyMac_InitApplet(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000440{
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000441 int argc;
442 char **argv;
Jack Jansen696c9581995-08-14 12:33:20 +0000443 int err;
444
Jack Jansen52ac0371997-01-15 15:49:08 +0000445 init_common(&argc, &argv, 0);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000446
Jack Jansen696c9581995-08-14 12:33:20 +0000447 Py_Initialize();
448 PySys_SetArgv(argc, argv);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000449
Jack Jansen696c9581995-08-14 12:33:20 +0000450 err = run_main_resource();
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000451
452 err = (run_inspect() || err);
453
Jack Jansen696c9581995-08-14 12:33:20 +0000454 fflush(stderr);
455 fflush(stdout);
Jack Jansen0168f271995-10-27 13:32:30 +0000456 PyMac_Exit(err);
Jack Jansen696c9581995-08-14 12:33:20 +0000457 /* XXX Should we bother to Py_Exit(sts)? */
458}
459
Jack Jansen52ac0371997-01-15 15:49:08 +0000460/*
461** Hook for embedding python.
462*/
463void
Jack Jansendff77702001-09-05 22:07:52 +0000464PyMac_Initialize(void)
Jack Jansen52ac0371997-01-15 15:49:08 +0000465{
466 int argc;
467 char **argv;
468
469 init_common(&argc, &argv, 1);
470 Py_Initialize();
471 PySys_SetArgv(argc, argv);
472}
473
Jack Jansen696c9581995-08-14 12:33:20 +0000474#endif /* USE_MAC_APPLET_SUPPORT */
475
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000476#if TARGET_API_MAC_OSX /* Really: TARGET_API_MAC_CARBON */
Jack Jansen998a40a2001-09-11 13:08:10 +0000477
478static int
Jack Jansen3cef7212002-03-29 14:43:50 +0000479locateResourcePy(CFStringRef resourceType, char *resourceName, char *resourceURLCStr, int length)
480{
Jack Jansen998a40a2001-09-11 13:08:10 +0000481 CFBundleRef mainBundle = NULL;
482 CFURLRef URL, absoluteURL;
483 CFStringRef filenameString, filepathString, rsrcString;
484 CFIndex size, i;
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000485 CFArrayRef arrayRef = NULL;
486 int success = 0;
487
488#if TARGET_API_MAC_OSX
489 CFURLPathStyle thePathStyle = kCFURLPOSIXPathStyle;
490#else
491 CFURLPathStyle thePathStyle = kCFURLHFSPathStyle;
492#endif
Jack Jansen998a40a2001-09-11 13:08:10 +0000493
494 /* Get a reference to our main bundle */
495 mainBundle = CFBundleGetMainBundle();
496
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000497 /* If we are running inside a bundle, look through it. Otherwise, do nothing. */
498 if (mainBundle) {
499 /* Create a CFString with the resource name in it */
500 rsrcString = CFStringCreateWithCString(0, resourceName, kCFStringEncodingMacRoman);
Jack Jansen998a40a2001-09-11 13:08:10 +0000501
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000502 /* Look for py files in the main bundle by type */
503 arrayRef = CFBundleCopyResourceURLsOfType( mainBundle,
Jack Jansen3cef7212002-03-29 14:43:50 +0000504 resourceType,
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000505 NULL );
Jack Jansen998a40a2001-09-11 13:08:10 +0000506
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000507 /* See if there are any filename matches */
508 size = CFArrayGetCount(arrayRef);
509 for (i = 0; i < size; i++) {
510 URL = CFArrayGetValueAtIndex(arrayRef, i);
511 filenameString = CFURLCopyLastPathComponent(URL);
512 if (CFStringCompare(filenameString, rsrcString, 0) == kCFCompareEqualTo) {
513 /* We found a match, get the file's full path */
514 absoluteURL = CFURLCopyAbsoluteURL(URL);
515 filepathString = CFURLCopyFileSystemPath(absoluteURL, thePathStyle);
516 CFRelease(absoluteURL);
Jack Jansen998a40a2001-09-11 13:08:10 +0000517
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000518 /* Copy the full path into the caller's character buffer */
519 success = CFStringGetCString(filepathString, resourceURLCStr, length,
520 kCFStringEncodingMacRoman);
Jack Jansen998a40a2001-09-11 13:08:10 +0000521
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000522 CFRelease(filepathString);
523 }
524 CFRelease(filenameString);
525 }
526 CFRelease(arrayRef);
527 CFRelease(rsrcString);
528 }
Jack Jansen998a40a2001-09-11 13:08:10 +0000529 return success;
530}
531
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000532#endif /* TARGET_API_MAC_CARBON */
533
534#if TARGET_API_MAC_OSX
535
Jack Jansendff77702001-09-05 22:07:52 +0000536int
537main(int argc, char **argv)
538{
Jack Jansen998a40a2001-09-11 13:08:10 +0000539 static char scriptpath[1024];
540 char *script = NULL;
541
542 /* First we see whether we have __rawmain__.py and run that if it
543 ** is there
544 */
Jack Jansen3cef7212002-03-29 14:43:50 +0000545 if (locateResourcePy(CFSTR("py"), "__rawmain__.py", scriptpath, 1024)) {
Jack Jansen998a40a2001-09-11 13:08:10 +0000546 /* If we have a raw main we don't do AppleEvent processing.
547 ** Notice that this also means we keep the -psn.... argv[1]
548 ** value intact. Not sure whether that is important to someone,
549 ** but you never know...
550 */
551 script = scriptpath;
Jack Jansen3cef7212002-03-29 14:43:50 +0000552 } else if (locateResourcePy(CFSTR("pyc"), "__rawmain__.pyc", scriptpath, 1024)) {
553 script = scriptpath;
Jack Jansen998a40a2001-09-11 13:08:10 +0000554 } else {
555 /* Otherwise we look for __main__.py. Whether that is
556 ** found or not we also process AppleEvent arguments.
557 */
Jack Jansen3cef7212002-03-29 14:43:50 +0000558 if (locateResourcePy(CFSTR("py"), "__main__.py", scriptpath, 1024))
559 script = scriptpath;
560 else if (locateResourcePy(CFSTR("pyc"), "__main__.pyc", scriptpath, 1024))
Jack Jansen998a40a2001-09-11 13:08:10 +0000561 script = scriptpath;
562
Jack Jansen998a40a2001-09-11 13:08:10 +0000563 init_common(&argc, &argv, 0);
564
Jack Jansen998a40a2001-09-11 13:08:10 +0000565 }
566
567 Py_Main(argc, argv, script);
568 return 0;
Jack Jansendff77702001-09-05 22:07:52 +0000569}
570
571#else
572
Jack Jansen696c9581995-08-14 12:33:20 +0000573/* For normal application */
574void
Jack Jansendff77702001-09-05 22:07:52 +0000575PyMac_InitApplication(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000576{
577 int argc;
578 char **argv;
579
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000580 static char scriptpath[1024];
581 char *script = NULL;
582
Jack Jansen52ac0371997-01-15 15:49:08 +0000583 init_common(&argc, &argv, 0);
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000584
585#if TARGET_API_MAC_OSX /* Really: TARGET_API_MAC_CARBON */
586 /* If we are running inside of a bundle, and a __main__.py is available, use it */
587 if (locateResourcePy("__main__.py", scriptpath, 1024))
588 script = scriptpath;
589#endif
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000590
Jack Jansen696c9581995-08-14 12:33:20 +0000591 if ( argc > 1 ) {
592 /* We're running a script. Attempt to change current directory */
593 char curwd[256], *endp;
594
595 strcpy(curwd, argv[1]);
596 endp = strrchr(curwd, ':');
597 if ( endp && endp > curwd ) {
598 *endp = '\0';
599
600 chdir(curwd);
Jack Jansen2d1306b2000-04-07 09:10:49 +0000601#ifdef USE_GUSI1
Jack Jansen378815c1996-03-06 16:21:34 +0000602 /* Change MacOS's idea of wd too */
603 PyMac_FixGUSIcd();
604#endif
Jack Jansen696c9581995-08-14 12:33:20 +0000605 }
Jack Jansencbed91b2001-08-03 13:31:36 +0000606 /* Check that the first argument is a text file */
607 if ( PyMac_getfiletype(argv[1]) != 'TEXT' ) {
608 Alert(NOTASCRIPT_ID, NULL);
609 exit(0);
610 }
Jack Jansen696c9581995-08-14 12:33:20 +0000611 }
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000612 Py_Main(argc, argv, script);
Jack Jansen696c9581995-08-14 12:33:20 +0000613}
Jack Jansendff77702001-09-05 22:07:52 +0000614#endif /* TARGET_API_MAC_OSX */
Jack Jansen696c9581995-08-14 12:33:20 +0000615
Jack Jansen696c9581995-08-14 12:33:20 +0000616/* Main program */
617
Jack Jansen76ceece1996-08-19 11:18:24 +0000618static void
Jack Jansen998a40a2001-09-11 13:08:10 +0000619Py_Main(int argc, char **argv, char *filename)
Jack Jansen696c9581995-08-14 12:33:20 +0000620{
Jack Jansen696c9581995-08-14 12:33:20 +0000621 int sts;
622 char *command = NULL;
Jack Jansen696c9581995-08-14 12:33:20 +0000623 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000624
Jack Jansen998a40a2001-09-11 13:08:10 +0000625 if ( filename ) {
626 /* Someone else has found our "script" already */
627 argv[0] = filename;
628 } else {
629 filename = argv[1];
630 argv++;
631 argc--;
632 }
Jack Jansen696c9581995-08-14 12:33:20 +0000633
634 if (Py_VerboseFlag ||
Jack Jansendff77702001-09-05 22:07:52 +0000635 (command == NULL && filename == NULL && isatty((int)fileno(fp))))
Jack Jansen0035fb22002-03-29 14:27:06 +0000636 fprintf(stderr, "%s %s on %s\n%s\n",
637#if !TARGET_API_MAC_OSX
638 "Python",
639#else
640 "Pythonw",
641#endif
Jack Jansen65c3ee02000-09-08 10:20:37 +0000642 Py_GetVersion(), Py_GetPlatform(), COPYRIGHT);
Jack Jansen696c9581995-08-14 12:33:20 +0000643
644 if (filename != NULL) {
645 if ((fp = fopen(filename, "r")) == NULL) {
646 fprintf(stderr, "%s: can't open file '%s'\n",
647 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000648 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000649 }
650 }
651
Jack Jansendff77702001-09-05 22:07:52 +0000652#if !TARGET_API_MAC_OSX
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000653 /* We initialize the menubar here, hoping SIOUX is initialized by now */
Jack Jansen3469e991996-09-06 00:30:45 +0000654 PyMac_InitMenuBar();
Jack Jansendff77702001-09-05 22:07:52 +0000655#endif
656
Jack Jansen696c9581995-08-14 12:33:20 +0000657 Py_Initialize();
658
unknownd1054ef2001-07-04 22:37:19 +0000659 PyUnicode_SetDefaultEncoding(PyMac_getscript());
660
Jack Jansen998a40a2001-09-11 13:08:10 +0000661 PySys_SetArgv(argc, argv);
Jack Jansen696c9581995-08-14 12:33:20 +0000662
663 if (filename == NULL && isatty((int)fileno(fp))) {
664 FILE *fp = fopen(STARTUP, "r");
665 if (fp != NULL) {
666 (void) PyRun_SimpleFile(fp, STARTUP);
667 PyErr_Clear();
668 fclose(fp);
669 }
670 }
671 sts = PyRun_AnyFile(
672 fp, filename == NULL ? "<stdin>" : filename) != 0;
673 if (filename != NULL)
674 fclose(fp);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000675
676 if ( filename != NULL || command != NULL )
677 sts = (run_inspect() || sts);
Jack Jansen696c9581995-08-14 12:33:20 +0000678
679 Py_Exit(sts);
680 /*NOTREACHED*/
681}
682
Jack Jansendff77702001-09-05 22:07:52 +0000683#if !TARGET_API_MAC_OSX
Jack Jansen0168f271995-10-27 13:32:30 +0000684/*
Jack Jansen8413b472000-10-19 22:02:16 +0000685** Reset the "unseen output" flag
686*/
687void
Jack Jansendff77702001-09-05 22:07:52 +0000688PyMac_OutputSeen(void)
Jack Jansen8413b472000-10-19 22:02:16 +0000689{
Jack Jansen657ba272001-02-17 22:02:07 +0000690 if ( console_output_state == STATE_UNKNOWN )
691 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000692 console_output_state = STATE_LASTREAD;
Jack Jansen8413b472000-10-19 22:02:16 +0000693}
694
695/*
Jack Jansen8a387142001-02-11 01:08:04 +0000696** Set the "unseen output" flag
697*/
698void
Jack Jansendff77702001-09-05 22:07:52 +0000699PyMac_OutputNotSeen(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000700{
Jack Jansen657ba272001-02-17 22:02:07 +0000701 if ( console_output_state == STATE_UNKNOWN )
702 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000703 console_output_state = STATE_LASTWRITE;
704}
Jack Jansen15f1c082001-04-25 22:07:27 +0000705
706/*
707** Override abort() - The default one is not what we want.
708*/
709void
Jack Jansendff77702001-09-05 22:07:52 +0000710abort(void)
Jack Jansen15f1c082001-04-25 22:07:27 +0000711{
712 console_output_state = STATE_LASTWRITE;
713 PyMac_Exit(1);
714}
Jack Jansendff77702001-09-05 22:07:52 +0000715#endif /* !TARGET_API_MAC_OSX */
Jack Jansen8a387142001-02-11 01:08:04 +0000716
717/*
Jack Jansen0168f271995-10-27 13:32:30 +0000718** Terminate application
719*/
Jack Jansen76ceece1996-08-19 11:18:24 +0000720void
Jack Jansendff77702001-09-05 22:07:52 +0000721PyMac_Exit(int status)
Jack Jansen0168f271995-10-27 13:32:30 +0000722{
Jack Jansendff77702001-09-05 22:07:52 +0000723#ifdef USE_SIOUX
Jack Jansen4a5eb962000-09-22 21:50:11 +0000724 int keep = 0;
Jack Jansendff77702001-09-05 22:07:52 +0000725#endif
Jack Jansen8c693211997-01-07 16:19:42 +0000726
727#if __profile__ == 1
728 ProfilerDump("\pPython Profiler Results");
729 ProfilerTerm();
730#endif
Jack Jansen0168f271995-10-27 13:32:30 +0000731
Jack Jansen1e8557a1995-11-10 14:51:26 +0000732#ifdef USE_SIOUX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000733 switch (PyMac_options.keep_console) {
Jack Jansen4a5eb962000-09-22 21:50:11 +0000734 case POPT_KEEPCONSOLE_NEVER:
735 keep = 0;
736 break;
737 case POPT_KEEPCONSOLE_OUTPUT:
Jack Jansen8a387142001-02-11 01:08:04 +0000738 if (console_output_state == STATE_LASTWRITE ||
739 console_output_state == STATE_UNKNOWN )
Jack Jansen4a5eb962000-09-22 21:50:11 +0000740 keep = 1;
741 else
742 keep = 0;
743 break;
744 case POPT_KEEPCONSOLE_ERROR:
745 keep = (status != 0);
746 break;
747 default:
748 keep = 1;
749 }
Jack Jansen1e8557a1995-11-10 14:51:26 +0000750 if (keep) {
751 SIOUXSettings.standalone = 1;
752 SIOUXSettings.autocloseonquit = 0;
Jack Jansen415571c1996-03-25 15:46:03 +0000753 SIOUXSetTitle("\p\307terminated\310");
Jack Jansen15f1c082001-04-25 22:07:27 +0000754 PyMac_RaiseConsoleWindow();
Jack Jansencaa7c461997-06-12 10:49:13 +0000755 PyMac_RestoreMenuBar();
Jack Jansene44545f1997-05-07 15:48:54 +0000756#ifdef USE_MSL
757 /*
758 ** Temporary workaround: autocloseonquit clearing does not
759 ** currently work for the MSL/GUSI combo.
760 */
761 while(getchar() > 0);
762#endif
Jack Jansen1e8557a1995-11-10 14:51:26 +0000763 }
Jack Jansen0168f271995-10-27 13:32:30 +0000764 else
765 SIOUXSettings.autocloseonquit = 1;
Jack Jansenf6865f71996-09-04 15:24:59 +0000766#endif /* USE_SIOUX */
Jack Jansen0168f271995-10-27 13:32:30 +0000767
768 exit(status);
769}
Jack Jansen696c9581995-08-14 12:33:20 +0000770
Jack Jansendff77702001-09-05 22:07:52 +0000771#if !TARGET_API_MAC_OSX
Jack Jansen696c9581995-08-14 12:33:20 +0000772/* Make the *original* argc/argv available to other modules.
773 This is rare, but it is needed by the secureware extension. */
774
775void
Jack Jansen9ae898b2000-07-11 21:16:03 +0000776Py_GetArgcArgv(int *argc,char ***argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000777{
778 *argc = orig_argc;
779 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000780}
Jack Jansendff77702001-09-05 22:07:52 +0000781#endif
Jack Jansen1d2f8631996-08-02 15:16:16 +0000782
783/* More cruft that shouldn't really be here, used in sysmodule.c */
Jack Jansendff77702001-09-05 22:07:52 +0000784#if !TARGET_API_MAC_OSX
785/* Return the program name -- some code out there needs this. */
786char *
787Py_GetProgramFullPath(void)
788{
789 return orig_argv[0];
790}
Jack Jansen1d2f8631996-08-02 15:16:16 +0000791
792char *
Jack Jansendff77702001-09-05 22:07:52 +0000793Py_GetPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000794{
Jack Jansenac625691997-09-08 13:22:22 +0000795 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000796}
797
798char *
Jack Jansendff77702001-09-05 22:07:52 +0000799Py_GetExecPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000800{
Jack Jansenac625691997-09-08 13:22:22 +0000801 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000802}
Jack Jansen8a387142001-02-11 01:08:04 +0000803
804int
Jack Jansendff77702001-09-05 22:07:52 +0000805PyMac_GetDelayConsoleFlag(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000806{
807 return (int)PyMac_options.delayconsole;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000808}
809
810#ifndef WITHOUT_UNIX_NEWLINES
811/*
812** Experimental feature (for 2.2a2): optionally allow unix newlines
813** as well as Mac newlines on input. We replace a lowlevel
814** MSL routine to accomplish this.
815*/
816void
817__convert_to_newlines(unsigned char * buf, size_t * n_ptr)
818{
819 unsigned char *p;
820 size_t n = *n_ptr;
821
822 for(p=buf; n > 0; p++, n--)
823 if ( *p == '\r' ) *p = '\n';
824 else if ( *p == '\n' && !PyMac_options.unixnewlines )
825 *p = '\r';
826}
827#endif /* WITHOUT_UNIX_NEWLINES */
Jack Jansendff77702001-09-05 22:07:52 +0000828#endif /* !TARGET_API_MAC_OSX */
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000829