Kaydet (Commit) 3165fe6a authored tarafından 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.
üst 3a40ae4e
......@@ -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));
......
......@@ -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 *));
......@@ -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);
}
}
}
......@@ -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, "<stdin>", 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);
......
......@@ -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);
}
......
......@@ -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 *
......
......@@ -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;
......
......@@ -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;
}
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