1 # include "../hdr/defines.h"
2 # include "../hdr/had.h"
3 
4 SCCSID(@(#)prt.c	4.1);
5 
6 /*
7 	Program to print parts or all of an SCCS file.
8 	Arguments to the program may appear in any order
9 	and consist of keyletters, which begin with '-',
10 	and named files.
11 
12 	If a direcory is given as an argument, each
13 	SCCS file within the directory is processed as if
14 	it had been specifically named. If a name of '-'
15 	is given, the standard input is read for a list
16 	of names of SCCS files to be processed.
17 	Non-SCCS files are ignored.
18 */
19 
20 # define NOEOF	0
21 # define BLANK(p)	while (!(*p == ' ' || *p == '\t')) p++;
22 
23 char had[26];
24 FILE *iptr;
25 char line[512];
26 char statistics[25];
27 struct delent {
28 	char type;
29 	char *osid;
30 	char *datetime;
31 	char *pgmr;
32 	char *serial;
33 	char *pred;
34 } del;
35 int num_files;
36 int prefix;
37 long cutoff;
38 long revcut;
39 int linenum;
40 char *ysid;
41 char *flagdesc[26] {	"",
42 			"branch",
43 			"ceiling",
44 			"default SID",
45 			"",
46 			"floor",
47 			"",
48 			"",
49 			"id keywd err/warn",
50 			"",
51 			"",
52 			"",
53 			"module",
54 			"null delta",
55 			"",
56 			"",
57 			"",
58 			"",
59 			"",
60 			"type",
61 			"",
62 			"validate MRs",
63 			"",
64 			"",
65 			"",
66 			""
67 };
68 
69 main(argc,argv)
70 int argc;
71 char *argv[];
72 {
73 	register int j;
74 	register char *p;
75 	char c;
76 	int testklt;
77 	extern prt();
78 	extern int Fcnt;
79 
80 	/*
81 	Set flags for 'fatal' to issue message, call clean-up
82 	routine, and terminate processing.
83 	*/
84 	Fflags = FTLMSG | FTLCLN | FTLEXIT;
85 
86 	testklt = 1;
87 
88 	/*
89 	The following loop processes keyletters and arguments.
90 	Note that these are processed only once for each
91 	invocation of 'main'.
92 	*/
93 	for (j = 1; j < argc; j++)
94 		if (argv[j][0] == '-' && (c = argv[j][1])) {
95 			p = &argv[j][2];
96 			switch (c) {
97 			case 'e':	/* print everything but body */
98 			case 's':	/* print only delta desc. and stats */
99 			case 'd':	/* print whole delta table */
100 			case 'a':	/* print all deltas */
101 			case 'i':	/* print inc, exc, and ignore info */
102 			case 'u':	/* print users allowed to do deltas */
103 			case 'f':	/* print flags */
104 			case 't':	/* print descriptive user-text */
105 			case 'b':	/* print body */
106 				break;
107 
108 			case 'y':	/* delta cutoff */
109 				ysid = p;
110 				prefix++;
111 				break;
112 
113 			case 'c':	/* time cutoff */
114 				if (*p && date_ab(p,&cutoff))
115 					fatal("bad date/time (cm5)");
116 				prefix++;
117 				break;
118 
119 			case 'r':	/* reverse time cutoff */
120 				if (*p && date_ab(p,&revcut))
121 					fatal ("bad date/time (cm5)");
122 				prefix++;
123 				break;
124 
125 			default:
126 				fatal("unknown key letter (cm1)");
127 			}
128 
129 			if (had[c - 'a']++ && testklt++)
130 				fatal("key letter twice (cm2)");
131 			argv[j] = 0;
132 		}
133 		else
134 			num_files++;
135 
136 	if (num_files == 0)
137 		fatal("missing file arg (cm3)");
138 
139 	if (HADC && HADR)
140 		fatal("both 'c' and 'r' keyletters specified (pr2)");
141 
142 	setsig();
143 
144 	/*
145 	Change flags for 'fatal' so that it will return to this
146 	routine (main) instead of terminating processing.
147 	*/
148 	Fflags =& ~FTLEXIT;
149 	Fflags =| FTLJMP;
150 
151 	/*
152 	Call 'prt' routine for each file argument.
153 	*/
154 	for (j = 1; j < argc; j++)
155 		if (p = argv[j])
156 			do_file(p,prt);
157 
158 	exit(Fcnt ? 1 : 0);
159 }
160 
161 
162 /*
163 	Routine that actually performs the 'prt' functions.
164 */
165 
166 prt(file)
167 char *file;
168 {
169 	int stopdel;
170 	int user, flag, text;
171 	char *p;
172 	long bindate;
173 
174 	if (setjmp(Fjmp))	/* set up to return here from 'fatal' */
175 		return;		/* and return to caller of prt */
176 
177 	if (HADE)
178 		HADD = HADI = HADU = HADF = HADT = 1;
179 
180 	if (!HADU && !HADF && !HADT && !HADB)
181 		HADD = 1;
182 
183 	if (!HADD)
184 		HADR = HADS = HADA = HADI = HADY = HADC = 0;
185 
186 	if (HADS && HADI)
187 		fatal("s and i conflict (pr1)");
188 
189 	iptr = xfopen(file,0);
190 
191 	p = lineread(NOEOF);
192 	if (*p++ != CTLCHAR || *p != HEAD)
193 		fatal("not an sccs file (co2)");
194 
195 	stopdel = 0;
196 
197 	if (!prefix)
198 		printf("\n%s:\n",file);
199 
200 	if (HADD) {
201 		while ((p = lineread(NOEOF)) && *p++ == CTLCHAR &&
202 				*p++ == STATS && !stopdel) {
203 			NONBLANK(p);
204 			copy(p,statistics);
205 
206 			p = lineread(NOEOF);
207 			getdel(&del,p);
208 
209 			if (!HADA && del.type != 'D') {
210 				read_to(EDELTAB);
211 				continue;
212 			}
213 			if (HADC) {
214 				date_ab(del.datetime,&bindate);
215 				if (bindate < cutoff) {
216 					stopdel = 1;
217 					break;
218 				}
219 			}
220 			if (HADR) {
221 				date_ab(del.datetime,&bindate);
222 				if (bindate >= revcut) {
223 					read_to(EDELTAB);
224 					continue;
225 				}
226 			}
227 			if (HADY && (equal(del.osid,ysid) || !(*ysid)))
228 				stopdel = 1;
229 
230 			printdel(file,&del);
231 
232 			while ((p = lineread(NOEOF)) && *p++ == CTLCHAR) {
233 				if (*p == EDELTAB)
234 					break;
235 				switch (*p) {
236 				case INCLUDE:
237 					if (HADI)
238 						printit(file,"Included:\t",p);
239 					break;
240 
241 				case EXCLUDE:
242 					if (HADI)
243 						printit(file,"Excluded:\t",p);
244 					break;
245 
246 				case IGNORE:
247 					if (HADI)
248 						printit(file,"Ignored:\t",p);
249 					break;
250 
251 				case MRNUM:
252 					if (!HADS)
253 						printit(file,"MRs:\t",p);
254 					break;
255 
256 				case COMMENTS:
257 					if (!HADS)
258 						printit(file,"",p);
259 					break;
260 
261 				default:
262 					fatal(sprintf(Error,
263 					"format error at line %d (co4)",linenum));
264 				}
265 			}
266 		}
267 		if (prefix)
268 			printf("\n");
269 
270 		if (stopdel && !(line[0] == CTLCHAR && line[1] == BUSERNAM))
271 			read_to(BUSERNAM);
272 	}
273 	else
274 		read_to(BUSERNAM);
275 
276 	if (HADU) {
277 		user = 0;
278 		printf("\nUsers allowed to make deltas --\n");
279 		while ((p = lineread(NOEOF)) && *p != CTLCHAR) {
280 			user = 1;
281 			printf("\t%s",p);
282 		}
283 		if (!user)
284 			printf("\teveryone\n");
285 	}
286 	else
287 		read_to(EUSERNAM);
288 
289 	if (HADF) {
290 		flag = 0;
291 		printf("\nFlags --\n");
292 		while ((p = lineread(NOEOF)) && *p++ == CTLCHAR &&
293 				*p++ == FLAG) {
294 			flag = 1;
295 			NONBLANK(p);
296 			printf("\t%s",flagdesc[*p - 'a']);
297 
298 			if (*++p) {
299 				NONBLANK(p);
300 				printf("\t%s",p);
301 			}
302 		}
303 		if (!flag)
304 			printf("\tnone\n");
305 	}
306 	else
307 		read_to(BUSERTXT);
308 
309 	if (HADT) {
310 		text = 0;
311 		printf("\nDescription --\n");
312 		while ((p = lineread(NOEOF)) && *p != CTLCHAR) {
313 			text = 1;
314 			printf("\t%s",p);
315 		}
316 		if (!text)
317 			printf("\tnone\n");
318 	}
319 	else
320 		read_to(EUSERTXT);
321 
322 	if (HADB) {
323 		printf("\n");
324 		while (p = lineread(EOF))
325 			if (*p == CTLCHAR)
326 				printf("*** %s", ++p);
327 			else
328 				printf("\t%s", p);
329 	}
330 
331 	fclose(iptr);
332 }
333 
334 
335 getdel(delp,lp)
336 register struct delent *delp;
337 register char *lp;
338 {
339 	lp =+ 2;
340 	NONBLANK(lp);
341 	delp->type = *lp++;
342 	NONBLANK(lp);
343 	delp->osid = lp;
344 	BLANK(lp);
345 	*lp++ = '\0';
346 	NONBLANK(lp);
347 	delp->datetime = lp;
348 	BLANK(lp);
349 	NONBLANK(lp);
350 	BLANK(lp);
351 	*lp++ = '\0';
352 	NONBLANK(lp);
353 	delp->pgmr = lp;
354 	BLANK(lp);
355 	*lp++ = '\0';
356 	NONBLANK(lp);
357 	delp->serial = lp;
358 	BLANK(lp);
359 	*lp++ = '\0';
360 	NONBLANK(lp);
361 	delp->pred = lp;
362 	repl(lp,'\n','\0');
363 }
364 
365 
366 read_to(ch)
367 register char ch;
368 {
369 	char *n;
370 
371 	while ((n = lineread(NOEOF)) &&
372 			!(*n++ == CTLCHAR && *n == ch))
373 		;
374 
375 	return(n);
376 }
377 
378 
379 lineread(eof)
380 register int eof;
381 {
382 	char *k;
383 
384 	k = fgets(line,512,iptr);
385 
386 	if (k == NULL && !eof)
387 		fatal("premature eof (co5)");
388 
389 	linenum++;
390 
391 	return(k);
392 }
393 
394 
395 printdel(file,delp)
396 register char *file;
397 register struct delent *delp;
398 {
399 	printf("\n");
400 
401 	if (prefix) {
402 		statistics[length(statistics) - 1] = '\0';
403 		printf("%s:\t",file);
404 	}
405 
406 	printf("%c %s\t%s\t%s\t%s\t%s\t%s",delp->type,delp->osid,
407 		delp->datetime,delp->pgmr,delp->serial,delp->pred,statistics);
408 }
409 
410 
411 printit(file,str,cp)
412 register char *file;
413 register char *str, *cp;
414 {
415 	cp++;
416 	NONBLANK(cp);
417 
418 	if (prefix) {
419 		cp[length(cp) - 1] = '\0';
420 		printf(" ");
421 	}
422 
423 	printf("%s%s",str,cp);
424 }
425