comparison Python/pythonrun.c @ 1839:1f4a86dbcd79 legacy-trunk

* Python/pythonrun.c (print_error): added INCREF/DECREF pair -- the exception returned by a syntax error (when reported) would contain an object with refcnt zero! MPW changes
author Guido van Rossum <guido@python.org>
date Mon, 29 Aug 1994 12:50:44 +0000
parents c914b10bf2ed
children 61738ed6cc10
comparison
equal deleted inserted replaced
1838:5f6acd1ab5c5 1839:1f4a86dbcd79
1 /*********************************************************** 1 /***********************************************************
2 Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, 2 Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
3 Amsterdam, The Netherlands. 3 Amsterdam, The Netherlands.
4 4
5 All Rights Reserved 5 All Rights Reserved
6 6
7 Permission to use, copy, modify, and distribute this software and its 7 Permission to use, copy, modify, and distribute this software and its
36 #include "eval.h" 36 #include "eval.h"
37 #include "ceval.h" 37 #include "ceval.h"
38 #include "pythonrun.h" 38 #include "pythonrun.h"
39 #include "import.h" 39 #include "import.h"
40 40
41 #ifdef unix 41 #ifdef HAVE_SIGNAL_H
42 #define HANDLE_SIGNALS
43 #endif
44
45 #ifdef HANDLE_SIGNALS
46 #include <signal.h> 42 #include <signal.h>
47 #include "sigtype.h"
48 #endif 43 #endif
49 44
50 extern char *getpythonpath(); 45 extern char *getpythonpath();
51 46
52 extern grammar gram; /* From graminit.c */ 47 extern grammar gram; /* From graminit.c */
53 48
54 /* Forward */ 49 /* Forward */
55 static object *run_err_node PROTO((int err, node *n, char *filename, 50 static object *run_err_node PROTO((node *n, char *filename,
56 object *globals, object *locals)); 51 object *globals, object *locals));
57 static object *run_node PROTO((node *n, char *filename, 52 static object *run_node PROTO((node *n, char *filename,
58 object *globals, object *locals)); 53 object *globals, object *locals));
59 static object *eval_node PROTO((node *n, char *filename, 54 static void err_input PROTO((perrdetail *));
60 object *globals, object *locals));
61 static void initsigs PROTO((void)); 55 static void initsigs PROTO((void));
62 56
63 int debugging; /* Needed by parser.c */ 57 int debugging; /* Needed by parser.c */
64 int verbose; /* Needed by import.c */ 58 int verbose; /* Needed by import.c */
59 int suppress_print; /* Needed by ceval.c */
65 60
66 /* Initialize all */ 61 /* Initialize all */
67 62
68 void 63 void
69 initall() 64 initall()
74 return; 69 return;
75 inited = 1; 70 inited = 1;
76 71
77 initimport(); 72 initimport();
78 73
79 /* Modules 'builtin' and 'sys' are initialized here, 74 /* Modules '__builtin__' and 'sys' are initialized here,
80 they are needed by random bits of the interpreter. 75 they are needed by random bits of the interpreter.
81 All other modules are optional and are initialized 76 All other modules are optional and are initialized
82 when they are first imported. */ 77 when they are first imported. */
83 78
84 initbuiltin(); /* Also initializes builtin exceptions */ 79 initbuiltin(); /* Also initializes builtin exceptions */
85 initsys(); 80 initsys();
86
87 initcalls(); /* Configuration-dependent initializations */
88 81
89 setpythonpath(getpythonpath()); 82 setpythonpath(getpythonpath());
90 83
91 initsigs(); /* Signal handling stuff, including initintr() */ 84 initsigs(); /* Signal handling stuff, including initintr() */
92 } 85 }
142 FILE *fp; 135 FILE *fp;
143 char *filename; 136 char *filename;
144 { 137 {
145 object *m, *d, *v, *w; 138 object *m, *d, *v, *w;
146 node *n; 139 node *n;
140 perrdetail err;
147 char *ps1, *ps2; 141 char *ps1, *ps2;
148 int err;
149 v = sysget("ps1"); 142 v = sysget("ps1");
150 w = sysget("ps2"); 143 w = sysget("ps2");
151 if (v != NULL && is_stringobject(v)) { 144 if (v != NULL && is_stringobject(v)) {
152 INCREF(v); 145 INCREF(v);
153 ps1 = getstringvalue(v); 146 ps1 = getstringvalue(v);
163 else { 156 else {
164 w = NULL; 157 w = NULL;
165 ps2 = ""; 158 ps2 = "";
166 } 159 }
167 BGN_SAVE 160 BGN_SAVE
168 err = parsefile(fp, filename, &gram, single_input, ps1, ps2, &n); 161 n = parsefile(fp, filename, &gram, single_input, ps1, ps2, &err);
169 END_SAVE 162 END_SAVE
170 XDECREF(v); 163 XDECREF(v);
171 XDECREF(w); 164 XDECREF(w);
172 if (err == E_EOF) 165 if (n == NULL) {
173 return E_EOF; 166 if (err.error == E_EOF) {
174 if (err != E_DONE) { 167 if (err.text)
175 err_input(err); 168 free(err.text);
169 return E_EOF;
170 }
171 err_input(&err);
176 print_error(); 172 print_error();
177 return err; 173 return err.error;
178 } 174 }
179 m = add_module("__main__"); 175 m = add_module("__main__");
180 if (m == NULL) 176 if (m == NULL)
181 return -1; 177 return -1;
182 d = getmoduledict(m); 178 d = getmoduledict(m);
232 void 228 void
233 print_error() 229 print_error()
234 { 230 {
235 object *exception, *v, *f; 231 object *exception, *v, *f;
236 err_get(&exception, &v); 232 err_get(&exception, &v);
233 if (exception == NULL) {
234 fprintf(stderr, "print_error called but no exception\n");
235 abort();
236 }
237 if (exception == SystemExit) { 237 if (exception == SystemExit) {
238 if (v == NULL || v == None) 238 if (v == NULL || v == None)
239 goaway(0); 239 goaway(0);
240 if (is_intobject(v)) 240 if (is_intobject(v))
241 goaway((int)getintvalue(v)); 241 goaway((int)getintvalue(v));
251 f = sysget("stderr"); 251 f = sysget("stderr");
252 if (f == NULL) 252 if (f == NULL)
253 fprintf(stderr, "lost sys.stderr\n"); 253 fprintf(stderr, "lost sys.stderr\n");
254 else { 254 else {
255 printtraceback(f); 255 printtraceback(f);
256 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 }
256 if (writeobject(exception, f, PRINT_RAW) != 0) 297 if (writeobject(exception, f, PRINT_RAW) != 0)
257 err_clear(); 298 err_clear();
258 if (v != NULL && v != None) { 299 if (v != NULL && v != None) {
259 writestring(": ", f); 300 writestring(": ", f);
260 if (writeobject(v, f, PRINT_RAW) != 0) 301 if (writeobject(v, f, PRINT_RAW) != 0)
270 run_string(str, start, globals, locals) 311 run_string(str, start, globals, locals)
271 char *str; 312 char *str;
272 int start; 313 int start;
273 object *globals, *locals; 314 object *globals, *locals;
274 { 315 {
275 node *n; 316 return run_err_node(parse_string(str, start),
276 int err; 317 "<string>", globals, locals);
277 err = parse_string(str, start, &n);
278 return run_err_node(err, n, "<string>", globals, locals);
279 } 318 }
280 319
281 object * 320 object *
282 run_file(fp, filename, start, globals, locals) 321 run_file(fp, filename, start, globals, locals)
283 FILE *fp; 322 FILE *fp;
284 char *filename; 323 char *filename;
285 int start; 324 int start;
286 object *globals, *locals; 325 object *globals, *locals;
287 { 326 {
327 return run_err_node(parse_file(fp, filename, start),
328 filename, globals, locals);
329 }
330
331 static object *
332 run_err_node(n, filename, globals, locals)
288 node *n; 333 node *n;
289 int err;
290 err = parse_file(fp, filename, start, &n);
291 return run_err_node(err, n, filename, globals, locals);
292 }
293
294 static object *
295 run_err_node(err, n, filename, globals, locals)
296 int err;
297 node *n;
298 char *filename; 334 char *filename;
299 object *globals, *locals; 335 object *globals, *locals;
300 { 336 {
301 if (err != E_DONE) { 337 if (n == NULL)
302 err_input(err); 338 return NULL;
303 return NULL;
304 }
305 return run_node(n, filename, globals, locals); 339 return run_node(n, filename, globals, locals);
306 } 340 }
307 341
308 static object * 342 static object *
309 run_node(n, filename, globals, locals) 343 run_node(n, filename, globals, locals)
310 node *n; 344 node *n;
311 char *filename; 345 char *filename;
312 object *globals, *locals; 346 object *globals, *locals;
313 {
314 return eval_node(n, filename, globals, locals);
315 }
316
317 static object *
318 eval_node(n, filename, globals, locals)
319 node *n;
320 char *filename;
321 object *globals;
322 object *locals;
323 { 347 {
324 codeobject *co; 348 codeobject *co;
325 object *v; 349 object *v;
326 co = compile(n, filename); 350 co = compile(n, filename);
327 freetree(n); 351 freetree(n);
339 int start; 363 int start;
340 { 364 {
341 node *n; 365 node *n;
342 int err; 366 int err;
343 codeobject *co; 367 codeobject *co;
344 err = parse_string(str, start, &n); 368 n = parse_string(str, start);
345 if (err != E_DONE) { 369 if (n == NULL)
346 err_input(err);
347 return NULL; 370 return NULL;
348 }
349 co = compile(n, filename); 371 co = compile(n, filename);
350 freetree(n); 372 freetree(n);
351 return (object *)co; 373 return (object *)co;
352 } 374 }
353 375
354 /* Simplified interface to parsefile */ 376 /* Simplified interface to parsefile -- return node or set exception */
355 377
356 int 378 node *
357 parse_file(fp, filename, start, n_ret) 379 parse_file(fp, filename, start)
358 FILE *fp; 380 FILE *fp;
359 char *filename; 381 char *filename;
360 int start; 382 int start;
361 node **n_ret; 383 {
362 { 384 node *n;
363 int ret; 385 perrdetail err;
364 BGN_SAVE 386 BGN_SAVE
365 ret = parsefile(fp, filename, &gram, start, 387 n = parsefile(fp, filename, &gram, start,
366 (char *)0, (char *)0, n_ret); 388 (char *)0, (char *)0, &err);
367 END_SAVE 389 END_SAVE
368 return ret; 390 if (n == NULL)
369 } 391 err_input(&err);
370 392 return n;
371 /* Simplified interface to parsestring */ 393 }
372 394
373 int 395 /* Simplified interface to parsestring -- return node or set exception */
374 parse_string(str, start, n_ret) 396
397 node *
398 parse_string(str, start)
375 char *str; 399 char *str;
376 int start; 400 int start;
377 node **n_ret; 401 {
378 { 402 node *n;
379 int err = parsestring(str, &gram, start, n_ret); 403 perrdetail err;
380 /* Don't confuse early end of string with early end of input */ 404 n = parsestring(str, &gram, start, &err);
381 if (err == E_EOF) 405 if (n == NULL)
382 err = E_SYNTAX; 406 err_input(&err);
383 return err; 407 return n;
408 }
409
410 /* Set the error appropriate to the given input error code (see errcode.h) */
411
412 static void
413 err_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);
384 } 450 }
385 451
386 /* Print fatal error message and abort */ 452 /* Print fatal error message and abort */
387 453
388 void 454 void
393 abort(); 459 abort();
394 } 460 }
395 461
396 /* Clean up and exit */ 462 /* Clean up and exit */
397 463
398 #ifdef USE_THREAD 464 #ifdef WITH_THREAD
399 extern int threads_started; 465 #include "thread.h"
400 #endif 466 int threads_started = 0; /* Set by threadmodule.c and maybe others */
401 467 #endif
402 static void 468
469 void
403 cleanup() 470 cleanup()
404 { 471 {
405 object *exitfunc = sysget("exitfunc"); 472 object *exitfunc = sysget("exitfunc");
406 473
407 if (exitfunc) { 474 if (exitfunc) {
436 503
437 #ifdef COUNT_ALLOCS 504 #ifdef COUNT_ALLOCS
438 dump_counts(); 505 dump_counts();
439 #endif 506 #endif
440 507
441 #ifdef USE_THREAD 508 #ifdef WITH_THREAD
442 509
443 /* Other threads may still be active, so skip most of the 510 /* Other threads may still be active, so skip most of the
444 cleanup actions usually done (these are mostly for 511 cleanup actions usually done (these are mostly for
445 debugging anyway). */ 512 debugging anyway). */
446 513
447 (void) save_thread(); 514 (void) save_thread();
448 donecalls(); 515 #ifndef NO_EXIT_PROG
449 if (threads_started) 516 if (threads_started)
450 _exit_prog(sts); 517 _exit_prog(sts);
451 else 518 else
452 exit_prog(sts); 519 exit_prog(sts);
453 520 #else /* !NO_EXIT_PROG */
454 #else /* USE_THREAD */ 521 if (threads_started)
455 522 _exit(sts);
456 /* XXX Call doneimport() before donecalls(), since donecalls() 523 else
457 calls wdone(), and doneimport() may close windows */ 524 exit(sts);
525 #endif /* !NO_EXIT_PROG */
526
527 #else /* WITH_THREAD */
528
458 doneimport(); 529 doneimport();
459 donecalls();
460 530
461 err_clear(); 531 err_clear();
462 532
463 #ifdef REF_DEBUG 533 #ifdef REF_DEBUG
464 fprintf(stderr, "[%ld refs]\n", ref_total); 534 fprintf(stderr, "[%ld refs]\n", ref_total);
469 printrefs(stderr); 539 printrefs(stderr);
470 } 540 }
471 #endif /* TRACE_REFS */ 541 #endif /* TRACE_REFS */
472 542
473 exit(sts); 543 exit(sts);
474 #endif /* USE_THREAD */ 544 #endif /* WITH_THREAD */
475 /*NOTREACHED*/ 545 /*NOTREACHED*/
476 } 546 }
477 547
478 #ifdef HANDLE_SIGNALS 548 #ifdef HAVE_SIGNAL_H
479 static SIGTYPE 549 static RETSIGTYPE
480 sighandler(sig) 550 sighandler(sig)
481 int sig; 551 int sig;
482 { 552 {
483 signal(sig, SIG_DFL); /* Don't catch recursive signals */ 553 signal(sig, SIG_DFL); /* Don't catch recursive signals */
484 cleanup(); /* Do essential clean-up */ 554 cleanup(); /* Do essential clean-up */
555 #ifdef HAVE_GETPID
485 kill(getpid(), sig); /* Pretend the signal killed us */ 556 kill(getpid(), sig); /* Pretend the signal killed us */
557 #else
558 exit(1);
559 #endif
486 /*NOTREACHED*/ 560 /*NOTREACHED*/
487 } 561 }
488 #endif 562 #endif
489 563
490 static void 564 static void
491 initsigs() 565 initsigs()
492 { 566 {
493 initintr(); 567 RETSIGTYPE (*t)();
494 #ifdef HANDLE_SIGNALS 568 #ifdef HAVE_SIGNAL_H
495 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 569 #ifdef SIGPIPE
570 signal(SIGPIPE, SIG_IGN);
571 #endif
572 #ifdef SIGHUP
573 t = signal(SIGHUP, SIG_IGN);
574 if (t == SIG_DFL)
496 signal(SIGHUP, sighandler); 575 signal(SIGHUP, sighandler);
497 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 576 else
577 signal(SIGHUP, t);
578 #endif
579 #ifdef SIGTERM
580 t = signal(SIGTERM, SIG_IGN);
581 if (t == SIG_DFL)
498 signal(SIGTERM, sighandler); 582 signal(SIGTERM, sighandler);
499 #endif 583 else
584 signal(SIGTERM, t);
585 #endif
586 #endif /* HAVE_SIGNAL_H */
587 initintr(); /* May imply initsignal() */
500 } 588 }
501 589
502 #ifdef TRACE_REFS 590 #ifdef TRACE_REFS
503 /* Ask a yes/no question */ 591 /* Ask a yes/no question */
504 592
513 return 0; 601 return 0;
514 return buf[0] == 'y' || buf[0] == 'Y'; 602 return buf[0] == 'y' || buf[0] == 'Y';
515 } 603 }
516 #endif 604 #endif
517 605
518 #ifdef applec /* MPW (also usable for Think C 3.0) */ 606 #ifdef MPW
519 607
520 /* Check for file descriptor connected to interactive device. 608 /* Check for file descriptor connected to interactive device.
521 Pretend that stdin is always interactive, other files never. */ 609 Pretend that stdin is always interactive, other files never. */
522 610
523 int 611 int