ArchWizard

DGD/

source navigation ]
diff markup ]
identifier search ]
file search ]
Version: [ 1.0.a0 ] [ 1.1 ] [ 1.2 ] [ 1.2p1 ] [ 1.2p2 ] [ 1.2p3 ] [ 1.2p4 ] [ 1.2.151 ]

  1 # define INCLUDE_FILE_IO
  2 # include "dgd.h"
  3 # include "str.h"
  4 # include "array.h"
  5 # include "object.h"
  6 # include "interpret.h"
  7 # include "comm.h"
  8 
  9 typedef struct _context_ {
 10     jmp_buf env;                        /* error context */
 11     frame *f;                           /* frame context */
 12     unsigned short offset;              /* sp offset */
 13     rlinfo *rlim;                       /* rlimits info */
 14     ec_ftn handler;                     /* error handler */
 15     struct _context_ *next;             /* next in linked list */
 16 } context;
 17 
 18 static context firstcontext;            /* bottom context */
 19 static context *econtext;               /* current error context */
 20 static context *atomicec;               /* first context beyond atomic */
 21 static string *errstr;                  /* current error string */
 22 
 23 /*
 24  * NAME:        errcontext->clear()
 25  * DESCRIPTION: clear the error context string
 26  */
 27 void ec_clear()
 28 {
 29     if (errstr != (string *) NULL) {
 30         str_del(errstr);
 31         errstr = (string *) NULL;
 32     }
 33 }
 34 
 35 /*
 36  * NAME:        errcontext->_push_()
 37  * DESCRIPTION: push and return the current errorcontext
 38  */
 39 jmp_buf *_ec_push_(handler)
 40 ec_ftn handler;
 41 {
 42     register context *e;
 43 
 44     if (econtext == (context *) NULL) {
 45         e = &firstcontext;
 46     } else {
 47         e = ALLOC(context, 1);
 48     }
 49     e->f = cframe;
 50     e->offset = cframe->fp - cframe->sp;
 51     e->rlim = cframe->rlim;
 52 
 53     e->handler = handler;
 54     e->next = econtext;
 55     econtext = e;
 56     return &e->env;
 57 }
 58 
 59 /*
 60  * NAME:        errcontext->pop()
 61  * DESCRIPTION: pop the current errorcontext
 62  */
 63 void ec_pop()
 64 {
 65     register context *e;
 66 
 67     e = econtext;
 68 # ifdef DEBUG
 69     if (e == (context *) NULL) {
 70         fatal("pop empty error stack");
 71     }
 72 # endif
 73     econtext = e->next;
 74     if (e != &firstcontext) {
 75         FREE(e);
 76     } else {
 77         ec_clear();
 78     }
 79 }
 80 
 81 /*
 82  * NAME:        errorcontext->handler()
 83  * DESCRIPTION: dummy handler for previously handled error
 84  */
 85 static void ec_handler(f, depth)
 86 frame *f;
 87 Int depth;
 88 {
 89 }
 90 
 91 /*
 92  * NAME:        errorstr()
 93  * DESCRIPTION: return the current error string
 94  */
 95 string *errorstr()
 96 {
 97     return errstr;
 98 }
 99 
100 /*
101  * NAME:        serror()
102  * DESCRIPTION: cause an error, with a string argument
103  */
104 void serror(str)
105 string *str;
106 {
107     jmp_buf env;
108     register context *e;
109     int offset;
110     ec_ftn handler;
111 
112     if (str != (string *) NULL) {
113         if (errstr != (string *) NULL) {
114             str_del(errstr);
115         }
116         str_ref(errstr = str);
117 # ifdef DEBUG
118     } else if (errstr == (string *) NULL) {
119         fatal("no error string");
120 # endif
121     }
122 
123     e = econtext;
124     offset = e->offset;
125     memcpy(&env, &e->env, sizeof(jmp_buf));
126 
127     if (atomicec == (context *) NULL || atomicec == e) {
128         do {
129             if (cframe->level != e->f->level) {
130                 if (atomicec == (context *) NULL) {
131                     i_atomic_error(cframe, e->f->level);
132                     if (e != econtext) {
133                         atomicec = e;
134                         break;  /* handle rollback later */
135                     }
136                 }
137 
138                 cframe = i_restore(cframe, e->f->level);
139                 atomicec = (context *) NULL;
140             }
141 
142             if (e->handler != (ec_ftn) NULL) {
143                 handler = e->handler;
144                 e->handler = (ec_ftn) ec_handler;
145                 (*handler)(cframe, e->f->depth);
146                 break;
147             }
148             e = e->next;
149         } while (e != (context *) NULL);
150     }
151 
152     if (cframe->rlim != econtext->rlim) {
153         i_set_rlimits(cframe, econtext->rlim);
154     }
155     cframe = i_set_sp(cframe, econtext->f->fp - offset);
156     cframe->rlim = econtext->rlim;
157     ec_pop();
158     longjmp(env, 1);
159 }
160 
161 /*
162  * NAME:        error()
163  * DESCRIPTION: cause an error
164  */
165 void error(format, arg1, arg2, arg3, arg4, arg5, arg6)
166 char *format, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
167 {
168     char ebuf[4 * STRINGSZ];
169 
170     if (format != (char *) NULL) {
171         sprintf(ebuf, format, arg1, arg2, arg3, arg4, arg5, arg6);
172         serror(str_new(ebuf, (long) strlen(ebuf)));
173     } else {
174         serror((string *) NULL);
175     }
176 }
177 
178 /*
179  * NAME:        fatal()
180  * DESCRIPTION: a fatal error has been encountered; terminate the program and
181  *              dump a core if possible
182  */
183 void fatal(format, arg1, arg2, arg3, arg4, arg5, arg6)
184 char *format, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
185 {
186     static short count;
187     char ebuf1[STRINGSZ], ebuf2[STRINGSZ];
188 
189     if (count++ == 0) {
190         sprintf(ebuf1, format, arg1, arg2, arg3, arg4, arg5, arg6);
191         sprintf(ebuf2, "Fatal error: %s\012", ebuf1);   /* LF */
192 
193         P_message(ebuf2);       /* show message */
194 
195         comm_finish();
196     }
197     abort();
198 }
199 
200 /*
201  * NAME:        message()
202  * DESCRIPTION: issue a message on stderr
203  */
204 void message(format, arg1, arg2, arg3, arg4, arg5, arg6)
205 char *format, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
206 {
207     char ebuf[4 * STRINGSZ];
208 
209     if (format == (char *) NULL) {
210 # ifdef DEBUG
211         if (errstr == (string *) NULL) {
212             fatal("no error string");
213         }
214 # endif
215         if (errstr->len <= sizeof(ebuf) - 2) {
216             sprintf(ebuf, "%s\012", errstr->text);
217         } else {
218             strcpy(ebuf, "[too long error string]\012");
219         }
220     } else {
221         sprintf(ebuf, format, arg1, arg2, arg3, arg4, arg5, arg6);
222     }
223     P_message(ebuf);    /* show message */
224 }
225 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.