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