Mercurial > cpython-lru_cache-weakref
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 |
