blob: 8b38a2c8b30f83064b4cf62910d33b2da8bcb3d8 [file] [log] [blame]
Guido van Rossumb0f3c821994-08-23 13:34:25 +00001/***********************************************************
Jack Jansen42218ce1997-01-31 16:15:11 +00002Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
Guido van Rossum99546991995-01-08 14:33:34 +00003The Netherlands.
Guido van Rossumb0f3c821994-08-23 13:34:25 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Jack Jansen696c9581995-08-14 12:33:20 +000025/* Python interpreter main program */
Guido van Rossumb0f3c821994-08-23 13:34:25 +000026
Jack Jansen696c9581995-08-14 12:33:20 +000027#include "Python.h"
28#include "pythonresources.h"
29#include "import.h"
30#include "marshal.h"
Jack Jansenf6865f71996-09-04 15:24:59 +000031#include "macglue.h"
Guido van Rossumb0f3c821994-08-23 13:34:25 +000032
Jack Jansendff77702001-09-05 22:07:52 +000033#ifdef WITHOUT_FRAMEWORKS
Jack Jansen696c9581995-08-14 12:33:20 +000034#include <Memory.h>
35#include <Resources.h>
Guido van Rossumb0f3c821994-08-23 13:34:25 +000036#include <stdio.h>
Jack Jansen696c9581995-08-14 12:33:20 +000037#include <Events.h>
38#include <Windows.h>
Jack Jansen2429c721996-03-07 15:17:11 +000039#include <Fonts.h>
Jack Jansen36b983c1997-09-09 13:53:21 +000040#include <Balloons.h>
Jack Jansen5ded1bf2001-10-30 22:48:36 +000041#if TARGET_API_MAC_CARBON
42#include <CFBundle.h>
43#include <CFURL.h>
44#include <CFString.h>
45#include <CFBase.h>
46#include <CFArray.h>
47#endif /* TARGET_API_MAC_CARBON */
Jack Jansen8f5725a1999-12-07 23:08:10 +000048#include <Gestalt.h>
49#include <Appearance.h>
Jack Jansendff77702001-09-05 22:07:52 +000050#else
51#include <Carbon/Carbon.h>
52#endif /* WITHOUT_FRAMEWORKS */
53
Jack Jansenc76fd391995-02-02 14:27:31 +000054#ifdef __MWERKS__
55#include <SIOUX.h>
Jack Jansen1e8557a1995-11-10 14:51:26 +000056#define USE_SIOUX
Jack Jansen9ae898b2000-07-11 21:16:03 +000057extern int ccommand(char ***);
Jack Jansen8c693211997-01-07 16:19:42 +000058#if __profile__ == 1
59#include <profiler.h>
Jack Jansendff77702001-09-05 22:07:52 +000060#endif /* __profile__ */
61#endif /* __MWERKS__ */
62
Jack Jansenee6eeb12000-06-02 21:28:52 +000063#include <unistd.h>
Jack Jansen5bdbabd2000-07-24 19:52:52 +000064#ifdef USE_MAC_SHARED_LIBRARY
65extern PyMac_AddLibResources(void);
66#endif
Jack Jansenc76fd391995-02-02 14:27:31 +000067
Jack Jansen696c9581995-08-14 12:33:20 +000068#define STARTUP "PythonStartup"
Jack Jansenbac428d1994-12-14 13:47:30 +000069
Jack Jansen65c3ee02000-09-08 10:20:37 +000070#define COPYRIGHT \
71 "Type \"copyright\", \"credits\" or \"license\" for more information."
72
Jack Jansen3f7d2b41996-09-06 22:21:07 +000073short PyMac_AppRefNum; /* RefNum of application resource fork */
Jack Jansen696c9581995-08-14 12:33:20 +000074
Jack Jansen1d2f8631996-08-02 15:16:16 +000075/* For Py_GetArgcArgv(); set by main() */
Jack Jansen696c9581995-08-14 12:33:20 +000076static char **orig_argv;
77static int orig_argc;
78
Jack Jansen8a387142001-02-11 01:08:04 +000079/* A flag which remembers whether the user has acknowledged all the console
80** output (by typing something)
81*/
82#define STATE_UNKNOWN 0
83#define STATE_LASTREAD 1
84#define STATE_LASTWRITE 2
85int console_output_state = STATE_UNKNOWN;
86
Jack Jansendc86f9e2000-10-12 21:23:19 +000087PyMac_PrefRecord PyMac_options;
Jack Jansen0168f271995-10-27 13:32:30 +000088
Jack Jansen998a40a2001-09-11 13:08:10 +000089static void Py_Main(int, char **, char *); /* Forward */
Jack Jansend88296d2000-07-11 19:51:05 +000090void PyMac_Exit(int); /* Forward */
Jack Jansen76ceece1996-08-19 11:18:24 +000091
Jack Jansen01fbc681996-02-28 15:42:47 +000092/* Initialize the Mac toolbox world */
93
94static void
Jack Jansendff77702001-09-05 22:07:52 +000095init_mac_world(void)
Jack Jansen01fbc681996-02-28 15:42:47 +000096{
Jack Jansen74a1e632000-07-14 22:37:27 +000097#if !TARGET_API_MAC_CARBON
Jack Jansenee6eeb12000-06-02 21:28:52 +000098 /* These aren't needed for carbon */
Jack Jansen01fbc681996-02-28 15:42:47 +000099 MaxApplZone();
100 InitGraf(&qd.thePort);
101 InitFonts();
102 InitWindows();
103 TEInit();
104 InitDialogs((long)0);
105 InitMenus();
Jack Jansenee6eeb12000-06-02 21:28:52 +0000106#endif
Jack Jansen01fbc681996-02-28 15:42:47 +0000107 InitCursor();
Jack Jansen01fbc681996-02-28 15:42:47 +0000108}
109
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000110/*
111** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
112*/
Jack Jansen01fbc681996-02-28 15:42:47 +0000113static void
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000114PyMac_InteractiveOptions(PyMac_PrefRecord *p, int *argcp, char ***argvp)
115{
116 KeyMap rmap;
117 unsigned char *map;
118 short item, type;
119 ControlHandle handle;
120 DialogPtr dialog;
121 Rect rect;
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000122
123 /*
124 ** If the preferences disallows interactive options we return,
125 ** similarly of <option> isn't pressed.
126 */
127 if (p->nointopt) return;
128
129 GetKeys(rmap);
130 map = (unsigned char *)rmap;
131 if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
132 return;
133
134 dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
135 if ( dialog == NULL ) {
136 printf("Option dialog not found - cannot set options\n");
137 return;
138 }
139 SetDialogDefaultItem(dialog, OPT_OK);
140 SetDialogCancelItem(dialog, OPT_CANCEL);
141
142 /* Set default values */
143#define SET_OPT_ITEM(num, var) \
144 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
Jack Jansen08c3be31997-04-08 15:27:00 +0000145 SetControlValue(handle, (short)p->var);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000146
147 SET_OPT_ITEM(OPT_INSPECT, inspect);
148 SET_OPT_ITEM(OPT_VERBOSE, verbose);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000149 /* OPT_VERBOSEVERBOSE is default off */
Jack Jansen36b983c1997-09-09 13:53:21 +0000150 SET_OPT_ITEM(OPT_OPTIMIZE, optimize);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000151 SET_OPT_ITEM(OPT_UNBUFFERED, unbuffered);
152 SET_OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen4a5eb962000-09-22 21:50:11 +0000153 GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
154 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
155 GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
156 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
157 GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
158 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
159 GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
160 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
161/* SET_OPT_ITEM(OPT_KEEPCONSOLE, keep_console); */
Jack Jansen0c6d0372000-05-05 23:11:14 +0000162 SET_OPT_ITEM(OPT_TABWARN, tabwarn);
Jack Jansen36b983c1997-09-09 13:53:21 +0000163 SET_OPT_ITEM(OPT_NOSITE, nosite);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000164 SET_OPT_ITEM(OPT_DIVISIONWARN, divisionwarn);
165 SET_OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000166 /* The rest are not settable interactively */
167
168#undef SET_OPT_ITEM
169
170 while (1) {
171 handle = NULL;
172 ModalDialog(NULL, &item);
173 if ( item == OPT_OK )
174 break;
175 if ( item == OPT_CANCEL ) {
Jack Jansen08c3be31997-04-08 15:27:00 +0000176 DisposeDialog(dialog);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000177 exit(0);
178 }
Jack Jansen74a1e632000-07-14 22:37:27 +0000179#if !TARGET_API_MAC_CARBON
Jack Jansen36b983c1997-09-09 13:53:21 +0000180 if ( item == OPT_HELP ) {
181 HMSetBalloons(!HMGetBalloons());
182 }
Jack Jansenee6eeb12000-06-02 21:28:52 +0000183#endif
Jack Jansendff77702001-09-05 22:07:52 +0000184#if !TARGET_API_MAC_OSX
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000185 if ( item == OPT_CMDLINE ) {
Jack Jansendff77702001-09-05 22:07:52 +0000186 int old_argc = *argcp;
187 int i;
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000188 int new_argc, newer_argc;
189 char **new_argv, **newer_argv;
190
191 new_argc = ccommand(&new_argv);
192 newer_argc = (new_argc-1) + old_argc;
193 newer_argv = malloc((newer_argc+1)*sizeof(char *));
194 if( !newer_argv )
195 Py_FatalError("Cannot malloc argv\n");
196 for(i=0; i<old_argc; i++)
197 newer_argv[i] = (*argvp)[i];
198 for(i=old_argc; i<=newer_argc; i++) /* Copy the NULL too */
199 newer_argv[i] = new_argv[i-old_argc+1];
200 *argvp = newer_argv;
201 *argcp = newer_argc;
202
203 /* XXXX Is it not safe to use free() here, apparently */
204 }
Jack Jansendff77702001-09-05 22:07:52 +0000205#endif /* !TARGET_API_MAC_OSX */
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000206#define OPT_ITEM(num, var) \
207 if ( item == (num) ) { \
208 p->var = !p->var; \
209 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
Jack Jansen08c3be31997-04-08 15:27:00 +0000210 SetControlValue(handle, (short)p->var); \
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000211 }
212
213 OPT_ITEM(OPT_INSPECT, inspect);
214 OPT_ITEM(OPT_VERBOSE, verbose);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000215 if ( item == OPT_VERBOSEVERBOSE ) {
216 if ( p->verbose == 2 )
217 p->verbose = 1;
218 else
219 p->verbose = 2;
220 GetDialogItem(dialog, OPT_VERBOSE, &type, (Handle *)&handle, &rect);
221 SetControlValue(handle, 1);
222 }
223 GetDialogItem(dialog, OPT_VERBOSEVERBOSE, &type, (Handle *)&handle, &rect);
224 SetControlValue(handle, p->verbose == 2);
Jack Jansen36b983c1997-09-09 13:53:21 +0000225 OPT_ITEM(OPT_OPTIMIZE, optimize);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000226 OPT_ITEM(OPT_UNBUFFERED, unbuffered);
227 OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen4a5eb962000-09-22 21:50:11 +0000228 if ( item == OPT_KEEPALWAYS ) p->keep_console = POPT_KEEPCONSOLE_ALWAYS;
229 if ( item == OPT_KEEPOUTPUT ) p->keep_console = POPT_KEEPCONSOLE_OUTPUT;
230 if ( item == OPT_KEEPERROR ) p->keep_console = POPT_KEEPCONSOLE_ERROR;
231 if ( item == OPT_KEEPNEVER ) p->keep_console = POPT_KEEPCONSOLE_NEVER;
232 GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
233 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
234 GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
235 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
236 GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
237 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
238 GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
239 SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
Jack Jansen0c6d0372000-05-05 23:11:14 +0000240 OPT_ITEM(OPT_TABWARN, tabwarn);
Jack Jansen36b983c1997-09-09 13:53:21 +0000241 OPT_ITEM(OPT_NOSITE, nosite);
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000242 OPT_ITEM(OPT_DIVISIONWARN, divisionwarn);
243 OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000244
245#undef OPT_ITEM
246 }
Jack Jansen08c3be31997-04-08 15:27:00 +0000247 DisposeDialog(dialog);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000248}
249
250/*
251** Initialization code, shared by interpreter and applets
252*/
253static void
Jack Jansen52ac0371997-01-15 15:49:08 +0000254init_common(int *argcp, char ***argvp, int embedded)
Jack Jansen01fbc681996-02-28 15:42:47 +0000255{
Jack Jansen3f7d2b41996-09-06 22:21:07 +0000256 /* Remember resource fork refnum, for later */
257 PyMac_AppRefNum = CurResFile();
258
Jack Jansen01fbc681996-02-28 15:42:47 +0000259 /* Initialize toolboxes */
260 init_mac_world();
261
262#ifdef USE_MAC_SHARED_LIBRARY
263 /* Add the shared library to the stack of resource files */
Jack Jansen87c485c1998-07-31 09:38:01 +0000264 (void)PyMac_init_process_location();
Jack Jansen01fbc681996-02-28 15:42:47 +0000265 PyMac_AddLibResources();
266#endif
267
Jack Jansen2d1306b2000-04-07 09:10:49 +0000268#if defined(USE_GUSI)
269 atexit(PyMac_StopGUSISpin);
270#endif
Jack Jansen01fbc681996-02-28 15:42:47 +0000271
272#ifdef USE_SIOUX
273 /* Set various SIOUX flags. Some are changed later based on options */
274 SIOUXSettings.asktosaveonclose = 0;
275 SIOUXSettings.showstatusline = 0;
276 SIOUXSettings.tabspaces = 4;
277#endif
278
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000279 /* Get options from preference file (or from applet resource fork) */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000280 PyMac_options.keep_console = POPT_KEEPCONSOLE_OUTPUT; /* default-default */
Jack Jansendff77702001-09-05 22:07:52 +0000281 PyMac_options.unixnewlines = 1;
282#if !TARGET_API_MAC_OSX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000283 PyMac_PreferenceOptions(&PyMac_options);
Jack Jansendff77702001-09-05 22:07:52 +0000284#endif
285
Jack Jansen52ac0371997-01-15 15:49:08 +0000286 if ( embedded ) {
287 static char *emb_argv[] = {"embedded-python", 0};
288
289 *argcp = 1;
290 *argvp = emb_argv;
291 } else {
Jack Jansen4b517852002-01-02 22:53:38 +0000292 /* Create argc/argv. Do it before we go into the options event loop.
293 ** In MachoPython we skip this step if we already have plausible
294 ** command line arguments.
295 */
296#if TARGET_API_MAC_OSX
297 if (*argcp == 2 && strncmp((*argvp)[1], "-psn_", 5) == 0)
298#endif
299 *argcp = PyMac_GetArgv(argvp, PyMac_options.noargs);
Jack Jansendff77702001-09-05 22:07:52 +0000300#if !TARGET_API_MAC_OSX
Jack Jansenc00df0b2001-01-16 15:54:58 +0000301#ifndef NO_ARGV0_CHDIR
Jack Jansen660bb1d2000-07-18 09:40:39 +0000302 if (*argcp >= 1 && (*argvp)[0] && (*argvp)[0][0]) {
303 /* Workaround for MacOS X, which currently (DP4) doesn't set
304 ** the working folder correctly
305 */
306 char app_wd[256], *p;
307
308 strncpy(app_wd, (*argvp)[0], 256);
Jack Jansen660bb1d2000-07-18 09:40:39 +0000309 p = strrchr(app_wd, ':');
310 if ( p ) *p = 0;
Jack Jansen660bb1d2000-07-18 09:40:39 +0000311 chdir(app_wd);
312 }
313#endif
Jack Jansendff77702001-09-05 22:07:52 +0000314#endif
Jack Jansen52ac0371997-01-15 15:49:08 +0000315 /* Do interactive option setting, if allowed and <option> depressed */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000316 PyMac_InteractiveOptions(&PyMac_options, argcp, argvp);
Jack Jansen52ac0371997-01-15 15:49:08 +0000317 }
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000318
319 /* Copy selected options to where the machine-independent stuff wants it */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000320 Py_VerboseFlag = PyMac_options.verbose;
321/* Py_SuppressPrintingFlag = PyMac_options.suppress_print; */
322 Py_OptimizeFlag = PyMac_options.optimize;
323 Py_DebugFlag = PyMac_options.debugging;
324 Py_NoSiteFlag = PyMac_options.nosite;
325 Py_TabcheckFlag = PyMac_options.tabwarn;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000326 Py_DivisionWarningFlag = PyMac_options.divisionwarn;
Jack Jansendff77702001-09-05 22:07:52 +0000327#if !TARGET_API_MAC_OSX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000328 if ( PyMac_options.noargs ) {
Jack Jansene3ae0df1997-06-03 15:28:29 +0000329 /* don't process events at all without the scripts permission */
330 PyMacSchedParams scp;
331
332 PyMac_GetSchedParams(&scp);
333 scp.process_events = 0;
334 /* Should we disable command-dot as well? */
335 PyMac_SetSchedParams(&scp);
336 }
Jack Jansendff77702001-09-05 22:07:52 +0000337#endif /* !TARGET_API_MAC_OSX */
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000338
339 /* Set buffering */
Jack Jansendc86f9e2000-10-12 21:23:19 +0000340 if (PyMac_options.unbuffered) {
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000341#ifndef MPW
342 setbuf(stdout, (char *)NULL);
343 setbuf(stderr, (char *)NULL);
344#else
345 /* On MPW (3.2) unbuffered seems to hang */
346 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
347 setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
348#endif
349 }
Jack Jansen8c693211997-01-07 16:19:42 +0000350#if __profile__ == 1
351 /* collectSummary or collectDetailed, timebase, #routines, max stack depth */
Jack Jansene7424871999-09-30 11:20:11 +0000352 ProfilerInit(collectSummary, bestTimeBase, 8000, 250);
Jack Jansen8c693211997-01-07 16:19:42 +0000353#endif
Jack Jansen7330b391997-08-08 14:56:41 +0000354
355 /* Tell the rest of python about our argc/argv */
356 orig_argc = *argcp; /* For Py_GetArgcArgv() */
357 orig_argv = *argvp;
358 Py_SetProgramName((*argvp)[0]);
Jack Jansen01fbc681996-02-28 15:42:47 +0000359}
360
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000361/*
362** Inspection mode after script/applet termination
363*/
364static int
Jack Jansendff77702001-09-05 22:07:52 +0000365run_inspect(void)
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000366{
367 int sts = 0;
368
Jack Jansendc86f9e2000-10-12 21:23:19 +0000369 if (PyMac_options.inspect && isatty((int)fileno(stdin)))
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000370 sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
371 return sts;
372}
Jack Jansen6438e1d2001-09-11 11:29:31 +0000373
Jack Jansen696c9581995-08-14 12:33:20 +0000374#ifdef USE_MAC_APPLET_SUPPORT
375/* Applet support */
376
377/* Run a compiled Python Python script from 'PYC ' resource __main__ */
378static int
Jack Jansendff77702001-09-05 22:07:52 +0000379run_main_resource(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000380{
381 Handle h;
382 long size;
383 PyObject *code;
384 PyObject *result;
385
386 h = GetNamedResource('PYC ', "\p__main__");
387 if (h == NULL) {
388 Alert(NOPYC_ALERT, NULL);
389 return 1;
390 }
391 size = GetResourceSizeOnDisk(h);
392 HLock(h);
393 code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
394 HUnlock(h);
395 ReleaseResource(h);
396 if (code == NULL) {
397 PyErr_Print();
398 return 1;
399 }
400 result = PyImport_ExecCodeModule("__main__", code);
401 Py_DECREF(code);
402 if (result == NULL) {
403 PyErr_Print();
404 return 1;
405 }
406 Py_DECREF(result);
407 return 0;
408}
409
410/* Initialization sequence for applets */
411void
Jack Jansendff77702001-09-05 22:07:52 +0000412PyMac_InitApplet(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000413{
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000414 int argc;
415 char **argv;
Jack Jansen696c9581995-08-14 12:33:20 +0000416 int err;
417
Jack Jansen52ac0371997-01-15 15:49:08 +0000418 init_common(&argc, &argv, 0);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000419
Jack Jansen696c9581995-08-14 12:33:20 +0000420 Py_Initialize();
421 PySys_SetArgv(argc, argv);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000422
Jack Jansen696c9581995-08-14 12:33:20 +0000423 err = run_main_resource();
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000424
425 err = (run_inspect() || err);
426
Jack Jansen696c9581995-08-14 12:33:20 +0000427 fflush(stderr);
428 fflush(stdout);
Jack Jansen0168f271995-10-27 13:32:30 +0000429 PyMac_Exit(err);
Jack Jansen696c9581995-08-14 12:33:20 +0000430 /* XXX Should we bother to Py_Exit(sts)? */
431}
432
Jack Jansen52ac0371997-01-15 15:49:08 +0000433/*
434** Hook for embedding python.
435*/
436void
Jack Jansendff77702001-09-05 22:07:52 +0000437PyMac_Initialize(void)
Jack Jansen52ac0371997-01-15 15:49:08 +0000438{
439 int argc;
440 char **argv;
441
442 init_common(&argc, &argv, 1);
443 Py_Initialize();
444 PySys_SetArgv(argc, argv);
445}
446
Jack Jansen696c9581995-08-14 12:33:20 +0000447#endif /* USE_MAC_APPLET_SUPPORT */
448
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000449#if TARGET_API_MAC_OSX /* Really: TARGET_API_MAC_CARBON */
Jack Jansen998a40a2001-09-11 13:08:10 +0000450
451static int
Jack Jansen3cef7212002-03-29 14:43:50 +0000452locateResourcePy(CFStringRef resourceType, char *resourceName, char *resourceURLCStr, int length)
453{
Jack Jansen998a40a2001-09-11 13:08:10 +0000454 CFBundleRef mainBundle = NULL;
455 CFURLRef URL, absoluteURL;
456 CFStringRef filenameString, filepathString, rsrcString;
457 CFIndex size, i;
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000458 CFArrayRef arrayRef = NULL;
459 int success = 0;
460
461#if TARGET_API_MAC_OSX
462 CFURLPathStyle thePathStyle = kCFURLPOSIXPathStyle;
463#else
464 CFURLPathStyle thePathStyle = kCFURLHFSPathStyle;
465#endif
Jack Jansen998a40a2001-09-11 13:08:10 +0000466
467 /* Get a reference to our main bundle */
468 mainBundle = CFBundleGetMainBundle();
469
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000470 /* If we are running inside a bundle, look through it. Otherwise, do nothing. */
471 if (mainBundle) {
472 /* Create a CFString with the resource name in it */
473 rsrcString = CFStringCreateWithCString(0, resourceName, kCFStringEncodingMacRoman);
Jack Jansen998a40a2001-09-11 13:08:10 +0000474
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000475 /* Look for py files in the main bundle by type */
476 arrayRef = CFBundleCopyResourceURLsOfType( mainBundle,
Jack Jansen3cef7212002-03-29 14:43:50 +0000477 resourceType,
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000478 NULL );
Jack Jansen998a40a2001-09-11 13:08:10 +0000479
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000480 /* See if there are any filename matches */
481 size = CFArrayGetCount(arrayRef);
482 for (i = 0; i < size; i++) {
483 URL = CFArrayGetValueAtIndex(arrayRef, i);
484 filenameString = CFURLCopyLastPathComponent(URL);
485 if (CFStringCompare(filenameString, rsrcString, 0) == kCFCompareEqualTo) {
486 /* We found a match, get the file's full path */
487 absoluteURL = CFURLCopyAbsoluteURL(URL);
488 filepathString = CFURLCopyFileSystemPath(absoluteURL, thePathStyle);
489 CFRelease(absoluteURL);
Jack Jansen998a40a2001-09-11 13:08:10 +0000490
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000491 /* Copy the full path into the caller's character buffer */
492 success = CFStringGetCString(filepathString, resourceURLCStr, length,
493 kCFStringEncodingMacRoman);
Jack Jansen998a40a2001-09-11 13:08:10 +0000494
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000495 CFRelease(filepathString);
496 }
497 CFRelease(filenameString);
498 }
499 CFRelease(arrayRef);
500 CFRelease(rsrcString);
501 }
Jack Jansen998a40a2001-09-11 13:08:10 +0000502 return success;
503}
504
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000505#endif /* TARGET_API_MAC_CARBON */
506
507#if TARGET_API_MAC_OSX
508
Jack Jansendff77702001-09-05 22:07:52 +0000509int
510main(int argc, char **argv)
511{
Jack Jansen998a40a2001-09-11 13:08:10 +0000512 static char scriptpath[1024];
513 char *script = NULL;
514
515 /* First we see whether we have __rawmain__.py and run that if it
516 ** is there
517 */
Jack Jansen3cef7212002-03-29 14:43:50 +0000518 if (locateResourcePy(CFSTR("py"), "__rawmain__.py", scriptpath, 1024)) {
Jack Jansen998a40a2001-09-11 13:08:10 +0000519 /* If we have a raw main we don't do AppleEvent processing.
520 ** Notice that this also means we keep the -psn.... argv[1]
521 ** value intact. Not sure whether that is important to someone,
522 ** but you never know...
523 */
524 script = scriptpath;
Jack Jansen3cef7212002-03-29 14:43:50 +0000525 } else if (locateResourcePy(CFSTR("pyc"), "__rawmain__.pyc", scriptpath, 1024)) {
526 script = scriptpath;
Jack Jansen998a40a2001-09-11 13:08:10 +0000527 } else {
528 /* Otherwise we look for __main__.py. Whether that is
529 ** found or not we also process AppleEvent arguments.
530 */
Jack Jansen3cef7212002-03-29 14:43:50 +0000531 if (locateResourcePy(CFSTR("py"), "__main__.py", scriptpath, 1024))
532 script = scriptpath;
533 else if (locateResourcePy(CFSTR("pyc"), "__main__.pyc", scriptpath, 1024))
Jack Jansen998a40a2001-09-11 13:08:10 +0000534 script = scriptpath;
535
Jack Jansen998a40a2001-09-11 13:08:10 +0000536 init_common(&argc, &argv, 0);
537
Jack Jansen998a40a2001-09-11 13:08:10 +0000538 }
539
540 Py_Main(argc, argv, script);
541 return 0;
Jack Jansendff77702001-09-05 22:07:52 +0000542}
543
544#else
545
Jack Jansen696c9581995-08-14 12:33:20 +0000546/* For normal application */
547void
Jack Jansendff77702001-09-05 22:07:52 +0000548PyMac_InitApplication(void)
Jack Jansen696c9581995-08-14 12:33:20 +0000549{
550 int argc;
551 char **argv;
552
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000553 static char scriptpath[1024];
554 char *script = NULL;
555
Jack Jansen52ac0371997-01-15 15:49:08 +0000556 init_common(&argc, &argv, 0);
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000557
558#if TARGET_API_MAC_OSX /* Really: TARGET_API_MAC_CARBON */
559 /* If we are running inside of a bundle, and a __main__.py is available, use it */
560 if (locateResourcePy("__main__.py", scriptpath, 1024))
561 script = scriptpath;
562#endif
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000563
Jack Jansen696c9581995-08-14 12:33:20 +0000564 if ( argc > 1 ) {
565 /* We're running a script. Attempt to change current directory */
566 char curwd[256], *endp;
567
568 strcpy(curwd, argv[1]);
569 endp = strrchr(curwd, ':');
570 if ( endp && endp > curwd ) {
571 *endp = '\0';
572
573 chdir(curwd);
574 }
Jack Jansencbed91b2001-08-03 13:31:36 +0000575 /* Check that the first argument is a text file */
576 if ( PyMac_getfiletype(argv[1]) != 'TEXT' ) {
577 Alert(NOTASCRIPT_ID, NULL);
578 exit(0);
579 }
Jack Jansen696c9581995-08-14 12:33:20 +0000580 }
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000581 Py_Main(argc, argv, script);
Jack Jansen696c9581995-08-14 12:33:20 +0000582}
Jack Jansendff77702001-09-05 22:07:52 +0000583#endif /* TARGET_API_MAC_OSX */
Jack Jansen696c9581995-08-14 12:33:20 +0000584
Jack Jansen696c9581995-08-14 12:33:20 +0000585/* Main program */
586
Jack Jansen76ceece1996-08-19 11:18:24 +0000587static void
Jack Jansen998a40a2001-09-11 13:08:10 +0000588Py_Main(int argc, char **argv, char *filename)
Jack Jansen696c9581995-08-14 12:33:20 +0000589{
Jack Jansen696c9581995-08-14 12:33:20 +0000590 int sts;
591 char *command = NULL;
Jack Jansen696c9581995-08-14 12:33:20 +0000592 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000593
Jack Jansen998a40a2001-09-11 13:08:10 +0000594 if ( filename ) {
595 /* Someone else has found our "script" already */
596 argv[0] = filename;
597 } else {
598 filename = argv[1];
599 argv++;
600 argc--;
601 }
Jack Jansen696c9581995-08-14 12:33:20 +0000602
603 if (Py_VerboseFlag ||
Jack Jansendff77702001-09-05 22:07:52 +0000604 (command == NULL && filename == NULL && isatty((int)fileno(fp))))
Jack Jansen0035fb22002-03-29 14:27:06 +0000605 fprintf(stderr, "%s %s on %s\n%s\n",
606#if !TARGET_API_MAC_OSX
607 "Python",
608#else
609 "Pythonw",
610#endif
Jack Jansen65c3ee02000-09-08 10:20:37 +0000611 Py_GetVersion(), Py_GetPlatform(), COPYRIGHT);
Jack Jansen696c9581995-08-14 12:33:20 +0000612
613 if (filename != NULL) {
614 if ((fp = fopen(filename, "r")) == NULL) {
615 fprintf(stderr, "%s: can't open file '%s'\n",
616 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000617 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000618 }
619 }
620
Jack Jansendff77702001-09-05 22:07:52 +0000621#if !TARGET_API_MAC_OSX
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000622 /* We initialize the menubar here, hoping SIOUX is initialized by now */
Jack Jansen3469e991996-09-06 00:30:45 +0000623 PyMac_InitMenuBar();
Jack Jansendff77702001-09-05 22:07:52 +0000624#endif
625
Jack Jansen696c9581995-08-14 12:33:20 +0000626 Py_Initialize();
627
unknownd1054ef2001-07-04 22:37:19 +0000628 PyUnicode_SetDefaultEncoding(PyMac_getscript());
629
Jack Jansen998a40a2001-09-11 13:08:10 +0000630 PySys_SetArgv(argc, argv);
Jack Jansen696c9581995-08-14 12:33:20 +0000631
632 if (filename == NULL && isatty((int)fileno(fp))) {
633 FILE *fp = fopen(STARTUP, "r");
634 if (fp != NULL) {
635 (void) PyRun_SimpleFile(fp, STARTUP);
636 PyErr_Clear();
637 fclose(fp);
638 }
639 }
640 sts = PyRun_AnyFile(
641 fp, filename == NULL ? "<stdin>" : filename) != 0;
642 if (filename != NULL)
643 fclose(fp);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000644
645 if ( filename != NULL || command != NULL )
646 sts = (run_inspect() || sts);
Jack Jansen696c9581995-08-14 12:33:20 +0000647
648 Py_Exit(sts);
649 /*NOTREACHED*/
650}
651
Jack Jansendff77702001-09-05 22:07:52 +0000652#if !TARGET_API_MAC_OSX
Jack Jansen0168f271995-10-27 13:32:30 +0000653/*
Jack Jansen8413b472000-10-19 22:02:16 +0000654** Reset the "unseen output" flag
655*/
656void
Jack Jansendff77702001-09-05 22:07:52 +0000657PyMac_OutputSeen(void)
Jack Jansen8413b472000-10-19 22:02:16 +0000658{
Jack Jansen657ba272001-02-17 22:02:07 +0000659 if ( console_output_state == STATE_UNKNOWN )
660 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000661 console_output_state = STATE_LASTREAD;
Jack Jansen8413b472000-10-19 22:02:16 +0000662}
663
664/*
Jack Jansen8a387142001-02-11 01:08:04 +0000665** Set the "unseen output" flag
666*/
667void
Jack Jansendff77702001-09-05 22:07:52 +0000668PyMac_OutputNotSeen(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000669{
Jack Jansen657ba272001-02-17 22:02:07 +0000670 if ( console_output_state == STATE_UNKNOWN )
671 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000672 console_output_state = STATE_LASTWRITE;
673}
Jack Jansen15f1c082001-04-25 22:07:27 +0000674
675/*
676** Override abort() - The default one is not what we want.
677*/
678void
Jack Jansendff77702001-09-05 22:07:52 +0000679abort(void)
Jack Jansen15f1c082001-04-25 22:07:27 +0000680{
681 console_output_state = STATE_LASTWRITE;
682 PyMac_Exit(1);
683}
Jack Jansendff77702001-09-05 22:07:52 +0000684#endif /* !TARGET_API_MAC_OSX */
Jack Jansen8a387142001-02-11 01:08:04 +0000685
686/*
Jack Jansen0168f271995-10-27 13:32:30 +0000687** Terminate application
688*/
Jack Jansen76ceece1996-08-19 11:18:24 +0000689void
Jack Jansendff77702001-09-05 22:07:52 +0000690PyMac_Exit(int status)
Jack Jansen0168f271995-10-27 13:32:30 +0000691{
Jack Jansendff77702001-09-05 22:07:52 +0000692#ifdef USE_SIOUX
Jack Jansen4a5eb962000-09-22 21:50:11 +0000693 int keep = 0;
Jack Jansendff77702001-09-05 22:07:52 +0000694#endif
Jack Jansen8c693211997-01-07 16:19:42 +0000695
696#if __profile__ == 1
697 ProfilerDump("\pPython Profiler Results");
698 ProfilerTerm();
699#endif
Jack Jansen0168f271995-10-27 13:32:30 +0000700
Jack Jansen1e8557a1995-11-10 14:51:26 +0000701#ifdef USE_SIOUX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000702 switch (PyMac_options.keep_console) {
Jack Jansen4a5eb962000-09-22 21:50:11 +0000703 case POPT_KEEPCONSOLE_NEVER:
704 keep = 0;
705 break;
706 case POPT_KEEPCONSOLE_OUTPUT:
Jack Jansen8a387142001-02-11 01:08:04 +0000707 if (console_output_state == STATE_LASTWRITE ||
708 console_output_state == STATE_UNKNOWN )
Jack Jansen4a5eb962000-09-22 21:50:11 +0000709 keep = 1;
710 else
711 keep = 0;
712 break;
713 case POPT_KEEPCONSOLE_ERROR:
714 keep = (status != 0);
715 break;
716 default:
717 keep = 1;
718 }
Jack Jansen1e8557a1995-11-10 14:51:26 +0000719 if (keep) {
720 SIOUXSettings.standalone = 1;
721 SIOUXSettings.autocloseonquit = 0;
Jack Jansen415571c1996-03-25 15:46:03 +0000722 SIOUXSetTitle("\p\307terminated\310");
Jack Jansen15f1c082001-04-25 22:07:27 +0000723 PyMac_RaiseConsoleWindow();
Jack Jansencaa7c461997-06-12 10:49:13 +0000724 PyMac_RestoreMenuBar();
Jack Jansene44545f1997-05-07 15:48:54 +0000725#ifdef USE_MSL
726 /*
727 ** Temporary workaround: autocloseonquit clearing does not
728 ** currently work for the MSL/GUSI combo.
729 */
730 while(getchar() > 0);
731#endif
Jack Jansen1e8557a1995-11-10 14:51:26 +0000732 }
Jack Jansen0168f271995-10-27 13:32:30 +0000733 else
734 SIOUXSettings.autocloseonquit = 1;
Jack Jansenf6865f71996-09-04 15:24:59 +0000735#endif /* USE_SIOUX */
Jack Jansen0168f271995-10-27 13:32:30 +0000736
737 exit(status);
738}
Jack Jansen696c9581995-08-14 12:33:20 +0000739
Jack Jansendff77702001-09-05 22:07:52 +0000740#if !TARGET_API_MAC_OSX
Jack Jansen696c9581995-08-14 12:33:20 +0000741/* Make the *original* argc/argv available to other modules.
742 This is rare, but it is needed by the secureware extension. */
743
744void
Jack Jansen9ae898b2000-07-11 21:16:03 +0000745Py_GetArgcArgv(int *argc,char ***argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000746{
747 *argc = orig_argc;
748 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000749}
Jack Jansendff77702001-09-05 22:07:52 +0000750#endif
Jack Jansen1d2f8631996-08-02 15:16:16 +0000751
752/* More cruft that shouldn't really be here, used in sysmodule.c */
Jack Jansendff77702001-09-05 22:07:52 +0000753#if !TARGET_API_MAC_OSX
754/* Return the program name -- some code out there needs this. */
755char *
756Py_GetProgramFullPath(void)
757{
758 return orig_argv[0];
759}
Jack Jansen1d2f8631996-08-02 15:16:16 +0000760
761char *
Jack Jansendff77702001-09-05 22:07:52 +0000762Py_GetPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000763{
Jack Jansenac625691997-09-08 13:22:22 +0000764 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000765}
766
767char *
Jack Jansendff77702001-09-05 22:07:52 +0000768Py_GetExecPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000769{
Jack Jansenac625691997-09-08 13:22:22 +0000770 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000771}
Jack Jansen8a387142001-02-11 01:08:04 +0000772
773int
Jack Jansendff77702001-09-05 22:07:52 +0000774PyMac_GetDelayConsoleFlag(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000775{
776 return (int)PyMac_options.delayconsole;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000777}
778
779#ifndef WITHOUT_UNIX_NEWLINES
780/*
781** Experimental feature (for 2.2a2): optionally allow unix newlines
782** as well as Mac newlines on input. We replace a lowlevel
783** MSL routine to accomplish this.
784*/
785void
786__convert_to_newlines(unsigned char * buf, size_t * n_ptr)
787{
788 unsigned char *p;
789 size_t n = *n_ptr;
790
791 for(p=buf; n > 0; p++, n--)
792 if ( *p == '\r' ) *p = '\n';
793 else if ( *p == '\n' && !PyMac_options.unixnewlines )
794 *p = '\r';
795}
796#endif /* WITHOUT_UNIX_NEWLINES */
Jack Jansendff77702001-09-05 22:07:52 +0000797#endif /* !TARGET_API_MAC_OSX */
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000798