MACHINE defined by make(1), now
[unix-history] / usr / src / usr.bin / pascal / pxp / main.c
CommitLineData
252367af
DF
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
8char 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
8ea25423 14static char sccsid[] = "@(#)main.c 5.2 (Berkeley) %G%";
252367af
DF
15#endif not lint
16
d6a5dbff
PK
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
43char usagestr[] =
44 "pxp [ -acdefjntuw_ ] [ -23456789 ] [ -z [ name ... ] ] name.p";
45char *howfile = "/usr/lib/how_pxp";
46char *stdoutn = "Standard output";
47
48int unit = 4;
49
50FILE *ibuf;
51extern char errout;
52
53/*
54 * Main program for pxp.
55 * Process options, then call yymain
56 * to do all the real work.
57 */
58FILE *ibp;
59main(argc, argv)
60 int argc;
61 char *argv[];
62{
63 register char *cp;
64 register c;
65
66 if (argv[0][0] == 'a')
8ea25423 67 howfile += 9;
d6a5dbff
PK
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;
c7096a14
PK
148# ifdef RMOTHERS
149 case 'O':
150 rmothers++;
151 continue;
152# endif RMOTHERS
d6a5dbff
PK
153 default:
154 if (c >= '2' && c <= '9') {
155 unit = c - '0';
156 continue;
157 }
158usage:
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);
8ea25423
JL
197 for (c = getpid(); c; c /= 10)
198 *--cp |= (c % 10);
d6a5dbff
PK
199 if (freopen(stdoutn, "w", stdout) == NULL)
200bad:
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 */
220header()
221{
222 extern char version[];
223 static char reenter;
224 extern int outcol;
225
510f6c6a 226 gettime(filename);
d6a5dbff
PK
227 if (reenter) {
228 if (outcol)
229 putchar('\n');
230 putchar('\f');
231 }
232 reenter++;
233 if (profile || table) {
7c79ee59
PK
234 printf("Berkeley Pascal PXP -- Version %s\n\n%s %s\n\n",
235 version, myctime(&tvec), filename);
d6a5dbff
PK
236 printf("Profiled %s\n\n", myctime(&ptvec));
237 }
238}
239
240char 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 */
248pexit(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
264onintr()
265{
266
267 pexit(DIED);
268}
269
270puthedr()
271{
272
273 yysetfile(filename);
274}