Annotation of coherent/d/bin/diff/z8001/diff2.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * This code is common between diff and /usr/lib/diffh.
        !             3:  * It is a restructuring and re-write of the earlier
        !             4:  * Tom Duff code so that reading options, opening files,
        !             5:  * and outputing of the differences is common.
        !             6:  */
        !             7: 
        !             8: #include "diff.h"
        !             9: #include <sys/stat.h>
        !            10: #include <signal.h>
        !            11: 
        !            12: int    dflag;                  /* Dynamic decision about -h or not */
        !            13: int    bflag;                  /* Strip trailing blanks, multiple blanks */
        !            14: int    eflag;                  /* Editor script */
        !            15: int    sflag;                  /* Sed script output (used by SCCS) */
        !            16: int    rflag;                  /* Reversed order of printed (usually -e) */
        !            17: int    incr;                   /* Line number increment for `rflag' diff */
        !            18: char   *csymbol;               /* Symbol for C pre-processor (#ifdef) */
        !            19: int    sepflag;                /* On if text from both files involved */
        !            20: int    caflag;                 /* On for a change or append */
        !            21: unsigned ninsert;              /* Number of lines inserted */
        !            22: unsigned ndelete;              /* Number of lines deleted */
        !            23: unsigned nunchanged;           /* Number of line unchanged */
        !            24: char   *tmpnam1, *tmpnam2;
        !            25: FILE   *fp1;                   /* First input stream */
        !            26: FILE   *fp2;                   /* Second input stream */
        !            27: char   *fn1, *fn2;             /* Filenames */
        !            28: 
        !            29: char   buf1[BUFSIZ];
        !            30: char   buf2[BUFSIZ];
        !            31: 
        !            32: FILE   *openfile();
        !            33: int    rmexit();
        !            34: int    catchsig();
        !            35: int    streq();
        !            36: int    bstreq();
        !            37: 
        !            38: int    (*equal)() = streq;
        !            39: 
        !            40: main(argc, argv)
        !            41: int argc;
        !            42: char *argv[];
        !            43: {
        !            44:        register char *ap;
        !            45:        register char **sargv = argv;
        !            46:        fsize_t size1, size2;
        !            47: 
        !            48:        while (argc>1 && argv[1][0]=='-' && argv[1][1]!='\0') {
        !            49:                for (ap = &argv[1][1]; *ap != '\0'; ap++)
        !            50:                        switch (*ap) {
        !            51:                        case 'b':
        !            52:                                bflag = 1;
        !            53:                                equal = bstreq;
        !            54:                                break;
        !            55: 
        !            56:                        case 'c':
        !            57:                                if (argc < 3)
        !            58:                                        usage();
        !            59:                                csymbol = argv[2];
        !            60:                                argv++;
        !            61:                                argc--;
        !            62:                                break;
        !            63: 
        !            64:                        case 'd':
        !            65:                                dflag = 1;
        !            66:                                break;
        !            67: 
        !            68:                        case 'e':
        !            69:                                eflag = rflag = 1;
        !            70:                                break;
        !            71: 
        !            72:                        case 'f':
        !            73:                                eflag = 1;
        !            74:                                rflag = 0;
        !            75:                                break;
        !            76: 
        !            77:                        case 's':
        !            78:                                eflag = sflag = 1;
        !            79:                                break;
        !            80: 
        !            81:                        case 'h':
        !            82:                                diffh(sargv);
        !            83:                                break;
        !            84: 
        !            85:                        default:
        !            86:                                usage();
        !            87:                        }
        !            88:                argc--;
        !            89:                argv++;
        !            90:        }
        !            91:        if (argc != 3)
        !            92:                usage();
        !            93:        if (eflag && csymbol!=NULL)
        !            94:                cerr("-e and -c are incompatible options");
        !            95:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
        !            96:                signal(SIGINT, catchsig);
        !            97:        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
        !            98:                signal(SIGHUP, catchsig);
        !            99:        if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
        !           100:                signal(SIGTERM, catchsig);
        !           101:        fp1 = openfile(argv[1], argv[2], &tmpnam1, &size1);
        !           102:        fp2 = openfile(argv[2], argv[1], &tmpnam2, &size2);
        !           103:        if (dflag && (size1>NBIGF || size2>NBIGF))
        !           104:                diffh(argv);
        !           105:        setbuf(fp1, buf1);
        !           106:        setbuf(fp2, buf2);
        !           107:        fn1 = argv[1];
        !           108:        fn2 = argv[2];
        !           109:        diff(fp1, fp2);
        !           110:        if (sflag)
        !           111:                printf(":I%d\n:D%d\n:U%d\n", ninsert, ndelete, nunchanged);
        !           112:        rmexit(ninsert || ndelete);
        !           113: }
        !           114: 
        !           115: /*
        !           116:  * Compare input lines for equality.
        !           117:  */
        !           118: bstreq(s1, s2)
        !           119: register char *s1, *s2;
        !           120: {
        !           121:        for (;;) {
        !           122:                if (*s1==' ' || *s1=='\t') {
        !           123:                        do {
        !           124:                                s1++;
        !           125:                        } while (*s1==' ' || *s1=='\t');
        !           126:                        if (*s1 == '\n') {
        !           127:                                while (*s2==' ' || *s2=='\t')
        !           128:                                        s2++;
        !           129:                                return (*s2 == '\n');
        !           130:                        }
        !           131:                        if (*s2!=' ' && *s2!='\t')
        !           132:                                return (0);
        !           133:                        do {
        !           134:                                s2++;
        !           135:                        } while (*s2==' ' || *s2=='\t');
        !           136:                } else {
        !           137:                        if (*s1 == '\n')
        !           138:                                while (*s2==' ' || *s2=='\t')
        !           139:                                        s2++;
        !           140:                        if (*s1++ != *s2)
        !           141:                                return (0);
        !           142:                        if (*s2++ == '\n')
        !           143:                                return (1);
        !           144:                }
        !           145:        }
        !           146: }
        !           147: 
        !           148: /*
        !           149:  * Open the files, allowing for special standard input
        !           150:  * convention (`-') and directories.  Copy any special
        !           151:  * files or pipes to a tempfile because they cannot be
        !           152:  * rewound.
        !           153:  * `ofn' is the other name, for directory concatenation.
        !           154:  */
        !           155: FILE *
        !           156: openfile(fn, ofn, tfnp, sizep)
        !           157: char *fn;
        !           158: char *ofn;
        !           159: char **tfnp;
        !           160: fsize_t *sizep;
        !           161: {
        !           162:        register char *cp;
        !           163:        register int c;
        !           164:        register FILE *fp;
        !           165:        register FILE *tfp;
        !           166:        char fname[300];
        !           167:        struct stat sb;
        !           168:        static int dirflag;
        !           169: 
        !           170: again:
        !           171:        if (fn[0]=='-' && fn[1]=='\0')
        !           172:                fp = stdin;
        !           173:        else if ((fp = fopen(fn, "r")) == NULL)
        !           174:                cerr("cannot open `%s'", fn);
        !           175:        fstat(fileno(fp), &sb);
        !           176:        *sizep = sb.st_size;
        !           177:        switch (sb.st_mode & S_IFMT) {
        !           178:        case S_IFDIR:
        !           179:                if (dirflag)
        !           180:                        break;
        !           181:                dirflag++;
        !           182:                for (cp = ofn; *cp != '\0'; cp++)
        !           183:                        ;
        !           184:                while (cp > ofn)
        !           185:                        if (*--cp == '/') {
        !           186:                                cp++;
        !           187:                                break;
        !           188:                        }
        !           189:                fn = sprintf(fname, "%s/%s", fn, cp);
        !           190:                goto again;
        !           191: 
        !           192:        case S_IFREG:
        !           193:                break;
        !           194: 
        !           195:        default:
        !           196:                *tfnp = "/tmp/difXXXXXX";
        !           197:                if ((tfp = fopen(mktemp(*tfnp), "w")) == NULL)
        !           198:                        cerr("cannot create tempfile");
        !           199:                setbuf(fp, buf1);
        !           200:                setbuf(tfp, buf2);
        !           201:                while ((c = getc(fp)) != EOF)
        !           202:                        putc(c, tfp);
        !           203:                fflush(tfp);
        !           204:                if (ferror(tfp))
        !           205:                        cerr("write error on tempfile");
        !           206:                fclose(tfp);
        !           207:                if (fp != stdin)
        !           208:                        fclose(fp);
        !           209:                if ((fp = fopen(*tfnp, "r")) == NULL)
        !           210:                        cerr("cannot re-open tempfile");
        !           211:        }
        !           212:        return (fp);
        !           213: }
        !           214: 
        !           215: /*
        !           216:  * Output a text line common to both files.
        !           217:  * This is only used by the `-c' option.
        !           218:  */
        !           219: text(line)
        !           220: char *line;
        !           221: {
        !           222:        ++nunchanged;
        !           223:        if (csymbol != NULL)
        !           224:                fputs(line, stdout);
        !           225: }
        !           226: 
        !           227: /*
        !           228:  * Output a text line from the first file.
        !           229:  */
        !           230: text1(line)
        !           231: register char *line;
        !           232: {
        !           233:        if (csymbol != NULL)
        !           234:                fputs(line, stdout);
        !           235:        else if (!eflag) {
        !           236:                fputs("< ", stdout);
        !           237:                fputs(line, stdout);
        !           238:        }
        !           239:        ++ndelete;
        !           240: }
        !           241: 
        !           242: /*
        !           243:  * Output a line that is only in
        !           244:  * the second file.
        !           245:  */
        !           246: text2(line)
        !           247: register char *line;
        !           248: {
        !           249:        if (sflag) {
        !           250:                putchar('\\');
        !           251:                putchar('\n');
        !           252: #if REALSED
        !           253:                /*
        !           254:                 * Sed is documented to strip
        !           255:                 * leading blanks/tabs in appended
        !           256:                 * text but doesn't.  This appears
        !           257:                 * to be a feature rather than a bug.
        !           258:                 */
        !           259:                if (line[0]==' ' || line[0]=='\t')
        !           260:                        putchar('\\');
        !           261: #endif
        !           262:                while (*line != '\n') {
        !           263:                        if (*line == '\\')
        !           264:                                putchar(*line);
        !           265:                        putchar(*line++);
        !           266:                }
        !           267:        } else if (eflag) {
        !           268:                if (line[0]=='.' && line[1]=='\n' && line[2]=='\0')
        !           269:                        fputs("~\n.\ns/~/./\na\n", stdout); else
        !           270:                        fputs(line, stdout);
        !           271:        } else if (csymbol != NULL)
        !           272:                fputs(line, stdout);
        !           273:        else {
        !           274:                fputs("> ", stdout);
        !           275:                fputs(line, stdout);
        !           276:        }
        !           277:        caflag = 1;
        !           278:        ++ninsert;
        !           279: }
        !           280: 
        !           281: /*
        !           282:  * Output the start of a set of
        !           283:  * changed lines.
        !           284:  * Change is from `f1',`f2' (other file is `t1,t2').
        !           285:  */
        !           286: change(f1, f2, t1, t2)
        !           287: unsigned f1, f2, t1, t2;
        !           288: {
        !           289:        sepflag = 1;
        !           290:        if (csymbol != NULL)
        !           291:                printf("#ifndef %s\n", csymbol);
        !           292:        else {
        !           293:                prange(f1, f2);
        !           294:                if (sflag)
        !           295:                        putchar('c');
        !           296:                else if (eflag)
        !           297:                        fputs("c\n", stdout);
        !           298:                else {
        !           299:                        fputs(" c ", stdout);
        !           300:                        prange(t1, t2);
        !           301:                        putchar('\n');
        !           302:                }
        !           303:        }
        !           304:        if (rflag)
        !           305:                incr += t2-t1 + f1-f2;
        !           306: }
        !           307: 
        !           308: /*
        !           309:  * Output a set of appended lines.
        !           310:  * Append after `f' the lines in
        !           311:  * range `t1,t2'.
        !           312:  */
        !           313: append(f, t1, t2)
        !           314: unsigned f, t1, t2;
        !           315: {
        !           316:        f--;
        !           317:        if (csymbol != NULL)
        !           318:                printf("#ifndef %s\n", csymbol);
        !           319:        else {
        !           320:                prange(f, f);
        !           321:                if (sflag)
        !           322:                        putchar('a');
        !           323:                else if (eflag) {
        !           324:                        fputs("a\n", stdout);
        !           325:                } else {
        !           326:                        fputs(" a ", stdout);
        !           327:                        prange(t1, t2);
        !           328:                        putchar('\n');
        !           329:                }
        !           330:        }
        !           331:        if (rflag)
        !           332:                incr += t2-t1+1;
        !           333: }
        !           334: 
        !           335: /*
        !           336:  * Output a set of deleted lines.
        !           337:  * Delete range `f1,f2' (other file
        !           338:  * number is `t'.
        !           339:  */
        !           340: delete(f1, f2, t)
        !           341: unsigned f1, f2, t;
        !           342: {
        !           343:        if (csymbol != NULL)
        !           344:                printf("#ifdef %s\n", csymbol);
        !           345:        else {
        !           346:                prange(f1, f2);
        !           347:                if (eflag)
        !           348:                        fputs("d\n", stdout);
        !           349:                else
        !           350:                        printf(" d %u\n", t-1);
        !           351:        }
        !           352:        if (rflag)
        !           353:                incr -= f2-f1+1;
        !           354: }
        !           355: 
        !           356: /*
        !           357:  * Output the middle of a set of
        !           358:  * changed lines.
        !           359:  */
        !           360: prsep()
        !           361: {
        !           362:        if (!sepflag)
        !           363:                return;
        !           364:        sepflag = 0;
        !           365:        if (csymbol != NULL)
        !           366:                fputs("#else\n", stdout);
        !           367:        else if (!eflag)
        !           368:                fputs("---\n", stdout);
        !           369: }
        !           370: 
        !           371: /*
        !           372:  * Output the end part of a set
        !           373:  * of changed lines.
        !           374:  */
        !           375: prend()
        !           376: {
        !           377:        if (csymbol != NULL)
        !           378:                fputs("#endif\n", stdout);
        !           379:        else if (caflag) {
        !           380:                if (sflag)
        !           381:                        putchar('\n');
        !           382:                else if (eflag)
        !           383:                        fputs(".\n", stdout);
        !           384:        }
        !           385:        caflag = 0;
        !           386: }
        !           387: 
        !           388: /*
        !           389:  * Print a line range either in the form
        !           390:  * `a,b' or `a' (if a==b).
        !           391:  */
        !           392: prange(a, b)
        !           393: register unsigned a, b;
        !           394: {
        !           395:        a += incr;
        !           396:        b += incr;
        !           397:        if (a == b)
        !           398:                printf("%u", a); else
        !           399:                printf("%u,%u", a, b);
        !           400: }
        !           401: 
        !           402: /*
        !           403:  * Exit, removing any possible temmpfiles.
        !           404:  */
        !           405: rmexit(s)
        !           406: {
        !           407:        if (tmpnam1 != NULL)
        !           408:                unlink(tmpnam1);
        !           409:        if (tmpnam2 != NULL)
        !           410:                unlink(tmpnam2);
        !           411:        exit(s);
        !           412: }
        !           413: 
        !           414: /*
        !           415:  * Catch signal and exit.
        !           416:  */
        !           417: catchsig()
        !           418: {
        !           419:        rmexit(2);
        !           420: }
        !           421: usage()
        !           422: {
        !           423:        fprintf(stderr, "Usage: diff [-bdefhs] [-c symbol] file1 file2\n");
        !           424:        exit(2);
        !           425: }
        !           426: 
        !           427: /* VARARGS */
        !           428: cerr(x)
        !           429: {
        !           430:        fprintf(stderr, "diff: %r\n", &x);
        !           431:        exit(2);
        !           432: }

unix.superglobalmegacorp.com

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