blob: 0a03c475d43ee4eef3a955442b53b77770ace85b [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 Rossumd3f9a1a1995-07-10 23:32:26 +0000379 n = -1;
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 }
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000384 n2 = n >= 0 ? n : BUFSIZ;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000385 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000386 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000387 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000388 n1 = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000389 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000390 for (;;) {
391 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
392 /* XXX Error check? */
393 if (n3 == 0)
394 break;
395 n1 += n3;
396 if (n1 == n)
397 break;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000398 if (n < 0) {
Guido van Rossumce5ba841991-03-06 13:06:18 +0000399 n2 = n1 + BUFSIZ;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000400 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000401 if (resizestring(&v, n2) < 0)
402 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000403 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000404 }
405 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000406 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000407 if (n1 != n2)
408 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000409 return v;
410}
411
Guido van Rossum0bd24411991-04-04 15:21:57 +0000412/* Internal routine to get a line.
413 Size argument interpretation:
414 > 0: max length;
415 = 0: read arbitrary line;
416 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000417*/
418
Guido van Rossum234f9421993-06-17 12:35:49 +0000419static object *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000420getline(f, n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000421 fileobject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000422 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000423{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000424 register FILE *fp;
425 register int c;
426 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000427 int n1, n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000428 object *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000429
Guido van Rossumc10aa771992-07-31 12:42:38 +0000430 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000431 n2 = n > 0 ? n : 100;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000432 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000433 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000434 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000435 buf = BUF(v);
436 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000437
Guido van Rossumff4949e1992-08-05 19:58:53 +0000438 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000439 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000440 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000441 clearerr(fp);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000442 if (sigcheck()) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000443 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000444 DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000445 return NULL;
446 }
447 if (n < 0 && buf == BUF(v)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000448 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000449 DECREF(v);
Guido van Rossum201be051991-12-24 13:26:41 +0000450 err_setstr(EOFError,
451 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000452 return NULL;
453 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000454 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000455 }
456 if ((*buf++ = c) == '\n') {
457 if (n < 0)
458 buf--;
459 break;
460 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000461 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000462 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000463 break;
464 n1 = n2;
465 n2 += 1000;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000466 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000467 if (resizestring(&v, n2) < 0)
468 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000469 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000470 buf = BUF(v) + n1;
471 end = BUF(v) + n2;
472 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000473 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000474 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000475
Guido van Rossumce5ba841991-03-06 13:06:18 +0000476 n1 = buf - BUF(v);
477 if (n1 != n2)
478 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000479 return v;
480}
481
Guido van Rossum0bd24411991-04-04 15:21:57 +0000482/* External C interface */
483
484object *
485filegetline(f, n)
486 object *f;
487 int n;
488{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000489 if (f == NULL) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000490 err_badcall();
491 return NULL;
492 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000493 if (!is_fileobject(f)) {
494 object *reader;
495 object *args;
496 object *result;
497 reader = getattr(f, "readline");
498 if (reader == NULL)
499 return NULL;
500 if (n <= 0)
501 args = mkvalue("()");
502 else
503 args = mkvalue("(i)", n);
504 if (args == NULL) {
505 DECREF(reader);
506 return NULL;
507 }
508 result = call_object(reader, args);
509 DECREF(reader);
510 DECREF(args);
511 if (result != NULL && !is_stringobject(result)) {
512 DECREF(result);
513 result = NULL;
514 err_setstr(TypeError,
515 "object.readline() returned non-string");
516 }
517 if (n < 0 && result != NULL) {
518 char *s = getstringvalue(result);
519 int len = getstringsize(result);
520 if (len == 0) {
521 DECREF(result);
522 result = NULL;
523 err_setstr(EOFError,
524 "EOF when reading a line");
525 }
526 else if (s[len-1] == '\n') {
527 if (result->ob_refcnt == 1)
528 resizestring(&result, len-1);
529 else {
530 object *v;
Guido van Rossumde788b81992-12-22 14:24:04 +0000531 v = newsizedstringobject(s, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000532 DECREF(result);
533 result = v;
534 }
535 }
536 }
537 return result;
538 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000539 if (((fileobject*)f)->f_fp == NULL)
540 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000541 return getline((fileobject *)f, n);
542}
543
544/* Python method */
545
546static object *
547file_readline(f, args)
548 fileobject *f;
549 object *args;
550{
551 int n;
552
Guido van Rossumd7297e61992-07-06 14:19:26 +0000553 if (f->f_fp == NULL)
554 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000555 if (args == NULL)
556 n = 0; /* Unlimited */
557 else {
558 if (!getintarg(args, &n))
559 return NULL;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000560 if (n == 0)
561 return newstringobject("");
562 if (n < 0)
563 n = 0;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000564 }
565
Guido van Rossum51415a71992-03-27 17:23:38 +0000566 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000567}
568
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000569static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000570file_readlines(f, args)
571 fileobject *f;
572 object *args;
573{
574 object *list;
575 object *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000576
Guido van Rossumd7297e61992-07-06 14:19:26 +0000577 if (f->f_fp == NULL)
578 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000579 if (!getnoarg(args))
580 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000581 if ((list = newlistobject(0)) == NULL)
582 return NULL;
583 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000584 line = getline(f, 0);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000585 if (line != NULL && getstringsize(line) == 0) {
586 DECREF(line);
587 break;
588 }
589 if (line == NULL || addlistitem(list, line) != 0) {
590 DECREF(list);
591 XDECREF(line);
592 return NULL;
593 }
594 DECREF(line);
595 }
596 return list;
597}
598
599static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000600file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000601 fileobject *f;
602 object *args;
603{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000604 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000605 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000606 if (f->f_fp == NULL)
607 return err_closed();
608 if (!getargs(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000609 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000610 f->f_softspace = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000611 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000613 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000614 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000615 if (n2 != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000616 err_errno(IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000617 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000618 return NULL;
619 }
620 INCREF(None);
621 return None;
622}
623
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000624static object *
625file_writelines(f, args)
626 fileobject *f;
627 object *args;
628{
629 int i, n;
630 if (f->f_fp == NULL)
631 return err_closed();
632 if (args == NULL || !is_listobject(args)) {
633 err_setstr(TypeError,
634 "writelines() requires list of strings");
635 return NULL;
636 }
637 n = getlistsize(args);
638 f->f_softspace = 0;
639 BGN_SAVE
640 errno = 0;
641 for (i = 0; i < n; i++) {
642 object *line = getlistitem(args, i);
643 int len;
644 int nwritten;
645 if (!is_stringobject(line)) {
646 RET_SAVE
647 err_setstr(TypeError,
648 "writelines() requires list of strings");
649 return NULL;
650 }
651 len = getstringsize(line);
652 nwritten = fwrite(getstringvalue(line), 1, len, f->f_fp);
653 if (nwritten != len) {
654 RET_SAVE
655 err_errno(IOError);
656 clearerr(f->f_fp);
657 return NULL;
658 }
659 }
660 END_SAVE
661 INCREF(None);
662 return None;
663}
664
Guido van Rossum3f5da241990-12-20 15:06:42 +0000665static struct methodlist file_methods[] = {
Guido van Rossum295d1711995-02-19 15:55:19 +0000666 {"close", (method)file_close, 0},
667 {"flush", (method)file_flush, 0},
668 {"fileno", (method)file_fileno, 0},
669 {"isatty", (method)file_isatty, 0},
670 {"read", (method)file_read, 0},
671 {"readline", (method)file_readline, 0},
672 {"readlines", (method)file_readlines, 0},
673 {"seek", (method)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000674#ifdef HAVE_FTRUNCATE
Guido van Rossum295d1711995-02-19 15:55:19 +0000675 {"truncate", (method)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000676#endif
Guido van Rossum295d1711995-02-19 15:55:19 +0000677 {"tell", (method)file_tell, 0},
678 {"write", (method)file_write, 0},
679 {"writelines", (method)file_writelines, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000680 {NULL, NULL} /* sentinel */
681};
682
Guido van Rossumb6775db1994-08-01 11:34:53 +0000683#define OFF(x) offsetof(fileobject, x)
684
685static struct memberlist file_memberlist[] = {
686 {"softspace", T_INT, OFF(f_softspace)},
687 {"mode", T_OBJECT, OFF(f_mode), RO},
688 {"name", T_OBJECT, OFF(f_name), RO},
689 /* getattr(f, "closed") is implemented without this table */
690 {"closed", T_INT, 0, RO},
691 {NULL} /* Sentinel */
692};
693
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000694static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000695file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000696 fileobject *f;
697 char *name;
698{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000699 object *res;
700
701 res = findmethod(file_methods, (object *)f, name);
702 if (res != NULL)
703 return res;
704 err_clear();
705 if (strcmp(name, "closed") == 0)
706 return newintobject((long)(f->f_fp == 0));
707 return getmember((char *)f, file_memberlist, name);
708}
709
710static int
711file_setattr(f, name, v)
712 fileobject *f;
713 char *name;
714 object *v;
715{
716 if (v == NULL) {
717 err_setstr(AttributeError, "can't delete file attributes");
718 return -1;
719 }
720 return setmember((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000721}
722
723typeobject Filetype = {
724 OB_HEAD_INIT(&Typetype)
725 0,
726 "file",
727 sizeof(fileobject),
728 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000729 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000730 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000731 (getattrfunc)file_getattr, /*tp_getattr*/
732 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000733 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000734 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000735};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000736
737/* Interface for the 'soft space' between print items. */
738
739int
740softspace(f, newflag)
741 object *f;
742 int newflag;
743{
744 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000745 if (f == NULL) {
746 /* Do nothing */
747 }
Guido van Rossum82d410e1993-11-01 16:26:16 +0000748 else if (is_fileobject(f)) {
Guido van Rossumeb183da1991-04-04 10:44:06 +0000749 oldflag = ((fileobject *)f)->f_softspace;
750 ((fileobject *)f)->f_softspace = newflag;
751 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000752 else {
753 object *v;
754 v = getattr(f, "softspace");
755 if (v == NULL)
756 err_clear();
757 else {
758 if (is_intobject(v))
759 oldflag = getintvalue(v);
760 DECREF(v);
761 }
762 v = newintobject((long)newflag);
763 if (v == NULL)
764 err_clear();
765 else {
766 if (setattr(f, "softspace", v) != 0)
767 err_clear();
768 DECREF(v);
769 }
770 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000771 return oldflag;
772}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000773
774/* Interfaces to write objects/strings to file-like objects */
775
776int
777writeobject(v, f, flags)
778 object *v;
779 object *f;
780 int flags;
781{
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000782 object *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000783 if (f == NULL) {
784 err_setstr(TypeError, "writeobject with NULL file");
785 return -1;
786 }
787 else if (is_fileobject(f)) {
788 FILE *fp = getfilefile(f);
789 if (fp == NULL) {
790 err_closed();
791 return -1;
792 }
793 return printobject(v, fp, flags);
794 }
795 writer = getattr(f, "write");
796 if (writer == NULL)
797 return -1;
Guido van Rossumc6004111993-11-05 10:22:19 +0000798 if (flags & PRINT_RAW)
799 value = strobject(v);
800 else
Guido van Rossum3165fe61992-09-25 21:59:05 +0000801 value = reprobject(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000802 if (value == NULL) {
803 DECREF(writer);
804 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000805 }
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000806 args = mkvalue("(O)", value);
807 if (value == NULL) {
808 DECREF(value);
809 DECREF(writer);
810 return -1;
811 }
812 result = call_object(writer, args);
813 DECREF(args);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000814 DECREF(value);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000815 DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000816 if (result == NULL)
817 return -1;
818 DECREF(result);
819 return 0;
820}
821
822void
823writestring(s, f)
824 char *s;
825 object *f;
826{
827 if (f == NULL) {
828 /* Do nothing */
829 }
830 else if (is_fileobject(f)) {
831 FILE *fp = getfilefile(f);
832 if (fp != NULL)
833 fputs(s, fp);
834 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000835 else if (!err_occurred()) {
Guido van Rossum3165fe61992-09-25 21:59:05 +0000836 object *v = newstringobject(s);
837 if (v == NULL) {
838 err_clear();
839 }
840 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000841 if (writeobject(v, f, PRINT_RAW) != 0)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000842 err_clear();
843 DECREF(v);
844 }
845 }
846}