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