blob: a14e3a893b833cd94ed244b39220ad3f0d030741 [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 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
491int
492main(int argc, char **argv)
493{
494 int i;
495 printf("first argc=%d\n", argc);
496 for(i=0; i<argc; i++) printf("first argv[%d] = \"%s\"\n", i, argv[i]);
497 init_common(&argc, &argv, 0);
498 printf("second argc=%d\n", argc);
499 for(i=0; i<argc; i++) printf("second argv[%d] = \"%s\"\n", i, argv[i]);
500 Py_Main(argc, argv);
501 return 0;
502}
503
504#else
505
Jack Jansen696c9581995-08-14 12:33:20 +0000506/* For normal application */
507void
Jack Jansendff77702001-09-05 22:07:52 +0000508PyMac_InitApplication(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000509{
510 int argc;
511 char **argv;
512
Jack Jansen52ac0371997-01-15 15:49:08 +0000513 init_common(&argc, &argv, 0);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000514
Jack Jansen696c9581995-08-14 12:33:20 +0000515 if ( argc > 1 ) {
516 /* We're running a script. Attempt to change current directory */
517 char curwd[256], *endp;
518
519 strcpy(curwd, argv[1]);
520 endp = strrchr(curwd, ':');
521 if ( endp && endp > curwd ) {
522 *endp = '\0';
523
524 chdir(curwd);
Jack Jansen2d1306b2000-04-07 09:10:49 +0000525#ifdef USE_GUSI1
Jack Jansen378815c1996-03-06 16:21:34 +0000526 /* Change MacOS's idea of wd too */
527 PyMac_FixGUSIcd();
528#endif
Jack Jansen696c9581995-08-14 12:33:20 +0000529 }
Jack Jansencbed91b2001-08-03 13:31:36 +0000530 /* Check that the first argument is a text file */
531 if ( PyMac_getfiletype(argv[1]) != 'TEXT' ) {
532 Alert(NOTASCRIPT_ID, NULL);
533 exit(0);
534 }
Jack Jansen696c9581995-08-14 12:33:20 +0000535 }
536 Py_Main(argc, argv);
537}
Jack Jansendff77702001-09-05 22:07:52 +0000538#endif /* TARGET_API_MAC_OSX */
Jack Jansen696c9581995-08-14 12:33:20 +0000539
Jack Jansen696c9581995-08-14 12:33:20 +0000540/* Main program */
541
Jack Jansen76ceece1996-08-19 11:18:24 +0000542static void
Jack Jansendff77702001-09-05 22:07:52 +0000543Py_Main(int argc, char **argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000544{
Jack Jansen696c9581995-08-14 12:33:20 +0000545 int sts;
546 char *command = NULL;
547 char *filename = NULL;
548 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000549
Jack Jansen696c9581995-08-14 12:33:20 +0000550 filename = argv[1];
551
552 if (Py_VerboseFlag ||
Jack Jansendff77702001-09-05 22:07:52 +0000553 (command == NULL && filename == NULL && isatty((int)fileno(fp))))
Jack Jansen65c3ee02000-09-08 10:20:37 +0000554 fprintf(stderr, "Python %s on %s\n%s\n",
555 Py_GetVersion(), Py_GetPlatform(), COPYRIGHT);
Jack Jansen696c9581995-08-14 12:33:20 +0000556
557 if (filename != NULL) {
558 if ((fp = fopen(filename, "r")) == NULL) {
559 fprintf(stderr, "%s: can't open file '%s'\n",
560 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000561 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000562 }
563 }
564
Jack Jansendff77702001-09-05 22:07:52 +0000565#if !TARGET_API_MAC_OSX
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000566 /* We initialize the menubar here, hoping SIOUX is initialized by now */
Jack Jansen3469e991996-09-06 00:30:45 +0000567 PyMac_InitMenuBar();
Jack Jansendff77702001-09-05 22:07:52 +0000568#endif
569
Jack Jansen696c9581995-08-14 12:33:20 +0000570 Py_Initialize();
571
unknownd1054ef2001-07-04 22:37:19 +0000572 PyUnicode_SetDefaultEncoding(PyMac_getscript());
573
Jack Jansen0c6d0372000-05-05 23:11:14 +0000574 PyMac_InstallNavServicesForSF();
575
Jack Jansen696c9581995-08-14 12:33:20 +0000576 PySys_SetArgv(argc-1, argv+1);
577
578 if (filename == NULL && isatty((int)fileno(fp))) {
579 FILE *fp = fopen(STARTUP, "r");
580 if (fp != NULL) {
581 (void) PyRun_SimpleFile(fp, STARTUP);
582 PyErr_Clear();
583 fclose(fp);
584 }
585 }
586 sts = PyRun_AnyFile(
587 fp, filename == NULL ? "<stdin>" : filename) != 0;
588 if (filename != NULL)
589 fclose(fp);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000590
591 if ( filename != NULL || command != NULL )
592 sts = (run_inspect() || sts);
Jack Jansen696c9581995-08-14 12:33:20 +0000593
594 Py_Exit(sts);
595 /*NOTREACHED*/
596}
597
Jack Jansendff77702001-09-05 22:07:52 +0000598#if !TARGET_API_MAC_OSX
Jack Jansen0168f271995-10-27 13:32:30 +0000599/*
Jack Jansen8413b472000-10-19 22:02:16 +0000600** Reset the "unseen output" flag
601*/
602void
Jack Jansendff77702001-09-05 22:07:52 +0000603PyMac_OutputSeen(void)
Jack Jansen8413b472000-10-19 22:02:16 +0000604{
Jack Jansen657ba272001-02-17 22:02:07 +0000605 if ( console_output_state == STATE_UNKNOWN )
606 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000607 console_output_state = STATE_LASTREAD;
Jack Jansen8413b472000-10-19 22:02:16 +0000608}
609
610/*
Jack Jansen8a387142001-02-11 01:08:04 +0000611** Set the "unseen output" flag
612*/
613void
Jack Jansendff77702001-09-05 22:07:52 +0000614PyMac_OutputNotSeen(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000615{
Jack Jansen657ba272001-02-17 22:02:07 +0000616 if ( console_output_state == STATE_UNKNOWN )
617 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000618 console_output_state = STATE_LASTWRITE;
619}
Jack Jansen15f1c082001-04-25 22:07:27 +0000620
621/*
622** Override abort() - The default one is not what we want.
623*/
624void
Jack Jansendff77702001-09-05 22:07:52 +0000625abort(void)
Jack Jansen15f1c082001-04-25 22:07:27 +0000626{
627 console_output_state = STATE_LASTWRITE;
628 PyMac_Exit(1);
629}
Jack Jansendff77702001-09-05 22:07:52 +0000630#endif /* !TARGET_API_MAC_OSX */
Jack Jansen8a387142001-02-11 01:08:04 +0000631
632/*
Jack Jansen0168f271995-10-27 13:32:30 +0000633** Terminate application
634*/
Jack Jansen76ceece1996-08-19 11:18:24 +0000635void
Jack Jansendff77702001-09-05 22:07:52 +0000636PyMac_Exit(int status)
Jack Jansen0168f271995-10-27 13:32:30 +0000637{
Jack Jansendff77702001-09-05 22:07:52 +0000638#ifdef USE_SIOUX
Jack Jansen4a5eb962000-09-22 21:50:11 +0000639 int keep = 0;
Jack Jansendff77702001-09-05 22:07:52 +0000640#endif
Jack Jansen8c693211997-01-07 16:19:42 +0000641
642#if __profile__ == 1
643 ProfilerDump("\pPython Profiler Results");
644 ProfilerTerm();
645#endif
Jack Jansen0168f271995-10-27 13:32:30 +0000646
Jack Jansen1e8557a1995-11-10 14:51:26 +0000647#ifdef USE_SIOUX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000648 switch (PyMac_options.keep_console) {
Jack Jansen4a5eb962000-09-22 21:50:11 +0000649 case POPT_KEEPCONSOLE_NEVER:
650 keep = 0;
651 break;
652 case POPT_KEEPCONSOLE_OUTPUT:
Jack Jansen8a387142001-02-11 01:08:04 +0000653 if (console_output_state == STATE_LASTWRITE ||
654 console_output_state == STATE_UNKNOWN )
Jack Jansen4a5eb962000-09-22 21:50:11 +0000655 keep = 1;
656 else
657 keep = 0;
658 break;
659 case POPT_KEEPCONSOLE_ERROR:
660 keep = (status != 0);
661 break;
662 default:
663 keep = 1;
664 }
Jack Jansen1e8557a1995-11-10 14:51:26 +0000665 if (keep) {
666 SIOUXSettings.standalone = 1;
667 SIOUXSettings.autocloseonquit = 0;
Jack Jansen415571c1996-03-25 15:46:03 +0000668 SIOUXSetTitle("\p\307terminated\310");
Jack Jansen15f1c082001-04-25 22:07:27 +0000669 PyMac_RaiseConsoleWindow();
Jack Jansencaa7c461997-06-12 10:49:13 +0000670 PyMac_RestoreMenuBar();
Jack Jansene44545f1997-05-07 15:48:54 +0000671#ifdef USE_MSL
672 /*
673 ** Temporary workaround: autocloseonquit clearing does not
674 ** currently work for the MSL/GUSI combo.
675 */
676 while(getchar() > 0);
677#endif
Jack Jansen1e8557a1995-11-10 14:51:26 +0000678 }
Jack Jansen0168f271995-10-27 13:32:30 +0000679 else
680 SIOUXSettings.autocloseonquit = 1;
Jack Jansenf6865f71996-09-04 15:24:59 +0000681#endif /* USE_SIOUX */
Jack Jansen0168f271995-10-27 13:32:30 +0000682
683 exit(status);
684}
Jack Jansen696c9581995-08-14 12:33:20 +0000685
Jack Jansendff77702001-09-05 22:07:52 +0000686#if !TARGET_API_MAC_OSX
Jack Jansen696c9581995-08-14 12:33:20 +0000687/* Make the *original* argc/argv available to other modules.
688 This is rare, but it is needed by the secureware extension. */
689
690void
Jack Jansen9ae898b2000-07-11 21:16:03 +0000691Py_GetArgcArgv(int *argc,char ***argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000692{
693 *argc = orig_argc;
694 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000695}
Jack Jansendff77702001-09-05 22:07:52 +0000696#endif
Jack Jansen1d2f8631996-08-02 15:16:16 +0000697
698/* More cruft that shouldn't really be here, used in sysmodule.c */
Jack Jansendff77702001-09-05 22:07:52 +0000699#if !TARGET_API_MAC_OSX
700/* Return the program name -- some code out there needs this. */
701char *
702Py_GetProgramFullPath(void)
703{
704 return orig_argv[0];
705}
Jack Jansen1d2f8631996-08-02 15:16:16 +0000706
707char *
Jack Jansendff77702001-09-05 22:07:52 +0000708Py_GetPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000709{
Jack Jansenac625691997-09-08 13:22:22 +0000710 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000711}
712
713char *
Jack Jansendff77702001-09-05 22:07:52 +0000714Py_GetExecPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000715{
Jack Jansenac625691997-09-08 13:22:22 +0000716 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000717}
Jack Jansen8a387142001-02-11 01:08:04 +0000718
719int
Jack Jansendff77702001-09-05 22:07:52 +0000720PyMac_GetDelayConsoleFlag(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000721{
722 return (int)PyMac_options.delayconsole;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000723}
724
725#ifndef WITHOUT_UNIX_NEWLINES
726/*
727** Experimental feature (for 2.2a2): optionally allow unix newlines
728** as well as Mac newlines on input. We replace a lowlevel
729** MSL routine to accomplish this.
730*/
731void
732__convert_to_newlines(unsigned char * buf, size_t * n_ptr)
733{
734 unsigned char *p;
735 size_t n = *n_ptr;
736
737 for(p=buf; n > 0; p++, n--)
738 if ( *p == '\r' ) *p = '\n';
739 else if ( *p == '\n' && !PyMac_options.unixnewlines )
740 *p = '\r';
741}
742#endif /* WITHOUT_UNIX_NEWLINES */
Jack Jansendff77702001-09-05 22:07:52 +0000743#endif /* !TARGET_API_MAC_OSX */
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000744