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

📄 rcskeep.c

📁 早期freebsd实现
💻 C
字号:
/* *                     RCS keyword extraction *//***************************************************************************** *                       main routine: getoldkeys() *                       Testprogram: define KEEPTEST ***************************************************************************** *//* 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: rcskeep.c,v $ * Revision 5.4  1991/08/19  03:13:55  eggert * Tune. * * Revision 5.3  1991/04/21  11:58:25  eggert * Shorten names to keep them distinct on shortname hosts. * * Revision 5.2  1990/10/04  06:30:20  eggert * Parse time zone offsets; future RCS versions may output them. * * Revision 5.1  1990/09/20  02:38:56  eggert * ci -k now checks dates more thoroughly. * * Revision 5.0  1990/08/22  08:12:53  eggert * Retrieve old log message if there is one. * Don't require final newline. * Remove compile-time limits; use malloc instead.  Tune. * Permit dates past 1999/12/31.  Ansify and Posixate. * * Revision 4.6  89/05/01  15:12:56  narten * changed copyright header to reflect current distribution rules *  * Revision 4.5  88/08/09  19:13:03  eggert * Remove lint and speed up by making FILE *fp local, not global. *  * Revision 4.4  87/12/18  11:44:21  narten * more lint cleanups (Guy Harris) *  * Revision 4.3  87/10/18  10:35:50  narten * Updating version numbers. Changes relative to 1.1 actually relative * to 4.1 *  * Revision 1.3  87/09/24  14:00:00  narten * Sources now pass through lint (if you ignore printf/sprintf/fprintf  * warnings) *  * Revision 1.2  87/03/27  14:22:29  jenkins * Port to suns *  * Revision 4.1  83/05/10  16:26:44  wft * Added new markers Id and RCSfile; extraction added. * Marker matching with trymatch(). *  * Revision 3.2  82/12/24  12:08:26  wft * added missing #endif. * * Revision 3.1  82/12/04  13:22:41  wft * Initial revision. * *//*#define KEEPTEST*//* Testprogram; prints out the keyword values found. */#include  "rcsbase.h"libId(keepId, "$Id: rcskeep.c,v 5.4 1991/08/19 03:13:55 eggert Exp $")static int checknum P((char const*,int));static int getval P((RILE*,struct buf*,int));static int get0val P((int,RILE*,struct buf*,int));static int keepdate P((RILE*));static int keepid P((int,RILE*,struct buf*));static int keeprev P((RILE*));int prevkeys;struct buf prevauthor, prevdate, prevrev, prevstate;	intgetoldkeys(fp)	register RILE *fp;/* Function: Tries to read keyword values for author, date, * revision number, and state out of the file fp. * If FNAME is nonnull, it is opened and closed instead of using FP. * The results are placed into * prevauthor, prevdate, prevrev, prevstate. * Aborts immediately if it finds an error and returns false. * If it returns true, it doesn't mean that any of the * values were found; instead, check to see whether the corresponding arrays * contain the empty string. */{    register int c;    char keyword[keylength+1];    register char * tp;    int needs_closing;    if (prevkeys)	return true;    needs_closing = false;    if (!fp) {	if (!(fp = Iopen(workfilename, FOPEN_R_WORK, (struct stat*)0))) {	    eerror(workfilename);	    return false;	}	needs_closing = true;    }    /* initialize to empty */    bufscpy(&prevauthor, "");    bufscpy(&prevdate, "");    bufscpy(&prevrev, "");    bufscpy(&prevstate, "");    c = '\0'; /* anything but KDELIM */    for (;;) {        if ( c==KDELIM) {	    do {		/* try to get keyword */		tp = keyword;		for (;;) {		    Igeteof(fp, c, goto ok;);		    switch (c) {			default:			    if (keyword+keylength <= tp)				break;			    *tp++ = c;			    continue;			case '\n': case KDELIM: case VDELIM:			    break;		    }		    break;		}	    } while (c==KDELIM);            if (c!=VDELIM) continue;	    *tp = c;	    Igeteof(fp, c, break;);	    switch (c) {		case ' ': case '\t': break;		default: continue;	    }	    switch (trymatch(keyword)) {            case Author:		if (!keepid(0, fp, &prevauthor))		    return false;		c = 0;                break;            case Date:		if (!(c = keepdate(fp)))		    return false;                break;            case Header:            case Id:		if (!(		      getval(fp, (struct buf*)nil, false) &&		      keeprev(fp) &&		      (c = keepdate(fp)) &&		      keepid(c, fp, &prevauthor) &&		      keepid(0, fp, &prevstate)		))		    return false;		/* Skip either ``who'' (new form) or ``Locker: who'' (old).  */		if (getval(fp, (struct buf*)nil, true) &&		    getval(fp, (struct buf*)nil, true))			c = 0;		else if (nerror)			return false;		else			c = KDELIM;		break;            case Locker:            case Log:            case RCSfile:            case Source:		if (!getval(fp, (struct buf*)nil, false))		    return false;		c = 0;                break;            case Revision:		if (!keeprev(fp))		    return false;		c = 0;                break;            case State:		if (!keepid(0, fp, &prevstate))		    return false;		c = 0;                break;            default:               continue;            }	    if (!c)		Igeteof(fp, c, c=0;);	    if (c != KDELIM) {		error("closing %c missing on keyword", KDELIM);		return false;	    }	    if (*prevauthor.string && *prevdate.string && *prevrev.string && *prevstate.string) {                break;           }        }	Igeteof(fp, c, break;);    } ok:    if (needs_closing)	Ifclose(fp);    else	Irewind(fp);    prevkeys = true;    return true;}	static intbadly_terminated(){	error("badly terminated keyword value");	return false;}	static intgetval(fp, target, optional)	register RILE *fp;	struct buf *target;	int optional;/* Reads a keyword value from FP into TARGET. * Returns true if one is found, false otherwise. * Does not modify target if it is nil. * Do not report an error if OPTIONAL is set and KDELIM is found instead. */{	int c;	Igeteof(fp, c, return badly_terminated(););	return get0val(c, fp, target, optional);}	static intget0val(c, fp, target, optional)	register int c;	register RILE *fp;	struct buf *target;	int optional;/* Reads a keyword value from C+FP into TARGET, perhaps OPTIONALly. * Same as getval, except C is the lookahead character. */{   register char * tp;    char const *tlim;    register int got1;    if (target) {	bufalloc(target, 1);	tp = target->string;	tlim = tp + target->size;    } else	tlim = tp = 0;    got1 = false;    for (;;) {	switch (c) {	    default:		got1 = true;		if (tp) {		    *tp++ = c;		    if (tlim <= tp)			tp = bufenlarge(target, &tlim);		}		break;	    case ' ':	    case '\t':		if (tp) {		    *tp = 0;#		    ifdef KEEPTEST			VOID printf("getval: %s\n", target);#		    endif		}		if (!got1)		    error("too much white space in keyword value");		return got1;	    case KDELIM:		if (!got1 && optional)		    return false;		/* fall into */	    case '\n':	    case 0:		return badly_terminated();	}	Igeteof(fp, c, return badly_terminated(););    }}	static intkeepdate(fp)	RILE *fp;/* Function: reads a date prevdate; checks format * Return 0 on error, lookahead character otherwise. */{    struct buf prevday, prevtime, prevzone;    register char const *p;    register int c;    c = 0;    bufautobegin(&prevday);    if (getval(fp,&prevday,false)) {	bufautobegin(&prevtime);	if (getval(fp,&prevtime,false)) {	    bufautobegin(&prevzone);	    bufscpy(&prevzone, "");	    Igeteof(fp, c, c=0;);	    if (c=='-' || c=='+')		if (!get0val(c,fp,&prevzone,false))		    c = 0;		else		    Igeteof(fp, c, c=0;);	    if (c) {		p = prevday.string;		bufalloc(&prevdate, strlen(p) + strlen(prevtime.string) + strlen(prevzone.string) + 5);		VOID sprintf(prevdate.string, "%s%s %s %s",		    /* Parse dates put out by old versions of RCS.  */		    isdigit(p[0]) && isdigit(p[1]) && p[2]=='/'  ?  "19"  :  "",		    p, prevtime.string, prevzone.string		);	    }	    bufautoend(&prevzone);	}	bufautoend(&prevtime);    }    bufautoend(&prevday);    return c;}	static intkeepid(c, fp, b)	int c;	RILE *fp;	struct buf *b;/* Get previous identifier from C+FP into B.  */{	if (!c)	    Igeteof(fp, c, return false;);	if (!get0val(c, fp, b, false))	    return false;	checksid(b->string);	return true;}	static intkeeprev(fp)	RILE *fp;/* Get previous revision from FP into prevrev.  */{	return getval(fp,&prevrev,false) && checknum(prevrev.string,-1);}	static intchecknum(sp,fields)	register char const *sp;	int fields;{    register int dotcount;     dotcount=0;     while(*sp) {        if (*sp=='.') dotcount++;	else if (!isdigit(*sp)) return false;        sp++;     }     return fields<0 ? dotcount&1 : dotcount==fields;}#ifdef KEEPTESTchar const cmdid[] ="keeptest";	intmain(argc, argv)int  argc; char  *argv[];{        while (*(++argv)) {		workfilename = *argv;		getoldkeys((RILE*)0);                VOID printf("%s:  revision: %s, date: %s, author: %s, state: %s\n",			    *argv, prevrev.string, prevdate.string, prevauthor.string, prevstate.string);	}	exitmain(EXIT_SUCCESS);}#endif

⌨️ 快捷键说明

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