📄 cdiff.c
字号:
/* cdiff - context diff Author: Larry Wall *//* Cdiff - turns a regular diff into a new-style context diff * * Usage: cdiff file1 file2 */#define PATCHLEVEL 2#include <sys/types.h>#include <sys/stat.h>#include <sys/wait.h>#include <ctype.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <limits.h>#include <stdio.h>char buff[512];FILE *inputfp, *oldfp, *newfp;int oldmin, oldmax, newmin, newmax;int oldbeg, oldend, newbeg, newend;int preoldmax, prenewmax;int preoldbeg, preoldend, prenewbeg, prenewend;int oldwanted, newwanted;char *oldhunk, *newhunk;char *progname;size_t oldsize, oldalloc, newsize, newalloc;_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(void dumphunk, (void));_PROTOTYPE(char *getold, (int targ));_PROTOTYPE(char *getnew, (int targ));_PROTOTYPE(void *xmalloc, (size_t size));_PROTOTYPE(void *xrealloc, (void *ptr, size_t size));#define Nullfp (FILE*)0#define Nullch (char*)0#define ENOUGH (NAME_MAX + PATH_MAX + 1)#define CRC_END 12int main(argc, argv)int argc;char **argv;{ FILE *crcfp; char *old, *new; int context = 3; struct stat statbuf; register char *s; char op; char *newmark, *oldmark; char sysbuf1[ENOUGH], sysbuf2[ENOUGH]; int len; char *line; int i; int status; progname = argv[0]; oldalloc = 512; oldhunk = (char *) xmalloc(oldalloc); newalloc = 512; newhunk = (char *) xmalloc(newalloc); for (argc--, argv++; argc; argc--, argv++) { if (argv[0][0] != '-') break; if (argv[0][1] == 'c') context = atoi(argv[0] + 2); } if (argc != 2) { fprintf(stderr, "Usage: cdiff old new\n"); exit(2); } old = argv[0]; new = argv[1]; oldfp = fopen(old, "r"); if (!oldfp) { fprintf(stderr, "Can't open %s\n", old); exit(2); } newfp = fopen(new, "r"); if (!newfp) { fprintf(stderr, "Can't open %s\n", new); exit(2); } /* Compute crcs by popen()ing crc and reading the output. Do this before * popen()ing diff to do the work. popen() attempts to support multiple * clients, but the 1.3-1.6.24b versions don't succeed. */ sprintf(sysbuf1, "crc %s", old); crcfp = popen(sysbuf1, "r"); if (!crcfp) { /* The only advantage of cdiff over diff is that it prints crcs, so * give up easily if crc fails. */ fprintf(stderr, "Can't execute crc %s\n", old); exit(2); } fgets(sysbuf1, sizeof(sysbuf1), crcfp); sysbuf1[CRC_END] = '\0'; status = pclose(crcfp); if (status != 0) { fprintf(stderr, "crc %s returned bad status %d\n", old, status); exit(2); } sprintf(sysbuf2, "crc %s", new); crcfp = popen(sysbuf2, "r"); if (!crcfp) { fprintf(stderr, "Can't execute crc %s\n", new); exit(2); } fgets(sysbuf2, sizeof(sysbuf2), crcfp); sysbuf2[CRC_END] = '\0'; status = pclose(crcfp); if (status != 0) { fprintf(stderr, "crc %s returned bad status %d\n", new, status); exit(2); } sprintf(buff, "diff %s %s 2>/dev/null", old, new); inputfp = popen(buff, "r"); if (!inputfp) { fprintf(stderr, "Can't execute diff %s %s\n", old, new); exit(2); } fstat(fileno(oldfp), &statbuf); printf("*** %s crc=%s\t%s", old, sysbuf1, ctime(&statbuf.st_mtime)); fstat(fileno(newfp), &statbuf); printf("--- %s crc=%s\t%s", new, sysbuf2, ctime(&statbuf.st_mtime)); preoldend = -1000; while (fgets(buff, sizeof buff, inputfp) != Nullch) { if (isdigit(*buff)) { oldmin = atoi(buff); for (s = buff; isdigit(*s); s++); if (*s == ',') { s++; oldmax = atoi(s); for (; isdigit(*s); s++); } else { oldmax = oldmin; } if (*s != 'a' && *s != 'd' && *s != 'c') { fprintf(stderr, "Unparseable input: %s\n", s); exit(2); } op = *s; s++; newmin = atoi(s); for (; isdigit(*s); s++); if (*s == ',') { s++; newmax = atoi(s); for (; isdigit(*s); s++); } else { newmax = newmin; } if (*s != '\n' && *s != ' ') { fprintf(stderr, "Unparseable input: %s\n", s); exit(2); } newmark = oldmark = "! "; if (op == 'a') { oldmin++; newmark = "+ "; } if (op == 'd') { newmin++; oldmark = "- "; } oldbeg = oldmin - context; oldend = oldmax + context; if (oldbeg < 1) oldbeg = 1; newbeg = newmin - context; newend = newmax + context; if (newbeg < 1) newbeg = 1; if (preoldend < oldbeg - 1) { if (preoldend >= 0) { dumphunk(); } preoldbeg = oldbeg; prenewbeg = newbeg; oldwanted = newwanted = 0; oldsize = newsize = 0; } else { /* we want to append to previous hunk */ oldbeg = preoldmax + 1; newbeg = prenewmax + 1; } for (i = oldbeg; i <= oldmax; i++) { line = getold(i); if (!line) { oldend = oldmax = i - 1; break; } len = strlen(line) + 2; if (oldsize + len + 1 >= oldalloc) { oldalloc *= 2; oldhunk = (char *) xrealloc(oldhunk, oldalloc); } if (i >= oldmin) { strcpy(oldhunk + oldsize, oldmark); oldwanted++; } else { strcpy(oldhunk + oldsize, " "); } strcpy(oldhunk + oldsize + 2, line); oldsize += len; } preoldmax = oldmax; preoldend = oldend; for (i = newbeg; i <= newmax; i++) { line = getnew(i); if (!line) { newend = newmax = i - 1; break; } len = strlen(line) + 2; if (newsize + len + 1 >= newalloc) { newalloc *= 2; newhunk = (char *) xrealloc(newhunk, newalloc); } if (i >= newmin) { strcpy(newhunk + newsize, newmark); newwanted++; } else { strcpy(newhunk + newsize, " "); } strcpy(newhunk + newsize + 2, line); newsize += len; } prenewmax = newmax; prenewend = newend; } } if (preoldend >= 0) { dumphunk(); } status = pclose(inputfp); if (!WIFEXITED(status)) exit(2); status = WEXITSTATUS(status); return(status == 0 || status == 1 ? status : 2);}void dumphunk(){ int i; char *line; int len; for (i = preoldmax + 1; i <= preoldend; i++) { line = getold(i); if (!line) { preoldend = i - 1; break; } len = strlen(line) + 2; if (oldsize + len + 1 >= oldalloc) { oldalloc *= 2; oldhunk = (char *) xrealloc(oldhunk, oldalloc); } strcpy(oldhunk + oldsize, " "); strcpy(oldhunk + oldsize + 2, line); oldsize += len; } for (i = prenewmax + 1; i <= prenewend; i++) { line = getnew(i); if (!line) { prenewend = i - 1; break; } len = strlen(line) + 2; if (newsize + len + 1 >= newalloc) { newalloc *= 2; newhunk = (char *) xrealloc(newhunk, newalloc); } strcpy(newhunk + newsize, " "); strcpy(newhunk + newsize + 2, line); newsize += len; } printf("***************\n"); if (preoldbeg >= preoldend) { printf("*** %d ****\n", preoldend); } else { printf("*** %d,%d ****\n", preoldbeg, preoldend); } if (oldwanted) { printf("%s", oldhunk); } oldsize = 0; *oldhunk = '\0'; if (prenewbeg >= prenewend) { printf("--- %d ----\n", prenewend); } else { printf("--- %d,%d ----\n", prenewbeg, prenewend); } if (newwanted) { printf("%s", newhunk); } newsize = 0; *newhunk = '\0';}char *getold(targ)int targ;{ static int oldline = 0; while (fgets(buff, sizeof buff, oldfp) != Nullch) { oldline++; if (oldline == targ) return buff; } return Nullch;}char *getnew(targ)int targ;{ static int newline = 0; while (fgets(buff, sizeof buff, newfp) != Nullch) { newline++; if (newline == targ) return buff; } return Nullch;}void *xmalloc(size)size_t size;{ void *ptr; ptr = malloc(size); if (ptr == NULL) { fprintf(stderr, "%s: out of memory\n", progname); exit(2); } return(ptr);}void *xrealloc(ptr, size)void *ptr;size_t size;{ ptr = realloc(ptr, size); if (ptr == NULL) { fprintf(stderr, "%s: out of memory\n", progname); exit(2); } return(ptr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -