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

📄 rcsdiff.c

📁 早期freebsd实现
💻 C
字号:
/* *                     RCS rcsdiff operation *//***************************************************************************** *                       generate difference between RCS revisions ***************************************************************************** *//* Copyright (C) 1982, 1988, 1989 Walter Tichy   Copyright 1990, 1991 by Paul Eggert   Distributed under license by the Free Software Foundation, Inc.This file is part of RCS.RCS is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.RCS is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with RCS; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.Report problems and direct all questions to:    rcs-bugs@cs.purdue.edu*//* $Log: rcsdiff.c,v $ * Revision 5.10  1991/10/07  17:32:46  eggert * Remove lint. * * Revision 5.9  1991/08/19  03:13:55  eggert * Add RCSINIT, -r$.  Tune. * * Revision 5.8  1991/04/21  11:58:21  eggert * Add -x, RCSINIT, MS-DOS support. * * Revision 5.7  1990/12/13  06:54:07  eggert * GNU diff 1.15 has -u. * * Revision 5.6  1990/11/01  05:03:39  eggert * Remove unneeded setid check. * * Revision 5.5  1990/10/04  06:30:19  eggert * Accumulate exit status across files. * * Revision 5.4  1990/09/27  01:31:43  eggert * Yield 1, not EXIT_FAILURE, when diffs are found. * * Revision 5.3  1990/09/11  02:41:11  eggert * Simplify -kkvl test. * * Revision 5.2  1990/09/04  17:07:19  eggert * Diff's argv was too small by 1. * * Revision 5.1  1990/08/29  07:13:55  eggert * Add -kkvl. * * Revision 5.0  1990/08/22  08:12:46  eggert * Add -k, -V.  Don't use access().  Add setuid support. * Remove compile-time limits; use malloc instead. * Don't pass arguments with leading '+' to diff; GNU DIFF treats them as options. * Add GNU diff's flags.  Make lock and temp files faster and safer. * Ansify and Posixate. * * Revision 4.6  89/05/01  15:12:27  narten * changed copyright header to reflect current distribution rules *  * Revision 4.5  88/08/09  19:12:41  eggert * Use execv(), not system(); yield exit status like diff(1)s; allow cc -R. *  * Revision 4.4  87/12/18  11:37:46  narten * changes Jay Lepreau made in the 4.3 BSD version, to add support for * "-i", "-w", and "-t" flags and to permit flags to be bundled together, * merged in. *  * Revision 4.3  87/10/18  10:31:42  narten * Updating version numbers. Changes relative to 1.1 actually * relative to 4.1 *  * Revision 1.3  87/09/24  13:59:21  narten * Sources now pass through lint (if you ignore printf/sprintf/fprintf  * warnings) *  * Revision 1.2  87/03/27  14:22:15  jenkins * Port to suns *  * Revision 4.1  83/05/03  22:13:19  wft * Added default branch, option -q, exit status like diff. * Added fterror() to replace faterror(). *  * Revision 3.6  83/01/15  17:52:40  wft * Expanded mainprogram to handle multiple RCS files. * * Revision 3.5  83/01/06  09:33:45  wft * Fixed passing of -c (context) option to diff. * * Revision 3.4  82/12/24  15:28:38  wft * Added call to catchsig(). * * Revision 3.3  82/12/10  16:08:17  wft * Corrected checking of return code from diff; improved error msgs. * * Revision 3.2  82/12/04  13:20:09  wft * replaced getdelta() with gettree(). Changed diagnostics. * * Revision 3.1  82/11/28  19:25:04  wft * Initial revision. * */#include "rcsbase.h"#if DIFF_Lstatic char const *setup_label P((struct buf*,char const*,char const[datesize]));#endifstatic void cleanup P((void));static int exitstatus;static RILE *workptr;static struct stat workstat;mainProg(rcsdiffId, "rcsdiff", "$Id: rcsdiff.c,v 5.10 1991/10/07 17:32:46 eggert Exp $"){    static char const cmdusage[] =	    "\nrcsdiff usage: rcsdiff [-q] [-rrev1 [-rrev2]] [-Vn] [diff options] file ...";    int  revnums;                 /* counter for revision numbers given */    char const *rev1, *rev2;	/* revision numbers from command line */    char const *xrev1, *xrev2;	/* expanded revision numbers */    char const *expandarg, *lexpandarg, *versionarg;#if DIFF_L    static struct buf labelbuf[2];    int file_labels;    char const **diff_label1, **diff_label2;    char date2[datesize];#endif    char const *cov[9];    char const **diffv, **diffp;	/* argv for subsidiary diff */    char const **pp, *p, *diffvstr;    struct buf commarg;    struct buf numericrev;	/* expanded revision number */    struct hshentries *gendeltas;	/* deltas to be generated */    struct hshentry * target;    char *a, *dcp, **newargv;    register c;    exitstatus = DIFF_SUCCESS;    bufautobegin(&commarg);    bufautobegin(&numericrev);    revnums = 0;    rev1 = rev2 = xrev2 = nil;#if DIFF_L    file_labels = 0;#endif    expandarg = versionarg = 0;    suffixes = X_DEFAULT;    /* Room for args + 2 i/o [+ 2 labels] + 1 file + 1 trailing null.  */    diffp = diffv = tnalloc(char const*, argc + 4 + 2*DIFF_L);    *diffp++ = nil;    *diffp++ = nil;    *diffp++ = DIFF;    argc = getRCSINIT(argc, argv, &newargv);    argv = newargv;    while (a = *++argv,  0<--argc && *a++=='-') {	dcp = a;	while (c = *a++) switch (c) {	    case 'r':		    switch (++revnums) {			case 1: rev1=a; break;			case 2: rev2=a; break;			default: faterror("too many revision numbers");		    }		    goto option_handled;#if DIFF_L	    case 'L':		    if (++file_labels == 2)			faterror("too many -L options");		    /* fall into */#endif	    case 'C': case 'D': case 'F': case 'I':		    *dcp++ = c;		    if (*a)			do *dcp++ = *a++;			while (*a);		    else {			if (!--argc)			    faterror("-%c needs following argument%s",				    c, cmdusage			    );			*diffp++ = *argv++;		    }		    break;	    case 'B': case 'H': case 'T':	    case '0': case '1': case '2': case '3': case '4':	    case '5': case '6': case '7': case '8': case '9':	    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':	    case 'h': case 'i': case 'n': case 'p':	    case 't': case 'u': case 'w':		    *dcp++ = c;		    break;	    case 'q':		    quietflag=true;		    break;	    case 'x':		    suffixes = *argv + 2;		    goto option_handled;	    case 'V':		    versionarg = *argv;		    setRCSversion(versionarg);		    goto option_handled;	    case 'k':		    expandarg = *argv;		    if (0 <= str2expmode(expandarg+2))			goto option_handled;		    /* fall into */	    default:		    faterror("unknown option: %s%s", *argv, cmdusage);	    };      option_handled:	if (dcp != *argv+1) {	    *dcp = 0;	    *diffp++ = *argv;	}    } /* end of option processing */    if (argc<1) faterror("no input file%s", cmdusage);    for (pp = diffv+3, c = 0;  pp<diffp;  )	    c += strlen(*pp++) + 1;    diffvstr = a = tnalloc(char, c + 1);    for (pp = diffv+3;  pp<diffp;  ) {	    p = *pp++;	    *a++ = ' ';	    while ((*a = *p++))		    a++;    }    *a = 0;#if DIFF_L    diff_label1 = diff_label2 = nil;    if (file_labels < 2) {	    if (!file_labels)		    diff_label1 = diffp++;	    diff_label2 = diffp++;    }#endif    diffp[2] = nil;    cov[0] = 0;    cov[2] = CO;    cov[3] = "-q";    /* now handle all filenames */    do {	    ffree();	    if (pairfilenames(argc, argv, rcsreadopen, true, false)  <=  0)		    continue;	    diagnose("===================================================================\nRCS file: %s\n",RCSfilename);	    if (!rev2) {		/* Make sure work file is readable, and get its status.  */		if (!(workptr = Iopen(workfilename,FOPEN_R_WORK,&workstat))) {		    eerror(workfilename);		    continue;		}	    }	    gettree(); /* reads in the delta tree */	    if (Head==nil) {		    error("no revisions present");		    continue;	    }	    if (revnums==0  ||  !*rev1)		    rev1  =  Dbranch ? Dbranch : Head->num;	    if (!fexpandsym(rev1, &numericrev, workptr)) continue;	    if (!(target=genrevs(numericrev.string,(char *)nil,(char *)nil,(char *)nil,&gendeltas))) continue;	    xrev1=target->num;#if DIFF_L	    if (diff_label1)		*diff_label1 = setup_label(&labelbuf[0], target->num, target->date);#endif	    lexpandarg = expandarg;	    if (revnums==2) {		    if (!fexpandsym(			    *rev2 ? rev2  : Dbranch ? Dbranch  : Head->num,			    &numericrev,			    workptr		    ))			continue;		    if (!(target=genrevs(numericrev.string,(char *)nil,(char *)nil,(char *)nil,&gendeltas))) continue;		    xrev2=target->num;	    } else if (			target->lockedby		&&	!lexpandarg		&&	Expand == KEYVAL_EXPAND		&&	WORKMODE(RCSstat.st_mode,true) == workstat.st_mode	    )		    lexpandarg = "-kkvl";	    Izclose(&workptr);#if DIFF_L	    if (diff_label2)		if (revnums == 2)		    *diff_label2 = setup_label(&labelbuf[1], target->num, target->date);		else {		    time2date(workstat.st_mtime, date2);		    *diff_label2 = setup_label(&labelbuf[1], workfilename, date2);		}#endif	    diagnose("retrieving revision %s\n", xrev1);	    bufscpy(&commarg, "-p");	    bufscat(&commarg, xrev1);	    cov[1] = diffp[0] = maketemp(0);	    pp = &cov[4];	    *pp++ = commarg.string;	    if (lexpandarg)		    *pp++ = lexpandarg;	    if (versionarg)		    *pp++ = versionarg;	    *pp++ = RCSfilename;	    *pp = 0;	    if (runv(cov)) {		    error("co failed");		    continue;	    }	    if (!rev2) {		    diffp[1] = workfilename;		    if (workfilename[0] == '+') {			/* Some diffs have options with leading '+'.  */			char *dp = ftnalloc(char, strlen(workfilename)+3);			diffp[1] = dp;			*dp++ = '.';			*dp++ = SLASH;			VOID strcpy(dp, workfilename);		    }	    } else {		    diagnose("retrieving revision %s\n",xrev2);		    bufscpy(&commarg, "-p");		    bufscat(&commarg, xrev2);		    cov[1] = diffp[1] = maketemp(1);		    cov[4] = commarg.string;		    if (runv(cov)) {			    error("co failed");			    continue;		    }	    }	    if (!rev2)		    diagnose("diff%s -r%s %s\n", diffvstr, xrev1, workfilename);	    else		    diagnose("diff%s -r%s -r%s\n", diffvstr, xrev1, xrev2);	    switch (runv(diffv)) {		    case DIFF_SUCCESS:			    break;		    case DIFF_FAILURE:			    if (exitstatus == DIFF_SUCCESS)				    exitstatus = DIFF_FAILURE;			    break;		    default:			    error("diff failed");	    }    } while (cleanup(),	     ++argv, --argc >=1);    tempunlink();    exitmain(exitstatus);}    static voidcleanup(){    if (nerror) exitstatus = DIFF_TROUBLE;    Izclose(&finptr);    Izclose(&workptr);}#if lint#	define exiterr rdiffExit#endif    exiting voidexiterr(){    tempunlink();    _exit(DIFF_TROUBLE);}#if DIFF_L	static char const *setup_label(b, name, date)	struct buf *b;	char const *name;	char const date[datesize];{	char *p;	size_t l = strlen(name) + 3;	bufalloc(b, l+datesize);	p = b->string;	VOID sprintf(p, "-L%s\t", name);	VOID date2str(date, p+l);	return p;}#endif

⌨️ 快捷键说明

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