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