blob: 39f62221d942d4d936dc83413eba7d41e230b0c5 [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 Jansend88296d2000-07-11 19:51:05 +000084static void Py_Main(int, char **); /* Forward */
85void 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 Jansen01fbc681996-02-28 15:42:47 +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 }
408 }
409 }
410}
411
Jack Jansen696c9581995-08-14 12:33:20 +0000412#ifdef USE_MAC_APPLET_SUPPORT
413/* Applet support */
414
415/* Run a compiled Python Python script from 'PYC ' resource __main__ */
416static int
Jack Jansendff77702001-09-05 22:07:52 +0000417run_main_resource(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000418{
419 Handle h;
420 long size;
421 PyObject *code;
422 PyObject *result;
423
424 h = GetNamedResource('PYC ', "\p__main__");
425 if (h == NULL) {
426 Alert(NOPYC_ALERT, NULL);
427 return 1;
428 }
429 size = GetResourceSizeOnDisk(h);
430 HLock(h);
431 code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
432 HUnlock(h);
433 ReleaseResource(h);
434 if (code == NULL) {
435 PyErr_Print();
436 return 1;
437 }
438 result = PyImport_ExecCodeModule("__main__", code);
439 Py_DECREF(code);
440 if (result == NULL) {
441 PyErr_Print();
442 return 1;
443 }
444 Py_DECREF(result);
445 return 0;
446}
447
448/* Initialization sequence for applets */
449void
Jack Jansendff77702001-09-05 22:07:52 +0000450PyMac_InitApplet(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000451{
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000452 int argc;
453 char **argv;
Jack Jansen696c9581995-08-14 12:33:20 +0000454 int err;
455
Jack Jansen52ac0371997-01-15 15:49:08 +0000456 init_common(&argc, &argv, 0);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000457
Jack Jansen696c9581995-08-14 12:33:20 +0000458 Py_Initialize();
Jack Jansen0c6d0372000-05-05 23:11:14 +0000459 PyMac_InstallNavServicesForSF();
Jack Jansen696c9581995-08-14 12:33:20 +0000460 PySys_SetArgv(argc, argv);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000461
Jack Jansen696c9581995-08-14 12:33:20 +0000462 err = run_main_resource();
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000463
464 err = (run_inspect() || err);
465
Jack Jansen696c9581995-08-14 12:33:20 +0000466 fflush(stderr);
467 fflush(stdout);
Jack Jansen0168f271995-10-27 13:32:30 +0000468 PyMac_Exit(err);
Jack Jansen696c9581995-08-14 12:33:20 +0000469 /* XXX Should we bother to Py_Exit(sts)? */
470}
471
Jack Jansen52ac0371997-01-15 15:49:08 +0000472/*
473** Hook for embedding python.
474*/
475void
Jack Jansendff77702001-09-05 22:07:52 +0000476PyMac_Initialize(void)
Jack Jansen52ac0371997-01-15 15:49:08 +0000477{
478 int argc;
479 char **argv;
480
481 init_common(&argc, &argv, 1);
482 Py_Initialize();
Jack Jansen0c6d0372000-05-05 23:11:14 +0000483 PyMac_InstallNavServicesForSF();
Jack Jansen52ac0371997-01-15 15:49:08 +0000484 PySys_SetArgv(argc, argv);
485}
486
Jack Jansen696c9581995-08-14 12:33:20 +0000487#endif /* USE_MAC_APPLET_SUPPORT */
488
Jack Jansendff77702001-09-05 22:07:52 +0000489#if TARGET_API_MAC_OSX
490int
491main(int argc, char **argv)
492{
493 int i;
494 printf("first argc=%d\n", argc);
495 for(i=0; i<argc; i++) printf("first argv[%d] = \"%s\"\n", i, argv[i]);
496 init_common(&argc, &argv, 0);
497 printf("second argc=%d\n", argc);
498 for(i=0; i<argc; i++) printf("second argv[%d] = \"%s\"\n", i, argv[i]);
499 Py_Main(argc, argv);
500 return 0;
501}
502
503#else
504
Jack Jansen696c9581995-08-14 12:33:20 +0000505/* For normal application */
506void
Jack Jansendff77702001-09-05 22:07:52 +0000507PyMac_InitApplication(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000508{
509 int argc;
510 char **argv;
511
Jack Jansen52ac0371997-01-15 15:49:08 +0000512 init_common(&argc, &argv, 0);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000513
Jack Jansen696c9581995-08-14 12:33:20 +0000514 if ( argc > 1 ) {
515 /* We're running a script. Attempt to change current directory */
516 char curwd[256], *endp;
517
518 strcpy(curwd, argv[1]);
519 endp = strrchr(curwd, ':');
520 if ( endp && endp > curwd ) {
521 *endp = '\0';
522
523 chdir(curwd);
Jack Jansen2d1306b2000-04-07 09:10:49 +0000524#ifdef USE_GUSI1
Jack Jansen378815c1996-03-06 16:21:34 +0000525 /* Change MacOS's idea of wd too */
526 PyMac_FixGUSIcd();
527#endif
Jack Jansen696c9581995-08-14 12:33:20 +0000528 }
Jack Jansencbed91b2001-08-03 13:31:36 +0000529 /* Check that the first argument is a text file */
530 if ( PyMac_getfiletype(argv[1]) != 'TEXT' ) {
531 Alert(NOTASCRIPT_ID, NULL);
532 exit(0);
533 }
Jack Jansen696c9581995-08-14 12:33:20 +0000534 }
535 Py_Main(argc, argv);
536}
Jack Jansendff77702001-09-05 22:07:52 +0000537#endif /* TARGET_API_MAC_OSX */
Jack Jansen696c9581995-08-14 12:33:20 +0000538
Jack Jansen696c9581995-08-14 12:33:20 +0000539/* Main program */
540
Jack Jansen76ceece1996-08-19 11:18:24 +0000541static void
Jack Jansendff77702001-09-05 22:07:52 +0000542Py_Main(int argc, char **argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000543{
Jack Jansen696c9581995-08-14 12:33:20 +0000544 int sts;
545 char *command = NULL;
546 char *filename = NULL;
547 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000548
Jack Jansen696c9581995-08-14 12:33:20 +0000549 filename = argv[1];
550
551 if (Py_VerboseFlag ||
Jack Jansendff77702001-09-05 22:07:52 +0000552 (command == NULL && filename == NULL && isatty((int)fileno(fp))))
Jack Jansen65c3ee02000-09-08 10:20:37 +0000553 fprintf(stderr, "Python %s on %s\n%s\n",
554 Py_GetVersion(), Py_GetPlatform(), COPYRIGHT);
Jack Jansen696c9581995-08-14 12:33:20 +0000555
556 if (filename != NULL) {
557 if ((fp = fopen(filename, "r")) == NULL) {
558 fprintf(stderr, "%s: can't open file '%s'\n",
559 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000560 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000561 }
562 }
563
Jack Jansendff77702001-09-05 22:07:52 +0000564#if !TARGET_API_MAC_OSX
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000565 /* We initialize the menubar here, hoping SIOUX is initialized by now */
Jack Jansen3469e991996-09-06 00:30:45 +0000566 PyMac_InitMenuBar();
Jack Jansendff77702001-09-05 22:07:52 +0000567#endif
568
Jack Jansen696c9581995-08-14 12:33:20 +0000569 Py_Initialize();
570
unknownd1054ef2001-07-04 22:37:19 +0000571 PyUnicode_SetDefaultEncoding(PyMac_getscript());
572
Jack Jansen0c6d0372000-05-05 23:11:14 +0000573 PyMac_InstallNavServicesForSF();
574
Jack Jansen696c9581995-08-14 12:33:20 +0000575 PySys_SetArgv(argc-1, argv+1);
576
577 if (filename == NULL && isatty((int)fileno(fp))) {
578 FILE *fp = fopen(STARTUP, "r");
579 if (fp != NULL) {
580 (void) PyRun_SimpleFile(fp, STARTUP);
581 PyErr_Clear();
582 fclose(fp);
583 }
584 }
585 sts = PyRun_AnyFile(
586 fp, filename == NULL ? "<stdin>" : filename) != 0;
587 if (filename != NULL)
588 fclose(fp);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000589
590 if ( filename != NULL || command != NULL )
591 sts = (run_inspect() || sts);
Jack Jansen696c9581995-08-14 12:33:20 +0000592
593 Py_Exit(sts);
594 /*NOTREACHED*/
595}
596
Jack Jansendff77702001-09-05 22:07:52 +0000597#if !TARGET_API_MAC_OSX
Jack Jansen0168f271995-10-27 13:32:30 +0000598/*
Jack Jansen8413b472000-10-19 22:02:16 +0000599** Reset the "unseen output" flag
600*/
601void
Jack Jansendff77702001-09-05 22:07:52 +0000602PyMac_OutputSeen(void)
Jack Jansen8413b472000-10-19 22:02:16 +0000603{
Jack Jansen657ba272001-02-17 22:02:07 +0000604 if ( console_output_state == STATE_UNKNOWN )
605 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000606 console_output_state = STATE_LASTREAD;
Jack Jansen8413b472000-10-19 22:02:16 +0000607}
608
609/*
Jack Jansen8a387142001-02-11 01:08:04 +0000610** Set the "unseen output" flag
611*/
612void
Jack Jansendff77702001-09-05 22:07:52 +0000613PyMac_OutputNotSeen(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000614{
Jack Jansen657ba272001-02-17 22:02:07 +0000615 if ( console_output_state == STATE_UNKNOWN )
616 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000617 console_output_state = STATE_LASTWRITE;
618}
Jack Jansen15f1c082001-04-25 22:07:27 +0000619
620/*
621** Override abort() - The default one is not what we want.
622*/
623void
Jack Jansendff77702001-09-05 22:07:52 +0000624abort(void)
Jack Jansen15f1c082001-04-25 22:07:27 +0000625{
626 console_output_state = STATE_LASTWRITE;
627 PyMac_Exit(1);
628}
Jack Jansendff77702001-09-05 22:07:52 +0000629#endif /* !TARGET_API_MAC_OSX */
Jack Jansen8a387142001-02-11 01:08:04 +0000630
631/*
Jack Jansen0168f271995-10-27 13:32:30 +0000632** Terminate application
633*/
Jack Jansen76ceece1996-08-19 11:18:24 +0000634void
Jack Jansendff77702001-09-05 22:07:52 +0000635PyMac_Exit(int status)
Jack Jansen0168f271995-10-27 13:32:30 +0000636{
Jack Jansendff77702001-09-05 22:07:52 +0000637#ifdef USE_SIOUX
Jack Jansen4a5eb962000-09-22 21:50:11 +0000638 int keep = 0;
Jack Jansendff77702001-09-05 22:07:52 +0000639#endif
Jack Jansen8c693211997-01-07 16:19:42 +0000640
641#if __profile__ == 1
642 ProfilerDump("\pPython Profiler Results");
643 ProfilerTerm();
644#endif
Jack Jansen0168f271995-10-27 13:32:30 +0000645
Jack Jansen1e8557a1995-11-10 14:51:26 +0000646#ifdef USE_SIOUX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000647 switch (PyMac_options.keep_console) {
Jack Jansen4a5eb962000-09-22 21:50:11 +0000648 case POPT_KEEPCONSOLE_NEVER:
649 keep = 0;
650 break;
651 case POPT_KEEPCONSOLE_OUTPUT:
Jack Jansen8a387142001-02-11 01:08:04 +0000652 if (console_output_state == STATE_LASTWRITE ||
653 console_output_state == STATE_UNKNOWN )
Jack Jansen4a5eb962000-09-22 21:50:11 +0000654 keep = 1;
655 else
656 keep = 0;
657 break;
658 case POPT_KEEPCONSOLE_ERROR:
659 keep = (status != 0);
660 break;
661 default:
662 keep = 1;
663 }
Jack Jansen1e8557a1995-11-10 14:51:26 +0000664 if (keep) {
665 SIOUXSettings.standalone = 1;
666 SIOUXSettings.autocloseonquit = 0;
Jack Jansen415571c1996-03-25 15:46:03 +0000667 SIOUXSetTitle("\p\307terminated\310");
Jack Jansen15f1c082001-04-25 22:07:27 +0000668 PyMac_RaiseConsoleWindow();
Jack Jansencaa7c461997-06-12 10:49:13 +0000669 PyMac_RestoreMenuBar();
Jack Jansene44545f1997-05-07 15:48:54 +0000670#ifdef USE_MSL
671 /*
672 ** Temporary workaround: autocloseonquit clearing does not
673 ** currently work for the MSL/GUSI combo.
674 */
675 while(getchar() > 0);
676#endif
Jack Jansen1e8557a1995-11-10 14:51:26 +0000677 }
Jack Jansen0168f271995-10-27 13:32:30 +0000678 else
679 SIOUXSettings.autocloseonquit = 1;
Jack Jansenf6865f71996-09-04 15:24:59 +0000680#endif /* USE_SIOUX */
Jack Jansen0168f271995-10-27 13:32:30 +0000681
682 exit(status);
683}
Jack Jansen696c9581995-08-14 12:33:20 +0000684
Jack Jansendff77702001-09-05 22:07:52 +0000685#if !TARGET_API_MAC_OSX
Jack Jansen696c9581995-08-14 12:33:20 +0000686/* Make the *original* argc/argv available to other modules.
687 This is rare, but it is needed by the secureware extension. */
688
689void
Jack Jansen9ae898b2000-07-11 21:16:03 +0000690Py_GetArgcArgv(int *argc,char ***argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000691{
692 *argc = orig_argc;
693 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000694}
Jack Jansendff77702001-09-05 22:07:52 +0000695#endif
Jack Jansen1d2f8631996-08-02 15:16:16 +0000696
697/* More cruft that shouldn't really be here, used in sysmodule.c */
Jack Jansendff77702001-09-05 22:07:52 +0000698#if !TARGET_API_MAC_OSX
699/* Return the program name -- some code out there needs this. */
700char *
701Py_GetProgramFullPath(void)
702{
703 return orig_argv[0];
704}
Jack Jansen1d2f8631996-08-02 15:16:16 +0000705
706char *
Jack Jansendff77702001-09-05 22:07:52 +0000707Py_GetPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000708{
Jack Jansenac625691997-09-08 13:22:22 +0000709 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000710}
711
712char *
Jack Jansendff77702001-09-05 22:07:52 +0000713Py_GetExecPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000714{
Jack Jansenac625691997-09-08 13:22:22 +0000715 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000716}
Jack Jansen8a387142001-02-11 01:08:04 +0000717
718int
Jack Jansendff77702001-09-05 22:07:52 +0000719PyMac_GetDelayConsoleFlag(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000720{
721 return (int)PyMac_options.delayconsole;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000722}
723
724#ifndef WITHOUT_UNIX_NEWLINES
725/*
726** Experimental feature (for 2.2a2): optionally allow unix newlines
727** as well as Mac newlines on input. We replace a lowlevel
728** MSL routine to accomplish this.
729*/
730void
731__convert_to_newlines(unsigned char * buf, size_t * n_ptr)
732{
733 unsigned char *p;
734 size_t n = *n_ptr;
735
736 for(p=buf; n > 0; p++, n--)
737 if ( *p == '\r' ) *p = '\n';
738 else if ( *p == '\n' && !PyMac_options.unixnewlines )
739 *p = '\r';
740}
741#endif /* WITHOUT_UNIX_NEWLINES */
Jack Jansendff77702001-09-05 22:07:52 +0000742#endif /* !TARGET_API_MAC_OSX */
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000743