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