Index: trunk/Ohana/src/tools/src/roc.c
===================================================================
--- trunk/Ohana/src/tools/src/roc.c	(revision 30606)
+++ trunk/Ohana/src/tools/src/roc.c	(revision 30607)
@@ -4,6 +4,5 @@
 # include <regex.h>
 
-// # define myAssert(LOGIC,MSG) { if (!(LOGIC)) { fprintf (stderr, "%s\n", MSG); abort(); } }
-# define myAssert(LOGIC,MSG) { if (!(LOGIC)) { fprintf (stderr, "%s\n", MSG); exit(1); } }
+# define myAssert(LOGIC,...) { if (!(LOGIC)) { fprintf (stderr, __VA_ARGS__); abort(); } }
 
 # define ROC_HEADER_SIZE  0x1000
@@ -15,4 +14,6 @@
 int roc_insert (int argc, char **argv);
 int roc_delete (int argc, char **argv);
+int roc_validate (int argc, char **argv);
+
 int usage (void);
 int print_block (char *header, int *header_size, int *Noff, char *format,...);
@@ -29,4 +30,5 @@
   if (!strcasecmp(argv[1], "-insert")) roc_insert (argc, argv);
   if (!strcasecmp(argv[1], "-delete")) roc_delete (argc, argv);
+  if (!strcasecmp(argv[1], "-validate")) roc_validate (argc, argv);
 
   usage();
@@ -302,4 +304,111 @@
 }
 
+int roc_validate (int argc, char **argv) {
+
+  int i, j, n, Ninput, Nblocks, header_size, Nbytes, Nread;
+  off_t *sizes, *bytes_read;
+  char value;
+  char *header, *line, *ptr;
+  char **inputName, *targetName;
+  char **inputData;
+  char *targetData;
+  FILE **input, *target;
+
+  if (argc != 3) usage();
+
+
+  /* find the md5 sum for each input file (ADD LATER)
+   * find the size of the input files
+   * define the output file size = MAX(sizes)
+   * create the target file header
+   */
+
+  // the output file
+  targetName = argv[2];
+
+  target = fopen(targetName, "r");
+  myAssert (target, "failed to open roc datafile %s\n",targetName);
+  
+  ALLOCATE (line, char, 1024);
+
+  scan_line (target, line);
+  myAssert (!strncmp(line, "ROC Version 0", strlen("ROC Verion 0")), "invalid ROC file or format in %s",targetName);
+
+  scan_line (target, line);
+  sscanf (line, "HEADER SIZE %x", &header_size);
+
+  ALLOCATE (header, char, header_size);
+
+  // read the full header
+  fseeko (target, 0, SEEK_SET);
+  Nbytes = fread (header, 1, header_size, target);
+  myAssert (Nbytes == header_size, "failed to read header data\n");
+
+  ptr = header;
+  ptr = strchr (ptr, '\n'); ptr ++; // ROC Version
+  ptr = strchr (ptr, '\n'); ptr ++; // HEADER SIZE
+  
+  sscanf (ptr, "N_FILES %d", &Ninput); ptr = strchr (ptr, '\n'); ptr ++; 
+  sscanf (ptr, "N_BLOCKS %d", &Nblocks); ptr = strchr (ptr, '\n'); ptr ++; 
+
+  // the input files
+  ALLOCATE (inputName, char *, Ninput);
+  ALLOCATE (sizes, off_t, Ninput);
+  ALLOCATE (bytes_read, off_t, Ninput);
+  for (i = 0; i < Ninput; i++) {
+    ALLOCATE (inputName[i], char, 1024);
+    sscanf (ptr, "%*s : %s", inputName[i]); ptr = strchr (ptr, '\n'); ptr ++; 
+    ptr = strchr (ptr, '\n'); ptr ++; // BASE
+    sscanf (ptr, "%*s : "OFF_T_FMT, &sizes[i]); ptr = strchr (ptr, '\n'); ptr ++; 
+    ptr = strchr (ptr, '\n'); ptr ++; // MD5
+    bytes_read[i] = 0;
+  }
+
+  ALLOCATE (input, FILE *, Ninput);
+  for (i = 0; i < Ninput; i++) {
+    input[i] = fopen(inputName[i], "r");
+    myAssert (input[i], "failed to open file %s in %s\n",inputName[i],targetName);
+  }
+
+  ALLOCATE (inputData, char *, Ninput);
+  ALLOCATE (targetData, char, ROC_BLOCKSIZE);
+  for (i = 0; i < Ninput; i++) {
+    ALLOCATE (inputData[i], char, ROC_BLOCKSIZE);
+  }
+
+  for (n = 0; n < Nblocks; n++) {
+    for (i = 0; i < Ninput; i++) {
+      Nread = MIN (ROC_BLOCKSIZE, sizes[i] - bytes_read[i]);
+      Nbytes = fread (inputData[i], 1, Nread, input[i]);
+      myAssert (Nbytes == Nread, "failed to read data file: %s read: %d expect: %d prev_read: %d block: %d in %s\n",inputName[i],Nbytes,Nread,(int) bytes_read[i],n,targetName);
+      if (Nread < ROC_BLOCKSIZE) {
+	// if we have reached the end of the file, fill in the rest with NULLs
+	memset (&inputData[i][Nread], 0, ROC_BLOCKSIZE - Nread);
+      }
+      bytes_read[i] += Nread;
+    }
+    Nbytes = fread (targetData, 1, ROC_BLOCKSIZE, target);
+    myAssert (Nbytes == ROC_BLOCKSIZE, "failed to read roc file: %s read: %d expect %d\n", targetName, Nbytes, ROC_BLOCKSIZE);
+    
+    for (j = 0; j < ROC_BLOCKSIZE; j++) {
+      value = targetData[j];
+      for (i = 0; i < Ninput; i++) {
+	value = value ^ inputData[i][j];
+      }
+      myAssert(value == 0, "validation failed on block %d and byte %d in %s\n",n,j,targetName);
+    }
+
+  }
+
+  for (i = 0; i < Ninput; i++) {
+    fclose(input[i]);
+  }
+
+  fclose (target);
+
+  fprintf (stderr, "validation: %s appears correct.\n",targetName);
+  exit (0);
+}
+
 int roc_insert (int argc, char **argv) {
 
@@ -334,6 +443,8 @@
   fprintf (stderr, " -create (target) (input) (input) (input) ... [options]\n");
   fprintf (stderr, " -repair (target) (file #) (output\n");
+  fprintf (stderr, " -validate (target)\n");
   fprintf (stderr, " -insert (target) (input)\n");
   fprintf (stderr, " -delete (target) (file)\n");
+
   exit (2);
 }
