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