mirror of
https://github.com/python/cpython.git
synced 2025-10-21 22:22:48 +00:00
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.
This commit is contained in:
parent
3a40ae4ef3
commit
3165fe6a56
8 changed files with 217 additions and 76 deletions
|
@ -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.
|
||||||
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 *
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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()
|
||||||
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()
|
||||||
}
|
}
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue