Commit 60067e67 authored by Guido van Rossum's avatar Guido van Rossum

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.
parent d6eb8922
...@@ -29,7 +29,7 @@ object *call_object PROTO((object *, object *)); ...@@ -29,7 +29,7 @@ object *call_object PROTO((object *, object *));
object *getglobals PROTO((void)); object *getglobals PROTO((void));
object *getlocals PROTO((void)); object *getlocals PROTO((void));
void printtraceback PROTO((FILE *)); void printtraceback PROTO((object *));
void flushline PROTO((void)); void flushline PROTO((void));
......
...@@ -27,4 +27,4 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ...@@ -27,4 +27,4 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
int tb_here PROTO((struct _frame *)); int tb_here PROTO((struct _frame *));
object *tb_fetch PROTO((void)); object *tb_fetch PROTO((void));
int tb_store PROTO((object *)); int tb_store PROTO((object *));
int tb_print PROTO((object *, FILE *)); int tb_print PROTO((object *, object *));
...@@ -48,11 +48,10 @@ FILE * ...@@ -48,11 +48,10 @@ FILE *
getfilefile(f) getfilefile(f)
object *f; object *f;
{ {
if (!is_fileobject(f) || ((fileobject *)f)->f_fp == NULL) { if (f == NULL || !is_fileobject(f))
err_badcall();
return NULL; return NULL;
} else
return ((fileobject *)f)->f_fp; return ((fileobject *)f)->f_fp;
} }
object * object *
...@@ -399,10 +398,56 @@ filegetline(f, n) ...@@ -399,10 +398,56 @@ filegetline(f, n)
object *f; object *f;
int n; int n;
{ {
if (f == NULL || !is_fileobject(f)) { if (f == NULL) {
err_badcall(); err_badcall();
return NULL; 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) if (((fileobject*)f)->f_fp == NULL)
return err_closed(); return err_closed();
return getline((fileobject *)f, n); return getline((fileobject *)f, n);
...@@ -532,9 +577,101 @@ softspace(f, newflag) ...@@ -532,9 +577,101 @@ softspace(f, newflag)
int newflag; int newflag;
{ {
int oldflag = 0; int oldflag = 0;
if (f != NULL && is_fileobject(f)) { if (f == NULL) {
/* Do nothing */
}
if (is_fileobject(f)) {
oldflag = ((fileobject *)f)->f_softspace; oldflag = ((fileobject *)f)->f_softspace;
((fileobject *)f)->f_softspace = newflag; ((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; 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);
}
}
}
...@@ -308,28 +308,19 @@ builtin_hex(self, v) ...@@ -308,28 +308,19 @@ builtin_hex(self, v)
return (*nb->nb_hex)(v); return (*nb->nb_hex)(v);
} }
static object *builtin_raw_input PROTO((object *, object *));
static object * static object *
builtin_input(self, v) builtin_input(self, v)
object *self; object *self;
object *v; object *v;
{ {
FILE *in = sysgetfile("stdin", stdin); object *line = builtin_raw_input(self, v);
FILE *out = sysgetfile("stdout", stdout); if (line == NULL)
int c; return line;
object *m, *d; v = exec_eval(line, eval_input);
flushline(); DECREF(line);
if (v != NULL) { return v;
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, "<stdin>", expr_input, d, d);
} }
static object * static object *
...@@ -578,10 +569,14 @@ builtin_raw_input(self, v) ...@@ -578,10 +569,14 @@ builtin_raw_input(self, v)
object *self; object *self;
object *v; object *v;
{ {
FILE *out = sysgetfile("stdout", stdout); object *f = sysget("stdout");
if (f == NULL) {
err_setstr(RuntimeError, "lost sys.stdout");
return NULL;
}
flushline(); flushline();
if (v != NULL) { if (v != NULL) {
if (printobject(v, out, PRINT_RAW) != 0) if (writeobject(v, f, PRINT_RAW) != 0)
return NULL; return NULL;
} }
return filegetline(sysget("stdin"), -1); return filegetline(sysget("stdin"), -1);
......
...@@ -176,7 +176,6 @@ eval_code(co, globals, locals, arg) ...@@ -176,7 +176,6 @@ eval_code(co, globals, locals, arg)
object *trace = NULL; /* Trace function or NULL */ object *trace = NULL; /* Trace function or NULL */
object *retval; /* Return value iff why == WHY_RETURN */ object *retval; /* Return value iff why == WHY_RETURN */
char *name; /* Name used by some instructions */ char *name; /* Name used by some instructions */
FILE *fp; /* Used by print operations */
#ifdef LLTRACE #ifdef LLTRACE
int lltrace = dictlookup(globals, "__lltrace__") != NULL; int lltrace = dictlookup(globals, "__lltrace__") != NULL;
#endif #endif
...@@ -598,12 +597,12 @@ eval_code(co, globals, locals, arg) ...@@ -598,12 +597,12 @@ eval_code(co, globals, locals, arg)
case PRINT_EXPR: case PRINT_EXPR:
v = POP(); v = POP();
fp = sysgetfile("stdout", stdout);
/* Print value except if procedure result */ /* Print value except if procedure result */
if (v != None) { if (v != None) {
flushline(); flushline();
softspace(sysget("stdout"), 1); x = sysget("stdout");
err = printobject(v, fp, 0); softspace(x, 1);
err = writeobject(v, x, 0);
flushline(); flushline();
} }
DECREF(v); DECREF(v);
...@@ -611,30 +610,30 @@ eval_code(co, globals, locals, arg) ...@@ -611,30 +610,30 @@ eval_code(co, globals, locals, arg)
case PRINT_ITEM: case PRINT_ITEM:
v = POP(); v = POP();
fp = sysgetfile("stdout", stdout); w = sysget("stdout");
if (softspace(sysget("stdout"), 1)) if (softspace(w, 1))
fprintf(fp, " "); writestring(" ", w);
if (is_stringobject(v)) { if (is_stringobject(v)) {
char *s = getstringvalue(v); char *s = getstringvalue(v);
int len = getstringsize(v); int len = getstringsize(v);
fwrite(s, 1, len, fp); err = writeobject(v, w, PRINT_RAW);
if (ferror(fp)) { if (err == 0 && len > 0 && s[len-1] == '\n')
err_errno(IOError); softspace(w, 0);
err = -1;
}
else if (len > 0 && s[len-1] == '\n')
softspace(sysget("stdout"), 0);
} }
else { else {
err = printobject(v, fp, 0); err = writeobject(v, w, 0);
} }
DECREF(v); DECREF(v);
break; break;
case PRINT_NEWLINE: case PRINT_NEWLINE:
fp = sysgetfile("stdout", stdout); x = sysget("stdout");
fprintf(fp, "\n"); if (x == NULL)
softspace(sysget("stdout"), 0); err_setstr(RuntimeError, "lost sys.stdout");
else {
writestring("\n", x);
softspace(x, 0);
}
break; break;
case BREAK_LOOP: case BREAK_LOOP:
...@@ -1395,13 +1394,13 @@ getglobals() ...@@ -1395,13 +1394,13 @@ getglobals()
} }
void void
printtraceback(fp) printtraceback(f)
FILE *fp; object *f;
{ {
object *v = tb_fetch(); object *v = tb_fetch();
if (v != NULL) { if (v != NULL) {
fprintf(fp, "Stack backtrace (innermost last):\n"); writestring("Stack backtrace (innermost last):\n", f);
tb_print(v, fp); tb_print(v, f);
DECREF(v); DECREF(v);
} }
} }
...@@ -1410,8 +1409,9 @@ printtraceback(fp) ...@@ -1410,8 +1409,9 @@ printtraceback(fp)
void void
flushline() flushline()
{ {
if (softspace(sysget("stdout"), 0)) object *f = sysget("stdout");
fprintf(sysgetfile("stdout", stdout), "\n"); if (softspace(f, 0))
writestring("\n", f);
} }
......
...@@ -214,7 +214,7 @@ run_command(command) ...@@ -214,7 +214,7 @@ run_command(command)
void void
print_error() print_error()
{ {
object *exception, *v; object *exception, *v, *f;
err_get(&exception, &v); err_get(&exception, &v);
if (exception == SystemExit) { if (exception == SystemExit) {
if (v == NULL || v == None) if (v == NULL || v == None)
...@@ -222,6 +222,7 @@ print_error() ...@@ -222,6 +222,7 @@ print_error()
if (is_intobject(v)) if (is_intobject(v))
goaway((int)getintvalue(v)); goaway((int)getintvalue(v));
else { else {
/* OK to use real stderr here */
printobject(v, stderr, PRINT_RAW); printobject(v, stderr, PRINT_RAW);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
goaway(1); goaway(1);
...@@ -229,17 +230,22 @@ print_error() ...@@ -229,17 +230,22 @@ print_error()
} }
sysset("last_type", exception); sysset("last_type", exception);
sysset("last_value", v); sysset("last_value", v);
if (printobject(exception, stderr, PRINT_RAW) != 0) f = sysget("stderr");
err_clear(); if (f == NULL)
if (v != NULL && v != None) { fprintf(stderr, "lost sys.stderr\n");
fprintf(stderr, ": "); else {
if (printobject(v, stderr, PRINT_RAW) != 0) if (writeobject(exception, f, PRINT_RAW) != 0)
err_clear(); 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(exception);
XDECREF(v); XDECREF(v);
printtraceback(stderr);
} }
object * object *
......
...@@ -62,7 +62,7 @@ sysgetfile(name, def) ...@@ -62,7 +62,7 @@ sysgetfile(name, def)
{ {
FILE *fp = NULL; FILE *fp = NULL;
object *v = sysget(name); object *v = sysget(name);
if (v != NULL) if (v != NULL && is_fileobject(v))
fp = getfilefile(v); fp = getfilefile(v);
if (fp == NULL) if (fp == NULL)
fp = def; fp = def;
......
...@@ -150,8 +150,8 @@ tb_store(v) ...@@ -150,8 +150,8 @@ tb_store(v)
} }
static void static void
tb_displayline(fp, filename, lineno) tb_displayline(f, filename, lineno)
FILE *fp; object *f;
char *filename; char *filename;
int lineno; int lineno;
{ {
...@@ -189,15 +189,17 @@ tb_displayline(fp, filename, 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 */ #ifdef applec /* MPW */
/* This is needed by MPW's File and Line commands */ /* This is needed by MPW's File and Line commands */
fprintf(fp, "; "); ";",
#else #else
/* This is needed by Emacs' compile command */ /* This is needed by Emacs' compile command */
fprintf(fp, ", "); ",",
#endif #endif
fprintf(fp, "line %d\n", lineno); lineno);
writestring(linebuf, f);
if (xfp == NULL) if (xfp == NULL)
return; return;
for (i = 0; i < lineno; i++) { for (i = 0; i < lineno; i++) {
...@@ -208,20 +210,21 @@ tb_displayline(fp, filename, lineno) ...@@ -208,20 +210,21 @@ tb_displayline(fp, filename, lineno)
char *p = linebuf; char *p = linebuf;
while (*p == ' ' || *p == '\t') while (*p == ' ' || *p == '\t')
p++; p++;
fprintf(fp, " %s", p); writestring(" ", f);
writestring(p, f);
if (strchr(p, '\n') == NULL) if (strchr(p, '\n') == NULL)
fprintf(fp, "\n"); writestring("\n", f);
} }
fclose(xfp); fclose(xfp);
} }
static void static void
tb_printinternal(tb, fp) tb_printinternal(tb, f)
tracebackobject *tb; tracebackobject *tb;
FILE *fp; object *f;
{ {
while (tb != NULL && !intrcheck()) { while (tb != NULL && !intrcheck()) {
tb_displayline(fp, tb_displayline(f,
getstringvalue(tb->tb_frame->f_code->co_filename), getstringvalue(tb->tb_frame->f_code->co_filename),
tb->tb_lineno); tb->tb_lineno);
tb = tb->tb_next; tb = tb->tb_next;
...@@ -229,9 +232,9 @@ tb_printinternal(tb, fp) ...@@ -229,9 +232,9 @@ tb_printinternal(tb, fp)
} }
int int
tb_print(v, fp) tb_print(v, f)
object *v; object *v;
FILE *fp; object *f;
{ {
if (v == NULL) if (v == NULL)
return 0; return 0;
...@@ -240,6 +243,6 @@ tb_print(v, fp) ...@@ -240,6 +243,6 @@ tb_print(v, fp)
return -1; return -1;
} }
sysset("last_traceback", v); sysset("last_traceback", v);
tb_printinternal((tracebackobject *)v, fp); tb_printinternal((tracebackobject *)v, f);
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment