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.1 (Berkeley) 06/05/85"; 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 } 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 */ 220 header() 221 { 222 extern char version[]; 223 static char reenter; 224 extern int outcol; 225 226 gettime(filename); 227 if (reenter) { 228 if (outcol) 229 putchar('\n'); 230 putchar('\f'); 231 } 232 reenter++; 233 if (profile || table) { 234 printf("Berkeley Pascal PXP -- Version %s\n\n%s %s\n\n", 235 version, myctime(&tvec), filename); 236 printf("Profiled %s\n\n", myctime(&ptvec)); 237 } 238 } 239 240 char 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 */ 248 pexit(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 264 onintr() 265 { 266 267 pexit(DIED); 268 } 269 270 puthedr() 271 { 272 273 yysetfile(filename); 274 } 275