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