blob: eb8f4aa0652be715b199ae1c6c0ad704e3251079 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumb6775db1994-08-01 11:34:53 +00002Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Guido van Rossum34679b71993-01-26 13:33:44 +00003Amsterdam, 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 Rossumb6775db1994-08-01 11:34:53 +000029#include "structmember.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000030#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000031
Guido van Rossumce5ba841991-03-06 13:06:18 +000032#define BUF(v) GETSTRINGVALUE((stringobject *)v)
33
Guido van Rossumf1dc5661993-07-05 10:31:29 +000034#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000035
36typedef struct {
37 OB_HEAD
38 FILE *f_fp;
39 object *f_name;
40 object *f_mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000041 int (*f_close) PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000042 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043} fileobject;
44
45FILE *
46getfilefile(f)
47 object *f;
48{
Guido van Rossum3165fe61992-09-25 21:59:05 +000049 if (f == NULL || !is_fileobject(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000051 else
52 return ((fileobject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053}
54
55object *
Guido van Rossumdb3165e1993-10-18 17:06:59 +000056getfilename(f)
57 object *f;
58{
59 if (f == NULL || !is_fileobject(f))
60 return NULL;
61 else
62 return ((fileobject *)f)->f_name;
63}
64
65object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000066newopenfileobject(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067 FILE *fp;
68 char *name;
69 char *mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000070 int (*close) FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071{
72 fileobject *f = NEWOBJ(fileobject, &Filetype);
73 if (f == NULL)
74 return NULL;
75 f->f_fp = NULL;
76 f->f_name = newstringobject(name);
77 f->f_mode = newstringobject(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000078 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000079 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080 if (f->f_name == NULL || f->f_mode == NULL) {
81 DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082 return NULL;
83 }
84 f->f_fp = fp;
85 return (object *) f;
86}
87
88object *
89newfileobject(name, mode)
90 char *name, *mode;
91{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000092 extern int fclose PROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000093 fileobject *f;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000094 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095 if (f == NULL)
96 return NULL;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000097#ifdef USE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +000098 if (*mode == '*') {
99 FILE *fopenRF();
100 f->f_fp = fopenRF(name, mode+1);
101 }
102 else
103#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000104 {
105 BGN_SAVE
106 f->f_fp = fopen(name, mode);
107 END_SAVE
108 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000109 if (f->f_fp == NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000110 err_errno(IOError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111 DECREF(f);
112 return NULL;
113 }
114 return (object *)f;
115}
116
Guido van Rossumb6775db1994-08-01 11:34:53 +0000117void
118setfilebufsize(f, bufsize)
119 object *f;
120 int bufsize;
121{
122 if (bufsize >= 0) {
123#ifdef HAVE_SETVBUF
124 int type;
125 switch (bufsize) {
126 case 0:
127 type = _IONBF;
128 break;
129 case 1:
130 type = _IOLBF;
131 bufsize = BUFSIZ;
132 break;
133 default:
134 type = _IOFBF;
135 }
136 setvbuf(((fileobject *)f)->f_fp, (char *)NULL, type, bufsize);
137#endif /* HAVE_SETVBUF */
138 }
139}
140
Guido van Rossumd7297e61992-07-06 14:19:26 +0000141static object *
142err_closed()
143{
144 err_setstr(ValueError, "I/O operation on closed file");
145 return NULL;
146}
147
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148/* Methods */
149
150static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000151file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152 fileobject *f;
153{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000154 if (f->f_fp != NULL && f->f_close != NULL) {
155 BGN_SAVE
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000156 (*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 if (f->f_name != NULL)
160 DECREF(f->f_name);
161 if (f->f_mode != NULL)
162 DECREF(f->f_mode);
163 free((char *)f);
164}
165
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000167file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 fileobject *f;
169{
170 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000171 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 f->f_fp == NULL ? "closed" : "open",
173 getstringvalue(f->f_name),
Guido van Rossume35399e1993-01-10 18:33:56 +0000174 getstringvalue(f->f_mode),
175 (long)f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 return newstringobject(buf);
177}
178
179static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000180file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181 fileobject *f;
182 object *args;
183{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000184 int sts = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000185 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000188 if (f->f_close != NULL) {
189 BGN_SAVE
190 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000191 sts = (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000192 END_SAVE
193 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 f->f_fp = NULL;
195 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000196 if (sts == EOF)
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000197 return err_errno(IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000198 if (sts != 0)
199 return newintobject((long)sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200 INCREF(None);
201 return None;
202}
203
204static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000205file_seek(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206 fileobject *f;
207 object *args;
208{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000209 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000210 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000211 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000212
Guido van Rossumd7297e61992-07-06 14:19:26 +0000213 if (f->f_fp == NULL)
214 return err_closed();
215 whence = 0;
216 if (!getargs(args, "l", &offset)) {
217 err_clear();
218 if (!getargs(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000219 return NULL;
220 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000221 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000222 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000223 ret = fseek(f->f_fp, offset, whence);
224 END_SAVE
225 if (ret != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000226 err_errno(IOError);
227 clearerr(f->f_fp);
228 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000229 }
230 INCREF(None);
231 return None;
232}
233
234static object *
235file_tell(f, args)
236 fileobject *f;
237 object *args;
238{
239 long offset;
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;
246 offset = ftell(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000247 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000248 if (offset == -1L) {
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 return newintobject(offset);
254}
255
256static object *
Guido van Rossumed233a51992-06-23 09:07:03 +0000257file_fileno(f, args)
258 fileobject *f;
259 object *args;
260{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000261 if (f->f_fp == NULL)
262 return err_closed();
Guido van Rossumed233a51992-06-23 09:07:03 +0000263 if (!getnoarg(args))
264 return NULL;
265 return newintobject((long) fileno(f->f_fp));
266}
267
268static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000269file_flush(f, args)
270 fileobject *f;
271 object *args;
272{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000273 int res;
274
Guido van Rossumd7297e61992-07-06 14:19:26 +0000275 if (f->f_fp == NULL)
276 return err_closed();
277 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000279 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000280 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000281 res = fflush(f->f_fp);
282 END_SAVE
283 if (res != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000284 err_errno(IOError);
285 clearerr(f->f_fp);
286 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000287 }
288 INCREF(None);
289 return None;
290}
291
292static object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000293file_isatty(f, args)
294 fileobject *f;
295 object *args;
296{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000297 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000298 if (f->f_fp == NULL)
299 return err_closed();
300 if (!getnoarg(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000301 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000302 BGN_SAVE
303 res = isatty((int)fileno(f->f_fp));
304 END_SAVE
305 return newintobject(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000306}
307
308static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000309file_read(f, args)
310 fileobject *f;
311 object *args;
312{
313 int n, n1, n2, n3;
314 object *v;
315
Guido van Rossumd7297e61992-07-06 14:19:26 +0000316 if (f->f_fp == NULL)
317 return err_closed();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318 if (args == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000319 n = 0;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000320 else {
321 if (!getargs(args, "i", &n))
322 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000323 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000324 err_setstr(ValueError, "negative read count");
Guido van Rossumce5ba841991-03-06 13:06:18 +0000325 return NULL;
326 }
327 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000328 n2 = n != 0 ? n : BUFSIZ;
329 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000330 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000332 n1 = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000333 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000334 for (;;) {
335 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
336 /* XXX Error check? */
337 if (n3 == 0)
338 break;
339 n1 += n3;
340 if (n1 == n)
341 break;
342 if (n == 0) {
343 n2 = n1 + BUFSIZ;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000344 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000345 if (resizestring(&v, n2) < 0)
346 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000347 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000348 }
349 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000350 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000351 if (n1 != n2)
352 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000353 return v;
354}
355
Guido van Rossum0bd24411991-04-04 15:21:57 +0000356/* Internal routine to get a line.
357 Size argument interpretation:
358 > 0: max length;
359 = 0: read arbitrary line;
360 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000361*/
362
Guido van Rossum234f9421993-06-17 12:35:49 +0000363static object *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000364getline(f, n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000365 fileobject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000366 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000367{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000368 register FILE *fp;
369 register int c;
370 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000371 int n1, n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000372 object *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000373
Guido van Rossumc10aa771992-07-31 12:42:38 +0000374 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000375 n2 = n > 0 ? n : 100;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000376 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000377 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000378 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000379 buf = BUF(v);
380 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000381
Guido van Rossumff4949e1992-08-05 19:58:53 +0000382 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000383 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000384 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000385 clearerr(fp);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000386 if (sigcheck()) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000387 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000388 DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000389 return NULL;
390 }
391 if (n < 0 && buf == BUF(v)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000392 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000393 DECREF(v);
Guido van Rossum201be051991-12-24 13:26:41 +0000394 err_setstr(EOFError,
395 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000396 return NULL;
397 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000398 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000399 }
400 if ((*buf++ = c) == '\n') {
401 if (n < 0)
402 buf--;
403 break;
404 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000405 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000406 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000407 break;
408 n1 = n2;
409 n2 += 1000;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000410 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000411 if (resizestring(&v, n2) < 0)
412 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000413 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000414 buf = BUF(v) + n1;
415 end = BUF(v) + n2;
416 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000417 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000418 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000419
Guido van Rossumce5ba841991-03-06 13:06:18 +0000420 n1 = buf - BUF(v);
421 if (n1 != n2)
422 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000423 return v;
424}
425
Guido van Rossum0bd24411991-04-04 15:21:57 +0000426/* External C interface */
427
428object *
429filegetline(f, n)
430 object *f;
431 int n;
432{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000433 if (f == NULL) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000434 err_badcall();
435 return NULL;
436 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000437 if (!is_fileobject(f)) {
438 object *reader;
439 object *args;
440 object *result;
441 reader = getattr(f, "readline");
442 if (reader == NULL)
443 return NULL;
444 if (n <= 0)
445 args = mkvalue("()");
446 else
447 args = mkvalue("(i)", n);
448 if (args == NULL) {
449 DECREF(reader);
450 return NULL;
451 }
452 result = call_object(reader, args);
453 DECREF(reader);
454 DECREF(args);
455 if (result != NULL && !is_stringobject(result)) {
456 DECREF(result);
457 result = NULL;
458 err_setstr(TypeError,
459 "object.readline() returned non-string");
460 }
461 if (n < 0 && result != NULL) {
462 char *s = getstringvalue(result);
463 int len = getstringsize(result);
464 if (len == 0) {
465 DECREF(result);
466 result = NULL;
467 err_setstr(EOFError,
468 "EOF when reading a line");
469 }
470 else if (s[len-1] == '\n') {
471 if (result->ob_refcnt == 1)
472 resizestring(&result, len-1);
473 else {
474 object *v;
Guido van Rossumde788b81992-12-22 14:24:04 +0000475 v = newsizedstringobject(s, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000476 DECREF(result);
477 result = v;
478 }
479 }
480 }
481 return result;
482 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000483 if (((fileobject*)f)->f_fp == NULL)
484 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000485 return getline((fileobject *)f, n);
486}
487
488/* Python method */
489
490static object *
491file_readline(f, args)
492 fileobject *f;
493 object *args;
494{
495 int n;
496
Guido van Rossumd7297e61992-07-06 14:19:26 +0000497 if (f->f_fp == NULL)
498 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000499 if (args == NULL)
500 n = 0; /* Unlimited */
501 else {
502 if (!getintarg(args, &n))
503 return NULL;
504 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000505 err_setstr(ValueError, "negative readline count");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000506 return NULL;
507 }
508 }
509
Guido van Rossum51415a71992-03-27 17:23:38 +0000510 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000511}
512
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000514file_readlines(f, args)
515 fileobject *f;
516 object *args;
517{
518 object *list;
519 object *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000520
Guido van Rossumd7297e61992-07-06 14:19:26 +0000521 if (f->f_fp == NULL)
522 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000523 if (!getnoarg(args))
524 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000525 if ((list = newlistobject(0)) == NULL)
526 return NULL;
527 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000528 line = getline(f, 0);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000529 if (line != NULL && getstringsize(line) == 0) {
530 DECREF(line);
531 break;
532 }
533 if (line == NULL || addlistitem(list, line) != 0) {
534 DECREF(list);
535 XDECREF(line);
536 return NULL;
537 }
538 DECREF(line);
539 }
540 return list;
541}
542
543static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000544file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000545 fileobject *f;
546 object *args;
547{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000548 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000549 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000550 if (f->f_fp == NULL)
551 return err_closed();
552 if (!getargs(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000553 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000554 f->f_softspace = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000555 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000556 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000557 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000558 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000559 if (n2 != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000560 err_errno(IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000561 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000562 return NULL;
563 }
564 INCREF(None);
565 return None;
566}
567
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000568static object *
569file_writelines(f, args)
570 fileobject *f;
571 object *args;
572{
573 int i, n;
574 if (f->f_fp == NULL)
575 return err_closed();
576 if (args == NULL || !is_listobject(args)) {
577 err_setstr(TypeError,
578 "writelines() requires list of strings");
579 return NULL;
580 }
581 n = getlistsize(args);
582 f->f_softspace = 0;
583 BGN_SAVE
584 errno = 0;
585 for (i = 0; i < n; i++) {
586 object *line = getlistitem(args, i);
587 int len;
588 int nwritten;
589 if (!is_stringobject(line)) {
590 RET_SAVE
591 err_setstr(TypeError,
592 "writelines() requires list of strings");
593 return NULL;
594 }
595 len = getstringsize(line);
596 nwritten = fwrite(getstringvalue(line), 1, len, f->f_fp);
597 if (nwritten != len) {
598 RET_SAVE
599 err_errno(IOError);
600 clearerr(f->f_fp);
601 return NULL;
602 }
603 }
604 END_SAVE
605 INCREF(None);
606 return None;
607}
608
Guido van Rossum3f5da241990-12-20 15:06:42 +0000609static struct methodlist file_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000610 {"close", (method)file_close},
611 {"flush", (method)file_flush},
612 {"fileno", (method)file_fileno},
613 {"isatty", (method)file_isatty},
614 {"read", (method)file_read},
615 {"readline", (method)file_readline},
616 {"readlines", (method)file_readlines},
617 {"seek", (method)file_seek},
618 {"tell", (method)file_tell},
619 {"write", (method)file_write},
620 {"writelines", (method)file_writelines},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000621 {NULL, NULL} /* sentinel */
622};
623
Guido van Rossumb6775db1994-08-01 11:34:53 +0000624#define OFF(x) offsetof(fileobject, x)
625
626static struct memberlist file_memberlist[] = {
627 {"softspace", T_INT, OFF(f_softspace)},
628 {"mode", T_OBJECT, OFF(f_mode), RO},
629 {"name", T_OBJECT, OFF(f_name), RO},
630 /* getattr(f, "closed") is implemented without this table */
631 {"closed", T_INT, 0, RO},
632 {NULL} /* Sentinel */
633};
634
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000635static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000636file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000637 fileobject *f;
638 char *name;
639{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000640 object *res;
641
642 res = findmethod(file_methods, (object *)f, name);
643 if (res != NULL)
644 return res;
645 err_clear();
646 if (strcmp(name, "closed") == 0)
647 return newintobject((long)(f->f_fp == 0));
648 return getmember((char *)f, file_memberlist, name);
649}
650
651static int
652file_setattr(f, name, v)
653 fileobject *f;
654 char *name;
655 object *v;
656{
657 if (v == NULL) {
658 err_setstr(AttributeError, "can't delete file attributes");
659 return -1;
660 }
661 return setmember((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000662}
663
664typeobject Filetype = {
665 OB_HEAD_INIT(&Typetype)
666 0,
667 "file",
668 sizeof(fileobject),
669 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000670 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000671 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000672 (getattrfunc)file_getattr, /*tp_getattr*/
673 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000674 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000675 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000676};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000677
678/* Interface for the 'soft space' between print items. */
679
680int
681softspace(f, newflag)
682 object *f;
683 int newflag;
684{
685 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000686 if (f == NULL) {
687 /* Do nothing */
688 }
Guido van Rossum82d410e1993-11-01 16:26:16 +0000689 else if (is_fileobject(f)) {
Guido van Rossumeb183da1991-04-04 10:44:06 +0000690 oldflag = ((fileobject *)f)->f_softspace;
691 ((fileobject *)f)->f_softspace = newflag;
692 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000693 else {
694 object *v;
695 v = getattr(f, "softspace");
696 if (v == NULL)
697 err_clear();
698 else {
699 if (is_intobject(v))
700 oldflag = getintvalue(v);
701 DECREF(v);
702 }
703 v = newintobject((long)newflag);
704 if (v == NULL)
705 err_clear();
706 else {
707 if (setattr(f, "softspace", v) != 0)
708 err_clear();
709 DECREF(v);
710 }
711 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000712 return oldflag;
713}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000714
715/* Interfaces to write objects/strings to file-like objects */
716
717int
718writeobject(v, f, flags)
719 object *v;
720 object *f;
721 int flags;
722{
723 object *writer, *value, *result;
724 if (f == NULL) {
725 err_setstr(TypeError, "writeobject with NULL file");
726 return -1;
727 }
728 else if (is_fileobject(f)) {
729 FILE *fp = getfilefile(f);
730 if (fp == NULL) {
731 err_closed();
732 return -1;
733 }
734 return printobject(v, fp, flags);
735 }
736 writer = getattr(f, "write");
737 if (writer == NULL)
738 return -1;
Guido van Rossumc6004111993-11-05 10:22:19 +0000739 if (flags & PRINT_RAW)
740 value = strobject(v);
741 else
Guido van Rossum3165fe61992-09-25 21:59:05 +0000742 value = reprobject(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000743 if (value == NULL) {
744 DECREF(writer);
745 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000746 }
747 result = call_object(writer, value);
748 DECREF(writer);
749 DECREF(value);
750 if (result == NULL)
751 return -1;
752 DECREF(result);
753 return 0;
754}
755
756void
757writestring(s, f)
758 char *s;
759 object *f;
760{
761 if (f == NULL) {
762 /* Do nothing */
763 }
764 else if (is_fileobject(f)) {
765 FILE *fp = getfilefile(f);
766 if (fp != NULL)
767 fputs(s, fp);
768 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000769 else if (!err_occurred()) {
Guido van Rossum3165fe61992-09-25 21:59:05 +0000770 object *v = newstringobject(s);
771 if (v == NULL) {
772 err_clear();
773 }
774 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000775 if (writeobject(v, f, PRINT_RAW) != 0)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000776 err_clear();
777 DECREF(v);
778 }
779 }
780}