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