blob: f5e5c5974c7741701ff1ee4eb4b26f04763dd6a2 [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 Rossum295d1711995-02-19 15:55:19 +000039#ifdef THINK_C
40#define HAVE_FOPENRF
41#endif
Jack Jansene08dea191995-04-23 22:12:47 +000042#ifdef __MWERKS__
43/* Mwerks fopen() doesn't always set errno */
44#define NO_FOPEN_ERRNO
45#endif
Guido van Rossum295d1711995-02-19 15:55:19 +000046
Guido van Rossumce5ba841991-03-06 13:06:18 +000047#define BUF(v) GETSTRINGVALUE((stringobject *)v)
48
Guido van Rossumf1dc5661993-07-05 10:31:29 +000049#include <errno.h>
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050
51typedef struct {
52 OB_HEAD
53 FILE *f_fp;
54 object *f_name;
55 object *f_mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000056 int (*f_close) PROTO((FILE *));
Guido van Rossumeb183da1991-04-04 10:44:06 +000057 int f_softspace; /* Flag used by 'print' command */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000058} fileobject;
59
60FILE *
61getfilefile(f)
62 object *f;
63{
Guido van Rossum3165fe61992-09-25 21:59:05 +000064 if (f == NULL || !is_fileobject(f))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000065 return NULL;
Guido van Rossum3165fe61992-09-25 21:59:05 +000066 else
67 return ((fileobject *)f)->f_fp;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000068}
69
70object *
Guido van Rossumdb3165e1993-10-18 17:06:59 +000071getfilename(f)
72 object *f;
73{
74 if (f == NULL || !is_fileobject(f))
75 return NULL;
76 else
77 return ((fileobject *)f)->f_name;
78}
79
80object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000081newopenfileobject(fp, name, mode, close)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082 FILE *fp;
83 char *name;
84 char *mode;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000085 int (*close) FPROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086{
87 fileobject *f = NEWOBJ(fileobject, &Filetype);
88 if (f == NULL)
89 return NULL;
90 f->f_fp = NULL;
91 f->f_name = newstringobject(name);
92 f->f_mode = newstringobject(mode);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +000093 f->f_close = close;
Guido van Rossumeb183da1991-04-04 10:44:06 +000094 f->f_softspace = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095 if (f->f_name == NULL || f->f_mode == NULL) {
96 DECREF(f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 return NULL;
98 }
99 f->f_fp = fp;
100 return (object *) f;
101}
102
103object *
104newfileobject(name, mode)
105 char *name, *mode;
106{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000107 extern int fclose PROTO((FILE *));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000108 fileobject *f;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000109 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode, fclose);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 if (f == NULL)
111 return NULL;
Guido van Rossumd7047b31995-01-02 19:07:15 +0000112#ifdef HAVE_FOPENRF
Guido van Rossuma08095a1991-02-13 23:25:27 +0000113 if (*mode == '*') {
114 FILE *fopenRF();
115 f->f_fp = fopenRF(name, mode+1);
116 }
117 else
118#endif
Guido van Rossumff4949e1992-08-05 19:58:53 +0000119 {
120 BGN_SAVE
121 f->f_fp = fopen(name, mode);
122 END_SAVE
123 }
Guido van Rossuma08095a1991-02-13 23:25:27 +0000124 if (f->f_fp == NULL) {
Jack Jansene08dea191995-04-23 22:12:47 +0000125#ifdef NO_FOPEN_ERRNO
126 if ( errno == 0 ) {
127 err_setstr(IOError, "Cannot open file");
128 DECREF(f);
129 return NULL;
130 }
131#endif
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000132 err_errno(IOError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133 DECREF(f);
134 return NULL;
135 }
136 return (object *)f;
137}
138
Guido van Rossumb6775db1994-08-01 11:34:53 +0000139void
140setfilebufsize(f, bufsize)
141 object *f;
142 int bufsize;
143{
144 if (bufsize >= 0) {
145#ifdef HAVE_SETVBUF
146 int type;
147 switch (bufsize) {
148 case 0:
149 type = _IONBF;
150 break;
151 case 1:
152 type = _IOLBF;
153 bufsize = BUFSIZ;
154 break;
155 default:
156 type = _IOFBF;
157 }
158 setvbuf(((fileobject *)f)->f_fp, (char *)NULL, type, bufsize);
159#endif /* HAVE_SETVBUF */
160 }
161}
162
Guido van Rossumd7297e61992-07-06 14:19:26 +0000163static object *
164err_closed()
165{
166 err_setstr(ValueError, "I/O operation on closed file");
167 return NULL;
168}
169
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000170/* Methods */
171
172static void
Guido van Rossum3f5da241990-12-20 15:06:42 +0000173file_dealloc(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174 fileobject *f;
175{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000176 if (f->f_fp != NULL && f->f_close != NULL) {
177 BGN_SAVE
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000178 (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000179 END_SAVE
180 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181 if (f->f_name != NULL)
182 DECREF(f->f_name);
183 if (f->f_mode != NULL)
184 DECREF(f->f_mode);
185 free((char *)f);
186}
187
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000189file_repr(f)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000190 fileobject *f;
191{
192 char buf[300];
Guido van Rossume35399e1993-01-10 18:33:56 +0000193 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 f->f_fp == NULL ? "closed" : "open",
195 getstringvalue(f->f_name),
Guido van Rossume35399e1993-01-10 18:33:56 +0000196 getstringvalue(f->f_mode),
197 (long)f);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198 return newstringobject(buf);
199}
200
201static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000202file_close(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000203 fileobject *f;
204 object *args;
205{
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000206 int sts = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000207 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209 if (f->f_fp != NULL) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000210 if (f->f_close != NULL) {
211 BGN_SAVE
212 errno = 0;
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000213 sts = (*f->f_close)(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000214 END_SAVE
215 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000216 f->f_fp = NULL;
217 }
Guido van Rossumfebd5511992-03-04 16:39:24 +0000218 if (sts == EOF)
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000219 return err_errno(IOError);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000220 if (sts != 0)
221 return newintobject((long)sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 INCREF(None);
223 return None;
224}
225
226static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000227file_seek(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228 fileobject *f;
229 object *args;
230{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000231 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000232 int whence;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000233 int ret;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000234
Guido van Rossumd7297e61992-07-06 14:19:26 +0000235 if (f->f_fp == NULL)
236 return err_closed();
237 whence = 0;
238 if (!getargs(args, "l", &offset)) {
239 err_clear();
240 if (!getargs(args, "(li)", &offset, &whence))
Guido van Rossumce5ba841991-03-06 13:06:18 +0000241 return NULL;
242 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000243 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000244 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000245 ret = fseek(f->f_fp, offset, whence);
246 END_SAVE
247 if (ret != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000248 err_errno(IOError);
249 clearerr(f->f_fp);
250 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000251 }
252 INCREF(None);
253 return None;
254}
255
Guido van Rossumd7047b31995-01-02 19:07:15 +0000256#ifdef HAVE_FTRUNCATE
257static object *
258file_truncate(f, args)
259 fileobject *f;
260 object *args;
261{
262 long newsize;
263 int ret;
264
265 if (f->f_fp == NULL)
266 return err_closed();
267 if (!getargs(args, "l", &newsize)) {
268 err_clear();
269 if (!getnoarg(args))
270 return NULL;
271 BGN_SAVE
272 errno = 0;
273 newsize = ftell(f->f_fp); /* default to current position*/
274 END_SAVE
275 if (newsize == -1L) {
276 err_errno(IOError);
277 clearerr(f->f_fp);
278 return NULL;
279 }
280 }
281 BGN_SAVE
282 errno = 0;
283 ret = fflush(f->f_fp);
284 END_SAVE
285 if (ret == 0) {
286 BGN_SAVE
287 errno = 0;
288 ret = ftruncate(fileno(f->f_fp), newsize);
289 END_SAVE
290 }
291 if (ret != 0) {
292 err_errno(IOError);
293 clearerr(f->f_fp);
294 return NULL;
295 }
296 INCREF(None);
297 return None;
298}
299#endif /* HAVE_FTRUNCATE */
300
Guido van Rossumce5ba841991-03-06 13:06:18 +0000301static object *
302file_tell(f, args)
303 fileobject *f;
304 object *args;
305{
306 long offset;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000307 if (f->f_fp == NULL)
308 return err_closed();
309 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000311 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000312 errno = 0;
313 offset = ftell(f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000314 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000315 if (offset == -1L) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000316 err_errno(IOError);
317 clearerr(f->f_fp);
318 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000319 }
320 return newintobject(offset);
321}
322
323static object *
Guido van Rossumed233a51992-06-23 09:07:03 +0000324file_fileno(f, args)
325 fileobject *f;
326 object *args;
327{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000328 if (f->f_fp == NULL)
329 return err_closed();
Guido van Rossumed233a51992-06-23 09:07:03 +0000330 if (!getnoarg(args))
331 return NULL;
332 return newintobject((long) fileno(f->f_fp));
333}
334
335static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000336file_flush(f, args)
337 fileobject *f;
338 object *args;
339{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000340 int res;
341
Guido van Rossumd7297e61992-07-06 14:19:26 +0000342 if (f->f_fp == NULL)
343 return err_closed();
344 if (!getnoarg(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000346 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000347 errno = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000348 res = fflush(f->f_fp);
349 END_SAVE
350 if (res != 0) {
Guido van Rossumfebd5511992-03-04 16:39:24 +0000351 err_errno(IOError);
352 clearerr(f->f_fp);
353 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000354 }
355 INCREF(None);
356 return None;
357}
358
359static object *
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000360file_isatty(f, args)
361 fileobject *f;
362 object *args;
363{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000364 long res;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000365 if (f->f_fp == NULL)
366 return err_closed();
367 if (!getnoarg(args))
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000368 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000369 BGN_SAVE
370 res = isatty((int)fileno(f->f_fp));
371 END_SAVE
372 return newintobject(res);
Guido van Rossuma1ab7fa1991-06-04 19:37:39 +0000373}
374
375static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000376file_read(f, args)
377 fileobject *f;
378 object *args;
379{
380 int n, n1, n2, n3;
381 object *v;
382
Guido van Rossumd7297e61992-07-06 14:19:26 +0000383 if (f->f_fp == NULL)
384 return err_closed();
Guido van Rossumb6775db1994-08-01 11:34:53 +0000385 if (args == NULL)
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000386 n = -1;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000387 else {
388 if (!getargs(args, "i", &n))
389 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000390 }
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000391 n2 = n >= 0 ? n : BUFSIZ;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000392 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000393 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000394 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000395 n1 = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000396 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000397 for (;;) {
398 n3 = fread(BUF(v)+n1, 1, n2-n1, f->f_fp);
399 /* XXX Error check? */
400 if (n3 == 0)
401 break;
402 n1 += n3;
403 if (n1 == n)
404 break;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000405 if (n < 0) {
Guido van Rossumce5ba841991-03-06 13:06:18 +0000406 n2 = n1 + BUFSIZ;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000407 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000408 if (resizestring(&v, n2) < 0)
409 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000410 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000411 }
412 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000413 END_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000414 if (n1 != n2)
415 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000416 return v;
417}
418
Guido van Rossum0bd24411991-04-04 15:21:57 +0000419/* Internal routine to get a line.
420 Size argument interpretation:
421 > 0: max length;
422 = 0: read arbitrary line;
423 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
Guido van Rossumce5ba841991-03-06 13:06:18 +0000424*/
425
Guido van Rossum234f9421993-06-17 12:35:49 +0000426static object *
Guido van Rossum0bd24411991-04-04 15:21:57 +0000427getline(f, n)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000428 fileobject *f;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000429 int n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000430{
Guido van Rossumce5ba841991-03-06 13:06:18 +0000431 register FILE *fp;
432 register int c;
433 register char *buf, *end;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000434 int n1, n2;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000435 object *v;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000436
Guido van Rossumc10aa771992-07-31 12:42:38 +0000437 fp = f->f_fp;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000438 n2 = n > 0 ? n : 100;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000439 v = newsizedstringobject((char *)NULL, n2);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000440 if (v == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000441 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000442 buf = BUF(v);
443 end = buf + n2;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000444
Guido van Rossumff4949e1992-08-05 19:58:53 +0000445 BGN_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000446 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000447 if ((c = getc(fp)) == EOF) {
Guido van Rossum76ad8ed1991-06-03 10:54:55 +0000448 clearerr(fp);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000449 if (sigcheck()) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000450 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000451 DECREF(v);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000452 return NULL;
453 }
454 if (n < 0 && buf == BUF(v)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000455 RET_SAVE
Guido van Rossum0bd24411991-04-04 15:21:57 +0000456 DECREF(v);
Guido van Rossum201be051991-12-24 13:26:41 +0000457 err_setstr(EOFError,
458 "EOF when reading a line");
Guido van Rossum0bd24411991-04-04 15:21:57 +0000459 return NULL;
460 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000461 break;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000462 }
463 if ((*buf++ = c) == '\n') {
464 if (n < 0)
465 buf--;
466 break;
467 }
Guido van Rossumce5ba841991-03-06 13:06:18 +0000468 if (buf == end) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000469 if (n > 0)
Guido van Rossumce5ba841991-03-06 13:06:18 +0000470 break;
471 n1 = n2;
472 n2 += 1000;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000473 RET_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000474 if (resizestring(&v, n2) < 0)
475 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000476 RES_SAVE
Guido van Rossumce5ba841991-03-06 13:06:18 +0000477 buf = BUF(v) + n1;
478 end = BUF(v) + n2;
479 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000480 }
Guido van Rossumff4949e1992-08-05 19:58:53 +0000481 END_SAVE
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000482
Guido van Rossumce5ba841991-03-06 13:06:18 +0000483 n1 = buf - BUF(v);
484 if (n1 != n2)
485 resizestring(&v, n1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000486 return v;
487}
488
Guido van Rossum0bd24411991-04-04 15:21:57 +0000489/* External C interface */
490
491object *
492filegetline(f, n)
493 object *f;
494 int n;
495{
Guido van Rossum3165fe61992-09-25 21:59:05 +0000496 if (f == NULL) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000497 err_badcall();
498 return NULL;
499 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000500 if (!is_fileobject(f)) {
501 object *reader;
502 object *args;
503 object *result;
504 reader = getattr(f, "readline");
505 if (reader == NULL)
506 return NULL;
507 if (n <= 0)
508 args = mkvalue("()");
509 else
510 args = mkvalue("(i)", n);
511 if (args == NULL) {
512 DECREF(reader);
513 return NULL;
514 }
515 result = call_object(reader, args);
516 DECREF(reader);
517 DECREF(args);
518 if (result != NULL && !is_stringobject(result)) {
519 DECREF(result);
520 result = NULL;
521 err_setstr(TypeError,
522 "object.readline() returned non-string");
523 }
524 if (n < 0 && result != NULL) {
525 char *s = getstringvalue(result);
526 int len = getstringsize(result);
527 if (len == 0) {
528 DECREF(result);
529 result = NULL;
530 err_setstr(EOFError,
531 "EOF when reading a line");
532 }
533 else if (s[len-1] == '\n') {
534 if (result->ob_refcnt == 1)
535 resizestring(&result, len-1);
536 else {
537 object *v;
Guido van Rossumde788b81992-12-22 14:24:04 +0000538 v = newsizedstringobject(s, len-1);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000539 DECREF(result);
540 result = v;
541 }
542 }
543 }
544 return result;
545 }
Guido van Rossumd7297e61992-07-06 14:19:26 +0000546 if (((fileobject*)f)->f_fp == NULL)
547 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000548 return getline((fileobject *)f, n);
549}
550
551/* Python method */
552
553static object *
554file_readline(f, args)
555 fileobject *f;
556 object *args;
557{
558 int n;
559
Guido van Rossumd7297e61992-07-06 14:19:26 +0000560 if (f->f_fp == NULL)
561 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000562 if (args == NULL)
563 n = 0; /* Unlimited */
564 else {
565 if (!getintarg(args, &n))
566 return NULL;
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000567 if (n == 0)
568 return newstringobject("");
569 if (n < 0)
570 n = 0;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000571 }
572
Guido van Rossum51415a71992-03-27 17:23:38 +0000573 return getline(f, n);
Guido van Rossum0bd24411991-04-04 15:21:57 +0000574}
575
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000576static object *
Guido van Rossumce5ba841991-03-06 13:06:18 +0000577file_readlines(f, args)
578 fileobject *f;
579 object *args;
580{
581 object *list;
582 object *line;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000583
Guido van Rossumd7297e61992-07-06 14:19:26 +0000584 if (f->f_fp == NULL)
585 return err_closed();
Guido van Rossum0bd24411991-04-04 15:21:57 +0000586 if (!getnoarg(args))
587 return NULL;
Guido van Rossumce5ba841991-03-06 13:06:18 +0000588 if ((list = newlistobject(0)) == NULL)
589 return NULL;
590 for (;;) {
Guido van Rossum0bd24411991-04-04 15:21:57 +0000591 line = getline(f, 0);
Guido van Rossumce5ba841991-03-06 13:06:18 +0000592 if (line != NULL && getstringsize(line) == 0) {
593 DECREF(line);
594 break;
595 }
596 if (line == NULL || addlistitem(list, line) != 0) {
597 DECREF(list);
598 XDECREF(line);
599 return NULL;
600 }
601 DECREF(line);
602 }
603 return list;
604}
605
606static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000607file_write(f, args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000608 fileobject *f;
609 object *args;
610{
Guido van Rossumd7297e61992-07-06 14:19:26 +0000611 char *s;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612 int n, n2;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000613 if (f->f_fp == NULL)
614 return err_closed();
615 if (!getargs(args, "s#", &s, &n))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000616 return NULL;
Guido van Rossumeb183da1991-04-04 10:44:06 +0000617 f->f_softspace = 0;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000618 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000619 errno = 0;
Guido van Rossumd7297e61992-07-06 14:19:26 +0000620 n2 = fwrite(s, 1, n, f->f_fp);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000621 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000622 if (n2 != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000623 err_errno(IOError);
Guido van Rossumfebd5511992-03-04 16:39:24 +0000624 clearerr(f->f_fp);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000625 return NULL;
626 }
627 INCREF(None);
628 return None;
629}
630
Guido van Rossum5a2a6831993-10-25 09:59:04 +0000631static object *
632file_writelines(f, args)
633 fileobject *f;
634 object *args;
635{
636 int i, n;
637 if (f->f_fp == NULL)
638 return err_closed();
639 if (args == NULL || !is_listobject(args)) {
640 err_setstr(TypeError,
641 "writelines() requires list of strings");
642 return NULL;
643 }
644 n = getlistsize(args);
645 f->f_softspace = 0;
646 BGN_SAVE
647 errno = 0;
648 for (i = 0; i < n; i++) {
649 object *line = getlistitem(args, i);
650 int len;
651 int nwritten;
652 if (!is_stringobject(line)) {
653 RET_SAVE
654 err_setstr(TypeError,
655 "writelines() requires list of strings");
656 return NULL;
657 }
658 len = getstringsize(line);
659 nwritten = fwrite(getstringvalue(line), 1, len, f->f_fp);
660 if (nwritten != len) {
661 RET_SAVE
662 err_errno(IOError);
663 clearerr(f->f_fp);
664 return NULL;
665 }
666 }
667 END_SAVE
668 INCREF(None);
669 return None;
670}
671
Guido van Rossum3f5da241990-12-20 15:06:42 +0000672static struct methodlist file_methods[] = {
Guido van Rossum295d1711995-02-19 15:55:19 +0000673 {"close", (method)file_close, 0},
674 {"flush", (method)file_flush, 0},
675 {"fileno", (method)file_fileno, 0},
676 {"isatty", (method)file_isatty, 0},
677 {"read", (method)file_read, 0},
678 {"readline", (method)file_readline, 0},
679 {"readlines", (method)file_readlines, 0},
680 {"seek", (method)file_seek, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000681#ifdef HAVE_FTRUNCATE
Guido van Rossum295d1711995-02-19 15:55:19 +0000682 {"truncate", (method)file_truncate, 0},
Guido van Rossumd7047b31995-01-02 19:07:15 +0000683#endif
Guido van Rossum295d1711995-02-19 15:55:19 +0000684 {"tell", (method)file_tell, 0},
685 {"write", (method)file_write, 0},
686 {"writelines", (method)file_writelines, 0},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000687 {NULL, NULL} /* sentinel */
688};
689
Guido van Rossumb6775db1994-08-01 11:34:53 +0000690#define OFF(x) offsetof(fileobject, x)
691
692static struct memberlist file_memberlist[] = {
693 {"softspace", T_INT, OFF(f_softspace)},
694 {"mode", T_OBJECT, OFF(f_mode), RO},
695 {"name", T_OBJECT, OFF(f_name), RO},
696 /* getattr(f, "closed") is implemented without this table */
697 {"closed", T_INT, 0, RO},
698 {NULL} /* Sentinel */
699};
700
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000701static object *
Guido van Rossum3f5da241990-12-20 15:06:42 +0000702file_getattr(f, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000703 fileobject *f;
704 char *name;
705{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000706 object *res;
707
708 res = findmethod(file_methods, (object *)f, name);
709 if (res != NULL)
710 return res;
711 err_clear();
712 if (strcmp(name, "closed") == 0)
713 return newintobject((long)(f->f_fp == 0));
714 return getmember((char *)f, file_memberlist, name);
715}
716
717static int
718file_setattr(f, name, v)
719 fileobject *f;
720 char *name;
721 object *v;
722{
723 if (v == NULL) {
724 err_setstr(AttributeError, "can't delete file attributes");
725 return -1;
726 }
727 return setmember((char *)f, file_memberlist, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000728}
729
730typeobject Filetype = {
731 OB_HEAD_INIT(&Typetype)
732 0,
733 "file",
734 sizeof(fileobject),
735 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000736 (destructor)file_dealloc, /*tp_dealloc*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000737 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000738 (getattrfunc)file_getattr, /*tp_getattr*/
739 (setattrfunc)file_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000740 0, /*tp_compare*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000741 (reprfunc)file_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000742};
Guido van Rossumeb183da1991-04-04 10:44:06 +0000743
744/* Interface for the 'soft space' between print items. */
745
746int
747softspace(f, newflag)
748 object *f;
749 int newflag;
750{
751 int oldflag = 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000752 if (f == NULL) {
753 /* Do nothing */
754 }
Guido van Rossum82d410e1993-11-01 16:26:16 +0000755 else if (is_fileobject(f)) {
Guido van Rossumeb183da1991-04-04 10:44:06 +0000756 oldflag = ((fileobject *)f)->f_softspace;
757 ((fileobject *)f)->f_softspace = newflag;
758 }
Guido van Rossum3165fe61992-09-25 21:59:05 +0000759 else {
760 object *v;
761 v = getattr(f, "softspace");
762 if (v == NULL)
763 err_clear();
764 else {
765 if (is_intobject(v))
766 oldflag = getintvalue(v);
767 DECREF(v);
768 }
769 v = newintobject((long)newflag);
770 if (v == NULL)
771 err_clear();
772 else {
773 if (setattr(f, "softspace", v) != 0)
774 err_clear();
775 DECREF(v);
776 }
777 }
Guido van Rossumeb183da1991-04-04 10:44:06 +0000778 return oldflag;
779}
Guido van Rossum3165fe61992-09-25 21:59:05 +0000780
781/* Interfaces to write objects/strings to file-like objects */
782
783int
784writeobject(v, f, flags)
785 object *v;
786 object *f;
787 int flags;
788{
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000789 object *writer, *value, *args, *result;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000790 if (f == NULL) {
791 err_setstr(TypeError, "writeobject with NULL file");
792 return -1;
793 }
794 else if (is_fileobject(f)) {
795 FILE *fp = getfilefile(f);
796 if (fp == NULL) {
797 err_closed();
798 return -1;
799 }
800 return printobject(v, fp, flags);
801 }
802 writer = getattr(f, "write");
803 if (writer == NULL)
804 return -1;
Guido van Rossumc6004111993-11-05 10:22:19 +0000805 if (flags & PRINT_RAW)
806 value = strobject(v);
807 else
Guido van Rossum3165fe61992-09-25 21:59:05 +0000808 value = reprobject(v);
Guido van Rossumc6004111993-11-05 10:22:19 +0000809 if (value == NULL) {
810 DECREF(writer);
811 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000812 }
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000813 args = mkvalue("(O)", value);
814 if (value == NULL) {
815 DECREF(value);
816 DECREF(writer);
817 return -1;
818 }
819 result = call_object(writer, args);
820 DECREF(args);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000821 DECREF(value);
Guido van Rossumd3f9a1a1995-07-10 23:32:26 +0000822 DECREF(writer);
Guido van Rossum3165fe61992-09-25 21:59:05 +0000823 if (result == NULL)
824 return -1;
825 DECREF(result);
826 return 0;
827}
828
829void
830writestring(s, f)
831 char *s;
832 object *f;
833{
834 if (f == NULL) {
835 /* Do nothing */
836 }
837 else if (is_fileobject(f)) {
838 FILE *fp = getfilefile(f);
839 if (fp != NULL)
840 fputs(s, fp);
841 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000842 else if (!err_occurred()) {
Guido van Rossum3165fe61992-09-25 21:59:05 +0000843 object *v = newstringobject(s);
844 if (v == NULL) {
845 err_clear();
846 }
847 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000848 if (writeobject(v, f, PRINT_RAW) != 0)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000849 err_clear();
850 DECREF(v);
851 }
852 }
853}