blob: 7241539f1575464bc33642da606d9677b78bf37d [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 Jansena547dca1996-07-10 15:48:25 +000057extern char *Py_GetVersion Py_PROTO((void));
58extern char *Py_GetCopyright Py_PROTO((void));
Jack Jansen696c9581995-08-14 12:33:20 +000059
60
Jack Jansen1d2f8631996-08-02 15:16:16 +000061/* For Py_GetProgramName(); set by main() */
Jack Jansen696c9581995-08-14 12:33:20 +000062static char *argv0;
63
Jack Jansen1d2f8631996-08-02 15:16:16 +000064/* For Py_GetArgcArgv(); set by main() */
Jack Jansen696c9581995-08-14 12:33:20 +000065static 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 Jansen76ceece1996-08-19 11:18:24 +000072static void Py_Main Py_PROTO((int, char **)); /* Forward */
73void PyMac_Exit Py_PROTO((int)); /* Forward */
74
Jack Jansen01fbc681996-02-28 15:42:47 +000075/* Initialize the Mac toolbox world */
76
77static void
78init_mac_world()
79{
80#ifdef THINK_C
81 printf("\n");
82#else
83 MaxApplZone();
84 InitGraf(&qd.thePort);
85 InitFonts();
86 InitWindows();
87 TEInit();
88 InitDialogs((long)0);
89 InitMenus();
90 InitCursor();
91#endif
92}
93
94/* Initialization code shared by interpreter and applets */
95
96static void
97init_common()
98{
99
100 /* Initialize toolboxes */
101 init_mac_world();
102
103#ifdef USE_MAC_SHARED_LIBRARY
104 /* Add the shared library to the stack of resource files */
105 PyMac_AddLibResources();
106#endif
107
108#if defined(USE_GUSI)
109 /* Setup GUSI */
110 GUSIDefaultSetup();
111#endif
112
113#ifdef USE_SIOUX
114 /* Set various SIOUX flags. Some are changed later based on options */
115 SIOUXSettings.asktosaveonclose = 0;
116 SIOUXSettings.showstatusline = 0;
117 SIOUXSettings.tabspaces = 4;
118#endif
119
120}
121
122
Jack Jansen696c9581995-08-14 12:33:20 +0000123#ifdef USE_MAC_APPLET_SUPPORT
124/* Applet support */
125
126/* Run a compiled Python Python script from 'PYC ' resource __main__ */
127static int
128run_main_resource()
129{
130 Handle h;
131 long size;
132 PyObject *code;
133 PyObject *result;
134
135 h = GetNamedResource('PYC ', "\p__main__");
136 if (h == NULL) {
137 Alert(NOPYC_ALERT, NULL);
138 return 1;
139 }
140 size = GetResourceSizeOnDisk(h);
141 HLock(h);
142 code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
143 HUnlock(h);
144 ReleaseResource(h);
145 if (code == NULL) {
146 PyErr_Print();
147 return 1;
148 }
149 result = PyImport_ExecCodeModule("__main__", code);
150 Py_DECREF(code);
151 if (result == NULL) {
152 PyErr_Print();
153 return 1;
154 }
155 Py_DECREF(result);
156 return 0;
157}
158
159/* Initialization sequence for applets */
160void
161PyMac_InitApplet()
162{
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000163 int argc;
164 char **argv;
Jack Jansen696c9581995-08-14 12:33:20 +0000165 int err;
166
Jack Jansen01fbc681996-02-28 15:42:47 +0000167 init_common();
Jack Jansen696c9581995-08-14 12:33:20 +0000168 argc = PyMac_GetArgv(&argv);
169 Py_Initialize();
170 PySys_SetArgv(argc, argv);
171 err = run_main_resource();
172 fflush(stderr);
173 fflush(stdout);
Jack Jansen0168f271995-10-27 13:32:30 +0000174 PyMac_Exit(err);
Jack Jansen696c9581995-08-14 12:33:20 +0000175 /* XXX Should we bother to Py_Exit(sts)? */
176}
177
178#endif /* USE_MAC_APPLET_SUPPORT */
179
180/* For normal application */
181void
182PyMac_InitApplication()
183{
184 int argc;
185 char **argv;
186
Jack Jansen01fbc681996-02-28 15:42:47 +0000187 init_common();
Jack Jansen696c9581995-08-14 12:33:20 +0000188 argc = PyMac_GetArgv(&argv);
189 if ( argc > 1 ) {
190 /* We're running a script. Attempt to change current directory */
191 char curwd[256], *endp;
192
193 strcpy(curwd, argv[1]);
194 endp = strrchr(curwd, ':');
195 if ( endp && endp > curwd ) {
196 *endp = '\0';
197
198 chdir(curwd);
Jack Jansen378815c1996-03-06 16:21:34 +0000199#ifdef USE_GUSI
200 /* Change MacOS's idea of wd too */
201 PyMac_FixGUSIcd();
202#endif
Jack Jansen696c9581995-08-14 12:33:20 +0000203 }
204 }
205 Py_Main(argc, argv);
206}
207
208/*
209** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
210*/
211void
212PyMac_InteractiveOptions(int *inspect, int *verbose, int *suppress_print,
Jack Jansen0168f271995-10-27 13:32:30 +0000213 int *unbuffered, int *debugging, int *keep_normal,
Jack Jansene355c451996-03-12 13:29:04 +0000214 int *keep_error, int *argcp, char ***argvp)
Jack Jansen696c9581995-08-14 12:33:20 +0000215{
216 KeyMap rmap;
217 unsigned char *map;
218 short item, type;
219 ControlHandle handle;
220 DialogPtr dialog;
221 Rect rect;
Jack Jansene355c451996-03-12 13:29:04 +0000222 int old_argc = *argcp;
223 int i;
Jack Jansen696c9581995-08-14 12:33:20 +0000224
Jack Jansena4b7e141996-02-21 16:46:57 +0000225 /* Default-defaults: */
226 *keep_error = 1;
227 /* Get default settings from our preference file */
Jack Jansen01fbc681996-02-28 15:42:47 +0000228 PyMac_PreferenceOptions(inspect, verbose, suppress_print,
229 unbuffered, debugging, keep_normal, keep_error);
Jack Jansena4b7e141996-02-21 16:46:57 +0000230 /* If option is pressed override these */
Jack Jansen696c9581995-08-14 12:33:20 +0000231 GetKeys(rmap);
232 map = (unsigned char *)rmap;
233 if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
234 return;
235
236 dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
237 if ( dialog == NULL ) {
238 printf("Option dialog not found - cannot set options\n");
239 return;
240 }
Jack Jansene355c451996-03-12 13:29:04 +0000241 SetDialogDefaultItem(dialog, OPT_OK);
242 SetDialogCancelItem(dialog, OPT_CANCEL);
Jack Jansen0168f271995-10-27 13:32:30 +0000243
Jack Jansena4b7e141996-02-21 16:46:57 +0000244 /* Set default values */
245#define SET_OPT_ITEM(num, var) \
246 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
247 SetCtlValue(handle, (short)*(var));
248
249 SET_OPT_ITEM(OPT_INSPECT, inspect);
250 SET_OPT_ITEM(OPT_VERBOSE, verbose);
251 SET_OPT_ITEM(OPT_SUPPRESS, suppress_print);
252 SET_OPT_ITEM(OPT_UNBUFFERED, unbuffered);
253 SET_OPT_ITEM(OPT_DEBUGGING, debugging);
254 SET_OPT_ITEM(OPT_KEEPNORMAL, keep_normal);
255 SET_OPT_ITEM(OPT_KEEPERROR, keep_error);
256
257#undef SET_OPT_ITEM
Jack Jansen0168f271995-10-27 13:32:30 +0000258
Jack Jansen696c9581995-08-14 12:33:20 +0000259 while (1) {
260 handle = NULL;
261 ModalDialog(NULL, &item);
262 if ( item == OPT_OK )
263 break;
264 if ( item == OPT_CANCEL ) {
265 DisposDialog(dialog);
266 exit(0);
267 }
Jack Jansene355c451996-03-12 13:29:04 +0000268 if ( item == OPT_CMDLINE ) {
269 int new_argc, newer_argc;
270 char **new_argv, **newer_argv;
271
272 new_argc = ccommand(&new_argv);
273 newer_argc = (new_argc-1) + old_argc;
274 newer_argv = malloc((newer_argc+1)*sizeof(char *));
275 if( !newer_argv )
276 Py_FatalError("Cannot malloc argv\n");
277 for(i=0; i<old_argc; i++)
278 newer_argv[i] = (*argvp)[i];
279 for(i=old_argc; i<=newer_argc; i++) /* Copy the NULL too */
280 newer_argv[i] = new_argv[i-old_argc+1];
281 *argvp = newer_argv;
282 *argcp = newer_argc;
283
284 /* XXXX Is it not safe to use free() here, apparently */
285 }
Jack Jansen696c9581995-08-14 12:33:20 +0000286#define OPT_ITEM(num, var) \
287 if ( item == (num) ) { \
288 *(var) = !*(var); \
289 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
290 SetCtlValue(handle, (short)*(var)); \
291 }
292
293 OPT_ITEM(OPT_INSPECT, inspect);
294 OPT_ITEM(OPT_VERBOSE, verbose);
295 OPT_ITEM(OPT_SUPPRESS, suppress_print);
296 OPT_ITEM(OPT_UNBUFFERED, unbuffered);
297 OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen0168f271995-10-27 13:32:30 +0000298 OPT_ITEM(OPT_KEEPNORMAL, keep_normal);
299 OPT_ITEM(OPT_KEEPERROR, keep_error);
Jack Jansen696c9581995-08-14 12:33:20 +0000300
301#undef OPT_ITEM
302 }
303 DisposDialog(dialog);
304}
305/* Main program */
306
Jack Jansen76ceece1996-08-19 11:18:24 +0000307static void
Jack Jansen696c9581995-08-14 12:33:20 +0000308Py_Main(argc, argv)
309 int argc;
310 char **argv;
311{
Jack Jansen696c9581995-08-14 12:33:20 +0000312 int sts;
313 char *command = NULL;
314 char *filename = NULL;
315 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000316 int inspect = 0;
317 int unbuffered = 0;
318
Jack Jansene355c451996-03-12 13:29:04 +0000319 PyMac_InteractiveOptions(&inspect, &Py_VerboseFlag, &Py_SuppressPrintingFlag,
320 &unbuffered, &Py_DebugFlag, &keep_normal, &keep_error, &argc, &argv);
321
Jack Jansen1d2f8631996-08-02 15:16:16 +0000322 orig_argc = argc; /* For Py_GetArgcArgv() */
Jack Jansen696c9581995-08-14 12:33:20 +0000323 orig_argv = argv;
Jack Jansen1d2f8631996-08-02 15:16:16 +0000324 argv0 = argv[0]; /* For Py_GetProgramName() */
Jack Jansen696c9581995-08-14 12:33:20 +0000325
326 if (unbuffered) {
327#ifndef MPW
328 setbuf(stdout, (char *)NULL);
329 setbuf(stderr, (char *)NULL);
330#else
331 /* On MPW (3.2) unbuffered seems to hang */
332 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
333 setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
334#endif
335 }
336
337 filename = argv[1];
338
339 if (Py_VerboseFlag ||
340 command == NULL && filename == NULL && isatty((int)fileno(fp)))
341 fprintf(stderr, "Python %s\n%s\n",
Jack Jansena547dca1996-07-10 15:48:25 +0000342 Py_GetVersion(), Py_GetCopyright());
Jack Jansen696c9581995-08-14 12:33:20 +0000343
344 if (filename != NULL) {
345 if ((fp = fopen(filename, "r")) == NULL) {
346 fprintf(stderr, "%s: can't open file '%s'\n",
347 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000348 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000349 }
350 }
351
352 Py_Initialize();
353
354 PySys_SetArgv(argc-1, argv+1);
355
356 if (filename == NULL && isatty((int)fileno(fp))) {
357 FILE *fp = fopen(STARTUP, "r");
358 if (fp != NULL) {
359 (void) PyRun_SimpleFile(fp, STARTUP);
360 PyErr_Clear();
361 fclose(fp);
362 }
363 }
364 sts = PyRun_AnyFile(
365 fp, filename == NULL ? "<stdin>" : filename) != 0;
366 if (filename != NULL)
367 fclose(fp);
368
369 if (inspect && isatty((int)fileno(stdin)) &&
370 (filename != NULL || command != NULL))
371 sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
372
373 Py_Exit(sts);
374 /*NOTREACHED*/
375}
376
Jack Jansen0168f271995-10-27 13:32:30 +0000377/*
378** Terminate application
379*/
Jack Jansen76ceece1996-08-19 11:18:24 +0000380void
Jack Jansen0168f271995-10-27 13:32:30 +0000381PyMac_Exit(status)
382 int status;
383{
384 int keep;
385
386 if ( status )
387 keep = keep_error;
388 else
389 keep = keep_normal;
390
Jack Jansen1e8557a1995-11-10 14:51:26 +0000391#ifdef USE_SIOUX
392 if (keep) {
393 SIOUXSettings.standalone = 1;
394 SIOUXSettings.autocloseonquit = 0;
Jack Jansen415571c1996-03-25 15:46:03 +0000395 SIOUXSetTitle("\p\307terminated\310");
Jack Jansen1e8557a1995-11-10 14:51:26 +0000396 }
Jack Jansen0168f271995-10-27 13:32:30 +0000397 else
398 SIOUXSettings.autocloseonquit = 1;
399#endif
400#ifdef THINK_C
401 console_options.pause_atexit = keep;
402#endif
403
404 exit(status);
405}
Jack Jansen696c9581995-08-14 12:33:20 +0000406
407/* Return the program name -- some code out there needs this. */
408
409char *
Jack Jansen1d2f8631996-08-02 15:16:16 +0000410Py_GetProgramName()
Jack Jansen696c9581995-08-14 12:33:20 +0000411{
412 return argv0;
413}
414
415
416/* Make the *original* argc/argv available to other modules.
417 This is rare, but it is needed by the secureware extension. */
418
419void
Jack Jansen1d2f8631996-08-02 15:16:16 +0000420Py_GetArgcArgv(argc,argv)
Jack Jansen696c9581995-08-14 12:33:20 +0000421 int *argc;
422 char ***argv;
423{
424 *argc = orig_argc;
425 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000426}
Jack Jansen1d2f8631996-08-02 15:16:16 +0000427
428/* More cruft that shouldn't really be here, used in sysmodule.c */
429
430char *
431Py_GetPrefix()
432{
433 return "";
434}
435
436char *
437Py_GetExecPrefix()
438{
439 return "";
440}