blob: d8335275801425244845ca1499b83cb321a78370 [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
Jack Jansene08dea191995-04-23 22:12:47 +000035#ifdef __MWERKS__
36/* Mwerks fopen() doesn't always set errno */
37#define NO_FOPEN_ERRNO
38#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000039
Guido van Rossumce5ba841991-03-06 13:06:18 +000040#define BUF(v) GETSTRINGVALUE((stringobject *)v)
41
Guido van Rossumf1dc5661993-07-05 10:31:29 +000042#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043
44typedef struct {
45 OB_HEAD
46 FILE *f_fp;
47 object *f_name;
48 object *f_mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000049 int (*f_close) PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000050 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000051} fileobject;
52
53FILE *
54getfilefile(f)
55 object *f;
56{
Guido van Rossum3165fe61992-09-25 21:59:05 +000057 if (f == NULL || !is_fileobject(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000058 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000059 else
60 return ((fileobject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061}
62
63object *
Guido van Rossumdb3165e1993-10-18 17:06:59 +000064getfilename(f)
65 object *f;
66{
67 if (f == NULL || !is_fileobject(f))
68 return NULL;
69 else
70 return ((fileobject *)f)->f_name;
71}
72
73object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000074newopenfileobject(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075 FILE *fp;
76 char *name;
77 char *mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000078 int (*close) FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079{
80 fileobject *f = NEWOBJ(fileobject, &Filetype);
81 if (f == NULL)
82 return NULL;
83 f->f_fp = NULL;
84 f->f_name = newstringobject(name);
85 f->f_mode = newstringobject(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000086 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000087 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000088 if (f->f_name == NULL || f->f_mode == NULL) {
89 DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090 return NULL;
91 }
92 f->f_fp = fp;
93 return (object *) f;
94}
95
96object *
97newfileobject(name, mode)
98 char *name, *mode;
99{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000100 extern int fclose PROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101 fileobject *f;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000102 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103 if (f == NULL)
104 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000105#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000106 if (*mode == '*') {
107 FILE *fopenRF();
108 f->f_fp = fopenRF(name, mode+1);
109 }
110 else
111#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000112 {
113 BGN_SAVE
114 f->f_fp = fopen(name, mode);
115 END_SAVE
116 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000117 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000118#ifdef NO_FOPEN_ERRNO
119 if ( errno == 0 ) {
120 err_setstr(IOError, "Cannot open file");
121 DECREF(f);
122 return NULL;
123 }
124#endif
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000125 err_errno(IOError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000126 DECREF(f);
127 return NULL;
128 }
129 return (object *)f;
130}
131
Guido van Rossumb6775db1994-08-01 11:34:53 +0000132void
133setfilebufsize(f, bufsize)
134 object *f;
135 int bufsize;
136{
137 if (bufsize >= 0) {
138#ifdef HAVE_SETVBUF
139 int type;
140 switch (bufsize) {
141 case 0:
142 type = _IONBF;
143 break;
144 case 1:
145 type = _IOLBF;
146 bufsize = BUFSIZ;
147 break;
148 default:
149 type = _IOFBF;
150 }
151 setvbuf(((fileobject *)f)->f_fp, (char *)NULL, type, bufsize);
152#endif /* HAVE_SETVBUF */
153 }
154}
155
Guido van Rossumd7297e61992-07-06 14:19:26 +0000156static object *
157err_closed()
158{
159 err_setstr(ValueError, "I/O operation on closed file");
160 return NULL;
161}
162
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163/* Methods */
164
165static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000166file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000167 fileobject *f;
168{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000169 if (f->f_fp != NULL && f->f_close != NULL) {
170 BGN_SAVE
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000171 (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000172 END_SAVE
173 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174 if (f->f_name != NULL)
175 DECREF(f->f_name);
176 if (f->f_mode != NULL)
177 DECREF(f->f_mode);
178 free((char *)f);
179}
180
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000182file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183 fileobject *f;
184{
185 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000186 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187 f->f_fp == NULL ? "closed" : "open",
188 getstringvalue(f->f_name),
Guido van Rossume35399e1993-01-10 18:33:56 +0000189 getstringvalue(f->f_mode),
190 (long)f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 return newstringobject(buf);
192}
193
194static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000195file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196 fileobject *f;
197 object *args;
198{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000199 int sts = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000200 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000203 if (f->f_close != NULL) {
204 BGN_SAVE
205 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000206 sts = (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000207 END_SAVE
208 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209 f->f_fp = NULL;
210 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000211 if (sts == EOF)
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000212 return err_errno(IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000213 if (sts != 0)
214 return newintobject((long)sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215 INCREF(None);
216 return None;
217}
218
219static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000220file_seek(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000221 fileobject *f;
222 object *args;
223{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000224 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000225 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000226 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000227
Guido van Rossumd7297e61992-07-06 14:19:26 +0000228 if (f->f_fp == NULL)
229 return err_closed();
230 whence = 0;
231 if (!getargs(args, "l", &offset)) {
232 err_clear();
233 if (!getargs(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000234 return NULL;
235 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000236 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000237 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000238 ret = fseek(f->f_fp, offset, whence);
239 END_SAVE
240 if (ret != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000241 err_errno(IOError);
242 clearerr(f->f_fp);
243 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000244 }
245 INCREF(None);
246 return None;
247}
248
Guido van Rossumd7047b31995-01-02 19:07:15 +0000249#ifdef HAVE_FTRUNCATE
250static object *
251file_truncate(f, args)
252 fileobject *f;
253 object *args;
254{
255 long newsize;
256 int ret;
257
258 if (f->f_fp == NULL)
259 return err_closed();
260 if (!getargs(args, "l", &newsize)) {
261 err_clear();
262 if (!getnoarg(args))
263 return NULL;
264 BGN_SAVE
265 errno = 0;
266 newsize = ftell(f->f_fp); /* default to current position*/
267 END_SAVE
268 if (newsize == -1L) {
269 err_errno(IOError);
270 clearerr(f->f_fp);
271 return NULL;
272 }
273 }
274 BGN_SAVE
275 errno = 0;
276 ret = fflush(f->f_fp);
277 END_SAVE
278 if (ret == 0) {
279 BGN_SAVE
280 errno = 0;
281 ret = ftruncate(fileno(f->f_fp), newsize);
282 END_SAVE
283 }
284 if (ret != 0) {
285 err_errno(IOError);
286 clearerr(f->f_fp);
287 return NULL;
288 }
289 INCREF(None);
290 return None;
291}
292#endif /* HAVE_FTRUNCATE */
293
Guido van Rossumce5ba841991-03-06 13:06:18 +0000294static object *
295file_tell(f, args)
296 fileobject *f;
297 object *args;
298{
299 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000300 if (f->f_fp == NULL)
301 return err_closed();
302 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000303 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000304 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000305 errno = 0;
306 offset = ftell(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000307 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000308 if (offset == -1L) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000309 err_errno(IOError);
310 clearerr(f->f_fp);
311 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000312 }
313 return newintobject(offset);
314}
315
316static object *
Guido van Rossumed233a51992-06-23 09:07:03 +0000317file_fileno(f, args)
318 fileobject *f;
319 object *args;
320{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000321 if (f->f_fp == NULL)
322 return err_closed();
Guido van Rossumed233a51992-06-23 09:07:03 +0000323 if (!getnoarg(args))
324 return NULL;
325 return newintobject((long) fileno(f->f_fp));
326}
327
328static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000329file_flush(f, args)
330 fileobject *f;
331 object *args;
332{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000333 int res;
334
Guido van Rossumd7297e61992-07-06 14:19:26 +0000335 if (f->f_fp == NULL)
336 return err_closed();
337 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000339 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000340 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000341 res = fflush(f->f_fp);
342 END_SAVE
343 if (res != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000344 err_errno(IOError);
345 clearerr(f->f_fp);
346 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000347 }
348 INCREF(None);
349 return None;
350}
351
352static object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000353file_isatty(f, args)
354 fileobject *f;
355 object *args;
356{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000357 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000358 if (f->f_fp == NULL)
359 return err_closed();
360 if (!getnoarg(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000361 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000362 BGN_SAVE
363 res = isatty((int)fileno(f->f_fp));
364 END_SAVE
365 return newintobject(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000366}
367
368static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000369file_read(f, args)
370 fileobject *f;
371 object *args;
372{
373 int n, n1, n2, n3;
374 object *v;
375
Guido van Rossumd7297e61992-07-06 14:19:26 +0000376 if (f->f_fp == NULL)
377 return err_closed();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000378 if (args == NULL)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000379 n = 0;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000380 else {
381 if (!getargs(args, "i", &n))
382 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000383 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000384 err_setstr(ValueError, "negative read count");
Guido van Rossumce5ba841991-03-06 13:06:18 +0000385 return NULL;
386 }
387 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000388 n2 = n != 0 ? n : BUFSIZ;
389 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000390 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000391 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000392 n1 = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000393 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000394 for (;;) {
395 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
396 /* XXX Error check? */
397 if (n3 == 0)
398 break;
399 n1 += n3;
400 if (n1 == n)
401 break;
402 if (n == 0) {
403 n2 = n1 + BUFSIZ;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000404 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000405 if (resizestring(&v, n2) < 0)
406 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000407 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000408 }
409 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000410 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000411 if (n1 != n2)
412 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000413 return v;
414}
415
Guido van Rossum0bd24411991-04-04 15:21:57 +0000416/* Internal routine to get a line.
417 Size argument interpretation:
418 > 0: max length;
419 = 0: read arbitrary line;
420 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000421*/
422
Guido van Rossum234f9421993-06-17 12:35:49 +0000423static object *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000424getline(f, n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000425 fileobject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000426 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000427{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000428 register FILE *fp;
429 register int c;
430 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000431 int n1, n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000432 object *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000433
Guido van Rossumc10aa771992-07-31 12:42:38 +0000434 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000435 n2 = n > 0 ? n : 100;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000436 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000437 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000438 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000439 buf = BUF(v);
440 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000441
Guido van Rossumff4949e1992-08-05 19:58:53 +0000442 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000443 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000444 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000445 clearerr(fp);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000446 if (sigcheck()) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000447 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000448 DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000449 return NULL;
450 }
451 if (n < 0 && buf == BUF(v)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000452 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000453 DECREF(v);
Guido van Rossum201be051991-12-24 13:26:41 +0000454 err_setstr(EOFError,
455 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000456 return NULL;
457 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000458 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000459 }
460 if ((*buf++ = c) == '\n') {
461 if (n < 0)
462 buf--;
463 break;
464 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000465 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000466 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000467 break;
468 n1 = n2;
469 n2 += 1000;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000470 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000471 if (resizestring(&v, n2) < 0)
472 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000473 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000474 buf = BUF(v) + n1;
475 end = BUF(v) + n2;
476 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000477 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000478 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000479
Guido van Rossumce5ba841991-03-06 13:06:18 +0000480 n1 = buf - BUF(v);
481 if (n1 != n2)
482 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483 return v;
484}
485
Guido van Rossum0bd24411991-04-04 15:21:57 +0000486/* External C interface */
487
488object *
489filegetline(f, n)
490 object *f;
491 int n;
492{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000493 if (f == NULL) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000494 err_badcall();
495 return NULL;
496 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000497 if (!is_fileobject(f)) {
498 object *reader;
499 object *args;
500 object *result;
501 reader = getattr(f, "readline");
502 if (reader == NULL)
503 return NULL;
504 if (n <= 0)
505 args = mkvalue("()");
506 else
507 args = mkvalue("(i)", n);
508 if (args == NULL) {
509 DECREF(reader);
510 return NULL;
511 }
512 result = call_object(reader, args);
513 DECREF(reader);
514 DECREF(args);
515 if (result != NULL && !is_stringobject(result)) {
516 DECREF(result);
517 result = NULL;
518 err_setstr(TypeError,
519 "object.readline() returned non-string");
520 }
521 if (n < 0 && result != NULL) {
522 char *s = getstringvalue(result);
523 int len = getstringsize(result);
524 if (len == 0) {
525 DECREF(result);
526 result = NULL;
527 err_setstr(EOFError,
528 "EOF when reading a line");
529 }
530 else if (s[len-1] == '\n') {
531 if (result->ob_refcnt == 1)
532 resizestring(&result, len-1);
533 else {
534 object *v;
Guido van Rossumde788b81992-12-22 14:24:04 +0000535 v = newsizedstringobject(s, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000536 DECREF(result);
537 result = v;
538 }
539 }
540 }
541 return result;
542 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000543 if (((fileobject*)f)->f_fp == NULL)
544 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000545 return getline((fileobject *)f, n);
546}
547
548/* Python method */
549
550static object *
551file_readline(f, args)
552 fileobject *f;
553 object *args;
554{
555 int n;
556
Guido van Rossumd7297e61992-07-06 14:19:26 +0000557 if (f->f_fp == NULL)
558 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000559 if (args == NULL)
560 n = 0; /* Unlimited */
561 else {
562 if (!getintarg(args, &n))
563 return NULL;
564 if (n < 0) {
Guido van Rossumd7297e61992-07-06 14:19:26 +0000565 err_setstr(ValueError, "negative readline count");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000566 return NULL;
567 }
568 }
569
Guido van Rossum51415a71992-03-27 17:23:38 +0000570 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000571}
572
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000573static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000574file_readlines(f, args)
575 fileobject *f;
576 object *args;
577{
578 object *list;
579 object *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000580
Guido van Rossumd7297e61992-07-06 14:19:26 +0000581 if (f->f_fp == NULL)
582 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000583 if (!getnoarg(args))
584 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000585 if ((list = newlistobject(0)) == NULL)
586 return NULL;
587 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000588 line = getline(f, 0);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000589 if (line != NULL && getstringsize(line) == 0) {
590 DECREF(line);
591 break;
592 }
593 if (line == NULL || addlistitem(list, line) != 0) {
594 DECREF(list);
595 XDECREF(line);
596 return NULL;
597 }
598 DECREF(line);
599 }
600 return list;
601}
602
603static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000604file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000605 fileobject *f;
606 object *args;
607{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000608 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000609 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000610 if (f->f_fp == NULL)
611 return err_closed();
612 if (!getargs(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000613 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000614 f->f_softspace = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000615 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000616 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000617 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000618 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000619 if (n2 != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000620 err_errno(IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000621 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000622 return NULL;
623 }
624 INCREF(None);
625 return None;
626}
627
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000628static object *
629file_writelines(f, args)
630 fileobject *f;
631 object *args;
632{
633 int i, n;
634 if (f->f_fp == NULL)
635 return err_closed();
636 if (args == NULL || !is_listobject(args)) {
637 err_setstr(TypeError,
638 "writelines() requires list of strings");
639 return NULL;
640 }
641 n = getlistsize(args);
642 f->f_softspace = 0;
643 BGN_SAVE
644 errno = 0;
645 for (i = 0; i < n; i++) {
646 object *line = getlistitem(args, i);
647 int len;
648 int nwritten;
649 if (!is_stringobject(line)) {
650 RET_SAVE
651 err_setstr(TypeError,
652 "writelines() requires list of strings");
653 return NULL;
654 }
655 len = getstringsize(line);
656 nwritten = fwrite(getstringvalue(line), 1, len, f->f_fp);
657 if (nwritten != len) {
658 RET_SAVE
659 err_errno(IOError);
660 clearerr(f->f_fp);
661 return NULL;
662 }
663 }
664 END_SAVE
665 INCREF(None);
666 return None;
667}
668
Guido van Rossum3f5da241990-12-20 15:06:42 +0000669static struct methodlist file_methods[] = {
Guido van Rossum295d1711995-02-19 15:55:19 +0000670 {"close", (method)file_close, 0},
671 {"flush", (method)file_flush, 0},
672 {"fileno", (method)file_fileno, 0},
673 {"isatty", (method)file_isatty, 0},
674 {"read", (method)file_read, 0},
675 {"readline", (method)file_readline, 0},
676 {"readlines", (method)file_readlines, 0},
677 {"seek", (method)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000678#ifdef HAVE_FTRUNCATE
Guido van Rossum295d1711995-02-19 15:55:19 +0000679 {"truncate", (method)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000680#endif
Guido van Rossum295d1711995-02-19 15:55:19 +0000681 {"tell", (method)file_tell, 0},
682 {"write", (method)file_write, 0},
683 {"writelines", (method)file_writelines, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000684 {NULL, NULL} /* sentinel */
685};
686
Guido van Rossumb6775db1994-08-01 11:34:53 +0000687#define OFF(x) offsetof(fileobject, x)
688
689static struct memberlist file_memberlist[] = {
690 {"softspace", T_INT, OFF(f_softspace)},
691 {"mode", T_OBJECT, OFF(f_mode), RO},
692 {"name", T_OBJECT, OFF(f_name), RO},
693 /* getattr(f, "closed") is implemented without this table */
694 {"closed", T_INT, 0, RO},
695 {NULL} /* Sentinel */
696};
697
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000698static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000699file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000700 fileobject *f;
701 char *name;
702{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000703 object *res;
704
705 res = findmethod(file_methods, (object *)f, name);
706 if (res != NULL)
707 return res;
708 err_clear();
709 if (strcmp(name, "closed") == 0)
710 return newintobject((long)(f->f_fp == 0));
711 return getmember((char *)f, file_memberlist, name);
712}
713
714static int
715file_setattr(f, name, v)
716 fileobject *f;
717 char *name;
718 object *v;
719{
720 if (v == NULL) {
721 err_setstr(AttributeError, "can't delete file attributes");
722 return -1;
723 }
724 return setmember((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000725}
726
727typeobject Filetype = {
728 OB_HEAD_INIT(&Typetype)
729 0,
730 "file",
731 sizeof(fileobject),
732 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000733 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000734 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000735 (getattrfunc)file_getattr, /*tp_getattr*/
736 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000737 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000738 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000739};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000740
741/* Interface for the 'soft space' between print items. */
742
743int
744softspace(f, newflag)
745 object *f;
746 int newflag;
747{
748 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000749 if (f == NULL) {
750 /* Do nothing */
751 }
Guido van Rossum82d410e1993-11-01 16:26:16 +0000752 else if (is_fileobject(f)) {
Guido van Rossumeb183da1991-04-04 10:44:06 +0000753 oldflag = ((fileobject *)f)->f_softspace;
754 ((fileobject *)f)->f_softspace = newflag;
755 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000756 else {
757 object *v;
758 v = getattr(f, "softspace");
759 if (v == NULL)
760 err_clear();
761 else {
762 if (is_intobject(v))
763 oldflag = getintvalue(v);
764 DECREF(v);
765 }
766 v = newintobject((long)newflag);
767 if (v == NULL)
768 err_clear();
769 else {
770 if (setattr(f, "softspace", v) != 0)
771 err_clear();
772 DECREF(v);
773 }
774 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000775 return oldflag;
776}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000777
778/* Interfaces to write objects/strings to file-like objects */
779
780int
781writeobject(v, f, flags)
782 object *v;
783 object *f;
784 int flags;
785{
786 object *writer, *value, *result;
787 if (f == NULL) {
788 err_setstr(TypeError, "writeobject with NULL file");
789 return -1;
790 }
791 else if (is_fileobject(f)) {
792 FILE *fp = getfilefile(f);
793 if (fp == NULL) {
794 err_closed();
795 return -1;
796 }
797 return printobject(v, fp, flags);
798 }
799 writer = getattr(f, "write");
800 if (writer == NULL)
801 return -1;
Guido van Rossumc6004111993-11-05 10:22:19 +0000802 if (flags & PRINT_RAW)
803 value = strobject(v);
804 else
Guido van Rossum3165fe61992-09-25 21:59:05 +0000805 value = reprobject(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000806 if (value == NULL) {
807 DECREF(writer);
808 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000809 }
810 result = call_object(writer, value);
811 DECREF(writer);
812 DECREF(value);
813 if (result == NULL)
814 return -1;
815 DECREF(result);
816 return 0;
817}
818
819void
820writestring(s, f)
821 char *s;
822 object *f;
823{
824 if (f == NULL) {
825 /* Do nothing */
826 }
827 else if (is_fileobject(f)) {
828 FILE *fp = getfilefile(f);
829 if (fp != NULL)
830 fputs(s, fp);
831 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000832 else if (!err_occurred()) {
Guido van Rossum3165fe61992-09-25 21:59:05 +0000833 object *v = newstringobject(s);
834 if (v == NULL) {
835 err_clear();
836 }
837 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000838 if (writeobject(v, f, PRINT_RAW) != 0)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000839 err_clear();
840 DECREF(v);
841 }
842 }
843}