Added upstream version.
[vlp.git] / int / handler.c
1 #include "depend.h"
2 #include "genint.h"
3 #include "int.h"
4 #include "process.h"
5 #include "intproto.h"
6
7 /* Handler routines */
8
9 /* Pataud le 13-06-1995
10 #if !NO_GRAPH ||!DJE
11 #if MSDOS
12 #include "graf\graf.h"
13 #else
14 #include "graf/graf.h"
15 #endif
16 #endif
17 */
18
19 void errsignal(exception)
20 int exception;
21 {
22     word signum, ah, am;
23
24
25     signum = scot[ exception ];
26     /* A.Salwicki 30 pazdz. 2002 *
27     fprintf(stderr, "\n signum= %ld\n", signum);
28     
29   *    fprintf(stderr, " Wlazl kotek");   *
30     
31     
32     if (signum != -1)                   * attempt to call a handler *
33     {
34          
35         raise_signal(signum, (word) 0, &ah, &am);
36         fprintf(stderr, "\n ic= %ld\n", ic);
37         
38       /*  if (ic != 0)                    /* continue execution *
39         {
40             go(ah, am);
41             longjmp(contenv, 1);
42         } *
43     }
44     */
45     
46 /* A. Salwicki 27-10-2002
47 #if MSDOS && !NO_GRAPH
48     {
49         extern bool graphmode;
50
51         if (graphmode) groff();
52         graphmode = FALSE;
53     }
54 #endif
55 */
56
57     putc('\n', stderr);
58     switch (exception)
59     {
60         case RTESLCOF: fprintf(stderr, " SL CHAIN CUT OFF");                    break;
61         case RTEUNSTP: fprintf(stderr, " UNIMPLEMENTED STANDARD PROCEDURE");    break;
62         case RTEILLAT: fprintf(stderr, " ILLEGAL ATTACH");                      break;
63         case RTEILLDT: fprintf(stderr, " ILLEGAL DETACH");                      break;
64         case RTECORTM: fprintf(stderr, " COROUTINE TERMINATED");                break;
65         case RTECORAC: fprintf(stderr, " COROUTINE ACTIVE");                    break;
66         case RTEINVIN: fprintf(stderr, " ARRAY INDEX ERROR");                   break;
67         case RTEILLAB: fprintf(stderr, " INCORRECT ARRAY BOUNDS");              break;
68         case RTEINCQA: fprintf(stderr, " IMPROPER QUA");                        break;
69         case RTEINCAS: fprintf(stderr, " ILLEGAL ASSIGNMENT");                  break;
70         case RTEFTPMS: fprintf(stderr, " FORMAL TYPE MISSING");                 break;
71         case RTEILLKL: fprintf(stderr, " ILLEGAL KILL");                        break;
72         case RTEILLCP: fprintf(stderr, " ILLEGAL COPY");                        break;
73         case RTEINCHS: fprintf(stderr, " INCOMPATIBLE HEADERS");                break;
74         case RTEHNDNF: fprintf(stderr, " HANDLER NOT FOUND");                   break;
75         case RTEMEMOV: fprintf(stderr, " MEMORY OVERFLOW");                     break;
76         case RTEFHTLG: fprintf(stderr, " FORMAL LIST TOO LONG");                break;
77         case RTEILLRT: fprintf(stderr, " ILLEGAL RETURN");                      break;
78         case RTEREFTN: fprintf(stderr, " REFERENCE TO NONE");                   break;
79         case RTEDIVBZ: fprintf(stderr, " DIVISION BY ZERO");                    break;
80         case RTESYSER: fprintf(stderr, " SYSTEM ERROR");                        break;
81         case RTEILLIO: fprintf(stderr, " ILLEGAL I/O OPERATION");               break;
82         case RTEIOERR: fprintf(stderr, " I/O ERROR");                           break;
83         case RTECNTOP: fprintf(stderr, " CANNOT OPEN FILE");                    break;
84         case RTEBADFM: fprintf(stderr, " INPUT DATA FORMAT BAD");               break;
85         case RTEILLRS: fprintf(stderr, " ILLEGAL RESUME");                      break;
86         case RTETMPRC: fprintf(stderr, " TOO MANY PROCESSES ON ONE MACHINE");   break;
87         case RTEINVND: fprintf(stderr, " INVALID NODE NUMBER");                 break;
88         case RTENEGST: fprintf(stderr, " NEGATIVE STEP VALUE");                 break;
89         case RTENONGL: fprintf(stderr, " REFERENCE TO GLOBAL NON PROCESS OBJECT FROM PROCESS");                 break;
90         default      : fprintf(stderr, " UNRECOGNIZED ERROR");
91     }
92     if (thisp->trlnumber < 0) thisp->trlnumber = - thisp->trlnumber;
93     if (thisp->trlnumber != 0)
94         fprintf(stderr, "\n AT LINE: %ld\n", (long) thisp->trlnumber);
95     endprocess(4);
96 } /* end errsignal */
97
98
99 void raise_signal(signal, skip, ahnew, amnew)   /* Raise exception */
100 word signal, skip;
101 word *ahnew, *amnew;
102 {
103     word t1, t2, t3, t4, t5, virts;
104     protdescr *ptr;
105
106     t1 = 0;                             /* handler for others = no */
107     t2 = M[ display2+M[ c1+PROTNUM ] ]; /* ah of current */
108     t3 = c1;                            /* am of current */
109     t5 = 0;                             /* flag handler not found */
110     do
111     {
112         ptr = prototype[ M[ t3+PROTNUM ] ]; /* prototype of current */
113         t4 = ptr->handlerlist;
114         if (t4 != 0)                    /* any handlers ? */
115         {
116             do
117             {
118                 t5 = M[ t4 ];           /* signal number */
119                 if (t5 != signal)
120                 {
121                     if (t5 == 0 && t1 == 0) t1 = t4;
122                     t4 = M[ t4+2 ];
123                 }
124             } while (t5 != signal && t4 != 0);
125         }
126         if (t5 != signal)               /* look in DL or SL */
127         {
128             if (t1 != 0) t4 = t1;       /* handler for others found */
129             else
130             {
131                 t4 = t3+M[ t3 ];
132                 if (ptr->kind == HANDLER)
133                     t2 = M[ t4+SL ];    /* use SL for handlers */
134                 else
135                     t2 = M[ t4+DL ];    /* or DL for other goodies */
136                 if (t2 == 0)            /* handler not found */
137                 {
138                     if (signal <= MAXSYSSN)
139                     {                   /* system signal */
140                         ic = skip;
141                         if (ic != 0) longjmp(contenv, 1);
142                         else return;
143                     }
144                     else errsignal(RTEHNDNF);
145                 }
146                 t3 = M[ t2 ];
147             }
148         }
149         else t1 = 0;
150     } while (t1 == 0 && t5 != signal);
151
152     virts = thisp->prochead+M[ thisp->prochead ]+VIRTSC;
153     M[ virts ] = t2;                    /* compactification possible */
154     M[ virts+1 ] = M[ t2+1 ];
155     t3 = M[ t4+1 ];                     /* prototype number of handler */
156     t5 = prototype[ t3 ]->appetite;
157     if (t1 != 0)                        /* others */
158     {
159         request(t5, ahnew, amnew);
160         M[ *amnew+M[ *amnew ]+SIGNR ] = 0;
161     }
162     else
163     {
164         if (signal == scot[ RTEMEMOV ] &&
165             thisp->lastitem-thisp->lastused-1 < t5)
166         {
167             scot[ RTEMEMOV ] = -1;      /* make memov look like abort */
168             errsignal(RTEMEMOV);
169         }
170         request(t5, ahnew, amnew);
171         M[ *amnew+M[ *amnew ]+SIGNR ] = signal;
172     }
173     M[ *amnew+PROTNUM ] = t3;           /* provide system attributes */
174     t5 = *amnew+M[ *amnew ];
175     M[ t5+SL ] = M[ virts ];
176     M[ t5+SL+1 ] = M[ virts+1 ];
177     t2 = M[ display2+M[ c1+PROTNUM ] ]; /* ah of current */
178     M[ t5+DL ] = t2;
179     M[ t5+DL+1 ] = M[ t2+1 ];
180     if (t1 != 0)                        /* skip */
181     {
182         ic = skip;
183         go(*ahnew, *amnew);
184     }
185 } /* end raise_signal */
186
187
188 void wind()
189 {
190     word t1, t2;
191
192     t1 = M[ M[ c1+M[ c1 ]+SL ] ];       /* am of handlers' SL */
193     t2 = c1;                            /* current */
194     while (TRUE)
195     {
196         t2 = M[ M[ t2+M[ t2 ]+DL ] ];   /* am of DL */
197         if (t2 == t1) break;
198         M[ t2+M[ t2 ]+LSC ] = prototype[ M[ t2+PROTNUM ] ]->lastwill;
199     }
200     back(&thisp->backobj, &M[ temporary ], (word) 0);
201 } /* end wind */
202
203
204 void term()
205 {
206     word t1;
207
208     t1 = M[ M[ c1+M[ c1 ]+SL ] ];       /* am of handlers' SL */
209     M[ t1+M[ t1 ]+LSC ] = prototype[ M[ t1+PROTNUM ] ]->lastwill;
210     wind();
211 } /* end term */
212
213
214 /* This wraps up the above series of the handler procedures.
215  */
216
217 void backhd(virt, am)
218 virtaddr *virt;
219 word *am;
220 {
221     if (M[ c1+M[ c1 ]+SIGNR ] <= MAXSYSSN)
222         errsignal(RTEILLRT);            /* illegal return */
223     else
224         back(virt, am, (word) 0);
225 } /* end backhd */