|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.