klee
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
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 
25 static 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 
33 static 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 
42 static 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 
55 static 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 
72 static 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 
82 int 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 
94 KTest *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 
178 int 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;
186  if (!write_uint32(f, KTEST_VERSION))
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 
222 unsigned 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 
229 void 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 }
Definition: KTest.h:26
unsigned symArgvs
Definition: KTest.h:33
#define KTEST_MAGIC
Definition: KTest.cpp:18
int kTest_isKTestFile(const char *path)
Definition: KTest.cpp:82
unsigned numBytes
Definition: KTest.h:21
unsigned kTest_numBytes(KTest *bo)
Definition: KTest.cpp:222
#define BOUT_MAGIC
Definition: KTest.cpp:21
unsigned numArgs
Definition: KTest.h:30
unsigned numObjects
Definition: KTest.h:36
#define KTEST_MAGIC_SIZE
Definition: KTest.cpp:17
char ** args
Definition: KTest.h:31
int kTest_toFile(KTest *bo, const char *path)
Definition: KTest.cpp:178
unsigned char * bytes
Definition: KTest.h:22
static int read_string(FILE *f, char **value_out)
Definition: KTest.cpp:42
static int write_string(FILE *f, const char *value)
Definition: KTest.cpp:55
unsigned version
Definition: KTest.h:28
KTestObject * objects
Definition: KTest.h:37
unsigned kTest_getCurrentVersion()
Definition: KTest.cpp:67
unsigned symArgvLen
Definition: KTest.h:34
char * name
Definition: KTest.h:20
static int write_uint32(FILE *f, unsigned value)
Definition: KTest.cpp:33
static int kTest_checkHeader(FILE *f)
Definition: KTest.cpp:72
KTest * kTest_fromFile(const char *path)
Definition: KTest.cpp:94
#define KTEST_VERSION
Definition: KTest.cpp:16
static int read_uint32(FILE *f, unsigned *value_out)
Definition: KTest.cpp:25
void kTest_free(KTest *bo)
Definition: KTest.cpp:229