klee
KTest.cpp
Go to the documentation of this file.
1//===-- KTest.cpp ---------------------------------------------------------===//
2//
3// The KLEE Symbolic Virtual Machine
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "klee/ADT/KTest.h"
11
12#include <stdlib.h>
13#include <string.h>
14#include <stdio.h>
15
16#define KTEST_VERSION 3
17#define KTEST_MAGIC_SIZE 5
18#define KTEST_MAGIC "KTEST"
19
20// for compatibility reasons
21#define BOUT_MAGIC "BOUT\n"
22
23/***/
24
25static int read_uint32(FILE *f, unsigned *value_out) {
26 unsigned char data[4];
27 if (fread(data, 4, 1, f)!=1)
28 return 0;
29 *value_out = (((((data[0]<<8) + data[1])<<8) + data[2])<<8) + data[3];
30 return 1;
31}
32
33static int write_uint32(FILE *f, unsigned value) {
34 unsigned char data[4];
35 data[0] = value>>24;
36 data[1] = value>>16;
37 data[2] = value>> 8;
38 data[3] = value>> 0;
39 return fwrite(data, 1, 4, f)==4;
40}
41
42static int read_string(FILE *f, char **value_out) {
43 unsigned len;
44 if (!read_uint32(f, &len))
45 return 0;
46 *value_out = (char*) malloc(len+1);
47 if (!*value_out)
48 return 0;
49 if (fread(*value_out, len, 1, f)!=1)
50 return 0;
51 (*value_out)[len] = 0;
52 return 1;
53}
54
55static int write_string(FILE *f, const char *value) {
56 unsigned len = strlen(value);
57 if (!write_uint32(f, len))
58 return 0;
59 if (fwrite(value, len, 1, f)!=1)
60 return 0;
61 return 1;
62}
63
64/***/
65
66
68 return KTEST_VERSION;
69}
70
71
72static int kTest_checkHeader(FILE *f) {
73 char header[KTEST_MAGIC_SIZE];
74 if (fread(header, KTEST_MAGIC_SIZE, 1, f)!=1)
75 return 0;
76 if (memcmp(header, KTEST_MAGIC, KTEST_MAGIC_SIZE) &&
77 memcmp(header, BOUT_MAGIC, KTEST_MAGIC_SIZE))
78 return 0;
79 return 1;
80}
81
82int kTest_isKTestFile(const char *path) {
83 FILE *f = fopen(path, "rb");
84 int res;
85
86 if (!f)
87 return 0;
88 res = kTest_checkHeader(f);
89 fclose(f);
90
91 return res;
92}
93
94KTest *kTest_fromFile(const char *path) {
95 FILE *f = fopen(path, "rb");
96 KTest *res = 0;
97 unsigned i, version;
98
99 if (!f)
100 goto error;
101 if (!kTest_checkHeader(f))
102 goto error;
103
104 res = (KTest*) calloc(1, sizeof(*res));
105 if (!res)
106 goto error;
107
108 if (!read_uint32(f, &version))
109 goto error;
110
111 if (version > kTest_getCurrentVersion())
112 goto error;
113
114 res->version = version;
115
116 if (!read_uint32(f, &res->numArgs))
117 goto error;
118 res->args = (char**) calloc(res->numArgs, sizeof(*res->args));
119 if (!res->args)
120 goto error;
121
122 for (i=0; i<res->numArgs; i++)
123 if (!read_string(f, &res->args[i]))
124 goto error;
125
126 if (version >= 2) {
127 if (!read_uint32(f, &res->symArgvs))
128 goto error;
129 if (!read_uint32(f, &res->symArgvLen))
130 goto error;
131 }
132
133 if (!read_uint32(f, &res->numObjects))
134 goto error;
135 res->objects = (KTestObject*) calloc(res->numObjects, sizeof(*res->objects));
136 if (!res->objects)
137 goto error;
138 for (i=0; i<res->numObjects; i++) {
139 KTestObject *o = &res->objects[i];
140 if (!read_string(f, &o->name))
141 goto error;
142 if (!read_uint32(f, &o->numBytes))
143 goto error;
144 o->bytes = (unsigned char*) malloc(o->numBytes);
145 if (fread(o->bytes, o->numBytes, 1, f)!=1)
146 goto error;
147 }
148
149 fclose(f);
150
151 return res;
152 error:
153 if (res) {
154 if (res->args) {
155 for (i=0; i<res->numArgs; i++)
156 if (res->args[i])
157 free(res->args[i]);
158 free(res->args);
159 }
160 if (res->objects) {
161 for (i=0; i<res->numObjects; i++) {
162 KTestObject *bo = &res->objects[i];
163 if (bo->name)
164 free(bo->name);
165 if (bo->bytes)
166 free(bo->bytes);
167 }
168 free(res->objects);
169 }
170 free(res);
171 }
172
173 if (f) fclose(f);
174
175 return 0;
176}
177
178int kTest_toFile(KTest *bo, const char *path) {
179 FILE *f = fopen(path, "wb");
180 unsigned i;
181
182 if (!f)
183 goto error;
184 if (fwrite(KTEST_MAGIC, strlen(KTEST_MAGIC), 1, f)!=1)
185 goto error;
187 goto error;
188
189 if (!write_uint32(f, bo->numArgs))
190 goto error;
191 for (i=0; i<bo->numArgs; i++) {
192 if (!write_string(f, bo->args[i]))
193 goto error;
194 }
195
196 if (!write_uint32(f, bo->symArgvs))
197 goto error;
198 if (!write_uint32(f, bo->symArgvLen))
199 goto error;
200
201 if (!write_uint32(f, bo->numObjects))
202 goto error;
203 for (i=0; i<bo->numObjects; i++) {
204 KTestObject *o = &bo->objects[i];
205 if (!write_string(f, o->name))
206 goto error;
207 if (!write_uint32(f, o->numBytes))
208 goto error;
209 if (fwrite(o->bytes, o->numBytes, 1, f)!=1)
210 goto error;
211 }
212
213 fclose(f);
214
215 return 1;
216 error:
217 if (f) fclose(f);
218
219 return 0;
220}
221
222unsigned kTest_numBytes(KTest *bo) {
223 unsigned i, res = 0;
224 for (i=0; i<bo->numObjects; i++)
225 res += bo->objects[i].numBytes;
226 return res;
227}
228
229void kTest_free(KTest *bo) {
230 unsigned i;
231 for (i=0; i<bo->numArgs; i++)
232 free(bo->args[i]);
233 free(bo->args);
234 for (i=0; i<bo->numObjects; i++) {
235 free(bo->objects[i].name);
236 free(bo->objects[i].bytes);
237 }
238 free(bo->objects);
239 free(bo);
240}
#define KTEST_VERSION
Definition: KTest.cpp:16
void kTest_free(KTest *bo)
Definition: KTest.cpp:229
int kTest_toFile(KTest *bo, const char *path)
Definition: KTest.cpp:178
static int write_uint32(FILE *f, unsigned value)
Definition: KTest.cpp:33
KTest * kTest_fromFile(const char *path)
Definition: KTest.cpp:94
static int write_string(FILE *f, const char *value)
Definition: KTest.cpp:55
#define KTEST_MAGIC_SIZE
Definition: KTest.cpp:17
#define KTEST_MAGIC
Definition: KTest.cpp:18
#define BOUT_MAGIC
Definition: KTest.cpp:21
static int kTest_checkHeader(FILE *f)
Definition: KTest.cpp:72
static int read_uint32(FILE *f, unsigned *value_out)
Definition: KTest.cpp:25
static int read_string(FILE *f, char **value_out)
Definition: KTest.cpp:42
int kTest_isKTestFile(const char *path)
Definition: KTest.cpp:82
unsigned kTest_numBytes(KTest *bo)
Definition: KTest.cpp:222
unsigned kTest_getCurrentVersion()
Definition: KTest.cpp:67
char * name
Definition: KTest.h:19
unsigned char * bytes
Definition: KTest.h:21
unsigned numBytes
Definition: KTest.h:20
Definition: KTest.h:25
unsigned symArgvLen
Definition: KTest.h:33
unsigned version
Definition: KTest.h:27
unsigned numObjects
Definition: KTest.h:35
KTestObject * objects
Definition: KTest.h:36
unsigned numArgs
Definition: KTest.h:29
unsigned symArgvs
Definition: KTest.h:32
char ** args
Definition: KTest.h:30