diffreg.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,111 行 · 第 1/2 页

C
1,111
字号
					} while(isspace(d=getc(input[1])));				} else if ( wflag ) {					while( isspace(c) && c!='\n' ) {						c=getc(input[0]);						ctold++;					}					while( isspace(d) && d!='\n' ) {						d=getc(input[1]);						ctnew++;					}				}				if(chrtran[c] != chrtran[d]) {					jackpot++;					J[i] = 0;					if(c!='\n')						ctold += skipline(0);					if(d!='\n')						ctnew += skipline(1);					break;				}				if(c=='\n')					break;			}		} else {			for(;;) {				ctold++;				ctnew++;				if((c=getc(input[0])) != (d=getc(input[1]))) {					/* jackpot++; */					J[i] = 0;					if(c!='\n')						ctold += skipline(0);					if(d!='\n')						ctnew += skipline(1);					break;				}				if(c=='\n')					break;			}		}		ixold[i] = ctold;		ixnew[j] = ctnew;		j++;	}	for(;j<=len[1];j++) {		ixnew[j] = ctnew += skipline(1);	}	fclose(input[0]);	fclose(input[1]);/*	if(jackpot)		fprintf(stderr, "jackpot\n");*/}sort(a,n)	/*shellsort CACM #201*/struct line *a;{	register struct line w;	register int j,m;	register struct line *ai;	register struct line *aim;	int k;	if (n == 0)		return;	for(j=1;j<=n;j*= 2)		m = 2*j - 1;	for(m/=2;m!=0;m/=2) {		k = n-m;		for(j=1;j<=k;j++) {			for(ai = &a[j]; ai > a; ai -= m) {				aim = &ai[m];				if(aim < ai)					break;	/*wraparound*/				if(aim->value > ai->value ||				   aim->value == ai->value &&				   aim->serial > ai->serial)					break;				w    = *ai;				*ai  = *aim;				*aim = w;			}		}	}}unsort(f, l, b)struct line *f;int *b;{	register int *a;	register int i;	a = (int *)talloc((l+1)*sizeof(int));	for(i=1;i<=l;i++)		a[f[i].serial] = f[i].value;	for(i=1;i<=l;i++)		b[i] = a[i];	free((char *)a);}skipline(f){	register i, c;	for(i=1;(c=getc(input[f]))!='\n';i++)		if (c < 0)			return(i);	return(i);}output(){	int m;	register int i0, i1, j1;	int j0;	input[0] = fopen(file1,"r");	input[1] = fopen(file2,"r");	m = len[0];	J[0] = 0;	J[m+1] = len[1]+1;	if(opt!=D_EDIT) for(i0=1;i0<=m;i0=i1+1) {		while(i0<=m&&J[i0]==J[i0-1]+1) i0++;		j0 = J[i0-1]+1;		i1 = i0-1;		while(i1<m&&J[i1+1]==0) i1++;		j1 = J[i1+1]-1;		J[i1] = j1;		change(i0,i1,j0,j1);	} else for(i0=m;i0>=1;i0=i1-1) {		while(i0>=1&&J[i0]==J[i0+1]-1&&J[i0]!=0) i0--;		j0 = J[i0+1]-1;		i1 = i0+1;		while(i1>1&&J[i1-1]==0) i1--;		j1 = J[i1-1]+1;		J[i1] = j1;		change(i1,i0,j1,j0);	}	if(m==0)		change(1,0,1,len[1]);	if (opt==D_IFDEF) {		for (;;) {#define	c i0			c = getc(input[0]);			if (c < 0)				return;			putchar(c);		}#undef c	}	if (anychange && opt == D_CONTEXT)		dump_context_vec();}/* * The following struct is used to record change information when * doing a "context" diff.  (see routine "change" to understand the * highly mneumonic field names) */struct context_vec {	int	a;	/* start line in old file */	int	b;	/* end line in old file */	int	c;	/* start line in new file */	int	d;	/* end line in new file */};struct	context_vec	*context_vec_start,			*context_vec_end,			*context_vec_ptr;#define	MAX_CONTEXT	128/* indicate that there is a difference between lines a and b of the from file   to get to lines c to d of the to file.   If a is greater then b then there are no lines in the from file involved   and this means that there were lines appended (beginning at b).   If c is greater than d then there are lines missing from the to file.*/change(a,b,c,d){	int ch;	int lowa,upb,lowc,upd;	struct stat stbuf;	if (opt != D_IFDEF && a>b && c>d)		return;	if (anychange == 0) {		anychange = 1;		if(opt == D_CONTEXT) {			printf("*** %s	", file1);			stat(file1, &stbuf);			printf("%s--- %s	",			    ctime(&stbuf.st_mtime), file2);			stat(file2, &stbuf);			printf("%s", ctime(&stbuf.st_mtime));			context_vec_start = (struct context_vec *) 						malloc(MAX_CONTEXT *						   sizeof(struct context_vec));			context_vec_end = context_vec_start + MAX_CONTEXT;			context_vec_ptr = context_vec_start - 1;		}	}	if (a <= b && c <= d)		ch = 'c';	else		ch = (a <= b) ? 'd' : 'a';	if(opt == D_CONTEXT) {		/*		 * if this new change is within 'context' lines of		 * the previous change, just add it to the change		 * record.  If the record is full or if this		 * change is more than 'context' lines from the previous		 * change, dump the record, reset it & add the new change.		 */		if ( context_vec_ptr >= context_vec_end ||		     ( context_vec_ptr >= context_vec_start &&		       a > (context_vec_ptr->b + 2*context) &&		       c > (context_vec_ptr->d + 2*context) ) )			dump_context_vec();		context_vec_ptr++;		context_vec_ptr->a = a;		context_vec_ptr->b = b;		context_vec_ptr->c = c;		context_vec_ptr->d = d;		return;	}	switch (opt) {	case D_NORMAL:	case D_EDIT:		range(a,b,",");		putchar(a>b?'a':c>d?'d':'c');		if(opt==D_NORMAL)			range(c,d,",");		putchar('\n');		break;	case D_REVERSE:		putchar(a>b?'a':c>d?'d':'c');		range(a,b," ");		putchar('\n');		break;        case D_NREVERSE:                if (a>b)                        printf("a%d %d\n",b,d-c+1);                else {                        printf("d%d %d\n",a,b-a+1);                        if (!(c>d))                           /* add changed lines */                           printf("a%d %d\n",b, d-c+1);                }                break;	}	if(opt == D_NORMAL || opt == D_IFDEF) {		fetch(ixold,a,b,input[0],"< ", 1);		if(a<=b&&c<=d && opt == D_NORMAL)			prints("---\n");	}	fetch(ixnew,c,d,input[1],opt==D_NORMAL?"> ":"", 0);	if ((opt ==D_EDIT || opt == D_REVERSE) && c<=d)		prints(".\n");	if (inifdef) {		fprintf(stdout, "#endif %s\n", endifname);		inifdef = 0;	}}range(a,b,separator)char *separator;{	printf("%d", a>b?b:a);	if(a<b) {		printf("%s%d", separator, b);	}}fetch(f,a,b,lb,s,oldfile)long *f;FILE *lb;char *s;{	register int i, j;	register int c;	register int col;	register int nc;	int oneflag = (*ifdef1!='\0') != (*ifdef2!='\0');	/*	 * When doing #ifdef's, copy down to current line	 * if this is the first file, so that stuff makes it to output.	 */	if (opt == D_IFDEF && oldfile){		long curpos = ftell(lb);		/* print through if append (a>b), else to (nb: 0 vs 1 orig) */		nc = f[a>b? b : a-1 ] - curpos;		for (i = 0; i < nc; i++)			putchar(getc(lb));	}	if (a > b)		return;	if (opt == D_IFDEF) {		if (inifdef)			fprintf(stdout, "#else %s%s\n", oneflag && oldfile==1 ? "!" : "", ifdef2);		else {			if (oneflag) {				/* There was only one ifdef given */				endifname = ifdef2;				if (oldfile)					fprintf(stdout, "#ifndef %s\n", endifname);				else					fprintf(stdout, "#ifdef %s\n", endifname);			}			else {				endifname = oldfile ? ifdef1 : ifdef2;				fprintf(stdout, "#ifdef %s\n", endifname);			}		}		inifdef = 1+oldfile;	}	for(i=a;i<=b;i++) {		fseek(lb,f[i-1],0);		nc = f[i]-f[i-1];		if (opt != D_IFDEF)			prints(s);		col = 0;		for(j=0;j<nc;j++) {			c = getc(lb);			if (c == '\t' && tflag)				do					putchar(' ');				while (++col & 7);			else {				putchar(c);				col++;			}		}	}	if (inifdef && !wantelses) {		fprintf(stdout, "#endif %s\n", endifname);		inifdef = 0;	}}#define POW2			/* define only if HALFLONG is 2**n */#define HALFLONG 16#define low(x)	(x&((1L<<HALFLONG)-1))#define high(x)	(x>>HALFLONG)/* * hashing has the effect of * arranging line in 7-bit bytes and then * summing 1-s complement in 16-bit hunks  */readhash(f)register FILE *f;{	register long sum;	register unsigned shift;	register t;	register space;	sum = 1;	space = 0;	if(!bflag && !wflag) {		if(iflag)			for(shift=0;(t=getc(f))!='\n';shift+=7) {				if(t==-1)					return(0);				sum += (long)chrtran[t] << (shift#ifdef POW2				    &= HALFLONG - 1);#else				    %= HALFLONG);#endif			}		else			for(shift=0;(t=getc(f))!='\n';shift+=7) {				if(t==-1)					return(0);				sum += (long)t << (shift#ifdef POW2				    &= HALFLONG - 1);#else				    %= HALFLONG);#endif			}	} else {		for(shift=0;;) {			switch(t=getc(f)) {			case -1:				return(0);			case '\t':			case ' ':				space++;				continue;			default:				if(space && !wflag) {					shift += 7;					space = 0;				}				sum += (long)chrtran[t] << (shift#ifdef POW2				    &= HALFLONG - 1);#else				    %= HALFLONG);#endif				shift += 7;				continue;			case '\n':				break;			}			break;		}	}	sum = low(sum) + high(sum);	return((short)low(sum) + (short)high(sum));}#include <a.out.h>asciifile(f)	FILE *f;{	char buf[BUFSIZ];	register int cnt, c;	register char *cp;	fseek(f, (long)0, 0);	cnt = fread(buf, 1, BUFSIZ, f);#ifdef mips	if (cnt >= FILHSZ + AOUTHSZ) {		AOUTHDR hdr;		hdr = *(AOUTHDR *)&buf[FILHSZ];		if (!N_BADMAG(hdr))			return (0);	}#else	if (cnt >= sizeof (struct exec)) {		struct exec hdr;		hdr = *(struct exec *)buf;		if (!N_BADMAG(hdr))			return (0);	}#endif mips	cp = buf;	while (--cnt >= 0)	{			c = *cp++ & 0377;		if (!(c & 0200))			continue;		if (ismulti(c))			continue;		return (0);	}	return (1);}/* dump accumulated "context" diff changes */dump_context_vec(){	register int	a, b, c, d;	register char	ch;	register struct	context_vec *cvp = context_vec_start;	register int	lowa, upb, lowc, upd;	register int	do_output;	if ( cvp > context_vec_ptr )		return;	lowa = max(1, cvp->a - context);	upb  = min(len[0], context_vec_ptr->b + context);	lowc = max(1, cvp->c - context);	upd  = min(len[1], context_vec_ptr->d + context);	printf("***************\n*** ");	range(lowa,upb,",");	printf(" ****\n");	/*	 * output changes to the "old" file.  The first loop suppresses	 * output if there were no changes to the "old" file (we'll see	 * the "old" lines as context in the "new" list).	 */	do_output = 0;	for ( ; cvp <= context_vec_ptr; cvp++)		if (cvp->a <= cvp->b) {			cvp = context_vec_start;			do_output++;			break;		}		if ( do_output ) {		while (cvp <= context_vec_ptr) {			a = cvp->a; b = cvp->b; c = cvp->c; d = cvp->d;			if (a <= b && c <= d)				ch = 'c';			else				ch = (a <= b) ? 'd' : 'a';			if (ch == 'a')				fetch(ixold,lowa,b,input[0],"  ");			else {				fetch(ixold,lowa,a-1,input[0],"  ");				fetch(ixold,a,b,input[0],ch == 'c' ? "! " : "- ");			}			lowa = b + 1;			cvp++;		}		fetch(ixold, b+1, upb, input[0], "  ");	}	/* output changes to the "new" file */	printf("--- ");	range(lowc,upd,",");	printf(" ----\n");	do_output = 0;	for (cvp = context_vec_start; cvp <= context_vec_ptr; cvp++)		if (cvp->c <= cvp->d) {			cvp = context_vec_start;			do_output++;			break;		}		if (do_output) {		while (cvp <= context_vec_ptr) {			a = cvp->a; b = cvp->b; c = cvp->c; d = cvp->d;			if (a <= b && c <= d)				ch = 'c';			else				ch = (a <= b) ? 'd' : 'a';			if (ch == 'd')				fetch(ixnew,lowc,d,input[1],"  ");			else {				fetch(ixnew,lowc,c-1,input[1],"  ");				fetch(ixnew,c,d,input[1],ch == 'c' ? "! " : "+ ");			}			lowc = d + 1;			cvp++;		}		fetch(ixnew, d+1, upd, input[1], "  ");	}	context_vec_ptr = context_vec_start - 1;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?