blob: 0498be4e6d7ef208be43a03d4afda42a1f90d2fa [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 Jansen8f5725a1999-12-07 23:08:10 +000041#ifdef USE_APPEARANCE
42#include <Gestalt.h>
43#include <Appearance.h>
44#endif /* USE_APPEARANCE */
Jack Jansendff77702001-09-05 22:07:52 +000045#else
46#include <Carbon/Carbon.h>
47#endif /* WITHOUT_FRAMEWORKS */
48
Jack Jansenc76fd391995-02-02 14:27:31 +000049#ifdef __MWERKS__
50#include <SIOUX.h>
Jack Jansen1e8557a1995-11-10 14:51:26 +000051#define USE_SIOUX
Jack Jansen9ae898b2000-07-11 21:16:03 +000052extern int ccommand(char ***);
Jack Jansen8c693211997-01-07 16:19:42 +000053#if __profile__ == 1
54#include <profiler.h>
Jack Jansendff77702001-09-05 22:07:52 +000055#endif /* __profile__ */
56#endif /* __MWERKS__ */
57
Jack Jansenee6eeb12000-06-02 21:28:52 +000058#include <unistd.h>
Jack Jansen5bdbabd2000-07-24 19:52:52 +000059#ifdef USE_MAC_SHARED_LIBRARY
60extern PyMac_AddLibResources(void);
61#endif
Jack Jansenc76fd391995-02-02 14:27:31 +000062
Jack Jansen696c9581995-08-14 12:33:20 +000063#define STARTUP "PythonStartup"
Jack Jansenbac428d1994-12-14 13:47:30 +000064
Jack Jansen65c3ee02000-09-08 10:20:37 +000065#define COPYRIGHT \
66 "Type \"copyright\", \"credits\" or \"license\" for more information."
67
Jack Jansen3f7d2b41996-09-06 22:21:07 +000068short PyMac_AppRefNum; /* RefNum of application resource fork */
Jack Jansen696c9581995-08-14 12:33:20 +000069
Jack Jansen1d2f8631996-08-02 15:16:16 +000070/* For Py_GetArgcArgv(); set by main() */
Jack Jansen696c9581995-08-14 12:33:20 +000071static char **orig_argv;
72static int orig_argc;
73
Jack Jansen8a387142001-02-11 01:08:04 +000074/* A flag which remembers whether the user has acknowledged all the console
75** output (by typing something)
76*/
77#define STATE_UNKNOWN 0
78#define STATE_LASTREAD 1
79#define STATE_LASTWRITE 2
80int console_output_state = STATE_UNKNOWN;
81
Jack Jansendc86f9e2000-10-12 21:23:19 +000082PyMac_PrefRecord PyMac_options;
Jack Jansen0168f271995-10-27 13:32:30 +000083
Jack Jansen998a40a2001-09-11 13:08:10 +000084static void Py_Main(int, char **, char *); /* Forward */
Jack Jansend88296d2000-07-11 19:51:05 +000085void PyMac_Exit(int); /* Forward */
Jack Jansen76ceece1996-08-19 11:18:24 +000086
Jack Jansendff77702001-09-05 22:07:52 +000087static void init_appearance(void)
Jack Jansen8f5725a1999-12-07 23:08:10 +000088{
89#ifdef USE_APPEARANCE
90 OSErr err;
91 SInt32 response;
92
93 err = Gestalt(gestaltAppearanceAttr,&response);
94 if ( err ) goto no_appearance;
95 if ( !(response&(1<<gestaltAppearanceExists)) ) goto no_appearance;
96 /* XXXX Should we check the version? Compat-mode? */
97 PyMac_AppearanceCompliant = 1;
98no_appearance:
99 return;
100#endif /* USE_APPEARANCE */
101}
Jack Jansen01fbc681996-02-28 15:42:47 +0000102/* Initialize the Mac toolbox world */
103
104static void
Jack Jansendff77702001-09-05 22:07:52 +0000105init_mac_world(void)
Jack Jansen01fbc681996-02-28 15:42:47 +0000106{
Jack Jansen74a1e632000-07-14 22:37:27 +0000107#if !TARGET_API_MAC_CARBON
Jack Jansenee6eeb12000-06-02 21:28:52 +0000108 /* These aren't needed for carbon */
Jack Jansen01fbc681996-02-28 15:42:47 +0000109 MaxApplZone();
110 InitGraf(&qd.thePort);
111 InitFonts();
112 InitWindows();
113 TEInit();
114 InitDialogs((long)0);
115 InitMenus();
Jack Jansenee6eeb12000-06-02 21:28:52 +0000116#endif
Jack Jansen01fbc681996-02-28 15:42:47 +0000117 InitCursor();
Jack Jansen8f5725a1999-12-07 23:08:10 +0000118 init_appearance();
Jack Jansen01fbc681996-02-28 15:42:47 +0000119}
120
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000121/*
122** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
123*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000124static void
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000125PyMac_InteractiveOptions(PyMac_PrefRecord *p, int *argcp, char ***argvp)
126{
127 KeyMap rmap;
128 unsigned char *map;
129 short item, type;
130 ControlHandle handle;
131 DialogPtr dialog;
132 Rect rect;
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000133
134 /*
135 ** If the preferences disallows interactive options we return,
136 ** similarly of <option> isn't pressed.
137 */
138 if (p->nointopt) return;
139
140 GetKeys(rmap);
141 map = (unsigned char *)rmap;
142 if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
143 return;
144
145 dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
146 if ( dialog == NULL ) {
147 printf("Option dialog not found - cannot set options\n");
148 return;
149 }
150 SetDialogDefaultItem(dialog, OPT_OK);
151 SetDialogCancelItem(dialog, OPT_CANCEL);
152
153 /* Set default values */
154#define SET_OPT_ITEM(num, var) \
155 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
Jack Jansen08c3be31997-04-08 15:27:00 +0000156 SetControlValue(handle, (short)p->var);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000157
158 SET_OPT_ITEM(OPT_INSPECT, inspect);
159 SET_OPT_ITEM(OPT_VERBOSE, verbose);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000160 /* OPT_VERBOSEVERBOSE is default off */
Jack Jansen36b983c1997-09-09 13:53:21 +0000161 SET_OPT_ITEM(OPT_OPTIMIZE, optimize);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000162 SET_OPT_ITEM(OPT_UNBUFFERED, unbuffered);
163 SET_OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen4a5eb962000-09-22 21:50:11 +0000164 GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
165 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
166 GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
167 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
168 GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
169 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
170 GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
171 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
172/* SET_OPT_ITEM(OPT_KEEPCONSOLE, keep_console); */
Jack Jansen0c6d0372000-05-05 23:11:14 +0000173 SET_OPT_ITEM(OPT_TABWARN, tabwarn);
Jack Jansen36b983c1997-09-09 13:53:21 +0000174 SET_OPT_ITEM(OPT_NOSITE, nosite);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000175 SET_OPT_ITEM(OPT_DIVISIONWARN, divisionwarn);
176 SET_OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000177 /* The rest are not settable interactively */
178
179#undef SET_OPT_ITEM
180
181 while (1) {
182 handle = NULL;
183 ModalDialog(NULL, &item);
184 if ( item == OPT_OK )
185 break;
186 if ( item == OPT_CANCEL ) {
Jack Jansen08c3be31997-04-08 15:27:00 +0000187 DisposeDialog(dialog);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000188 exit(0);
189 }
Jack Jansen74a1e632000-07-14 22:37:27 +0000190#if !TARGET_API_MAC_CARBON
Jack Jansen36b983c1997-09-09 13:53:21 +0000191 if ( item == OPT_HELP ) {
192 HMSetBalloons(!HMGetBalloons());
193 }
Jack Jansenee6eeb12000-06-02 21:28:52 +0000194#endif
Jack Jansendff77702001-09-05 22:07:52 +0000195#if !TARGET_API_MAC_OSX
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000196 if ( item == OPT_CMDLINE ) {
Jack Jansendff77702001-09-05 22:07:52 +0000197 int old_argc = *argcp;
198 int i;
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000199 int new_argc, newer_argc;
200 char **new_argv, **newer_argv;
201
202 new_argc = ccommand(&new_argv);
203 newer_argc = (new_argc-1) + old_argc;
204 newer_argv = malloc((newer_argc+1)*sizeof(char *));
205 if( !newer_argv )
206 Py_FatalError("Cannot malloc argv\n");
207 for(i=0; i<old_argc; i++)
208 newer_argv[i] = (*argvp)[i];
209 for(i=old_argc; i<=newer_argc; i++) /* Copy the NULL too */
210 newer_argv[i] = new_argv[i-old_argc+1];
211 *argvp = newer_argv;
212 *argcp = newer_argc;
213
214 /* XXXX Is it not safe to use free() here, apparently */
215 }
Jack Jansendff77702001-09-05 22:07:52 +0000216#endif /* !TARGET_API_MAC_OSX */
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000217#define OPT_ITEM(num, var) \
218 if ( item == (num) ) { \
219 p->var = !p->var; \
220 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
Jack Jansen08c3be31997-04-08 15:27:00 +0000221 SetControlValue(handle, (short)p->var); \
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000222 }
223
224 OPT_ITEM(OPT_INSPECT, inspect);
225 OPT_ITEM(OPT_VERBOSE, verbose);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000226 if ( item == OPT_VERBOSEVERBOSE ) {
227 if ( p->verbose == 2 )
228 p->verbose = 1;
229 else
230 p->verbose = 2;
231 GetDialogItem(dialog, OPT_VERBOSE, &type, (Handle *)&handle, &rect);
232 SetControlValue(handle, 1);
233 }
234 GetDialogItem(dialog, OPT_VERBOSEVERBOSE, &type, (Handle *)&handle, &rect);
235 SetControlValue(handle, p->verbose == 2);
Jack Jansen36b983c1997-09-09 13:53:21 +0000236 OPT_ITEM(OPT_OPTIMIZE, optimize);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000237 OPT_ITEM(OPT_UNBUFFERED, unbuffered);
238 OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen4a5eb962000-09-22 21:50:11 +0000239 if ( item == OPT_KEEPALWAYS ) p->keep_console = POPT_KEEPCONSOLE_ALWAYS;
240 if ( item == OPT_KEEPOUTPUT ) p->keep_console = POPT_KEEPCONSOLE_OUTPUT;
241 if ( item == OPT_KEEPERROR ) p->keep_console = POPT_KEEPCONSOLE_ERROR;
242 if ( item == OPT_KEEPNEVER ) p->keep_console = POPT_KEEPCONSOLE_NEVER;
243 GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
244 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
245 GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
246 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
247 GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
248 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
249 GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
250 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
Jack Jansen0c6d0372000-05-05 23:11:14 +0000251 OPT_ITEM(OPT_TABWARN, tabwarn);
Jack Jansen36b983c1997-09-09 13:53:21 +0000252 OPT_ITEM(OPT_NOSITE, nosite);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000253 OPT_ITEM(OPT_DIVISIONWARN, divisionwarn);
254 OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000255
256#undef OPT_ITEM
257 }
Jack Jansen08c3be31997-04-08 15:27:00 +0000258 DisposeDialog(dialog);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000259}
260
261/*
262** Initialization code, shared by interpreter and applets
263*/
264static void
Jack Jansen52ac0371997-01-15 15:49:08 +0000265init_common(int *argcp, char ***argvp, int embedded)
Jack Jansen01fbc681996-02-28 15:42:47 +0000266{
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000267 /* Remember resource fork refnum, for later */
268 PyMac_AppRefNum = CurResFile();
269
Jack Jansen01fbc681996-02-28 15:42:47 +0000270 /* Initialize toolboxes */
271 init_mac_world();
272
273#ifdef USE_MAC_SHARED_LIBRARY
274 /* Add the shared library to the stack of resource files */
Jack Jansen87c485c1998-07-31 09:38:01 +0000275 (void)PyMac_init_process_location();
Jack Jansen01fbc681996-02-28 15:42:47 +0000276 PyMac_AddLibResources();
277#endif
278
Jack Jansen2d1306b2000-04-07 09:10:49 +0000279#if defined(USE_GUSI1)
Jack Jansen01fbc681996-02-28 15:42:47 +0000280 /* Setup GUSI */
281 GUSIDefaultSetup();
Jack Jansenf6865f71996-09-04 15:24:59 +0000282 PyMac_SetGUSISpin();
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000283 PyMac_SetGUSIOptions();
Jack Jansen01fbc681996-02-28 15:42:47 +0000284#endif
Jack Jansen2d1306b2000-04-07 09:10:49 +0000285#if defined(USE_GUSI)
286 atexit(PyMac_StopGUSISpin);
287#endif
Jack Jansen01fbc681996-02-28 15:42:47 +0000288
289#ifdef USE_SIOUX
290 /* Set various SIOUX flags. Some are changed later based on options */
Jack Jansendff77702001-09-05 22:07:52 +0000291#if 0
292 SIOUXSettings.standalone = 0; /* XXXX Attempting to keep sioux from eating events */
293#endif
Jack Jansen01fbc681996-02-28 15:42:47 +0000294 SIOUXSettings.asktosaveonclose = 0;
295 SIOUXSettings.showstatusline = 0;
296 SIOUXSettings.tabspaces = 4;
297#endif
298
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000299 /* Get options from preference file (or from applet resource fork) */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000300 PyMac_options.keep_console = POPT_KEEPCONSOLE_OUTPUT; /* default-default */
Jack Jansendff77702001-09-05 22:07:52 +0000301 PyMac_options.unixnewlines = 1;
302#if !TARGET_API_MAC_OSX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000303 PyMac_PreferenceOptions(&PyMac_options);
Jack Jansendff77702001-09-05 22:07:52 +0000304#endif
305
Jack Jansen52ac0371997-01-15 15:49:08 +0000306 if ( embedded ) {
307 static char *emb_argv[] = {"embedded-python", 0};
308
309 *argcp = 1;
310 *argvp = emb_argv;
311 } else {
312 /* Create argc/argv. Do it before we go into the options event loop. */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000313 *argcp = PyMac_GetArgv(argvp, PyMac_options.noargs);
Jack Jansendff77702001-09-05 22:07:52 +0000314#if !TARGET_API_MAC_OSX
Jack Jansenc00df0b2001-01-16 15:54:58 +0000315#ifndef NO_ARGV0_CHDIR
Jack Jansen660bb1d2000-07-18 09:40:39 +0000316 if (*argcp >= 1 && (*argvp)[0] && (*argvp)[0][0]) {
317 /* Workaround for MacOS X, which currently (DP4) doesn't set
318 ** the working folder correctly
319 */
320 char app_wd[256], *p;
321
322 strncpy(app_wd, (*argvp)[0], 256);
Jack Jansen660bb1d2000-07-18 09:40:39 +0000323 p = strrchr(app_wd, ':');
324 if ( p ) *p = 0;
Jack Jansen660bb1d2000-07-18 09:40:39 +0000325 chdir(app_wd);
326 }
327#endif
Jack Jansendff77702001-09-05 22:07:52 +0000328#endif
Jack Jansen52ac0371997-01-15 15:49:08 +0000329 /* Do interactive option setting, if allowed and <option> depressed */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000330 PyMac_InteractiveOptions(&PyMac_options, argcp, argvp);
Jack Jansen52ac0371997-01-15 15:49:08 +0000331 }
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000332
333 /* Copy selected options to where the machine-independent stuff wants it */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000334 Py_VerboseFlag = PyMac_options.verbose;
335/* Py_SuppressPrintingFlag = PyMac_options.suppress_print; */
336 Py_OptimizeFlag = PyMac_options.optimize;
337 Py_DebugFlag = PyMac_options.debugging;
338 Py_NoSiteFlag = PyMac_options.nosite;
339 Py_TabcheckFlag = PyMac_options.tabwarn;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000340 Py_DivisionWarningFlag = PyMac_options.divisionwarn;
Jack Jansendff77702001-09-05 22:07:52 +0000341#if !TARGET_API_MAC_OSX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000342 if ( PyMac_options.noargs ) {
Jack Jansene3ae0df1997-06-03 15:28:29 +0000343 /* don't process events at all without the scripts permission */
344 PyMacSchedParams scp;
345
346 PyMac_GetSchedParams(&scp);
347 scp.process_events = 0;
348 /* Should we disable command-dot as well? */
349 PyMac_SetSchedParams(&scp);
350 }
Jack Jansendff77702001-09-05 22:07:52 +0000351#endif /* !TARGET_API_MAC_OSX */
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000352
353 /* Set buffering */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000354 if (PyMac_options.unbuffered) {
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000355#ifndef MPW
356 setbuf(stdout, (char *)NULL);
357 setbuf(stderr, (char *)NULL);
358#else
359 /* On MPW (3.2) unbuffered seems to hang */
360 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
361 setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
362#endif
363 }
Jack Jansen8c693211997-01-07 16:19:42 +0000364#if __profile__ == 1
365 /* collectSummary or collectDetailed, timebase, #routines, max stack depth */
Jack Jansene7424871999-09-30 11:20:11 +0000366 ProfilerInit(collectSummary, bestTimeBase, 8000, 250);
Jack Jansen8c693211997-01-07 16:19:42 +0000367#endif
Jack Jansen7330b391997-08-08 14:56:41 +0000368
369 /* Tell the rest of python about our argc/argv */
370 orig_argc = *argcp; /* For Py_GetArgcArgv() */
371 orig_argv = *argvp;
372 Py_SetProgramName((*argvp)[0]);
Jack Jansen01fbc681996-02-28 15:42:47 +0000373}
374
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000375/*
376** Inspection mode after script/applet termination
377*/
378static int
Jack Jansendff77702001-09-05 22:07:52 +0000379run_inspect(void)
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000380{
381 int sts = 0;
382
Jack Jansendc86f9e2000-10-12 21:23:19 +0000383 if (PyMac_options.inspect && isatty((int)fileno(stdin)))
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000384 sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
385 return sts;
386}
Jack Jansen6438e1d2001-09-11 11:29:31 +0000387
Jack Jansen0c6d0372000-05-05 23:11:14 +0000388/*
389** Import the macfsn module, which will override the Standard File
390** calls in the macfs builtin module by Navigation Services versions,
391** if available on this machine.
392*/
393static void
Jack Jansendff77702001-09-05 22:07:52 +0000394PyMac_InstallNavServicesForSF(void)
Jack Jansen0c6d0372000-05-05 23:11:14 +0000395{
Jack Jansendc86f9e2000-10-12 21:23:19 +0000396 if ( !PyMac_options.nonavservice ) {
Jack Jansen0c6d0372000-05-05 23:11:14 +0000397 PyObject *m = PyImport_ImportModule("macfsn");
398
399 if ( m == NULL ) {
400 PySys_WriteStderr("'import macfsn' failed; ");
401 if (Py_VerboseFlag) {
402 PySys_WriteStderr("traceback:\n");
403 PyErr_Print();
404 }
405 else {
406 PySys_WriteStderr("use -v for traceback\n");
407 }
Jack Jansen6438e1d2001-09-11 11:29:31 +0000408 PyErr_Clear();
Jack Jansen0c6d0372000-05-05 23:11:14 +0000409 }
410 }
411}
412
Jack Jansen696c9581995-08-14 12:33:20 +0000413#ifdef USE_MAC_APPLET_SUPPORT
414/* Applet support */
415
416/* Run a compiled Python Python script from 'PYC ' resource __main__ */
417static int
Jack Jansendff77702001-09-05 22:07:52 +0000418run_main_resource(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000419{
420 Handle h;
421 long size;
422 PyObject *code;
423 PyObject *result;
424
425 h = GetNamedResource('PYC ', "\p__main__");
426 if (h == NULL) {
427 Alert(NOPYC_ALERT, NULL);
428 return 1;
429 }
430 size = GetResourceSizeOnDisk(h);
431 HLock(h);
432 code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
433 HUnlock(h);
434 ReleaseResource(h);
435 if (code == NULL) {
436 PyErr_Print();
437 return 1;
438 }
439 result = PyImport_ExecCodeModule("__main__", code);
440 Py_DECREF(code);
441 if (result == NULL) {
442 PyErr_Print();
443 return 1;
444 }
445 Py_DECREF(result);
446 return 0;
447}
448
449/* Initialization sequence for applets */
450void
Jack Jansendff77702001-09-05 22:07:52 +0000451PyMac_InitApplet(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000452{
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000453 int argc;
454 char **argv;
Jack Jansen696c9581995-08-14 12:33:20 +0000455 int err;
456
Jack Jansen52ac0371997-01-15 15:49:08 +0000457 init_common(&argc, &argv, 0);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000458
Jack Jansen696c9581995-08-14 12:33:20 +0000459 Py_Initialize();
Jack Jansen0c6d0372000-05-05 23:11:14 +0000460 PyMac_InstallNavServicesForSF();
Jack Jansen696c9581995-08-14 12:33:20 +0000461 PySys_SetArgv(argc, argv);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000462
Jack Jansen696c9581995-08-14 12:33:20 +0000463 err = run_main_resource();
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000464
465 err = (run_inspect() || err);
466
Jack Jansen696c9581995-08-14 12:33:20 +0000467 fflush(stderr);
468 fflush(stdout);
Jack Jansen0168f271995-10-27 13:32:30 +0000469 PyMac_Exit(err);
Jack Jansen696c9581995-08-14 12:33:20 +0000470 /* XXX Should we bother to Py_Exit(sts)? */
471}
472
Jack Jansen52ac0371997-01-15 15:49:08 +0000473/*
474** Hook for embedding python.
475*/
476void
Jack Jansendff77702001-09-05 22:07:52 +0000477PyMac_Initialize(void)
Jack Jansen52ac0371997-01-15 15:49:08 +0000478{
479 int argc;
480 char **argv;
481
482 init_common(&argc, &argv, 1);
483 Py_Initialize();
Jack Jansen0c6d0372000-05-05 23:11:14 +0000484 PyMac_InstallNavServicesForSF();
Jack Jansen52ac0371997-01-15 15:49:08 +0000485 PySys_SetArgv(argc, argv);
486}
487
Jack Jansen696c9581995-08-14 12:33:20 +0000488#endif /* USE_MAC_APPLET_SUPPORT */
489
Jack Jansendff77702001-09-05 22:07:52 +0000490#if TARGET_API_MAC_OSX
Jack Jansen998a40a2001-09-11 13:08:10 +0000491
492static int
493locateResourcePy(char * resourceName, char * resourceURLCStr, int length) {
494 CFBundleRef mainBundle = NULL;
495 CFURLRef URL, absoluteURL;
496 CFStringRef filenameString, filepathString, rsrcString;
497 CFIndex size, i;
498 CFArrayRef arrayRef;
499 Boolean success = 0;
500
501 /* Create a CFString with the resource name in it */
502 rsrcString = CFStringCreateWithCString(0, resourceName, kCFStringEncodingMacRoman);
503
504 /* Get a reference to our main bundle */
505 mainBundle = CFBundleGetMainBundle();
506
507 /* Look for py files in the main bundle by type */
508 arrayRef = CFBundleCopyResourceURLsOfType( mainBundle,
509 CFSTR("py"),
510 NULL );
511
512 /* See if there are any filename matches */
513 size = CFArrayGetCount(arrayRef);
514 for (i = 0; i < size; i++) {
515 URL = CFArrayGetValueAtIndex(arrayRef, i);
516 filenameString = CFURLCopyLastPathComponent(URL);
517 if (CFStringCompare(filenameString, rsrcString, 0) == kCFCompareEqualTo) {
518 /* We found a match, get the file's full path */
519 absoluteURL = CFURLCopyAbsoluteURL(URL);
520 filepathString = CFURLCopyFileSystemPath(absoluteURL, kCFURLPOSIXPathStyle);
521 CFRelease(absoluteURL);
522
523 /* Copy the full path into the caller's character buffer */
524 success = CFStringGetCString(filepathString, resourceURLCStr, length,
525 kCFStringEncodingMacRoman);
526
527 CFRelease(filepathString);
528 }
529 CFRelease(filenameString);
530 }
531 CFRelease(rsrcString);
532 CFRelease(arrayRef);
533
534 return success;
535}
536
Jack Jansendff77702001-09-05 22:07:52 +0000537int
538main(int argc, char **argv)
539{
Jack Jansen998a40a2001-09-11 13:08:10 +0000540 int i;
541 static char scriptpath[1024];
542 char *script = NULL;
543
544 /* First we see whether we have __rawmain__.py and run that if it
545 ** is there
546 */
547 if (locateResourcePy("__rawmain__.py", scriptpath, 1024)) {
548 /* If we have a raw main we don't do AppleEvent processing.
549 ** Notice that this also means we keep the -psn.... argv[1]
550 ** value intact. Not sure whether that is important to someone,
551 ** but you never know...
552 */
553 script = scriptpath;
554 } else {
555 /* Otherwise we look for __main__.py. Whether that is
556 ** found or not we also process AppleEvent arguments.
557 */
558 if (locateResourcePy("__main__.py", scriptpath, 1024))
559 script = scriptpath;
560
561 printf("original argc=%d\n", argc);
562 for(i=0; i<argc; i++) printf("original argv[%d] = \"%s\"\n", i, argv[i]);
563
564 init_common(&argc, &argv, 0);
565
566 printf("modified argc=%d\n", argc);
567 for(i=0; i<argc; i++) printf("modified argv[%d] = \"%s\"\n", i, argv[i]);
568 }
569
570 Py_Main(argc, argv, script);
571 return 0;
Jack Jansendff77702001-09-05 22:07:52 +0000572}
573
574#else
575
Jack Jansen696c9581995-08-14 12:33:20 +0000576/* For normal application */
577void
Jack Jansendff77702001-09-05 22:07:52 +0000578PyMac_InitApplication(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000579{
580 int argc;
581 char **argv;
582
Jack Jansen52ac0371997-01-15 15:49:08 +0000583 init_common(&argc, &argv, 0);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000584
Jack Jansen696c9581995-08-14 12:33:20 +0000585 if ( argc > 1 ) {
586 /* We're running a script. Attempt to change current directory */
587 char curwd[256], *endp;
588
589 strcpy(curwd, argv[1]);
590 endp = strrchr(curwd, ':');
591 if ( endp && endp > curwd ) {
592 *endp = '\0';
593
594 chdir(curwd);
Jack Jansen2d1306b2000-04-07 09:10:49 +0000595#ifdef USE_GUSI1
Jack Jansen378815c1996-03-06 16:21:34 +0000596 /* Change MacOS's idea of wd too */
597 PyMac_FixGUSIcd();
598#endif
Jack Jansen696c9581995-08-14 12:33:20 +0000599 }
Jack Jansencbed91b2001-08-03 13:31:36 +0000600 /* Check that the first argument is a text file */
601 if ( PyMac_getfiletype(argv[1]) != 'TEXT' ) {
602 Alert(NOTASCRIPT_ID, NULL);
603 exit(0);
604 }
Jack Jansen696c9581995-08-14 12:33:20 +0000605 }
Jack Jansen998a40a2001-09-11 13:08:10 +0000606 Py_Main(argc, argv, NULL);
Jack Jansen696c9581995-08-14 12:33:20 +0000607}
Jack Jansendff77702001-09-05 22:07:52 +0000608#endif /* TARGET_API_MAC_OSX */
Jack Jansen696c9581995-08-14 12:33:20 +0000609
Jack Jansen696c9581995-08-14 12:33:20 +0000610/* Main program */
611
Jack Jansen76ceece1996-08-19 11:18:24 +0000612static void
Jack Jansen998a40a2001-09-11 13:08:10 +0000613Py_Main(int argc, char **argv, char *filename)
Jack Jansen696c9581995-08-14 12:33:20 +0000614{
Jack Jansen696c9581995-08-14 12:33:20 +0000615 int sts;
616 char *command = NULL;
Jack Jansen696c9581995-08-14 12:33:20 +0000617 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000618
Jack Jansen998a40a2001-09-11 13:08:10 +0000619 if ( filename ) {
620 /* Someone else has found our "script" already */
621 argv[0] = filename;
622 } else {
623 filename = argv[1];
624 argv++;
625 argc--;
626 }
Jack Jansen696c9581995-08-14 12:33:20 +0000627
628 if (Py_VerboseFlag ||
Jack Jansendff77702001-09-05 22:07:52 +0000629 (command == NULL && filename == NULL && isatty((int)fileno(fp))))
Jack Jansen65c3ee02000-09-08 10:20:37 +0000630 fprintf(stderr, "Python %s on %s\n%s\n",
631 Py_GetVersion(), Py_GetPlatform(), COPYRIGHT);
Jack Jansen696c9581995-08-14 12:33:20 +0000632
633 if (filename != NULL) {
634 if ((fp = fopen(filename, "r")) == NULL) {
635 fprintf(stderr, "%s: can't open file '%s'\n",
636 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000637 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000638 }
639 }
640
Jack Jansendff77702001-09-05 22:07:52 +0000641#if !TARGET_API_MAC_OSX
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000642 /* We initialize the menubar here, hoping SIOUX is initialized by now */
Jack Jansen3469e991996-09-06 00:30:45 +0000643 PyMac_InitMenuBar();
Jack Jansendff77702001-09-05 22:07:52 +0000644#endif
645
Jack Jansen696c9581995-08-14 12:33:20 +0000646 Py_Initialize();
647
unknownd1054ef2001-07-04 22:37:19 +0000648 PyUnicode_SetDefaultEncoding(PyMac_getscript());
649
Jack Jansen0c6d0372000-05-05 23:11:14 +0000650 PyMac_InstallNavServicesForSF();
651
Jack Jansen998a40a2001-09-11 13:08:10 +0000652 PySys_SetArgv(argc, argv);
Jack Jansen696c9581995-08-14 12:33:20 +0000653
654 if (filename == NULL && isatty((int)fileno(fp))) {
655 FILE *fp = fopen(STARTUP, "r");
656 if (fp != NULL) {
657 (void) PyRun_SimpleFile(fp, STARTUP);
658 PyErr_Clear();
659 fclose(fp);
660 }
661 }
662 sts = PyRun_AnyFile(
663 fp, filename == NULL ? "<stdin>" : filename) != 0;
664 if (filename != NULL)
665 fclose(fp);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000666
667 if ( filename != NULL || command != NULL )
668 sts = (run_inspect() || sts);
Jack Jansen696c9581995-08-14 12:33:20 +0000669
670 Py_Exit(sts);
671 /*NOTREACHED*/
672}
673
Jack Jansendff77702001-09-05 22:07:52 +0000674#if !TARGET_API_MAC_OSX
Jack Jansen0168f271995-10-27 13:32:30 +0000675/*
Jack Jansen8413b472000-10-19 22:02:16 +0000676** Reset the "unseen output" flag
677*/
678void
Jack Jansendff77702001-09-05 22:07:52 +0000679PyMac_OutputSeen(void)
Jack Jansen8413b472000-10-19 22:02:16 +0000680{
Jack Jansen657ba272001-02-17 22:02:07 +0000681 if ( console_output_state == STATE_UNKNOWN )
682 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000683 console_output_state = STATE_LASTREAD;
Jack Jansen8413b472000-10-19 22:02:16 +0000684}
685
686/*
Jack Jansen8a387142001-02-11 01:08:04 +0000687** Set the "unseen output" flag
688*/
689void
Jack Jansendff77702001-09-05 22:07:52 +0000690PyMac_OutputNotSeen(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000691{
Jack Jansen657ba272001-02-17 22:02:07 +0000692 if ( console_output_state == STATE_UNKNOWN )
693 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000694 console_output_state = STATE_LASTWRITE;
695}
Jack Jansen15f1c082001-04-25 22:07:27 +0000696
697/*
698** Override abort() - The default one is not what we want.
699*/
700void
Jack Jansendff77702001-09-05 22:07:52 +0000701abort(void)
Jack Jansen15f1c082001-04-25 22:07:27 +0000702{
703 console_output_state = STATE_LASTWRITE;
704 PyMac_Exit(1);
705}
Jack Jansendff77702001-09-05 22:07:52 +0000706#endif /* !TARGET_API_MAC_OSX */
Jack Jansen8a387142001-02-11 01:08:04 +0000707
708/*
Jack Jansen0168f271995-10-27 13:32:30 +0000709** Terminate application
710*/
Jack Jansen76ceece1996-08-19 11:18:24 +0000711void
Jack Jansendff77702001-09-05 22:07:52 +0000712PyMac_Exit(int status)
Jack Jansen0168f271995-10-27 13:32:30 +0000713{
Jack Jansendff77702001-09-05 22:07:52 +0000714#ifdef USE_SIOUX
Jack Jansen4a5eb962000-09-22 21:50:11 +0000715 int keep = 0;
Jack Jansendff77702001-09-05 22:07:52 +0000716#endif
Jack Jansen8c693211997-01-07 16:19:42 +0000717
718#if __profile__ == 1
719 ProfilerDump("\pPython Profiler Results");
720 ProfilerTerm();
721#endif
Jack Jansen0168f271995-10-27 13:32:30 +0000722
Jack Jansen1e8557a1995-11-10 14:51:26 +0000723#ifdef USE_SIOUX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000724 switch (PyMac_options.keep_console) {
Jack Jansen4a5eb962000-09-22 21:50:11 +0000725 case POPT_KEEPCONSOLE_NEVER:
726 keep = 0;
727 break;
728 case POPT_KEEPCONSOLE_OUTPUT:
Jack Jansen8a387142001-02-11 01:08:04 +0000729 if (console_output_state == STATE_LASTWRITE ||
730 console_output_state == STATE_UNKNOWN )
Jack Jansen4a5eb962000-09-22 21:50:11 +0000731 keep = 1;
732 else
733 keep = 0;
734 break;
735 case POPT_KEEPCONSOLE_ERROR:
736 keep = (status != 0);
737 break;
738 default:
739 keep = 1;
740 }
Jack Jansen1e8557a1995-11-10 14:51:26 +0000741 if (keep) {
742 SIOUXSettings.standalone = 1;
743 SIOUXSettings.autocloseonquit = 0;
Jack Jansen415571c1996-03-25 15:46:03 +0000744 SIOUXSetTitle("\p\307terminated\310");
Jack Jansen15f1c082001-04-25 22:07:27 +0000745 PyMac_RaiseConsoleWindow();
Jack Jansencaa7c461997-06-12 10:49:13 +0000746 PyMac_RestoreMenuBar();
Jack Jansene44545f1997-05-07 15:48:54 +0000747#ifdef USE_MSL
748 /*
749 ** Temporary workaround: autocloseonquit clearing does not
750 ** currently work for the MSL/GUSI combo.
751 */
752 while(getchar() > 0);
753#endif
Jack Jansen1e8557a1995-11-10 14:51:26 +0000754 }
Jack Jansen0168f271995-10-27 13:32:30 +0000755 else
756 SIOUXSettings.autocloseonquit = 1;
Jack Jansenf6865f71996-09-04 15:24:59 +0000757#endif /* USE_SIOUX */
Jack Jansen0168f271995-10-27 13:32:30 +0000758
759 exit(status);
760}
Jack Jansen696c9581995-08-14 12:33:20 +0000761
Jack Jansendff77702001-09-05 22:07:52 +0000762#if !TARGET_API_MAC_OSX
Jack Jansen696c9581995-08-14 12:33:20 +0000763/* Make the *original* argc/argv available to other modules.
764 This is rare, but it is needed by the secureware extension. */
765
766void
Jack Jansen9ae898b2000-07-11 21:16:03 +0000767Py_GetArgcArgv(int *argc,char ***argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000768{
769 *argc = orig_argc;
770 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000771}
Jack Jansendff77702001-09-05 22:07:52 +0000772#endif
Jack Jansen1d2f8631996-08-02 15:16:16 +0000773
774/* More cruft that shouldn't really be here, used in sysmodule.c */
Jack Jansendff77702001-09-05 22:07:52 +0000775#if !TARGET_API_MAC_OSX
776/* Return the program name -- some code out there needs this. */
777char *
778Py_GetProgramFullPath(void)
779{
780 return orig_argv[0];
781}
Jack Jansen1d2f8631996-08-02 15:16:16 +0000782
783char *
Jack Jansendff77702001-09-05 22:07:52 +0000784Py_GetPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000785{
Jack Jansenac625691997-09-08 13:22:22 +0000786 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000787}
788
789char *
Jack Jansendff77702001-09-05 22:07:52 +0000790Py_GetExecPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000791{
Jack Jansenac625691997-09-08 13:22:22 +0000792 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000793}
Jack Jansen8a387142001-02-11 01:08:04 +0000794
795int
Jack Jansendff77702001-09-05 22:07:52 +0000796PyMac_GetDelayConsoleFlag(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000797{
798 return (int)PyMac_options.delayconsole;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000799}
800
801#ifndef WITHOUT_UNIX_NEWLINES
802/*
803** Experimental feature (for 2.2a2): optionally allow unix newlines
804** as well as Mac newlines on input. We replace a lowlevel
805** MSL routine to accomplish this.
806*/
807void
808__convert_to_newlines(unsigned char * buf, size_t * n_ptr)
809{
810 unsigned char *p;
811 size_t n = *n_ptr;
812
813 for(p=buf; n > 0; p++, n--)
814 if ( *p == '\r' ) *p = '\n';
815 else if ( *p == '\n' && !PyMac_options.unixnewlines )
816 *p = '\r';
817}
818#endif /* WITHOUT_UNIX_NEWLINES */
Jack Jansendff77702001-09-05 22:07:52 +0000819#endif /* !TARGET_API_MAC_OSX */
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000820