blob: 518fe04f141318919de61c0fa5f043c6d16831c9 [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 Rossumdb3165e1993-10-18 17:06:59 +000055getfilename(f)
56 object *f;
57{
58 if (f == NULL || !is_fileobject(f))
59 return NULL;
60 else
61 return ((fileobject *)f)->f_name;
62}
63
64object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000065newopenfileobject(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066 FILE *fp;
67 char *name;
68 char *mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000069 int (*close) FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070{
71 fileobject *f = NEWOBJ(fileobject, &Filetype);
72 if (f == NULL)
73 return NULL;
74 f->f_fp = NULL;
75 f->f_name = newstringobject(name);
76 f->f_mode = newstringobject(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000077 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000078 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079 if (f->f_name == NULL || f->f_mode == NULL) {
80 DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081 return NULL;
82 }
83 f->f_fp = fp;
84 return (object *) f;
85}
86
87object *
88newfileobject(name, mode)
89 char *name, *mode;
90{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000091 extern int fclose PROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092 fileobject *f;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000093 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094 if (f == NULL)
95 return NULL;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000096#ifdef USE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +000097 if (*mode == '*') {
98 FILE *fopenRF();
99 f->f_fp = fopenRF(name, mode+1);
100 }
101 else
102#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000103 {
104 BGN_SAVE
105 f->f_fp = fopen(name, mode);
106 END_SAVE
107 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000108 if (f->f_fp == NULL) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000109 err_errno(IOError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 DECREF(f);
111 return NULL;
112 }
113 return (object *)f;
114}
115
Guido van Rossumd7297e61992-07-06 14:19:26 +0000116static object *
117err_closed()
118{
119 err_setstr(ValueError, "I/O operation on closed file");
120 return NULL;
121}
122
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123/* Methods */
124
125static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000126file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127 fileobject *f;
128{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000129 if (f->f_fp != NULL && f->f_close != NULL) {
130 BGN_SAVE
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000131 (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000132 END_SAVE
133 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 if (f->f_name != NULL)
135 DECREF(f->f_name);
136 if (f->f_mode != NULL)
137 DECREF(f->f_mode);
138 free((char *)f);
139}
140
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000141static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000142file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143 fileobject *f;
144{
145 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000146 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000147 f->f_fp == NULL ? "closed" : "open",
148 getstringvalue(f->f_name),
Guido van Rossume35399e1993-01-10 18:33:56 +0000149 getstringvalue(f->f_mode),
150 (long)f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151 return newstringobject(buf);
152}
153
154static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000155file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156 fileobject *f;
157 object *args;
158{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000159 int sts = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000160 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000161 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000163 if (f->f_close != NULL) {
164 BGN_SAVE
165 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000166 sts = (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000167 END_SAVE
168 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000169 f->f_fp = NULL;
170 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000171 if (sts == EOF)
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000172 return err_errno(IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000173 if (sts != 0)
174 return newintobject((long)sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000175 INCREF(None);
176 return None;
177}
178
179static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000180file_seek(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181 fileobject *f;
182 object *args;
183{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000184 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000185 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000186 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000187
Guido van Rossumd7297e61992-07-06 14:19:26 +0000188 if (f->f_fp == NULL)
189 return err_closed();
190 whence = 0;
191 if (!getargs(args, "l", &offset)) {
192 err_clear();
193 if (!getargs(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000194 return NULL;
195 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000196 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000197 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000198 ret = fseek(f->f_fp, offset, whence);
199 END_SAVE
200 if (ret != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000201 err_errno(IOError);
202 clearerr(f->f_fp);
203 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000204 }
205 INCREF(None);
206 return None;
207}
208
209static object *
210file_tell(f, args)
211 fileobject *f;
212 object *args;
213{
214 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000215 if (f->f_fp == NULL)
216 return err_closed();
217 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000219 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000220 errno = 0;
221 offset = ftell(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000222 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000223 if (offset == -1L) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000224 err_errno(IOError);
225 clearerr(f->f_fp);
226 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000227 }
228 return newintobject(offset);
229}
230
231static object *
Guido van Rossumed233a51992-06-23 09:07:03 +0000232file_fileno(f, args)
233 fileobject *f;
234 object *args;
235{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000236 if (f->f_fp == NULL)
237 return err_closed();
Guido van Rossumed233a51992-06-23 09:07:03 +0000238 if (!getnoarg(args))
239 return NULL;
240 return newintobject((long) fileno(f->f_fp));
241}
242
243static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000244file_flush(f, args)
245 fileobject *f;
246 object *args;
247{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000248 int res;
249
Guido van Rossumd7297e61992-07-06 14:19:26 +0000250 if (f->f_fp == NULL)
251 return err_closed();
252 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000253 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000254 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000255 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000256 res = fflush(f->f_fp);
257 END_SAVE
258 if (res != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000259 err_errno(IOError);
260 clearerr(f->f_fp);
261 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000262 }
263 INCREF(None);
264 return None;
265}
266
267static object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000268file_isatty(f, args)
269 fileobject *f;
270 object *args;
271{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000272 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000273 if (f->f_fp == NULL)
274 return err_closed();
275 if (!getnoarg(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000276 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000277 BGN_SAVE
278 res = isatty((int)fileno(f->f_fp));
279 END_SAVE
280 return newintobject(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000281}
282
283static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000284file_read(f, args)
285 fileobject *f;
286 object *args;
287{
288 int n, n1, n2, n3;
289 object *v;
290
Guido van Rossumd7297e61992-07-06 14:19:26 +0000291 if (f->f_fp == NULL)
292 return err_closed();
293 if (args == NULL) {
Guido van Rossumce5ba841991-03-06 13:06:18 +0000294 n = 0;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000295 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000296 err_setstr(ValueError, "negative read count");
Guido van Rossumce5ba841991-03-06 13:06:18 +0000297 return NULL;
298 }
299 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000300 else if (!getargs(args, "i", &n))
301 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000302
303 n2 = n != 0 ? n : BUFSIZ;
304 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000305 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000307 n1 = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000308 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000309 for (;;) {
310 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
311 /* XXX Error check? */
312 if (n3 == 0)
313 break;
314 n1 += n3;
315 if (n1 == n)
316 break;
317 if (n == 0) {
318 n2 = n1 + BUFSIZ;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000319 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000320 if (resizestring(&v, n2) < 0)
321 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000322 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000323 }
324 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000325 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000326 if (n1 != n2)
327 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328 return v;
329}
330
Guido van Rossum0bd24411991-04-04 15:21:57 +0000331/* Internal routine to get a line.
332 Size argument interpretation:
333 > 0: max length;
334 = 0: read arbitrary line;
335 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000336*/
337
Guido van Rossum234f9421993-06-17 12:35:49 +0000338static object *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000339getline(f, n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000340 fileobject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000341 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000342{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000343 register FILE *fp;
344 register int c;
345 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000346 int n1, n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000347 object *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000348
Guido van Rossumc10aa771992-07-31 12:42:38 +0000349 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000350 n2 = n > 0 ? n : 100;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000351 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000352 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000353 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000354 buf = BUF(v);
355 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000356
Guido van Rossumff4949e1992-08-05 19:58:53 +0000357 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000358 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000359 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000360 clearerr(fp);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000361 if (intrcheck()) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000362 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000363 DECREF(v);
364 err_set(KeyboardInterrupt);
365 return NULL;
366 }
367 if (n < 0 && buf == BUF(v)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000368 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000369 DECREF(v);
Guido van Rossum201be051991-12-24 13:26:41 +0000370 err_setstr(EOFError,
371 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000372 return NULL;
373 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000374 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000375 }
376 if ((*buf++ = c) == '\n') {
377 if (n < 0)
378 buf--;
379 break;
380 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000381 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000382 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000383 break;
384 n1 = n2;
385 n2 += 1000;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000386 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000387 if (resizestring(&v, n2) < 0)
388 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000389 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000390 buf = BUF(v) + n1;
391 end = BUF(v) + n2;
392 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000394 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000395
Guido van Rossumce5ba841991-03-06 13:06:18 +0000396 n1 = buf - BUF(v);
397 if (n1 != n2)
398 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000399 return v;
400}
401
Guido van Rossum0bd24411991-04-04 15:21:57 +0000402/* External C interface */
403
404object *
405filegetline(f, n)
406 object *f;
407 int n;
408{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000409 if (f == NULL) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000410 err_badcall();
411 return NULL;
412 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000413 if (!is_fileobject(f)) {
414 object *reader;
415 object *args;
416 object *result;
417 reader = getattr(f, "readline");
418 if (reader == NULL)
419 return NULL;
420 if (n <= 0)
421 args = mkvalue("()");
422 else
423 args = mkvalue("(i)", n);
424 if (args == NULL) {
425 DECREF(reader);
426 return NULL;
427 }
428 result = call_object(reader, args);
429 DECREF(reader);
430 DECREF(args);
431 if (result != NULL && !is_stringobject(result)) {
432 DECREF(result);
433 result = NULL;
434 err_setstr(TypeError,
435 "object.readline() returned non-string");
436 }
437 if (n < 0 && result != NULL) {
438 char *s = getstringvalue(result);
439 int len = getstringsize(result);
440 if (len == 0) {
441 DECREF(result);
442 result = NULL;
443 err_setstr(EOFError,
444 "EOF when reading a line");
445 }
446 else if (s[len-1] == '\n') {
447 if (result->ob_refcnt == 1)
448 resizestring(&result, len-1);
449 else {
450 object *v;
Guido van Rossumde788b81992-12-22 14:24:04 +0000451 v = newsizedstringobject(s, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000452 DECREF(result);
453 result = v;
454 }
455 }
456 }
457 return result;
458 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000459 if (((fileobject*)f)->f_fp == NULL)
460 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000461 return getline((fileobject *)f, n);
462}
463
464/* Python method */
465
466static object *
467file_readline(f, args)
468 fileobject *f;
469 object *args;
470{
471 int n;
472
Guido van Rossumd7297e61992-07-06 14:19:26 +0000473 if (f->f_fp == NULL)
474 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000475 if (args == NULL)
476 n = 0; /* Unlimited */
477 else {
478 if (!getintarg(args, &n))
479 return NULL;
480 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000481 err_setstr(ValueError, "negative readline count");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000482 return NULL;
483 }
484 }
485
Guido van Rossum51415a71992-03-27 17:23:38 +0000486 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000487}
488
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000490file_readlines(f, args)
491 fileobject *f;
492 object *args;
493{
494 object *list;
495 object *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000496
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 (!getnoarg(args))
500 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000501 if ((list = newlistobject(0)) == NULL)
502 return NULL;
503 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000504 line = getline(f, 0);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000505 if (line != NULL && getstringsize(line) == 0) {
506 DECREF(line);
507 break;
508 }
509 if (line == NULL || addlistitem(list, line) != 0) {
510 DECREF(list);
511 XDECREF(line);
512 return NULL;
513 }
514 DECREF(line);
515 }
516 return list;
517}
518
519static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000520file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000521 fileobject *f;
522 object *args;
523{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000524 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000525 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000526 if (f->f_fp == NULL)
527 return err_closed();
528 if (!getargs(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000530 f->f_softspace = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000531 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000532 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000533 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000534 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000535 if (n2 != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000536 err_errno(IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000537 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000538 return NULL;
539 }
540 INCREF(None);
541 return None;
542}
543
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000544static object *
545file_writelines(f, args)
546 fileobject *f;
547 object *args;
548{
549 int i, n;
550 if (f->f_fp == NULL)
551 return err_closed();
552 if (args == NULL || !is_listobject(args)) {
553 err_setstr(TypeError,
554 "writelines() requires list of strings");
555 return NULL;
556 }
557 n = getlistsize(args);
558 f->f_softspace = 0;
559 BGN_SAVE
560 errno = 0;
561 for (i = 0; i < n; i++) {
562 object *line = getlistitem(args, i);
563 int len;
564 int nwritten;
565 if (!is_stringobject(line)) {
566 RET_SAVE
567 err_setstr(TypeError,
568 "writelines() requires list of strings");
569 return NULL;
570 }
571 len = getstringsize(line);
572 nwritten = fwrite(getstringvalue(line), 1, len, f->f_fp);
573 if (nwritten != len) {
574 RET_SAVE
575 err_errno(IOError);
576 clearerr(f->f_fp);
577 return NULL;
578 }
579 }
580 END_SAVE
581 INCREF(None);
582 return None;
583}
584
Guido van Rossum3f5da241990-12-20 15:06:42 +0000585static struct methodlist file_methods[] = {
Guido van Rossumce5ba841991-03-06 13:06:18 +0000586 {"close", file_close},
587 {"flush", file_flush},
Guido van Rossumed233a51992-06-23 09:07:03 +0000588 {"fileno", file_fileno},
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000589 {"isatty", file_isatty},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000590 {"read", file_read},
591 {"readline", file_readline},
Guido van Rossumce5ba841991-03-06 13:06:18 +0000592 {"readlines", file_readlines},
593 {"seek", file_seek},
594 {"tell", file_tell},
595 {"write", file_write},
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000596 {"writelines", file_writelines},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000597 {NULL, NULL} /* sentinel */
598};
599
600static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000601file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000602 fileobject *f;
603 char *name;
604{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000605 return findmethod(file_methods, (object *)f, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000606}
607
608typeobject Filetype = {
609 OB_HEAD_INIT(&Typetype)
610 0,
611 "file",
612 sizeof(fileobject),
613 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000614 file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000615 0, /*tp_print*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000616 file_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000617 0, /*tp_setattr*/
618 0, /*tp_compare*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000619 file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000620};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000621
622/* Interface for the 'soft space' between print items. */
623
624int
625softspace(f, newflag)
626 object *f;
627 int newflag;
628{
629 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000630 if (f == NULL) {
631 /* Do nothing */
632 }
Guido van Rossum82d410e1993-11-01 16:26:16 +0000633 else if (is_fileobject(f)) {
Guido van Rossumeb183da1991-04-04 10:44:06 +0000634 oldflag = ((fileobject *)f)->f_softspace;
635 ((fileobject *)f)->f_softspace = newflag;
636 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000637 else {
638 object *v;
639 v = getattr(f, "softspace");
640 if (v == NULL)
641 err_clear();
642 else {
643 if (is_intobject(v))
644 oldflag = getintvalue(v);
645 DECREF(v);
646 }
647 v = newintobject((long)newflag);
648 if (v == NULL)
649 err_clear();
650 else {
651 if (setattr(f, "softspace", v) != 0)
652 err_clear();
653 DECREF(v);
654 }
655 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000656 return oldflag;
657}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000658
659/* Interfaces to write objects/strings to file-like objects */
660
661int
662writeobject(v, f, flags)
663 object *v;
664 object *f;
665 int flags;
666{
667 object *writer, *value, *result;
668 if (f == NULL) {
669 err_setstr(TypeError, "writeobject with NULL file");
670 return -1;
671 }
672 else if (is_fileobject(f)) {
673 FILE *fp = getfilefile(f);
674 if (fp == NULL) {
675 err_closed();
676 return -1;
677 }
678 return printobject(v, fp, flags);
679 }
680 writer = getattr(f, "write");
681 if (writer == NULL)
682 return -1;
Guido van Rossumc6004111993-11-05 10:22:19 +0000683 if (flags & PRINT_RAW)
684 value = strobject(v);
685 else
Guido van Rossum3165fe61992-09-25 21:59:05 +0000686 value = reprobject(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000687 if (value == NULL) {
688 DECREF(writer);
689 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000690 }
691 result = call_object(writer, value);
692 DECREF(writer);
693 DECREF(value);
694 if (result == NULL)
695 return -1;
696 DECREF(result);
697 return 0;
698}
699
700void
701writestring(s, f)
702 char *s;
703 object *f;
704{
705 if (f == NULL) {
706 /* Do nothing */
707 }
708 else if (is_fileobject(f)) {
709 FILE *fp = getfilefile(f);
710 if (fp != NULL)
711 fputs(s, fp);
712 }
713 else {
714 object *v = newstringobject(s);
715 if (v == NULL) {
716 err_clear();
717 }
718 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000719 if (writeobject(v, f, PRINT_RAW) != 0)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000720 err_clear();
721 DECREF(v);
722 }
723 }
724}