1 static char *sccsid = "@(#)main.c 1.2 (Berkeley) 08/13/82"; 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 30 char usagestr[] = 31 "pxp [ -acdefjntuw_ ] [ -23456789 ] [ -z [ name ... ] ] name.p"; 32 char *howfile = "/usr/lib/how_pxp"; 33 char *stdoutn = "Standard output"; 34 35 int unit = 4; 36 37 FILE *ibuf; 38 extern char errout; 39 40 /* 41 * Main program for pxp. 42 * Process options, then call yymain 43 * to do all the real work. 44 */ 45 FILE *ibp; 46 main(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; 135 default: 136 if (c >= '2' && c <= '9') { 137 unit = c - '0'; 138 continue; 139 } 140 usage: 141 Perror("Usage", usagestr); 142 exit(1); 143 } 144 argc--, argv++; 145 } 146 if (core && !profile && !table) 147 profile++; 148 if (argc == 0 || argc > 2) 149 goto usage; 150 if (profile || table) { 151 noinclude = 0; 152 if (argc == 2) { 153 argc--; 154 getit(argv[1]); 155 } else 156 getit(core ? "core" : "pmon.out"); 157 } else 158 noinclude++; 159 if (argc != 1) 160 goto usage; 161 firstname = filename = argv[0]; 162 if (dotted(filename, 'i')) { 163 if (profile || table) 164 goto usage; 165 noinclude = 1; 166 bracket++; 167 } else if (!dotted(filename, 'p')) { 168 Perror(filename, "Name must end in '.p'"); 169 exit(1); 170 } 171 if ((ibuf = fopen(filename, "r")) == NULL) 172 perror(filename), pexit(NOSTART); 173 ibp = ibuf; 174 if (onefile) { 175 int onintr(); 176 177 cp = (stdoutn = "/tmp/pxp00000") + 13; 178 signal(2, onintr); 179 for (c = getpid(); c; c =/ 10) 180 *--cp =| (c % 10); 181 if (freopen(stdoutn, "w", stdout) == NULL) 182 bad: 183 perror(stdoutn), exit(1); 184 } else { 185 extern char _sobuf[BUFSIZ]; 186 setbuf(stdout, _sobuf); 187 } 188 if (profile || opt('l')) { 189 opt('n')++; 190 yysetfile(filename); 191 opt('n')--; 192 } else 193 lastname = filename; 194 errout = 2; 195 yymain(); 196 /* No return */ 197 } 198 199 /* 200 * Put a header on a top of a page 201 */ 202 header() 203 { 204 extern char version[]; 205 static char reenter; 206 extern int outcol; 207 208 gettime(); 209 if (reenter) { 210 if (outcol) 211 putchar('\n'); 212 putchar('\f'); 213 } 214 reenter++; 215 if (profile || table) { 216 printf("Berkeley Pascal PXP -- Version %s\n\n%s %s\n\n", 217 version, myctime(&tvec), filename); 218 printf("Profiled %s\n\n", myctime(&ptvec)); 219 } 220 } 221 222 char ugh[] = "Fatal error in pxp\n"; 223 /* 224 * Exit from the Pascal system. 225 * We throw in an ungraceful termination 226 * message if c > 1 indicating a severe 227 * error such as running out of memory 228 * or an internal inconsistency. 229 */ 230 pexit(c) 231 int c; 232 { 233 register char *cp; 234 extern int outcol; 235 236 if (stdoutn[0] == '/') 237 unlink(stdoutn); 238 if (outcol) 239 putchar('\n'); 240 flush(); 241 if (c == DIED) 242 write(2, ugh, sizeof ugh); 243 exit(c); 244 } 245 246 onintr() 247 { 248 249 pexit(DIED); 250 } 251 252 puthedr() 253 { 254 255 yysetfile(filename); 256 } 257