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