Start development on BSD 2
[unix-history] / .ref-BSD-1 / pxp / main.c
CommitLineData
4a9bdf3d
BJ
1#
2/*
3 * pxp - Pascal execution profiler
4 *
5 * Bill Joy UCB
6 * Version 1.0 August 1977
7 */
8
9#include "whoami"
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 compiler pc.
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 pc 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 reformat comments, rather discards them.
24 * It also does not place more than one statement per line and
25 * is not very intelligent about folding long lines, with only
26 * an ad hoc way of folding case label list and enumerated type
27 * declarations being implemented.
28 */
29
30char usagestr[]
31 "pxp [ -acdefjntuw_ ] [ -23456789 ] [ -z [ name ... ] ] name.p";
32char *howfile "/usr/lib/how_pxp";
33
34int unit 4;
35
36extern int ibuf[259];
37extern char errout;
38
39/*
40 * Main program for pxp.
41 * Process options, then call yymain
42 * to do all the real work.
43 */
44main(argc, argv)
45 int argc;
46 char *argv[];
47{
48 register char *cp;
49 register c;
50
51 if (argv[0][0] == 'a')
52 howfile =+ 9;
53 argc--, argv++;
54 if (argc == 0) {
55 execl("/bin/cat", "cat", howfile, 0);
56 goto usage;
57 }
58 while (argc > 0) {
59 cp = argv[0];
60 if (*cp++ != '-')
61 break;
62 while (c = *cp++) switch (c) {
63#ifdef DEBUG
64 case 'T':
65 typetest++;
66 continue;
67 case 'A':
68 testtrace++;
69 case 'F':
70 fulltrace++;
71 case 'E':
72 errtrace++;
73 continue;
74 case 'C':
75 yycosts();
76 pexit(NOSTART);
77 case 'U':
78 yyunique++;
79 continue;
80#endif
81 case 'a':
82 all++;
83 continue;
84 case 'c':
85 core++;
86 continue;
87 case 'd':
88 nodecl++;
89 continue;
90 case 'e':
91 noinclude = -1;
92 continue;
93 case 'f':
94 full++;
95 continue;
96 case 'j':
97 justify++;
98 continue;
99 case 'l':
100 case 'n':
101 togopt(c);
102 continue;
103 case 's':
104 stripcomm++;
105 continue;
106 case 't':
107 table++;
108 continue;
109 case 'u':
110 case 'w':
111 togopt(c);
112 continue;
113 case 'z':
114 profile++;
115 pflist = argv + 1;
116 pflstc = 0;
117 while (argc > 1) {
118 if (dotted(argv[1], 'p'))
119 break;
120 pflstc++, argc--, argv++;
121 }
122 if (pflstc == 0)
123 togopt(c);
124 else
125 nojunk++;
126 continue;
127 case '_':
128 underline++;
129 continue;
130 default:
131 if (c >= '2' && c <= '9') {
132 unit = c - '0';
133 continue;
134 }
135usage:
136 Perror("Usage", usagestr);
137 exit(1);
138 }
139 argc--, argv++;
140 }
141 if (core && !profile && !table)
142 profile++;
143 if (argc == 0 || argc > 2)
144 goto usage;
145 if (profile || table) {
146 noinclude = 0;
147 if (argc == 2) {
148 argc--;
149 getit(argv[1]);
150 } else
151 getit(core ? "core" : "pmon.out");
152 } else
153 noinclude++;
154 if (argc != 1)
155 goto usage;
156 filename = argv[0];
157 if (dotted(filename, 'i')) {
158 if (profile || table)
159 goto usage;
160 noinclude = 1;
161 bracket++;
162 } else if (!dotted(filename, 'p')) {
163 Perror(filename, "Name must end in '.p'");
164 exit(1);
165 }
166 if (fopen(filename, ibuf) < 0)
167 perror(filename), pexit(NOSTART);
168 fout[0] = dup(1);
169 if (profile || opt('l')) {
170 opt('n')++;
171 yysetfile(filename);
172 opt('n')--;
173 } else
174 lastname = filename;
175 errout = dup(2);
176 yymain();
177 /* No return */
178}
179
180/*
181 * Put a header on a top of a page
182 */
183header()
184{
185 extern char version[];
186 static char reenter;
187 extern int outcol;
188
189 gettime();
190 if (reenter) {
191 if (outcol)
192 putchar('\n');
193 putchar('\f');
194 }
195 reenter++;
196 if (profile || table) {
197 printf("UNIX Pascal PXP -- Version 1.0 (%s)\n\n%s %s\n\n", version, myctime(tvec), filename);
198 printf("Profiled %s\n\n", myctime(ptvec));
199 }
200}
201
202char ugh[] "Fatal error in pxp\n";
203/*
204 * Exit from the Pascal system.
205 * We throw in an ungraceful termination
206 * message if c > 1 indicating a severe
207 * error such as running out of memory
208 * or an internal inconsistency.
209 */
210pexit(c)
211 int c;
212{
213 register char *cp;
214 extern int outcol;
215
216 if (outcol)
217 putchar('\n');
218 flush();
219 if (c == DIED)
220 write(2, ugh, sizeof ugh);
221 exit(c);
222}
223
224extern int errno;
225/*
226 * Pxp uses a modified putchar
227 * which calls xflush to flush its buffer
228 * rather than the normal fflush.
229 * This allows us to check for write errors
230 * on standard output which we really care
231 * about, because we may be creating a new
232 * source program.
233 */
234xflush()
235{
236
237 errno = 0;
238 flush();
239 if (errno) {
240 perror("Standard output");
241 exit(DIED);
242 }
243}
244
245puthedr()
246{
247
248 yysetfile(filename);
249}