# 2.11BSD#431 - /usr/src/bin/cmp.c

##### Functions

    main              X

##### Variables

    copyright         X

##### Macros

    DIFF              X
    ERR               X
    NO                X
    OK                X
    YES               X

       1: /*
       2:  * Copyright (c) 1987 Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms are permitted
       6:  * provided that this notice is preserved and that due credit is given
       7:  * to the University of California at Berkeley. The name of the University
       8:  * may not be used to endorse or promote products derived from this
       9:  * software without specific written prior permission. This software
      10:  * is provided ``as is'' without express or implied warranty.
      11:  */
      12:
      13: #ifndef lint
      14: char copyright[] =
      15: "@(#) Copyright (c) 1987 Regents of the University of California.\n\
      16:  All rights reserved.\n";
      17: #endif /* !lint */
      18:
      19: #ifndef lint
      20: static char sccsid[] = "@(#)cmp.c	4.8 (Berkeley) 12/21/87";
      21: #endif /* !lint */
      22:
      23: #include <sys/param.h>
      24: #include <sys/file.h>
      25: #include <sys/stat.h>
      26: #include <stdio.h>
      27: #include <ctype.h>
      28: #include <errno.h>
      29:
      30: #define DIFF    1           /* found differences */
      31: #define ERR 2           /* error during run */
      32: #define NO  0           /* no/false */
      33: #define OK  0           /* didn't find differences */
      34: #define YES 1           /* yes/true */
      35:
      36: static int  fd1, fd2,       /* file descriptors */
      37:         silent = NO;        /* if silent run */
      38: static short    all = NO;       /* if report all differences */
      39: static u_char   buf1[MAXBSIZE],     /* read buffers */
      40:         buf2[MAXBSIZE];
      41: static char *file1, *file2;     /* file names */
      42:
      43: main(argc, argv)
      44:     int argc;
      45:     char    **argv;
      46: {
      47:     extern char *optarg;
      48:     extern int  optind;
      49:     int ch;
      50:     u_long  otoi();
      51:
      52:     while ((ch = getopt(argc, argv, "ls")) != EOF)
      53:         switch(ch) {
      54:         case 'l':       /* print all differences */
      55:             all = YES;
      56:             break;
      57:         case 's':       /* silent run */
      58:             silent = YES;
      59:             break;
      60:         case '?':
      61:         default:
      62:             usage();
      63:         }
      64:     argv += optind;
      65:     argc -= optind;
      66:
      67:     if (argc < 2 || argc > 4)
      68:         usage();
      69:
      70:     /* open up files; "-" is stdin */
      71:     file1 = argv[0];
      72:     if (strcmp(file1, "-") && (fd1 = open(file1, O_RDONLY, 0)) < 0)
      73:         error(file1);
      74:     file2 = argv[1];
      75:     if ((fd2 = open(file2, O_RDONLY, 0)) < 0)
      76:         error(file2);
      77:
      78:     /* handle skip arguments */
      79:     if (argc > 2) {
      80:         skip(otoi(argv[2]), fd1, file1);
      81:         if (argc == 4)
      82:             skip(otoi(argv[3]), fd2, file2);
      83:     }
      84:     cmp();
      85:     /*NOTREACHED*/
      86: }
      87:
      88: /*
      89:  * skip --
      90:  *	skip first part of file
      91:  */
      92: static
      93: skip(dist, fd, fname)
      94:     register u_long dist;       /* length in bytes, to skip */
      95:     register int    fd;     /* file descriptor */
      96:     char    *fname;         /* file name for error */
      97: {
      98:     register int    rlen;       /* read length */
      99:     register int    nread;
     100:
     101:     for (; dist; dist -= rlen) {
     102:         rlen = MIN(dist, sizeof(buf1));
     103:         if ((nread = read(fd, buf1, rlen)) != rlen) {
     104:             if (nread < 0)
     105:                 error(fname);
     106:             else
     107:                 endoffile(fname);
     108:         }
     109:     }
     110: }
     111:
     112: static
     113: cmp()
     114: {
     115:     register u_char *C1, *C2;   /* traveling pointers */
     116:     register int    cnt,        /* counter */
     117:             len1, len2; /* read lengths */
     118:     register long   byte,       /* byte count */
     119:             line;       /* line count */
     120:     short   dfound = NO;        /* if difference found */
     121:
     122:     for (byte = 0, line = 1;;) {
     123:         switch(len1 = read(fd1, buf1, MAXBSIZE)) {
     124:         case -1:
     125:             error(file1);
     126:         case 0:
     127:             /*
     128: 			 * read of file 1 just failed, find out
     129: 			 * if there's anything left in file 2
     130: 			 */
     131:             switch(read(fd2, buf2, 1)) {
     132:                 case -1:
     133:                     error(file2);
     134:                 case 0:
     135:                     exit(dfound ? DIFF : OK);
     136:                 default:
     137:                     endoffile(file1);
     138:             }
     139:         }
     140:         /*
     141: 		 * file1 might be stdio, which means that a read of less than
     142: 		 * MAXBSIZE might not mean an EOF.  So, read whatever we read
     143: 		 * from file1 from file2.
     144: 		 */
     145:         if ((len2 = read(fd2, buf2, len1)) == -1)
     146:             error(file2);
     147:         if (bcmp(buf1, buf2, len2)) {
     148:             if (silent)
     149:                 exit(DIFF);
     150:             if (all) {
     151:                 dfound = YES;
     152:                 for (C1 = buf1, C2 = buf2, cnt = len2; cnt--; ++C1, ++C2) {
     153:                     ++byte;
     154:                     if (*C1 != *C2)
     155:                         printf("%6ld %3o %3o\n", byte, *C1, *C2);
     156:                 }
     157:             }
     158:             else for (C1 = buf1, C2 = buf2;; ++C1, ++C2) {
     159:                 ++byte;
     160:                 if (*C1 != *C2) {
     161:                     printf("%s %s differ: char %ld, line %ld\n", file1, file2, byte, line);
     162:                     exit(DIFF);
     163:                 }
     164:                 if (*C1 == '\n')
     165:                     ++line;
     166:             }
     167:         }
     168:         else {
     169:             byte += len2;
     170:             /*
     171: 			 * here's the real performance problem, we've got to
     172: 			 * count the stupid lines, which means that -l is a
     173: 			 * *much* faster version, i.e., unless you really
     174: 			 * *want* to know the line number, run -s or -l.
     175: 			 */
     176:             if (!silent && !all)
     177:                 for (C1 = buf1, cnt = len2; cnt--;)
     178:                     if (*C1++ == '\n')
     179:                         ++line;
     180:         }
     181:         /*
     182: 		 * couldn't read as much from file2 as from file1; checked
     183: 		 * here because there might be a difference before we got
     184: 		 * to this point, which would have precedence.
     185: 		 */
     186:         if (len2 < len1)
     187:             endoffile(file2);
     188:     }
     189: }
     190:
     191: /*
     192:  * otoi --
     193:  *	octal/decimal string to u_long
     194:  */
     195: static u_long
     196: otoi(C)
     197:     register char   *C;     /* argument string */
     198: {
     199:     register u_long val;        /* return value */
     200:     register int    base;       /* number base */
     201:
     202:     base = (*C == '0') ? 8 : 10;
     203:     for (val = 0; isdigit(*C); ++C)
     204:         val = val * base + *C - '0';
     205:     return(val);
     206: }
     207:
     208: /*
     209:  * error --
     210:  *	print I/O error message and die
     211:  */
     212: static
     213: error(filename)
     214:     char *filename;
     215: {
     216:     extern int errno;
     217:     int sverrno;
     218:
     219:     if (!silent) {
     220:         sverrno = errno;
     221:         (void)fprintf(stderr, "cmp: %s: ", filename);
     222:         errno = sverrno;
     223:         perror((char *)NULL);
     224:     }
     225:     exit(ERR);
     226: }
     227:
     228: /*
     229:  * endoffile --
     230:  *	print end-of-file message and exit indicating the files were different
     231:  */
     232: static
     233: endoffile(filename)
     234:     char *filename;
     235: {
     236:     /* 32V put this message on stdout, S5 does it on stderr. */
     237:     if (!silent)
     238:         (void)fprintf(stderr, "cmp: EOF on %s\n", filename);
     239:     exit(DIFF);
     240: }
     241:
     242: /*
     243:  * usage --
     244:  *	print usage and die
     245:  */
     246: static
     247: usage()
     248: {
     249:     fputs("usage: cmp [-ls] file1 file2 [skip1] [skip2]\n", stderr);
     250:     exit(ERR);
     251: }

#### Defined functions

cmp defined in line 112; used 1 times

- in line 84

endoffile defined in line 232; used 3 times

- in line 107, 137, 187

error defined in line 212; used 6 times

- in line 73-76(2), 105, 125, 133, 146

main defined in line 43; never used
otoi defined in line 195; used 3 times

- in line 50, 80-82(2)

skip defined in line 92; used 2 times

- in line 80-82(2)

usage defined in line 246; used 2 times

- in line 62, 68

#### Defined variables

all defined in line 38; used 3 times

- in line 55, 150, 176

buf1 defined in line 39; used 7 times

- in line 102-103(2), 123, 147-152(2), 158, 177

buf2 defined in line 40; used 5 times

- in line 131, 145-152(3), 158

copyright defined in line 14; never used
fd1 defined in line 36; used 3 times

- in line 72, 80, 123

fd2 defined in line 36; used 4 times

- in line 75, 82, 131, 145

file1 defined in line 41; used 8 times

- in line 71-73(4), 80, 125, 137, 161

file2 defined in line 41; used 8 times

- in line 74-76(3), 82, 133, 146, 161, 187

sccsid defined in line 20; never used
silent defined in line 37; used 5 times

- in line 58, 148, 176, 219, 237

#### Defined macros

DIFF defined in line 30; used 4 times

- in line 135, 149, 162, 239

ERR defined in line 31; used 2 times

- in line 225, 250

NO defined in line 32; used 3 times

- in line 37-38(2), 120

OK defined in line 33; used 1 times

- in line 135

YES defined in line 34; used 3 times

- in line 55-58(2), 151

Last modified: 1988-07-04 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1681 |