home *** CD-ROM | disk | FTP | other *** search
- /*x.c*/
-
- /*From CLib*/
- #include <kernel.h>
- #include <setjmp.h>
- #include <signal.h>
- #include <stdlib.h>
- #include <string.h>
-
- /*From OSLib*/
- #include "macros.h"
- #include "messagetrans.h"
- #include "os.h"
-
- /*From Support*/
- #include "x.h"
-
- /*The type of a Shared C Library international error block*/
- typedef struct {bits defaultnum; char errmess [252]; bits errnum;
- char errtoken [252];} International_Error;
-
- /*A macro to declare them*/
- #define LOCAL_INTERNATIONAL_ERROR(id, token, num, mess) \
- static struct {bits defaultnum; char errmess [sizeof mess + 1]; \
- bits errnum; char errtoken [sizeof token + 1];} id ## _ = \
- {num, mess, num, token}; \
- static International_Error *id = (International_Error *) &id ## _;
-
- /*2 international error blocks (for use with Copy_Error())*/
- LOCAL_INTERNATIONAL_ERROR (Error_Stack, "C64", error_STK_OFLO, "Not "
- "enough memory, allocate failed")
- LOCAL_INTERNATIONAL_ERROR (Error_Unknown, "C35", 1, "No error (errno = "
- "0)")
-
- /*2 error blocks with tokens in (for use with MessageTrans).*/
- x_LOCAL_ERROR (Error_Escape, error_ESCAPE, "Escape")
- x_LOCAL_ERROR (Error_No_Memory, os_GLOBAL_NO_MEM, "NoMem")
-
- static int Signals [] = {SIGINT, SIGSTAK, SIGOSERROR};
- /*------------------------------------------------------------------------*/
- static os_error *Copy_Error (International_Error *ie)
-
- /*This code is what the SharedCLibrary does, except that this happens
- every time a message is to be looked up, and the module only opens
- the file at most once. We don't really care about this.*/
-
- { messagetrans_control_block cb;
- os_error *e;
-
- if (xmessagetrans_open_file (&cb, "SharedCLibrary:Messages", 0) ==
- NULL)
- { e = xmessagetrans_error_lookup ((os_error *) &ie->errnum, &cb,
- NULL, 0, "SharedCLibrary", NULL, NULL, NULL);
- xmessagetrans_close_file (&cb);
- }
- else
- e = (os_error *) &ie->defaultnum;
-
- return e;
- }
- /*------------------------------------------------------------------------*/
- static void Try_Handler (int sig, x_exception *x)
-
- /*Handler for use after x_try().*/
-
- { os_error *error = NULL /**/;
-
- /*Save this condition in the buffer.*/
- switch (sig)
- { case SIGINT:
- error = xmessagetrans_error_lookup (Error_Escape, NULL, NULL,
- 0, SKIP, SKIP, SKIP, SKIP);
- break;
-
- case SIGSTAK:
- error = Copy_Error (Error_Stack);
- break;
-
- case SIGOSERROR:
- error = x__last_error ();
- break;
- }
-
- /*Longjump back to the x_TRY() call.*/
- longjmp (x->buf, (int) (x->error = error));
- }
- /*------------------------------------------------------------------------*/
- void x__try (x_exception *x)
-
- { int sig;
-
- /*trampoline*/
- #if 0
- /*branch using B*/
- x->trampoline [0] = 0xE24F1008;
- /*i e, 'ADR R1, x,' which is the same as 'SUB R1, PC, #8'*/
- x->trampoline [1] = 0xEA000000 | ((int) &Try_Handler -
- (int) &x->trampoline [1] - 8 >> 2 & 0xFFFFFF);
- /*i e, 'B Try_Handler'*/
- #else
- /*branch using LDR PC*/
- x->trampoline [0] = 0xE24F1008;
- /*i e, 'ADR R1, x,' which is the same as 'SUB R1, PC, #8'*/
- x->trampoline [1] = 0xE591F008;
- /*i e, 'LDR PC, [R1, #8]'*/
- x->trampoline [2] = (int) &Try_Handler;
- /*i e, '& Try_Handler'*/
- #endif
-
- /*previous*/
- for (sig = 0; sig < COUNT (Signals); sig++)
- if ((x->previous [sig] = signal (Signals [sig],
- (void (*) (int)) x)) == SIG_ERR)
- x->previous [sig] = NULL;
-
- /*error*/
- x->error = NULL;
-
- /*buf*/
- /*Done in calling macro.*/
- }
- /*------------------------------------------------------------------------*/
- void x__catch (x_exception *x)
-
- { int sig;
-
- /*Restore the caller's handlers.*/
- for (sig = 0; sig < COUNT (Signals); sig++)
- if (x->previous [sig] != NULL)
- (void) signal (Signals [sig], x->previous [sig]);
- }
- /*------------------------------------------------------------------------*/
- os_error *x__last_error (void)
-
- /*Messing about here because _kernel_last_oserror() returns NULL the
- second time it's called*/
-
- { os_error *last_error;
-
- static os_error *Last_Error;
-
- if ((last_error = (os_error *) _kernel_last_oserror ()) != NULL)
- Last_Error = last_error;
-
- if (Last_Error == NULL)
- Last_Error = Copy_Error (Error_Unknown);
-
- return Last_Error; /*never NULL*/
- }
- /*------------------------------------------------------------------------*/
- void *x__alloc (int size)
-
- { void *ptr;
-
- if ((ptr = malloc (size)) == NULL && size != 0)
- messagetrans_error_lookup (Error_No_Memory, NULL, NULL, 0, SKIP,
- SKIP, SKIP, SKIP);
-
- return ptr;
- }
- /*------------------------------------------------------------------------*/
- void *x__calloc (int count, int size)
-
- { void *ptr;
-
- if ((ptr = calloc (count, size)) == NULL && size != 0 && count != 0)
- messagetrans_error_lookup (Error_No_Memory, NULL, NULL, 0, SKIP,
- SKIP, SKIP, SKIP);
-
- return ptr;
- }
- /*------------------------------------------------------------------------*/
- void x__free (void *ptr, int size) {NOT_USED (size) free (ptr);}
- /*------------------------------------------------------------------------*/
- void *x__realloc (void *ptr, int old_size, int size)
-
- { NOT_USED (old_size)
- NOT_USED (size)
-
- if ((ptr = realloc (ptr, size)) == NULL && size != 0)
- messagetrans_error_lookup (Error_No_Memory, NULL, NULL, 0, SKIP,
- SKIP, SKIP, SKIP);
-
- return ptr;
- }