ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
file.c
Go to the documentation of this file.
1#include "file.h"
2#include "keatures.h"
3#include "utilities.h"
4
5#include <errno.h>
6#include <stdlib.h>
7#include <string.h>
8#include <sys/stat.h>
9#include <sys/types.h>
10
11#ifdef WIN32
12#define unlink _unlink
13#define access _access
14#define R_OK 4
15#define W_OK 2
16#else
17#include <unistd.h>
18#endif
19
21
22bool kissat_file_exists (const char *path) {
23 if (!path)
24 return false;
25 struct stat buf;
26 if (stat (path, &buf))
27 return false;
28 return true;
29}
30
31bool kissat_file_readable (const char *path) {
32 if (!path)
33 return false;
34 struct stat buf;
35 if (stat (path, &buf))
36 return false;
37 if (access (path, R_OK))
38 return false;
39 return true;
40}
41
42bool kissat_file_writable (const char *path) {
43 int res;
44 if (!path)
45 res = 1;
46 else if (!strcmp (path, "/dev/null"))
47 res = 0;
48 else {
49 if (!*path)
50 res = 2;
51 else {
52 struct stat buf;
53 const char *p = strrchr (path, '/');
54 if (!p) {
55 if (stat (path, &buf)) {
56 if (errno == ENOENT)
57 res = 0;
58 else
59 res = -2;
60 } else if (S_ISDIR (buf.st_mode))
61 res = 3;
62 else if (access (path, W_OK))
63 res = 4;
64 else
65 res = 0;
66 } else if (!p[1])
67 res = 5;
68 else {
69 const size_t len = p - path;
70 char *dirname = (char*)malloc (len + 1);
71 if (dirname) {
72 strncpy (dirname, path, len);
73 dirname[len] = 0;
74 if (stat (dirname, &buf))
75 res = 6;
76 else if (!S_ISDIR (buf.st_mode))
77 res = 7;
78 else if (access (dirname, W_OK))
79 res = 8;
80 else if (stat (path, &buf)) {
81 if (errno == ENOENT)
82 res = 0;
83 else
84 res = -3;
85 } else if (access (path, W_OK))
86 res = 9;
87 else
88 res = 0;
89 free (dirname);
90 } else
91 res = 10;
92 }
93 }
94 }
95 return !res;
96}
97
98size_t kissat_file_size (const char *path) {
99 struct stat buf;
100 if (stat (path, &buf))
101 return 0;
102 return (size_t) buf.st_size;
103}
104
105bool kissat_find_executable (const char *name) {
106 const size_t name_len = strlen (name);
107 const char *environment = getenv ("PATH");
108 if (!environment)
109 return false;
110 const size_t dirs_len = strlen (environment);
111 char *dirs = (char*)malloc (dirs_len + 1);
112 if (!dirs)
113 return false;
114 strcpy (dirs, environment);
115 bool res = false;
116 const char *end = dirs + dirs_len + 1;
117 for (char *dir = dirs, *q; !res && dir != end; dir = q) {
118 for (q = dir; *q && *q != ':'; q++)
119 KISSAT_assert (q + 1 < end);
120 *q++ = 0;
121 const size_t path_len = (q - dir) + name_len;
122 char *path = (char*)malloc (path_len + 1);
123 if (!path) {
124 free (dirs);
125 return false;
126 }
127 sprintf (path, "%s/%s", dir, name);
128 KISSAT_assert (strlen (path) == path_len);
129 res = kissat_file_readable (path);
130 free (path);
131 }
132 free (dirs);
133 return res;
134}
135
136static int bz2sig[] = {0x42, 0x5A, 0x68, EOF};
137static int gzsig[] = {0x1F, 0x8B, EOF};
138static int lzmasig[] = {0x5D, 0x00, 0x00, 0x80, 0x00, EOF};
139static int sig7z[] = {0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C, EOF};
140static int xzsig[] = {0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, EOF};
141static int Zsig[] = {0x1F, 0x9D, 0x90, EOF};
142
143static bool match_signature (const char *path, const int *sig) {
144 KISSAT_assert (path);
145 FILE *tmp = fopen (path, "r");
146 if (!tmp)
147 return false;
148 bool res = true;
149 for (const int *p = sig; res && (*p != EOF); p++)
150 res = (getc (tmp) == *p);
151 fclose (tmp);
152 return res;
153}
154
155#ifdef KISSAT_HAS_COMPRESSION
156
157static FILE *open_pipe (const char *fmt, const char *path,
158 const char *mode) {
159 size_t name_len = 0;
160 while (fmt[name_len] && fmt[name_len] != ' ')
161 name_len++;
162 char *name = (char*)malloc (name_len + 1);
163 if (!name)
164 return 0;
165 strncpy (name, fmt, name_len);
166 name[name_len] = 0;
167 bool found = kissat_find_executable (name);
168 free (name);
169 if (!found)
170 return 0;
171 char *cmd = (char*)malloc (strlen (fmt) + strlen (path));
172 if (!cmd)
173 return 0;
174 sprintf (cmd, fmt, path);
175 FILE *res = popen (cmd, mode);
176 free (cmd);
177 return res;
178}
179
180static FILE *read_pipe (const char *fmt, const int *sig, const char *path) {
181 if (!kissat_file_readable (path))
182 return 0;
183 if (sig && !match_signature (path, sig))
184 return 0;
185 return open_pipe (fmt, path, "r");
186}
187
188#ifndef SAFE
189
190static FILE *write_pipe (const char *fmt, const char *path) {
191 return open_pipe (fmt, path, "w");
192}
193
194#endif
195
196#endif
197
198void kissat_read_already_open_file (file *file, FILE *f, const char *path) {
199 file->file = f;
200 file->close = false;
201 file->reading = true;
202 file->compressed = false;
203 file->path = path;
204 file->bytes = 0;
205}
206
208 const char *path) {
209 file->file = f;
210 file->close = false;
211 file->reading = false;
212 file->compressed = false;
213 file->path = path;
214 file->bytes = 0;
215}
216
217#ifndef KISSAT_HAS_COMPRESSION
218
219bool kissat_looks_like_a_compressed_file (const char *path) {
220#define RETURN_TRUE_IF_COMPRESSED(SUFFIX, SIGNATURE) \
221 if (kissat_has_suffix (path, SUFFIX) && \
222 match_signature (path, SIGNATURE)) \
223 return true
224
225 RETURN_TRUE_IF_COMPRESSED (".bz2", bz2sig);
226 RETURN_TRUE_IF_COMPRESSED (".gz", gzsig);
227 RETURN_TRUE_IF_COMPRESSED (".lzma", lzmasig);
228 RETURN_TRUE_IF_COMPRESSED (".7z", sig7z);
229 RETURN_TRUE_IF_COMPRESSED (".xz", xzsig);
230 RETURN_TRUE_IF_COMPRESSED (".Z", Zsig);
231
232 return false;
233}
234
235#endif
236
237bool kissat_open_to_read_file (file *file, const char *path) {
238#ifdef KISSAT_HAS_COMPRESSION
239#define READ_PIPE(SUFFIX, CMD, SIG) \
240 do { \
241 if (kissat_has_suffix (path, SUFFIX)) { \
242 file->file = read_pipe (CMD, SIG, path); \
243 if (!file->file) \
244 break; \
245 file->close = true; \
246 file->reading = true; \
247 file->compressed = true; \
248 file->path = path; \
249 file->bytes = 0; \
250 return true; \
251 } \
252 } while (0)
253 READ_PIPE (".bz2", "bzip2 -c -d %s", bz2sig);
254 READ_PIPE (".gz", "gzip -c -d %s", gzsig);
255 READ_PIPE (".lzma", "lzma -c -d %s", lzmasig);
256 READ_PIPE (".7z", "7z x -so %s 2>/dev/null", sig7z);
257 READ_PIPE (".xz", "xz -c -d %s", xzsig);
258 READ_PIPE (".Z", "gzip -c -d %s", Zsig);
259#endif
260 file->file = fopen (path, "r");
261 if (!file->file)
262 return false;
263 file->close = true;
264 file->reading = true;
265 file->compressed = false;
266 file->path = path;
267 file->bytes = 0;
268
269 return true;
270}
271
272bool kissat_open_to_write_file (file *file, const char *path) {
273#if defined(KISSAT_HAS_COMPRESSION) && !defined(SAFE)
274#define WRITE_PIPE(SUFFIX, CMD) \
275 do { \
276 if (kissat_has_suffix (path, SUFFIX)) { \
277 if (SUFFIX[1] == '7' && kissat_file_readable (path) && \
278 unlink (path)) \
279 return false; \
280 file->file = write_pipe (CMD, path); \
281 if (!file->file) \
282 return false; \
283 file->close = true; \
284 file->reading = false; \
285 file->compressed = true; \
286 file->path = path; \
287 file->bytes = 0; \
288 return true; \
289 } \
290 } while (0)
291 WRITE_PIPE (".bz2", "bzip2 -c > %s");
292 WRITE_PIPE (".gz", "gzip -c > %s");
293 WRITE_PIPE (".lzma", "lzma -c > %s");
294 WRITE_PIPE (".7z", "7z a -si %s 2>/dev/null");
295 WRITE_PIPE (".xz", "xz -c > %s");
296#endif
297 file->file = fopen (path, "w");
298 if (!file->file)
299 return false;
300 file->close = true;
301 file->reading = false;
302 file->compressed = false;
303 file->path = path;
304 file->bytes = 0;
305 return true;
306}
307
311#ifdef KISSAT_HAS_COMPRESSION
312 if (file->close && file->compressed)
313 pclose (file->file);
314#else
316#endif
317 if (file->close && !file->compressed)
318 fclose (file->file);
319 file->file = 0;
320}
321
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
Cube * p
Definition exorList.c:222
ABC_NAMESPACE_IMPL_START bool kissat_file_exists(const char *path)
Definition file.c:22
void kissat_write_already_open_file(file *file, FILE *f, const char *path)
Definition file.c:207
void kissat_close_file(file *file)
Definition file.c:308
#define RETURN_TRUE_IF_COMPRESSED(SUFFIX, SIGNATURE)
bool kissat_open_to_read_file(file *file, const char *path)
Definition file.c:237
size_t kissat_file_size(const char *path)
Definition file.c:98
void kissat_read_already_open_file(file *file, FILE *f, const char *path)
Definition file.c:198
bool kissat_open_to_write_file(file *file, const char *path)
Definition file.c:272
bool kissat_file_readable(const char *path)
Definition file.c:31
bool kissat_file_writable(const char *path)
Definition file.c:42
bool kissat_find_executable(const char *name)
Definition file.c:105
bool kissat_looks_like_a_compressed_file(const char *path)
Definition file.c:219
#define KISSAT_assert(ignore)
Definition global.h:13
char * name
Definition main.h:24
Definition file.h:23
bool compressed
Definition file.h:27
FILE * file
Definition file.h:24
bool close
Definition file.h:25
bool reading
Definition file.h:26
uint64_t bytes
Definition file.h:29
const char * path
Definition file.h:28
Definition mode.h:11
int pclose()
char * strrchr()
int strlen()
char * strncpy()
int strcmp()
char * sprintf()
char * strcpy()
VOID_HACK free()
char * getenv()
FILE * popen()
char * malloc()