From 3165fe6a56c07f4f85f4ea54b69f5b1f243e2463 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 25 Sep 1992 21:59:05 +0000 Subject: Modified most (but not yet all) I/O to always go through sys.stdout or sys.stderr or sys.stdin, and to work with any object as long as it has a write() (respectively readline()) methods. Some functions that took a FILE* argument now take an object* argument. --- Include/ceval.h | 2 +- Include/traceback.h | 2 +- Objects/fileobject.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++--- Python/bltinmodule.c | 33 +++++------- Python/ceval.c | 48 ++++++++--------- Python/pythonrun.c | 22 +++++--- Python/sysmodule.c | 2 +- Python/traceback.c | 35 ++++++------ 8 files changed, 217 insertions(+), 76 deletions(-) diff --git a/Include/ceval.h b/Include/ceval.h index dc31255..e7281f4 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -29,7 +29,7 @@ object *call_object PROTO((object *, object *)); object *getglobals PROTO((void)); object *getlocals PROTO((void)); -void printtraceback PROTO((FILE *)); +void printtraceback PROTO((object *)); void flushline PROTO((void)); diff --git a/Include/traceback.h b/Include/traceback.h index c9fb17a..08370e3 100644 --- a/Include/traceback.h +++ b/Include/traceback.h @@ -27,4 +27,4 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. int tb_here PROTO((struct _frame *)); object *tb_fetch PROTO((void)); int tb_store PROTO((object *)); -int tb_print PROTO((object *, FILE *)); +int tb_print PROTO((object *, object *)); diff --git a/Objects/fileobject.c b/Objects/fileobject.c index dd47905..52dd668 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -48,11 +48,10 @@ FILE * getfilefile(f) object *f; { - if (!is_fileobject(f) || ((fileobject *)f)->f_fp == NULL) { - err_badcall(); + if (f == NULL || !is_fileobject(f)) return NULL; - } - return ((fileobject *)f)->f_fp; + else + return ((fileobject *)f)->f_fp; } object * @@ -399,10 +398,56 @@ filegetline(f, n) object *f; int n; { - if (f == NULL || !is_fileobject(f)) { + if (f == NULL) { err_badcall(); return NULL; } + if (!is_fileobject(f)) { + object *reader; + object *args; + object *result; + reader = getattr(f, "readline"); + if (reader == NULL) + return NULL; + if (n <= 0) + args = mkvalue("()"); + else + args = mkvalue("(i)", n); + if (args == NULL) { + DECREF(reader); + return NULL; + } + result = call_object(reader, args); + DECREF(reader); + DECREF(args); + if (result != NULL && !is_stringobject(result)) { + DECREF(result); + result = NULL; + err_setstr(TypeError, + "object.readline() returned non-string"); + } + if (n < 0 && result != NULL) { + char *s = getstringvalue(result); + int len = getstringsize(result); + if (len == 0) { + DECREF(result); + result = NULL; + err_setstr(EOFError, + "EOF when reading a line"); + } + else if (s[len-1] == '\n') { + if (result->ob_refcnt == 1) + resizestring(&result, len-1); + else { + object *v; + v == newsizedstringobject(s, len-1); + DECREF(result); + result = v; + } + } + } + return result; + } if (((fileobject*)f)->f_fp == NULL) return err_closed(); return getline((fileobject *)f, n); @@ -532,9 +577,101 @@ softspace(f, newflag) int newflag; { int oldflag = 0; - if (f != NULL && is_fileobject(f)) { + if (f == NULL) { + /* Do nothing */ + } + if (is_fileobject(f)) { oldflag = ((fileobject *)f)->f_softspace; ((fileobject *)f)->f_softspace = newflag; } + else { + object *v; + v = getattr(f, "softspace"); + if (v == NULL) + err_clear(); + else { + if (is_intobject(v)) + oldflag = getintvalue(v); + DECREF(v); + } + v = newintobject((long)newflag); + if (v == NULL) + err_clear(); + else { + if (setattr(f, "softspace", v) != 0) + err_clear(); + DECREF(v); + } + } return oldflag; } + +/* Interfaces to write objects/strings to file-like objects */ + +int +writeobject(v, f, flags) + object *v; + object *f; + int flags; +{ + object *writer, *value, *result; + if (f == NULL) { + err_setstr(TypeError, "writeobject with NULL file"); + return -1; + } + else if (is_fileobject(f)) { + FILE *fp = getfilefile(f); + if (fp == NULL) { + err_closed(); + return -1; + } + return printobject(v, fp, flags); + } + writer = getattr(f, "write"); + if (writer == NULL) + return -1; + if ((flags & PRINT_RAW) && is_stringobject(v)) { + value = v; + INCREF(value); + } + else { + value = reprobject(v); + if (value == NULL) { + DECREF(writer); + return -1; + } + } + result = call_object(writer, value); + DECREF(writer); + DECREF(value); + if (result == NULL) + return -1; + DECREF(result); + return 0; +} + +void +writestring(s, f) + char *s; + object *f; +{ + if (f == NULL) { + /* Do nothing */ + } + else if (is_fileobject(f)) { + FILE *fp = getfilefile(f); + if (fp != NULL) + fputs(s, fp); + } + else { + object *v = newstringobject(s); + if (v == NULL) { + err_clear(); + } + else { + if (writeobject(v, f, PRINT_RAW) != NULL) + err_clear(); + DECREF(v); + } + } +} diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 2f46931..9ba07af 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -308,28 +308,19 @@ builtin_hex(self, v) return (*nb->nb_hex)(v); } +static object *builtin_raw_input PROTO((object *, object *)); + static object * builtin_input(self, v) object *self; object *v; { - FILE *in = sysgetfile("stdin", stdin); - FILE *out = sysgetfile("stdout", stdout); - int c; - object *m, *d; - flushline(); - if (v != NULL) { - if (printobject(v, out, PRINT_RAW) != 0) - return NULL; - } - m = add_module("__main__"); - d = getmoduledict(m); - BGN_SAVE - while ((c = getc(in)) != EOF && (c == ' ' || c == '\t')) - ; - ungetc(c, in); - END_SAVE - return run_file(in, "", expr_input, d, d); + object *line = builtin_raw_input(self, v); + if (line == NULL) + return line; + v = exec_eval(line, eval_input); + DECREF(line); + return v; } static object * @@ -578,10 +569,14 @@ builtin_raw_input(self, v) object *self; object *v; { - FILE *out = sysgetfile("stdout", stdout); + object *f = sysget("stdout"); + if (f == NULL) { + err_setstr(RuntimeError, "lost sys.stdout"); + return NULL; + } flushline(); if (v != NULL) { - if (printobject(v, out, PRINT_RAW) != 0) + if (writeobject(v, f, PRINT_RAW) != 0) return NULL; } return filegetline(sysget("stdin"), -1); diff --git a/Python/ceval.c b/Python/ceval.c index 469068e..4637d35 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -176,7 +176,6 @@ eval_code(co, globals, locals, arg) object *trace = NULL; /* Trace function or NULL */ object *retval; /* Return value iff why == WHY_RETURN */ char *name; /* Name used by some instructions */ - FILE *fp; /* Used by print operations */ #ifdef LLTRACE int lltrace = dictlookup(globals, "__lltrace__") != NULL; #endif @@ -598,12 +597,12 @@ eval_code(co, globals, locals, arg) case PRINT_EXPR: v = POP(); - fp = sysgetfile("stdout", stdout); /* Print value except if procedure result */ if (v != None) { flushline(); - softspace(sysget("stdout"), 1); - err = printobject(v, fp, 0); + x = sysget("stdout"); + softspace(x, 1); + err = writeobject(v, x, 0); flushline(); } DECREF(v); @@ -611,30 +610,30 @@ eval_code(co, globals, locals, arg) case PRINT_ITEM: v = POP(); - fp = sysgetfile("stdout", stdout); - if (softspace(sysget("stdout"), 1)) - fprintf(fp, " "); + w = sysget("stdout"); + if (softspace(w, 1)) + writestring(" ", w); if (is_stringobject(v)) { char *s = getstringvalue(v); int len = getstringsize(v); - fwrite(s, 1, len, fp); - if (ferror(fp)) { - err_errno(IOError); - err = -1; - } - else if (len > 0 && s[len-1] == '\n') - softspace(sysget("stdout"), 0); + err = writeobject(v, w, PRINT_RAW); + if (err == 0 && len > 0 && s[len-1] == '\n') + softspace(w, 0); } else { - err = printobject(v, fp, 0); + err = writeobject(v, w, 0); } DECREF(v); break; case PRINT_NEWLINE: - fp = sysgetfile("stdout", stdout); - fprintf(fp, "\n"); - softspace(sysget("stdout"), 0); + x = sysget("stdout"); + if (x == NULL) + err_setstr(RuntimeError, "lost sys.stdout"); + else { + writestring("\n", x); + softspace(x, 0); + } break; case BREAK_LOOP: @@ -1395,13 +1394,13 @@ getglobals() } void -printtraceback(fp) - FILE *fp; +printtraceback(f) + object *f; { object *v = tb_fetch(); if (v != NULL) { - fprintf(fp, "Stack backtrace (innermost last):\n"); - tb_print(v, fp); + writestring("Stack backtrace (innermost last):\n", f); + tb_print(v, f); DECREF(v); } } @@ -1410,8 +1409,9 @@ printtraceback(fp) void flushline() { - if (softspace(sysget("stdout"), 0)) - fprintf(sysgetfile("stdout", stdout), "\n"); + object *f = sysget("stdout"); + if (softspace(f, 0)) + writestring("\n", f); } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 35b1815..90a4294 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -214,7 +214,7 @@ run_command(command) void print_error() { - object *exception, *v; + object *exception, *v, *f; err_get(&exception, &v); if (exception == SystemExit) { if (v == NULL || v == None) @@ -222,6 +222,7 @@ print_error() if (is_intobject(v)) goaway((int)getintvalue(v)); else { + /* OK to use real stderr here */ printobject(v, stderr, PRINT_RAW); fprintf(stderr, "\n"); goaway(1); @@ -229,17 +230,22 @@ print_error() } sysset("last_type", exception); sysset("last_value", v); - if (printobject(exception, stderr, PRINT_RAW) != 0) - err_clear(); - if (v != NULL && v != None) { - fprintf(stderr, ": "); - if (printobject(v, stderr, PRINT_RAW) != 0) + f = sysget("stderr"); + if (f == NULL) + fprintf(stderr, "lost sys.stderr\n"); + else { + if (writeobject(exception, f, PRINT_RAW) != 0) err_clear(); + if (v != NULL && v != None) { + writestring(": ", f); + if (writeobject(v, f, PRINT_RAW) != 0) + err_clear(); + } + writestring("\n", f); + printtraceback(f); } - fprintf(stderr, "\n"); XDECREF(exception); XDECREF(v); - printtraceback(stderr); } object * diff --git a/Python/sysmodule.c b/Python/sysmodule.c index a83ec46..5dff38e 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -62,7 +62,7 @@ sysgetfile(name, def) { FILE *fp = NULL; object *v = sysget(name); - if (v != NULL) + if (v != NULL && is_fileobject(v)) fp = getfilefile(v); if (fp == NULL) fp = def; diff --git a/Python/traceback.c b/Python/traceback.c index bcd2f76..3c246b5 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -150,8 +150,8 @@ tb_store(v) } static void -tb_displayline(fp, filename, lineno) - FILE *fp; +tb_displayline(f, filename, lineno) + object *f; char *filename; int lineno; { @@ -189,15 +189,17 @@ tb_displayline(fp, filename, lineno) } } } - fprintf(fp, " File \"%s\"", filename); + sprintf(linebuf, " File \"%.900s\"%s line %d\n", + filename, #ifdef applec /* MPW */ - /* This is needed by MPW's File and Line commands */ - fprintf(fp, "; "); + /* This is needed by MPW's File and Line commands */ + ";", #else - /* This is needed by Emacs' compile command */ - fprintf(fp, ", "); + /* This is needed by Emacs' compile command */ + ",", #endif - fprintf(fp, "line %d\n", lineno); + lineno); + writestring(linebuf, f); if (xfp == NULL) return; for (i = 0; i < lineno; i++) { @@ -208,20 +210,21 @@ tb_displayline(fp, filename, lineno) char *p = linebuf; while (*p == ' ' || *p == '\t') p++; - fprintf(fp, " %s", p); + writestring(" ", f); + writestring(p, f); if (strchr(p, '\n') == NULL) - fprintf(fp, "\n"); + writestring("\n", f); } fclose(xfp); } static void -tb_printinternal(tb, fp) +tb_printinternal(tb, f) tracebackobject *tb; - FILE *fp; + object *f; { while (tb != NULL && !intrcheck()) { - tb_displayline(fp, + tb_displayline(f, getstringvalue(tb->tb_frame->f_code->co_filename), tb->tb_lineno); tb = tb->tb_next; @@ -229,9 +232,9 @@ tb_printinternal(tb, fp) } int -tb_print(v, fp) +tb_print(v, f) object *v; - FILE *fp; + object *f; { if (v == NULL) return 0; @@ -240,6 +243,6 @@ tb_print(v, fp) return -1; } sysset("last_traceback", v); - tb_printinternal((tracebackobject *)v, fp); + tb_printinternal((tracebackobject *)v, f); return 0; } -- cgit v0.12