2 * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interr.c,v 1.10 2009/06/11 16:04:01 rtoy Rel $
4 * Stuff to handle internal errors.
16 #include "internals.h"
22 /* Lossage handler. */
25 default_lossage_handler(void)
30 static void (*lossage_handler) (void) = default_lossage_handler;
33 set_lossage_handler(void handler(void))
35 lossage_handler = handler;
45 vfprintf(stderr, fmt, ap);
53 /* Internal error handler for when the Lisp error system doesn't exist. */
55 static char *errors[] = ERRORS;
58 internal_error(os_context_t * context)
60 unsigned char *ptr = arch_internal_error_arguments(context);
61 int len, scoffset, sc, offset, ch;
64 printf("Error: %s\n", errors[*ptr++]);
69 if (scoffset == 253) {
72 } else if (scoffset == 254) {
73 scoffset = ptr[0] + ptr[1] * 256;
76 } else if (scoffset == 255) {
77 scoffset = ptr[0] + (ptr[1] << 8) + (ptr[2] << 16) + (ptr[3] << 24);
82 offset = scoffset >> 5;
84 printf(" SC: %d, Offset: %d", sc, offset);
87 case sc_DescriptorReg:
89 brief_print(SC_REG(context, offset));
93 ch = SC_REG(context, offset);
113 if (ch < 32 || ch > 127)
114 printf("\\%03o", ch);
116 printf("\t'%c'\n", ch);
121 #ifdef sc_WordPointerReg
122 case sc_WordPointerReg:
124 printf("\t0x%08lx\n", SC_REG(context, offset));
127 printf("\t%ld\n", SC_REG(context, offset));
130 printf("\t%lu\n", SC_REG(context, offset));
135 printf("\t%g\n", *(float *) &context->sc_fpregs[offset]);
140 printf("\t%g\n", *(double *) &context->sc_fpregs[offset]);
145 printf("\t%Lg\n", *(long double *) &context->sc_fpregs[offset]);
161 /* Utility routines used by random pieces of code. */
165 /* The Unicode replacement character code */
166 #define REPLACEMENT_CODE 0xfffd
169 * Convert a unicode code point to a set of utf8-encoded octets to
170 * standard output. This is the algorithm used by the Lisp utf8
171 * encoder in src/code/extfmts.lisp.
174 utf8(int code, int len)
179 int init = 0xff & (0x7e << j);
183 * (ldb (byte j p) code): Extract j bits from position p of the code
185 c = (code >> p) & ((1 << j) - 1);
189 for (k = 0; k < len; ++k) {
191 /* (ldb (byte 6 p) code) */
192 c = (code >> p) & ((1 << 6) - 1);
198 * Test if code is a surrogate. Returns true if so. If the code is a
199 * surrogate, then type indicates if it is a high (0) or low (1)
200 * surrogate. If not a surrogate, type is not modified. If type is
201 * NULL, then no type is returned.
204 surrogatep(int code, int *type)
208 if ((code >> 11) == 0x1b) {
211 *type = (code >> 10) & 1;
221 * Convert one or two utf16 code units into a code point. utf16
222 * points to the string, len is the length of the string. The
223 * codepoint is returned and the number of code units consumed is
224 * returned in consumed.
227 utf16_codepoint(unsigned short int* utf16, int len, int* consumed)
235 * If the current code unit is not a surrogate, we're done.
236 * Otherwise process the surrogate.
239 if (surrogatep(code, &code_type)) {
241 * Try to get the following surrogate, if there are still code
242 * units left. If not, we have a bare surrogate, so just
243 * return the replacement character.
248 if (surrogatep(next, &next_type)) {
249 /* Got the following surrogate, so combine them if possible */
250 if ((code_type == 0) && (next_type == 1)) {
251 /* High followed by low surrogate */
252 code = ((code - 0xd800) << 10) + next + 0x2400;
254 } else if ((code_type == 1) && (next_type == 0)) {
256 * Low followed by high surrogate. Not sure if we
257 * really need to handle this case.
259 code = ((code - 0xd800) << 10) + next + 0x2400;;
263 code = REPLACEMENT_CODE;
266 /* Surrogate followed by non-surrogate. Give up */
267 code = REPLACEMENT_CODE;
270 code = REPLACEMENT_CODE;
279 * Send the utf-16 Lisp unicode string to standard output as a
280 * utf8-encoded sequence of octets.
283 utf16_output(unsigned short int* utf16, int len)
287 int code = utf16_codepoint(utf16, len, &consumed);
289 /* Output the codepoint */
292 } else if (code < 0x800) {
294 } else if (code < 0x10000) {
296 } else if (code < 0x110000) {
300 * This shouldn't happen, but if it does we don't want to
301 * signal any kind of error so just output a question mark
302 * so we can continue.
314 * debug_print is used by %primitive print to output a string.
317 debug_print(lispobj object)
321 printf("%s\n", (char *) (((struct vector *) PTR(object))->data));
324 if (Pointerp(object)) {
325 struct vector *lisp_string = (struct vector*) PTR(object);
327 if ((unsigned long) lisp_string->header == type_SimpleString) {
328 unsigned short int* lisp_chars;
331 len = lisp_string->length >> 2;
332 lisp_chars = (unsigned short int*) lisp_string->data;
334 utf16_output(lisp_chars, len);
343 * We should actually ever get here because %primitive print
344 * is only supposed to take strings. But if we do, it's
345 * useful to print something out anyway.
348 printf("obj @0x%lx: ", (unsigned long) object);