blob: 1bcc083b61a47750d7af9b7387ef797daad40f7d [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001/***********************************************************
2Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
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
25/* Python interpreter top-level routines, including init/exit */
26
27#include "allobjects.h"
28
29#include "grammar.h"
30#include "node.h"
31#include "parsetok.h"
32#include "graminit.h"
33#include "errcode.h"
34#include "sysmodule.h"
35#include "compile.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000036#include "eval.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000037#include "ceval.h"
38#include "pythonrun.h"
39#include "import.h"
40
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000041#ifdef unix
42#define HANDLE_SIGNALS
43#endif
44
45#ifdef HANDLE_SIGNALS
46#include <signal.h>
47#include "sigtype.h"
48#endif
49
Guido van Rossum1984f1e1992-08-04 12:41:02 +000050extern char *getpythonpath();
51
52extern grammar gram; /* From graminit.c */
53
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000054void initsigs(); /* Forward */
55
Guido van Rossum1984f1e1992-08-04 12:41:02 +000056int debugging; /* Needed by parser.c */
57int verbose; /* Needed by import.c */
58
59/* Initialize all */
60
61void
62initall()
63{
64 static int inited;
65
66 if (inited)
67 return;
68 inited = 1;
69
70 initimport();
71
72 /* Modules 'builtin' and 'sys' are initialized here,
73 they are needed by random bits of the interpreter.
74 All other modules are optional and are initialized
75 when they are first imported. */
76
77 initbuiltin(); /* Also initializes builtin exceptions */
78 initsys();
79
80 initcalls(); /* Configuration-dependent initializations */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000081
82 setpythonpath(getpythonpath());
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000083
84 initsigs(); /* Signal handling stuff, including initintr() */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000085}
86
87/* Parse input from a file and execute it */
88
89int
90run(fp, filename)
91 FILE *fp;
92 char *filename;
93{
94 if (filename == NULL)
95 filename = "???";
96 if (isatty((int)fileno(fp)))
97 return run_tty_loop(fp, filename);
98 else
99 return run_script(fp, filename);
100}
101
102int
103run_tty_loop(fp, filename)
104 FILE *fp;
105 char *filename;
106{
107 object *v;
108 int ret;
109 v = sysget("ps1");
110 if (v == NULL) {
111 sysset("ps1", v = newstringobject(">>> "));
112 XDECREF(v);
113 }
114 v = sysget("ps2");
115 if (v == NULL) {
116 sysset("ps2", v = newstringobject("... "));
117 XDECREF(v);
118 }
119 for (;;) {
120 ret = run_tty_1(fp, filename);
121#ifdef REF_DEBUG
122 fprintf(stderr, "[%ld refs]\n", ref_total);
123#endif
124 if (ret == E_EOF)
125 return 0;
126 /*
127 if (ret == E_NOMEM)
128 return -1;
129 */
130 }
131}
132
133int
134run_tty_1(fp, filename)
135 FILE *fp;
136 char *filename;
137{
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000138 object *m, *d, *v, *w;
139 node *n;
140 char *ps1, *ps2;
141 int err;
142 v = sysget("ps1");
143 w = sysget("ps2");
144 if (v != NULL && is_stringobject(v)) {
145 INCREF(v);
146 ps1 = getstringvalue(v);
147 }
148 else {
149 v = NULL;
150 ps1 = "";
151 }
152 if (w != NULL && is_stringobject(w)) {
153 INCREF(w);
154 ps2 = getstringvalue(w);
155 }
156 else {
157 w = NULL;
158 ps2 = "";
159 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000160 BGN_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000161 err = parsefile(fp, filename, &gram, single_input, ps1, ps2, &n);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000162 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000163 XDECREF(v);
164 XDECREF(w);
165 if (err == E_EOF)
166 return E_EOF;
167 if (err != E_DONE) {
168 err_input(err);
169 print_error();
170 return err;
171 }
172 m = add_module("__main__");
173 if (m == NULL)
174 return -1;
175 d = getmoduledict(m);
176 v = run_node(n, filename, d, d);
177 flushline();
178 if (v == NULL) {
179 print_error();
180 return -1;
181 }
182 DECREF(v);
183 return 0;
184}
185
186int
187run_script(fp, filename)
188 FILE *fp;
189 char *filename;
190{
191 object *m, *d, *v;
192 m = add_module("__main__");
193 if (m == NULL)
194 return -1;
195 d = getmoduledict(m);
196 v = run_file(fp, filename, file_input, d, d);
197 flushline();
198 if (v == NULL) {
199 print_error();
200 return -1;
201 }
202 DECREF(v);
203 return 0;
204}
205
206int
207run_command(command)
208 char *command;
209{
210 object *m, *d, *v;
211 m = add_module("__main__");
212 if (m == NULL)
213 return -1;
214 d = getmoduledict(m);
215 v = run_string(command, file_input, d, d);
216 flushline();
217 if (v == NULL) {
218 print_error();
219 return -1;
220 }
221 DECREF(v);
222 return 0;
223}
224
225void
226print_error()
227{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000228 object *exception, *v, *f;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000229 err_get(&exception, &v);
230 if (exception == SystemExit) {
231 if (v == NULL || v == None)
232 goaway(0);
233 if (is_intobject(v))
234 goaway((int)getintvalue(v));
235 else {
Guido van Rossum3165fe61992-09-25 21:59:05 +0000236 /* OK to use real stderr here */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000237 printobject(v, stderr, PRINT_RAW);
238 fprintf(stderr, "\n");
239 goaway(1);
240 }
241 }
242 sysset("last_type", exception);
243 sysset("last_value", v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000244 f = sysget("stderr");
245 if (f == NULL)
246 fprintf(stderr, "lost sys.stderr\n");
247 else {
248 if (writeobject(exception, f, PRINT_RAW) != 0)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000249 err_clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000250 if (v != NULL && v != None) {
251 writestring(": ", f);
252 if (writeobject(v, f, PRINT_RAW) != 0)
253 err_clear();
254 }
255 writestring("\n", f);
256 printtraceback(f);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000257 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000258 XDECREF(exception);
259 XDECREF(v);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000260}
261
262object *
263run_string(str, start, globals, locals)
264 char *str;
265 int start;
266 /*dict*/object *globals, *locals;
267{
268 node *n;
269 int err;
270 err = parse_string(str, start, &n);
271 return run_err_node(err, n, "<string>", globals, locals);
272}
273
274object *
275run_file(fp, filename, start, globals, locals)
276 FILE *fp;
277 char *filename;
278 int start;
279 /*dict*/object *globals, *locals;
280{
281 node *n;
282 int err;
283 err = parse_file(fp, filename, start, &n);
284 return run_err_node(err, n, filename, globals, locals);
285}
286
287object *
288run_err_node(err, n, filename, globals, locals)
289 int err;
290 node *n;
291 char *filename;
292 /*dict*/object *globals, *locals;
293{
294 if (err != E_DONE) {
295 err_input(err);
296 return NULL;
297 }
298 return run_node(n, filename, globals, locals);
299}
300
301object *
302run_node(n, filename, globals, locals)
303 node *n;
304 char *filename;
305 /*dict*/object *globals, *locals;
306{
307 if (globals == NULL) {
308 globals = getglobals();
309 if (locals == NULL)
310 locals = getlocals();
311 }
312 else {
313 if (locals == NULL)
314 locals = globals;
315 }
316 return eval_node(n, filename, globals, locals);
317}
318
319object *
320eval_node(n, filename, globals, locals)
321 node *n;
322 char *filename;
323 object *globals;
324 object *locals;
325{
326 codeobject *co;
327 object *v;
328 co = compile(n, filename);
329 freetree(n);
330 if (co == NULL)
331 return NULL;
332 v = eval_code(co, globals, locals, (object *)NULL);
333 DECREF(co);
334 return v;
335}
336
337/* Simplified interface to parsefile */
338
339int
340parse_file(fp, filename, start, n_ret)
341 FILE *fp;
342 char *filename;
343 int start;
344 node **n_ret;
345{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000346 int ret;
347 BGN_SAVE
348 ret = parsefile(fp, filename, &gram, start,
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000349 (char *)0, (char *)0, n_ret);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000350 END_SAVE
351 return ret;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000352}
353
354/* Simplified interface to parsestring */
355
356int
357parse_string(str, start, n_ret)
358 char *str;
359 int start;
360 node **n_ret;
361{
362 int err = parsestring(str, &gram, start, n_ret);
363 /* Don't confuse early end of string with early end of input */
364 if (err == E_EOF)
365 err = E_SYNTAX;
366 return err;
367}
368
369/* Print fatal error message and abort */
370
371void
372fatal(msg)
373 char *msg;
374{
375 fprintf(stderr, "Fatal error: %s\n", msg);
376 abort();
377}
378
379/* Clean up and exit */
380
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000381#ifdef USE_THREAD
382extern int threads_started;
383#endif
384
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000385void
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000386cleanup()
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000387{
Guido van Rossum59bff391992-09-03 20:28:00 +0000388 object *exitfunc = sysget("exitfunc");
389
390 if (exitfunc) {
391 object *arg;
392 object *res;
393 sysset("exitfunc", (object *)NULL);
394 arg = newtupleobject(0);
395 if (arg == NULL)
396 res = NULL;
397 else {
398 res = call_object(exitfunc, arg);
399 DECREF(arg);
400 }
401 if (res == NULL) {
402 fprintf(stderr, "Error in sys.exitfunc:\n");
403 print_error();
404 }
405 }
406
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000407 flushline();
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000408}
409
410void
411goaway(sts)
412 int sts;
413{
414 cleanup();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000415
416#ifdef USE_THREAD
417
418 /* Other threads may still be active, so skip most of the
419 cleanup actions usually done (these are mostly for
420 debugging anyway). */
421
Guido van Rossumdf72a651992-08-12 15:27:32 +0000422 (void) save_thread();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000423 donecalls();
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000424 if (threads_started)
425 _exit_prog(sts);
426 else
427 exit_prog(sts);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000428
429#else /* USE_THREAD */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000430
431 /* XXX Call doneimport() before donecalls(), since donecalls()
432 calls wdone(), and doneimport() may close windows */
433 doneimport();
434 donecalls();
435
436 err_clear();
437
438#ifdef REF_DEBUG
439 fprintf(stderr, "[%ld refs]\n", ref_total);
440#endif
441
442#ifdef TRACE_REFS
443 if (askyesno("Print left references?")) {
444 printrefs(stderr);
445 }
446#endif /* TRACE_REFS */
447
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000448 exit(sts);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000449#endif /* USE_THREAD */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000450 /*NOTREACHED*/
451}
452
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000453#ifdef HANDLE_SIGNALS
454SIGTYPE
455sighandler(sig)
456 int sig;
457{
458 signal(sig, SIG_DFL); /* Don't catch recursive signals */
459 cleanup(); /* Do essential clean-up */
460 kill(getpid(), sig); /* Pretend the signal killed us */
461 /*NOTREACHED*/
462}
463#endif
464
465void
466initsigs()
467{
468 initintr();
469#ifdef HANDLE_SIGNALS
470 if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
471 signal(SIGHUP, sighandler);
472 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
473 signal(SIGTERM, sighandler);
474#endif
475}
476
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000477#ifdef TRACE_REFS
478/* Ask a yes/no question */
479
Guido van Rossum59bff391992-09-03 20:28:00 +0000480int
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000481askyesno(prompt)
482 char *prompt;
483{
484 char buf[256];
485
486 printf("%s [ny] ", prompt);
487 if (fgets(buf, sizeof buf, stdin) == NULL)
488 return 0;
489 return buf[0] == 'y' || buf[0] == 'Y';
490}
491#endif
492
493#ifdef applec /* MPW (also usable for Think C 3.0) */
494
495/* Check for file descriptor connected to interactive device.
496 Pretend that stdin is always interactive, other files never. */
497
498int
499isatty(fd)
500 int fd;
501{
502 return fd == fileno(stdin);
503}
504
505#endif