1: /* 2: * RCS keyword extraction 3: */ 4: static char rcsid[]= 5: "$Header: /usr/wft/RCS/SRC/RCS/rcskeep.c,v 3.2 82/12/24 12:08:26 wft Exp $ Purdue CS"; 6: /***************************************************************************** 7: * main routine: getoldkeys() 8: * Testprogram: define GETOLDTEST 9: ***************************************************************************** 10: * 11: * Copyright (C) 1982 by Walter F. Tichy 12: * Purdue University 13: * Computer Science Department 14: * West Lafayette, IN 47907 15: * 16: * All rights reserved. No part of this software may be sold or distributed 17: * in any form or by any means without the prior written permission of the 18: * author. 19: * Report problems and direct all inquiries to Tichy@purdue (ARPA net). 20: */ 21: 22: 23: 24: /* $Log: rcskeep.c,v $ 25: * Revision 3.2 82/12/24 12:08:26 wft 26: * added missing #endif. 27: * 28: * Revision 3.1 82/12/04 13:22:41 wft 29: * Initial revision. 30: * 31: */ 32: 33: /* 34: #define GETOLDTEST 35: /* Testprogram; prints out the keyword values found. */ 36: 37: #include "rcsbase.h" 38: extern char * checkid(); 39: extern FILE * fopen(); 40: 41: FILE * fp; 42: #define IDLENGTH 30 43: char prevauthor[IDLENGTH]; 44: char prevdate[datelength]; 45: char prevrev[revlength]; 46: char prevsource[NCPPN]; 47: char prevstate [IDLENGTH]; 48: char prevlocker[IDLENGTH]; 49: 50: getoldkeys(fname) 51: /* Function: Tries to read keyword values for author, date, 52: * revision number, RCS file, and state out of the file fname. 53: * The results are placed into 54: * prevauthor, prevdate, prevrev, prevsource, and prevstate. 55: * Aborts immediately if it finds an error and returns false. 56: * If it returns true, it doesn't mean that any of the 57: * values were found; instead, check to see whether the corresponding arrays 58: * contain the empty string. 59: */ 60: { 61: register int c; 62: char keyword[keylength+2]; 63: register char * tp; 64: 65: /* initialize to empty */ 66: prevauthor[0]=prevsource[0]=prevstate[0]=prevdate[0]=prevrev[0]= '\0'; 67: 68: if ( (fp = fopen(fname, "r") ) == NULL ) { 69: error("Can't open %s\n", fname); 70: return false; 71: } 72: while( (c=getc(fp)) != EOF) { 73: if ( c==KDELIM) { 74: /* try to get keyword */ 75: tp = keyword; 76: while( ctab[(c=getc(fp))]==LETTER && tp< keyword+keylength) 77: *tp++ = c; 78: if (c==KDELIM) {ungetc(c,fp);continue;} 79: if (c!=VDELIM) continue; 80: *tp='\0'; 81: while ((c=getc(fp))==' '||c=='\t'); /* skip blanks */ 82: ungetc(c,fp); /* needed for getval */ 83: if (strcmp(keyword, AUTHOR)==0 ) { 84: if (getval(prevauthor,IDLENGTH,true)) 85: if (!checkid(prevauthor)) goto errexit; 86: } elsif ( strcmp(keyword,DATE)==0 ) { 87: if (!getprevdate(true)) goto errexit; 88: } elsif ( strcmp(keyword, HEADER)==0 ) { 89: if (getval(prevsource,NCPPN,true)) { 90: if (!getval(prevrev,revlength,false)) goto errexit; 91: if (!checknum(prevrev,-1)) { 92: error("Bad revision number"); 93: goto errexit; 94: } 95: if (!getprevdate(false)) goto errexit; 96: if (!getval(prevauthor,IDLENGTH,false)) goto errexit; 97: if (!checkid(prevauthor)) goto errexit; 98: if (!getval(prevstate,IDLENGTH,false)) goto errexit; 99: if (!checkid(prevstate)) goto errexit; 100: } 101: } elsif ( strcmp(keyword, LOCKER)==0 ) { 102: getval(prevlocker,IDLENGTH,true); 103: } elsif ( strcmp(keyword, LOG)==0 ) { 104: getval(prevsource,NCPPN,true); 105: } elsif (strcmp(keyword, REVISION)==0 ) { 106: if (getval(prevrev,revlength,true)) 107: if (!checknum(prevrev,-1)) { 108: error("Bad revision number"); 109: goto errexit; 110: } 111: } elsif (strcmp(keyword, SOURCE)==0 ) { 112: getval(prevsource,NCPPN,true); 113: } elsif ( strcmp(keyword, STATE)==0 ) { 114: if (getval(prevstate,IDLENGTH,true)) 115: if (!checkid(prevstate)) goto errexit; 116: } else { 117: continue; 118: } 119: if (getc(fp)!=KDELIM) 120: warn("Closing %c missing on keyword",KDELIM); 121: if (prevauthor[0]!='\0'&&prevrev[0]!='\0'&&prevstate[0]!='\0'&& 122: prevdate[0]!='\0' && prevsource[0]!='\0') { 123: /* done; prevlocker is irrelevant */ 124: break; 125: } 126: } 127: } 128: fclose(fp); 129: return true; 130: 131: errexit: 132: prevauthor[0]=prevsource[0]=prevstate[0]=prevdate[0]=prevrev[0]= '\0'; 133: fclose(fp); return false; 134: } 135: 136: 137: getval(target,maxchars,optional) 138: char * target; int maxchars, optional; 139: /* Function: Places a keyword value into target, but not more 140: * than maxchars characters. Prints an error if optiona==false 141: * and there is no keyword. Returns true if one is found, false otherwise. 142: */ 143: { register char * tp; 144: register int c; 145: 146: tp=target; 147: c=getc(fp); 148: if (c==KDELIM) { 149: if (!optional) 150: error("Missing keyword value"); 151: ungetc(c,fp); 152: return false; 153: } else { 154: while (!(c==' '||c=='\n'||c=='\t'||c==KDELIM||c==EOF)) { 155: if (tp-target>=maxchars-1) { 156: error("keyword value too long"); 157: return false; 158: } else { 159: *tp++ =c; 160: c=getc(fp); 161: } 162: } 163: *tp= '\0'; 164: # ifdef GETOLDTEST 165: printf("getval: %s\n",target); 166: # endif 167: while(c==' '||c=='\t') c=getc(fp); /* skip trailing blanks */ 168: } 169: ungetc(c,fp); 170: return true; 171: } 172: 173: 174: int getprevdate(optional) 175: int optional; 176: /* Function: reads a date prevdate; checks format 177: * If there is not date and optional==false, an error is printed. 178: * Returns false on error, true otherwise. 179: */ 180: { char prevday[10]; 181: char prevtime[10]; 182: 183: prevday[0]=prevtime[0]='\0'; 184: if (!getval(prevday,9,optional)) return optional; 185: if (!getval(prevtime,9,false)) return false; 186: /*process date */ 187: prevday[2]=prevday[5]=prevday[8]=prevtime[2]=prevtime[5]='.'; 188: prevday[9]='\0'; 189: strcpy(prevdate,prevday); 190: strcat(prevdate,prevtime); 191: if (!checknum(prevdate,5)) { 192: error("Bad date: %s",prevdate); 193: prevdate[0]='\0'; 194: return false; 195: } 196: return true; 197: } 198: 199: int checknum(sp,fields) 200: register char * sp; int fields; 201: { register int dotcount; 202: if (sp==nil||*sp=='\0') return true; 203: dotcount=0; 204: while(*sp) { 205: if (*sp=='.') dotcount++; 206: elsif (ctab[*sp]!=DIGIT) return false; 207: sp++; 208: } 209: if (fields >= 0 && dotcount!=fields) return false; 210: return true; 211: } 212: 213: 214: 215: #ifdef GETOLDTEST 216: cleanup(){} /* dummy */ 217: 218: main(argc, argv) 219: int argc; char *argv[]; 220: { 221: cmdid="getoldkeys"; 222: while (*(++argv)) { 223: if (getoldkeys(*argv)) 224: printf("%s: revision: %s, date: %s, author: %s, state: %s\n", 225: *argv, prevrev, prevdate, prevauthor,prevstate); 226: } 227: } 228: #endif