2 * Stuff to handle internal errors.
14 #include "internals.h"
20 /* Lossage handler. */
23 default_lossage_handler(void)
28 static void (*lossage_handler) (void) = default_lossage_handler;
31 set_lossage_handler(void handler(void))
33 lossage_handler = handler;
43 vfprintf(stderr, fmt, ap);
51 /* Internal error handler for when the Lisp error system doesn't exist. */
53 static char *errors[] = ERRORS;
56 internal_error(os_context_t * context)
58 unsigned char *ptr = arch_internal_error_arguments(context);
59 int len, scoffset, sc, offset, ch;
62 printf("Error: %s\n", errors[*ptr++]);
67 if (scoffset == 253) {
70 } else if (scoffset == 254) {
71 scoffset = ptr[0] + ptr[1] * 256;
74 } else if (scoffset == 255) {
75 scoffset = ptr[0] + (ptr[1] << 8) + (ptr[2] << 16) + (ptr[3] << 24);
80 offset = scoffset >> 5;
82 printf(" SC: %d, Offset: %d", sc, offset);
85 case sc_DescriptorReg:
87 brief_print(SC_REG(context, offset));
91 ch = SC_REG(context, offset);
111 if (ch < 32 || ch > 127)
112 printf("\\%03o", ch);
114 printf("\t'%c'\n", ch);
119 #ifdef sc_WordPointerReg
120 case sc_WordPointerReg:
122 printf("\t0x%08lx\n", SC_REG(context, offset));
125 printf("\t%ld\n", SC_REG(context, offset));
128 printf("\t%lu\n", SC_REG(context, offset));
133 printf("\t%g\n", *(float *) &context->sc_fpregs[offset]);
138 printf("\t%g\n", *(double *) &context->sc_fpregs[offset]);
143 printf("\t%Lg\n", *(long double *) &context->sc_fpregs[offset]);
159 /* Utility routines used by random pieces of code. */
163 /* The Unicode replacement character code */
164 #define REPLACEMENT_CODE 0xfffd
167 * Convert a unicode code point to a set of utf8-encoded octets to
168 * standard output. This is the algorithm used by the Lisp utf8
169 * encoder in src/code/extfmts.lisp.
172 utf8(int code, int len)
177 int init = 0xff & (0x7e << j);
181 * (ldb (byte j p) code): Extract j bits from position p of the code
183 c = (code >> p) & ((1 << j) - 1);
187 for (k = 0; k < len; ++k) {
189 /* (ldb (byte 6 p) code) */
190 c = (code >> p) & ((1 << 6) - 1);
196 * Test if code is a surrogate. Returns true if so. If the code is a
197 * surrogate, then type indicates if it is a high (0) or low (1)
198 * surrogate. If not a surrogate, type is not modified. If type is
199 * NULL, then no type is returned.
202 surrogatep(int code, int *type)
206 if ((code >> 11) == 0x1b) {
209 *type = (code >> 10) & 1;
219 * Convert one or two utf16 code units into a code point. utf16
220 * points to the string, len is the length of the string. The
221 * codepoint is returned and the number of code units consumed is
222 * returned in consumed.
225 utf16_codepoint(unsigned short int* utf16, int len, int* consumed)
227 int codepoint = REPLACEMENT_CODE;
228 int code_unit = *utf16;
233 * If the current code unit is not a surrogate, we're done.
234 * Otherwise process the surrogate. If this is a high (leading)
235 * surrogate and the next code unit is a low (trailing) surrogate,
236 * compute the code point. Otherwise we have a bare surrogate or
237 * an invalid surrogate sequence, so just return the replacement
241 if (surrogatep(code_unit, &code_type)) {
242 if (code_type == 0 && len > 0) {
243 int next_unit = utf16[1];
245 if (surrogatep(next_unit, &next_type)) {
246 if (next_type == 1) {
247 /* High followed by low surrogate */
248 codepoint = ((code_unit - 0xd800) << 10) + next_unit + 0x2400;
254 codepoint = code_unit;
262 * Send the utf-16 Lisp unicode string to standard output as a
263 * utf8-encoded sequence of octets.
266 utf16_output(unsigned short int* utf16, int len)
270 int code = utf16_codepoint(utf16, len, &consumed);
272 /* Output the codepoint */
275 } else if (code < 0x800) {
277 } else if (code < 0x10000) {
279 } else if (code < 0x110000) {
283 * This shouldn't happen, but if it does we don't want to
284 * signal any kind of error so just output a question mark
285 * so we can continue.
297 * debug_print is used by %primitive print to output a string.
300 debug_print(lispobj object)
304 printf("%s\n", (char *) (((struct vector *) PTR(object))->data));
307 if (Pointerp(object)) {
308 struct vector *lisp_string = (struct vector*) PTR(object);
310 if ((unsigned long) lisp_string->header == type_SimpleString) {
311 unsigned short int* lisp_chars;
314 len = lisp_string->length >> 2;
315 lisp_chars = (unsigned short int*) lisp_string->data;
317 utf16_output(lisp_chars, len);
326 * We shouldn't actually ever get here because %primitive
327 * print is only supposed to take strings. But if we do, it's
328 * useful to print something out anyway.
331 printf("obj @0x%lx: ", (unsigned long) object);