1: /* #define DEBUG */ 2: #define CHAR 3: #define STATIC 4: /* 5: * pxp - Pascal execution profiler 6: * 7: * Bill Joy 8: * University of California, Berkeley (UCB) 9: * Version 1.1 February 1978 10: */ 11: 12: #include <sys/types.h> 13: #include <sys/stat.h> 14: 15: /* 16: * Option flags 17: * 18: * The following options are recognized on the command line by pxp. 19: * Only the u, w, and z options here have effect in comments in the 20: * program; the others are command line only, and unrelated 21: * to the options with the same designations in comments. 22: * 23: * a Print all routines in a profile; normally, routines 24: * which have never been executed have their bodies suppressed. 25: * 26: * c Extract profile data from the file core, or the file 27: * named after the last argument rather than the file 'pmon.out'. 28: * Must be used with z to have an effect. 29: * 30: * d Suppress declarations 31: * 32: * f Fully parenthesize expressions. 33: * 34: * j Left justify all procedures and functions rather than 35: * indenting them. 36: * 37: * n Eject a new page in the listing as each 'include' file 38: * is incorporated into the profile. 39: * 40: * o Put output prettyprint in first argument file 41: * 42: * p Pretty print a main program without processing 43: * the include statements. 44: * 45: * t Print a table summarizing procedure and function call counts. 46: * 47: * u Card image mode; only the first 72 chars on a line count. 48: * 49: * w Suppress certain warning diagnostics. 50: * 51: * z Generate an execution profile of the program. 52: * May also be followed by a list of procedure and function 53: * names mixed, if desired, with include file names. 54: * Only these procedures and functions, and the contents 55: * of the specified include files will then be profiled. 56: * 57: * [23456789] Use the specified number of spaces for the basic 58: * indenting unit in the program. 59: * 60: * _ Underline keywords in the output. 61: */ 62: 63: char all, core, nodecl, full, justify, pmain, stripcomm, table, underline; 64: char profile, onefile; 65: char *firstname, *stdoutn; 66: #ifdef DEBUG 67: char fulltrace, errtrace, testtrace, yyunique, typetest; 68: #endif 69: int unit; 70: 71: /* 72: * The flag nojunk means that header lines 73: * of procedures and functions are to be suppressed 74: * when the z option is off. 75: * It is the default when command line z option 76: * control is specified. 77: * 78: * The flag noinclude indicates that include statements are not 79: * to be processed since we are pretty-printing the contents 80: * of a single file. 81: * 82: * The flag bracket indicates that the source code should be 83: * bracketed with lines of the form 84: * program x(output); 85: * and 86: * begin end. 87: * so that an include will pretty print without syntax errors. 88: */ 89: char nojunk, noinclude, bracket; 90: 91: /* 92: * IMPORTANT NOTE 93: * 94: * Many of the following globals are shared by pi and pxp. 95: * For more discussion of these see the available documentation 96: * on the structure of pi. 97: */ 98: 99: /* 100: * Each option has a stack of 17 option values, with opts giving 101: * the current, top value, and optstk the value beneath it. 102: * One refers to option `l' as, e.g., opt('l') in the text for clarity. 103: */ 104: char opts[26]; 105: int optstk[26]; 106: 107: #define opt(c) opts[c-'a'] 108: 109: /* 110: * NOTES ON THE DYNAMIC NATURE OF THE DATA STRUCTURES 111: * 112: * Pxp uses expandable tables for its string table 113: * hash table, and parse tree space. The following 114: * definitions specify the size of the increments 115: * for these items in fundamental units so that 116: * each uses approximately 1024 bytes. 117: */ 118: 119: #define STRINC 1024 /* string space increment */ 120: #define TRINC 512 /* tree space increment */ 121: #define HASHINC 509 /* hash table size in words, each increment */ 122: 123: /* 124: * The initial sizes of the structures. 125: * These should be large enough to profile 126: * an "average" sized program so as to minimize 127: * storage requests. 128: * On a small system or and 11/34 or 11/40 129: * these numbers can be trimmed to make the 130: * profiler smaller. 131: */ 132: #define ITREE 2000 133: #define IHASH 509 134: 135: /* 136: * The following limits on hash and tree tables currently 137: * allow approximately 1200 symbols and 20k words of tree 138: * space. The fundamental limit of 64k total data space 139: * should be exceeded well before these are full. 140: */ 141: #define MAXHASH 4 142: #define MAXTREE 30 143: #define MAXDEPTH 150 144: 145: /* 146: * ERROR RELATED DEFINITIONS 147: */ 148: 149: /* 150: * Exit statuses to pexit 151: * 152: * AOK 153: * ERRS Compilation errors inhibit obj productin 154: * NOSTART Errors before we ever got started 155: * DIED We ran out of memory or some such 156: */ 157: #define AOK 0 158: #define ERRS 1 159: #define NOSTART 2 160: #define DIED 3 161: 162: char Recovery; 163: /* 164: * The flag eflg is set whenever we have a hard error. 165: * The character in errpfx will precede the next error message. 166: */ 167: int eflg; 168: char errpfx; 169: 170: #define setpfx(x) errpfx = x 171: 172: #define standard() setpfx('s') 173: #define warning() setpfx('w') 174: #define recovered() setpfx('e') 175: #define quit() setpfx('Q') 176: 177: /* 178: * SEMANTIC DEFINITIONS 179: */ 180: 181: #define NIL 0 182: 183: /* 184: * NOCON and SAWCON are flags in the tree telling whether 185: * a constant set is part of an expression. 186: */ 187: #define NOCON 0 188: #define SAWCON 1 189: 190: /* 191: * The variable cbn gives the current block number. 192: * The variable lastbn gives the block number before 193: * it last changed and is used to know that we were 194: * in a nested procedure so that we can print 195: * begin { solve } 196: * when solve has nested procedures or functions in it. 197: */ 198: int cbn, lastbn; 199: 200: /* 201: * The variable line is the current semantic 202: * line and is set in stat.c from the numbers 203: * embedded in statement type tree nodes. 204: */ 205: int line; 206: 207: /* 208: * The size of the display 209: * which defines the maximum nesting 210: * of procedures and functions allowed. 211: */ 212: #define DSPLYSZ 20 213: 214: /* 215: * Routines which need types 216: * other than "integer" to be 217: * assumed by the compiler. 218: */ 219: int *tree(); 220: int *hash(); 221: char *alloc(); 222: long cntof(); 223: long nowcnt(); 224: 225: /* 226: * Funny structures to use 227: * pointers in wild and wooly ways 228: */ 229: struct { 230: char pchar; 231: }; 232: struct { 233: int pint; 234: int pint2; 235: }; 236: struct { 237: long plong; 238: }; 239: struct { 240: double pdouble; 241: }; 242: 243: #define OCT 1 244: #define HEX 2 245: 246: /* 247: * MAIN PROGRAM GLOBALS, MISCELLANY 248: */ 249: 250: /* 251: * Variables forming a data base referencing 252: * the command line arguments with the "z" option. 253: */ 254: char **pflist; 255: int pflstc; 256: int pfcnt; 257: 258: char *filename; /* current source file name */ 259: char *lastname; /* last file name printed */ 260: time_t tvec; /* mod time of the source file */ 261: time_t ptvec; /* time profiled */ 262: char printed; /* current file has been printed */ 263: char hadsome; /* had some output */ 264: 265: /* 266: * PROFILING AND FORMATTING DEFINITIONS 267: */ 268: 269: /* 270: * The basic counter information recording structure. 271: * This is global only because people outside 272: * the cluster in pmon.c need to know its size. 273: */ 274: struct pxcnt { 275: long ntimes; /* the count this structure is all about */ 276: int counter; /* a unique counter number for us */ 277: int gos; /* global goto count when we hatched */ 278: int printed; /* are we considered to have been printed? */ 279: } pfcnts[DSPLYSZ]; 280: 281: /* 282: * The pieces we divide the output line indents into: 283: * line# PRFN label: STAT 999.---| DECL text 284: */ 285: #define STAT 0 286: #define DECL 1 287: #define PRFN 2 288: 289: /* 290: * Gocnt records the total number of goto's and 291: * cnts records the current counter for generating 292: * COUNT operators. 293: */ 294: int gocnt; 295: int cnts; 296: 297: int fout[259]; 298: int flush(), putchar();