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