KTest.cpp

Go to the documentation of this file.
00001 //===-- KTest.cpp ---------------------------------------------------------===//
00002 //
00003 //                     The KLEE Symbolic Virtual Machine
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
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 // for compatibility reasons
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 }

Generated on Fri Jun 5 03:31:31 2009 for klee by  doxygen 1.5.8