/* * RCS keyword extraction */ static char rcsid[]= "$Header: /usr/wft/RCS/SRC/RCS/rcskeep.c,v 3.2 82/12/24 12:08:26 wft Exp $ Purdue CS"; /***************************************************************************** * main routine: getoldkeys() * Testprogram: define GETOLDTEST ***************************************************************************** * * Copyright (C) 1982 by Walter F. Tichy * Purdue University * Computer Science Department * West Lafayette, IN 47907 * * All rights reserved. No part of this software may be sold or distributed * in any form or by any means without the prior written permission of the * author. * Report problems and direct all inquiries to Tichy@purdue (ARPA net). */ /* $Log: rcskeep.c,v $ * 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 GETOLDTEST /* Testprogram; prints out the keyword values found. */ #include "rcsbase.h" extern char * checkid(); extern FILE * fopen(); FILE * fp; #define IDLENGTH 30 char prevauthor[IDLENGTH]; char prevdate[datelength]; char prevrev[revlength]; char prevsource[NCPPN]; char prevstate [IDLENGTH]; char prevlocker[IDLENGTH]; getoldkeys(fname) /* Function: Tries to read keyword values for author, date, * revision number, RCS file, and state out of the file fname. * The results are placed into * prevauthor, prevdate, prevrev, prevsource, and 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+2]; register char * tp; /* 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( ctab[(c=getc(fp))]==LETTER && tp< keyword+keylength) *tp++ = c; if (c==KDELIM) {ungetc(c,fp);continue;} if (c!=VDELIM) continue; *tp='\0'; while ((c=getc(fp))==' '||c=='\t'); /* skip blanks */ ungetc(c,fp); /* needed for getval */ if (strcmp(keyword, AUTHOR)==0 ) { if (getval(prevauthor,IDLENGTH,true)) if (!checkid(prevauthor)) goto errexit; } elsif ( strcmp(keyword,DATE)==0 ) { if (!getprevdate(true)) goto errexit; } elsif ( strcmp(keyword, HEADER)==0 ) { if (getval(prevsource,NCPPN,true)) { if (!getval(prevrev,revlength,false)) goto errexit; if (!checknum(prevrev,-1)) { error("Bad revision number"); goto errexit; } if (!getprevdate(false)) goto errexit; if (!getval(prevauthor,IDLENGTH,false)) goto errexit; if (!checkid(prevauthor)) goto errexit; if (!getval(prevstate,IDLENGTH,false)) goto errexit; if (!checkid(prevstate)) goto errexit; } } elsif ( strcmp(keyword, LOCKER)==0 ) { getval(prevlocker,IDLENGTH,true); } elsif ( strcmp(keyword, LOG)==0 ) { getval(prevsource,NCPPN,true); } elsif (strcmp(keyword, REVISION)==0 ) { if (getval(prevrev,revlength,true)) if (!checknum(prevrev,-1)) { error("Bad revision number"); goto errexit; } } elsif (strcmp(keyword, SOURCE)==0 ) { getval(prevsource,NCPPN,true); } elsif ( strcmp(keyword, STATE)==0 ) { if (getval(prevstate,IDLENGTH,true)) if (!checkid(prevstate)) goto errexit; } else { 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') { /* done; prevlocker is irrelevant */ break; } } } fclose(fp); return true; errexit: prevauthor[0]=prevsource[0]=prevstate[0]=prevdate[0]=prevrev[0]= '\0'; fclose(fp); return false; } getval(target,maxchars,optional) char * target; int maxchars, optional; /* Function: Places a keyword value into target, but not more * than maxchars characters. Prints an error if optiona==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"); 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 GETOLDTEST printf("getval: %s\n",target); # endif while(c==' '||c=='\t') c=getc(fp); /* skip trailing blanks */ } ungetc(c,fp); return true; } int getprevdate(optional) 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(prevday,9,optional)) return optional; if (!getval(prevtime,9,false)) return false; /*process date */ prevday[2]=prevday[5]=prevday[8]=prevtime[2]=prevtime[5]='.'; prevday[9]='\0'; strcpy(prevdate,prevday); 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 GETOLDTEST cleanup(){} /* dummy */ main(argc, argv) int argc; char *argv[]; { cmdid="getoldkeys"; while (*(++argv)) { if (getoldkeys(*argv)) printf("%s: revision: %s, date: %s, author: %s, state: %s\n", *argv, prevrev, prevdate, prevauthor,prevstate); } } #endif