blob: 2ba63bd16f7a4aa680ea418a1174d577e18b5c4c [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
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* File object implementation */
33
Guido van Rossum3f5da241990-12-20 15:06:42 +000034#include "allobjects.h"
Guido van Rossumfa3da8a1992-01-27 16:53:23 +000035#include "modsupport.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000036#include "structmember.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000037#include "ceval.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000038
Guido van Rossum685a38e1996-12-05 21:54:17 +000039#ifdef HAVE_UNISTD_H
40#include <unistd.h>
41#endif
42
Guido van Rossum295d1711995-02-19 15:55:19 +000043#ifdef THINK_C
44#define HAVE_FOPENRF
45#endif
Jack Jansene08dea191995-04-23 22:12:47 +000046#ifdef __MWERKS__
47/* Mwerks fopen() doesn't always set errno */
48#define NO_FOPEN_ERRNO
49#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000050
Guido van Rossumce5ba841991-03-06 13:06:18 +000051#define BUF(v) GETSTRINGVALUE((stringobject *)v)
52
Guido van Rossumf1dc5661993-07-05 10:31:29 +000053#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054
55typedef struct {
56 OB_HEAD
57 FILE *f_fp;
58 object *f_name;
59 object *f_mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000060 int (*f_close) PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000061 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000062} fileobject;
63
64FILE *
65getfilefile(f)
66 object *f;
67{
Guido van Rossum3165fe61992-09-25 21:59:05 +000068 if (f == NULL || !is_fileobject(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000070 else
71 return ((fileobject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000072}
73
74object *
Guido van Rossumdb3165e1993-10-18 17:06:59 +000075getfilename(f)
76 object *f;
77{
78 if (f == NULL || !is_fileobject(f))
79 return NULL;
80 else
81 return ((fileobject *)f)->f_name;
82}
83
84object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000085newopenfileobject(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086 FILE *fp;
87 char *name;
88 char *mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000089 int (*close) FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090{
91 fileobject *f = NEWOBJ(fileobject, &Filetype);
92 if (f == NULL)
93 return NULL;
94 f->f_fp = NULL;
95 f->f_name = newstringobject(name);
96 f->f_mode = newstringobject(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000097 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000098 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099 if (f->f_name == NULL || f->f_mode == NULL) {
100 DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101 return NULL;
102 }
103 f->f_fp = fp;
104 return (object *) f;
105}
106
107object *
108newfileobject(name, mode)
109 char *name, *mode;
110{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000111 extern int fclose PROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112 fileobject *f;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000113 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000114 if (f == NULL)
115 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000116#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000117 if (*mode == '*') {
118 FILE *fopenRF();
119 f->f_fp = fopenRF(name, mode+1);
120 }
121 else
122#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000123 {
124 BGN_SAVE
125 f->f_fp = fopen(name, mode);
126 END_SAVE
127 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000128 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000129#ifdef NO_FOPEN_ERRNO
130 if ( errno == 0 ) {
131 err_setstr(IOError, "Cannot open file");
132 DECREF(f);
133 return NULL;
134 }
135#endif
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000136 err_errno(IOError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137 DECREF(f);
138 return NULL;
139 }
140 return (object *)f;
141}
142
Guido van Rossumb6775db1994-08-01 11:34:53 +0000143void
144setfilebufsize(f, bufsize)
145 object *f;
146 int bufsize;
147{
148 if (bufsize >= 0) {
149#ifdef HAVE_SETVBUF
150 int type;
151 switch (bufsize) {
152 case 0:
153 type = _IONBF;
154 break;
155 case 1:
156 type = _IOLBF;
157 bufsize = BUFSIZ;
158 break;
159 default:
160 type = _IOFBF;
161 }
162 setvbuf(((fileobject *)f)->f_fp, (char *)NULL, type, bufsize);
163#endif /* HAVE_SETVBUF */
164 }
165}
166
Guido van Rossumd7297e61992-07-06 14:19:26 +0000167static object *
168err_closed()
169{
170 err_setstr(ValueError, "I/O operation on closed file");
171 return NULL;
172}
173
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174/* Methods */
175
176static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000177file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 fileobject *f;
179{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000180 if (f->f_fp != NULL && f->f_close != NULL) {
181 BGN_SAVE
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000182 (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000183 END_SAVE
184 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000185 if (f->f_name != NULL)
186 DECREF(f->f_name);
187 if (f->f_mode != NULL)
188 DECREF(f->f_mode);
189 free((char *)f);
190}
191
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000193file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 fileobject *f;
195{
196 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000197 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198 f->f_fp == NULL ? "closed" : "open",
199 getstringvalue(f->f_name),
Guido van Rossume35399e1993-01-10 18:33:56 +0000200 getstringvalue(f->f_mode),
201 (long)f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 return newstringobject(buf);
203}
204
205static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000206file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000207 fileobject *f;
208 object *args;
209{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000210 int sts = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000211 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000214 if (f->f_close != NULL) {
215 BGN_SAVE
216 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000217 sts = (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000218 END_SAVE
219 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220 f->f_fp = NULL;
221 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000222 if (sts == EOF)
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000223 return err_errno(IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000224 if (sts != 0)
225 return newintobject((long)sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226 INCREF(None);
227 return None;
228}
229
230static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000231file_seek(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000232 fileobject *f;
233 object *args;
234{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000235 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000236 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000237 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000238
Guido van Rossumd7297e61992-07-06 14:19:26 +0000239 if (f->f_fp == NULL)
240 return err_closed();
241 whence = 0;
242 if (!getargs(args, "l", &offset)) {
243 err_clear();
244 if (!getargs(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000245 return NULL;
246 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000247 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000248 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000249 ret = fseek(f->f_fp, offset, whence);
250 END_SAVE
251 if (ret != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000252 err_errno(IOError);
253 clearerr(f->f_fp);
254 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000255 }
256 INCREF(None);
257 return None;
258}
259
Guido van Rossumd7047b31995-01-02 19:07:15 +0000260#ifdef HAVE_FTRUNCATE
261static object *
262file_truncate(f, args)
263 fileobject *f;
264 object *args;
265{
266 long newsize;
267 int ret;
268
269 if (f->f_fp == NULL)
270 return err_closed();
271 if (!getargs(args, "l", &newsize)) {
272 err_clear();
273 if (!getnoarg(args))
274 return NULL;
275 BGN_SAVE
276 errno = 0;
277 newsize = ftell(f->f_fp); /* default to current position*/
278 END_SAVE
279 if (newsize == -1L) {
280 err_errno(IOError);
281 clearerr(f->f_fp);
282 return NULL;
283 }
284 }
285 BGN_SAVE
286 errno = 0;
287 ret = fflush(f->f_fp);
288 END_SAVE
289 if (ret == 0) {
290 BGN_SAVE
291 errno = 0;
292 ret = ftruncate(fileno(f->f_fp), newsize);
293 END_SAVE
294 }
295 if (ret != 0) {
296 err_errno(IOError);
297 clearerr(f->f_fp);
298 return NULL;
299 }
300 INCREF(None);
301 return None;
302}
303#endif /* HAVE_FTRUNCATE */
304
Guido van Rossumce5ba841991-03-06 13:06:18 +0000305static object *
306file_tell(f, args)
307 fileobject *f;
308 object *args;
309{
310 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000311 if (f->f_fp == NULL)
312 return err_closed();
313 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000314 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000315 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000316 errno = 0;
317 offset = ftell(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000318 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000319 if (offset == -1L) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000320 err_errno(IOError);
321 clearerr(f->f_fp);
322 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000323 }
324 return newintobject(offset);
325}
326
327static object *
Guido van Rossumed233a51992-06-23 09:07:03 +0000328file_fileno(f, args)
329 fileobject *f;
330 object *args;
331{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000332 if (f->f_fp == NULL)
333 return err_closed();
Guido van Rossumed233a51992-06-23 09:07:03 +0000334 if (!getnoarg(args))
335 return NULL;
336 return newintobject((long) fileno(f->f_fp));
337}
338
339static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000340file_flush(f, args)
341 fileobject *f;
342 object *args;
343{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000344 int res;
345
Guido van Rossumd7297e61992-07-06 14:19:26 +0000346 if (f->f_fp == NULL)
347 return err_closed();
348 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000350 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000351 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000352 res = fflush(f->f_fp);
353 END_SAVE
354 if (res != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000355 err_errno(IOError);
356 clearerr(f->f_fp);
357 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000358 }
359 INCREF(None);
360 return None;
361}
362
363static object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000364file_isatty(f, args)
365 fileobject *f;
366 object *args;
367{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000368 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000369 if (f->f_fp == NULL)
370 return err_closed();
371 if (!getnoarg(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000372 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000373 BGN_SAVE
374 res = isatty((int)fileno(f->f_fp));
375 END_SAVE
376 return newintobject(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000377}
378
379static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000380file_read(f, args)
381 fileobject *f;
382 object *args;
383{
384 int n, n1, n2, n3;
385 object *v;
386
Guido van Rossumd7297e61992-07-06 14:19:26 +0000387 if (f->f_fp == NULL)
388 return err_closed();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000389 if (args == NULL)
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000390 n = -1;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000391 else {
392 if (!getargs(args, "i", &n))
393 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000394 }
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000395 n2 = n >= 0 ? n : BUFSIZ;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000396 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000397 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000398 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000399 n1 = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000400 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000401 for (;;) {
402 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
403 /* XXX Error check? */
404 if (n3 == 0)
405 break;
406 n1 += n3;
407 if (n1 == n)
408 break;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000409 if (n < 0) {
Guido van Rossumce5ba841991-03-06 13:06:18 +0000410 n2 = n1 + BUFSIZ;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000411 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000412 if (resizestring(&v, n2) < 0)
413 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000414 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000415 }
416 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000417 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000418 if (n1 != n2)
419 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000420 return v;
421}
422
Guido van Rossum0bd24411991-04-04 15:21:57 +0000423/* Internal routine to get a line.
424 Size argument interpretation:
425 > 0: max length;
426 = 0: read arbitrary line;
427 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000428*/
429
Guido van Rossum234f9421993-06-17 12:35:49 +0000430static object *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000431getline(f, n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000432 fileobject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000433 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000434{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000435 register FILE *fp;
436 register int c;
437 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000438 int n1, n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000439 object *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000440
Guido van Rossumc10aa771992-07-31 12:42:38 +0000441 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000442 n2 = n > 0 ? n : 100;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000443 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000444 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000445 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000446 buf = BUF(v);
447 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000448
Guido van Rossumff4949e1992-08-05 19:58:53 +0000449 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000450 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000451 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000452 clearerr(fp);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000453 if (sigcheck()) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000454 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000455 DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000456 return NULL;
457 }
458 if (n < 0 && buf == BUF(v)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000459 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000460 DECREF(v);
Guido van Rossum201be051991-12-24 13:26:41 +0000461 err_setstr(EOFError,
462 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000463 return NULL;
464 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000465 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000466 }
467 if ((*buf++ = c) == '\n') {
468 if (n < 0)
469 buf--;
470 break;
471 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000472 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000473 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000474 break;
475 n1 = n2;
476 n2 += 1000;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000477 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000478 if (resizestring(&v, n2) < 0)
479 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000480 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000481 buf = BUF(v) + n1;
482 end = BUF(v) + n2;
483 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000484 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000486
Guido van Rossumce5ba841991-03-06 13:06:18 +0000487 n1 = buf - BUF(v);
488 if (n1 != n2)
489 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000490 return v;
491}
492
Guido van Rossum0bd24411991-04-04 15:21:57 +0000493/* External C interface */
494
495object *
496filegetline(f, n)
497 object *f;
498 int n;
499{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000500 if (f == NULL) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000501 err_badcall();
502 return NULL;
503 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000504 if (!is_fileobject(f)) {
505 object *reader;
506 object *args;
507 object *result;
508 reader = getattr(f, "readline");
509 if (reader == NULL)
510 return NULL;
511 if (n <= 0)
512 args = mkvalue("()");
513 else
514 args = mkvalue("(i)", n);
515 if (args == NULL) {
516 DECREF(reader);
517 return NULL;
518 }
519 result = call_object(reader, args);
520 DECREF(reader);
521 DECREF(args);
522 if (result != NULL && !is_stringobject(result)) {
523 DECREF(result);
524 result = NULL;
525 err_setstr(TypeError,
526 "object.readline() returned non-string");
527 }
528 if (n < 0 && result != NULL) {
529 char *s = getstringvalue(result);
530 int len = getstringsize(result);
531 if (len == 0) {
532 DECREF(result);
533 result = NULL;
534 err_setstr(EOFError,
535 "EOF when reading a line");
536 }
537 else if (s[len-1] == '\n') {
538 if (result->ob_refcnt == 1)
539 resizestring(&result, len-1);
540 else {
541 object *v;
Guido van Rossumde788b81992-12-22 14:24:04 +0000542 v = newsizedstringobject(s, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000543 DECREF(result);
544 result = v;
545 }
546 }
547 }
548 return result;
549 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000550 if (((fileobject*)f)->f_fp == NULL)
551 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000552 return getline((fileobject *)f, n);
553}
554
555/* Python method */
556
557static object *
558file_readline(f, args)
559 fileobject *f;
560 object *args;
561{
562 int n;
563
Guido van Rossumd7297e61992-07-06 14:19:26 +0000564 if (f->f_fp == NULL)
565 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000566 if (args == NULL)
567 n = 0; /* Unlimited */
568 else {
569 if (!getintarg(args, &n))
570 return NULL;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000571 if (n == 0)
572 return newstringobject("");
573 if (n < 0)
574 n = 0;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000575 }
576
Guido van Rossum51415a71992-03-27 17:23:38 +0000577 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000578}
579
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000580static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000581file_readlines(f, args)
582 fileobject *f;
583 object *args;
584{
585 object *list;
586 object *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000587
Guido van Rossumd7297e61992-07-06 14:19:26 +0000588 if (f->f_fp == NULL)
589 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000590 if (!getnoarg(args))
591 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000592 if ((list = newlistobject(0)) == NULL)
593 return NULL;
594 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000595 line = getline(f, 0);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000596 if (line != NULL && getstringsize(line) == 0) {
597 DECREF(line);
598 break;
599 }
600 if (line == NULL || addlistitem(list, line) != 0) {
601 DECREF(list);
602 XDECREF(line);
603 return NULL;
604 }
605 DECREF(line);
606 }
607 return list;
608}
609
610static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000611file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612 fileobject *f;
613 object *args;
614{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000615 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000616 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000617 if (f->f_fp == NULL)
618 return err_closed();
619 if (!getargs(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000620 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000621 f->f_softspace = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000622 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000623 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000624 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000625 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000626 if (n2 != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000627 err_errno(IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000628 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000629 return NULL;
630 }
631 INCREF(None);
632 return None;
633}
634
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000635static object *
636file_writelines(f, args)
637 fileobject *f;
638 object *args;
639{
640 int i, n;
641 if (f->f_fp == NULL)
642 return err_closed();
643 if (args == NULL || !is_listobject(args)) {
644 err_setstr(TypeError,
645 "writelines() requires list of strings");
646 return NULL;
647 }
648 n = getlistsize(args);
649 f->f_softspace = 0;
650 BGN_SAVE
651 errno = 0;
652 for (i = 0; i < n; i++) {
653 object *line = getlistitem(args, i);
654 int len;
655 int nwritten;
656 if (!is_stringobject(line)) {
657 RET_SAVE
658 err_setstr(TypeError,
659 "writelines() requires list of strings");
660 return NULL;
661 }
662 len = getstringsize(line);
663 nwritten = fwrite(getstringvalue(line), 1, len, f->f_fp);
664 if (nwritten != len) {
665 RET_SAVE
666 err_errno(IOError);
667 clearerr(f->f_fp);
668 return NULL;
669 }
670 }
671 END_SAVE
672 INCREF(None);
673 return None;
674}
675
Guido van Rossum3f5da241990-12-20 15:06:42 +0000676static struct methodlist file_methods[] = {
Guido van Rossum295d1711995-02-19 15:55:19 +0000677 {"close", (method)file_close, 0},
678 {"flush", (method)file_flush, 0},
679 {"fileno", (method)file_fileno, 0},
680 {"isatty", (method)file_isatty, 0},
681 {"read", (method)file_read, 0},
682 {"readline", (method)file_readline, 0},
683 {"readlines", (method)file_readlines, 0},
684 {"seek", (method)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000685#ifdef HAVE_FTRUNCATE
Guido van Rossum295d1711995-02-19 15:55:19 +0000686 {"truncate", (method)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000687#endif
Guido van Rossum295d1711995-02-19 15:55:19 +0000688 {"tell", (method)file_tell, 0},
689 {"write", (method)file_write, 0},
690 {"writelines", (method)file_writelines, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691 {NULL, NULL} /* sentinel */
692};
693
Guido van Rossumb6775db1994-08-01 11:34:53 +0000694#define OFF(x) offsetof(fileobject, x)
695
696static struct memberlist file_memberlist[] = {
697 {"softspace", T_INT, OFF(f_softspace)},
698 {"mode", T_OBJECT, OFF(f_mode), RO},
699 {"name", T_OBJECT, OFF(f_name), RO},
700 /* getattr(f, "closed") is implemented without this table */
701 {"closed", T_INT, 0, RO},
702 {NULL} /* Sentinel */
703};
704
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000705static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000706file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000707 fileobject *f;
708 char *name;
709{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000710 object *res;
711
712 res = findmethod(file_methods, (object *)f, name);
713 if (res != NULL)
714 return res;
715 err_clear();
716 if (strcmp(name, "closed") == 0)
717 return newintobject((long)(f->f_fp == 0));
718 return getmember((char *)f, file_memberlist, name);
719}
720
721static int
722file_setattr(f, name, v)
723 fileobject *f;
724 char *name;
725 object *v;
726{
727 if (v == NULL) {
728 err_setstr(AttributeError, "can't delete file attributes");
729 return -1;
730 }
731 return setmember((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000732}
733
734typeobject Filetype = {
735 OB_HEAD_INIT(&Typetype)
736 0,
737 "file",
738 sizeof(fileobject),
739 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000740 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000741 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000742 (getattrfunc)file_getattr, /*tp_getattr*/
743 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000744 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000745 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000746};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000747
748/* Interface for the 'soft space' between print items. */
749
750int
751softspace(f, newflag)
752 object *f;
753 int newflag;
754{
755 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000756 if (f == NULL) {
757 /* Do nothing */
758 }
Guido van Rossum82d410e1993-11-01 16:26:16 +0000759 else if (is_fileobject(f)) {
Guido van Rossumeb183da1991-04-04 10:44:06 +0000760 oldflag = ((fileobject *)f)->f_softspace;
761 ((fileobject *)f)->f_softspace = newflag;
762 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000763 else {
764 object *v;
765 v = getattr(f, "softspace");
766 if (v == NULL)
767 err_clear();
768 else {
769 if (is_intobject(v))
770 oldflag = getintvalue(v);
771 DECREF(v);
772 }
773 v = newintobject((long)newflag);
774 if (v == NULL)
775 err_clear();
776 else {
777 if (setattr(f, "softspace", v) != 0)
778 err_clear();
779 DECREF(v);
780 }
781 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000782 return oldflag;
783}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000784
785/* Interfaces to write objects/strings to file-like objects */
786
787int
788writeobject(v, f, flags)
789 object *v;
790 object *f;
791 int flags;
792{
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000793 object *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000794 if (f == NULL) {
795 err_setstr(TypeError, "writeobject with NULL file");
796 return -1;
797 }
798 else if (is_fileobject(f)) {
799 FILE *fp = getfilefile(f);
800 if (fp == NULL) {
801 err_closed();
802 return -1;
803 }
804 return printobject(v, fp, flags);
805 }
806 writer = getattr(f, "write");
807 if (writer == NULL)
808 return -1;
Guido van Rossumc6004111993-11-05 10:22:19 +0000809 if (flags & PRINT_RAW)
810 value = strobject(v);
811 else
Guido van Rossum3165fe61992-09-25 21:59:05 +0000812 value = reprobject(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000813 if (value == NULL) {
814 DECREF(writer);
815 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000816 }
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000817 args = mkvalue("(O)", value);
818 if (value == NULL) {
819 DECREF(value);
820 DECREF(writer);
821 return -1;
822 }
823 result = call_object(writer, args);
824 DECREF(args);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000825 DECREF(value);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000826 DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000827 if (result == NULL)
828 return -1;
829 DECREF(result);
830 return 0;
831}
832
833void
834writestring(s, f)
835 char *s;
836 object *f;
837{
838 if (f == NULL) {
839 /* Do nothing */
840 }
841 else if (is_fileobject(f)) {
842 FILE *fp = getfilefile(f);
843 if (fp != NULL)
844 fputs(s, fp);
845 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000846 else if (!err_occurred()) {
Guido van Rossum3165fe61992-09-25 21:59:05 +0000847 object *v = newstringobject(s);
848 if (v == NULL) {
849 err_clear();
850 }
851 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000852 if (writeobject(v, f, PRINT_RAW) != 0)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000853 err_clear();
854 DECREF(v);
855 }
856 }
857}