Annotation of researchv10no/cmd/idiff.c, revision 1.1

1.1     ! root        1: /* idiff:  interactive diff */
        !             2: 
        !             3: #include <stdio.h>
        !             4: #include <stdlib.h>
        !             5: #include <ctype.h>
        !             6: #include <string.h>
        !             7: #include <signal.h>
        !             8: #include <sys/types.h>
        !             9: #include <sys/stat.h>
        !            10: 
        !            11: #define        HUGE    10000   /* large number of lines */
        !            12: 
        !            13: char   *progname;
        !            14: char   diffout[100];
        !            15: char   tempfile[100];
        !            16: char   *outfile = "idiff.out";
        !            17: 
        !            18: FILE   *efopen(char *, char *);
        !            19: char   *basename(char *);
        !            20: void idiff(FILE *f1, FILE *f2, FILE *fin, FILE *fout);
        !            21: void parse(char *s, int *pfrom1, int *pto1, int *pcmd, int *pfrom2, int *pto2);
        !            22: void nskip(FILE *fin, int n);
        !            23: void ncopy(FILE *fin, int n, FILE *fout);
        !            24: void cleanup(int);
        !            25: 
        !            26: /* these have to be undone in a non-posix world: */
        !            27: 
        !            28: /* int fileno(FILE *); */
        !            29: #define        S_ISDIR(n)      ((n) & S_IFDIR) /* vaxes */
        !            30: #define        remove unlink
        !            31: 
        !            32: main(int argc, char *argv[])
        !            33: {
        !            34:        FILE *fin, *fout, *f1, *f2;
        !            35:        char buf[BUFSIZ], diffopts[100], *p;
        !            36:        struct stat stbuf;
        !            37: 
        !            38:        progname = argv[0];
        !            39:        buf[0] = 0;
        !            40:        while (argc > 3 && argv[1][0] == '-') { /* assume all flags go to diff for now */
        !            41:                strcat(diffopts, argv[1]);
        !            42:                strcat(diffopts, " ");
        !            43:                argv++;
        !            44:                argc--;
        !            45:        }
        !            46:        if (argc != 3) {
        !            47:                fprintf(stderr, "Usage: idiff [-opts] file1 file2\n");
        !            48:                exit(1);
        !            49:        }
        !            50:        f1 = efopen(argv[1], "r");
        !            51:        f2 = efopen(argv[2], "r");
        !            52:        fstat(fileno(f2), &stbuf);
        !            53:        if (S_ISDIR(stbuf.st_mode)) {
        !            54:                fclose(f2);
        !            55:                sprintf(buf, "%s/%s", argv[2], basename(argv[1]));
        !            56:                f2 = efopen(buf, "r");
        !            57:        }
        !            58:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
        !            59:                signal(SIGINT, cleanup);
        !            60:        fout = efopen(outfile, "w");
        !            61:        tmpnam(diffout);
        !            62:        sprintf(buf,"diff %s %s %s >%s", diffopts, argv[1], argv[2], diffout);
        !            63:        system(buf);
        !            64:        fin = efopen(diffout, "r");
        !            65:        tmpnam(tempfile);
        !            66:        idiff(f1, f2, fin, fout);
        !            67:        remove(diffout);
        !            68:        printf("%s output in file %s\n", progname, outfile);
        !            69:        exit(0);
        !            70: }
        !            71: 
        !            72: void cleanup(int i)
        !            73: {
        !            74:        remove(diffout);
        !            75:        remove(tempfile);
        !            76:        remove(outfile);
        !            77:        exit(1);
        !            78: }
        !            79: 
        !            80: char *basename(char *s)        /* find last component of filename */
        !            81: {
        !            82:        static char *p;
        !            83: 
        !            84:        for (p = s+strlen(s)-1; p >= s; p--)
        !            85:                if (*p == '/')
        !            86:                        return p+1;
        !            87:        return s;
        !            88: }
        !            89: 
        !            90: void idiff(FILE *f1, FILE *f2, FILE *fin, FILE *fout)  /* process diffs */
        !            91: {
        !            92:        char buf[BUFSIZ], buf2[BUFSIZ];
        !            93:        FILE *ft;
        !            94:        int cmd, n, from1, to1, from2, to2, nf1, nf2, done;
        !            95: 
        !            96:        nf1 = nf2 = 0;
        !            97:        done = 0;
        !            98:        while (!done && fgets(buf, sizeof buf, fin) != NULL) {
        !            99:                parse(buf, &from1, &to1, &cmd, &from2, &to2);
        !           100:                n = to1-from1 + to2-from2 + 1; /* #lines from diff */
        !           101:                if (cmd == 'c')
        !           102:                        n += 2;
        !           103:                else if (cmd == 'a')
        !           104:                        from1++;
        !           105:                else if (cmd == 'd')
        !           106:                        from2++;
        !           107:                printf("%s", buf);
        !           108:                while (n-- > 0) {
        !           109:                        fgets(buf, sizeof buf, fin);
        !           110:                        printf("%s", buf);
        !           111:                }
        !           112:                for(;;) {
        !           113:                        printf("? ");
        !           114:                        fflush(stdout);
        !           115:                        fgets(buf, sizeof buf, stdin);
        !           116:                        switch (buf[0]) {
        !           117:                        case '2':
        !           118:                                to1 = to2 = HUGE;
        !           119:                                done = 1;
        !           120:                        case '>':
        !           121:                                nskip(f1, to1-nf1);
        !           122:                                ncopy(f2, to2-nf2, fout);
        !           123:                                break;
        !           124:                        case '1':
        !           125:                                to1 = to2 = HUGE;
        !           126:                                done = 1;
        !           127:                        case '<':
        !           128:                                nskip(f2, to2-nf2);
        !           129:                                ncopy(f1, to1-nf1, fout);
        !           130:                                break;
        !           131:                        case 'e':
        !           132:                                ncopy(f1, from1-1-nf1, fout);
        !           133:                                nskip(f2, from2-1-nf2);
        !           134:                                ft = efopen(tempfile, "w");
        !           135:                                ncopy(f1, to1+1-from1, ft);
        !           136:                                fprintf(ft, "---\n");
        !           137:                                ncopy(f2, to2+1-from2, ft);
        !           138:                                fclose(ft);
        !           139:                                sprintf(buf2, "ed %s", tempfile);       
        !           140:                                system(buf2);
        !           141:                                ft = efopen(tempfile, "r");
        !           142:                                ncopy(ft, HUGE, fout);
        !           143:                                fclose(ft);
        !           144:                                break;
        !           145:                        case '!':
        !           146:                                system(buf+1);
        !           147:                                printf("!\n");
        !           148:                                break;
        !           149:                        case 'd':
        !           150:                                nskip(f1, to1-nf1);
        !           151:                                nskip(f2, to2-nf2);
        !           152:                                break;
        !           153:                        default:
        !           154:                                printf("< > d e 1 2 !\n");
        !           155:                                continue;
        !           156:                        }
        !           157:                        break;
        !           158:                }
        !           159:                nf1 = to1;
        !           160:                nf2 = to2;
        !           161:        }
        !           162:        ncopy(f1, HUGE, fout);  /* can fail on very long files */
        !           163:        remove(tempfile);
        !           164: }
        !           165: 
        !           166: void parse(char *s, int *pfrom1, int *pto1, int *pcmd, int *pfrom2, int *pto2)
        !           167: {
        !           168: #define a2i(p) while (isdigit(*s)) p = 10*(p) + *s++ - '0'
        !           169: 
        !           170:        *pfrom1 = *pto1 = *pfrom2 = *pto2 = 0;
        !           171:        a2i(*pfrom1);
        !           172:        if (*s == ',') {
        !           173:                s++;
        !           174:                a2i(*pto1);
        !           175:        } else
        !           176:                *pto1 = *pfrom1;
        !           177:        *pcmd = *s++;
        !           178:        a2i(*pfrom2);
        !           179:        if (*s == ',') {
        !           180:                s++;
        !           181:                a2i(*pto2);
        !           182:        } else
        !           183:                *pto2 = *pfrom2;
        !           184: }
        !           185: 
        !           186: void nskip(FILE *fin, int n)   /* skip n lines of file fin */
        !           187: {
        !           188:        char buf[BUFSIZ];
        !           189: 
        !           190:        while (n-- > 0)
        !           191:                fgets(buf, sizeof buf, fin);
        !           192: }
        !           193: 
        !           194: void ncopy(FILE *fin, int n, FILE *fout)       /* copy n lines from fin to fout */
        !           195: {
        !           196:        char buf[BUFSIZ];
        !           197: 
        !           198:        while (n-- > 0) {
        !           199:                if (fgets(buf, sizeof buf, fin) == NULL)
        !           200:                        return;
        !           201:                fputs(buf, fout);
        !           202:        }
        !           203: }
        !           204: 
        !           205: FILE *efopen(char *file, char *mode)   /* fopen file, die if can't */
        !           206: {
        !           207:        FILE *fp;
        !           208:        extern char *progname;
        !           209: 
        !           210:        if ((fp = fopen(file, mode)) != NULL)
        !           211:                return fp;
        !           212:        fprintf(stderr, "%s: can't open file %s mode %s\n",
        !           213:                progname, file, mode);
        !           214:        exit(1);
        !           215: }

unix.superglobalmegacorp.com

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