Sync usage with man page.
[netbsd-mini2440.git] / usr.bin / rcs / src / rcskeep.c
blob99d45312aa534594d656bb50c5ce13f08aaf82a7
1 /*
2 * RCS keyword extraction
3 */
4 #ifndef lint
5 static char rcsid[]= "$Id: rcskeep.c,v 1.1 1993/03/21 09:58:08 cgd Exp $ Purdue CS";
6 #endif
7 /*****************************************************************************
8 * main routine: getoldkeys()
9 * Testprogram: define KEEPTEST
10 *****************************************************************************
13 /* Copyright (C) 1982, 1988, 1989 Walter Tichy
14 * All rights reserved.
16 * Redistribution and use in source and binary forms are permitted
17 * provided that the above copyright notice and this paragraph are
18 * duplicated in all such forms and that any documentation,
19 * advertising materials, and other materials related to such
20 * distribution and use acknowledge that the software was developed
21 * by Walter Tichy.
22 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26 * Report all problems and direct all questions to:
27 * rcs-bugs@cs.purdue.edu
40 /* $Log: rcskeep.c,v $
41 * Revision 4.6 89/05/01 15:12:56 narten
42 * changed copyright header to reflect current distribution rules
44 * Revision 4.5 88/11/08 12:01:05 narten
45 * changes from eggert@sm.unisys.com (Paul Eggert)
47 * Revision 4.5 88/08/09 19:13:03 eggert
48 * Remove lint and speed up by making FILE *fp local, not global.
50 * Revision 4.4 87/12/18 11:44:21 narten
51 * more lint cleanups (Guy Harris)
53 * Revision 4.3 87/10/18 10:35:50 narten
54 * Updating version numbers. Changes relative to 1.1 actually relative
55 * to 4.1
57 * Revision 1.3 87/09/24 14:00:00 narten
58 * Sources now pass through lint (if you ignore printf/sprintf/fprintf
59 * warnings)
61 * Revision 1.2 87/03/27 14:22:29 jenkins
62 * Port to suns
64 * Revision 1.1 84/01/23 14:50:30 kcs
65 * Initial revision
67 * Revision 4.1 83/05/10 16:26:44 wft
68 * Added new markers Id and RCSfile; extraction added.
69 * Marker matching with trymatch().
71 * Revision 3.2 82/12/24 12:08:26 wft
72 * added missing #endif.
74 * Revision 3.1 82/12/04 13:22:41 wft
75 * Initial revision.
80 #define KEEPTEST
81 /* Testprogram; prints out the keyword values found. */
83 #include "rcsbase.h"
84 extern char * checkid();
85 extern FILE * fopen();
86 static int getval();
87 extern enum markers trymatch();
89 #define IDLENGTH 30
90 char prevauthor[IDLENGTH];
91 char prevdate[datelength];
92 char prevRCS[NCPFN];
93 char prevrev[revlength];
94 char prevsource[NCPPN];
95 char prevstate [IDLENGTH];
96 char prevlocker[IDLENGTH];
97 char dummy[IDLENGTH];
99 getoldkeys(fname)
100 char * fname;
101 /* Function: Tries to read keyword values for author, date,
102 * revision number, RCS file, (both with and without path),
103 * state, and workfilename out of the file fname.
104 * The results are placed into
105 * prevauthor, prevdate, prevRCS, prevrev, prevsource, prevstate.
106 * Aborts immediately if it finds an error and returns false.
107 * If it returns true, it doesn't mean that any of the
108 * values were found; instead, check to see whether the corresponding arrays
109 * contain the empty string.
112 register FILE *fp;
113 register int c;
114 char keyword[keylength+2];
115 register char * tp;
116 enum markers mresult;
118 /* initialize to empty */
119 prevauthor[0]=prevsource[0]=prevstate[0]=prevdate[0]=prevrev[0]= '\0';
121 if ( (fp = fopen(fname, "r") ) == NULL ) {
122 error("Can't open %s\n", fname);
123 return false;
125 while( (c=getc(fp)) != EOF) {
126 if ( c==KDELIM) {
127 /* try to get keyword */
128 tp = keyword;
129 while( (c=getc(fp))!=EOF && (tp< keyword+keylength) && (c!='\n')
130 && (c!=KDELIM) && (c!=VDELIM))
131 *tp++ = c;
133 if (c==KDELIM) {VOID ungetc(c,fp);continue;}
134 if (c!=VDELIM) continue;
135 *tp++ = c;
136 *tp='\0';
137 while ((c=getc(fp))==' '||c=='\t'); /* skip blanks */
138 VOID ungetc(c,fp); /* needed for getval */
140 switch (mresult=trymatch(keyword,true)) {
141 case Author:
142 if (getval(fp,prevauthor,IDLENGTH,true))
143 if (!checkid(prevauthor, '\0')) goto errexit;
144 break;
145 case Date:
146 if (!getprevdate(fp,true)) goto errexit;
147 break;
148 case Header:
149 case Id:
150 if (mresult==Header) {
151 if (!getval(fp,prevsource,NCPPN,true)) break; /*unexpanded*/
152 } else {
153 if (!getval(fp,prevRCS,NCPFN,true)) break; /*unexpanded*/
155 if (!getval(fp,prevrev,revlength,false)) goto errexit;
156 if (!checknum(prevrev,-1)) {
157 error("Bad revision number");
158 goto errexit;
160 if (!getprevdate(fp,false)) goto errexit;
161 if (!getval(fp,prevauthor,IDLENGTH,false)) goto errexit;
162 if (!checkid(prevauthor, '\0')) goto errexit;
163 if (!getval(fp,prevstate,IDLENGTH,false)) goto errexit;
164 if (!checkid(prevstate, '\0')) goto errexit;
165 VOID getval(fp, dummy, IDLENGTH, true); /* optional locker*/
166 VOID getval(fp, prevlocker,IDLENGTH,true); /* optional locker*/
167 break;
168 case Locker:
169 VOID getval(fp,prevlocker,IDLENGTH,true);
170 if (!checkid(prevlocker, '\0')) goto errexit;
171 break;
172 case Log:
173 VOID getval(fp,prevRCS,NCPPN,true);
174 break;
175 case RCSfile:
176 VOID getval(fp,prevRCS,NCPFN,true);
177 break;
178 case Revision:
179 if (getval(fp,prevrev,revlength,true))
180 if (!checknum(prevrev,-1)) {
181 error("Bad revision number");
182 goto errexit;
184 break;
185 case Source:
186 VOID getval(fp,prevsource,NCPPN,true);
187 break;
188 case State:
189 if (getval(fp,prevstate,IDLENGTH,true))
190 if (!checkid(prevstate, '\0')) goto errexit;
191 break;
192 default:
193 continue;
195 if (getc(fp)!=KDELIM)
196 warn("Closing %c missing on keyword",KDELIM);
197 if (prevauthor[0]!='\0'&&prevrev[0]!='\0'&&prevstate[0]!='\0'&&
198 prevdate[0]!='\0' &&
199 ((prevsource[0]!='\0')||(prevRCS[0]!='\0'))){
200 /* done; prevlocker is irrelevant */
201 break;
205 VOID fclose(fp);
206 return true;
208 errexit:
209 prevauthor[0]=prevsource[0]=prevstate[0]=prevdate[0]=prevrev[0]= '\0';
210 VOID fclose(fp); return false;
214 static int getval(fp,target,maxchars,optional)
215 register FILE *fp;
216 char * target; int maxchars, optional;
217 /* Function: Places a keyword value into target, but not more
218 * than maxchars characters. Prints an error if optional==false
219 * and there is no keyword. Returns true if one is found, false otherwise.
221 { register char * tp;
222 register int c;
224 tp=target;
225 c=getc(fp);
226 if (c==KDELIM) {
227 if (!optional)
228 error("Missing keyword value");
229 VOID ungetc(c,fp);
230 return false;
231 } else {
232 while (!(c==' '||c=='\n'||c=='\t'||c==KDELIM||c==EOF)) {
233 if (tp-target>=maxchars-1) {
234 error("keyword value too long");
235 return false;
236 } else {
237 *tp++ =c;
238 c=getc(fp);
241 *tp= '\0';
242 # ifdef KEEPTEST
243 VOID printf("getval: %s\n",target);
244 # endif
245 while(c==' '||c=='\t') c=getc(fp); /* skip trailing blanks */
247 VOID ungetc(c,fp);
248 return true;
252 int getprevdate(fp,optional)
253 FILE *fp;
254 int optional;
255 /* Function: reads a date prevdate; checks format
256 * If there is not date and optional==false, an error is printed.
257 * Returns false on error, true otherwise.
259 { char prevday[10];
260 char prevtime[10];
262 prevday[0]=prevtime[0]='\0';
263 if (!getval(fp,prevday,9,optional)) return optional;
264 if (!getval(fp,prevtime,9,false)) return false;
265 /*process date */
266 prevday[2]=prevday[5]=prevday[8]=prevtime[2]=prevtime[5]='.';
267 prevday[9]='\0';
268 VOID strcpy(prevdate,prevday);
269 VOID strcat(prevdate,prevtime);
270 if (!checknum(prevdate,5)) {
271 error("Bad date: %s",prevdate);
272 prevdate[0]='\0';
273 return false;
275 return true;
278 int checknum(sp,fields)
279 register char * sp; int fields;
280 { register int dotcount;
281 if (sp==nil||*sp=='\0') return true;
282 dotcount=0;
283 while(*sp) {
284 if (*sp=='.') dotcount++;
285 elsif (ctab[*sp]!=DIGIT) return false;
286 sp++;
288 if (fields >= 0 && dotcount!=fields) return false;
289 return true;
294 #ifdef KEEPTEST
295 char * RCSfilename, * workfilename;
297 main(argc, argv)
298 int argc; char *argv[];
300 cmdid="keeptest";
301 while (*(++argv)) {
302 if (getoldkeys(*argv))
303 VOID printf("%s: revision: %s, date: %s, author: %s, state: %s\n",
304 *argv, prevrev, prevdate, prevauthor,prevstate);
305 VOID printf("Source: %s, RCSfile: %s\n",prevsource,prevRCS);
307 exit(0);
309 #endif