blob: 5cea381b429f29d947819c4f0892e267d5736bac [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"
Guido van Rossumb0f3c821994-08-23 13:34:25 +000031
Jack Jansen696c9581995-08-14 12:33:20 +000032#include <Memory.h>
33#include <Resources.h>
Guido van Rossumb0f3c821994-08-23 13:34:25 +000034#include <stdio.h>
Jack Jansen696c9581995-08-14 12:33:20 +000035#include <Events.h>
36#include <Windows.h>
37#include <Desk.h>
Guido van Rossumb0f3c821994-08-23 13:34:25 +000038
Jack Jansenc76fd391995-02-02 14:27:31 +000039#ifdef __MWERKS__
40#include <SIOUX.h>
Jack Jansen1e8557a1995-11-10 14:51:26 +000041#define USE_SIOUX
Jack Jansenc76fd391995-02-02 14:27:31 +000042#endif
43
Jack Jansen0168f271995-10-27 13:32:30 +000044#ifdef THINK_C
45#include <console.h>
46#endif
47
Jack Jansen696c9581995-08-14 12:33:20 +000048#define STARTUP "PythonStartup"
Jack Jansenbac428d1994-12-14 13:47:30 +000049
Jack Jansen696c9581995-08-14 12:33:20 +000050extern int Py_DebugFlag; /* For parser.c, declared in pythonrun.c */
51extern int Py_VerboseFlag; /* For import.c, declared in pythonrun.c */
52extern int Py_SuppressPrintingFlag; /* For ceval.c, declared in pythonrun.c */
53
54
55/* Subroutines that live in their own file */
Jack Jansen85c9aea1995-10-23 13:57:03 +000056extern char *getversion Py_PROTO((void));
57extern char *getcopyright Py_PROTO((void));
Jack Jansen696c9581995-08-14 12:33:20 +000058
59
60/* For getprogramname(); set by main() */
61static char *argv0;
62
63/* For getargcargv(); set by main() */
64static char **orig_argv;
65static int orig_argc;
66
Jack Jansen0168f271995-10-27 13:32:30 +000067/* Flags indicating whether stdio window should stay open on termination */
68static int keep_normal;
69static int keep_error = 1;
70
Jack Jansen01fbc681996-02-28 15:42:47 +000071/* Initialize the Mac toolbox world */
72
73static void
74init_mac_world()
75{
76#ifdef THINK_C
77 printf("\n");
78#else
79 MaxApplZone();
80 InitGraf(&qd.thePort);
81 InitFonts();
82 InitWindows();
83 TEInit();
84 InitDialogs((long)0);
85 InitMenus();
86 InitCursor();
87#endif
88}
89
90/* Initialization code shared by interpreter and applets */
91
92static void
93init_common()
94{
95
96 /* Initialize toolboxes */
97 init_mac_world();
98
99#ifdef USE_MAC_SHARED_LIBRARY
100 /* Add the shared library to the stack of resource files */
101 PyMac_AddLibResources();
102#endif
103
104#if defined(USE_GUSI)
105 /* Setup GUSI */
106 GUSIDefaultSetup();
107#endif
108
109#ifdef USE_SIOUX
110 /* Set various SIOUX flags. Some are changed later based on options */
111 SIOUXSettings.asktosaveonclose = 0;
112 SIOUXSettings.showstatusline = 0;
113 SIOUXSettings.tabspaces = 4;
114#endif
115
116}
117
118
Jack Jansen696c9581995-08-14 12:33:20 +0000119#ifdef USE_MAC_APPLET_SUPPORT
120/* Applet support */
121
122/* Run a compiled Python Python script from 'PYC ' resource __main__ */
123static int
124run_main_resource()
125{
126 Handle h;
127 long size;
128 PyObject *code;
129 PyObject *result;
130
131 h = GetNamedResource('PYC ', "\p__main__");
132 if (h == NULL) {
133 Alert(NOPYC_ALERT, NULL);
134 return 1;
135 }
136 size = GetResourceSizeOnDisk(h);
137 HLock(h);
138 code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
139 HUnlock(h);
140 ReleaseResource(h);
141 if (code == NULL) {
142 PyErr_Print();
143 return 1;
144 }
145 result = PyImport_ExecCodeModule("__main__", code);
146 Py_DECREF(code);
147 if (result == NULL) {
148 PyErr_Print();
149 return 1;
150 }
151 Py_DECREF(result);
152 return 0;
153}
154
155/* Initialization sequence for applets */
156void
157PyMac_InitApplet()
158{
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000159 int argc;
160 char **argv;
Jack Jansen696c9581995-08-14 12:33:20 +0000161 int err;
162
Jack Jansen01fbc681996-02-28 15:42:47 +0000163 init_common();
Jack Jansen696c9581995-08-14 12:33:20 +0000164 argc = PyMac_GetArgv(&argv);
165 Py_Initialize();
166 PySys_SetArgv(argc, argv);
167 err = run_main_resource();
168 fflush(stderr);
169 fflush(stdout);
Jack Jansen0168f271995-10-27 13:32:30 +0000170 PyMac_Exit(err);
Jack Jansen696c9581995-08-14 12:33:20 +0000171 /* XXX Should we bother to Py_Exit(sts)? */
172}
173
174#endif /* USE_MAC_APPLET_SUPPORT */
175
176/* For normal application */
177void
178PyMac_InitApplication()
179{
180 int argc;
181 char **argv;
182
Jack Jansen01fbc681996-02-28 15:42:47 +0000183 init_common();
Jack Jansen696c9581995-08-14 12:33:20 +0000184 argc = PyMac_GetArgv(&argv);
185 if ( argc > 1 ) {
186 /* We're running a script. Attempt to change current directory */
187 char curwd[256], *endp;
188
189 strcpy(curwd, argv[1]);
190 endp = strrchr(curwd, ':');
191 if ( endp && endp > curwd ) {
192 *endp = '\0';
193
194 chdir(curwd);
Jack Jansen378815c1996-03-06 16:21:34 +0000195#ifdef USE_GUSI
196 /* Change MacOS's idea of wd too */
197 PyMac_FixGUSIcd();
198#endif
Jack Jansen696c9581995-08-14 12:33:20 +0000199 }
200 }
201 Py_Main(argc, argv);
202}
203
204/*
205** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
206*/
207void
208PyMac_InteractiveOptions(int *inspect, int *verbose, int *suppress_print,
Jack Jansen0168f271995-10-27 13:32:30 +0000209 int *unbuffered, int *debugging, int *keep_normal,
210 int *keep_error)
Jack Jansen696c9581995-08-14 12:33:20 +0000211{
212 KeyMap rmap;
213 unsigned char *map;
214 short item, type;
215 ControlHandle handle;
216 DialogPtr dialog;
217 Rect rect;
218
Jack Jansena4b7e141996-02-21 16:46:57 +0000219 /* Default-defaults: */
220 *keep_error = 1;
221 /* Get default settings from our preference file */
Jack Jansen01fbc681996-02-28 15:42:47 +0000222 PyMac_PreferenceOptions(inspect, verbose, suppress_print,
223 unbuffered, debugging, keep_normal, keep_error);
Jack Jansena4b7e141996-02-21 16:46:57 +0000224 /* If option is pressed override these */
Jack Jansen696c9581995-08-14 12:33:20 +0000225 GetKeys(rmap);
226 map = (unsigned char *)rmap;
227 if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
228 return;
229
230 dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
231 if ( dialog == NULL ) {
232 printf("Option dialog not found - cannot set options\n");
233 return;
234 }
Jack Jansen0168f271995-10-27 13:32:30 +0000235
Jack Jansena4b7e141996-02-21 16:46:57 +0000236 /* Set default values */
237#define SET_OPT_ITEM(num, var) \
238 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
239 SetCtlValue(handle, (short)*(var));
240
241 SET_OPT_ITEM(OPT_INSPECT, inspect);
242 SET_OPT_ITEM(OPT_VERBOSE, verbose);
243 SET_OPT_ITEM(OPT_SUPPRESS, suppress_print);
244 SET_OPT_ITEM(OPT_UNBUFFERED, unbuffered);
245 SET_OPT_ITEM(OPT_DEBUGGING, debugging);
246 SET_OPT_ITEM(OPT_KEEPNORMAL, keep_normal);
247 SET_OPT_ITEM(OPT_KEEPERROR, keep_error);
248
249#undef SET_OPT_ITEM
Jack Jansen0168f271995-10-27 13:32:30 +0000250
Jack Jansen696c9581995-08-14 12:33:20 +0000251 while (1) {
252 handle = NULL;
253 ModalDialog(NULL, &item);
254 if ( item == OPT_OK )
255 break;
256 if ( item == OPT_CANCEL ) {
257 DisposDialog(dialog);
258 exit(0);
259 }
260#define OPT_ITEM(num, var) \
261 if ( item == (num) ) { \
262 *(var) = !*(var); \
263 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
264 SetCtlValue(handle, (short)*(var)); \
265 }
266
267 OPT_ITEM(OPT_INSPECT, inspect);
268 OPT_ITEM(OPT_VERBOSE, verbose);
269 OPT_ITEM(OPT_SUPPRESS, suppress_print);
270 OPT_ITEM(OPT_UNBUFFERED, unbuffered);
271 OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen0168f271995-10-27 13:32:30 +0000272 OPT_ITEM(OPT_KEEPNORMAL, keep_normal);
273 OPT_ITEM(OPT_KEEPERROR, keep_error);
Jack Jansen696c9581995-08-14 12:33:20 +0000274
275#undef OPT_ITEM
276 }
277 DisposDialog(dialog);
278}
279/* Main program */
280
281int
282Py_Main(argc, argv)
283 int argc;
284 char **argv;
285{
Jack Jansen696c9581995-08-14 12:33:20 +0000286 int sts;
287 char *command = NULL;
288 char *filename = NULL;
289 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000290 int inspect = 0;
291 int unbuffered = 0;
292
293 orig_argc = argc; /* For getargcargv() */
294 orig_argv = argv;
295 argv0 = argv[0]; /* For getprogramname() */
296
297 PyMac_InteractiveOptions(&inspect, &Py_VerboseFlag, &Py_SuppressPrintingFlag,
Jack Jansen0168f271995-10-27 13:32:30 +0000298 &unbuffered, &Py_DebugFlag, &keep_normal, &keep_error);
Jack Jansen696c9581995-08-14 12:33:20 +0000299
300 if (unbuffered) {
301#ifndef MPW
302 setbuf(stdout, (char *)NULL);
303 setbuf(stderr, (char *)NULL);
304#else
305 /* On MPW (3.2) unbuffered seems to hang */
306 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
307 setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
308#endif
309 }
310
311 filename = argv[1];
312
313 if (Py_VerboseFlag ||
314 command == NULL && filename == NULL && isatty((int)fileno(fp)))
315 fprintf(stderr, "Python %s\n%s\n",
316 getversion(), getcopyright());
317
318 if (filename != NULL) {
319 if ((fp = fopen(filename, "r")) == NULL) {
320 fprintf(stderr, "%s: can't open file '%s'\n",
321 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000322 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000323 }
324 }
325
326 Py_Initialize();
327
328 PySys_SetArgv(argc-1, argv+1);
329
330 if (filename == NULL && isatty((int)fileno(fp))) {
331 FILE *fp = fopen(STARTUP, "r");
332 if (fp != NULL) {
333 (void) PyRun_SimpleFile(fp, STARTUP);
334 PyErr_Clear();
335 fclose(fp);
336 }
337 }
338 sts = PyRun_AnyFile(
339 fp, filename == NULL ? "<stdin>" : filename) != 0;
340 if (filename != NULL)
341 fclose(fp);
342
343 if (inspect && isatty((int)fileno(stdin)) &&
344 (filename != NULL || command != NULL))
345 sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
346
347 Py_Exit(sts);
348 /*NOTREACHED*/
349}
350
Jack Jansen0168f271995-10-27 13:32:30 +0000351/*
352** Terminate application
353*/
354PyMac_Exit(status)
355 int status;
356{
357 int keep;
358
359 if ( status )
360 keep = keep_error;
361 else
362 keep = keep_normal;
363
Jack Jansen1e8557a1995-11-10 14:51:26 +0000364#ifdef USE_SIOUX
365 if (keep) {
366 SIOUXSettings.standalone = 1;
367 SIOUXSettings.autocloseonquit = 0;
Jack Jansena4b7e141996-02-21 16:46:57 +0000368 SIOUXSetTitle("\pĀ«terminatedĀ»");
Jack Jansen1e8557a1995-11-10 14:51:26 +0000369 }
Jack Jansen0168f271995-10-27 13:32:30 +0000370 else
371 SIOUXSettings.autocloseonquit = 1;
372#endif
373#ifdef THINK_C
374 console_options.pause_atexit = keep;
375#endif
376
377 exit(status);
378}
Jack Jansen696c9581995-08-14 12:33:20 +0000379
380/* Return the program name -- some code out there needs this. */
381
382char *
383getprogramname()
384{
385 return argv0;
386}
387
388
389/* Make the *original* argc/argv available to other modules.
390 This is rare, but it is needed by the secureware extension. */
391
392void
393getargcargv(argc,argv)
394 int *argc;
395 char ***argv;
396{
397 *argc = orig_argc;
398 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000399}