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