00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "klee/Internal/ADT/KTest.h"
00011
00012 #include <stdlib.h>
00013 #include <string.h>
00014 #include <stdio.h>
00015
00016 #define KTEST_VERSION 3
00017 #define KTEST_MAGIC_SIZE 5
00018 #define KTEST_MAGIC "KTEST"
00019
00020
00021 #define BOUT_MAGIC "BOUT\n"
00022
00023
00024
00025 static int read_uint32(FILE *f, unsigned *value_out) {
00026 unsigned char data[4];
00027 if (fread(data, 4, 1, f)!=1)
00028 return 0;
00029 *value_out = (((((data[0]<<8) + data[1])<<8) + data[2])<<8) + data[3];
00030 return 1;
00031 }
00032
00033 static int write_uint32(FILE *f, unsigned value) {
00034 unsigned char data[4];
00035 data[0] = value>>24;
00036 data[1] = value>>16;
00037 data[2] = value>> 8;
00038 data[3] = value>> 0;
00039 return fwrite(data, 1, 4, f)==4;
00040 }
00041
00042 static int read_string(FILE *f, char **value_out) {
00043 unsigned len;
00044 if (!read_uint32(f, &len))
00045 return 0;
00046 *value_out = (char*) malloc(len+1);
00047 if (!*value_out)
00048 return 0;
00049 if (fread(*value_out, len, 1, f)!=1)
00050 return 0;
00051 (*value_out)[len] = 0;
00052 return 1;
00053 }
00054
00055 static int write_string(FILE *f, const char *value) {
00056 unsigned len = strlen(value);
00057 if (!write_uint32(f, len))
00058 return 0;
00059 if (fwrite(value, len, 1, f)!=1)
00060 return 0;
00061 return 1;
00062 }
00063
00064
00065
00066
00067 unsigned kTest_getCurrentVersion() {
00068 return KTEST_VERSION;
00069 }
00070
00071
00072 static int kTest_checkHeader(FILE *f) {
00073 char header[KTEST_MAGIC_SIZE];
00074 if (fread(header, KTEST_MAGIC_SIZE, 1, f)!=1)
00075 return 0;
00076 if (memcmp(header, KTEST_MAGIC, KTEST_MAGIC_SIZE) &&
00077 memcmp(header, BOUT_MAGIC, KTEST_MAGIC_SIZE))
00078 return 0;
00079 return 1;
00080 }
00081
00082 int kTest_isKTestFile(const char *path) {
00083 FILE *f = fopen(path, "rb");
00084 int res;
00085
00086 if (!f)
00087 return 0;
00088 res = kTest_checkHeader(f);
00089 fclose(f);
00090
00091 return res;
00092 }
00093
00094 KTest *kTest_fromFile(const char *path) {
00095 FILE *f = fopen(path, "rb");
00096 KTest *res = 0;
00097 unsigned i, version;
00098
00099 if (!f)
00100 goto error;
00101 if (!kTest_checkHeader(f))
00102 goto error;
00103
00104 res = (KTest*) calloc(1, sizeof(*res));
00105 if (!res)
00106 goto error;
00107
00108 if (!read_uint32(f, &version))
00109 goto error;
00110
00111 if (version > kTest_getCurrentVersion())
00112 goto error;
00113
00114 res->version = version;
00115
00116 if (!read_uint32(f, &res->numArgs))
00117 goto error;
00118 res->args = (char**) calloc(res->numArgs, sizeof(*res->args));
00119 if (!res->args)
00120 goto error;
00121
00122 for (i=0; i<res->numArgs; i++)
00123 if (!read_string(f, &res->args[i]))
00124 goto error;
00125
00126 if (version >= 2) {
00127 if (!read_uint32(f, &res->symArgvs))
00128 goto error;
00129 if (!read_uint32(f, &res->symArgvLen))
00130 goto error;
00131 }
00132
00133 if (!read_uint32(f, &res->numObjects))
00134 goto error;
00135 res->objects = (KTestObject*) calloc(res->numObjects, sizeof(*res->objects));
00136 if (!res->objects)
00137 goto error;
00138 for (i=0; i<res->numObjects; i++) {
00139 KTestObject *o = &res->objects[i];
00140 if (!read_string(f, &o->name))
00141 goto error;
00142 if (!read_uint32(f, &o->numBytes))
00143 goto error;
00144 o->bytes = (unsigned char*) malloc(o->numBytes);
00145 if (fread(o->bytes, o->numBytes, 1, f)!=1)
00146 goto error;
00147 }
00148
00149 fclose(f);
00150
00151 return res;
00152 error:
00153 if (res) {
00154 if (res->args) {
00155 for (i=0; i<res->numArgs; i++)
00156 if (res->args[i])
00157 free(res->args[i]);
00158 free(res->args);
00159 }
00160 if (res->objects) {
00161 for (i=0; i<res->numObjects; i++) {
00162 KTestObject *bo = &res->objects[i];
00163 if (bo->name)
00164 free(bo->name);
00165 if (bo->bytes)
00166 free(bo->bytes);
00167 }
00168 free(res->objects);
00169 }
00170 free(res);
00171 }
00172
00173 if (f) fclose(f);
00174
00175 return 0;
00176 }
00177
00178 int kTest_toFile(KTest *bo, const char *path) {
00179 FILE *f = fopen(path, "wb");
00180 unsigned i;
00181
00182 if (!f)
00183 goto error;
00184 if (fwrite(KTEST_MAGIC, strlen(KTEST_MAGIC), 1, f)!=1)
00185 goto error;
00186 if (!write_uint32(f, KTEST_VERSION))
00187 goto error;
00188
00189 if (!write_uint32(f, bo->numArgs))
00190 goto error;
00191 for (i=0; i<bo->numArgs; i++) {
00192 if (!write_string(f, bo->args[i]))
00193 goto error;
00194 }
00195
00196 if (!write_uint32(f, bo->symArgvs))
00197 goto error;
00198 if (!write_uint32(f, bo->symArgvLen))
00199 goto error;
00200
00201 if (!write_uint32(f, bo->numObjects))
00202 goto error;
00203 for (i=0; i<bo->numObjects; i++) {
00204 KTestObject *o = &bo->objects[i];
00205 if (!write_string(f, o->name))
00206 goto error;
00207 if (!write_uint32(f, o->numBytes))
00208 goto error;
00209 if (fwrite(o->bytes, o->numBytes, 1, f)!=1)
00210 goto error;
00211 }
00212
00213 fclose(f);
00214
00215 return 1;
00216 error:
00217 if (f) fclose(f);
00218
00219 return 0;
00220 }
00221
00222 unsigned kTest_numBytes(KTest *bo) {
00223 unsigned i, res = 0;
00224 for (i=0; i<bo->numObjects; i++)
00225 res += bo->objects[i].numBytes;
00226 return res;
00227 }
00228
00229 void kTest_free(KTest *bo) {
00230 unsigned i;
00231 for (i=0; i<bo->numArgs; i++)
00232 free(bo->args[i]);
00233 free(bo->args);
00234 for (i=0; i<bo->numObjects; i++) {
00235 free(bo->objects[i].name);
00236 free(bo->objects[i].bytes);
00237 }
00238 free(bo->objects);
00239 free(bo);
00240 }