Category : Dbase (Clipper, FoxBase, etc) Languages Source Code
Archive   : CMPDBFS2.ZIP
Filename : CMPDBFS2.C

 
Output of file : CMPDBFS2.C contained in archive : CMPDBFS2.ZIP

/* CMPDBFS Version 2 */

/************************************************************************
Revision 2.0 by P. L. Olympia, for dBASE IV and FoxPro on 10/25/90
Also changed the output somewhat to remove redundancy and make
the display more appealing
*************************************************************************/

/* First written 7/03/90 */
/* Last revision 8/10/90 */
/* T. D. Coyle
GPR Systems
11400 Game Preserve Road
Gaithersburg, MS 20878
(301)-948-9510 */
/* Program to compare two dBASEIII DBFs */
/* Accepts two filenames from command line. If files are authentic dBASEIII
DBF, the file header info and the structures are displayed. This version
creates two arrays of structures that contain the specifications for
the DBF fields, and arrays of pointers to the elements of each structure
array.
The pointers are sorted and the file structures are printed out
in alphabetical order of field name. with matching field names on the
same line. If the two files have fields with identical names but
different type, width, or decimals, a MISMATCH is indicated.
A final summary is printed.
Output can be redirected to printer or file from the command line. */


#include

#define DB2 0x02 /* This version does not recognize DB2 files */
#define DB3 0x03
#define DB3DBT 0x83
/* Add dB4 & FoxPro */
#define DB4DBT 0x8B /* p.o. */
#define FOXFPT 0xF5 /* p.o. */

#define PERIOD '.'
#define NORMEXT ".DBF"
#define MAXFLDS 128

typedef struct
{
unsigned char version; /* 03 if no memo, 83 otherwise */
char yy; /* date of */
char mm; /* last */
char dd; /* update */
long num_rec; /* number of db3+ records */
int len_hdr; /* length of header record */
int len_rec; /* length of data base record */
char dummy[20];
} DB3_HDR;

typedef struct
{
char name[11];
char type;
char data_addr[4]; /* field data address */
unsigned char length;
char decimal;
char other[14];
} DB3_FLD;


void fullname(char *str,char *arg);
void space(int numspc);
void printfld(DB3_FLD *ptrlist);
void fldhdr();
DB3_HDR gethdr(FILE *dbf,int *isdb,char *str,int *num_flds);
DB3_FLD getfld(FILE *dbf);

main(int argc,char *argv[])
{
DB3_HDR hdr1,hdr2; /* structures with file header info */
DB3_FLD fld1,fld2;
DB3_FLD file1[MAXFLDS],file2[MAXFLDS];
DB3_FLD *ptrlist1[MAXFLDS],*ptrlist2[MAXFLDS];
DB3_FLD *temp;
FILE *dbf1,*dbf2;
int i,j;
int canopen=1;
int isdbf=1;
char ipstr1[80],ipstr2[80]; /* strings holding file names */
int num_flds1,num_flds2;
int in,out;
int match;
int mismatches=0;
int notin1=0;
int notin2=0;
int samestru=1;

/* Check for required syntax and display message if incorrect */

if(argc<3)
{
printf("\nCMPDBFS v1.0 by T. D. Coyle");
printf("\nv2.0 by P. L. Olympia to recognize FoxPro & dBASE IV\n");

printf("\nCMPDBFS v2.0 compares structures of two Dbase data files");
printf("\nTo run, type CMPDBFS filename1 filename2");
printf("\nTo send to printer, type CMPDFS filename1 filename2 >PRN");
printf("\nTo keep output on screen, type CMPDBFS filename1 filename2 |MORE");
printf("\n");
exit(1);
}

/* The files to be compared have been named on the command line */
/* Put them into ipstr variables. If no extension provided,
add '.DBF' */

fullname(ipstr1,argv[1]);
fullname(ipstr2,argv[2]);

/* open the files for read */

if( (dbf1=fopen(ipstr1,"rb"))==NULL)
{
printf("\nSorry, can't read file %s",ipstr1);
canopen=0;
}
if( (dbf2=fopen(ipstr2,"rb"))==NULL)
{
printf("\nSorry, can't read file %s",ipstr2);
canopen=0;
}

if(!canopen) exit(1);

/* read the DBF file headers */

hdr1=gethdr(dbf1,&isdbf,ipstr1,&num_flds1);
hdr2=gethdr(dbf2,&isdbf,ipstr2,&num_flds2);


/* test whether dBASE DBF's and exit if not */

if(!isdbf)
exit(1);


/* output file header information to screen */
/*******************************************
This section lobotomized by p.o.
********************************************/
printf("\nCOMPARING DBF STRUCTURES WITH CMPDBFS Version 2.0");
printf("\nFile 1: %s",ipstr1);
space(30-strlen(ipstr1));
printf("File 2: %s",ipstr2);
printf("\nDate of last update: %2d/%2d/%2d",hdr1.mm,hdr1.dd,hdr1.yy);
space(6);
printf("%2d/%2d/%2d",hdr2.mm,hdr2.dd,hdr2.yy);
printf("\nNumber of data records: %-5ld",hdr1.num_rec);
space(9);
printf("%-5ld",hdr2.num_rec);
printf("\nNumber of fields: %-3d",num_flds1);
space(11);
printf("%-3d",num_flds2);
printf("\nRecord Length: %-4d",hdr1.len_rec);
space(10);
printf("%-4d",hdr2.len_rec);
printf("\n");


/* read the structures, one field at a time, and write to arrays */

for(i=0;i {
fld1=getfld(dbf1);
file1[i]=fld1;
ptrlist1[i]=&file1[i];
}
for(i=0;i {
fld2=getfld(dbf2);
file2[i]=fld2;
ptrlist2[i]=&file2[i];
}

/* sort the arrays */

for (out=0;out {
for(in=out+1;in {
if(strcmp(ptrlist1[out]->name,ptrlist1[in]->name)>0)
{
temp=ptrlist1[in];
ptrlist1[in]=ptrlist1[out];
ptrlist1[out]=temp;
}
}
}
for (out=0;out {
for(in=out+1;in {
if(strcmp(ptrlist2[out]->name,ptrlist2[in]->name)>0)
{
temp=ptrlist2[in];
ptrlist2[in]=ptrlist2[out];
ptrlist2[out]=temp;
}
}
}

/* display the sorted arrays */

fldhdr();
i=0;j=0;
while((i {
if(strcmp(ptrlist1[i]->name,ptrlist2[j]->name)==0)
{
printf("\n");
printfld(ptrlist1[i]);
space(7);
printfld(ptrlist2[j]);
if((ptrlist1[i]->type == ptrlist2[j]->type) &&
(ptrlist1[i]->length == ptrlist2[j]->length) &&
(ptrlist1[i]->decimal == ptrlist2[j]->decimal))
match=1;
else
match=0;
if(! match)
{
printf(" MISMATCH");
mismatches=1+mismatches;
}
i++;j++;
continue;
}
if(strcmp(ptrlist1[i]->name,ptrlist2[j]->name)<0)
{
printf("\n");
printfld(ptrlist1[i]);
notin2=1+notin2;
i++;
continue;
}
if(strcmp(ptrlist1[i]->name,ptrlist2[j]->name)>0)
{
printf("\n");
space(38);
printfld(ptrlist2[j]);
notin1=1+notin1;
j++;
continue;
}
}
if (j==num_flds2)
for(i=i;i {
printf("\n");
printfld(ptrlist1[i]);
notin2=1+notin2;
}
if (i==num_flds1)
for(j=j;j {
printf("\n");
space(38);
printfld(ptrlist2[j]);
notin1=1+notin1;
}


/* summarize */
/* p.o. strikes again here
printf("\n\nSummary of Comparison of dBASEIII data base files:");
printf("\n\nFile 1: %s",ipstr1);
printf("\nNumber of data records: %-5ld",hdr1.num_rec);
printf("\nDate of last update: %2d/%2d/%2d",hdr1.mm,hdr1.dd,hdr1.yy);
printf("\nNumber of fields: %-3d",num_flds1);
printf("\nRecord length: %-4d",hdr1.len_rec);
*/
if(notin2>0)
{
printf("\n%s contains %d field(s) not in %s",ipstr1,notin2,ipstr2); /* p.o. */
samestru=0;
}
/*
printf("\n\nFile 2: %s",ipstr2);
printf("\nNumber of data records: %-5ld",hdr2.num_rec);
printf("\nDate of last update: %2d/%2d/%2d",hdr2.mm,hdr2.dd,hdr2.yy);
printf("\nNumber of fields: %-3d",num_flds2);
printf("\nRecord length: %-4d",hdr2.len_rec);
*/
if(notin1>0)
{
printf("\n%s contains %d field(s) not in %s",ipstr2,notin1,ipstr1); /* p.o. */
samestru=0;
}


if(num_flds1!=num_flds2)
samestru=0;
if(mismatches>0)
{
samestru=0;
printf("\n\nFiles have %d field(s) with same name but different structures",
mismatches);
}
if(samestru)
printf("\n\nFILE STRUCTURES ARE IDENTICAL");
else
printf("\n\nFILE STRUCTURES ARE DIFFERENT");

printf("\n");

/* close the files */
fclose(dbf1);
fclose(dbf2);
}


void fullname(char *str,char *arg)
{
strcpy(str,arg);
if(!strchr(str,PERIOD))
strcat(str,NORMEXT);
}

DB3_HDR gethdr(FILE *dbf,int *isdb,char *str,int *num_flds)
{
DB3_HDR hdr;
fread(&hdr,sizeof(DB3_HDR),1,dbf);
if(!( (hdr.version==DB3) || (hdr.version==DB3DBT)
|| (hdr.version==DB4DBT) || (hdr.version==FOXFPT) )) /* p.o. */
{
printf("\nFile %s is not a dBASE-type data base",str); /* p.o. */
*isdb=0;
}
else

*num_flds=(hdr.len_hdr-1)/32-1;
return(hdr);
}

void space(int numspc)
{
int i;
for(i=1;i printf(" ");
}

DB3_FLD getfld(FILE *dbf)
{
DB3_FLD fld;
fread(&fld,sizeof(DB3_FLD),1,dbf);
return(fld);
}

void printfld(DB3_FLD *ptrlist)
{
printf("%-10s ",ptrlist->name);
switch(ptrlist->type)
{
case 'C': printf(" Character ");break;
case 'D': printf(" Date ");break;
case 'N': printf(" Numeric ");break;
case 'L': printf(" Logical ");break;
case 'M': printf(" Memo ");break;
case 'F': printf(" Float ");break; /* p.o. */
default : printf(" Unknown ");break;
}
printf("%5d",ptrlist->length);
if (ptrlist->type=='N')
printf("%4d",ptrlist->decimal);
else
printf(" ");

}

void fldhdr()
{
printf("\nFILE STRUCTURES: (Field names in alphabetical order)");

/* more damage by p.o.
printf("\nMISMATCH means files have fields with same names but ");
printf("\n different type, width, or decimal places");
*/
printf("\nField Name Type Width Dec");
space(7);
printf("Field Name Type Width Dec\n");

}