|
|
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.