⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdiff.c

📁 操作系统源代码
💻 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 + -