blob: 8387eed027bc5610c48b2bd3a43c68838eada78e [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001/***********************************************************
Guido van Rossuma110aa61994-08-29 12:50:44 +00002Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Guido van Rossum9bfef441993-03-29 10:43:31 +00003Amsterdam, The Netherlands.
Guido van Rossum1984f1e1992-08-04 12:41:02 +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
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 Rossuma110aa61994-08-29 12:50:44 +000041#ifdef HAVE_SIGNAL_H
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000042#include <signal.h>
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000043#endif
44
Guido van Rossum1984f1e1992-08-04 12:41:02 +000045extern char *getpythonpath();
46
47extern grammar gram; /* From graminit.c */
48
Guido van Rossumb73cc041993-11-01 16:28:59 +000049/* Forward */
Guido van Rossuma110aa61994-08-29 12:50:44 +000050static object *run_err_node PROTO((node *n, char *filename,
Guido van Rossumb73cc041993-11-01 16:28:59 +000051 object *globals, object *locals));
52static object *run_node PROTO((node *n, char *filename,
53 object *globals, object *locals));
Guido van Rossuma110aa61994-08-29 12:50:44 +000054static void err_input PROTO((perrdetail *));
Guido van Rossumb376a4a1993-11-23 17:53:17 +000055static void initsigs PROTO((void));
Guido van Rossuma9e7dc11992-10-18 18:53:57 +000056
Guido van Rossum1984f1e1992-08-04 12:41:02 +000057int debugging; /* Needed by parser.c */
58int verbose; /* Needed by import.c */
Guido van Rossuma110aa61994-08-29 12:50:44 +000059int suppress_print; /* Needed by ceval.c */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000060
61/* Initialize all */
62
63void
64initall()
65{
66 static int inited;
67
68 if (inited)
69 return;
70 inited = 1;
71
72 initimport();
73
Guido van Rossuma110aa61994-08-29 12:50:44 +000074 /* Modules '__builtin__' and 'sys' are initialized here,
Guido van Rossum1984f1e1992-08-04 12:41:02 +000075 they are needed by random bits of the interpreter.
76 All other modules are optional and are initialized
77 when they are first imported. */
78
79 initbuiltin(); /* Also initializes builtin exceptions */
80 initsys();
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;
Guido van Rossuma110aa61994-08-29 12:50:44 +0000140 perrdetail err;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000141 char *ps1, *ps2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000142 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 Rossuma110aa61994-08-29 12:50:44 +0000161 n = parsefile(fp, filename, &gram, single_input, ps1, ps2, &err);
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);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000165 if (n == NULL) {
166 if (err.error == E_EOF) {
167 if (err.text)
168 free(err.text);
169 return E_EOF;
170 }
171 err_input(&err);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000172 print_error();
Guido van Rossuma110aa61994-08-29 12:50:44 +0000173 return err.error;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000174 }
175 m = add_module("__main__");
176 if (m == NULL)
177 return -1;
178 d = getmoduledict(m);
179 v = run_node(n, filename, d, d);
180 flushline();
181 if (v == NULL) {
182 print_error();
183 return -1;
184 }
185 DECREF(v);
186 return 0;
187}
188
189int
190run_script(fp, filename)
191 FILE *fp;
192 char *filename;
193{
194 object *m, *d, *v;
195 m = add_module("__main__");
196 if (m == NULL)
197 return -1;
198 d = getmoduledict(m);
199 v = run_file(fp, filename, file_input, d, d);
200 flushline();
201 if (v == NULL) {
202 print_error();
203 return -1;
204 }
205 DECREF(v);
206 return 0;
207}
208
209int
210run_command(command)
211 char *command;
212{
213 object *m, *d, *v;
214 m = add_module("__main__");
215 if (m == NULL)
216 return -1;
217 d = getmoduledict(m);
218 v = run_string(command, file_input, d, d);
219 flushline();
220 if (v == NULL) {
221 print_error();
222 return -1;
223 }
224 DECREF(v);
225 return 0;
226}
227
228void
229print_error()
230{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000231 object *exception, *v, *f;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000232 err_get(&exception, &v);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000233 if (exception == NULL) {
234 fprintf(stderr, "print_error called but no exception\n");
235 abort();
236 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000237 if (exception == SystemExit) {
238 if (v == NULL || v == None)
239 goaway(0);
240 if (is_intobject(v))
241 goaway((int)getintvalue(v));
242 else {
Guido van Rossum3165fe61992-09-25 21:59:05 +0000243 /* OK to use real stderr here */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000244 printobject(v, stderr, PRINT_RAW);
245 fprintf(stderr, "\n");
246 goaway(1);
247 }
248 }
249 sysset("last_type", exception);
250 sysset("last_value", v);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000251 f = sysget("stderr");
252 if (f == NULL)
253 fprintf(stderr, "lost sys.stderr\n");
254 else {
Guido van Rossum6ac258d1993-05-12 08:24:20 +0000255 printtraceback(f);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000256 if (exception == SyntaxError) {
257 object *message;
258 char *filename, *text;
259 int lineno, offset;
260 if (!getargs(v, "(O(ziiz))", &message,
261 &filename, &lineno, &offset, &text))
262 err_clear();
263 else {
264 char buf[10];
265 writestring(" File \"", f);
266 if (filename == NULL)
267 writestring("<string>", f);
268 else
269 writestring(filename, f);
270 writestring("\", line ", f);
271 sprintf(buf, "%d", lineno);
272 writestring(buf, f);
273 writestring("\n", f);
274 if (text != NULL) {
275 while (*text == ' ' || *text == '\t') {
276 text++;
277 offset--;
278 }
279 writestring(" ", f);
280 writestring(text, f);
281 if (*text == '\0' ||
282 text[strlen(text)-1] != '\n')
283 writestring("\n", f);
284 writestring(" ", f);
285 offset--;
286 while (offset > 0) {
287 writestring(" ", f);
288 offset--;
289 }
290 writestring("^\n", f);
291 }
292 INCREF(message);
293 DECREF(v);
294 v = message;
295 }
296 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000297 if (writeobject(exception, f, PRINT_RAW) != 0)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000298 err_clear();
Guido van Rossum3165fe61992-09-25 21:59:05 +0000299 if (v != NULL && v != None) {
300 writestring(": ", f);
301 if (writeobject(v, f, PRINT_RAW) != 0)
302 err_clear();
303 }
304 writestring("\n", f);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000305 }
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000306 XDECREF(exception);
307 XDECREF(v);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000308}
309
310object *
311run_string(str, start, globals, locals)
312 char *str;
313 int start;
Guido van Rossum5b722181993-03-30 17:46:03 +0000314 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000315{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000316 return run_err_node(parse_string(str, start),
317 "<string>", globals, locals);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000318}
319
320object *
321run_file(fp, filename, start, globals, locals)
322 FILE *fp;
323 char *filename;
324 int start;
Guido van Rossum5b722181993-03-30 17:46:03 +0000325 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000326{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000327 return run_err_node(parse_file(fp, filename, start),
328 filename, globals, locals);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000329}
330
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000331static object *
Guido van Rossuma110aa61994-08-29 12:50:44 +0000332run_err_node(n, filename, globals, locals)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000333 node *n;
334 char *filename;
Guido van Rossum5b722181993-03-30 17:46:03 +0000335 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000336{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000337 if (n == NULL)
338 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000339 return run_node(n, filename, globals, locals);
340}
341
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000342static object *
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000343run_node(n, filename, globals, locals)
344 node *n;
345 char *filename;
Guido van Rossum5b722181993-03-30 17:46:03 +0000346 object *globals, *locals;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000347{
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000348 codeobject *co;
349 object *v;
350 co = compile(n, filename);
351 freetree(n);
352 if (co == NULL)
353 return NULL;
Guido van Rossum81daa321993-05-20 14:24:46 +0000354 v = eval_code(co, globals, locals, (object *)NULL, (object *)NULL);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000355 DECREF(co);
356 return v;
357}
358
Guido van Rossum5b722181993-03-30 17:46:03 +0000359object *
360compile_string(str, filename, start)
361 char *str;
362 char *filename;
363 int start;
364{
365 node *n;
366 int err;
367 codeobject *co;
Guido van Rossuma110aa61994-08-29 12:50:44 +0000368 n = parse_string(str, start);
369 if (n == NULL)
Guido van Rossum5b722181993-03-30 17:46:03 +0000370 return NULL;
Guido van Rossum5b722181993-03-30 17:46:03 +0000371 co = compile(n, filename);
372 freetree(n);
373 return (object *)co;
374}
375
Guido van Rossuma110aa61994-08-29 12:50:44 +0000376/* Simplified interface to parsefile -- return node or set exception */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000377
Guido van Rossuma110aa61994-08-29 12:50:44 +0000378node *
379parse_file(fp, filename, start)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000380 FILE *fp;
381 char *filename;
382 int start;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000383{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000384 node *n;
385 perrdetail err;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000386 BGN_SAVE
Guido van Rossuma110aa61994-08-29 12:50:44 +0000387 n = parsefile(fp, filename, &gram, start,
388 (char *)0, (char *)0, &err);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000389 END_SAVE
Guido van Rossuma110aa61994-08-29 12:50:44 +0000390 if (n == NULL)
391 err_input(&err);
392 return n;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000393}
394
Guido van Rossuma110aa61994-08-29 12:50:44 +0000395/* Simplified interface to parsestring -- return node or set exception */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000396
Guido van Rossuma110aa61994-08-29 12:50:44 +0000397node *
398parse_string(str, start)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000399 char *str;
400 int start;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000401{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000402 node *n;
403 perrdetail err;
404 n = parsestring(str, &gram, start, &err);
405 if (n == NULL)
406 err_input(&err);
407 return n;
408}
409
410/* Set the error appropriate to the given input error code (see errcode.h) */
411
412static void
413err_input(err)
414 perrdetail *err;
415{
416 object *v, *w;
417 char *msg = NULL;
418 v = mkvalue("(ziiz)", err->filename,
419 err->lineno, err->offset, err->text);
420 if (err->text != NULL) {
421 free(err->text);
422 err->text = NULL;
423 }
424 switch (err->error) {
425 case E_SYNTAX:
426 msg = "invalid syntax";
427 break;
428 case E_TOKEN:
429 msg = "invalid token";
430
431 break;
432 case E_INTR:
433 err_set(KeyboardInterrupt);
434 return;
435 case E_NOMEM:
436 err_nomem();
437 return;
438 case E_EOF:
439 msg = "unexpected EOF while parsing";
440 break;
441 default:
442 fprintf(stderr, "error=%d\n", err->error);
443 msg = "unknown parsing error";
444 break;
445 }
446 w = mkvalue("(sO)", msg, v);
447 XDECREF(v);
448 err_setval(SyntaxError, w);
449 XDECREF(w);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000450}
451
452/* Print fatal error message and abort */
453
454void
455fatal(msg)
456 char *msg;
457{
458 fprintf(stderr, "Fatal error: %s\n", msg);
459 abort();
460}
461
462/* Clean up and exit */
463
Guido van Rossuma110aa61994-08-29 12:50:44 +0000464#ifdef WITH_THREAD
465#include "thread.h"
466int threads_started = 0; /* Set by threadmodule.c and maybe others */
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000467#endif
468
Guido van Rossum1662dd51994-09-07 14:38:28 +0000469#define NEXITFUNCS 32
470static void (*exitfuncs[NEXITFUNCS])();
471static int nexitfuncs = 0;
472
473int Py_AtExit(func)
474 void (*func) PROTO((void));
475{
476 if (nexitfuncs >= NEXITFUNCS)
477 return -1;
478 exitfuncs[nexitfuncs++] = func;
479 return 0;
480}
481
Guido van Rossuma110aa61994-08-29 12:50:44 +0000482void
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000483cleanup()
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000484{
Guido van Rossum59bff391992-09-03 20:28:00 +0000485 object *exitfunc = sysget("exitfunc");
486
487 if (exitfunc) {
488 object *arg;
489 object *res;
490 sysset("exitfunc", (object *)NULL);
491 arg = newtupleobject(0);
492 if (arg == NULL)
493 res = NULL;
494 else {
495 res = call_object(exitfunc, arg);
496 DECREF(arg);
497 }
498 if (res == NULL) {
499 fprintf(stderr, "Error in sys.exitfunc:\n");
500 print_error();
501 }
502 }
503
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000504 flushline();
Guido van Rossum1662dd51994-09-07 14:38:28 +0000505
506 while (nexitfuncs > 0)
507 (*exitfuncs[--nexitfuncs])();
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000508}
509
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000510#ifdef COUNT_ALLOCS
511extern void dump_counts PROTO((void));
512#endif
513
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000514void
515goaway(sts)
516 int sts;
517{
518 cleanup();
Guido van Rossumff4949e1992-08-05 19:58:53 +0000519
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000520#ifdef COUNT_ALLOCS
521 dump_counts();
522#endif
523
Guido van Rossuma110aa61994-08-29 12:50:44 +0000524#ifdef WITH_THREAD
Guido van Rossumff4949e1992-08-05 19:58:53 +0000525
526 /* Other threads may still be active, so skip most of the
527 cleanup actions usually done (these are mostly for
528 debugging anyway). */
529
Guido van Rossumdf72a651992-08-12 15:27:32 +0000530 (void) save_thread();
Guido van Rossuma110aa61994-08-29 12:50:44 +0000531#ifndef NO_EXIT_PROG
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000532 if (threads_started)
533 _exit_prog(sts);
534 else
535 exit_prog(sts);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000536#else /* !NO_EXIT_PROG */
537 if (threads_started)
538 _exit(sts);
539 else
540 exit(sts);
541#endif /* !NO_EXIT_PROG */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000542
Guido van Rossuma110aa61994-08-29 12:50:44 +0000543#else /* WITH_THREAD */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000544
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000545 doneimport();
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000546
547 err_clear();
548
549#ifdef REF_DEBUG
550 fprintf(stderr, "[%ld refs]\n", ref_total);
551#endif
552
553#ifdef TRACE_REFS
554 if (askyesno("Print left references?")) {
555 printrefs(stderr);
556 }
557#endif /* TRACE_REFS */
558
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000559 exit(sts);
Guido van Rossuma110aa61994-08-29 12:50:44 +0000560#endif /* WITH_THREAD */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000561 /*NOTREACHED*/
562}
563
Guido van Rossuma110aa61994-08-29 12:50:44 +0000564#ifdef HAVE_SIGNAL_H
565static RETSIGTYPE
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000566sighandler(sig)
567 int sig;
568{
569 signal(sig, SIG_DFL); /* Don't catch recursive signals */
570 cleanup(); /* Do essential clean-up */
Guido van Rossuma110aa61994-08-29 12:50:44 +0000571#ifdef HAVE_GETPID
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000572 kill(getpid(), sig); /* Pretend the signal killed us */
Guido van Rossuma110aa61994-08-29 12:50:44 +0000573#else
574 exit(1);
575#endif
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000576 /*NOTREACHED*/
577}
578#endif
579
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000580static void
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000581initsigs()
582{
Guido van Rossuma110aa61994-08-29 12:50:44 +0000583 RETSIGTYPE (*t)();
584#ifdef HAVE_SIGNAL_H
585#ifdef SIGPIPE
586 signal(SIGPIPE, SIG_IGN);
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000587#endif
Guido van Rossuma110aa61994-08-29 12:50:44 +0000588#ifdef SIGHUP
589 t = signal(SIGHUP, SIG_IGN);
590 if (t == SIG_DFL)
591 signal(SIGHUP, sighandler);
592 else
593 signal(SIGHUP, t);
594#endif
595#ifdef SIGTERM
596 t = signal(SIGTERM, SIG_IGN);
597 if (t == SIG_DFL)
598 signal(SIGTERM, sighandler);
599 else
600 signal(SIGTERM, t);
601#endif
602#endif /* HAVE_SIGNAL_H */
603 initintr(); /* May imply initsignal() */
Guido van Rossuma9e7dc11992-10-18 18:53:57 +0000604}
605
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000606#ifdef TRACE_REFS
607/* Ask a yes/no question */
608
Guido van Rossum59bff391992-09-03 20:28:00 +0000609int
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000610askyesno(prompt)
611 char *prompt;
612{
613 char buf[256];
614
615 printf("%s [ny] ", prompt);
616 if (fgets(buf, sizeof buf, stdin) == NULL)
617 return 0;
618 return buf[0] == 'y' || buf[0] == 'Y';
619}
620#endif
621
Guido van Rossuma110aa61994-08-29 12:50:44 +0000622#ifdef MPW
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000623
624/* Check for file descriptor connected to interactive device.
625 Pretend that stdin is always interactive, other files never. */
626
627int
628isatty(fd)
629 int fd;
630{
631 return fd == fileno(stdin);
632}
633
634#endif