blob: 99cdba2bed399e173ce23de32970cac0475ac5dd [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum34679b71993-01-26 13:33:44 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* File object implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossumfa3da8a1992-01-27 16:53:23 +000028#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000029#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000030
Guido van Rossumce5ba841991-03-06 13:06:18 +000031#define BUF(v) GETSTRINGVALUE((stringobject *)v)
32
Guido van Rossumf1dc5661993-07-05 10:31:29 +000033#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000034
35typedef struct {
36 OB_HEAD
37 FILE *f_fp;
38 object *f_name;
39 object *f_mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000040 int (*f_close) PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000041 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000042} fileobject;
43
44FILE *
45getfilefile(f)
46 object *f;
47{
Guido van Rossum3165fe61992-09-25 21:59:05 +000048 if (f == NULL || !is_fileobject(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000049 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000050 else
51 return ((fileobject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052}
53
54object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000055newopenfileobject(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000056 FILE *fp;
57 char *name;
58 char *mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000059 int (*close) FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060{
61 fileobject *f = NEWOBJ(fileobject, &Filetype);
62 if (f == NULL)
63 return NULL;
64 f->f_fp = NULL;
65 f->f_name = newstringobject(name);
66 f->f_mode = newstringobject(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000067 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000068 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069 if (f->f_name == NULL || f->f_mode == NULL) {
70 DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071 return NULL;
72 }
73 f->f_fp = fp;
74 return (object *) f;
75}
76
77object *
78newfileobject(name, mode)
79 char *name, *mode;
80{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000081 extern int fclose PROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082 fileobject *f;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000083 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000084 if (f == NULL)
85 return NULL;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000086#ifdef USE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +000087 if (*mode == '*') {
88 FILE *fopenRF();
89 f->f_fp = fopenRF(name, mode+1);
90 }
91 else
92#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +000093 {
94 BGN_SAVE
95 f->f_fp = fopen(name, mode);
96 END_SAVE
97 }
Guido van Rossuma08095a1991-02-13 23:25:27 +000098 if (f->f_fp == NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +000099 err_errno(IOError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100 DECREF(f);
101 return NULL;
102 }
103 return (object *)f;
104}
105
Guido van Rossumd7297e61992-07-06 14:19:26 +0000106static object *
107err_closed()
108{
109 err_setstr(ValueError, "I/O operation on closed file");
110 return NULL;
111}
112
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113/* Methods */
114
115static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000116file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117 fileobject *f;
118{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000119 if (f->f_fp != NULL && f->f_close != NULL) {
120 BGN_SAVE
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000121 (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000122 END_SAVE
123 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124 if (f->f_name != NULL)
125 DECREF(f->f_name);
126 if (f->f_mode != NULL)
127 DECREF(f->f_mode);
128 free((char *)f);
129}
130
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000132file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133 fileobject *f;
134{
135 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000136 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137 f->f_fp == NULL ? "closed" : "open",
138 getstringvalue(f->f_name),
Guido van Rossume35399e1993-01-10 18:33:56 +0000139 getstringvalue(f->f_mode),
140 (long)f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000141 return newstringobject(buf);
142}
143
144static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000145file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000146 fileobject *f;
147 object *args;
148{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000149 int sts = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000150 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000153 if (f->f_close != NULL) {
154 BGN_SAVE
155 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000156 sts = (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000157 END_SAVE
158 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159 f->f_fp = NULL;
160 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000161 if (sts == EOF)
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000162 return err_errno(IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000163 if (sts != 0)
164 return newintobject((long)sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165 INCREF(None);
166 return None;
167}
168
169static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000170file_seek(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171 fileobject *f;
172 object *args;
173{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000174 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000175 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000176 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000177
Guido van Rossumd7297e61992-07-06 14:19:26 +0000178 if (f->f_fp == NULL)
179 return err_closed();
180 whence = 0;
181 if (!getargs(args, "l", &offset)) {
182 err_clear();
183 if (!getargs(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000184 return NULL;
185 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000186 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000187 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000188 ret = fseek(f->f_fp, offset, whence);
189 END_SAVE
190 if (ret != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000191 err_errno(IOError);
192 clearerr(f->f_fp);
193 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000194 }
195 INCREF(None);
196 return None;
197}
198
199static object *
200file_tell(f, args)
201 fileobject *f;
202 object *args;
203{
204 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000205 if (f->f_fp == NULL)
206 return err_closed();
207 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000209 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000210 errno = 0;
211 offset = ftell(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000212 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000213 if (offset == -1L) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000214 err_errno(IOError);
215 clearerr(f->f_fp);
216 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000217 }
218 return newintobject(offset);
219}
220
221static object *
Guido van Rossumed233a51992-06-23 09:07:03 +0000222file_fileno(f, args)
223 fileobject *f;
224 object *args;
225{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000226 if (f->f_fp == NULL)
227 return err_closed();
Guido van Rossumed233a51992-06-23 09:07:03 +0000228 if (!getnoarg(args))
229 return NULL;
230 return newintobject((long) fileno(f->f_fp));
231}
232
233static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000234file_flush(f, args)
235 fileobject *f;
236 object *args;
237{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000238 int res;
239
Guido van Rossumd7297e61992-07-06 14:19:26 +0000240 if (f->f_fp == NULL)
241 return err_closed();
242 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000244 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000245 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000246 res = fflush(f->f_fp);
247 END_SAVE
248 if (res != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000249 err_errno(IOError);
250 clearerr(f->f_fp);
251 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000252 }
253 INCREF(None);
254 return None;
255}
256
257static object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000258file_isatty(f, args)
259 fileobject *f;
260 object *args;
261{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000262 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000263 if (f->f_fp == NULL)
264 return err_closed();
265 if (!getnoarg(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000266 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000267 BGN_SAVE
268 res = isatty((int)fileno(f->f_fp));
269 END_SAVE
270 return newintobject(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000271}
272
273static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000274file_read(f, args)
275 fileobject *f;
276 object *args;
277{
278 int n, n1, n2, n3;
279 object *v;
280
Guido van Rossumd7297e61992-07-06 14:19:26 +0000281 if (f->f_fp == NULL)
282 return err_closed();
283 if (args == NULL) {
Guido van Rossumce5ba841991-03-06 13:06:18 +0000284 n = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000285 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000286 err_setstr(ValueError, "negative read count");
Guido van Rossumce5ba841991-03-06 13:06:18 +0000287 return NULL;
288 }
289 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000290 else if (!getargs(args, "i", &n))
291 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000292
293 n2 = n != 0 ? n : BUFSIZ;
294 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000295 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000297 n1 = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000298 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000299 for (;;) {
300 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
301 /* XXX Error check? */
302 if (n3 == 0)
303 break;
304 n1 += n3;
305 if (n1 == n)
306 break;
307 if (n == 0) {
308 n2 = n1 + BUFSIZ;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000309 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000310 if (resizestring(&v, n2) < 0)
311 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000312 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000313 }
314 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000315 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000316 if (n1 != n2)
317 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318 return v;
319}
320
Guido van Rossum0bd24411991-04-04 15:21:57 +0000321/* Internal routine to get a line.
322 Size argument interpretation:
323 > 0: max length;
324 = 0: read arbitrary line;
325 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000326*/
327
Guido van Rossum234f9421993-06-17 12:35:49 +0000328static object *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000329getline(f, n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000330 fileobject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000331 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000332{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000333 register FILE *fp;
334 register int c;
335 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000336 int n1, n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337 object *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000338
Guido van Rossumc10aa771992-07-31 12:42:38 +0000339 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000340 n2 = n > 0 ? n : 100;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000341 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000342 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000343 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000344 buf = BUF(v);
345 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000346
Guido van Rossumff4949e1992-08-05 19:58:53 +0000347 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000348 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000349 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000350 clearerr(fp);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000351 if (intrcheck()) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000352 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000353 DECREF(v);
354 err_set(KeyboardInterrupt);
355 return NULL;
356 }
357 if (n < 0 && buf == BUF(v)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000358 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000359 DECREF(v);
Guido van Rossum201be051991-12-24 13:26:41 +0000360 err_setstr(EOFError,
361 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000362 return NULL;
363 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000364 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000365 }
366 if ((*buf++ = c) == '\n') {
367 if (n < 0)
368 buf--;
369 break;
370 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000371 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000372 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000373 break;
374 n1 = n2;
375 n2 += 1000;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000376 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000377 if (resizestring(&v, n2) < 0)
378 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000379 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000380 buf = BUF(v) + n1;
381 end = BUF(v) + n2;
382 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000383 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000384 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000385
Guido van Rossumce5ba841991-03-06 13:06:18 +0000386 n1 = buf - BUF(v);
387 if (n1 != n2)
388 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389 return v;
390}
391
Guido van Rossum0bd24411991-04-04 15:21:57 +0000392/* External C interface */
393
394object *
395filegetline(f, n)
396 object *f;
397 int n;
398{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000399 if (f == NULL) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000400 err_badcall();
401 return NULL;
402 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000403 if (!is_fileobject(f)) {
404 object *reader;
405 object *args;
406 object *result;
407 reader = getattr(f, "readline");
408 if (reader == NULL)
409 return NULL;
410 if (n <= 0)
411 args = mkvalue("()");
412 else
413 args = mkvalue("(i)", n);
414 if (args == NULL) {
415 DECREF(reader);
416 return NULL;
417 }
418 result = call_object(reader, args);
419 DECREF(reader);
420 DECREF(args);
421 if (result != NULL && !is_stringobject(result)) {
422 DECREF(result);
423 result = NULL;
424 err_setstr(TypeError,
425 "object.readline() returned non-string");
426 }
427 if (n < 0 && result != NULL) {
428 char *s = getstringvalue(result);
429 int len = getstringsize(result);
430 if (len == 0) {
431 DECREF(result);
432 result = NULL;
433 err_setstr(EOFError,
434 "EOF when reading a line");
435 }
436 else if (s[len-1] == '\n') {
437 if (result->ob_refcnt == 1)
438 resizestring(&result, len-1);
439 else {
440 object *v;
Guido van Rossumde788b81992-12-22 14:24:04 +0000441 v = newsizedstringobject(s, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000442 DECREF(result);
443 result = v;
444 }
445 }
446 }
447 return result;
448 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000449 if (((fileobject*)f)->f_fp == NULL)
450 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000451 return getline((fileobject *)f, n);
452}
453
454/* Python method */
455
456static object *
457file_readline(f, args)
458 fileobject *f;
459 object *args;
460{
461 int n;
462
Guido van Rossumd7297e61992-07-06 14:19:26 +0000463 if (f->f_fp == NULL)
464 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000465 if (args == NULL)
466 n = 0; /* Unlimited */
467 else {
468 if (!getintarg(args, &n))
469 return NULL;
470 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000471 err_setstr(ValueError, "negative readline count");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000472 return NULL;
473 }
474 }
475
Guido van Rossum51415a71992-03-27 17:23:38 +0000476 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000477}
478
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000479static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000480file_readlines(f, args)
481 fileobject *f;
482 object *args;
483{
484 object *list;
485 object *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000486
Guido van Rossumd7297e61992-07-06 14:19:26 +0000487 if (f->f_fp == NULL)
488 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000489 if (!getnoarg(args))
490 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000491 if ((list = newlistobject(0)) == NULL)
492 return NULL;
493 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000494 line = getline(f, 0);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000495 if (line != NULL && getstringsize(line) == 0) {
496 DECREF(line);
497 break;
498 }
499 if (line == NULL || addlistitem(list, line) != 0) {
500 DECREF(list);
501 XDECREF(line);
502 return NULL;
503 }
504 DECREF(line);
505 }
506 return list;
507}
508
509static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000510file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511 fileobject *f;
512 object *args;
513{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000514 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000515 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000516 if (f->f_fp == NULL)
517 return err_closed();
518 if (!getargs(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000519 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000520 f->f_softspace = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000521 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000522 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000523 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000524 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000525 if (n2 != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000526 err_errno(IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000527 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000528 return NULL;
529 }
530 INCREF(None);
531 return None;
532}
533
Guido van Rossum3f5da241990-12-20 15:06:42 +0000534static struct methodlist file_methods[] = {
Guido van Rossumce5ba841991-03-06 13:06:18 +0000535 {"close", file_close},
536 {"flush", file_flush},
Guido van Rossumed233a51992-06-23 09:07:03 +0000537 {"fileno", file_fileno},
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000538 {"isatty", file_isatty},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000539 {"read", file_read},
540 {"readline", file_readline},
Guido van Rossumce5ba841991-03-06 13:06:18 +0000541 {"readlines", file_readlines},
542 {"seek", file_seek},
543 {"tell", file_tell},
544 {"write", file_write},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000545 {NULL, NULL} /* sentinel */
546};
547
548static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000549file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000550 fileobject *f;
551 char *name;
552{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000553 return findmethod(file_methods, (object *)f, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000554}
555
556typeobject Filetype = {
557 OB_HEAD_INIT(&Typetype)
558 0,
559 "file",
560 sizeof(fileobject),
561 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000562 file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000563 0, /*tp_print*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000564 file_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000565 0, /*tp_setattr*/
566 0, /*tp_compare*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000567 file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000568};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000569
570/* Interface for the 'soft space' between print items. */
571
572int
573softspace(f, newflag)
574 object *f;
575 int newflag;
576{
577 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000578 if (f == NULL) {
579 /* Do nothing */
580 }
581 if (is_fileobject(f)) {
Guido van Rossumeb183da1991-04-04 10:44:06 +0000582 oldflag = ((fileobject *)f)->f_softspace;
583 ((fileobject *)f)->f_softspace = newflag;
584 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000585 else {
586 object *v;
587 v = getattr(f, "softspace");
588 if (v == NULL)
589 err_clear();
590 else {
591 if (is_intobject(v))
592 oldflag = getintvalue(v);
593 DECREF(v);
594 }
595 v = newintobject((long)newflag);
596 if (v == NULL)
597 err_clear();
598 else {
599 if (setattr(f, "softspace", v) != 0)
600 err_clear();
601 DECREF(v);
602 }
603 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000604 return oldflag;
605}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000606
607/* Interfaces to write objects/strings to file-like objects */
608
609int
610writeobject(v, f, flags)
611 object *v;
612 object *f;
613 int flags;
614{
615 object *writer, *value, *result;
616 if (f == NULL) {
617 err_setstr(TypeError, "writeobject with NULL file");
618 return -1;
619 }
620 else if (is_fileobject(f)) {
621 FILE *fp = getfilefile(f);
622 if (fp == NULL) {
623 err_closed();
624 return -1;
625 }
626 return printobject(v, fp, flags);
627 }
628 writer = getattr(f, "write");
629 if (writer == NULL)
630 return -1;
631 if ((flags & PRINT_RAW) && is_stringobject(v)) {
632 value = v;
633 INCREF(value);
634 }
635 else {
636 value = reprobject(v);
637 if (value == NULL) {
638 DECREF(writer);
639 return -1;
640 }
641 }
642 result = call_object(writer, value);
643 DECREF(writer);
644 DECREF(value);
645 if (result == NULL)
646 return -1;
647 DECREF(result);
648 return 0;
649}
650
651void
652writestring(s, f)
653 char *s;
654 object *f;
655{
656 if (f == NULL) {
657 /* Do nothing */
658 }
659 else if (is_fileobject(f)) {
660 FILE *fp = getfilefile(f);
661 if (fp != NULL)
662 fputs(s, fp);
663 }
664 else {
665 object *v = newstringobject(s);
666 if (v == NULL) {
667 err_clear();
668 }
669 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000670 if (writeobject(v, f, PRINT_RAW) != 0)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000671 err_clear();
672 DECREF(v);
673 }
674 }
675}