1 /*-----------------------------------------------------------------------
2 
3 File  : cio_fileops.h
4 
5 Author: Stephan Schulz
6 
7 Contents
8 
9   Simple operations on files, with error-checking.
10 
11   Copyright 1998, 1999 by the author.
12   This code is released under the GNU General Public Licence and
13   the GNU Lesser General Public License.
14   See the file COPYING in the main E directory for details..
15   Run "eprover -h" for contact information.
16 
17 Changes
18 
19 <1> Wed Jul 28 12:48:11 MET DST 1999
20     New
21 
22 -----------------------------------------------------------------------*/
23 
24 #include "cio_fileops.h"
25 
26 
27 
28 /*---------------------------------------------------------------------*/
29 /*                        Global Variables                             */
30 /*---------------------------------------------------------------------*/
31 
32 
33 /*---------------------------------------------------------------------*/
34 /*                      Forward Declarations                           */
35 /*---------------------------------------------------------------------*/
36 
37 
38 /*---------------------------------------------------------------------*/
39 /*                         Internal Functions                          */
40 /*---------------------------------------------------------------------*/
41 
42 
43 
44 /*---------------------------------------------------------------------*/
45 /*                         Exported Functions                          */
46 /*---------------------------------------------------------------------*/
47 
48 
49 /*-----------------------------------------------------------------------
50 //
51 // Function: InputOpen()
52 //
53 //   Open an input file for reading. NULL and "-" are stdin. If fail
54 //   is true, terminate with error, otherwise pass  error down.
55 //
56 // Global Variables: -
57 //
58 // Side Effects    : No significant ones (I hope)
59 //
60 /----------------------------------------------------------------------*/
61 
InputOpen(char * name,bool fail)62 FILE* InputOpen(char *name, bool fail)
63 {
64    FILE* in;
65    int statres;
66    struct stat stat_buf;
67 
68    if(name && strcmp(name,"-")!= 0)
69    {
70 
71       VERBOUTARG2("Trying file ", name);
72       in = fopen(name, "r");
73 
74       statres = stat (name, &stat_buf);
75       if(statres != 0)
76       {
77          in = NULL;
78          if(fail)
79          {
80             TmpErrno = errno;
81             SysError("Cannot stat file %s", FILE_ERROR, name);
82          }
83       }
84       else if(!S_ISREG (stat_buf.st_mode))
85       {
86          in = NULL;
87          if(fail)
88          {
89             Error("%s it is not a regular file", FILE_ERROR, name);
90          }
91       }
92 
93       if(fail && !in)
94       {
95          TmpErrno = errno;
96          SysError("Cannot open file %s for reading", FILE_ERROR , name);
97       }
98       if(fail)
99       {
100          VERBOUTARG("Input file is ", name);
101       }
102 
103    }
104    else
105    {
106       VERBOUT("Input is coming from <stdin>\n");
107       in = stdin;
108    }
109    return in;
110 }
111 
112 /*-----------------------------------------------------------------------
113 //
114 // Function: InputClose()
115 //
116 //   Close an input file.
117 //
118 // Global Variables: -
119 //
120 // Side Effects    : As above ;-)
121 //
122 /----------------------------------------------------------------------*/
123 
InputClose(FILE * file)124 void  InputClose(FILE* file)
125 {
126    VERBOUT("Closing input\n");
127    if(file != stdin)
128    {
129       if(fclose(file) != 0)
130       {
131          TmpErrno = errno;
132          SysError("Error while closing file", FILE_ERROR);
133       }
134    }
135 }
136 
137 
138 /*-----------------------------------------------------------------------
139 //
140 // Function: FileLoad()
141 //
142 //   Load the content of the named file and append it to dest. Returns
143 //   number of characters read.
144 //
145 // Global Variables: -
146 //
147 // Side Effects    : Memory, IO
148 //
149 /----------------------------------------------------------------------*/
150 
FileLoad(char * name,DStr_p dest)151 long  FileLoad(char* name, DStr_p dest)
152 {
153    FILE* in;
154    long count=0;
155    int c;
156 
157    in = InputOpen(name, true);
158 
159    while((c = getc(in))!= EOF)
160    {
161       count++;
162       DStrAppendChar(dest, c);
163    }
164    InputClose(in);
165 
166    return count;
167 }
168 
169 
170 
171 /*-----------------------------------------------------------------------
172 //
173 // Function: ConcatFiles()
174 //
175 //   Concatenate all file in (NULL-terminated) array sources into
176 //   target. "-" is stdin, as always. Return number of files
177 //   concated. This could be much optimized. Let me know if it ever
178 //   shows up in a profile...
179 //
180 // Global Variables: -
181 //
182 // Side Effects    : Writes a new file ;-)
183 //
184 /----------------------------------------------------------------------*/
185 
ConcatFiles(char * target,char ** sources)186 long ConcatFiles(char* target, char** sources)
187 {
188    FILE *in, *out;
189    int i;
190    int c;
191 
192    out = OutOpen(target);
193 
194    for(i=0; sources[i]; i++)
195    {
196       in = InputOpen(sources[i], true);
197       while((c = getc(in))!= EOF)
198       {
199     putc(c, out);
200       }
201       InputClose(in);
202    }
203    OutClose(out);
204 
205    return i;
206 }
207 
208 /*-----------------------------------------------------------------------
209 //
210 // Function: CopyFile()
211 //
212 //   Copy source to target (the lazy way ;-). Notice argument order
213 //   (compatible with = and strcpy(), not with cp!)
214 //
215 // Global Variables: -
216 //
217 // Side Effects    : Via ConcatFiles()
218 //
219 /----------------------------------------------------------------------*/
220 
CopyFile(char * target,char * source)221 long CopyFile(char* target, char* source)
222 {
223    char* tmp[2];
224 
225    tmp[0] = source;
226    tmp[1] = NULL;
227 
228    return ConcatFiles(target, tmp);
229 }
230 
231 
232 
233 /*-----------------------------------------------------------------------
234 //
235 // Function: FileRemove()
236 //
237 //   Remove a arbitrary file.
238 //
239 // Global Variables: -
240 //
241 // Side Effects    : Removes file.
242 //
243 /----------------------------------------------------------------------*/
244 
FileRemove(char * name)245 void FileRemove(char* name)
246 {
247    VERBOUTARG("Removing ", name);
248    if(unlink(name)!=0)
249    {
250       TmpErrno = errno;
251       sprintf(ErrStr, "Cannot remove file %s", name);
252       SysError(ErrStr, FILE_ERROR);      TmpErrno = errno;
253       SysError("Could not remove temporary file", SYS_ERROR);
254    }
255 }
256 
257 /*-----------------------------------------------------------------------
258 //
259 // Function: FilePrint()
260 //
261 //   Print the contents of the named file to out.
262 //
263 // Global Variables: -
264 //
265 // Side Effects    : Output
266 //
267 /----------------------------------------------------------------------*/
268 
FilePrint(FILE * out,char * name)269 void  FilePrint(FILE* out, char* name)
270 {
271    FILE* in;
272    int   c;
273 
274    in = InputOpen(name, true);
275    while((c = getc(in))!=EOF)
276    {
277       putc(c, out);
278    }
279    InputClose(in);
280 }
281 
282 
283 /*-----------------------------------------------------------------------
284 //
285 // Function: FileNameDirName()
286 //
287 //   Given a path name, return the directory portion (i.e. the part
288 //   from the first character to the last / character (including
289 //   it). Return "" if no directory part exists. It is the users
290 //   responsibility to FREE the memory returned.
291 //
292 // Global Variables: -
293 //
294 // Side Effects    : Memory operations
295 //
296 /----------------------------------------------------------------------*/
297 
FileNameDirName(char * name)298 char* FileNameDirName(char* name)
299 {
300    char *res;
301    int i, endpos = 0;
302 
303    assert(name);
304 
305    for(i=0; name[i]; i++)
306    {
307       if(name[i] == '/')
308       {
309          endpos = i+1;
310       }
311    }
312    res = SecureStrndup(name, endpos);
313 
314    return res;
315 }
316 
317 
318 /*-----------------------------------------------------------------------
319 //
320 // Function: FileFindBaseName()
321 //
322 //   Return a pointer to the first character of the last file name
323 //   component of name.
324 //
325 // Global Variables:
326 //
327 // Side Effects    :
328 //
329 /----------------------------------------------------------------------*/
330 
FileFindBaseName(char * name)331 char *FileFindBaseName(char* name)
332 {
333    char *res = name;
334 
335    for( ; *name; name++)
336    {
337       if(*name == '/')
338       {
339     res = name+1;
340       }
341    }
342    return res;
343 }
344 
345 
346 /*-----------------------------------------------------------------------
347 //
348 // Function: FileNameBaseName()
349 //
350 // Given a path, return a copy of the base name part of it, i.e. the
351 // string starting at the last / (if any). In contrast to the UNIX
352 // command 'basename', it will return the empty string for a string
353 // ending in "/".
354 //
355 // Global Variables: -
356 //
357 // Side Effects    : Memory operations
358 //
359 /----------------------------------------------------------------------*/
360 
FileNameBaseName(char * name)361 char* FileNameBaseName(char* name)
362 {
363    char *res, *endpos = name;
364 
365    endpos = FileFindBaseName(name);
366    res = SecureStrdup(endpos);
367 
368    return res;
369 }
370 
371 
372 /*-----------------------------------------------------------------------
373 //
374 // Function: FileNameStrip()
375 //
376 //   Given a path, return a copy of the core name - i.e. the basename
377 //   without a possible suffix.
378 //
379 // Global Variables: -
380 //
381 // Side Effects    : Memory operations
382 //
383 /----------------------------------------------------------------------*/
384 
FileNameStrip(char * name)385 char* FileNameStrip(char* name)
386 {
387    char *res, *endpos = name;
388    int len = 0, i;
389 
390 
391    endpos = FileFindBaseName(name);
392    for(i=0; endpos[i]; i++)
393    {
394       if(endpos[i] == '.')
395       {
396          len = i;
397       }
398    }
399    if(!len)
400    {
401       len = i;
402    }
403    res = SecureStrndup(endpos, len);
404 
405    return res;
406 }
407 
408 
409 
410 
411 
412 /*---------------------------------------------------------------------*/
413 /*                        End of File                                  */
414 /*---------------------------------------------------------------------*/
415