/* Python interpreter main program */ #include #include #include "string.h" extern char *getpythonpath(); #include "PROTO.h" #include "grammar.h" #include "node.h" #include "parsetok.h" #include "graminit.h" #include "errcode.h" #include "object.h" #include "stringobject.h" #include "sysmodule.h" extern grammar gram; /* From graminit.c */ int debugging; main(argc, argv) int argc; char **argv; { char *filename = NULL; FILE *fp = stdin; int ret; initargs(&argc, &argv); initintr(); /* For intrcheck() */ if (argc > 1 && strcmp(argv[1], "-") != 0) filename = argv[1]; if (filename != NULL) { if ((fp = fopen(filename, "r")) == NULL) { fprintf(stderr, "python: can't open file '%s'\n", filename); exit(2); } } /* XXX what is the ideal initialization order? */ initsys(argc-1, argv+1); inittime(); initmath(); setpythonpath(getpythonpath()); initrun(); initcalls(); if (!isatty(fileno(fp))) { ret = runfile(fp, file_input, (char *)NULL, (char *)NULL); } else { sysset("ps1", newstringobject(">>> ")); sysset("ps2", newstringobject("... ")); for (;;) { object *v = sysget("ps1"), *w = sysget("ps2"); char *ps1 = NULL, *ps2 = NULL; if (v != NULL && is_stringobject(v)) { INCREF(v); ps1 = getstringvalue(v); } else v = NULL; if (w != NULL && is_stringobject(w)) { INCREF(w); ps2 = getstringvalue(w); } else w = NULL; ret = runfile(fp, single_input, ps1, ps2); if (v != NULL) DECREF(v); if (w != NULL) DECREF(w); if (ret == E_EOF || ret == E_NOMEM) break; } } goaway(ret == E_DONE || ret == E_EOF ? 0 : 1); /*NOTREACHED*/ } goaway(sts) int sts; { #ifdef THINK_C if (sts == 0) Click_On(0); #endif closerun(); donecalls(); exit(sts); /*NOTREACHED*/ } /* Parse input from a file and execute it */ static int runfile(fp, start, ps1, ps2) FILE *fp; int start; char *ps1, *ps2; { node *n; int ret; ret = parsefile(fp, &gram, start, ps1, ps2, &n); if (ret != E_DONE) return ret; return execute(n) == 0 ? E_DONE : E_ERROR; } /* Ask a yes/no question */ int askyesno(prompt) char *prompt; { char buf[256]; printf("%s [ny] ", prompt); if (fgets(buf, sizeof buf, stdin) == NULL) return 0; return buf[0] == 'y' || buf[0] == 'Y'; } #ifdef THINK_C /* Check for file descriptor connected to interactive device. Pretend that stdin is always interactive, other files never. */ int isatty(fd) int fd; { return fd == fileno(stdin); } #endif /* WISH LIST - improved per-module error handling; different use of errno - possible new types: - iterator (for range, keys, ...) - improve interpreter error handling, e.g., true tracebacks - release parse trees when no longer needed (make them objects?) - faster parser (for long modules) - save precompiled modules on file? - fork threads, locking - allow syntax extensions */