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 >
C/C++ Source or Header  |  1993-02-01  |  9KB  |  325 lines

  1. /*--------------------------------------------------------------------------*
  2.          ______
  3.         / ____/                          $RCSfile: fcmp.c,v $
  4.        / /_ ______ _   _   ______        $Release$
  5.       / __// ____// \_/ \ / __  /        $Revision: 1.6 $
  6.      / /  / /___ / /__/ // /_/ /         $Date: 92/12/04 07:10:12 $
  7.     /_/  /_____//_/  /_// ____/          $Author: tf $
  8.                        / /               $State: Exp $
  9.       Revision 1.6    /_/
  10.  
  11.          (c) Copyright 1989-92 Tobias Ferber, All Rights Reserved.
  12.  
  13.  *--------------------------------------------------------------------------*/
  14.    
  15. #include <exec/types.h>
  16. #include <stdio.h>
  17. #include <stdarg.h>
  18.  
  19. extern long hextol(char *); /* instead of xtoy.h */
  20.  
  21. static char rcs_id[]= "$Id: fcmp.c,v 1.6 92/12/04 07:10:12 tf Exp $";
  22. char *whoami;
  23.  
  24. BOOL silent=FALSE,   /* don't produce any output but the result */
  25.      brkdiff=FALSE;  /* break on the first non-equivalence */
  26.  
  27. FILE *fp0, *fp1;
  28.  
  29. void perror(const char *fmt, ...)
  30. {
  31.   va_list argp;
  32.   va_start(argp,fmt); /* name the last known argument */
  33.   fprintf(stderr,"\r%s: ",whoami);
  34.   vfprintf(stderr,fmt,argp);
  35.   fprintf(stderr,"\n");
  36.   fflush(stderr);
  37.   va_end(argp); /* just to be sure... */
  38. }
  39.  
  40. void closeall(void)
  41. { if(fp0) fclose(fp0);
  42.   if(fp1) fclose(fp1);
  43. }
  44.  
  45. void _abort(void)
  46. { printf("\33[31m^C\n\n** BREAK\n");
  47.   closeall();
  48.   exit(5);
  49. }
  50.  
  51. int openall(char *fname0,char *fname1,int rpos)
  52. {
  53.   if(!(fp0=fopen(fname0,"rb")))
  54.   { perror("Can't open %s for input - object not found",fname0);
  55.     return(0);
  56.   }
  57.   if(!(fp1=fopen(fname1,"rb")))
  58.   { perror("Can't open %s for input - object not found",fname1);
  59.     fclose(fp0);
  60.     return(0);
  61.   }
  62.   if(rpos>0)
  63.   { if(fseek(fp0,rpos,0L)<0||fseek(fp1,rpos,1L)<0)
  64.     { closeall();
  65.       return(0);
  66.     }
  67.   }
  68.   return(1);
  69. }
  70.  
  71. #define DUMP(x)  ((32<=(x)&&(x)<127)||(x)>161)?(x):('.')
  72. #define COLOR(x) (x)?("\33[31m"):("\33[33m")
  73.  
  74. /* single file hex dump */
  75.  
  76. long hexdump(char *fname0, char* fname1, long rpos)
  77. {
  78.   unsigned long bc=rpos,  /* byte counter */
  79.                 dc=0;     /* difference counter */
  80.  
  81.   BOOL abort=FALSE;
  82.  
  83.   while(!abort)
  84.   { unsigned long i,j,k; /* general counters */
  85.     unsigned char c0[16],c1[16]; /* char buffer */
  86.     BOOL d[16]; /* difference indicator */
  87.     for(j=0,k=0;(j<16&!abort);j++,bc++)
  88.     { c0[j]=fgetc(fp0);
  89.       c1[j]=fgetc(fp1);
  90.       abort=(feof(fp0)||feof(fp1));
  91.       if(!(d[j]=(c0[j]==c1[j]))) k++;
  92.     }
  93.     dc+=k;
  94.     if(j>0 && (!silent || (silent && k>0)))
  95.     { printf("%08lx: ",bc-j);
  96.       for(i=0;i<16;i++)
  97.       { if(i<j) printf("%s%02x%s",COLOR(d[i]),c0[i],(((i+1)%4)==0)?(" "):(""));
  98.         else printf("  %s",(((i+1)%4)==0)?(" "):(""));
  99.       }
  100.       printf("  ");
  101.       for(i=0;i<j;i++) printf("%s%c",COLOR(d[i]),DUMP(c0[i]));
  102.       printf("\33[31m\n");
  103.     }
  104.     if(brkdiff && dc>0) abort=TRUE;
  105.   }
  106.   if(brkdiff && dc>0)
  107.     perror("terminated; files %s and %s differ.",fname0,fname1);
  108.   else
  109.   { if(!(feof(fp0)&&feof(fp1)))
  110.       printf("Unexpected EOF \"%s\" at seek offset %d; ",feof(fp0)?fname0:fname1,bc);
  111.     else printf("Equal length: %ld bytes, ",bc);
  112.     printf("%d %s.\n",dc,(dc==1)?"difference":"differences");
  113.   }
  114.   return(dc);
  115. }
  116.  
  117. /* hex dump of both files */
  118.  
  119. long dumpdiff(char *fname0, char* fname1, long rpos)
  120. {
  121.   unsigned long bc=rpos,  /* byte counter */
  122.                 dc=0;     /* difference counter */
  123.  
  124.   BOOL abort=FALSE;
  125.  
  126.   while(!abort)
  127.   { unsigned long i,j,k; /* general counters */
  128.     unsigned char c0[8],c1[8]; /* char buffer */
  129.     BOOL d[8]; /* difference indicator */
  130.     for(j=0,k=0;(j<8&!abort);j++,bc++)
  131.     { c0[j]=fgetc(fp0);
  132.       c1[j]=fgetc(fp1);
  133.       abort=(feof(fp0)||feof(fp1));
  134.       if(!(d[j]=(c0[j]==c1[j]))) k++;
  135.     }
  136.     dc+=k;
  137.     if(j>0 && (!silent || (silent && k>0)))
  138.     { printf("%08lx: ",bc-j);
  139.       for(i=0;i<8;i++)
  140.       { if(i<j) printf("%s%02x%s",COLOR(d[i]),c0[i],(i==3)?(" "):(""));
  141.         else printf("  %s",((i==3)?(" "):("")));
  142.       }
  143.       printf("  ");
  144.       for(i=0;i<8;i++) printf("%s%c",COLOR(d[i]),((i<j)?(DUMP(c0[i])):(' ')));
  145.       printf("\33[31m  |  ");
  146.       for(i=0;i<8;i++)
  147.       { if(i<j) printf("%s%02x%s",COLOR(d[i]),c1[i],(i==3)?(" "):(""));
  148.         else printf("  %s",((i==3)?(" "):("")));
  149.       }
  150.       printf("  ");
  151.       for(i=0;i<j;i++) printf("%s%c",COLOR(d[i]),DUMP(c1[i]));
  152.       printf("\33[31m\n");
  153.     }
  154.     if(brkdiff && dc>0) abort=TRUE;
  155.   }
  156.   if(brkdiff && dc>0)
  157.     perror("terminated; files %s and %s differ.",fname0,fname1);
  158.   else
  159.   { if(!(feof(fp0)&&feof(fp1)))
  160.       printf("Unexpected EOF \"%s\" at seek offset %d; ",feof(fp0)?fname0:fname1,bc);
  161.     else printf("Equal length: %ld bytes, ",bc);
  162.     printf("%d %s.\n",dc,(dc==1)?"difference":"differences");
  163.   }
  164.   return(dc);
  165. }
  166.  
  167. /* single byte dump */
  168.  
  169. long sdbdump(char *fname0, char *fname1, long rpos)
  170. { unsigned char c0,c1;
  171.   unsigned long bc=rpos, /* byte counter */
  172.                 dc=0;    /* difference counter */
  173.  
  174.   BOOL abort=FALSE;
  175.  
  176.   do
  177.   { c0=fgetc(fp0);
  178.     c1=fgetc(fp1);
  179.     if(!(feof(fp0)||feof(fp1)))
  180.     { bc++;
  181.       if(c0!=c1)
  182.       { dc++;
  183.         if(!silent)
  184.           printf("%08lx:  #%03d ($%02x) \"%c\" !=  #%03d ($%02x) \"%c\"\n",
  185.             bc,c0,c0,DUMP(c0),c1,c1,DUMP(c1));
  186.         else printf("%08lx\n",bc);
  187.         if(brkdiff) abort=TRUE;
  188.       }
  189.     }
  190.   } while(!(feof(fp0)||feof(fp1)||abort));
  191.  
  192.   if(brkdiff && dc>0)
  193.     perror("terminated; files %s and %s differ.",fname0,fname1);
  194.   else
  195.   { if(!(feof(fp0)&&feof(fp1)))
  196.       printf("Unexpected EOF \"%s\" at seek offset %d; ",feof(fp0)?fname0:fname1,bc);
  197.     else printf("Equal length: %ld bytes, ",bc);
  198.     printf("%d %s.\n",dc,(dc==1)?"difference":"differences");
  199.   }
  200.   return(dc);
  201. }
  202.  
  203. /* simple compare */
  204.  
  205. long compare(char *fname0, char *fname1, long rpos)
  206. { unsigned char c0,c1;
  207.   unsigned long bc=rpos, /* byte counter */
  208.                 dc=0;    /* difference counter */
  209.  
  210.   BOOL abort=FALSE;
  211.  
  212.   do
  213.   { c0=fgetc(fp0);
  214.     c1=fgetc(fp1);
  215.     if(!(feof(fp0)||feof(fp1)))
  216.     { bc++;
  217.       if(c0!=c1)
  218.       { dc++;
  219.         if(brkdiff) abort=TRUE;
  220.       }
  221.     }
  222.   } while(!(feof(fp0)||feof(fp1)||abort));
  223.   if(!silent)
  224.   { if(abort)
  225.       perror("terminated; files %s and %s differ.",fname0,fname1);
  226.     else
  227.     { if(!(feof(fp0)&&feof(fp1)))
  228.         printf("Unexpected EOF \"%s\" at seek offset %d; ",feof(fp0)?fname0:fname1,bc);
  229.       else printf("Equal length: %ld bytes, ",bc);
  230.       printf("%d %s.\n",dc,(dc==1)?"difference":"differences");
  231.     }
  232.   }
  233.   return(dc);
  234. }
  235.  
  236.  
  237. main(int argc,char *argv[])
  238. {
  239.   long (*action)()= compare;
  240.   char *fname[2]; /* file names */
  241.   long f=0,       /* filename nº */
  242.        skip=0,    /* #of bytes to skip */
  243.        rc=0;      /* return code */
  244.  
  245.   onbreak(_abort);
  246.   whoami= argv[0];
  247.  
  248.   if(argc>1)
  249.   { --argc;
  250.     ++argv;
  251.     while(argc>0 && rc==0)
  252.     { char *arg=argv[0];
  253.       if(*arg=='-')
  254.       { arg++;
  255.         switch(*arg)
  256.         { case 'd': case 'D': /* dump */
  257.             switch(*++arg)
  258.             { case '0':  action=sdbdump;   /* single byte dump */
  259.                          break;
  260.               case '1':  action=hexdump;   /* hex dump */
  261.                          break;
  262.               case '2':  action=dumpdiff;  /* dump diff */
  263.                          break;
  264.               default:   perror("Bad dump option '-d%c'.",*arg);
  265.                          rc=5;
  266.                          break;
  267.             }
  268.             break;
  269.           case 'b': case 'B': /* break on diff */
  270.             brkdiff=TRUE;
  271.             break;          
  272.           case 'q': case 'Q': /* quiet (brief) */
  273.             silent=TRUE;
  274.             break;
  275.           case 's': case 'S': /* seek offset */
  276.             if(arg[1]) ++arg;
  277.             else
  278.             { ++argv;
  279.               --argc;
  280.               arg=argv[0];
  281.             }
  282.             if(arg[0]=='$')
  283.               skip= hextol(&arg[1]);
  284.             else if(arg[0]=='0' && (arg[1]=='x'||arg[1]=='X'))
  285.               skip= hextol(&arg[2]);
  286.             else skip= atol(arg);
  287.             if(skip<0)
  288.             { perror("Error: Negative begin-offset; can't skip %d bytes",skip);
  289.               rc=5;
  290.             }
  291.             break;
  292.           default:
  293.             perror("Bad option: -%c",*arg);
  294.             rc=5;
  295.             break;
  296.         }
  297.       }
  298.       else if(f<2) fname[f++]= arg;
  299.       else
  300.       { perror("Can't compare more than two files yet --Sorry!");
  301.         rc=5;
  302.       }
  303.       --argc;
  304.       ++argv;
  305.     }
  306.     if(rc==0)
  307.     { if(!silent) puts(rcs_id);
  308.       if(f==0) perror("requires two file names.");
  309.       else
  310.       { if(f==1) fname[1]=fname[0];
  311.         if(openall(fname[0],fname[1],skip))
  312.         { rc=action(fname[0],fname[1],skip);
  313.           closeall();
  314.         }
  315.       }
  316.     }
  317.   }
  318.   else /* no args */
  319.   { puts(rcs_id);
  320.     puts("(c)Copyright 1989-92 by Tobias Ferber, All Rights Reserved");
  321.     puts("FCMP <files> [-q] [-b] [-d0] [-d1] [-d2] [-s[$|0x]<n>]");
  322.   }
  323.   exit((rc==0)?0:5);
  324. }
  325.