blob: 019e0bec0f9001903bf25585a1f7c180d571bf5e [file] [log] [blame]
Guido van Rossumb0f3c821994-08-23 13:34:25 +00001/***********************************************************
Guido van Rossum99546991995-01-08 14:33:34 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The 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 Jansen696c9581995-08-14 12:33:20 +000033#include <Memory.h>
34#include <Resources.h>
Guido van Rossumb0f3c821994-08-23 13:34:25 +000035#include <stdio.h>
Jack Jansen696c9581995-08-14 12:33:20 +000036#include <Events.h>
37#include <Windows.h>
38#include <Desk.h>
Jack Jansen2429c721996-03-07 15:17:11 +000039#include <Fonts.h>
Guido van Rossumb0f3c821994-08-23 13:34:25 +000040
Jack Jansenc76fd391995-02-02 14:27:31 +000041#ifdef __MWERKS__
42#include <SIOUX.h>
Jack Jansen1e8557a1995-11-10 14:51:26 +000043#define USE_SIOUX
Jack Jansenc76fd391995-02-02 14:27:31 +000044#endif
45
Jack Jansen0168f271995-10-27 13:32:30 +000046#ifdef THINK_C
47#include <console.h>
48#endif
49
Jack Jansen696c9581995-08-14 12:33:20 +000050#define STARTUP "PythonStartup"
Jack Jansenbac428d1994-12-14 13:47:30 +000051
Jack Jansen696c9581995-08-14 12:33:20 +000052extern int Py_DebugFlag; /* For parser.c, declared in pythonrun.c */
53extern int Py_VerboseFlag; /* For import.c, declared in pythonrun.c */
54extern int Py_SuppressPrintingFlag; /* For ceval.c, declared in pythonrun.c */
55
56
57/* Subroutines that live in their own file */
Jack Jansena547dca1996-07-10 15:48:25 +000058extern char *Py_GetVersion Py_PROTO((void));
59extern char *Py_GetCopyright Py_PROTO((void));
Jack Jansen696c9581995-08-14 12:33:20 +000060
61
Jack Jansen1d2f8631996-08-02 15:16:16 +000062/* For Py_GetProgramName(); set by main() */
Jack Jansen696c9581995-08-14 12:33:20 +000063static char *argv0;
64
Jack Jansen1d2f8631996-08-02 15:16:16 +000065/* For Py_GetArgcArgv(); set by main() */
Jack Jansen696c9581995-08-14 12:33:20 +000066static char **orig_argv;
67static int orig_argc;
68
Jack Jansen0168f271995-10-27 13:32:30 +000069/* Flags indicating whether stdio window should stay open on termination */
70static int keep_normal;
71static int keep_error = 1;
72
Jack Jansen76ceece1996-08-19 11:18:24 +000073static void Py_Main Py_PROTO((int, char **)); /* Forward */
74void PyMac_Exit Py_PROTO((int)); /* Forward */
75
Jack Jansen01fbc681996-02-28 15:42:47 +000076/* Initialize the Mac toolbox world */
77
78static void
79init_mac_world()
80{
81#ifdef THINK_C
82 printf("\n");
83#else
84 MaxApplZone();
85 InitGraf(&qd.thePort);
86 InitFonts();
87 InitWindows();
88 TEInit();
89 InitDialogs((long)0);
90 InitMenus();
91 InitCursor();
92#endif
93}
94
95/* Initialization code shared by interpreter and applets */
96
97static void
98init_common()
99{
100
101 /* Initialize toolboxes */
102 init_mac_world();
103
104#ifdef USE_MAC_SHARED_LIBRARY
105 /* Add the shared library to the stack of resource files */
106 PyMac_AddLibResources();
107#endif
108
109#if defined(USE_GUSI)
110 /* Setup GUSI */
111 GUSIDefaultSetup();
Jack Jansenf6865f71996-09-04 15:24:59 +0000112 PyMac_SetGUSISpin();
Jack Jansen01fbc681996-02-28 15:42:47 +0000113#endif
114
115#ifdef USE_SIOUX
116 /* Set various SIOUX flags. Some are changed later based on options */
117 SIOUXSettings.asktosaveonclose = 0;
118 SIOUXSettings.showstatusline = 0;
119 SIOUXSettings.tabspaces = 4;
120#endif
121
122}
123
124
Jack Jansen696c9581995-08-14 12:33:20 +0000125#ifdef USE_MAC_APPLET_SUPPORT
126/* Applet support */
127
128/* Run a compiled Python Python script from 'PYC ' resource __main__ */
129static int
130run_main_resource()
131{
132 Handle h;
133 long size;
134 PyObject *code;
135 PyObject *result;
136
137 h = GetNamedResource('PYC ', "\p__main__");
138 if (h == NULL) {
139 Alert(NOPYC_ALERT, NULL);
140 return 1;
141 }
142 size = GetResourceSizeOnDisk(h);
143 HLock(h);
144 code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
145 HUnlock(h);
146 ReleaseResource(h);
147 if (code == NULL) {
148 PyErr_Print();
149 return 1;
150 }
151 result = PyImport_ExecCodeModule("__main__", code);
152 Py_DECREF(code);
153 if (result == NULL) {
154 PyErr_Print();
155 return 1;
156 }
157 Py_DECREF(result);
158 return 0;
159}
160
161/* Initialization sequence for applets */
162void
163PyMac_InitApplet()
164{
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000165 int argc;
166 char **argv;
Jack Jansen696c9581995-08-14 12:33:20 +0000167 int err;
168
Jack Jansen01fbc681996-02-28 15:42:47 +0000169 init_common();
Jack Jansen696c9581995-08-14 12:33:20 +0000170 argc = PyMac_GetArgv(&argv);
171 Py_Initialize();
172 PySys_SetArgv(argc, argv);
173 err = run_main_resource();
174 fflush(stderr);
175 fflush(stdout);
Jack Jansen0168f271995-10-27 13:32:30 +0000176 PyMac_Exit(err);
Jack Jansen696c9581995-08-14 12:33:20 +0000177 /* XXX Should we bother to Py_Exit(sts)? */
178}
179
180#endif /* USE_MAC_APPLET_SUPPORT */
181
182/* For normal application */
183void
184PyMac_InitApplication()
185{
186 int argc;
187 char **argv;
188
Jack Jansen01fbc681996-02-28 15:42:47 +0000189 init_common();
Jack Jansen696c9581995-08-14 12:33:20 +0000190 argc = PyMac_GetArgv(&argv);
191 if ( argc > 1 ) {
192 /* We're running a script. Attempt to change current directory */
193 char curwd[256], *endp;
194
195 strcpy(curwd, argv[1]);
196 endp = strrchr(curwd, ':');
197 if ( endp && endp > curwd ) {
198 *endp = '\0';
199
200 chdir(curwd);
Jack Jansen378815c1996-03-06 16:21:34 +0000201#ifdef USE_GUSI
202 /* Change MacOS's idea of wd too */
203 PyMac_FixGUSIcd();
204#endif
Jack Jansen696c9581995-08-14 12:33:20 +0000205 }
206 }
207 Py_Main(argc, argv);
208}
209
210/*
211** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
212*/
213void
214PyMac_InteractiveOptions(int *inspect, int *verbose, int *suppress_print,
Jack Jansen0168f271995-10-27 13:32:30 +0000215 int *unbuffered, int *debugging, int *keep_normal,
Jack Jansene355c451996-03-12 13:29:04 +0000216 int *keep_error, int *argcp, char ***argvp)
Jack Jansen696c9581995-08-14 12:33:20 +0000217{
218 KeyMap rmap;
219 unsigned char *map;
220 short item, type;
221 ControlHandle handle;
222 DialogPtr dialog;
223 Rect rect;
Jack Jansene355c451996-03-12 13:29:04 +0000224 int old_argc = *argcp;
225 int i;
Jack Jansen696c9581995-08-14 12:33:20 +0000226
Jack Jansena4b7e141996-02-21 16:46:57 +0000227 /* Default-defaults: */
228 *keep_error = 1;
229 /* Get default settings from our preference file */
Jack Jansen01fbc681996-02-28 15:42:47 +0000230 PyMac_PreferenceOptions(inspect, verbose, suppress_print,
231 unbuffered, debugging, keep_normal, keep_error);
Jack Jansena4b7e141996-02-21 16:46:57 +0000232 /* If option is pressed override these */
Jack Jansen696c9581995-08-14 12:33:20 +0000233 GetKeys(rmap);
234 map = (unsigned char *)rmap;
235 if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
236 return;
237
238 dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
239 if ( dialog == NULL ) {
240 printf("Option dialog not found - cannot set options\n");
241 return;
242 }
Jack Jansene355c451996-03-12 13:29:04 +0000243 SetDialogDefaultItem(dialog, OPT_OK);
244 SetDialogCancelItem(dialog, OPT_CANCEL);
Jack Jansen0168f271995-10-27 13:32:30 +0000245
Jack Jansena4b7e141996-02-21 16:46:57 +0000246 /* Set default values */
247#define SET_OPT_ITEM(num, var) \
248 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
249 SetCtlValue(handle, (short)*(var));
250
251 SET_OPT_ITEM(OPT_INSPECT, inspect);
252 SET_OPT_ITEM(OPT_VERBOSE, verbose);
253 SET_OPT_ITEM(OPT_SUPPRESS, suppress_print);
254 SET_OPT_ITEM(OPT_UNBUFFERED, unbuffered);
255 SET_OPT_ITEM(OPT_DEBUGGING, debugging);
256 SET_OPT_ITEM(OPT_KEEPNORMAL, keep_normal);
257 SET_OPT_ITEM(OPT_KEEPERROR, keep_error);
258
259#undef SET_OPT_ITEM
Jack Jansen0168f271995-10-27 13:32:30 +0000260
Jack Jansen696c9581995-08-14 12:33:20 +0000261 while (1) {
262 handle = NULL;
263 ModalDialog(NULL, &item);
264 if ( item == OPT_OK )
265 break;
266 if ( item == OPT_CANCEL ) {
267 DisposDialog(dialog);
268 exit(0);
269 }
Jack Jansene355c451996-03-12 13:29:04 +0000270 if ( item == OPT_CMDLINE ) {
271 int new_argc, newer_argc;
272 char **new_argv, **newer_argv;
273
274 new_argc = ccommand(&new_argv);
275 newer_argc = (new_argc-1) + old_argc;
276 newer_argv = malloc((newer_argc+1)*sizeof(char *));
277 if( !newer_argv )
278 Py_FatalError("Cannot malloc argv\n");
279 for(i=0; i<old_argc; i++)
280 newer_argv[i] = (*argvp)[i];
281 for(i=old_argc; i<=newer_argc; i++) /* Copy the NULL too */
282 newer_argv[i] = new_argv[i-old_argc+1];
283 *argvp = newer_argv;
284 *argcp = newer_argc;
285
286 /* XXXX Is it not safe to use free() here, apparently */
287 }
Jack Jansen696c9581995-08-14 12:33:20 +0000288#define OPT_ITEM(num, var) \
289 if ( item == (num) ) { \
290 *(var) = !*(var); \
291 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
292 SetCtlValue(handle, (short)*(var)); \
293 }
294
295 OPT_ITEM(OPT_INSPECT, inspect);
296 OPT_ITEM(OPT_VERBOSE, verbose);
297 OPT_ITEM(OPT_SUPPRESS, suppress_print);
298 OPT_ITEM(OPT_UNBUFFERED, unbuffered);
299 OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen0168f271995-10-27 13:32:30 +0000300 OPT_ITEM(OPT_KEEPNORMAL, keep_normal);
301 OPT_ITEM(OPT_KEEPERROR, keep_error);
Jack Jansen696c9581995-08-14 12:33:20 +0000302
303#undef OPT_ITEM
304 }
305 DisposDialog(dialog);
306}
307/* Main program */
308
Jack Jansen76ceece1996-08-19 11:18:24 +0000309static void
Jack Jansen696c9581995-08-14 12:33:20 +0000310Py_Main(argc, argv)
311 int argc;
312 char **argv;
313{
Jack Jansen696c9581995-08-14 12:33:20 +0000314 int sts;
315 char *command = NULL;
316 char *filename = NULL;
317 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000318 int inspect = 0;
319 int unbuffered = 0;
320
Jack Jansene355c451996-03-12 13:29:04 +0000321 PyMac_InteractiveOptions(&inspect, &Py_VerboseFlag, &Py_SuppressPrintingFlag,
322 &unbuffered, &Py_DebugFlag, &keep_normal, &keep_error, &argc, &argv);
323
Jack Jansen1d2f8631996-08-02 15:16:16 +0000324 orig_argc = argc; /* For Py_GetArgcArgv() */
Jack Jansen696c9581995-08-14 12:33:20 +0000325 orig_argv = argv;
Jack Jansen1d2f8631996-08-02 15:16:16 +0000326 argv0 = argv[0]; /* For Py_GetProgramName() */
Jack Jansen696c9581995-08-14 12:33:20 +0000327
328 if (unbuffered) {
329#ifndef MPW
330 setbuf(stdout, (char *)NULL);
331 setbuf(stderr, (char *)NULL);
332#else
333 /* On MPW (3.2) unbuffered seems to hang */
334 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
335 setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
336#endif
337 }
338
339 filename = argv[1];
340
341 if (Py_VerboseFlag ||
342 command == NULL && filename == NULL && isatty((int)fileno(fp)))
343 fprintf(stderr, "Python %s\n%s\n",
Jack Jansena547dca1996-07-10 15:48:25 +0000344 Py_GetVersion(), Py_GetCopyright());
Jack Jansen696c9581995-08-14 12:33:20 +0000345
346 if (filename != NULL) {
347 if ((fp = fopen(filename, "r")) == NULL) {
348 fprintf(stderr, "%s: can't open file '%s'\n",
349 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000350 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000351 }
352 }
353
354 Py_Initialize();
355
356 PySys_SetArgv(argc-1, argv+1);
357
358 if (filename == NULL && isatty((int)fileno(fp))) {
359 FILE *fp = fopen(STARTUP, "r");
360 if (fp != NULL) {
361 (void) PyRun_SimpleFile(fp, STARTUP);
362 PyErr_Clear();
363 fclose(fp);
364 }
365 }
366 sts = PyRun_AnyFile(
367 fp, filename == NULL ? "<stdin>" : filename) != 0;
368 if (filename != NULL)
369 fclose(fp);
370
371 if (inspect && isatty((int)fileno(stdin)) &&
372 (filename != NULL || command != NULL))
373 sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
374
375 Py_Exit(sts);
376 /*NOTREACHED*/
377}
378
Jack Jansen0168f271995-10-27 13:32:30 +0000379/*
380** Terminate application
381*/
Jack Jansen76ceece1996-08-19 11:18:24 +0000382void
Jack Jansen0168f271995-10-27 13:32:30 +0000383PyMac_Exit(status)
384 int status;
385{
386 int keep;
387
388 if ( status )
389 keep = keep_error;
390 else
391 keep = keep_normal;
392
Jack Jansen1e8557a1995-11-10 14:51:26 +0000393#ifdef USE_SIOUX
394 if (keep) {
395 SIOUXSettings.standalone = 1;
396 SIOUXSettings.autocloseonquit = 0;
Jack Jansen415571c1996-03-25 15:46:03 +0000397 SIOUXSetTitle("\p\307terminated\310");
Jack Jansen1e8557a1995-11-10 14:51:26 +0000398 }
Jack Jansen0168f271995-10-27 13:32:30 +0000399 else
400 SIOUXSettings.autocloseonquit = 1;
Jack Jansenf6865f71996-09-04 15:24:59 +0000401#ifdef USE_GUSI
402 /*
403 ** Workaround for Sioux/GUSI combo: we should not call
404 ** SiouxHandleOneEvent after the window is closed
405 */
406 PyMac_ConsoleIsDead = 1;
407#endif /* USE_GUSI */
408#endif /* USE_SIOUX */
Jack Jansen0168f271995-10-27 13:32:30 +0000409#ifdef THINK_C
410 console_options.pause_atexit = keep;
411#endif
412
413 exit(status);
414}
Jack Jansen696c9581995-08-14 12:33:20 +0000415
416/* Return the program name -- some code out there needs this. */
417
418char *
Jack Jansen1d2f8631996-08-02 15:16:16 +0000419Py_GetProgramName()
Jack Jansen696c9581995-08-14 12:33:20 +0000420{
421 return argv0;
422}
423
424
425/* Make the *original* argc/argv available to other modules.
426 This is rare, but it is needed by the secureware extension. */
427
428void
Jack Jansen1d2f8631996-08-02 15:16:16 +0000429Py_GetArgcArgv(argc,argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000430 int *argc;
431 char ***argv;
432{
433 *argc = orig_argc;
434 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000435}
Jack Jansen1d2f8631996-08-02 15:16:16 +0000436
437/* More cruft that shouldn't really be here, used in sysmodule.c */
438
439char *
440Py_GetPrefix()
441{
442 return "";
443}
444
445char *
446Py_GetExecPrefix()
447{
448 return "";
449}