source: trunk/minix/commands/simple/cdiff.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 7.5 KB
Line 
1/* cdiff - context diff Author: Larry Wall */
2
3/* Cdiff - turns a regular diff into a new-style context diff
4 *
5 * Usage: cdiff file1 file2
6 */
7
8#define PATCHLEVEL 2
9
10#include <sys/types.h>
11#include <sys/stat.h>
12#include <sys/wait.h>
13#include <ctype.h>
14#include <fcntl.h>
15#include <stdlib.h>
16#include <string.h>
17#include <time.h>
18#include <unistd.h>
19#include <limits.h>
20#include <stdio.h>
21
22char buff[512];
23
24FILE *inputfp, *oldfp, *newfp;
25
26int oldmin, oldmax, newmin, newmax;
27int oldbeg, oldend, newbeg, newend;
28int preoldmax, prenewmax;
29int preoldbeg, preoldend, prenewbeg, prenewend;
30int oldwanted, newwanted;
31
32char *oldhunk, *newhunk;
33char *progname;
34size_t oldsize, oldalloc, newsize, newalloc;
35
36_PROTOTYPE(int main, (int argc, char **argv));
37_PROTOTYPE(void dumphunk, (void));
38_PROTOTYPE(char *getold, (int targ));
39_PROTOTYPE(char *getnew, (int targ));
40_PROTOTYPE(void *xmalloc, (size_t size));
41_PROTOTYPE(void *xrealloc, (void *ptr, size_t size));
42
43#define Nullfp (FILE*)0
44#define Nullch (char*)0
45#define ENOUGH (NAME_MAX + PATH_MAX + 1)
46#define CRC_END 12
47
48int main(argc, argv)
49int argc;
50char **argv;
51{
52 FILE *crcfp;
53 char *old, *new;
54 int context = 3;
55 struct stat statbuf;
56 register char *s;
57 char op;
58 char *newmark, *oldmark;
59 char sysbuf1[ENOUGH], sysbuf2[ENOUGH];
60 int len;
61 char *line;
62 int i;
63 int status;
64
65 progname = argv[0];
66 oldalloc = 512;
67 oldhunk = (char *) xmalloc(oldalloc);
68 newalloc = 512;
69 newhunk = (char *) xmalloc(newalloc);
70
71 for (argc--, argv++; argc; argc--, argv++) {
72 if (argv[0][0] != '-') break;
73
74 if (argv[0][1] == 'c') context = atoi(argv[0] + 2);
75 }
76
77 if (argc != 2) {
78 fprintf(stderr, "Usage: cdiff old new\n");
79 exit(2);
80 }
81 old = argv[0];
82 new = argv[1];
83
84 oldfp = fopen(old, "r");
85 if (!oldfp) {
86 fprintf(stderr, "Can't open %s\n", old);
87 exit(2);
88 }
89 newfp = fopen(new, "r");
90 if (!newfp) {
91 fprintf(stderr, "Can't open %s\n", new);
92 exit(2);
93 }
94
95 /* Compute crcs by popen()ing crc and reading the output. Do this before
96 * popen()ing diff to do the work. popen() attempts to support multiple
97 * clients, but the 1.3-1.6.24b versions don't succeed.
98 */
99 sprintf(sysbuf1, "crc %s", old);
100 crcfp = popen(sysbuf1, "r");
101 if (!crcfp) {
102 /* The only advantage of cdiff over diff is that it prints crcs, so
103 * give up easily if crc fails.
104 */
105 fprintf(stderr, "Can't execute crc %s\n", old);
106 exit(2);
107 }
108 fgets(sysbuf1, sizeof(sysbuf1), crcfp);
109 sysbuf1[CRC_END] = '\0';
110 status = pclose(crcfp);
111 if (status != 0) {
112 fprintf(stderr, "crc %s returned bad status %d\n", old, status);
113 exit(2);
114 }
115 sprintf(sysbuf2, "crc %s", new);
116 crcfp = popen(sysbuf2, "r");
117 if (!crcfp) {
118 fprintf(stderr, "Can't execute crc %s\n", new);
119 exit(2);
120 }
121 fgets(sysbuf2, sizeof(sysbuf2), crcfp);
122 sysbuf2[CRC_END] = '\0';
123 status = pclose(crcfp);
124 if (status != 0) {
125 fprintf(stderr, "crc %s returned bad status %d\n", new, status);
126 exit(2);
127 }
128
129 sprintf(buff, "diff %s %s 2>/dev/null", old, new);
130 inputfp = popen(buff, "r");
131 if (!inputfp) {
132 fprintf(stderr, "Can't execute diff %s %s\n", old, new);
133 exit(2);
134 }
135
136 fstat(fileno(oldfp), &statbuf);
137 printf("*** %s crc=%s\t%s", old, sysbuf1, ctime(&statbuf.st_mtime));
138 fstat(fileno(newfp), &statbuf);
139 printf("--- %s crc=%s\t%s", new, sysbuf2, ctime(&statbuf.st_mtime));
140
141 preoldend = -1000;
142
143 while (fgets(buff, sizeof buff, inputfp) != Nullch) {
144 if (isdigit(*buff)) {
145 oldmin = atoi(buff);
146 for (s = buff; isdigit(*s); s++);
147 if (*s == ',') {
148 s++;
149 oldmax = atoi(s);
150 for (; isdigit(*s); s++);
151 } else {
152 oldmax = oldmin;
153 }
154 if (*s != 'a' && *s != 'd' && *s != 'c') {
155 fprintf(stderr, "Unparseable input: %s\n", s);
156 exit(2);
157 }
158 op = *s;
159 s++;
160 newmin = atoi(s);
161 for (; isdigit(*s); s++);
162 if (*s == ',') {
163 s++;
164 newmax = atoi(s);
165 for (; isdigit(*s); s++);
166 } else {
167 newmax = newmin;
168 }
169 if (*s != '\n' && *s != ' ') {
170 fprintf(stderr, "Unparseable input: %s\n", s);
171 exit(2);
172 }
173 newmark = oldmark = "! ";
174 if (op == 'a') {
175 oldmin++;
176 newmark = "+ ";
177 }
178 if (op == 'd') {
179 newmin++;
180 oldmark = "- ";
181 }
182 oldbeg = oldmin - context;
183 oldend = oldmax + context;
184 if (oldbeg < 1) oldbeg = 1;
185 newbeg = newmin - context;
186 newend = newmax + context;
187 if (newbeg < 1) newbeg = 1;
188
189 if (preoldend < oldbeg - 1) {
190 if (preoldend >= 0) {
191 dumphunk();
192 }
193 preoldbeg = oldbeg;
194 prenewbeg = newbeg;
195 oldwanted = newwanted = 0;
196 oldsize = newsize = 0;
197 } else { /* we want to append to previous hunk */
198 oldbeg = preoldmax + 1;
199 newbeg = prenewmax + 1;
200 }
201
202 for (i = oldbeg; i <= oldmax; i++) {
203 line = getold(i);
204 if (!line) {
205 oldend = oldmax = i - 1;
206 break;
207 }
208 len = strlen(line) + 2;
209 if (oldsize + len + 1 >= oldalloc) {
210 oldalloc *= 2;
211 oldhunk = (char *) xrealloc(oldhunk, oldalloc);
212 }
213 if (i >= oldmin) {
214 strcpy(oldhunk + oldsize, oldmark);
215 oldwanted++;
216 } else {
217 strcpy(oldhunk + oldsize, " ");
218 }
219 strcpy(oldhunk + oldsize + 2, line);
220 oldsize += len;
221 }
222 preoldmax = oldmax;
223 preoldend = oldend;
224
225 for (i = newbeg; i <= newmax; i++) {
226 line = getnew(i);
227 if (!line) {
228 newend = newmax = i - 1;
229 break;
230 }
231 len = strlen(line) + 2;
232 if (newsize + len + 1 >= newalloc) {
233 newalloc *= 2;
234 newhunk = (char *) xrealloc(newhunk, newalloc);
235 }
236 if (i >= newmin) {
237 strcpy(newhunk + newsize, newmark);
238 newwanted++;
239 } else {
240 strcpy(newhunk + newsize, " ");
241 }
242 strcpy(newhunk + newsize + 2, line);
243 newsize += len;
244 }
245 prenewmax = newmax;
246 prenewend = newend;
247 }
248 }
249
250 if (preoldend >= 0) {
251 dumphunk();
252 }
253 status = pclose(inputfp);
254 if (!WIFEXITED(status)) exit(2);
255 status = WEXITSTATUS(status);
256 return(status == 0 || status == 1 ? status : 2);
257}
258
259void dumphunk()
260{
261 int i;
262 char *line;
263 int len;
264
265 for (i = preoldmax + 1; i <= preoldend; i++) {
266 line = getold(i);
267 if (!line) {
268 preoldend = i - 1;
269 break;
270 }
271 len = strlen(line) + 2;
272 if (oldsize + len + 1 >= oldalloc) {
273 oldalloc *= 2;
274 oldhunk = (char *) xrealloc(oldhunk, oldalloc);
275 }
276 strcpy(oldhunk + oldsize, " ");
277 strcpy(oldhunk + oldsize + 2, line);
278 oldsize += len;
279 }
280 for (i = prenewmax + 1; i <= prenewend; i++) {
281 line = getnew(i);
282 if (!line) {
283 prenewend = i - 1;
284 break;
285 }
286 len = strlen(line) + 2;
287 if (newsize + len + 1 >= newalloc) {
288 newalloc *= 2;
289 newhunk = (char *) xrealloc(newhunk, newalloc);
290 }
291 strcpy(newhunk + newsize, " ");
292 strcpy(newhunk + newsize + 2, line);
293 newsize += len;
294 }
295 printf("***************\n");
296 if (preoldbeg >= preoldend) {
297 printf("*** %d ****\n", preoldend);
298 } else {
299 printf("*** %d,%d ****\n", preoldbeg, preoldend);
300 }
301 if (oldwanted) {
302 printf("%s", oldhunk);
303 }
304 oldsize = 0;
305 *oldhunk = '\0';
306 if (prenewbeg >= prenewend) {
307 printf("--- %d ----\n", prenewend);
308 } else {
309 printf("--- %d,%d ----\n", prenewbeg, prenewend);
310 }
311 if (newwanted) {
312 printf("%s", newhunk);
313 }
314 newsize = 0;
315 *newhunk = '\0';
316}
317
318char *getold(targ)
319int targ;
320{
321 static int oldline = 0;
322
323 while (fgets(buff, sizeof buff, oldfp) != Nullch) {
324 oldline++;
325 if (oldline == targ) return buff;
326 }
327 return Nullch;
328}
329
330char *getnew(targ)
331int targ;
332{
333 static int newline = 0;
334
335 while (fgets(buff, sizeof buff, newfp) != Nullch) {
336 newline++;
337 if (newline == targ) return buff;
338 }
339 return Nullch;
340}
341
342void *xmalloc(size)
343size_t size;
344{
345 void *ptr;
346
347 ptr = malloc(size);
348 if (ptr == NULL) {
349 fprintf(stderr, "%s: out of memory\n", progname);
350 exit(2);
351 }
352 return(ptr);
353}
354
355void *xrealloc(ptr, size)
356void *ptr;
357size_t size;
358{
359 ptr = realloc(ptr, size);
360 if (ptr == NULL) {
361 fprintf(stderr, "%s: out of memory\n", progname);
362 exit(2);
363 }
364 return(ptr);
365}
Note: See TracBrowser for help on using the repository browser.