blob: df27caf41fba4a7944113a2d5310ecd4bad1525d [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The 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 Rossum295d1711995-02-19 15:55:19 +000032#ifdef THINK_C
33#define HAVE_FOPENRF
34#endif
35
Guido van Rossumce5ba841991-03-06 13:06:18 +000036#define BUF(v) GETSTRINGVALUE((stringobject *)v)
37
Guido van Rossumf1dc5661993-07-05 10:31:29 +000038#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039
40typedef struct {
41 OB_HEAD
42 FILE *f_fp;
43 object *f_name;
44 object *f_mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000045 int (*f_close) PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000046 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047} fileobject;
48
49FILE *
50getfilefile(f)
51 object *f;
52{
Guido van Rossum3165fe61992-09-25 21:59:05 +000053 if (f == NULL || !is_fileobject(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000055 else
56 return ((fileobject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057}
58
59object *
Guido van Rossumdb3165e1993-10-18 17:06:59 +000060getfilename(f)
61 object *f;
62{
63 if (f == NULL || !is_fileobject(f))
64 return NULL;
65 else
66 return ((fileobject *)f)->f_name;
67}
68
69object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000070newopenfileobject(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071 FILE *fp;
72 char *name;
73 char *mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000074 int (*close) FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075{
76 fileobject *f = NEWOBJ(fileobject, &Filetype);
77 if (f == NULL)
78 return NULL;
79 f->f_fp = NULL;
80 f->f_name = newstringobject(name);
81 f->f_mode = newstringobject(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000082 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000083 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000084 if (f->f_name == NULL || f->f_mode == NULL) {
85 DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086 return NULL;
87 }
88 f->f_fp = fp;
89 return (object *) f;
90}
91
92object *
93newfileobject(name, mode)
94 char *name, *mode;
95{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000096 extern int fclose PROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 fileobject *f;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000098 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099 if (f == NULL)
100 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000101#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000102 if (*mode == '*') {
103 FILE *fopenRF();
104 f->f_fp = fopenRF(name, mode+1);
105 }
106 else
107#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000108 {
109 BGN_SAVE
110 f->f_fp = fopen(name, mode);
111 END_SAVE
112 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000113 if (f->f_fp == NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000114 err_errno(IOError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115 DECREF(f);
116 return NULL;
117 }
118 return (object *)f;
119}
120
Guido van Rossumb6775db1994-08-01 11:34:53 +0000121void
122setfilebufsize(f, bufsize)
123 object *f;
124 int bufsize;
125{
126 if (bufsize >= 0) {
127#ifdef HAVE_SETVBUF
128 int type;
129 switch (bufsize) {
130 case 0:
131 type = _IONBF;
132 break;
133 case 1:
134 type = _IOLBF;
135 bufsize = BUFSIZ;
136 break;
137 default:
138 type = _IOFBF;
139 }
140 setvbuf(((fileobject *)f)->f_fp, (char *)NULL, type, bufsize);
141#endif /* HAVE_SETVBUF */
142 }
143}
144
Guido van Rossumd7297e61992-07-06 14:19:26 +0000145static object *
146err_closed()
147{
148 err_setstr(ValueError, "I/O operation on closed file");
149 return NULL;
150}
151
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152/* Methods */
153
154static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000155file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156 fileobject *f;
157{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000158 if (f->f_fp != NULL && f->f_close != NULL) {
159 BGN_SAVE
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000160 (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000161 END_SAVE
162 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163 if (f->f_name != NULL)
164 DECREF(f->f_name);
165 if (f->f_mode != NULL)
166 DECREF(f->f_mode);
167 free((char *)f);
168}
169
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000170static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000171file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 fileobject *f;
173{
174 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000175 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 f->f_fp == NULL ? "closed" : "open",
177 getstringvalue(f->f_name),
Guido van Rossume35399e1993-01-10 18:33:56 +0000178 getstringvalue(f->f_mode),
179 (long)f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180 return newstringobject(buf);
181}
182
183static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000184file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000185 fileobject *f;
186 object *args;
187{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000188 int sts = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000189 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000190 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000192 if (f->f_close != NULL) {
193 BGN_SAVE
194 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000195 sts = (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000196 END_SAVE
197 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198 f->f_fp = NULL;
199 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000200 if (sts == EOF)
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000201 return err_errno(IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000202 if (sts != 0)
203 return newintobject((long)sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000204 INCREF(None);
205 return None;
206}
207
208static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000209file_seek(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210 fileobject *f;
211 object *args;
212{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000213 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000214 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000215 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000216
Guido van Rossumd7297e61992-07-06 14:19:26 +0000217 if (f->f_fp == NULL)
218 return err_closed();
219 whence = 0;
220 if (!getargs(args, "l", &offset)) {
221 err_clear();
222 if (!getargs(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000223 return NULL;
224 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000225 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000226 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000227 ret = fseek(f->f_fp, offset, whence);
228 END_SAVE
229 if (ret != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000230 err_errno(IOError);
231 clearerr(f->f_fp);
232 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000233 }
234 INCREF(None);
235 return None;
236}
237
Guido van Rossumd7047b31995-01-02 19:07:15 +0000238#ifdef HAVE_FTRUNCATE
239static object *
240file_truncate(f, args)
241 fileobject *f;
242 object *args;
243{
244 long newsize;
245 int ret;
246
247 if (f->f_fp == NULL)
248 return err_closed();
249 if (!getargs(args, "l", &newsize)) {
250 err_clear();
251 if (!getnoarg(args))
252 return NULL;
253 BGN_SAVE
254 errno = 0;
255 newsize = ftell(f->f_fp); /* default to current position*/
256 END_SAVE
257 if (newsize == -1L) {
258 err_errno(IOError);
259 clearerr(f->f_fp);
260 return NULL;
261 }
262 }
263 BGN_SAVE
264 errno = 0;
265 ret = fflush(f->f_fp);
266 END_SAVE
267 if (ret == 0) {
268 BGN_SAVE
269 errno = 0;
270 ret = ftruncate(fileno(f->f_fp), newsize);
271 END_SAVE
272 }
273 if (ret != 0) {
274 err_errno(IOError);
275 clearerr(f->f_fp);
276 return NULL;
277 }
278 INCREF(None);
279 return None;
280}
281#endif /* HAVE_FTRUNCATE */
282
Guido van Rossumce5ba841991-03-06 13:06:18 +0000283static object *
284file_tell(f, args)
285 fileobject *f;
286 object *args;
287{
288 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000289 if (f->f_fp == NULL)
290 return err_closed();
291 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000293 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000294 errno = 0;
295 offset = ftell(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000296 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000297 if (offset == -1L) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000298 err_errno(IOError);
299 clearerr(f->f_fp);
300 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000301 }
302 return newintobject(offset);
303}
304
305static object *
Guido van Rossumed233a51992-06-23 09:07:03 +0000306file_fileno(f, args)
307 fileobject *f;
308 object *args;
309{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000310 if (f->f_fp == NULL)
311 return err_closed();
Guido van Rossumed233a51992-06-23 09:07:03 +0000312 if (!getnoarg(args))
313 return NULL;
314 return newintobject((long) fileno(f->f_fp));
315}
316
317static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000318file_flush(f, args)
319 fileobject *f;
320 object *args;
321{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000322 int res;
323
Guido van Rossumd7297e61992-07-06 14:19:26 +0000324 if (f->f_fp == NULL)
325 return err_closed();
326 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000327 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000328 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000329 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000330 res = fflush(f->f_fp);
331 END_SAVE
332 if (res != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000333 err_errno(IOError);
334 clearerr(f->f_fp);
335 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000336 }
337 INCREF(None);
338 return None;
339}
340
341static object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000342file_isatty(f, args)
343 fileobject *f;
344 object *args;
345{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000346 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000347 if (f->f_fp == NULL)
348 return err_closed();
349 if (!getnoarg(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000350 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000351 BGN_SAVE
352 res = isatty((int)fileno(f->f_fp));
353 END_SAVE
354 return newintobject(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000355}
356
357static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000358file_read(f, args)
359 fileobject *f;
360 object *args;
361{
362 int n, n1, n2, n3;
363 object *v;
364
Guido van Rossumd7297e61992-07-06 14:19:26 +0000365 if (f->f_fp == NULL)
366 return err_closed();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000367 if (args == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000368 n = 0;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000369 else {
370 if (!getargs(args, "i", &n))
371 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000372 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000373 err_setstr(ValueError, "negative read count");
Guido van Rossumce5ba841991-03-06 13:06:18 +0000374 return NULL;
375 }
376 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000377 n2 = n != 0 ? n : BUFSIZ;
378 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000379 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000380 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000381 n1 = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000382 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000383 for (;;) {
384 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
385 /* XXX Error check? */
386 if (n3 == 0)
387 break;
388 n1 += n3;
389 if (n1 == n)
390 break;
391 if (n == 0) {
392 n2 = n1 + BUFSIZ;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000393 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000394 if (resizestring(&v, n2) < 0)
395 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000396 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000397 }
398 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000399 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000400 if (n1 != n2)
401 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000402 return v;
403}
404
Guido van Rossum0bd24411991-04-04 15:21:57 +0000405/* Internal routine to get a line.
406 Size argument interpretation:
407 > 0: max length;
408 = 0: read arbitrary line;
409 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000410*/
411
Guido van Rossum234f9421993-06-17 12:35:49 +0000412static object *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000413getline(f, n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000414 fileobject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000415 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000416{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000417 register FILE *fp;
418 register int c;
419 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000420 int n1, n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000421 object *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000422
Guido van Rossumc10aa771992-07-31 12:42:38 +0000423 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000424 n2 = n > 0 ? n : 100;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000425 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000426 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000427 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000428 buf = BUF(v);
429 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000430
Guido van Rossumff4949e1992-08-05 19:58:53 +0000431 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000432 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000433 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000434 clearerr(fp);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000435 if (sigcheck()) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000436 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000437 DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000438 return NULL;
439 }
440 if (n < 0 && buf == BUF(v)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000441 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000442 DECREF(v);
Guido van Rossum201be051991-12-24 13:26:41 +0000443 err_setstr(EOFError,
444 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000445 return NULL;
446 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000447 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000448 }
449 if ((*buf++ = c) == '\n') {
450 if (n < 0)
451 buf--;
452 break;
453 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000454 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000455 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000456 break;
457 n1 = n2;
458 n2 += 1000;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000459 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000460 if (resizestring(&v, n2) < 0)
461 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000462 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000463 buf = BUF(v) + n1;
464 end = BUF(v) + n2;
465 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000466 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000467 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000468
Guido van Rossumce5ba841991-03-06 13:06:18 +0000469 n1 = buf - BUF(v);
470 if (n1 != n2)
471 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000472 return v;
473}
474
Guido van Rossum0bd24411991-04-04 15:21:57 +0000475/* External C interface */
476
477object *
478filegetline(f, n)
479 object *f;
480 int n;
481{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000482 if (f == NULL) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000483 err_badcall();
484 return NULL;
485 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000486 if (!is_fileobject(f)) {
487 object *reader;
488 object *args;
489 object *result;
490 reader = getattr(f, "readline");
491 if (reader == NULL)
492 return NULL;
493 if (n <= 0)
494 args = mkvalue("()");
495 else
496 args = mkvalue("(i)", n);
497 if (args == NULL) {
498 DECREF(reader);
499 return NULL;
500 }
501 result = call_object(reader, args);
502 DECREF(reader);
503 DECREF(args);
504 if (result != NULL && !is_stringobject(result)) {
505 DECREF(result);
506 result = NULL;
507 err_setstr(TypeError,
508 "object.readline() returned non-string");
509 }
510 if (n < 0 && result != NULL) {
511 char *s = getstringvalue(result);
512 int len = getstringsize(result);
513 if (len == 0) {
514 DECREF(result);
515 result = NULL;
516 err_setstr(EOFError,
517 "EOF when reading a line");
518 }
519 else if (s[len-1] == '\n') {
520 if (result->ob_refcnt == 1)
521 resizestring(&result, len-1);
522 else {
523 object *v;
Guido van Rossumde788b81992-12-22 14:24:04 +0000524 v = newsizedstringobject(s, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000525 DECREF(result);
526 result = v;
527 }
528 }
529 }
530 return result;
531 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000532 if (((fileobject*)f)->f_fp == NULL)
533 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000534 return getline((fileobject *)f, n);
535}
536
537/* Python method */
538
539static object *
540file_readline(f, args)
541 fileobject *f;
542 object *args;
543{
544 int n;
545
Guido van Rossumd7297e61992-07-06 14:19:26 +0000546 if (f->f_fp == NULL)
547 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000548 if (args == NULL)
549 n = 0; /* Unlimited */
550 else {
551 if (!getintarg(args, &n))
552 return NULL;
553 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000554 err_setstr(ValueError, "negative readline count");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000555 return NULL;
556 }
557 }
558
Guido van Rossum51415a71992-03-27 17:23:38 +0000559 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000560}
561
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000562static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000563file_readlines(f, args)
564 fileobject *f;
565 object *args;
566{
567 object *list;
568 object *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000569
Guido van Rossumd7297e61992-07-06 14:19:26 +0000570 if (f->f_fp == NULL)
571 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000572 if (!getnoarg(args))
573 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000574 if ((list = newlistobject(0)) == NULL)
575 return NULL;
576 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000577 line = getline(f, 0);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000578 if (line != NULL && getstringsize(line) == 0) {
579 DECREF(line);
580 break;
581 }
582 if (line == NULL || addlistitem(list, line) != 0) {
583 DECREF(list);
584 XDECREF(line);
585 return NULL;
586 }
587 DECREF(line);
588 }
589 return list;
590}
591
592static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000593file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000594 fileobject *f;
595 object *args;
596{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000597 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000598 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000599 if (f->f_fp == NULL)
600 return err_closed();
601 if (!getargs(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000602 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000603 f->f_softspace = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000604 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000605 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000606 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000607 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000608 if (n2 != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000609 err_errno(IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000610 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000611 return NULL;
612 }
613 INCREF(None);
614 return None;
615}
616
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000617static object *
618file_writelines(f, args)
619 fileobject *f;
620 object *args;
621{
622 int i, n;
623 if (f->f_fp == NULL)
624 return err_closed();
625 if (args == NULL || !is_listobject(args)) {
626 err_setstr(TypeError,
627 "writelines() requires list of strings");
628 return NULL;
629 }
630 n = getlistsize(args);
631 f->f_softspace = 0;
632 BGN_SAVE
633 errno = 0;
634 for (i = 0; i < n; i++) {
635 object *line = getlistitem(args, i);
636 int len;
637 int nwritten;
638 if (!is_stringobject(line)) {
639 RET_SAVE
640 err_setstr(TypeError,
641 "writelines() requires list of strings");
642 return NULL;
643 }
644 len = getstringsize(line);
645 nwritten = fwrite(getstringvalue(line), 1, len, f->f_fp);
646 if (nwritten != len) {
647 RET_SAVE
648 err_errno(IOError);
649 clearerr(f->f_fp);
650 return NULL;
651 }
652 }
653 END_SAVE
654 INCREF(None);
655 return None;
656}
657
Guido van Rossum3f5da241990-12-20 15:06:42 +0000658static struct methodlist file_methods[] = {
Guido van Rossum295d1711995-02-19 15:55:19 +0000659 {"close", (method)file_close, 0},
660 {"flush", (method)file_flush, 0},
661 {"fileno", (method)file_fileno, 0},
662 {"isatty", (method)file_isatty, 0},
663 {"read", (method)file_read, 0},
664 {"readline", (method)file_readline, 0},
665 {"readlines", (method)file_readlines, 0},
666 {"seek", (method)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000667#ifdef HAVE_FTRUNCATE
Guido van Rossum295d1711995-02-19 15:55:19 +0000668 {"truncate", (method)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000669#endif
Guido van Rossum295d1711995-02-19 15:55:19 +0000670 {"tell", (method)file_tell, 0},
671 {"write", (method)file_write, 0},
672 {"writelines", (method)file_writelines, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000673 {NULL, NULL} /* sentinel */
674};
675
Guido van Rossumb6775db1994-08-01 11:34:53 +0000676#define OFF(x) offsetof(fileobject, x)
677
678static struct memberlist file_memberlist[] = {
679 {"softspace", T_INT, OFF(f_softspace)},
680 {"mode", T_OBJECT, OFF(f_mode), RO},
681 {"name", T_OBJECT, OFF(f_name), RO},
682 /* getattr(f, "closed") is implemented without this table */
683 {"closed", T_INT, 0, RO},
684 {NULL} /* Sentinel */
685};
686
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000687static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000688file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000689 fileobject *f;
690 char *name;
691{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000692 object *res;
693
694 res = findmethod(file_methods, (object *)f, name);
695 if (res != NULL)
696 return res;
697 err_clear();
698 if (strcmp(name, "closed") == 0)
699 return newintobject((long)(f->f_fp == 0));
700 return getmember((char *)f, file_memberlist, name);
701}
702
703static int
704file_setattr(f, name, v)
705 fileobject *f;
706 char *name;
707 object *v;
708{
709 if (v == NULL) {
710 err_setstr(AttributeError, "can't delete file attributes");
711 return -1;
712 }
713 return setmember((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000714}
715
716typeobject Filetype = {
717 OB_HEAD_INIT(&Typetype)
718 0,
719 "file",
720 sizeof(fileobject),
721 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000722 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000723 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000724 (getattrfunc)file_getattr, /*tp_getattr*/
725 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000726 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000727 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000728};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000729
730/* Interface for the 'soft space' between print items. */
731
732int
733softspace(f, newflag)
734 object *f;
735 int newflag;
736{
737 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000738 if (f == NULL) {
739 /* Do nothing */
740 }
Guido van Rossum82d410e1993-11-01 16:26:16 +0000741 else if (is_fileobject(f)) {
Guido van Rossumeb183da1991-04-04 10:44:06 +0000742 oldflag = ((fileobject *)f)->f_softspace;
743 ((fileobject *)f)->f_softspace = newflag;
744 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000745 else {
746 object *v;
747 v = getattr(f, "softspace");
748 if (v == NULL)
749 err_clear();
750 else {
751 if (is_intobject(v))
752 oldflag = getintvalue(v);
753 DECREF(v);
754 }
755 v = newintobject((long)newflag);
756 if (v == NULL)
757 err_clear();
758 else {
759 if (setattr(f, "softspace", v) != 0)
760 err_clear();
761 DECREF(v);
762 }
763 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000764 return oldflag;
765}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000766
767/* Interfaces to write objects/strings to file-like objects */
768
769int
770writeobject(v, f, flags)
771 object *v;
772 object *f;
773 int flags;
774{
775 object *writer, *value, *result;
776 if (f == NULL) {
777 err_setstr(TypeError, "writeobject with NULL file");
778 return -1;
779 }
780 else if (is_fileobject(f)) {
781 FILE *fp = getfilefile(f);
782 if (fp == NULL) {
783 err_closed();
784 return -1;
785 }
786 return printobject(v, fp, flags);
787 }
788 writer = getattr(f, "write");
789 if (writer == NULL)
790 return -1;
Guido van Rossumc6004111993-11-05 10:22:19 +0000791 if (flags & PRINT_RAW)
792 value = strobject(v);
793 else
Guido van Rossum3165fe61992-09-25 21:59:05 +0000794 value = reprobject(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000795 if (value == NULL) {
796 DECREF(writer);
797 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000798 }
799 result = call_object(writer, value);
800 DECREF(writer);
801 DECREF(value);
802 if (result == NULL)
803 return -1;
804 DECREF(result);
805 return 0;
806}
807
808void
809writestring(s, f)
810 char *s;
811 object *f;
812{
813 if (f == NULL) {
814 /* Do nothing */
815 }
816 else if (is_fileobject(f)) {
817 FILE *fp = getfilefile(f);
818 if (fp != NULL)
819 fputs(s, fp);
820 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000821 else if (!err_occurred()) {
Guido van Rossum3165fe61992-09-25 21:59:05 +0000822 object *v = newstringobject(s);
823 if (v == NULL) {
824 err_clear();
825 }
826 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000827 if (writeobject(v, f, PRINT_RAW) != 0)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000828 err_clear();
829 DECREF(v);
830 }
831 }
832}