106 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | |
|   See the copyright notice in the ACK home directory, in the file "Copyright".
 | |
| */
 | |
| 
 | |
| /*
 | |
|   Module:	default modula-2 trap handler
 | |
|   Author:	Ceriel J.H. Jacobs
 | |
|   Version:	$Id$
 | |
| */
 | |
| #include <em_abs.h>
 | |
| #include <m2_traps.h>
 | |
| #include <signal.h>
 | |
| #include "libm2.h"
 | |
| 
 | |
| static struct errm
 | |
| {
 | |
| 	int errno;
 | |
| 	char* errmes;
 | |
| } errors[] = { { EARRAY, "array bound error" },
 | |
| 	           { ERANGE, "range bound error" },
 | |
| 	           { ESET, "set bound error" },
 | |
| 	           { EIOVFL, "integer overflow" },
 | |
| 	           { EFOVFL, "real overflow" },
 | |
| 	           { EFUNFL, "real underflow" },
 | |
| 	           { EIDIVZ, "divide by 0" },
 | |
| 	           { EFDIVZ, "divide by 0.0" },
 | |
| 	           { EIUND, "undefined integer" },
 | |
| 	           { EFUND, "undefined real" },
 | |
| 	           { ECONV, "conversion error" },
 | |
| 
 | |
| 	           { ESTACK, "stack overflow" },
 | |
| 	           { EHEAP, "heap overflow" },
 | |
| 	           { EILLINS, "illegal instruction" },
 | |
| 	           { EODDZ, "illegal size argument" },
 | |
| 	           { ECASE, "case error" },
 | |
| 	           { EMEMFLT, "addressing non existent memory" },
 | |
| 	           { EBADPTR, "bad pointer used" },
 | |
| 	           { EBADPC, "program counter out of range" },
 | |
| 	           { EBADLAE, "bad argument of lae" },
 | |
| 	           { EBADMON, "bad monitor call" },
 | |
| 	           { EBADLIN, "argument if LIN too high" },
 | |
| 	           { EBADGTO, "GTO descriptor error" },
 | |
| 
 | |
| 	           { M2_TOOLARGE, "stack size of process too large" },
 | |
| 	           { M2_TOOMANY, "too many nested traps + handlers" },
 | |
| 	           { M2_NORESULT, "no RETURN from function procedure" },
 | |
| 	           { M2_UOVFL, "cardinal overflow" },
 | |
| 	           { M2_FORCH, "(warning) FOR-loop control variable was changed in the body" },
 | |
| 	           { M2_UUVFL, "cardinal underflow" },
 | |
| 	           { M2_INTERNAL, "internal error; ask an expert for help" },
 | |
| 	           { M2_UNIXSIG, "got a unix signal" },
 | |
| 	           { -1, 0 } };
 | |
| 
 | |
| void catch (int trapno)
 | |
| {
 | |
| 	register struct errm* ep = &errors[0];
 | |
| 	char* errmessage;
 | |
| 	char buf[20];
 | |
| 	register char *p, *s;
 | |
| 
 | |
| 	while (ep->errno != trapno && ep->errmes != 0)
 | |
| 		ep++;
 | |
| 	if (p = ep->errmes)
 | |
| 	{
 | |
| 		while (*p)
 | |
| 			p++;
 | |
| 		_Traps__Message(ep->errmes, 0, (int)(p - ep->errmes), 1);
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		int i = trapno;
 | |
| 		static char q[] = "error number xxxxxxxxxxxxx";
 | |
| 
 | |
| 		p = &q[13];
 | |
| 		s = buf;
 | |
| 		if (i < 0)
 | |
| 		{
 | |
| 			i = -i;
 | |
| 			*p++ = '-';
 | |
| 		}
 | |
| 		do
 | |
| 			*s++ = i % 10 + '0';
 | |
| 		while (i /= 10);
 | |
| 		while (s > buf)
 | |
| 			*p++ = *--s;
 | |
| 		*p = 0;
 | |
| 		_Traps__Message(q, 0, (int)(p - q), 1);
 | |
| 	}
 | |
| #if !defined(__em24) && !defined(__em44) && !defined(__em22)
 | |
| 	if (trapno == M2_UNIXSIG)
 | |
| 	{
 | |
| 		extern int __signo;
 | |
| 		signal(__signo, SIG_DFL);
 | |
| 		_cleanup();
 | |
| 		kill(getpid(), __signo);
 | |
| 		_exit(trapno + 1);
 | |
| 	}
 | |
| #endif
 | |
| 	if (trapno != M2_FORCH)
 | |
| 	{
 | |
| 		_cleanup();
 | |
| 		_exit(trapno + 1);
 | |
| 	}
 | |
| 	SIG(catch);
 | |
| }
 |