Example Source Code: hhdb_check.c


/*
  **********************************************************************
  * hhdb_check.c                                                       *
  * Copyright (C) 1997 Dept. of Mathematics, University of Houston     *
  * This is free software; you can use, copy, distribute and/or modify *
  * it freely under the disclaimer that no warranties are offered nor  *
  * liabilities assumed through such actions.                          *
  **********************************************************************
  **********************************************************************
  * Compile: > cc hhdb_check.c -o hhdb_check                           *
  * Run:     > hhdb_check [-v] filename                                *
  *   Checks that filename is for the most part a valid hhdb file.     *
  *   Be aware that the checking is not exhaustive and that this       *
  *   routine is not fully tested.                                     *
  **********************************************************************
*/

#include <stdio.h>

#define MAGIC      1212432974

#define ITM_COMM   0
#define BOS_HHDB   32
#define EOS_HHDB   33

#define BOS_UNSTR  64
#define EOS_UNSTR  65
#define BOS_STRUC  66
#define EOS_STRUC  67

#define ITM_VCINT  256
#define ITM_CCINT  257
#define ITM_VCBOU  258
#define ITM_CCBOU  259

unsigned long getuint();

main(argc,argv)
int argc;
char *argv[];
{
  char *fname = NULL;
  FILE *fp;
  long recl, tag;
  int  inHHDB  = 0,
       inUNSTR = 0,
       inSTRUC = 0;
  int  k,
       bnum = 0,
       nwarns = 0,
       verbose = 0;
  int  nread,
       ndims,nvars,bvars,
       i1,i2,j1,j2,k1,k2,
       ncell,nnode,nconn;

  if( argc < 2 ) {
    fprintf(stderr,"Usage: %s [-v] filename\n",argv[0]);
    exit(256);
  }
  for( k = 1; k < argc; k++ ) {
    if( (!verbose) && (strcmp(argv[k],"-v") == 0) )
      verbose = 1;
    else
    if( !fname )
      fname = argv[k];
    else {
      fprintf(stderr,"Usage: %s [-v] filename\n",argv[0]);
      exit(256);
    }
  }
  if( fname ) 
    fp = fopen(fname,"rb");
  else {
    fprintf(stderr,"Usage: %s [-v] filename\n",argv[0]);
    exit(256);
  }
  if( !fp ) {
    fprintf(stderr,"Could not open %s.\n",fname);
    exit(256);
  }

  recl = getuint(fp);
  if( recl&3 ) {
    fprintf(stderr,"*** Format error: Record length not a multiple of 4 bytes.\n");
    fprintf(stderr,"(Perhaps this file was created on a non big-endian machine.)\n");
    exit(256);
  }
  recl = recl>>2;
  tag = getuint(fp);
  if( tag != MAGIC ) {
    fprintf(stderr,"*** Format error: Not an hhdb file.\n");
    fprintf(stderr,"(Perhaps this file was created on a non big-endian machine.)\n");
    exit(256);
  }
  fseek(fp,(recl-1)*4,SEEK_CUR);
  tag = getuint(fp);
  if( tag != 4*recl ) {
    fprintf(stderr,"*** Format error: Incorrect fortran record.\n");
    fprintf(stderr,"(Perhaps this file was created on a non big-endian machine.)\n");
    exit(256);
  }
  bnum += recl*4+8;

  while( 1 ) {
    recl = getuint(fp);
    if( feof(fp) ) break;
    if( recl&3 ) {
      fprintf(stderr,"*** Format error: Record length not a multiple of 4 bytes.\n");
      exit(256);
    }
    recl = recl>>2;
    tag = getuint(fp);
    nread = 1;

    switch( tag ) {

    case ITM_COMM:
      if( verbose ) {
        fflush(stderr);
        printf("ITM_COMM\n");
        fflush(stdout);
      }
      break;

    case BOS_HHDB:
      if( verbose ) {
        fflush(stderr);
        printf("BOS_HHDB\n");
        fflush(stdout);
      }
      if( inHHDB ) {
        fprintf(stderr,"*** Format error: Incorrectly nested BOS_HHDB.\n");
        fprintf(stderr,"    Record starting at byte: %d\n",bnum);
        exit(256);
      }
      inHHDB = 1;
      nread += 5;
              getuint(fp);
              getuint(fp);
      ndims = getuint(fp);
      nvars = getuint(fp);
      bvars = getuint(fp);
      break;

    case EOS_HHDB:
      if( verbose ) {
        fflush(stderr);
        printf("EOS_HHDB\n");
        fflush(stdout);
      }
      if( !inHHDB ) {
        fprintf(stderr,"*** Format error: Incorrectly nested EOS_HHDB.\n");
        fprintf(stderr,"    Record starting at byte: %d\n",bnum);
        exit(256);
      }
      inHHDB = 0;
      break;

    case BOS_UNSTR:
      if( verbose ) {
        fflush(stderr);
        printf("    BOS_UNSTR\n");
        fflush(stdout);
      }
      if( inUNSTR || inSTRUC ) {
        fprintf(stderr,"*** Format error: Incorrectly nested BOS_UNSTR.\n");
        fprintf(stderr,"    Record starting at byte: %d\n",bnum);
        exit(256);
      }
      inUNSTR = 1;
      break;

    case EOS_UNSTR:
      if( verbose ) {
        fflush(stderr);
        printf("    EOS_UNSTR\n");
        fflush(stdout);
      }
      if( !inUNSTR ) {
        fprintf(stderr,"*** Format error: Incorrectly nested EOS_UNSTR.\n");
        fprintf(stderr,"    Record starting at byte: %d\n",bnum);
        exit(256);
      }
      inUNSTR = 0;
      break;

    case BOS_STRUC:
      if( verbose ) {
        fflush(stderr);
        printf("    BOS_STRUCR\n");
        fflush(stdout);
      }
      if( inUNSTR || inSTRUC ) {
        fprintf(stderr,"*** Format error: Incorrectly nested BOS_STRUC.\n");
        fprintf(stderr,"    Record starting at byte: %d\n",bnum);
        exit(256);
      }
      inSTRUC = 1;
      break;

    case EOS_STRUC:
      if( verbose ) {
        fflush(stderr);
        printf("    EOS_STRUC\n");
        fflush(stdout);
      }
      if( !inSTRUC ) {
        fprintf(stderr,"*** Format error: Incorrectly nested EOS_STRUC.\n");
        fprintf(stderr,"    Record starting at byte: %d\n",bnum);
        exit(256);
      }
      inSTRUC = 0;
      break;

    case ITM_VCINT:
      if( verbose ) {
        fflush(stderr);
        printf("        ITM_VCINT\n");
        fflush(stdout);
      }
      if( inSTRUC ) {
        int len;
        nread += 3;
        i1 = getuint(fp);
        j1 = getuint(fp);
        k1 = getuint(fp);
        len = i1*j1*k1;
        if( recl != 4+(i1*j1*k1)*ndims+len*nvars ) {
          nwarns++;
          printf("*** Warning: Record length of ITM_VCINT does not agree with data.\n");
          printf("    (#dims %d) (#vars %d) (%d x %d x %d)\n",
                       ndims,     nvars,     i1,  j1,  k1);
          printf("    should have %d words of data. It has %d however.\n",
                          (i1*j1*k1)*ndims+len*nvars,      recl-4);
          printf("    (See record starting at byte %d.)\n\n",bnum);
        }
      }
      else
      if( inUNSTR ) {
        nread += 3;
        nnode = getuint(fp);
        ncell = getuint(fp);
        nconn = getuint(fp);
        if( recl != 4+nnode*ndims+nnode*nvars+nconn ) {
          nwarns++;
          printf("*** Warning: Record length of ITM_VCINT does not agree with data.\n");
          printf("    (#dims %d) (#vars %d) (#node %d) (#cell %d) (#conn %d)\n",
                       ndims,     nvars,     nnode,     ncell,     nconn);
          printf("    should have %d words of data. It has %d however.\n",
                            nnode*ndims+nnode*nvars+nconn, recl-4);
          printf("    (See record starting at byte %d.)\n\n",bnum);
        }
      }
      else {
        fprintf(stderr,"*** Format error: Incorrectly nested ITM_VCINT.\n");
        fprintf(stderr,"    Record starting at byte: %d\n",bnum);
        exit(256);
      }
      break;

    case ITM_CCINT:
      if( verbose ) {
        fflush(stderr);
        printf("        ITM_CCINT\n");
        fflush(stdout);
      }
      if( inSTRUC ) {
        int len;
        nread += 3;
        i1 = getuint(fp);
        j1 = getuint(fp);
        k1 = getuint(fp);
        len = 1;
        if( i1 > 1 ) len *= (i1-1);
        if( j1 > 1 ) len *= (j1-1);
        if( k1 > 1 ) len *= (k1-1);
        if( recl != 4+(i1*j1*k1)*ndims+len*nvars ) {
          nwarns++;
          printf("*** Warning: Record length of ITM_CCINT does not agree with data.\n");
          printf("    (#dims %d) (#vars %d) (%d x %d x %d)\n",
                       ndims,     nvars,     i1,  j1,  k1);
          printf("    should have %d words of data. It has %d however.\n",
                          (i1*j1*k1)*ndims+len*nvars,      recl-4);
          printf("    (See record starting at byte %d.)\n\n",bnum);
        }
      }
      else
      if( inUNSTR ) {
        nread += 3;
        nnode = getuint(fp);
        ncell = getuint(fp);
        nconn = getuint(fp);
        if( recl != 4+nnode*ndims+ncell*nvars+nconn ) {
          nwarns++;
          printf("*** Warning: Record length of ITM_CCINT does not agree with data.\n");
          printf("    (#dims %d) (#vars %d) (#node %d) (#cell %d) (#conn %d)\n",
                       ndims,     nvars,     nnode,     ncell,     nconn);
          printf("    should have %d words of data. It has %d however.\n",
                            nnode*ndims+ncell*nvars+nconn, recl-4);
          printf("    (See record starting at byte %d.)\n\n",bnum);
        }
      }
      else {
        fprintf(stderr,"*** Format error: Incorrectly nested ITM_CCINT.\n");
        fprintf(stderr,"    Record starting at byte: %d\n",bnum);
        exit(256);
      }
      break;

    case ITM_VCBOU:
      if( verbose ) {
        fflush(stderr);
        printf("        ITM_VCBOU\n");
        fflush(stdout);
      }
      if( inSTRUC ) {
        int len;
        nread += 7;
             getuint(fp);
        i1 = getuint(fp);
        i2 = getuint(fp);
        j1 = getuint(fp);
        j2 = getuint(fp);
        k1 = getuint(fp);
        k2 = getuint(fp);
        len = (i2-i1+1)*(j2-j1+1)*(k2-k1+1);
        if( recl != 8+len*bvars ) {
          nwarns++;
          printf("*** Warning: Record length of ITM_VCBOU does not agree with data.\n");
          printf("    (#vars %d) (%d-%d) (%d-%d) (%d-%d)\n",
                      bvars,     i1,i2,  j1,j2,  k1,k2);
          printf("    should have %d words of data. It has %d however.\n",
                                  len*bvars,               recl-8);
          printf("    (See record starting at byte %d.)\n\n",bnum);
        }
      }
      else
      if( inUNSTR ) {
        nread += 4;
                getuint(fp);
        nnode = getuint(fp);
        ncell = getuint(fp);
        nconn = getuint(fp);
        if( recl != 5+nnode+nnode*bvars+nconn ) {
          nwarns++;
          printf("*** Warning: Record length of ITM_VCBOU does not agree with data.\n");
          printf("    (#dims %d) (#vars %d) (#node %d) (#cell %d) (#conn %d)\n",
                       ndims,     bvars,     nnode,     ncell,     nconn);
          printf("    should have %d words of data. It has %d however.\n",
                                  nnode+nnode*bvars+nconn, recl-5);
          printf("    (See record starting at byte %d.)\n\n",bnum);
        }
      }
      else {
        fprintf(stderr,"*** Format error: Incorrectly nested ITM_VCBOU.\n");
        fprintf(stderr,"    Record starting at byte: %d\n",bnum);
        exit(256);
      }
      break;

    case ITM_CCBOU:
      if( verbose ) {
        fflush(stderr);
        printf("        ITM_CCBOU\n");
        fflush(stdout);
      }
      if( inSTRUC ) {
        int len;
        nread += 7;
             getuint(fp);
        i1 = getuint(fp);
        i2 = getuint(fp);
        j1 = getuint(fp);
        j2 = getuint(fp);
        k1 = getuint(fp);
        k2 = getuint(fp);
        len = 1;
        if( i2 > i1 ) len *= (i2-i1);
        if( j2 > j1 ) len *= (j2-j1);
        if( k2 > k1 ) len *= (k2-k1);
        if( recl != 8+len*bvars ) {
          nwarns++;
          printf("*** Warning: Record length of ITM_CCBOU does not agree with data.\n");
          printf("    (#vars %d) (%d-%d) (%d-%d) (%d-%d)\n",
                      bvars,     i1,i2,  j1,j2,  k1,k2);
          printf("    should have %d words of data. It has %d however.\n",
                                  len*bvars,               recl-8);
          printf("    (See record starting at byte %d.)\n\n",bnum);
        }
      }
      else
      if( inUNSTR ) {
        nread += 4;
                getuint(fp);
        nnode = getuint(fp);
        ncell = getuint(fp);
        nconn = getuint(fp);
        if( recl != 5+nnode+ncell*bvars+nconn ) {
          nwarns++;
          printf("*** Warning: Record length of ITM_CCBOU does not agree with data.\n");
          printf("    (#dims %d) (#vars %d) (#node %d) (#cell %d) (#conn %d)\n",
                       ndims,     bvars,     nnode,     ncell,     nconn);
          printf("    should have %d words of data. It has %d however.\n",
                                  nnode+ncell*bvars+nconn, recl-5);
          printf("    (See record starting at byte %d.)\n\n",bnum);
        }
      }
      else {
        fprintf(stderr,"*** Format error: Incorrectly nested ITM_CCBOU.\n");
        fprintf(stderr,"    Record starting at byte: %d\n",bnum);
        exit(256);
      }
      break;      

    default:
      fprintf(stderr,"*** Format error: Undefined record tag.\n",fname);
      fprintf(stderr,"    Record starting at byte: %d\n",bnum);
      fprintf(stderr,"    (Found tag: %d ???)\n",tag);
      exit(256);
    }

    if( nwarns > 255 ) break;
    fseek(fp,(recl+1-nread)*4,SEEK_CUR);
    bnum += recl*4+8;
  }

  fflush(stderr);
  if( !nwarns )
    printf("%s seems OK.\n",fname);
  else
    printf("Found %d warning(s) in %s.\n",nwarns,fname);
  printf("File size (in bytes): %d\n",bnum);

  fclose(fp);
  exit(nwarns);
}


unsigned long getuint(fp)
FILE *fp;
{
  unsigned char cint[4];
  unsigned long uint;
  if( fread(cint,1,4,fp) != 4 )
    uint = ~0;
  else
    uint = 256*(256*(256*cint[0]+cint[1])+cint[2])+cint[3];
  return( uint );
}



Last modified: Mon Sep 14 11:20:38 MET DST 1998