1 /* cdiff - context diff Author: Larry Wall */
3 /* Cdiff - turns a regular diff into a new-style context diff
5 * Usage: cdiff file1 file2
10 #include <sys/types.h>
24 FILE *inputfp
, *oldfp
, *newfp
;
26 int oldmin
, oldmax
, newmin
, newmax
;
27 int oldbeg
, oldend
, newbeg
, newend
;
28 int preoldmax
, prenewmax
;
29 int preoldbeg
, preoldend
, prenewbeg
, prenewend
;
30 int oldwanted
, newwanted
;
32 char *oldhunk
, *newhunk
;
34 size_t oldsize
, oldalloc
, newsize
, newalloc
;
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
));
43 #define Nullfp (FILE*)0
44 #define Nullch (char*)0
45 #define ENOUGH (NAME_MAX + PATH_MAX + 1)
58 char *newmark
, *oldmark
;
59 char sysbuf1
[ENOUGH
], sysbuf2
[ENOUGH
];
67 oldhunk
= (char *) xmalloc(oldalloc
);
69 newhunk
= (char *) xmalloc(newalloc
);
71 for (argc
--, argv
++; argc
; argc
--, argv
++) {
72 if (argv
[0][0] != '-') break;
74 if (argv
[0][1] == 'c') context
= atoi(argv
[0] + 2);
78 fprintf(stderr
, "Usage: cdiff old new\n");
84 oldfp
= fopen(old
, "r");
86 fprintf(stderr
, "Can't open %s\n", old
);
89 newfp
= fopen(new, "r");
91 fprintf(stderr
, "Can't open %s\n", new);
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.
99 sprintf(sysbuf1
, "crc %s", old
);
100 crcfp
= popen(sysbuf1
, "r");
102 /* The only advantage of cdiff over diff is that it prints crcs, so
103 * give up easily if crc fails.
105 fprintf(stderr
, "Can't execute crc %s\n", old
);
108 fgets(sysbuf1
, sizeof(sysbuf1
), crcfp
);
109 sysbuf1
[CRC_END
] = '\0';
110 status
= pclose(crcfp
);
112 fprintf(stderr
, "crc %s returned bad status %d\n", old
, status
);
115 sprintf(sysbuf2
, "crc %s", new);
116 crcfp
= popen(sysbuf2
, "r");
118 fprintf(stderr
, "Can't execute crc %s\n", new);
121 fgets(sysbuf2
, sizeof(sysbuf2
), crcfp
);
122 sysbuf2
[CRC_END
] = '\0';
123 status
= pclose(crcfp
);
125 fprintf(stderr
, "crc %s returned bad status %d\n", new, status
);
129 sprintf(buff
, "diff %s %s 2>/dev/null", old
, new);
130 inputfp
= popen(buff
, "r");
132 fprintf(stderr
, "Can't execute diff %s %s\n", old
, new);
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
));
143 while (fgets(buff
, sizeof buff
, inputfp
) != Nullch
) {
144 if (isdigit(*buff
)) {
146 for (s
= buff
; isdigit(*s
); s
++);
150 for (; isdigit(*s
); s
++);
154 if (*s
!= 'a' && *s
!= 'd' && *s
!= 'c') {
155 fprintf(stderr
, "Unparseable input: %s\n", s
);
161 for (; isdigit(*s
); s
++);
165 for (; isdigit(*s
); s
++);
169 if (*s
!= '\n' && *s
!= ' ') {
170 fprintf(stderr
, "Unparseable input: %s\n", s
);
173 newmark
= oldmark
= "! ";
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;
189 if (preoldend
< oldbeg
- 1) {
190 if (preoldend
>= 0) {
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;
202 for (i
= oldbeg
; i
<= oldmax
; i
++) {
205 oldend
= oldmax
= i
- 1;
208 len
= strlen(line
) + 2;
209 if (oldsize
+ len
+ 1 >= oldalloc
) {
211 oldhunk
= (char *) xrealloc(oldhunk
, oldalloc
);
214 strcpy(oldhunk
+ oldsize
, oldmark
);
217 strcpy(oldhunk
+ oldsize
, " ");
219 strcpy(oldhunk
+ oldsize
+ 2, line
);
225 for (i
= newbeg
; i
<= newmax
; i
++) {
228 newend
= newmax
= i
- 1;
231 len
= strlen(line
) + 2;
232 if (newsize
+ len
+ 1 >= newalloc
) {
234 newhunk
= (char *) xrealloc(newhunk
, newalloc
);
237 strcpy(newhunk
+ newsize
, newmark
);
240 strcpy(newhunk
+ newsize
, " ");
242 strcpy(newhunk
+ newsize
+ 2, line
);
250 if (preoldend
>= 0) {
253 status
= pclose(inputfp
);
254 if (!WIFEXITED(status
)) exit(2);
255 status
= WEXITSTATUS(status
);
256 return(status
== 0 || status
== 1 ? status
: 2);
265 for (i
= preoldmax
+ 1; i
<= preoldend
; i
++) {
271 len
= strlen(line
) + 2;
272 if (oldsize
+ len
+ 1 >= oldalloc
) {
274 oldhunk
= (char *) xrealloc(oldhunk
, oldalloc
);
276 strcpy(oldhunk
+ oldsize
, " ");
277 strcpy(oldhunk
+ oldsize
+ 2, line
);
280 for (i
= prenewmax
+ 1; i
<= prenewend
; i
++) {
286 len
= strlen(line
) + 2;
287 if (newsize
+ len
+ 1 >= newalloc
) {
289 newhunk
= (char *) xrealloc(newhunk
, newalloc
);
291 strcpy(newhunk
+ newsize
, " ");
292 strcpy(newhunk
+ newsize
+ 2, line
);
295 printf("***************\n");
296 if (preoldbeg
>= preoldend
) {
297 printf("*** %d ****\n", preoldend
);
299 printf("*** %d,%d ****\n", preoldbeg
, preoldend
);
302 printf("%s", oldhunk
);
306 if (prenewbeg
>= prenewend
) {
307 printf("--- %d ----\n", prenewend
);
309 printf("--- %d,%d ----\n", prenewbeg
, prenewend
);
312 printf("%s", newhunk
);
321 static int oldline
= 0;
323 while (fgets(buff
, sizeof buff
, oldfp
) != Nullch
) {
325 if (oldline
== targ
) return buff
;
333 static int newline
= 0;
335 while (fgets(buff
, sizeof buff
, newfp
) != Nullch
) {
337 if (newline
== targ
) return buff
;
349 fprintf(stderr
, "%s: out of memory\n", progname
);
355 void *xrealloc(ptr
, size
)
359 ptr
= realloc(ptr
, size
);
361 fprintf(stderr
, "%s: out of memory\n", progname
);