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

📄 rcs.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
        } else  {		error("no lock set on revision %s", num);        }}	static struct hshentry *searchcutpt(object, length, store)	char const *object;	unsigned length;	struct hshentries *store;/*   Function:  Search store and return entry with number being object. *//*              cuttail = nil, if the entry is Head; otherwise, cuttail *//*              is the entry point to the one with number being object  */{	cuthead = nil;	while (compartial(store->first->num, object, length)) {		cuthead = store->first;		store = store->rest;	}	return store->first;}	static intbranchpoint(strt, tail)struct  hshentry        *strt,  *tail;/*   Function: check whether the deltas between strt and tail	*//*		are locked or branch point, return 1 if any is  *//*		locked or branch point; otherwise, return 0 and *//*		mark deleted					*/{        struct  hshentry    *pt;	struct lock const *lockpt;        int     flag;        pt = strt;        flag = false;        while( pt != tail) {            if ( pt->branches ){ /*  a branch point  */                flag = true;		error("can't remove branch point %s", pt->num);            }	    lockpt = Locks;	    while(lockpt && lockpt->delta != pt)		lockpt = lockpt->nextlock;	    if ( lockpt ) {		flag = true;		error("can't remove locked revision %s",pt->num);	    }            pt = pt->next;        }        if ( ! flag ) {            pt = strt;            while( pt != tail ) {		pt->selector = false;		diagnose("deleting revision %s\n",pt->num);                pt = pt->next;            }        }        return flag;}	static intremoverevs()/*   Function:  get the revision range to be removed, and place the     *//*              first revision removed in delstrt, the revision before  *//*              delstrt in cuthead( nil, if delstrt is head), and the   *//*              revision after the last removed revision in cuttail(nil *//*              if the last is a leaf                                   */{	struct  hshentry *target, *target2, *temp;	unsigned length;	int flag;        flag = false;	if (!expandsym(delrev.strt, &numrev)) return 0;	target = genrevs(numrev.string, (char*)nil, (char*)nil, (char*)nil, &gendeltas);        if ( ! target ) return 0;	if (cmpnum(target->num, numrev.string)) flag = true;	length = countnumflds(numrev.string);	if (delrev.code == 0) {  /*  -o  rev    or    -o  branch   */	    if (length & 1)		temp=searchcutpt(target->num,length+1,gendeltas);	    else if (flag) {		error("Revision %s doesn't exist.", numrev.string);		return 0;	    }	    else		temp = searchcutpt(numrev.string, length, gendeltas);	    cuttail = target->next;            if ( branchpoint(temp, cuttail) ) {                cuttail = nil;                return 0;            }            delstrt = temp;     /* first revision to be removed   */            return 1;        }	if (length & 1) {   /*  invalid branch after -o   */	    error("invalid branch range %s after -o", numrev.string);            return 0;        }	if (delrev.code == 1) {  /*  -o  -rev   */            if ( length > 2 ) {                temp = searchcutpt( target->num, length-1, gendeltas);                cuttail = target->next;            }            else {                temp = searchcutpt(target->num, length, gendeltas);                cuttail = target;                while( cuttail && ! cmpnumfld(target->num,cuttail->num,1) )                    cuttail = cuttail->next;            }            if ( branchpoint(temp, cuttail) ){                cuttail = nil;                return 0;            }            delstrt = temp;            return 1;        }	if (delrev.code == 2) {   /*  -o  rev-   */            if ( length == 2 ) {                temp = searchcutpt(target->num, 1,gendeltas);                if ( flag)                    cuttail = target;                else                    cuttail = target->next;            }            else  {                if ( flag){                    cuthead = target;                    if ( !(temp = target->next) ) return 0;                }                else                    temp = searchcutpt(target->num, length, gendeltas);		getbranchno(temp->num, &numrev);  /* get branch number */		target = genrevs(numrev.string, (char*)nil, (char*)nil, (char*)nil, &gendeltas);            }            if ( branchpoint( temp, cuttail ) ) {                cuttail = nil;                return 0;            }            delstrt = temp;            return 1;        }        /*   -o   rev1-rev2   */	if (!expandsym(delrev.end, &numrev)) return 0;	if (		length != countnumflds(numrev.string)	    ||	length>2 && compartial(numrev.string, target->num, length-1)	) {	    error("invalid revision range %s-%s", target->num, numrev.string);            return 0;        }	target2 = genrevs(numrev.string,(char*)nil,(char*)nil,(char*)nil,&gendeltas);        if ( ! target2 ) return 0;        if ( length > 2) {  /* delete revisions on branches  */            if ( cmpnum(target->num, target2->num) > 0) {		if (cmpnum(target2->num, numrev.string))                    flag = true;                else                    flag = false;                temp = target;                target = target2;                target2 = temp;            }            if ( flag ) {                if ( ! cmpnum(target->num, target2->num) ) {		    error("Revisions %s-%s don't exist.", delrev.strt,delrev.end);                    return 0;                }                cuthead = target;                temp = target->next;            }            else                temp = searchcutpt(target->num, length, gendeltas);            cuttail = target2->next;        }        else { /*  delete revisions on trunk  */            if ( cmpnum( target->num, target2->num) < 0 ) {                temp = target;                target = target2;                target2 = temp;            }            else		if (cmpnum(target2->num, numrev.string))                    flag = true;                else                    flag = false;            if ( flag ) {                if ( ! cmpnum(target->num, target2->num) ) {		    error("Revisions %s-%s don't exist.", delrev.strt, delrev.end);                    return 0;                }                cuttail = target2;            }            else                cuttail = target2->next;            temp = searchcutpt(target->num, length, gendeltas);        }        if ( branchpoint(temp, cuttail) )  {            cuttail = nil;            return 0;        }        delstrt = temp;        return 1;}	static voiddoassoc()/*   Function: add or delete(if revno is nil) association	*//*		which is stored in assoclst			*/{	char const *p;	struct Symrev const *curassoc;	struct  assoc   * pre,  * pt;        /*  add new associations   */        curassoc = assoclst;        while( curassoc ) {            if ( curassoc->revno == nil ) {  /* delete symbol  */		pre = pt = Symbols;                while( pt && strcmp(pt->symbol,curassoc->ssymbol) ) {		    pre = pt;		    pt = pt->nextassoc;		}		if ( pt )		    if ( pre == pt )			Symbols = pt->nextassoc;		    else			pre->nextassoc = pt->nextassoc;		else		    warn("can't delete nonexisting symbol %s",curassoc->ssymbol);	    }	    else {		if (curassoc->revno[0]) {		    p = 0;		    if (expandsym(curassoc->revno, &numrev))			p = fstr_save(numrev.string);		} else if (!(p = tiprev()))		    error("no latest revision to associate with symbol %s",			    curassoc->ssymbol		    );		if (p)		    VOID addsymbol(p, curassoc->ssymbol, curassoc->override);	    }            curassoc = curassoc->nextsym;        }}	static voiddolocks()/* Function: remove lock for caller or first lock if unlockcaller is set; *           remove locks which are stored in rmvlocklst, *           add new locks which are stored in newlocklst, *           add lock for Dbranch or Head if lockhead is set. */{	struct Lockrev const *lockpt;	struct hshentry *target;	if (unlockcaller) { /*  find lock for caller  */            if ( Head ) {		if (Locks) {		    switch (findlock(true, &target)) {		      case 0:			breaklock(Locks->delta); /* remove most recent lock */			break;		      case 1:			diagnose("%s unlocked\n",target->num);			break;		    }		} else {		    warn("No locks are set.");		}            } else {		warn("can't unlock an empty tree");            }        }        /*  remove locks which are stored in rmvlocklst   */        lockpt = rmvlocklst;        while( lockpt ) {	    if (expandsym(lockpt->revno, &numrev)) {		target = genrevs(numrev.string, (char *)nil, (char *)nil, (char *)nil, &gendeltas);                if ( target )		   if (!(countnumflds(numrev.string)&1) && cmpnum(target->num,numrev.string))			error("can't unlock nonexisting revision %s",lockpt->revno);                   else			breaklock(target);                        /* breaklock does its own diagnose */            }            lockpt = lockpt->nextrev;        }        /*  add new locks which stored in newlocklst  */        lockpt = newlocklst;        while( lockpt ) {	    setlock(lockpt->revno);            lockpt = lockpt->nextrev;        }	if (lockhead) {  /*  lock default branch or head  */            if (Dbranch) {		setlock(Dbranch);	    } else if (Head) {		if (0 <= addlock(Head))		    diagnose("%s locked\n",Head->num);            } else {		warn("can't lock an empty tree");            }        }}	static voidsetlock(rev)	char const *rev;/* Function: Given a revision or branch number, finds the corresponding * delta and locks it for caller. */{        struct  hshentry *target;	if (expandsym(rev, &numrev)) {	    target = genrevs(numrev.string, (char*)nil, (char*)nil,			     (char*)nil, &gendeltas);            if ( target )	       if (!(countnumflds(numrev.string)&1) && cmpnum(target->num,numrev.string))		    error("can't lock nonexisting revision %s", numrev.string);               else		    if (0 <= addlock(target))			diagnose("%s locked\n", target->num);        }}	static voiddomessages(){	struct hshentry *target;	struct Message *p;	for (p = messagelst;  p;  p = p->nextmessage)	    if (		expandsym(p->revno, &numrev)  &&		(target = genrevs(			numrev.string, (char*)0, (char*)0, (char*)0, &gendeltas		))	    )		target->log = p->message;}	static voidrcs_setstate(rev,status)	char const *rev, *status;/* Function: Given a revision or branch number, finds the corresponding delta * and sets its state to status. */{        struct  hshentry *target;	if (expandsym(rev, &numrev)) {	    target = genrevs(numrev.string, (char*)nil, (char*)nil,			     (char*)nil, &gendeltas);            if ( target )	       if (!(countnumflds(numrev.string)&1) && cmpnum(target->num,numrev.string))		    error("can't set state of nonexisting revision %s to %s",			  numrev.string, status);               else                    target->state = status;        }}	static intbuildeltatext(deltas)	struct hshentries const *deltas;/*   Function:  put the delta text on frewrite and make necessary   *//*              change to delta text                                */{	register FILE *fcut;	/* temporary file to rebuild delta tree */	char const *cutfilename, *diffilename;	cutfilename = nil;	cuttail->selector = false;	scanlogtext(deltas->first, false);        if ( cuthead )  {	    cutfilename = maketemp(3);	    if (!(fcut = fopen(cutfilename, FOPEN_W_WORK))) {		efaterror(cutfilename);            }	    while (deltas->first != cuthead) {		deltas = deltas->rest;		scanlogtext(deltas->first, true);            }	    snapshotedit(fcut);	    Ofclose(fcut);        }	while (deltas->first != cuttail)	    scanlogtext((deltas = deltas->rest)->first, true);	finishedit((struct hshentry *)nil, (FILE*)0, true);	Ozclose(&fcopy);        if ( cuthead ) {	    diffilename = maketemp(0);	    switch (run((char*)nil,diffilename,			DIFF DIFF_FLAGS, cutfilename, resultfile, (char*)nil	    )) {		case DIFF_FAILURE: case DIFF_SUCCESS: break;		default: faterror ("diff failed");	    }	    return putdtext(cuttail->num,cuttail->log,diffilename,frewrite,true);	} else	    return putdtext(cuttail->num,cuttail->log,resultfile,frewrite,false);}	static voidbuildtree()/*   Function:  actually removes revisions whose selector field  *//*		is false, and rebuilds the linkage of deltas.	 *//*              asks for reconfirmation if deleting last revision*/{	struct	hshentry   * Delta;        struct  branchhead      *pt, *pre;        if ( cuthead )           if ( cuthead->next == delstrt )                cuthead->next = cuttail;           else {                pre = pt = cuthead->branches;                while( pt && pt->hsh != delstrt )  {                    pre = pt;                    pt = pt->nextbranch;                }                if ( cuttail )                    pt->hsh = cuttail;                else if ( pt == pre )                    cuthead->branches = pt->nextbranch;                else                    pre->nextbranch = pt->nextbranch;            }	else {            if ( cuttail == nil && !quietflag) {		if (!yesorno(false, "Do you really want to delete all revisions? [ny](n): ")) {		    error("No revision deleted");		    Delta = delstrt;		    while( Delta) {			Delta->selector = true;			Delta = Delta->next;		    }		    return;		}	    }            Head = cuttail;	}        return;}#if lint/* This lets us lint everything all at once. */char const cmdid[] = "";#define go(p,e) {int p P((int,char**)); void e P((void)); if(*argv)return p(argc,argv);if(*argv[1])e();}	intmain(argc, argv)	int argc;	char **argv;{	go(ciId,	ciExit);	go(coId,	coExit);	go(identId,	identExit);	go(mergeId,	mergeExit);	go(rcsId,	exiterr);	go(rcscleanId,	rcscleanExit);	go(rcsdiffId,	rdiffExit);	go(rcsmergeId,	rmergeExit);	go(rlogId,	rlogExit);	return 0;}#endif

⌨️ 快捷键说明

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