home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
disk
/
misc
/
dcmp
/
source
/
source.lha
/
fcmp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-01
|
9KB
|
325 lines
/*--------------------------------------------------------------------------*
______
/ ____/ $RCSfile: fcmp.c,v $
/ /_ ______ _ _ ______ $Release$
/ __// ____// \_/ \ / __ / $Revision: 1.6 $
/ / / /___ / /__/ // /_/ / $Date: 92/12/04 07:10:12 $
/_/ /_____//_/ /_// ____/ $Author: tf $
/ / $State: Exp $
Revision 1.6 /_/
(c) Copyright 1989-92 Tobias Ferber, All Rights Reserved.
*--------------------------------------------------------------------------*/
#include <exec/types.h>
#include <stdio.h>
#include <stdarg.h>
extern long hextol(char *); /* instead of xtoy.h */
static char rcs_id[]= "$Id: fcmp.c,v 1.6 92/12/04 07:10:12 tf Exp $";
char *whoami;
BOOL silent=FALSE, /* don't produce any output but the result */
brkdiff=FALSE; /* break on the first non-equivalence */
FILE *fp0, *fp1;
void perror(const char *fmt, ...)
{
va_list argp;
va_start(argp,fmt); /* name the last known argument */
fprintf(stderr,"\r%s: ",whoami);
vfprintf(stderr,fmt,argp);
fprintf(stderr,"\n");
fflush(stderr);
va_end(argp); /* just to be sure... */
}
void closeall(void)
{ if(fp0) fclose(fp0);
if(fp1) fclose(fp1);
}
void _abort(void)
{ printf("\33[31m^C\n\n** BREAK\n");
closeall();
exit(5);
}
int openall(char *fname0,char *fname1,int rpos)
{
if(!(fp0=fopen(fname0,"rb")))
{ perror("Can't open %s for input - object not found",fname0);
return(0);
}
if(!(fp1=fopen(fname1,"rb")))
{ perror("Can't open %s for input - object not found",fname1);
fclose(fp0);
return(0);
}
if(rpos>0)
{ if(fseek(fp0,rpos,0L)<0||fseek(fp1,rpos,1L)<0)
{ closeall();
return(0);
}
}
return(1);
}
#define DUMP(x) ((32<=(x)&&(x)<127)||(x)>161)?(x):('.')
#define COLOR(x) (x)?("\33[31m"):("\33[33m")
/* single file hex dump */
long hexdump(char *fname0, char* fname1, long rpos)
{
unsigned long bc=rpos, /* byte counter */
dc=0; /* difference counter */
BOOL abort=FALSE;
while(!abort)
{ unsigned long i,j,k; /* general counters */
unsigned char c0[16],c1[16]; /* char buffer */
BOOL d[16]; /* difference indicator */
for(j=0,k=0;(j<16&!abort);j++,bc++)
{ c0[j]=fgetc(fp0);
c1[j]=fgetc(fp1);
abort=(feof(fp0)||feof(fp1));
if(!(d[j]=(c0[j]==c1[j]))) k++;
}
dc+=k;
if(j>0 && (!silent || (silent && k>0)))
{ printf("%08lx: ",bc-j);
for(i=0;i<16;i++)
{ if(i<j) printf("%s%02x%s",COLOR(d[i]),c0[i],(((i+1)%4)==0)?(" "):(""));
else printf(" %s",(((i+1)%4)==0)?(" "):(""));
}
printf(" ");
for(i=0;i<j;i++) printf("%s%c",COLOR(d[i]),DUMP(c0[i]));
printf("\33[31m\n");
}
if(brkdiff && dc>0) abort=TRUE;
}
if(brkdiff && dc>0)
perror("terminated; files %s and %s differ.",fname0,fname1);
else
{ if(!(feof(fp0)&&feof(fp1)))
printf("Unexpected EOF \"%s\" at seek offset %d; ",feof(fp0)?fname0:fname1,bc);
else printf("Equal length: %ld bytes, ",bc);
printf("%d %s.\n",dc,(dc==1)?"difference":"differences");
}
return(dc);
}
/* hex dump of both files */
long dumpdiff(char *fname0, char* fname1, long rpos)
{
unsigned long bc=rpos, /* byte counter */
dc=0; /* difference counter */
BOOL abort=FALSE;
while(!abort)
{ unsigned long i,j,k; /* general counters */
unsigned char c0[8],c1[8]; /* char buffer */
BOOL d[8]; /* difference indicator */
for(j=0,k=0;(j<8&!abort);j++,bc++)
{ c0[j]=fgetc(fp0);
c1[j]=fgetc(fp1);
abort=(feof(fp0)||feof(fp1));
if(!(d[j]=(c0[j]==c1[j]))) k++;
}
dc+=k;
if(j>0 && (!silent || (silent && k>0)))
{ printf("%08lx: ",bc-j);
for(i=0;i<8;i++)
{ if(i<j) printf("%s%02x%s",COLOR(d[i]),c0[i],(i==3)?(" "):(""));
else printf(" %s",((i==3)?(" "):("")));
}
printf(" ");
for(i=0;i<8;i++) printf("%s%c",COLOR(d[i]),((i<j)?(DUMP(c0[i])):(' ')));
printf("\33[31m | ");
for(i=0;i<8;i++)
{ if(i<j) printf("%s%02x%s",COLOR(d[i]),c1[i],(i==3)?(" "):(""));
else printf(" %s",((i==3)?(" "):("")));
}
printf(" ");
for(i=0;i<j;i++) printf("%s%c",COLOR(d[i]),DUMP(c1[i]));
printf("\33[31m\n");
}
if(brkdiff && dc>0) abort=TRUE;
}
if(brkdiff && dc>0)
perror("terminated; files %s and %s differ.",fname0,fname1);
else
{ if(!(feof(fp0)&&feof(fp1)))
printf("Unexpected EOF \"%s\" at seek offset %d; ",feof(fp0)?fname0:fname1,bc);
else printf("Equal length: %ld bytes, ",bc);
printf("%d %s.\n",dc,(dc==1)?"difference":"differences");
}
return(dc);
}
/* single byte dump */
long sdbdump(char *fname0, char *fname1, long rpos)
{ unsigned char c0,c1;
unsigned long bc=rpos, /* byte counter */
dc=0; /* difference counter */
BOOL abort=FALSE;
do
{ c0=fgetc(fp0);
c1=fgetc(fp1);
if(!(feof(fp0)||feof(fp1)))
{ bc++;
if(c0!=c1)
{ dc++;
if(!silent)
printf("%08lx: #%03d ($%02x) \"%c\" != #%03d ($%02x) \"%c\"\n",
bc,c0,c0,DUMP(c0),c1,c1,DUMP(c1));
else printf("%08lx\n",bc);
if(brkdiff) abort=TRUE;
}
}
} while(!(feof(fp0)||feof(fp1)||abort));
if(brkdiff && dc>0)
perror("terminated; files %s and %s differ.",fname0,fname1);
else
{ if(!(feof(fp0)&&feof(fp1)))
printf("Unexpected EOF \"%s\" at seek offset %d; ",feof(fp0)?fname0:fname1,bc);
else printf("Equal length: %ld bytes, ",bc);
printf("%d %s.\n",dc,(dc==1)?"difference":"differences");
}
return(dc);
}
/* simple compare */
long compare(char *fname0, char *fname1, long rpos)
{ unsigned char c0,c1;
unsigned long bc=rpos, /* byte counter */
dc=0; /* difference counter */
BOOL abort=FALSE;
do
{ c0=fgetc(fp0);
c1=fgetc(fp1);
if(!(feof(fp0)||feof(fp1)))
{ bc++;
if(c0!=c1)
{ dc++;
if(brkdiff) abort=TRUE;
}
}
} while(!(feof(fp0)||feof(fp1)||abort));
if(!silent)
{ if(abort)
perror("terminated; files %s and %s differ.",fname0,fname1);
else
{ if(!(feof(fp0)&&feof(fp1)))
printf("Unexpected EOF \"%s\" at seek offset %d; ",feof(fp0)?fname0:fname1,bc);
else printf("Equal length: %ld bytes, ",bc);
printf("%d %s.\n",dc,(dc==1)?"difference":"differences");
}
}
return(dc);
}
main(int argc,char *argv[])
{
long (*action)()= compare;
char *fname[2]; /* file names */
long f=0, /* filename nº */
skip=0, /* #of bytes to skip */
rc=0; /* return code */
onbreak(_abort);
whoami= argv[0];
if(argc>1)
{ --argc;
++argv;
while(argc>0 && rc==0)
{ char *arg=argv[0];
if(*arg=='-')
{ arg++;
switch(*arg)
{ case 'd': case 'D': /* dump */
switch(*++arg)
{ case '0': action=sdbdump; /* single byte dump */
break;
case '1': action=hexdump; /* hex dump */
break;
case '2': action=dumpdiff; /* dump diff */
break;
default: perror("Bad dump option '-d%c'.",*arg);
rc=5;
break;
}
break;
case 'b': case 'B': /* break on diff */
brkdiff=TRUE;
break;
case 'q': case 'Q': /* quiet (brief) */
silent=TRUE;
break;
case 's': case 'S': /* seek offset */
if(arg[1]) ++arg;
else
{ ++argv;
--argc;
arg=argv[0];
}
if(arg[0]=='$')
skip= hextol(&arg[1]);
else if(arg[0]=='0' && (arg[1]=='x'||arg[1]=='X'))
skip= hextol(&arg[2]);
else skip= atol(arg);
if(skip<0)
{ perror("Error: Negative begin-offset; can't skip %d bytes",skip);
rc=5;
}
break;
default:
perror("Bad option: -%c",*arg);
rc=5;
break;
}
}
else if(f<2) fname[f++]= arg;
else
{ perror("Can't compare more than two files yet --Sorry!");
rc=5;
}
--argc;
++argv;
}
if(rc==0)
{ if(!silent) puts(rcs_id);
if(f==0) perror("requires two file names.");
else
{ if(f==1) fname[1]=fname[0];
if(openall(fname[0],fname[1],skip))
{ rc=action(fname[0],fname[1],skip);
closeall();
}
}
}
}
else /* no args */
{ puts(rcs_id);
puts("(c)Copyright 1989-92 by Tobias Ferber, All Rights Reserved");
puts("FCMP <files> [-q] [-b] [-d0] [-d1] [-d2] [-s[$|0x]<n>]");
}
exit((rc==0)?0:5);
}