summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/ceval.h2
-rw-r--r--Include/traceback.h2
-rw-r--r--Objects/fileobject.c149
-rw-r--r--Python/bltinmodule.c33
-rw-r--r--Python/ceval.c48
-rw-r--r--Python/pythonrun.c22
-rw-r--r--Python/sysmodule.c2
-rw-r--r--Python/traceback.c35
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, "<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);
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;
}