|
|
1.1 root 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:
29: char usagestr[] =
30: "pxp [ -acdefjntuw_ ] [ -23456789 ] [ -z [ name ... ] ] name.p";
31: char *howfile = "/usr/lib/how_pxp";
32: char *stdoutn = "Standard output";
33:
34: int unit = 4;
35:
36: FILE *ibuf;
37: extern char errout;
38:
39: /*
40: * Main program for pxp.
41: * Process options, then call yymain
42: * to do all the real work.
43: */
44: FILE *ibp;
45: main(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: }
139: usage:
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)
181: bad:
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: */
201: header()
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:
220: char 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: */
228: pexit(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:
244: onintr()
245: {
246:
247: pexit(DIED);
248: }
249:
250: puthedr()
251: {
252:
253: yysetfile(filename);
254: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.