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