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

📄 rcsrev.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *                     RCS revision number handling *//* 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: rcsrev.c,v $ * Revision 5.3  1991/08/19  03:13:55  eggert * Add `-r$', `-rB.'.  Remove botches like `<now>' from messages.  Tune. * * Revision 5.2  1991/04/21  11:58:28  eggert * Add tiprev(). * * Revision 5.1  1991/02/25  07:12:43  eggert * Avoid overflow when comparing revision numbers. * * Revision 5.0  1990/08/22  08:13:43  eggert * Remove compile-time limits; use malloc instead. * Ansify and Posixate.  Tune. * Remove possibility of an internal error.  Remove lint. * * Revision 4.5  89/05/01  15:13:22  narten * changed copyright header to reflect current distribution rules *  * Revision 4.4  87/12/18  11:45:22  narten * more lint cleanups. Also, the NOTREACHED comment is no longer necessary,  * since there's now a return value there with a value. (Guy Harris) *  * Revision 4.3  87/10/18  10:38:42  narten * Updating version numbers. Changes relative to version 1.1 actually  * relative to 4.1 *  * Revision 1.3  87/09/24  14:00:37  narten * Sources now pass through lint (if you ignore printf/sprintf/fprintf  * warnings) *  * Revision 1.2  87/03/27  14:22:37  jenkins * Port to suns *  * Revision 4.1  83/03/25  21:10:45  wft * Only changed $Header to $Id. *  * Revision 3.4  82/12/04  13:24:08  wft * Replaced getdelta() with gettree(). * * Revision 3.3  82/11/28  21:33:15  wft * fixed compartial() and compnum() for nil-parameters; fixed nils * in error messages. Testprogram output shortenend. * * Revision 3.2  82/10/18  21:19:47  wft * renamed compnum->cmpnum, compnumfld->cmpnumfld, * numericrevno->numricrevno. * * Revision 3.1  82/10/11  19:46:09  wft * changed expandsym() to check for source==nil; returns zero length string * in that case. *//*#define REVTEST*//* version REVTEST is for testing the routines that generate a sequence * of delta numbers needed to regenerate a given delta. */#include "rcsbase.h"libId(revId, "$Id: rcsrev.c,v 5.3 1991/08/19 03:13:55 eggert Exp $")static char const *branchtip P((char const*));static struct hshentry *genbranch P((struct hshentry const*,char const*,unsigned,char const*,char const*,char const*,struct hshentries**));	unsignedcountnumflds(s)	char const *s;/* Given a pointer s to a dotted number (date or revision number), * countnumflds returns the number of digitfields in s. */{	register char const *sp;	register unsigned count;        if ((sp=s)==nil) return(0);        if (*sp == '\0') return(0);        count = 1;	do {                if (*sp++ == '.') count++;	} while (*sp);        return(count);}	voidgetbranchno(revno,branchno)	char const *revno;	struct buf *branchno;/* Given a non-nil revision number revno, getbranchno copies the number of the branch * on which revno is into branchno. If revno itself is a branch number, * it is copied unchanged. */{	register unsigned numflds;	register char *tp;	bufscpy(branchno, revno);        numflds=countnumflds(revno);	if (!(numflds & 1)) {		tp = branchno->string;		while (--numflds)			while (*tp++ != '.')				;                *(tp-1)='\0';        }}int cmpnum(num1, num2)	char const *num1, *num2;/* compares the two dotted numbers num1 and num2 lexicographically * by field. Individual fields are compared numerically. * returns <0, 0, >0 if num1<num2, num1==num2, and num1>num2, resp. * omitted fields are assumed to be higher than the existing ones.*/{	register char const *s1, *s2;	register size_t d1, d2;	register int r;        s1=num1==nil?"":num1;        s2=num2==nil?"":num2;	for (;;) {		/* Give precedence to shorter one.  */		if (!*s1)			return (unsigned char)*s2;		if (!*s2)			return -1;		/* Strip leading zeros, then find number of digits.  */		while (*s1=='0') ++s1;  for (d1=0; isdigit(s1[d1]); d1++) ;		while (*s2=='0') ++s2;  for (d2=0; isdigit(s2[d2]); d2++) ;		/* Do not convert to integer; it might overflow!  */		if (d1 != d2)			return d1<d2 ? -1 : 1;		if ((r = memcmp(s1, s2, d1)))			return r;		s1 += d1;		s2 += d1;                /* skip '.' */		if (*s1) s1++;		if (*s2) s2++;	}}int cmpnumfld(num1, num2, fld)	char const *num1, *num2;	unsigned fld;/* Compare the two dotted numbers at field fld. * num1 and num2 must have at least fld fields. * fld must be positive.*/{	register char const *s1, *s2;	register size_t d1, d2;	s1 = num1;	s2 = num2;        /* skip fld-1 fields */	while (--fld) {		while (*s1++ != '.')			;		while (*s2++ != '.')			;	}        /* Now s1 and s2 point to the beginning of the respective fields */	while (*s1=='0') ++s1;  for (d1=0; isdigit(s1[d1]); d1++) ;	while (*s2=='0') ++s2;  for (d2=0; isdigit(s2[d2]); d2++) ;	return d1<d2 ? -1 : d1==d2 ? memcmp(s1,s2,d1) : 1;}	static voidcantfindbranch(revno, date, author, state)	char const *revno, date[datesize], *author, *state;{	char datebuf[datesize];	error("No revision on branch %s has%s%s%s%s%s%s.",		revno,		date ? " a date before " : "",		date ? date2str(date,datebuf) : "",		author ? " and author "+(date?0:4) : "",		author ? author : "",		state ? " and state "+(date||author?0:4) : "",		state ? state : ""	);}	static voidabsent(revno, field)	char const *revno;	unsigned field;{	struct buf t;	bufautobegin(&t);	error("%s %s absent", field&1?"revision":"branch",		partialno(&t,revno,field)	);	bufautoend(&t);}	intcompartial(num1, num2, length)	char const *num1, *num2;	unsigned length;/*   compare the first "length" fields of two dot numbers;     the omitted field is considered to be larger than any number  *//*   restriction:  at least one number has length or more fields   */{	register char const *s1, *s2;	register size_t d1, d2;	register int r;        s1 = num1;      s2 = num2;	if (!s1) return 1;	if (!s2) return -1;	for (;;) {	    if (!*s1) return 1;	    if (!*s2) return -1;	    while (*s1=='0') ++s1;  for (d1=0; isdigit(s1[d1]); d1++) ;	    while (*s2=='0') ++s2;  for (d2=0; isdigit(s2[d2]); d2++) ;	    if (d1 != d2)		    return d1<d2 ? -1 : 1;	    if ((r = memcmp(s1, s2, d1)))		    return r;	    s1 += d1;	    s2 += d1;	    if (*s1 == '.') s1++;            if (*s2 == '.') s2++;	    if ( --length == 0 ) return 0;	}}char * partialno(rev1,rev2,length)	struct buf *rev1;	char const *rev2;	register unsigned length;/* Function: Copies length fields of revision number rev2 into rev1. * Return rev1's string. */{	register char *r1;	bufscpy(rev1, rev2);	r1 = rev1->string;        while (length) {		while (*r1!='.' && *r1)			++r1;		++r1;                length--;        }        /* eliminate last '.'*/        *(r1-1)='\0';	return rev1->string;}	static voidstore1(store, next)	struct hshentries ***store;	struct hshentry *next;/* * Allocate a new list node that addresses NEXT. * Append it to the list that **STORE is the end pointer of. */{	register struct hshentries *p;	p = ftalloc(struct hshentries);	p->first = next;	**store = p;	*store = &p->rest;}struct hshentry * genrevs(revno,date,author,state,store)	char const *revno, *date, *author, *state;	struct hshentries **store;/* Function: finds the deltas needed for reconstructing the * revision given by revno, date, author, and state, and stores pointers * to these deltas into a list whose starting address is given by store. * The last delta (target delta) is returned. * If the proper delta could not be found, nil is returned. */{	unsigned length;        register struct hshentry * next;        int result;	char const *branchnum;	struct buf t;	char datebuf[datesize];	bufautobegin(&t);	if (!(next = Head)) {		error("RCS file empty");		goto norev;        }        length = countnumflds(revno);        if (length >= 1) {                /* at least one field; find branch exactly */		while ((result=cmpnumfld(revno,next->num,1)) < 0) {			store1(&store, next);                        next = next->next;			if (!next) {			    error("branch number %s too low", partialno(&t,revno,1));			    goto norev;			}                }		if (result>0) {			absent(revno, 1);			goto norev;		}        }        if (length<=1){                /* pick latest one on given branch */                branchnum = next->num; /* works even for empty revno*/                while ((next!=nil) &&                       (cmpnumfld(branchnum,next->num,1)==0) &&                       !(                        (date==nil?1:(cmpnum(date,next->date)>=0)) &&                        (author==nil?1:(strcmp(author,next->author)==0)) &&                        (state ==nil?1:(strcmp(state, next->state) ==0))                        )                       )		{			store1(&store, next);                        next=next->next;                }                if ((next==nil) ||                    (cmpnumfld(branchnum,next->num,1)!=0))/*overshot*/ {			cantfindbranch(				length ? revno : partialno(&t,branchnum,1),				date, author, state			);			goto norev;                } else {			store1(&store, next);

⌨️ 快捷键说明

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