Start development on BSD 2
[unix-history] / .ref-BSD-1 / pxp / main.c
#
/*
* pxp - Pascal execution profiler
*
* Bill Joy UCB
* Version 1.0 August 1977
*/
#include "whoami"
#include "0.h"
/*
* This program is described in detail in the "PXP 1.0 Implementation Notes"
*
* The structure of pxp is very similar to that of the compiler pc.
* The major new pieces here are a set of profile data maintenance
* routines in the file pmon.c and a set of pretty printing utility
* routines in the file pp.c.
* The semantic routines of pc have been rewritten to do a simple
* reformatting tree walk, the parsing and scanning remains
* the same.
*
* This version does not reformat comments, rather discards them.
* It also does not place more than one statement per line and
* is not very intelligent about folding long lines, with only
* an ad hoc way of folding case label list and enumerated type
* declarations being implemented.
*/
char usagestr[]
"pxp [ -acdefjntuw_ ] [ -23456789 ] [ -z [ name ... ] ] name.p";
char *howfile "/usr/lib/how_pxp";
int unit 4;
extern int ibuf[259];
extern char errout;
/*
* Main program for pxp.
* Process options, then call yymain
* to do all the real work.
*/
main(argc, argv)
int argc;
char *argv[];
{
register char *cp;
register c;
if (argv[0][0] == 'a')
howfile =+ 9;
argc--, argv++;
if (argc == 0) {
execl("/bin/cat", "cat", howfile, 0);
goto usage;
}
while (argc > 0) {
cp = argv[0];
if (*cp++ != '-')
break;
while (c = *cp++) switch (c) {
#ifdef DEBUG
case 'T':
typetest++;
continue;
case 'A':
testtrace++;
case 'F':
fulltrace++;
case 'E':
errtrace++;
continue;
case 'C':
yycosts();
pexit(NOSTART);
case 'U':
yyunique++;
continue;
#endif
case 'a':
all++;
continue;
case 'c':
core++;
continue;
case 'd':
nodecl++;
continue;
case 'e':
noinclude = -1;
continue;
case 'f':
full++;
continue;
case 'j':
justify++;
continue;
case 'l':
case 'n':
togopt(c);
continue;
case 's':
stripcomm++;
continue;
case 't':
table++;
continue;
case 'u':
case 'w':
togopt(c);
continue;
case 'z':
profile++;
pflist = argv + 1;
pflstc = 0;
while (argc > 1) {
if (dotted(argv[1], 'p'))
break;
pflstc++, argc--, argv++;
}
if (pflstc == 0)
togopt(c);
else
nojunk++;
continue;
case '_':
underline++;
continue;
default:
if (c >= '2' && c <= '9') {
unit = c - '0';
continue;
}
usage:
Perror("Usage", usagestr);
exit(1);
}
argc--, argv++;
}
if (core && !profile && !table)
profile++;
if (argc == 0 || argc > 2)
goto usage;
if (profile || table) {
noinclude = 0;
if (argc == 2) {
argc--;
getit(argv[1]);
} else
getit(core ? "core" : "pmon.out");
} else
noinclude++;
if (argc != 1)
goto usage;
filename = argv[0];
if (dotted(filename, 'i')) {
if (profile || table)
goto usage;
noinclude = 1;
bracket++;
} else if (!dotted(filename, 'p')) {
Perror(filename, "Name must end in '.p'");
exit(1);
}
if (fopen(filename, ibuf) < 0)
perror(filename), pexit(NOSTART);
fout[0] = dup(1);
if (profile || opt('l')) {
opt('n')++;
yysetfile(filename);
opt('n')--;
} else
lastname = filename;
errout = dup(2);
yymain();
/* No return */
}
/*
* Put a header on a top of a page
*/
header()
{
extern char version[];
static char reenter;
extern int outcol;
gettime();
if (reenter) {
if (outcol)
putchar('\n');
putchar('\f');
}
reenter++;
if (profile || table) {
printf("UNIX Pascal PXP -- Version 1.0 (%s)\n\n%s %s\n\n", version, myctime(tvec), filename);
printf("Profiled %s\n\n", myctime(ptvec));
}
}
char ugh[] "Fatal error in pxp\n";
/*
* Exit from the Pascal system.
* We throw in an ungraceful termination
* message if c > 1 indicating a severe
* error such as running out of memory
* or an internal inconsistency.
*/
pexit(c)
int c;
{
register char *cp;
extern int outcol;
if (outcol)
putchar('\n');
flush();
if (c == DIED)
write(2, ugh, sizeof ugh);
exit(c);
}
extern int errno;
/*
* Pxp uses a modified putchar
* which calls xflush to flush its buffer
* rather than the normal fflush.
* This allows us to check for write errors
* on standard output which we really care
* about, because we may be creating a new
* source program.
*/
xflush()
{
errno = 0;
flush();
if (errno) {
perror("Standard output");
exit(DIED);
}
}
puthedr()
{
yysetfile(filename);
}