blob: faf7e861414f67e44f8cbd683ea36689ba24cf3f [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 Rossum3f5da241990-12-20 15:06:42 +000033#include "errno.h"
34#ifndef errno
35extern int errno;
36#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000037
38typedef struct {
39 OB_HEAD
40 FILE *f_fp;
41 object *f_name;
42 object *f_mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000043 int (*f_close) PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000044 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000045} fileobject;
46
47FILE *
48getfilefile(f)
49 object *f;
50{
Guido van Rossum3165fe61992-09-25 21:59:05 +000051 if (f == NULL || !is_fileobject(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000053 else
54 return ((fileobject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000055}
56
57object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000058newopenfileobject(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059 FILE *fp;
60 char *name;
61 char *mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000062 int (*close) FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000063{
64 fileobject *f = NEWOBJ(fileobject, &Filetype);
65 if (f == NULL)
66 return NULL;
67 f->f_fp = NULL;
68 f->f_name = newstringobject(name);
69 f->f_mode = newstringobject(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000070 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000071 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000072 if (f->f_name == NULL || f->f_mode == NULL) {
73 DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074 return NULL;
75 }
76 f->f_fp = fp;
77 return (object *) f;
78}
79
80object *
81newfileobject(name, mode)
82 char *name, *mode;
83{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000084 extern int fclose PROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085 fileobject *f;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000086 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087 if (f == NULL)
88 return NULL;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000089#ifdef USE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +000090 if (*mode == '*') {
91 FILE *fopenRF();
92 f->f_fp = fopenRF(name, mode+1);
93 }
94 else
95#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +000096 {
97 BGN_SAVE
98 f->f_fp = fopen(name, mode);
99 END_SAVE
100 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000101 if (f->f_fp == NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000102 err_errno(IOError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103 DECREF(f);
104 return NULL;
105 }
106 return (object *)f;
107}
108
Guido van Rossumd7297e61992-07-06 14:19:26 +0000109static object *
110err_closed()
111{
112 err_setstr(ValueError, "I/O operation on closed file");
113 return NULL;
114}
115
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116/* Methods */
117
118static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000119file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120 fileobject *f;
121{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000122 if (f->f_fp != NULL && f->f_close != NULL) {
123 BGN_SAVE
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000124 (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000125 END_SAVE
126 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127 if (f->f_name != NULL)
128 DECREF(f->f_name);
129 if (f->f_mode != NULL)
130 DECREF(f->f_mode);
131 free((char *)f);
132}
133
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000135file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136 fileobject *f;
137{
138 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000139 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000140 f->f_fp == NULL ? "closed" : "open",
141 getstringvalue(f->f_name),
Guido van Rossume35399e1993-01-10 18:33:56 +0000142 getstringvalue(f->f_mode),
143 (long)f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000144 return newstringobject(buf);
145}
146
147static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000148file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149 fileobject *f;
150 object *args;
151{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000152 int sts = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000153 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000156 if (f->f_close != NULL) {
157 BGN_SAVE
158 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000159 sts = (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000160 END_SAVE
161 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162 f->f_fp = NULL;
163 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000164 if (sts == EOF)
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000165 return err_errno(IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000166 if (sts != 0)
167 return newintobject((long)sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 INCREF(None);
169 return None;
170}
171
172static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000173file_seek(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174 fileobject *f;
175 object *args;
176{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000177 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000178 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000179 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000180
Guido van Rossumd7297e61992-07-06 14:19:26 +0000181 if (f->f_fp == NULL)
182 return err_closed();
183 whence = 0;
184 if (!getargs(args, "l", &offset)) {
185 err_clear();
186 if (!getargs(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000187 return NULL;
188 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000189 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000190 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000191 ret = fseek(f->f_fp, offset, whence);
192 END_SAVE
193 if (ret != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000194 err_errno(IOError);
195 clearerr(f->f_fp);
196 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000197 }
198 INCREF(None);
199 return None;
200}
201
202static object *
203file_tell(f, args)
204 fileobject *f;
205 object *args;
206{
207 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000208 if (f->f_fp == NULL)
209 return err_closed();
210 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000212 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000213 errno = 0;
214 offset = ftell(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000215 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000216 if (offset == -1L) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000217 err_errno(IOError);
218 clearerr(f->f_fp);
219 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000220 }
221 return newintobject(offset);
222}
223
224static object *
Guido van Rossumed233a51992-06-23 09:07:03 +0000225file_fileno(f, args)
226 fileobject *f;
227 object *args;
228{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000229 if (f->f_fp == NULL)
230 return err_closed();
Guido van Rossumed233a51992-06-23 09:07:03 +0000231 if (!getnoarg(args))
232 return NULL;
233 return newintobject((long) fileno(f->f_fp));
234}
235
236static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000237file_flush(f, args)
238 fileobject *f;
239 object *args;
240{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000241 int res;
242
Guido van Rossumd7297e61992-07-06 14:19:26 +0000243 if (f->f_fp == NULL)
244 return err_closed();
245 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000246 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000247 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000248 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000249 res = fflush(f->f_fp);
250 END_SAVE
251 if (res != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000252 err_errno(IOError);
253 clearerr(f->f_fp);
254 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000255 }
256 INCREF(None);
257 return None;
258}
259
260static object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000261file_isatty(f, args)
262 fileobject *f;
263 object *args;
264{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000265 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000266 if (f->f_fp == NULL)
267 return err_closed();
268 if (!getnoarg(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000269 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000270 BGN_SAVE
271 res = isatty((int)fileno(f->f_fp));
272 END_SAVE
273 return newintobject(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000274}
275
276static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000277file_read(f, args)
278 fileobject *f;
279 object *args;
280{
281 int n, n1, n2, n3;
282 object *v;
283
Guido van Rossumd7297e61992-07-06 14:19:26 +0000284 if (f->f_fp == NULL)
285 return err_closed();
286 if (args == NULL) {
Guido van Rossumce5ba841991-03-06 13:06:18 +0000287 n = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000288 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000289 err_setstr(ValueError, "negative read count");
Guido van Rossumce5ba841991-03-06 13:06:18 +0000290 return NULL;
291 }
292 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000293 else if (!getargs(args, "i", &n))
294 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000295
296 n2 = n != 0 ? n : BUFSIZ;
297 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000298 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000300 n1 = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000301 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000302 for (;;) {
303 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
304 /* XXX Error check? */
305 if (n3 == 0)
306 break;
307 n1 += n3;
308 if (n1 == n)
309 break;
310 if (n == 0) {
311 n2 = n1 + BUFSIZ;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000312 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000313 if (resizestring(&v, n2) < 0)
314 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000315 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000316 }
317 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000318 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000319 if (n1 != n2)
320 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000321 return v;
322}
323
Guido van Rossum0bd24411991-04-04 15:21:57 +0000324/* Internal routine to get a line.
325 Size argument interpretation:
326 > 0: max length;
327 = 0: read arbitrary line;
328 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000329*/
330
Guido van Rossum0bd24411991-04-04 15:21:57 +0000331object *
332getline(f, n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333 fileobject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000334 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000336 register FILE *fp;
337 register int c;
338 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000339 int n1, n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000340 object *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000341
Guido van Rossumc10aa771992-07-31 12:42:38 +0000342 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000343 n2 = n > 0 ? n : 100;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000344 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000345 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000347 buf = BUF(v);
348 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000349
Guido van Rossumff4949e1992-08-05 19:58:53 +0000350 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000351 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000352 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000353 clearerr(fp);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000354 if (intrcheck()) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000355 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000356 DECREF(v);
357 err_set(KeyboardInterrupt);
358 return NULL;
359 }
360 if (n < 0 && buf == BUF(v)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000361 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000362 DECREF(v);
Guido van Rossum201be051991-12-24 13:26:41 +0000363 err_setstr(EOFError,
364 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000365 return NULL;
366 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000367 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000368 }
369 if ((*buf++ = c) == '\n') {
370 if (n < 0)
371 buf--;
372 break;
373 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000374 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000375 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000376 break;
377 n1 = n2;
378 n2 += 1000;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000379 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000380 if (resizestring(&v, n2) < 0)
381 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000382 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000383 buf = BUF(v) + n1;
384 end = BUF(v) + n2;
385 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000386 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000387 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000388
Guido van Rossumce5ba841991-03-06 13:06:18 +0000389 n1 = buf - BUF(v);
390 if (n1 != n2)
391 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000392 return v;
393}
394
Guido van Rossum0bd24411991-04-04 15:21:57 +0000395/* External C interface */
396
397object *
398filegetline(f, n)
399 object *f;
400 int n;
401{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000402 if (f == NULL) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000403 err_badcall();
404 return NULL;
405 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000406 if (!is_fileobject(f)) {
407 object *reader;
408 object *args;
409 object *result;
410 reader = getattr(f, "readline");
411 if (reader == NULL)
412 return NULL;
413 if (n <= 0)
414 args = mkvalue("()");
415 else
416 args = mkvalue("(i)", n);
417 if (args == NULL) {
418 DECREF(reader);
419 return NULL;
420 }
421 result = call_object(reader, args);
422 DECREF(reader);
423 DECREF(args);
424 if (result != NULL && !is_stringobject(result)) {
425 DECREF(result);
426 result = NULL;
427 err_setstr(TypeError,
428 "object.readline() returned non-string");
429 }
430 if (n < 0 && result != NULL) {
431 char *s = getstringvalue(result);
432 int len = getstringsize(result);
433 if (len == 0) {
434 DECREF(result);
435 result = NULL;
436 err_setstr(EOFError,
437 "EOF when reading a line");
438 }
439 else if (s[len-1] == '\n') {
440 if (result->ob_refcnt == 1)
441 resizestring(&result, len-1);
442 else {
443 object *v;
Guido van Rossumde788b81992-12-22 14:24:04 +0000444 v = newsizedstringobject(s, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000445 DECREF(result);
446 result = v;
447 }
448 }
449 }
450 return result;
451 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000452 if (((fileobject*)f)->f_fp == NULL)
453 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000454 return getline((fileobject *)f, n);
455}
456
457/* Python method */
458
459static object *
460file_readline(f, args)
461 fileobject *f;
462 object *args;
463{
464 int n;
465
Guido van Rossumd7297e61992-07-06 14:19:26 +0000466 if (f->f_fp == NULL)
467 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000468 if (args == NULL)
469 n = 0; /* Unlimited */
470 else {
471 if (!getintarg(args, &n))
472 return NULL;
473 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000474 err_setstr(ValueError, "negative readline count");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000475 return NULL;
476 }
477 }
478
Guido van Rossum51415a71992-03-27 17:23:38 +0000479 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000480}
481
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000482static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000483file_readlines(f, args)
484 fileobject *f;
485 object *args;
486{
487 object *list;
488 object *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000489
Guido van Rossumd7297e61992-07-06 14:19:26 +0000490 if (f->f_fp == NULL)
491 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000492 if (!getnoarg(args))
493 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000494 if ((list = newlistobject(0)) == NULL)
495 return NULL;
496 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000497 line = getline(f, 0);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000498 if (line != NULL && getstringsize(line) == 0) {
499 DECREF(line);
500 break;
501 }
502 if (line == NULL || addlistitem(list, line) != 0) {
503 DECREF(list);
504 XDECREF(line);
505 return NULL;
506 }
507 DECREF(line);
508 }
509 return list;
510}
511
512static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000513file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514 fileobject *f;
515 object *args;
516{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000517 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000518 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000519 if (f->f_fp == NULL)
520 return err_closed();
521 if (!getargs(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000522 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000523 f->f_softspace = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000524 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000525 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000526 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000527 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000528 if (n2 != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000529 err_errno(IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000530 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000531 return NULL;
532 }
533 INCREF(None);
534 return None;
535}
536
Guido van Rossum3f5da241990-12-20 15:06:42 +0000537static struct methodlist file_methods[] = {
Guido van Rossumce5ba841991-03-06 13:06:18 +0000538 {"close", file_close},
539 {"flush", file_flush},
Guido van Rossumed233a51992-06-23 09:07:03 +0000540 {"fileno", file_fileno},
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000541 {"isatty", file_isatty},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000542 {"read", file_read},
543 {"readline", file_readline},
Guido van Rossumce5ba841991-03-06 13:06:18 +0000544 {"readlines", file_readlines},
545 {"seek", file_seek},
546 {"tell", file_tell},
547 {"write", file_write},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000548 {NULL, NULL} /* sentinel */
549};
550
551static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000552file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000553 fileobject *f;
554 char *name;
555{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000556 return findmethod(file_methods, (object *)f, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000557}
558
559typeobject Filetype = {
560 OB_HEAD_INIT(&Typetype)
561 0,
562 "file",
563 sizeof(fileobject),
564 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000565 file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000566 0, /*tp_print*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000567 file_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000568 0, /*tp_setattr*/
569 0, /*tp_compare*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000570 file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000571};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000572
573/* Interface for the 'soft space' between print items. */
574
575int
576softspace(f, newflag)
577 object *f;
578 int newflag;
579{
580 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000581 if (f == NULL) {
582 /* Do nothing */
583 }
584 if (is_fileobject(f)) {
Guido van Rossumeb183da1991-04-04 10:44:06 +0000585 oldflag = ((fileobject *)f)->f_softspace;
586 ((fileobject *)f)->f_softspace = newflag;
587 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000588 else {
589 object *v;
590 v = getattr(f, "softspace");
591 if (v == NULL)
592 err_clear();
593 else {
594 if (is_intobject(v))
595 oldflag = getintvalue(v);
596 DECREF(v);
597 }
598 v = newintobject((long)newflag);
599 if (v == NULL)
600 err_clear();
601 else {
602 if (setattr(f, "softspace", v) != 0)
603 err_clear();
604 DECREF(v);
605 }
606 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000607 return oldflag;
608}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000609
610/* Interfaces to write objects/strings to file-like objects */
611
612int
613writeobject(v, f, flags)
614 object *v;
615 object *f;
616 int flags;
617{
618 object *writer, *value, *result;
619 if (f == NULL) {
620 err_setstr(TypeError, "writeobject with NULL file");
621 return -1;
622 }
623 else if (is_fileobject(f)) {
624 FILE *fp = getfilefile(f);
625 if (fp == NULL) {
626 err_closed();
627 return -1;
628 }
629 return printobject(v, fp, flags);
630 }
631 writer = getattr(f, "write");
632 if (writer == NULL)
633 return -1;
634 if ((flags & PRINT_RAW) && is_stringobject(v)) {
635 value = v;
636 INCREF(value);
637 }
638 else {
639 value = reprobject(v);
640 if (value == NULL) {
641 DECREF(writer);
642 return -1;
643 }
644 }
645 result = call_object(writer, value);
646 DECREF(writer);
647 DECREF(value);
648 if (result == NULL)
649 return -1;
650 DECREF(result);
651 return 0;
652}
653
654void
655writestring(s, f)
656 char *s;
657 object *f;
658{
659 if (f == NULL) {
660 /* Do nothing */
661 }
662 else if (is_fileobject(f)) {
663 FILE *fp = getfilefile(f);
664 if (fp != NULL)
665 fputs(s, fp);
666 }
667 else {
668 object *v = newstringobject(s);
669 if (v == NULL) {
670 err_clear();
671 }
672 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000673 if (writeobject(v, f, PRINT_RAW) != 0)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000674 err_clear();
675 DECREF(v);
676 }
677 }
678}