blob: 9e5a30013834e19fdf89094b86af7074164b88d2 [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 Jansenace9d952002-08-05 14:13:31 +000089static void PyMac_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
Jack Jansenace9d952002-08-05 14:13:31 +0000540 PyMac_Main(argc, argv, script);
Jack Jansen998a40a2001-09-11 13:08:10 +0000541 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;
Jack Jansena7f4ded2002-05-22 15:02:08 +0000552 OSType filetype;
Jack Jansen696c9581995-08-14 12:33:20 +0000553
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000554 static char scriptpath[1024];
555 char *script = NULL;
556
Jack Jansen52ac0371997-01-15 15:49:08 +0000557 init_common(&argc, &argv, 0);
Jack Jansen5ded1bf2001-10-30 22:48:36 +0000558
559#if TARGET_API_MAC_OSX /* Really: TARGET_API_MAC_CARBON */
560 /* If we are running inside of a bundle, and a __main__.py is available, use it */
561 if (locateResourcePy("__main__.py", scriptpath, 1024))
562 script = scriptpath;
563#endif
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000564
Jack Jansen696c9581995-08-14 12:33:20 +0000565 if ( argc > 1 ) {
566 /* We're running a script. Attempt to change current directory */
567 char curwd[256], *endp;
568
569 strcpy(curwd, argv[1]);
570 endp = strrchr(curwd, ':');
571 if ( endp && endp > curwd ) {
572 *endp = '\0';
573
574 chdir(curwd);
575 }
Jack Jansencbed91b2001-08-03 13:31:36 +0000576 /* Check that the first argument is a text file */
Jack Jansena7f4ded2002-05-22 15:02:08 +0000577 filetype = PyMac_getfiletype(argv[1]);
578 if ( filetype != 'TEXT' && filetype != 0 ) {
Jack Jansencbed91b2001-08-03 13:31:36 +0000579 Alert(NOTASCRIPT_ID, NULL);
580 exit(0);
581 }
Jack Jansen696c9581995-08-14 12:33:20 +0000582 }
Jack Jansenace9d952002-08-05 14:13:31 +0000583 PyMac_Main(argc, argv, script);
Jack Jansen696c9581995-08-14 12:33:20 +0000584}
Jack Jansendff77702001-09-05 22:07:52 +0000585#endif /* TARGET_API_MAC_OSX */
Jack Jansen696c9581995-08-14 12:33:20 +0000586
Jack Jansen696c9581995-08-14 12:33:20 +0000587/* Main program */
588
Jack Jansen76ceece1996-08-19 11:18:24 +0000589static void
Jack Jansenace9d952002-08-05 14:13:31 +0000590PyMac_Main(int argc, char **argv, char *filename)
Jack Jansen696c9581995-08-14 12:33:20 +0000591{
Jack Jansen696c9581995-08-14 12:33:20 +0000592 int sts;
593 char *command = NULL;
Jack Jansen696c9581995-08-14 12:33:20 +0000594 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000595
Jack Jansen998a40a2001-09-11 13:08:10 +0000596 if ( filename ) {
597 /* Someone else has found our "script" already */
598 argv[0] = filename;
599 } else {
600 filename = argv[1];
601 argv++;
602 argc--;
603 }
Jack Jansen696c9581995-08-14 12:33:20 +0000604
605 if (Py_VerboseFlag ||
Jack Jansendff77702001-09-05 22:07:52 +0000606 (command == NULL && filename == NULL && isatty((int)fileno(fp))))
Jack Jansen0035fb22002-03-29 14:27:06 +0000607 fprintf(stderr, "%s %s on %s\n%s\n",
608#if !TARGET_API_MAC_OSX
609 "Python",
610#else
611 "Pythonw",
612#endif
Jack Jansen65c3ee02000-09-08 10:20:37 +0000613 Py_GetVersion(), Py_GetPlatform(), COPYRIGHT);
Jack Jansen696c9581995-08-14 12:33:20 +0000614
615 if (filename != NULL) {
Jack Jansen7b8c7542002-04-14 20:12:41 +0000616 if ((fp = fopen(filename, "r" PY_STDIOTEXTMODE)) == NULL) {
Jack Jansen696c9581995-08-14 12:33:20 +0000617 fprintf(stderr, "%s: can't open file '%s'\n",
618 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000619 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000620 }
621 }
622
Jack Jansendff77702001-09-05 22:07:52 +0000623#if !TARGET_API_MAC_OSX
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000624 /* We initialize the menubar here, hoping SIOUX is initialized by now */
Jack Jansen3469e991996-09-06 00:30:45 +0000625 PyMac_InitMenuBar();
Jack Jansendff77702001-09-05 22:07:52 +0000626#endif
627
Jack Jansen696c9581995-08-14 12:33:20 +0000628 Py_Initialize();
629
unknownd1054ef2001-07-04 22:37:19 +0000630 PyUnicode_SetDefaultEncoding(PyMac_getscript());
631
Jack Jansen998a40a2001-09-11 13:08:10 +0000632 PySys_SetArgv(argc, argv);
Jack Jansen696c9581995-08-14 12:33:20 +0000633
634 if (filename == NULL && isatty((int)fileno(fp))) {
Jack Jansen7b8c7542002-04-14 20:12:41 +0000635 FILE *fp = fopen(STARTUP, "r" PY_STDIOTEXTMODE);
Jack Jansen696c9581995-08-14 12:33:20 +0000636 if (fp != NULL) {
637 (void) PyRun_SimpleFile(fp, STARTUP);
638 PyErr_Clear();
639 fclose(fp);
640 }
641 }
642 sts = PyRun_AnyFile(
643 fp, filename == NULL ? "<stdin>" : filename) != 0;
644 if (filename != NULL)
645 fclose(fp);
Jack Jansen7d5f9e81996-09-07 17:09:31 +0000646
647 if ( filename != NULL || command != NULL )
648 sts = (run_inspect() || sts);
Jack Jansen696c9581995-08-14 12:33:20 +0000649
650 Py_Exit(sts);
651 /*NOTREACHED*/
652}
653
Jack Jansendff77702001-09-05 22:07:52 +0000654#if !TARGET_API_MAC_OSX
Jack Jansen0168f271995-10-27 13:32:30 +0000655/*
Jack Jansen8413b472000-10-19 22:02:16 +0000656** Reset the "unseen output" flag
657*/
658void
Jack Jansendff77702001-09-05 22:07:52 +0000659PyMac_OutputSeen(void)
Jack Jansen8413b472000-10-19 22:02:16 +0000660{
Jack Jansen657ba272001-02-17 22:02:07 +0000661 if ( console_output_state == STATE_UNKNOWN )
662 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000663 console_output_state = STATE_LASTREAD;
Jack Jansen8413b472000-10-19 22:02:16 +0000664}
665
666/*
Jack Jansen8a387142001-02-11 01:08:04 +0000667** Set the "unseen output" flag
668*/
669void
Jack Jansendff77702001-09-05 22:07:52 +0000670PyMac_OutputNotSeen(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000671{
Jack Jansen657ba272001-02-17 22:02:07 +0000672 if ( console_output_state == STATE_UNKNOWN )
673 PyMac_InitMenuBar();
Jack Jansen8a387142001-02-11 01:08:04 +0000674 console_output_state = STATE_LASTWRITE;
675}
Jack Jansen15f1c082001-04-25 22:07:27 +0000676
677/*
678** Override abort() - The default one is not what we want.
679*/
680void
Jack Jansendff77702001-09-05 22:07:52 +0000681abort(void)
Jack Jansen15f1c082001-04-25 22:07:27 +0000682{
683 console_output_state = STATE_LASTWRITE;
684 PyMac_Exit(1);
685}
Jack Jansendff77702001-09-05 22:07:52 +0000686#endif /* !TARGET_API_MAC_OSX */
Jack Jansen8a387142001-02-11 01:08:04 +0000687
688/*
Jack Jansen0168f271995-10-27 13:32:30 +0000689** Terminate application
690*/
Jack Jansen76ceece1996-08-19 11:18:24 +0000691void
Jack Jansendff77702001-09-05 22:07:52 +0000692PyMac_Exit(int status)
Jack Jansen0168f271995-10-27 13:32:30 +0000693{
Jack Jansendff77702001-09-05 22:07:52 +0000694#ifdef USE_SIOUX
Jack Jansen4a5eb962000-09-22 21:50:11 +0000695 int keep = 0;
Jack Jansendff77702001-09-05 22:07:52 +0000696#endif
Jack Jansen8c693211997-01-07 16:19:42 +0000697
698#if __profile__ == 1
699 ProfilerDump("\pPython Profiler Results");
700 ProfilerTerm();
701#endif
Jack Jansen0168f271995-10-27 13:32:30 +0000702
Jack Jansen1e8557a1995-11-10 14:51:26 +0000703#ifdef USE_SIOUX
Jack Jansendc86f9e2000-10-12 21:23:19 +0000704 switch (PyMac_options.keep_console) {
Jack Jansen4a5eb962000-09-22 21:50:11 +0000705 case POPT_KEEPCONSOLE_NEVER:
706 keep = 0;
707 break;
708 case POPT_KEEPCONSOLE_OUTPUT:
Jack Jansen8a387142001-02-11 01:08:04 +0000709 if (console_output_state == STATE_LASTWRITE ||
710 console_output_state == STATE_UNKNOWN )
Jack Jansen4a5eb962000-09-22 21:50:11 +0000711 keep = 1;
712 else
713 keep = 0;
714 break;
715 case POPT_KEEPCONSOLE_ERROR:
716 keep = (status != 0);
717 break;
718 default:
719 keep = 1;
720 }
Jack Jansen1e8557a1995-11-10 14:51:26 +0000721 if (keep) {
722 SIOUXSettings.standalone = 1;
723 SIOUXSettings.autocloseonquit = 0;
Jack Jansen415571c1996-03-25 15:46:03 +0000724 SIOUXSetTitle("\p\307terminated\310");
Jack Jansen15f1c082001-04-25 22:07:27 +0000725 PyMac_RaiseConsoleWindow();
Jack Jansencaa7c461997-06-12 10:49:13 +0000726 PyMac_RestoreMenuBar();
Jack Jansene44545f1997-05-07 15:48:54 +0000727#ifdef USE_MSL
728 /*
729 ** Temporary workaround: autocloseonquit clearing does not
730 ** currently work for the MSL/GUSI combo.
731 */
732 while(getchar() > 0);
733#endif
Jack Jansen1e8557a1995-11-10 14:51:26 +0000734 }
Jack Jansen0168f271995-10-27 13:32:30 +0000735 else
736 SIOUXSettings.autocloseonquit = 1;
Jack Jansenf6865f71996-09-04 15:24:59 +0000737#endif /* USE_SIOUX */
Jack Jansen0168f271995-10-27 13:32:30 +0000738
739 exit(status);
740}
Jack Jansen696c9581995-08-14 12:33:20 +0000741
Jack Jansendff77702001-09-05 22:07:52 +0000742#if !TARGET_API_MAC_OSX
Jack Jansen696c9581995-08-14 12:33:20 +0000743/* Make the *original* argc/argv available to other modules.
744 This is rare, but it is needed by the secureware extension. */
745
746void
Jack Jansen9ae898b2000-07-11 21:16:03 +0000747Py_GetArgcArgv(int *argc,char ***argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000748{
749 *argc = orig_argc;
750 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000751}
Jack Jansendff77702001-09-05 22:07:52 +0000752#endif
Jack Jansen1d2f8631996-08-02 15:16:16 +0000753
754/* More cruft that shouldn't really be here, used in sysmodule.c */
Jack Jansendff77702001-09-05 22:07:52 +0000755#if !TARGET_API_MAC_OSX
756/* Return the program name -- some code out there needs this. */
757char *
758Py_GetProgramFullPath(void)
759{
760 return orig_argv[0];
761}
Jack Jansen1d2f8631996-08-02 15:16:16 +0000762
763char *
Jack Jansendff77702001-09-05 22:07:52 +0000764Py_GetPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000765{
Jack Jansenac625691997-09-08 13:22:22 +0000766 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000767}
768
769char *
Jack Jansendff77702001-09-05 22:07:52 +0000770Py_GetExecPrefix(void)
Jack Jansen1d2f8631996-08-02 15:16:16 +0000771{
Jack Jansenac625691997-09-08 13:22:22 +0000772 return PyMac_GetPythonDir();
Jack Jansen1d2f8631996-08-02 15:16:16 +0000773}
Jack Jansen8a387142001-02-11 01:08:04 +0000774
775int
Jack Jansendff77702001-09-05 22:07:52 +0000776PyMac_GetDelayConsoleFlag(void)
Jack Jansen8a387142001-02-11 01:08:04 +0000777{
778 return (int)PyMac_options.delayconsole;
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000779}
780
781#ifndef WITHOUT_UNIX_NEWLINES
782/*
783** Experimental feature (for 2.2a2): optionally allow unix newlines
784** as well as Mac newlines on input. We replace a lowlevel
785** MSL routine to accomplish this.
786*/
787void
788__convert_to_newlines(unsigned char * buf, size_t * n_ptr)
789{
790 unsigned char *p;
791 size_t n = *n_ptr;
792
793 for(p=buf; n > 0; p++, n--)
794 if ( *p == '\r' ) *p = '\n';
795 else if ( *p == '\n' && !PyMac_options.unixnewlines )
796 *p = '\r';
797}
798#endif /* WITHOUT_UNIX_NEWLINES */
Jack Jansendff77702001-09-05 22:07:52 +0000799#endif /* !TARGET_API_MAC_OSX */
Jack Jansenff5d8aa2001-09-01 22:37:54 +0000800