[BACK]Return to diff.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / diff

Annotation of src/usr.bin/diff/diff.c, Revision 1.22

1.22    ! millert     1: /*     $OpenBSD: diff.c,v 1.21 2003/07/04 17:50:24 millert Exp $       */
1.2       deraadt     2:
                      3: /*
                      4:  * Copyright (C) Caldera International Inc.  2001-2002.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code and documentation must retain the above
                     11:  *    copyright notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *     This product includes software developed or owned by Caldera
                     18:  *     International, Inc.
                     19:  * 4. Neither the name of Caldera International, Inc. nor the names of other
                     20:  *    contributors may be used to endorse or promote products derived from
                     21:  *    this software without specific prior written permission.
                     22:  *
                     23:  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
                     24:  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
                     25:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     26:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     27:  * IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT,
                     28:  * INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     29:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     30:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     32:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
                     33:  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     34:  * POSSIBILITY OF SUCH DAMAGE.
                     35:  */
                     36:
1.15      millert    37: #include <errno.h>
1.3       tedu       38: #include <stdlib.h>
1.15      millert    39: #include <stdarg.h>
1.18      david      40: #include <string.h>
1.3       tedu       41: #include <unistd.h>
1.1       deraadt    42:
                     43: #include "diff.h"
                     44: #include "pathnames.h"
                     45:
1.3       tedu       46: #if 0
                     47: static char const sccsid[] = "@(#)diff.c 4.7 5/11/89";
                     48: #endif
                     49:
1.1       deraadt    50: /*
                     51:  * diff - driver and subroutines
                     52:  */
1.12      tedu       53: int    opt;
                     54: int    aflag;                  /* treat all files as text */
                     55: int    tflag;                  /* expand tabs on output */
                     56: /* Algorithm related options. */
                     57: int    bflag;                  /* ignore blanks in comparisons */
                     58: int    wflag;                  /* totally ignore blanks in comparisons */
                     59: int    iflag;                  /* ignore case in comparisons */
                     60: /* Options on hierarchical diffs. */
                     61: int    rflag;                  /* recursively trace directories */
                     62: int    sflag;                  /* announce files which are same */
                     63: char   *start;                 /* do file only if name >= this */
1.19      millert    64: /* Variable for -D D_IFDEF option. */
1.17      millert    65: char   *ifdefname;             /* What we will print for #ifdef/#endif */
1.12      tedu       66: /* Variables for -c and -u context option. */
                     67: int    context;                /* lines of context to be printed */
                     68: /* State for exit status. */
                     69: int    status;
                     70: int    anychange;
                     71: /* Variables for diffdir. */
                     72: char   **diffargv;             /* option list to pass to recursive diffs */
                     73:
                     74: /*
                     75:  * Input file names.
1.19      millert    76:  * With diffdir, file1 and file2 are allocated MAXPATHLEN space,
                     77:  * and padded with a '/', and then efile1 and efile2 point after
1.12      tedu       78:  * the '/'.
                     79:  */
                     80: char   *file1, *file2, *efile1, *efile2;
                     81: struct stat stb1, stb2;
1.1       deraadt    82:
1.6       millert    83: __dead void usage(void);
1.3       tedu       84:
                     85: int
                     86: main(int argc, char **argv)
1.1       deraadt    87: {
1.6       millert    88:        int ch;
1.1       deraadt    89:
                     90:        status = 2;
                     91:        diffargv = argv;
1.6       millert    92:
1.22    ! millert    93:        while ((ch = getopt(argc, argv, "abC:cD:efhinrS:stU:uw")) != -1) {
1.6       millert    94:                switch (ch) {
1.12      tedu       95:                case 'a':
                     96:                        aflag++;
                     97:                        break;
1.6       millert    98:                case 'b':
                     99:                        bflag++;
                    100:                        break;
                    101:                case 'C':
                    102:                        opt = D_CONTEXT;
                    103:                        if (!isdigit(*optarg))
                    104:                                usage();
                    105:                        context = atoi(optarg); /* XXX - use strtol */
                    106:                        break;
                    107:                case 'c':
                    108:                        opt = D_CONTEXT;
                    109:                        context = 3;
                    110:                        break;
                    111:                case 'D':
                    112:                        opt = D_IFDEF;
1.17      millert   113:                        ifdefname = optarg;
1.6       millert   114:                        break;
                    115:                case 'e':
                    116:                        opt = D_EDIT;
                    117:                        break;
                    118:                case 'f':
                    119:                        opt = D_REVERSE;
                    120:                        break;
1.22    ! millert   121:                case 'h':
        !           122:                        /* silently ignore for backwards compatibility */
        !           123:                        break;
1.6       millert   124:                case 'i':
                    125:                        iflag++;
                    126:                        break;
                    127:                case 'n':
                    128:                        opt = D_NREVERSE;
                    129:                        break;
                    130:                case 'r':
1.16      millert   131:                        rflag++;
1.6       millert   132:                        break;
                    133:                case 'S':
                    134:                        start = optarg;
                    135:                        break;
                    136:                case 's':
                    137:                        sflag++;
                    138:                        break;
                    139:                case 't':
                    140:                        tflag++;
                    141:                        break;
1.9       millert   142:                case 'U':
                    143:                        opt = D_UNIFIED;
                    144:                        if (!isdigit(*optarg))
                    145:                                usage();
                    146:                        context = atoi(optarg); /* XXX - use strtol */
                    147:                        break;
                    148:                case 'u':
                    149:                        opt = D_UNIFIED;
                    150:                        context = 3;
                    151:                        break;
1.6       millert   152:                case 'w':
                    153:                        wflag++;
                    154:                        break;
                    155:                default:
                    156:                        usage();
                    157:                        break;
                    158:                }
1.1       deraadt   159:        }
1.6       millert   160:        argc -= optind;
                    161:        argv += optind;
                    162:
                    163:        if (argc != 2)
1.15      millert   164:                errorx("two filename arguments required");
1.1       deraadt   165:        file1 = argv[0];
                    166:        file2 = argv[1];
                    167:        if (!strcmp(file1, "-"))
                    168:                stb1.st_mode = S_IFREG;
1.6       millert   169:        else if (stat(file1, &stb1) < 0)
1.15      millert   170:                error("%s", file1);
1.1       deraadt   171:        if (!strcmp(file2, "-"))
                    172:                stb2.st_mode = S_IFREG;
1.6       millert   173:        else if (stat(file2, &stb2) < 0)
1.15      millert   174:                error("%s", file2);
1.8       millert   175:        if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode))
1.1       deraadt   176:                diffdir(argv);
1.8       millert   177:        else
1.1       deraadt   178:                diffreg();
1.4       deraadt   179:        done(0);
1.1       deraadt   180: }
                    181:
1.3       tedu      182: int
                    183: min(int a, int b)
1.1       deraadt   184: {
                    185:
                    186:        return (a < b ? a : b);
                    187: }
                    188:
1.3       tedu      189: int
                    190: max(int a, int b)
1.1       deraadt   191: {
                    192:
                    193:        return (a > b ? a : b);
                    194: }
                    195:
1.6       millert   196: __dead void
1.4       deraadt   197: done(int sig)
1.1       deraadt   198: {
1.15      millert   199:        if (tempfiles[0] != NULL)
1.13      millert   200:                unlink(tempfiles[0]);
1.15      millert   201:        if (tempfiles[1] != NULL)
1.13      millert   202:                unlink(tempfiles[1]);
1.4       deraadt   203:        if (sig)
                    204:                _exit(status);
1.1       deraadt   205:        exit(status);
1.3       tedu      206: }
1.1       deraadt   207:
1.3       tedu      208: void *
1.8       millert   209: emalloc(size_t n)
1.3       tedu      210: {
                    211:        void *p;
                    212:
                    213:        if ((p = malloc(n)) == NULL)
1.22    ! millert   214:                error(NULL);
1.3       tedu      215:        return (p);
1.1       deraadt   216: }
                    217:
1.3       tedu      218: void *
1.8       millert   219: erealloc(void *p, size_t n)
1.1       deraadt   220: {
1.3       tedu      221:        void *q;
1.1       deraadt   222:
1.3       tedu      223:        if ((q = realloc(p, n)) == NULL)
1.22    ! millert   224:                error(NULL);
1.3       tedu      225:        return (q);
1.1       deraadt   226: }
                    227:
1.15      millert   228: __dead void
                    229: error(const char *fmt, ...)
                    230: {
                    231:        va_list ap;
                    232:        int sverrno = errno;
                    233:
                    234:        if (tempfiles[0] != NULL)
                    235:                unlink(tempfiles[0]);
                    236:        if (tempfiles[1] != NULL)
                    237:                unlink(tempfiles[1]);
                    238:        errno = sverrno;
                    239:        va_start(ap, fmt);
                    240:        verr(status, fmt, ap);
                    241:        va_end(ap);
                    242: }
                    243:
                    244: __dead void
                    245: errorx(const char *fmt, ...)
1.1       deraadt   246: {
1.15      millert   247:        va_list ap;
                    248:
                    249:        if (tempfiles[0] != NULL)
                    250:                unlink(tempfiles[0]);
                    251:        if (tempfiles[1] != NULL)
                    252:                unlink(tempfiles[1]);
                    253:        va_start(ap, fmt);
                    254:        verrx(status, fmt, ap);
                    255:        va_end(ap);
1.6       millert   256: }
                    257:
                    258: __dead void
                    259: usage(void)
                    260: {
1.14      deraadt   261:        (void)fprintf(stderr,
1.21      millert   262:            "usage: diff [-bitw] [-c | -e | -f | -n | -u ] file1 file2\n"
1.11      millert   263:            "       diff [-bitw] -C number file1 file2\n"
                    264:            "       diff [-bitw] -D string file1 file2\n"
                    265:            "       diff [-bitw] -U number file1 file2\n"
1.21      millert   266:            "       diff [-biwt] [-c | -e | -f | -n | -u ] "
                    267:            "[-r] [-s] [-S name]\n            dir1 dir2\n");
1.6       millert   268:
1.15      millert   269:        exit(2);
1.1       deraadt   270: }