blob: f6b1dee4d9f6ace7d2a5bc50cb0a3a82fa0c81d4 [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 Jansen696c9581995-08-14 12:33:20 +000071#ifdef USE_MAC_APPLET_SUPPORT
72/* Applet support */
73
74/* Run a compiled Python Python script from 'PYC ' resource __main__ */
75static int
76run_main_resource()
77{
78 Handle h;
79 long size;
80 PyObject *code;
81 PyObject *result;
82
83 h = GetNamedResource('PYC ', "\p__main__");
84 if (h == NULL) {
85 Alert(NOPYC_ALERT, NULL);
86 return 1;
87 }
88 size = GetResourceSizeOnDisk(h);
89 HLock(h);
90 code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
91 HUnlock(h);
92 ReleaseResource(h);
93 if (code == NULL) {
94 PyErr_Print();
95 return 1;
96 }
97 result = PyImport_ExecCodeModule("__main__", code);
98 Py_DECREF(code);
99 if (result == NULL) {
100 PyErr_Print();
101 return 1;
102 }
103 Py_DECREF(result);
104 return 0;
105}
106
107/* Initialization sequence for applets */
108void
109PyMac_InitApplet()
110{
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000111 int argc;
112 char **argv;
Jack Jansen696c9581995-08-14 12:33:20 +0000113 int err;
114
Jack Jansenf950f8d1995-02-13 11:35:34 +0000115#ifdef USE_MAC_SHARED_LIBRARY
116 PyMac_AddLibResources();
117#endif
Jack Jansen1e8557a1995-11-10 14:51:26 +0000118#ifdef USE_SIOUX
Jack Jansenf950f8d1995-02-13 11:35:34 +0000119 SIOUXSettings.asktosaveonclose = 0;
120 SIOUXSettings.showstatusline = 0;
121 SIOUXSettings.tabspaces = 4;
122#endif
Jack Jansen696c9581995-08-14 12:33:20 +0000123 argc = PyMac_GetArgv(&argv);
124 Py_Initialize();
125 PySys_SetArgv(argc, argv);
126 err = run_main_resource();
127 fflush(stderr);
128 fflush(stdout);
Jack Jansen0168f271995-10-27 13:32:30 +0000129 PyMac_Exit(err);
Jack Jansen696c9581995-08-14 12:33:20 +0000130 /* XXX Should we bother to Py_Exit(sts)? */
131}
132
133#endif /* USE_MAC_APPLET_SUPPORT */
134
135/* For normal application */
136void
137PyMac_InitApplication()
138{
139 int argc;
140 char **argv;
141
142#ifdef USE_MAC_SHARED_LIBRARY
143 PyMac_AddLibResources();
144#endif
Jack Jansen1e8557a1995-11-10 14:51:26 +0000145#ifdef USE_SIOUX
Jack Jansen696c9581995-08-14 12:33:20 +0000146 SIOUXSettings.asktosaveonclose = 0;
147 SIOUXSettings.showstatusline = 0;
148 SIOUXSettings.tabspaces = 4;
149#endif
150 argc = PyMac_GetArgv(&argv);
151 if ( argc > 1 ) {
152 /* We're running a script. Attempt to change current directory */
153 char curwd[256], *endp;
154
155 strcpy(curwd, argv[1]);
156 endp = strrchr(curwd, ':');
157 if ( endp && endp > curwd ) {
158 *endp = '\0';
159
160 chdir(curwd);
161 }
162 }
163 Py_Main(argc, argv);
164}
165
166/*
167** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
168*/
169void
170PyMac_InteractiveOptions(int *inspect, int *verbose, int *suppress_print,
Jack Jansen0168f271995-10-27 13:32:30 +0000171 int *unbuffered, int *debugging, int *keep_normal,
172 int *keep_error)
Jack Jansen696c9581995-08-14 12:33:20 +0000173{
174 KeyMap rmap;
175 unsigned char *map;
176 short item, type;
177 ControlHandle handle;
178 DialogPtr dialog;
179 Rect rect;
180
181 GetKeys(rmap);
182 map = (unsigned char *)rmap;
183 if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
184 return;
185
186 dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
187 if ( dialog == NULL ) {
188 printf("Option dialog not found - cannot set options\n");
189 return;
190 }
Jack Jansen0168f271995-10-27 13:32:30 +0000191
192 /* Set keep-open-on-error */
193 GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
194 SetCtlValue(handle, *keep_error);
195
Jack Jansen696c9581995-08-14 12:33:20 +0000196 while (1) {
197 handle = NULL;
198 ModalDialog(NULL, &item);
199 if ( item == OPT_OK )
200 break;
201 if ( item == OPT_CANCEL ) {
202 DisposDialog(dialog);
203 exit(0);
204 }
205#define OPT_ITEM(num, var) \
206 if ( item == (num) ) { \
207 *(var) = !*(var); \
208 GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
209 SetCtlValue(handle, (short)*(var)); \
210 }
211
212 OPT_ITEM(OPT_INSPECT, inspect);
213 OPT_ITEM(OPT_VERBOSE, verbose);
214 OPT_ITEM(OPT_SUPPRESS, suppress_print);
215 OPT_ITEM(OPT_UNBUFFERED, unbuffered);
216 OPT_ITEM(OPT_DEBUGGING, debugging);
Jack Jansen0168f271995-10-27 13:32:30 +0000217 OPT_ITEM(OPT_KEEPNORMAL, keep_normal);
218 OPT_ITEM(OPT_KEEPERROR, keep_error);
Jack Jansen696c9581995-08-14 12:33:20 +0000219
220#undef OPT_ITEM
221 }
222 DisposDialog(dialog);
223}
224/* Main program */
225
226int
227Py_Main(argc, argv)
228 int argc;
229 char **argv;
230{
Jack Jansen696c9581995-08-14 12:33:20 +0000231 int sts;
232 char *command = NULL;
233 char *filename = NULL;
234 FILE *fp = stdin;
Jack Jansen696c9581995-08-14 12:33:20 +0000235 int inspect = 0;
236 int unbuffered = 0;
237
238 orig_argc = argc; /* For getargcargv() */
239 orig_argv = argv;
240 argv0 = argv[0]; /* For getprogramname() */
241
242 PyMac_InteractiveOptions(&inspect, &Py_VerboseFlag, &Py_SuppressPrintingFlag,
Jack Jansen0168f271995-10-27 13:32:30 +0000243 &unbuffered, &Py_DebugFlag, &keep_normal, &keep_error);
Jack Jansen696c9581995-08-14 12:33:20 +0000244
245 if (unbuffered) {
246#ifndef MPW
247 setbuf(stdout, (char *)NULL);
248 setbuf(stderr, (char *)NULL);
249#else
250 /* On MPW (3.2) unbuffered seems to hang */
251 setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
252 setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
253#endif
254 }
255
256 filename = argv[1];
257
258 if (Py_VerboseFlag ||
259 command == NULL && filename == NULL && isatty((int)fileno(fp)))
260 fprintf(stderr, "Python %s\n%s\n",
261 getversion(), getcopyright());
262
263 if (filename != NULL) {
264 if ((fp = fopen(filename, "r")) == NULL) {
265 fprintf(stderr, "%s: can't open file '%s'\n",
266 argv[0], filename);
Jack Jansen0168f271995-10-27 13:32:30 +0000267 PyMac_Exit(2);
Jack Jansen696c9581995-08-14 12:33:20 +0000268 }
269 }
270
271 Py_Initialize();
272
273 PySys_SetArgv(argc-1, argv+1);
274
275 if (filename == NULL && isatty((int)fileno(fp))) {
276 FILE *fp = fopen(STARTUP, "r");
277 if (fp != NULL) {
278 (void) PyRun_SimpleFile(fp, STARTUP);
279 PyErr_Clear();
280 fclose(fp);
281 }
282 }
283 sts = PyRun_AnyFile(
284 fp, filename == NULL ? "<stdin>" : filename) != 0;
285 if (filename != NULL)
286 fclose(fp);
287
288 if (inspect && isatty((int)fileno(stdin)) &&
289 (filename != NULL || command != NULL))
290 sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
291
292 Py_Exit(sts);
293 /*NOTREACHED*/
294}
295
Jack Jansen0168f271995-10-27 13:32:30 +0000296/*
297** Terminate application
298*/
299PyMac_Exit(status)
300 int status;
301{
302 int keep;
303
304 if ( status )
305 keep = keep_error;
306 else
307 keep = keep_normal;
308
Jack Jansen1e8557a1995-11-10 14:51:26 +0000309#ifdef USE_SIOUX
310 if (keep) {
311 SIOUXSettings.standalone = 1;
312 SIOUXSettings.autocloseonquit = 0;
313 SIOUXSetTitle("\pÇterminatedÈ");
314 }
Jack Jansen0168f271995-10-27 13:32:30 +0000315 else
316 SIOUXSettings.autocloseonquit = 1;
317#endif
318#ifdef THINK_C
319 console_options.pause_atexit = keep;
320#endif
321
322 exit(status);
323}
Jack Jansen696c9581995-08-14 12:33:20 +0000324
325/* Return the program name -- some code out there needs this. */
326
327char *
328getprogramname()
329{
330 return argv0;
331}
332
333
334/* Make the *original* argc/argv available to other modules.
335 This is rare, but it is needed by the secureware extension. */
336
337void
338getargcargv(argc,argv)
339 int *argc;
340 char ***argv;
341{
342 *argc = orig_argc;
343 *argv = orig_argv;
Guido van Rossumb0f3c821994-08-23 13:34:25 +0000344}