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