home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*
- ______
- / ____/ $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);
- }
-