import source from 1.3.40
[external/swig.git] / Source / DOH / file.c
1 /* ----------------------------------------------------------------------------- 
2  * file.c
3  *
4  *     This file implements a file-like object that can be built around an 
5  *     ordinary FILE * or integer file descriptor.
6  * 
7  * Author(s) : David Beazley (beazley@cs.uchicago.edu)
8  *
9  * Copyright (C) 1999-2000.  The University of Chicago
10  * See the file LICENSE for information on usage and redistribution.    
11  * ----------------------------------------------------------------------------- */
12
13 char cvsroot_file_c[] = "$Id: file.c 10898 2008-11-03 12:51:45Z wsfulton $";
14
15 #include "dohint.h"
16
17 #ifdef DOH_INTFILE
18 #include <unistd.h>
19 #endif
20 #include <errno.h>
21
22 typedef struct {
23   FILE *filep;
24   int fd;
25   int closeondel;
26 } DohFile;
27
28 /* -----------------------------------------------------------------------------
29  * DelFile()
30  * ----------------------------------------------------------------------------- */
31
32 static void DelFile(DOH *fo) {
33   DohFile *f = (DohFile *) ObjData(fo);
34   if (f->closeondel) {
35     if (f->filep) {
36       fclose(f->filep);
37     }
38 #ifdef DOH_INTFILE
39     if (f->fd) {
40       close(f->fd);
41     }
42 #endif
43   }
44   DohFree(f);
45 }
46
47 /* -----------------------------------------------------------------------------
48  * File_read()
49  * ----------------------------------------------------------------------------- */
50
51 static int File_read(DOH *fo, void *buffer, int len) {
52   DohFile *f = (DohFile *) ObjData(fo);
53
54   if (f->filep) {
55     return fread(buffer, 1, len, f->filep);
56   } else if (f->fd) {
57 #ifdef DOH_INTFILE
58     return read(f->fd, buffer, len);
59 #endif
60   }
61   return -1;
62 }
63
64 /* -----------------------------------------------------------------------------
65  * File_write()
66  * ----------------------------------------------------------------------------- */
67
68 static int File_write(DOH *fo, void *buffer, int len) {
69   DohFile *f = (DohFile *) ObjData(fo);
70   if (f->filep) {
71     int ret = (int) fwrite(buffer, 1, len, f->filep);
72     int err = (ret != len) ? ferror(f->filep) : 0;
73     return err ? -1 : ret;
74   } else if (f->fd) {
75 #ifdef DOH_INTFILE
76     return write(f->fd, buffer, len);
77 #endif
78   }
79   return -1;
80 }
81
82 /* -----------------------------------------------------------------------------
83  * File_seek()
84  * ----------------------------------------------------------------------------- */
85
86 static int File_seek(DOH *fo, long offset, int whence) {
87   DohFile *f = (DohFile *) ObjData(fo);
88   if (f->filep) {
89     return fseek(f->filep, offset, whence);
90   } else if (f->fd) {
91 #ifdef DOH_INTFILE
92     return lseek(f->fd, offset, whence);
93 #endif
94   }
95   return -1;
96 }
97
98 /* -----------------------------------------------------------------------------
99  * File_tell()
100  * ----------------------------------------------------------------------------- */
101
102 static long File_tell(DOH *fo) {
103   DohFile *f = (DohFile *) ObjData(fo);
104   if (f->filep) {
105     return ftell(f->filep);
106   } else if (f->fd) {
107 #ifdef DOH_INTFILE
108     return lseek(f->fd, 0, SEEK_CUR);
109 #endif
110   }
111   return -1;
112 }
113
114 /* -----------------------------------------------------------------------------
115  * File_putc()
116  * ----------------------------------------------------------------------------- */
117
118 static int File_putc(DOH *fo, int ch) {
119   DohFile *f = (DohFile *) ObjData(fo);
120   if (f->filep) {
121     return fputc(ch, f->filep);
122   } else if (f->fd) {
123 #ifdef DOH_INTFILE
124     char c;
125     c = (char) ch;
126     return write(f->fd, &c, 1);
127 #endif
128   }
129   return -1;
130 }
131
132 /* -----------------------------------------------------------------------------
133  * File_getc()
134  * ----------------------------------------------------------------------------- */
135
136 static int File_getc(DOH *fo) {
137   DohFile *f = (DohFile *) ObjData(fo);
138   if (f->filep) {
139     return fgetc(f->filep);
140   } else if (f->fd) {
141 #ifdef DOH_INTFILE
142     unsigned char c;
143     if (read(f->fd, &c, 1) < 0)
144       return EOF;
145     return c;
146 #endif
147   }
148   return EOF;
149 }
150
151 /* -----------------------------------------------------------------------------
152  * File_ungetc()
153  *
154  * Put a character back onto the input
155  * ----------------------------------------------------------------------------- */
156
157 static int File_ungetc(DOH *fo, int ch) {
158   DohFile *f = (DohFile *) ObjData(fo);
159   if (f->filep) {
160     return ungetc(ch, f->filep);
161   } else if (f->fd) {
162 #ifdef DOH_INTFILE
163     /* Not implemented yet */
164 #endif
165   }
166   return -1;
167 }
168
169 /* -----------------------------------------------------------------------------
170  * File_close()
171  *
172  * Close the file
173  * ----------------------------------------------------------------------------- */
174
175 static int File_close(DOH *fo) {
176   int ret = 0;
177   DohFile *f = (DohFile *) ObjData(fo);
178   if (f->filep) {
179     ret = fclose(f->filep);
180     f->filep = 0;
181   } else if (f->fd) {
182 #ifdef DOH_INTFILE
183     ret = close(f->fd);
184     f->fd = 0;
185 #endif
186   }
187   return ret;
188 }
189
190 static DohFileMethods FileFileMethods = {
191   File_read,
192   File_write,
193   File_putc,
194   File_getc,
195   File_ungetc,
196   File_seek,
197   File_tell,
198   File_close,                   /* close */
199 };
200
201 static DohObjInfo DohFileType = {
202   "DohFile",                    /* objname      */
203   DelFile,                      /* doh_del      */
204   0,                            /* doh_copy     */
205   0,                            /* doh_clear    */
206   0,                            /* doh_str      */
207   0,                            /* doh_data     */
208   0,                            /* doh_dump     */
209   0,                            /* doh_len      */
210   0,                            /* doh_hash     */
211   0,                            /* doh_cmp      */
212   0,                            /* doh_equal    */
213   0,                            /* doh_first    */
214   0,                            /* doh_next     */
215   0,                            /* doh_setfile  */
216   0,                            /* doh_getfile  */
217   0,                            /* doh_setline  */
218   0,                            /* doh_getline  */
219   0,                            /* doh_mapping  */
220   0,                            /* doh_sequence */
221   &FileFileMethods,             /* doh_file     */
222   0,                            /* doh_string   */
223   0,                            /* doh_callable */
224   0,                            /* doh_position */
225 };
226
227 /* -----------------------------------------------------------------------------
228  * NewFile()
229  *
230  * Create a new file from a given filename and mode.
231  * If newfiles is non-zero, the filename is added to the list of new files.
232  * ----------------------------------------------------------------------------- */
233
234 DOH *DohNewFile(DOH *filename, const char *mode, DOHList *newfiles) {
235   DohFile *f;
236   FILE *file;
237   char *filen;
238
239   filen = Char(filename);
240   file = fopen(filen, mode);
241   if (!file)
242     return 0;
243
244   f = (DohFile *) DohMalloc(sizeof(DohFile));
245   if (!f) {
246     fclose(file);
247     return 0;
248   }
249   if (newfiles)
250     Append(newfiles, filename);
251   f->filep = file;
252   f->fd = 0;
253   f->closeondel = 1;
254   return DohObjMalloc(&DohFileType, f);
255 }
256
257 /* -----------------------------------------------------------------------------
258  * NewFileFromFile()
259  *
260  * Create a file object from an already open FILE *.
261  * ----------------------------------------------------------------------------- */
262
263 DOH *DohNewFileFromFile(FILE *file) {
264   DohFile *f;
265   f = (DohFile *) DohMalloc(sizeof(DohFile));
266   if (!f)
267     return 0;
268   f->filep = file;
269   f->fd = 0;
270   f->closeondel = 0;
271   return DohObjMalloc(&DohFileType, f);
272 }
273
274 /* -----------------------------------------------------------------------------
275  * NewFileFromFd()
276  *
277  * Create a file object from an already open FILE *.
278  * ----------------------------------------------------------------------------- */
279
280 DOH *DohNewFileFromFd(int fd) {
281   DohFile *f;
282   f = (DohFile *) DohMalloc(sizeof(DohFile));
283   if (!f)
284     return 0;
285   f->filep = 0;
286   f->fd = fd;
287   f->closeondel = 0;
288   return DohObjMalloc(&DohFileType, f);
289 }
290
291 /* -----------------------------------------------------------------------------
292  * FileErrorDisplay()
293  *
294  * Display cause of one of the NewFile functions failing.
295  * ----------------------------------------------------------------------------- */
296
297 void DohFileErrorDisplay(DOHString * filename) {
298   Printf(stderr, "Unable to open file %s: %s\n", filename, strerror(errno));
299 }