Annotation of researchv10no/cmd/idiff.c, revision 1.1.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.