|
|
1.1 root 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
8: char 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
14: static char sccsid[] = "@(#)main.c 5.3 (Berkeley) 6/2/88";
15: #endif not lint
16:
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:
43: char usagestr[] =
44: "pxp [ -acdefjntuw_ ] [ -23456789 ] [ -z [ name ... ] ] name.p";
45: char *howfile = "/usr/lib/how_pxp";
46: char *stdoutn = "Standard output";
47:
48: int unit = 4;
49:
50: FILE *ibuf;
51: extern char errout;
52:
53: /*
54: * Main program for pxp.
55: * Process options, then call yymain
56: * to do all the real work.
57: */
58: FILE *ibp;
59: main(argc, argv)
60: int argc;
61: char *argv[];
62: {
63: register char *cp;
64: register c;
65:
66: if (argv[0][0] == 'a')
67: howfile += 9;
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;
148: # ifdef RMOTHERS
149: case 'O':
150: rmothers++;
151: continue;
152: # endif RMOTHERS
153: default:
154: if (c >= '2' && c <= '9') {
155: unit = c - '0';
156: continue;
157: }
158: usage:
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);
197: for (c = getpid(); c; c /= 10)
198: *--cp |= (c % 10);
199: if (freopen(stdoutn, "w", stdout) == NULL)
200: bad:
201: perror(stdoutn), exit(1);
202: }
203: if (profile || opt('l')) {
204: opt('n')++;
205: yysetfile(filename);
206: opt('n')--;
207: } else
208: lastname = filename;
209: errout = 2;
210: yymain();
211: /* No return */
212: }
213:
214: /*
215: * Put a header on a top of a page
216: */
217: header()
218: {
219: extern char version[];
220: static char reenter;
221: extern int outcol;
222:
223: gettime(filename);
224: if (reenter) {
225: if (outcol)
226: putchar('\n');
227: putchar('\f');
228: }
229: reenter++;
230: if (profile || table) {
231: printf("Berkeley Pascal PXP -- Version %s\n\n%s %s\n\n",
232: version, myctime(&tvec), filename);
233: printf("Profiled %s\n\n", myctime(&ptvec));
234: }
235: }
236:
237: char ugh[] = "Fatal error in pxp\n";
238: /*
239: * Exit from the Pascal system.
240: * We throw in an ungraceful termination
241: * message if c > 1 indicating a severe
242: * error such as running out of memory
243: * or an internal inconsistency.
244: */
245: pexit(c)
246: int c;
247: {
248: register char *cp;
249: extern int outcol;
250:
251: if (stdoutn[0] == '/')
252: unlink(stdoutn);
253: if (outcol)
254: putchar('\n');
255: flush();
256: if (c == DIED)
257: write(2, ugh, sizeof ugh);
258: exit(c);
259: }
260:
261: onintr()
262: {
263:
264: pexit(DIED);
265: }
266:
267: puthedr()
268: {
269:
270: yysetfile(filename);
271: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.