From a19a216bc60160c162e616145ef091dd18ce4e61 Mon Sep 17 00:00:00 2001 From: Skip Montanaro Date: Tue, 16 Feb 2021 14:40:46 -0600 Subject: Python 0.9.1 as posted in alt.sources --- src/fileobject.c | 293 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 src/fileobject.c (limited to 'src/fileobject.c') diff --git a/src/fileobject.c b/src/fileobject.c new file mode 100644 index 0000000..640e27b --- /dev/null +++ b/src/fileobject.c @@ -0,0 +1,293 @@ +/*********************************************************** +Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The +Netherlands. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +******************************************************************/ + +/* File object implementation */ + +/* XXX This should become a built-in module 'io'. It should support more + functionality, better exception handling for invalid calls, etc. + (Especially reading on a write-only file or vice versa!) + It should also cooperate with posix to support popen(), which should + share most code but have a special close function. */ + +#include "allobjects.h" + +#include "errno.h" +#ifndef errno +extern int errno; +#endif + +typedef struct { + OB_HEAD + FILE *f_fp; + object *f_name; + object *f_mode; + /* XXX Should move the 'need space' on printing flag here */ +} fileobject; + +FILE * +getfilefile(f) + object *f; +{ + if (!is_fileobject(f)) { + err_badcall(); + return NULL; + } + return ((fileobject *)f)->f_fp; +} + +object * +newopenfileobject(fp, name, mode) + FILE *fp; + char *name; + char *mode; +{ + fileobject *f = NEWOBJ(fileobject, &Filetype); + if (f == NULL) + return NULL; + f->f_fp = NULL; + f->f_name = newstringobject(name); + f->f_mode = newstringobject(mode); + if (f->f_name == NULL || f->f_mode == NULL) { + DECREF(f); + return NULL; + } + f->f_fp = fp; + return (object *) f; +} + +object * +newfileobject(name, mode) + char *name, *mode; +{ + fileobject *f; + FILE *fp; + f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode); + if (f == NULL) + return NULL; +#ifdef THINK_C + if (*mode == '*') { + FILE *fopenRF(); + f->f_fp = fopenRF(name, mode+1); + } + else +#endif + f->f_fp = fopen(name, mode); + if (f->f_fp == NULL) { + err_errno(RuntimeError); + DECREF(f); + return NULL; + } + return (object *)f; +} + +/* Methods */ + +static void +file_dealloc(f) + fileobject *f; +{ + if (f->f_fp != NULL) + fclose(f->f_fp); + if (f->f_name != NULL) + DECREF(f->f_name); + if (f->f_mode != NULL) + DECREF(f->f_mode); + free((char *)f); +} + +static void +file_print(f, fp, flags) + fileobject *f; + FILE *fp; + int flags; +{ + fprintf(fp, "<%s file ", f->f_fp == NULL ? "closed" : "open"); + printobject(f->f_name, fp, flags); + fprintf(fp, ", mode "); + printobject(f->f_mode, fp, flags); + fprintf(fp, ">"); +} + +static object * +file_repr(f) + fileobject *f; +{ + char buf[300]; + /* XXX This differs from file_print if the filename contains + quotes or other funny characters. */ + sprintf(buf, "<%s file '%.256s', mode '%.10s'>", + f->f_fp == NULL ? "closed" : "open", + getstringvalue(f->f_name), + getstringvalue(f->f_mode)); + return newstringobject(buf); +} + +static object * +file_close(f, args) + fileobject *f; + object *args; +{ + if (args != NULL) { + err_badarg(); + return NULL; + } + if (f->f_fp != NULL) { + fclose(f->f_fp); + f->f_fp = NULL; + } + INCREF(None); + return None; +} + +static object * +file_read(f, args) + fileobject *f; + object *args; +{ + int n; + object *v; + if (f->f_fp == NULL) { + err_badarg(); + return NULL; + } + if (args == NULL || !is_intobject(args)) { + err_badarg(); + return NULL; + } + n = getintvalue(args); + if (n < 0) { + err_badarg(); + return NULL; + } + v = newsizedstringobject((char *)NULL, n); + if (v == NULL) + return NULL; + n = fread(getstringvalue(v), 1, n, f->f_fp); + /* EOF is reported as an empty string */ + /* XXX should detect real I/O errors? */ + resizestring(&v, n); + return v; +} + +/* XXX Should this be unified with raw_input()? */ + +static object * +file_readline(f, args) + fileobject *f; + object *args; +{ + int n; + object *v; + if (f->f_fp == NULL) { + err_badarg(); + return NULL; + } + if (args == NULL) { + n = 10000; /* XXX should really be unlimited */ + } + else if (is_intobject(args)) { + n = getintvalue(args); + if (n < 0) { + err_badarg(); + return NULL; + } + } + else { + err_badarg(); + return NULL; + } + v = newsizedstringobject((char *)NULL, n); + if (v == NULL) + return NULL; +#ifndef THINK_C_3_0 + /* XXX Think C 3.0 wrongly reads up to n characters... */ + n = n+1; +#endif + if (fgets(getstringvalue(v), n, f->f_fp) == NULL) { + /* EOF is reported as an empty string */ + /* XXX should detect real I/O errors? */ + n = 0; + } + else { + n = strlen(getstringvalue(v)); + } + resizestring(&v, n); + return v; +} + +static object * +file_write(f, args) + fileobject *f; + object *args; +{ + int n, n2; + if (f->f_fp == NULL) { + err_badarg(); + return NULL; + } + if (args == NULL || !is_stringobject(args)) { + err_badarg(); + return NULL; + } + errno = 0; + n2 = fwrite(getstringvalue(args), 1, n = getstringsize(args), f->f_fp); + if (n2 != n) { + if (errno == 0) + errno = EIO; + err_errno(RuntimeError); + return NULL; + } + INCREF(None); + return None; +} + +static struct methodlist file_methods[] = { + {"write", file_write}, + {"read", file_read}, + {"readline", file_readline}, + {"close", file_close}, + {NULL, NULL} /* sentinel */ +}; + +static object * +file_getattr(f, name) + fileobject *f; + char *name; +{ + return findmethod(file_methods, (object *)f, name); +} + +typeobject Filetype = { + OB_HEAD_INIT(&Typetype) + 0, + "file", + sizeof(fileobject), + 0, + file_dealloc, /*tp_dealloc*/ + file_print, /*tp_print*/ + file_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + file_repr, /*tp_repr*/ +}; -- cgit v1.2.3