xref: /original-bsd/usr.bin/pascal/pxp/main.c (revision 5b10f61c)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 char copyright[] =
9 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10  All rights reserved.\n";
11 #endif not lint
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)main.c	5.1 (Berkeley) 06/05/85";
15 #endif not lint
16 
17 /*
18  * pxp - Pascal execution profiler
19  *
20  * Bill Joy UCB
21  * Version 1.2 January 1979
22  */
23 
24 #include "0.h"
25 
26 /*
27  * This program is described in detail in the "PXP 1.0 Implementation Notes"
28  *
29  * The structure of pxp is very similar to that of the translator pi.
30  * The major new pieces here are a set of profile data maintenance
31  * routines in the file pmon.c and a set of pretty printing utility
32  * routines in the file pp.c.
33  * The semantic routines of pi have been rewritten to do a simple
34  * reformatting tree walk, the parsing and scanning remains
35  * the same.
36  *
37  * This version does not place more than one statement per line and
38  * is not very intelligent about folding long lines, with only
39  * an ad hoc way of folding case label list and enumerated type
40  * declarations being implemented.
41  */
42 
43 char	usagestr[] =
44 	"pxp [ -acdefjntuw_ ] [ -23456789 ] [ -z [ name ... ] ] name.p";
45 char	*howfile =	"/usr/lib/how_pxp";
46 char	*stdoutn =	"Standard output";
47 
48 int	unit =	4;
49 
50 FILE	*ibuf;
51 extern	char errout;
52 
53 /*
54  * Main program for pxp.
55  * Process options, then call yymain
56  * to do all the real work.
57  */
58 FILE *ibp;
59 main(argc, argv)
60 	int argc;
61 	char *argv[];
62 {
63 	register char *cp;
64 	register c;
65 
66 	if (argv[0][0] == 'a')
67 		howfile =+ 9;
68 	argc--, argv++;
69 	if (argc == 0) {
70 		execl("/bin/cat", "cat", howfile, 0);
71 		goto usage;
72 	}
73 	while (argc > 0) {
74 		cp = argv[0];
75 		if (*cp++ != '-')
76 			break;
77 		while (c = *cp++) switch (c) {
78 #ifdef DEBUG
79 			case 'T':
80 				typetest++;
81 				continue;
82 			case 'A':
83 				testtrace++;
84 			case 'F':
85 				fulltrace++;
86 			case 'E':
87 				errtrace++;
88 				continue;
89 			case 'C':
90 				yycosts();
91 				pexit(NOSTART);
92 			case 'U':
93 				yyunique++;
94 				continue;
95 #endif
96 			case 'a':
97 				all++;
98 				continue;
99 			case 'c':
100 				core++;
101 				continue;
102 			case 'd':
103 				nodecl++;
104 				continue;
105 			case 'e':
106 				noinclude = -1;
107 				continue;
108 			case 'f':
109 				full++;
110 				continue;
111 			case 'j':
112 				justify++;
113 				continue;
114 			case 'l':
115 			case 'n':
116 				togopt(c);
117 				continue;
118 			case 'o':
119 				onefile++;
120 				continue;
121 			case 's':
122 				stripcomm++;
123 				continue;
124 			case 't':
125 				table++;
126 				continue;
127 			case 'u':
128 			case 'w':
129 				togopt(c);
130 				continue;
131 			case 'z':
132 				profile++;
133 				pflist = argv + 1;
134 				pflstc = 0;
135 				while (argc > 1) {
136 					if (dotted(argv[1], 'p'))
137 						break;
138 					pflstc++, argc--, argv++;
139 				}
140 				if (pflstc == 0)
141 					togopt(c);
142 				else
143 					nojunk++;
144 				continue;
145 			case '_':
146 				underline++;
147 				continue;
148 #			ifdef RMOTHERS
149 			case 'O':
150 				rmothers++;
151 				continue;
152 #			endif RMOTHERS
153 			default:
154 				if (c >= '2' && c <= '9') {
155 					unit = c - '0';
156 					continue;
157 				}
158 usage:
159 				Perror("Usage", usagestr);
160 				exit(1);
161 		}
162 		argc--, argv++;
163 	}
164 	if (core && !profile && !table)
165 		profile++;
166 	if (argc == 0 || argc > 2)
167 		goto usage;
168 	if (profile || table) {
169 		noinclude = 0;
170 		if (argc == 2) {
171 			argc--;
172 			getit(argv[1]);
173 		} else
174 			getit(core ? "core" : "pmon.out");
175 	} else
176 		noinclude++;
177 	if (argc != 1)
178 		goto usage;
179 	firstname = filename = argv[0];
180 	if (dotted(filename, 'i')) {
181 		if (profile || table)
182 			goto usage;
183 		noinclude = 1;
184 		bracket++;
185 	} else if (!dotted(filename, 'p')) {
186 		Perror(filename, "Name must end in '.p'");
187 		exit(1);
188 	}
189 	if ((ibuf = fopen(filename, "r")) == NULL)
190 		perror(filename), pexit(NOSTART);
191 	ibp = ibuf;
192 	if (onefile) {
193 		int onintr();
194 
195 		cp = (stdoutn = "/tmp/pxp00000") + 13;
196 		signal(2, onintr);
197 		for (c = getpid(); c; c =/ 10)
198 			*--cp =| (c % 10);
199 		if (freopen(stdoutn, "w", stdout) == NULL)
200 bad:
201 			perror(stdoutn), exit(1);
202 	} else {
203 		extern char _sobuf[BUFSIZ];
204 		setbuf(stdout, _sobuf);
205 	}
206 	if (profile || opt('l')) {
207 		opt('n')++;
208 		yysetfile(filename);
209 		opt('n')--;
210 	} else
211 		lastname = filename;
212 	errout = 2;
213 	yymain();
214 	/* No return */
215 }
216 
217 /*
218  * Put a header on a top of a page
219  */
220 header()
221 {
222 	extern char version[];
223 	static char reenter;
224 	extern int outcol;
225 
226 	gettime(filename);
227 	if (reenter) {
228 		if (outcol)
229 			putchar('\n');
230 		putchar('\f');
231 	}
232 	reenter++;
233 	if (profile || table) {
234 		printf("Berkeley Pascal PXP -- Version %s\n\n%s  %s\n\n",
235 			version, myctime(&tvec), filename);
236 		printf("Profiled %s\n\n", myctime(&ptvec));
237 	}
238 }
239 
240 char	ugh[] =	"Fatal error in pxp\n";
241 /*
242  * Exit from the Pascal system.
243  * We throw in an ungraceful termination
244  * message if c > 1 indicating a severe
245  * error such as running out of memory
246  * or an internal inconsistency.
247  */
248 pexit(c)
249 	int c;
250 {
251 	register char *cp;
252 	extern int outcol;
253 
254 	if (stdoutn[0] == '/')
255 		unlink(stdoutn);
256 	if (outcol)
257 		putchar('\n');
258 	flush();
259 	if (c == DIED)
260 		write(2, ugh, sizeof ugh);
261 	exit(c);
262 }
263 
264 onintr()
265 {
266 
267 	pexit(DIED);
268 }
269 
270 puthedr()
271 {
272 
273 	yysetfile(filename);
274 }
275