Annotation of 43BSDTahoe/bin/cmp.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.