home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / oslib / examples / c / x < prev   
Encoding:
Text File  |  1995-09-20  |  5.3 KB  |  185 lines

  1. /*x.c*/
  2.  
  3. /*From CLib*/
  4. #include <kernel.h>
  5. #include <setjmp.h>
  6. #include <signal.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. /*From OSLib*/
  11. #include "macros.h"
  12. #include "messagetrans.h"
  13. #include "os.h"
  14.  
  15. /*From Support*/
  16. #include "x.h"
  17.  
  18. /*The type of a Shared C Library international error block*/
  19. typedef struct {bits defaultnum; char errmess [252]; bits errnum;
  20.       char errtoken [252];} International_Error;
  21.  
  22. /*A macro to declare them*/
  23. #define LOCAL_INTERNATIONAL_ERROR(id, token, num, mess) \
  24.    static struct {bits defaultnum; char errmess [sizeof mess + 1]; \
  25.          bits errnum; char errtoken [sizeof token + 1];} id ## _ = \
  26.          {num, mess, num, token}; \
  27.    static International_Error *id = (International_Error *) &id ## _;
  28.  
  29. /*2 international error blocks (for use with Copy_Error())*/
  30. LOCAL_INTERNATIONAL_ERROR (Error_Stack, "C64", error_STK_OFLO, "Not "
  31.       "enough memory, allocate failed")
  32. LOCAL_INTERNATIONAL_ERROR (Error_Unknown, "C35", 1, "No error (errno = "
  33.       "0)")
  34.  
  35. /*2 error blocks with tokens in (for use with MessageTrans).*/
  36. x_LOCAL_ERROR (Error_Escape, error_ESCAPE, "Escape")
  37. x_LOCAL_ERROR (Error_No_Memory, os_GLOBAL_NO_MEM, "NoMem")
  38.  
  39. static int Signals [] = {SIGINT, SIGSTAK, SIGOSERROR};
  40. /*------------------------------------------------------------------------*/
  41. static os_error *Copy_Error (International_Error *ie)
  42.  
  43.    /*This code is what the SharedCLibrary does, except that this happens
  44.       every time a message is to be looked up, and the module only opens
  45.       the file at most once. We don't really care about this.*/
  46.  
  47. {  messagetrans_control_block cb;
  48.    os_error *e;
  49.  
  50.    if (xmessagetrans_open_file (&cb, "SharedCLibrary:Messages", 0) ==
  51.          NULL)
  52.    {  e = xmessagetrans_error_lookup ((os_error *) &ie->errnum, &cb,
  53.             NULL, 0, "SharedCLibrary", NULL, NULL, NULL);
  54.       xmessagetrans_close_file (&cb);
  55.    }
  56.    else
  57.       e = (os_error *) &ie->defaultnum;
  58.  
  59.    return e;
  60. }
  61. /*------------------------------------------------------------------------*/
  62. static void Try_Handler (int sig, x_exception *x)
  63.  
  64.    /*Handler for use after x_try().*/
  65.  
  66. {  os_error *error = NULL /**/;
  67.  
  68.    /*Save this condition in the buffer.*/
  69.    switch (sig)
  70.    {  case SIGINT:
  71.          error = xmessagetrans_error_lookup (Error_Escape, NULL, NULL,
  72.                0, SKIP, SKIP, SKIP, SKIP);
  73.       break;
  74.  
  75.       case SIGSTAK:
  76.          error = Copy_Error (Error_Stack);
  77.       break;
  78.  
  79.       case SIGOSERROR:
  80.          error = x__last_error ();
  81.       break;
  82.    }
  83.  
  84.    /*Longjump back to the x_TRY() call.*/
  85.    longjmp (x->buf, (int) (x->error = error));
  86. }
  87. /*------------------------------------------------------------------------*/
  88. void x__try (x_exception *x)
  89.  
  90. {  int sig;
  91.  
  92.    /*trampoline*/
  93. #if 0
  94.    /*branch using B*/
  95.    x->trampoline [0] = 0xE24F1008;
  96.       /*i e, 'ADR R1, x,' which is the same as 'SUB R1, PC, #8'*/
  97.    x->trampoline [1] = 0xEA000000 | ((int) &Try_Handler -
  98.          (int) &x->trampoline [1] - 8 >> 2 & 0xFFFFFF);
  99.       /*i e, 'B Try_Handler'*/
  100. #else
  101.    /*branch using LDR PC*/
  102.    x->trampoline [0] = 0xE24F1008;
  103.       /*i e, 'ADR R1, x,' which is the same as 'SUB R1, PC, #8'*/
  104.    x->trampoline [1] = 0xE591F008;
  105.       /*i e, 'LDR PC, [R1, #8]'*/
  106.    x->trampoline [2] = (int) &Try_Handler;
  107.       /*i e, '& Try_Handler'*/
  108. #endif
  109.  
  110.    /*previous*/
  111.    for (sig = 0; sig < COUNT (Signals); sig++)
  112.       if ((x->previous [sig] = signal (Signals [sig],
  113.             (void (*) (int)) x)) == SIG_ERR)
  114.          x->previous [sig] = NULL;
  115.  
  116.    /*error*/
  117.    x->error = NULL;
  118.  
  119.    /*buf*/
  120.    /*Done in calling macro.*/
  121. }
  122. /*------------------------------------------------------------------------*/
  123. void x__catch (x_exception *x)
  124.  
  125. {  int sig;
  126.  
  127.    /*Restore the caller's handlers.*/
  128.    for (sig = 0; sig < COUNT (Signals); sig++)
  129.       if (x->previous [sig] != NULL)
  130.          (void) signal (Signals [sig], x->previous [sig]);
  131. }
  132. /*------------------------------------------------------------------------*/
  133. os_error *x__last_error (void)
  134.  
  135.    /*Messing about here because _kernel_last_oserror() returns NULL the
  136.       second time it's called*/
  137.  
  138. {  os_error *last_error;
  139.  
  140.    static os_error *Last_Error;
  141.  
  142.    if ((last_error = (os_error *) _kernel_last_oserror ()) != NULL)
  143.       Last_Error = last_error;
  144.  
  145.    if (Last_Error == NULL)
  146.       Last_Error = Copy_Error (Error_Unknown);
  147.  
  148.    return Last_Error; /*never NULL*/
  149. }
  150. /*------------------------------------------------------------------------*/
  151. void *x__alloc (int size)
  152.  
  153. {  void *ptr;
  154.  
  155.    if ((ptr = malloc (size)) == NULL && size != 0)
  156.       messagetrans_error_lookup (Error_No_Memory, NULL, NULL, 0, SKIP,
  157.             SKIP, SKIP, SKIP);
  158.  
  159.    return ptr;
  160. }
  161. /*------------------------------------------------------------------------*/
  162. void *x__calloc (int count, int size)
  163.  
  164. {  void *ptr;
  165.  
  166.    if ((ptr = calloc (count, size)) == NULL && size != 0 && count != 0)
  167.       messagetrans_error_lookup (Error_No_Memory, NULL, NULL, 0, SKIP,
  168.             SKIP, SKIP, SKIP);
  169.  
  170.    return ptr;
  171. }
  172. /*------------------------------------------------------------------------*/
  173. void x__free (void *ptr, int size) {NOT_USED (size) free (ptr);}
  174. /*------------------------------------------------------------------------*/
  175. void *x__realloc (void *ptr, int old_size, int size)
  176.  
  177. {  NOT_USED (old_size)
  178.    NOT_USED (size)
  179.  
  180.    if ((ptr = realloc (ptr, size)) == NULL && size != 0)
  181.       messagetrans_error_lookup (Error_No_Memory, NULL, NULL, 0, SKIP,
  182.             SKIP, SKIP, SKIP);
  183.  
  184.    return ptr;
  185. }