xref: /original-bsd/usr.bin/pascal/px/utilities.c (revision 92d3de31)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)utilities.c 1.7 01/22/83";
4 
5 #include	<signal.h>
6 #include	"whoami.h"
7 #include	"vars.h"
8 #include	"objfmt.h"
9 
10 stats()
11 {
12 	struct	{
13 		long	usr_time;
14 		long	sys_time;
15 		long	child_usr_time;
16 		long	child_sys_time;
17 	} tbuf;
18 	register double l;
19 	register long count;
20 #	ifdef PROFILE
21 #	define	proffile	"/vb/grad/mckusick/px/profile/pcnt.out"
22 	struct cntrec {
23 		double	counts[NUMOPS];	/* instruction counts */
24 		long	runs;		/* number of interpreter runs */
25 		long	startdate;	/* date profile started */
26 		long	usrtime;	/* total user time consumed */
27 		long	systime;	/* total system time consumed */
28 		double	stmts;		/* number of pascal stmts executed */
29 	} profdata;
30 	FILE *datafile;
31 #	endif PROFILE
32 
33 	if (_nodump)
34 		return(0);
35 	times(&tbuf);
36 #	ifdef PROFILE
37 	datafile = fopen(proffile,"r");
38 	if (datafile == NULL)
39 		goto skipprof;
40 	count = fread(&profdata,1,sizeof(profdata),datafile);
41 	if (count != sizeof(profdata))
42 		goto skipprof;
43 	for (count = 0;  count < NUMOPS;  count++)
44 		profdata.counts[count] += _profcnts[count];
45 	profdata.runs += 1;
46 	profdata.stmts += _stcnt;
47 	profdata.usrtime += tbuf.usr_time;
48 	profdata.systime += tbuf.sys_time;
49 	datafile = freopen(proffile,"w",datafile);
50 	if (datafile == NULL)
51 		goto skipprof;
52 	count = fwrite(&profdata,1,sizeof(profdata),datafile);
53 	if (count != sizeof(profdata))
54 		goto skipprof;
55 	fclose(datafile);
56 skipprof:
57 #	endif PROFILE
58 	l = tbuf.usr_time;
59 	l = l / HZ;
60 	fprintf(stderr,
61 		"\n%1ld statements executed in %04.2f seconds cpu time.\n",
62 		_stcnt,l);
63 }
64 
65 backtrace(type)
66 	char	*type;
67 {
68 	register struct dispsave *mydp;
69 	register struct blockmark *ap;
70 	register char *cp;
71 	register long i, linum;
72 	struct display disp;
73 
74 	if (_lino <= 0) {
75 		fputs("Program was not executed.\n",stderr);
76 		return;
77 	}
78 	disp = _display;
79 	fprintf(stderr, "\n\t%s in \"", type);
80 	mydp = _dp;
81 	linum = _lino;
82 	for (;;) {
83 		ap = mydp->stp;
84 		i = linum - (((ap)->entry)->offset & 0177777);
85 		fprintf(stderr,"%s\"",(ap->entry)->name);
86 		if (_nodump == FALSE)
87 			fprintf(stderr,"+%D near line %D.",i,linum);
88 		fputc('\n',stderr);
89 		*mydp = (ap)->odisp;
90 		if (mydp <= &_display.frame[1]){
91 			_display = disp;
92 			return;
93 		}
94 		mydp = (ap)->dp;
95 		linum = (ap)->lino;
96 		fputs("\tCalled by \"",stderr);
97 	}
98 }
99 
100 psexit(code)
101 
102 	int	code;
103 {
104 	if (_pcpcount != 0)
105 		PMFLUSH(_cntrs, _rtns, _pcpcount);
106 	if (_mode == PIX) {
107 		fputs("Execution terminated",stderr);
108 		if (code)
109 			fputs(" abnormally",stderr);
110 		fputc('.',stderr);
111 		fputc('\n',stderr);
112 	}
113 	stats();
114 	exit(code);
115 }
116 
117 /*
118  * Routines to field various types of signals
119  *
120  * catch a library error and generate a backtrace
121  */
122 liberr()
123 {
124 	backtrace("Error");
125 	psexit(2);
126 }
127 
128 /*
129  * catch an interrupt and generate a backtrace
130  */
131 intr()
132 {
133 	signal(SIGINT, intr);
134 	backtrace("Interrupted");
135 	psexit(1);
136 }
137 
138 /*
139  * catch memory faults
140  */
141 memsize()
142 {
143 	signal(SIGSEGV, memsize);
144 	ERROR("Run time stack overflow\n");
145 }
146 
147 /*
148  * catch random system faults
149  */
150 syserr(signum)
151 	int signum;
152 {
153 	signal(signum, syserr);
154 	ERROR("Panic: Computational error in interpreter\n");
155 }
156