home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
RCS_SRC.ZIP
/
RCSKEEP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-15
|
10KB
|
310 lines
/*
* RCS keyword extraction
*/
#ifndef lint
static char rcsid[]= "$Id: rcskeep.c,v 4.6 89/05/01 15:12:56 narten Exp $ Purdue CS";
#endif
/*****************************************************************************
* main routine: getoldkeys()
* Testprogram: define KEEPTEST
*****************************************************************************
*/
/* Copyright (C) 1982, 1988, 1989 Walter Tichy
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 modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, 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 of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RCS; see the file COPYING. If not, write to
the 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 4.6 89/05/01 15:12:56 narten
* changed copyright header to reflect current distribution rules
*
* Revision 4.5 88/11/08 12:01:05 narten
* changes from eggert@sm.unisys.com (Paul Eggert)
*
* 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 1.1 84/01/23 14:50:30 kcs
* Initial revision
*
* 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"
extern char * checkid();
extern FILE * fopen();
static int getval();
extern enum markers trymatch();
#define IDLENGTH 30
char prevauthor[IDLENGTH];
char prevdate[datelength];
char prevRCS[NCPFN];
char prevrev[revlength];
char prevsource[NCPPN];
char prevstate [IDLENGTH];
char prevlocker[IDLENGTH];
char dummy[IDLENGTH];
getoldkeys(fname)
char * fname;
/* Function: Tries to read keyword values for author, date,
* revision number, RCS file, (both with and without path),
* state, and workfilename out of the file fname.
* The results are placed into
* prevauthor, prevdate, prevRCS, prevrev, prevsource, 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 FILE *fp;
register int c;
char keyword[keylength+2];
register char * tp;
enum markers mresult;
/* initialize to empty */
prevauthor[0]=prevsource[0]=prevstate[0]=prevdate[0]=prevrev[0]= '\0';
if ( (fp = fopen(fname, "r") ) == NULL ) {
error("Can't open %s\n", fname);
return false;
}
while( (c=getc(fp)) != EOF) {
if ( c==KDELIM) {
/* try to get keyword */
tp = keyword;
while( (c=getc(fp))!=EOF && (tp< keyword+keylength) && (c!='\n')
&& (c!=KDELIM) && (c!=VDELIM))
*tp++ = c;
if (c==KDELIM) {VOID ungetc(c,fp);continue;}
if (c!=VDELIM) continue;
*tp++ = c;
*tp='\0';
while ((c=getc(fp))==' '||c=='\t'); /* skip blanks */
VOID ungetc(c,fp); /* needed for getval */
switch (mresult=trymatch(keyword,true)) {
case Author:
if (getval(fp,prevauthor,IDLENGTH,true))
if (!checkid(prevauthor, '\0')) goto errexit;
break;
case Date:
if (!getprevdate(fp,true)) goto errexit;
break;
case Header:
case Id:
if (mresult==Header) {
if (!getval(fp,prevsource,NCPPN,true)) break; /*unexpanded*/
} else {
if (!getval(fp,prevRCS,NCPFN,true)) break; /*unexpanded*/
}
if (!getval(fp,prevrev,revlength,false)) goto errexit;
if (!checknum(prevrev,-1)) {
error("Bad revision number");
goto errexit;
}
if (!getprevdate(fp,false)) goto errexit;
if (!getval(fp,prevauthor,IDLENGTH,false)) goto errexit;
if (!checkid(prevauthor, '\0')) goto errexit;
if (!getval(fp,prevstate,IDLENGTH,false)) goto errexit;
if (!checkid(prevstate, '\0')) goto errexit;
VOID getval(fp, dummy, IDLENGTH, true); /* optional locker*/
VOID getval(fp, prevlocker,IDLENGTH,true); /* optional locker*/
break;
case Locker:
VOID getval(fp,prevlocker,IDLENGTH,true);
if (!checkid(prevlocker, '\0')) goto errexit;
break;
case Log:
VOID getval(fp,prevRCS,NCPPN,true);
break;
case RCSfile:
VOID getval(fp,prevRCS,NCPFN,true);
break;
case Revision:
if (getval(fp,prevrev,revlength,true))
if (!checknum(prevrev,-1)) {
error("Bad revision number");
goto errexit;
}
break;
case Source:
VOID getval(fp,prevsource,NCPPN,true);
break;
case State:
if (getval(fp,prevstate,IDLENGTH,true))
if (!checkid(prevstate, '\0')) goto errexit;
break;
default:
continue;
}
if (getc(fp)!=KDELIM)
warn("Closing %c missing on keyword",KDELIM);
if (prevauthor[0]!='\0'&&prevrev[0]!='\0'&&prevstate[0]!='\0'&&
prevdate[0]!='\0' &&
((prevsource[0]!='\0')||(prevRCS[0]!='\0'))){
/* done; prevlocker is irrelevant */
break;
}
}
}
VOID fclose(fp);
return true;
errexit:
prevauthor[0]=prevsource[0]=prevstate[0]=prevdate[0]=prevrev[0]= '\0';
VOID fclose(fp); return false;
}
static int getval(fp,target,maxchars,optional)
register FILE *fp;
char * target; int maxchars, optional;
/* Function: Places a keyword value into target, but not more
* than maxchars characters. Prints an error if optional==false
* and there is no keyword. Returns true if one is found, false otherwise.
*/
{ register char * tp;
register int c;
tp=target;
c=getc(fp);
if (c==KDELIM) {
if (!optional)
error("Missing keyword value");
VOID ungetc(c,fp);
return false;
} else {
while (!(c==' '||c=='\n'||c=='\t'||c==KDELIM||c==EOF)) {
if (tp-target>=maxchars-1) {
error("keyword value too long");
return false;
} else {
*tp++ =c;
c=getc(fp);
}
}
*tp= '\0';
# ifdef KEEPTEST
VOID printf("getval: %s\n",target);
# endif
while(c==' '||c=='\t') c=getc(fp); /* skip trailing blanks */
}
VOID ungetc(c,fp);
return true;
}
int getprevdate(fp,optional)
FILE *fp;
int optional;
/* Function: reads a date prevdate; checks format
* If there is not date and optional==false, an error is printed.
* Returns false on error, true otherwise.
*/
{ char prevday[10];
char prevtime[10];
prevday[0]=prevtime[0]='\0';
if (!getval(fp,prevday,9,optional)) return optional;
if (!getval(fp,prevtime,9,false)) return false;
/*process date */
prevday[2]=prevday[5]=prevday[8]=prevtime[2]=prevtime[5]='.';
prevday[9]='\0';
VOID strcpy(prevdate,prevday);
VOID strcat(prevdate,prevtime);
if (!checknum(prevdate,5)) {
error("Bad date: %s",prevdate);
prevdate[0]='\0';
return false;
}
return true;
}
int checknum(sp,fields)
register char * sp; int fields;
{ register int dotcount;
if (sp==nil||*sp=='\0') return true;
dotcount=0;
while(*sp) {
if (*sp=='.') dotcount++;
elsif (ctab[*sp]!=DIGIT) return false;
sp++;
}
if (fields >= 0 && dotcount!=fields) return false;
return true;
}
#ifdef KEEPTEST
char * RCSfilename, * workfilename;
main(argc, argv)
int argc; char *argv[];
{
cmdid="keeptest";
while (*(++argv)) {
if (getoldkeys(*argv))
VOID printf("%s: revision: %s, date: %s, author: %s, state: %s\n",
*argv, prevrev, prevdate, prevauthor,prevstate);
VOID printf("Source: %s, RCSfile: %s\n",prevsource,prevRCS);
}
exit(0);
}
#endif