home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3298 / strerr.c < prev    next >
C/C++ Source or Header  |  1991-05-06  |  2KB  |  132 lines

  1. /* History:
  2. 5/1/91 DJB baseline public domain
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <errno.h>
  7. extern int errno;
  8. extern int sys_nerr;
  9. extern char *sys_errlist[];
  10. #include <strings.h>
  11. #include "mallocfree.h"
  12. #include "strerr.h"
  13.  
  14. char *strerrtaberr(ke,err,tab,n,dfl)
  15. strerrfun *ke;
  16. int err; /* error number */
  17. struct strerrtab *tab; /* error table */
  18. int n; /* size of tab */
  19. char *dfl; /* what to say if err isn't in tab */
  20. {
  21.  int i;
  22.  if ((err < 0) || (err >= n))
  23.   {
  24.    *ke = 0;
  25.    return dfl;
  26.   }
  27.  if (tab[err].err != err)
  28.   {
  29.    for (i = 0;i < n;++i)
  30.      if (tab[i].err == err)
  31.        break;
  32.    if (i == n)
  33.     {
  34.      *ke = 0;
  35.      return dfl;
  36.     }
  37.   }
  38.  else
  39.    i = err; /* fastest this way */
  40.  /* So now tab[i].err == err. */
  41.  *ke = tab[i].next;
  42.  return tab[i].s;
  43. }
  44.  
  45. char *strerrstr(ke,s)
  46. strerrfun *ke;
  47. char *s;
  48. {
  49.  *ke = 0;
  50.  return s;
  51. }
  52.  
  53. char *strerrsys(ke)
  54. strerrfun *ke;
  55. {
  56.  *ke = strerrno;
  57.  return ": ";
  58. }
  59.  
  60. static char unk[30];
  61.  
  62. char *strerrno(ke)
  63. strerrfun *ke;
  64. {
  65.  *ke = 0;
  66.  if ((errno < 0) || (errno > sys_nerr))
  67.   {
  68.    (void) sprintf(unk,"unknown error %d",errno);
  69.    return unk;
  70.   }
  71.  return sys_errlist[errno];
  72. }
  73.  
  74. struct sel { struct sel *next; char *s; unsigned len; } ;
  75.  
  76. char *strerr(ke)
  77. strerrfun ke;
  78. {
  79.  char *s;
  80.  char *t;
  81.  struct sel head;
  82.  struct sel *sel;
  83.  struct sel *temp;
  84.  int saveerrno; /*XXX: what if malloc messes up other errors? */
  85.  unsigned len;
  86.  
  87.  head.next = 0;
  88.  sel = &head;
  89.  
  90.  /* Note that *sel is always allocated. We do this so that we can */
  91.  /* better handle malloc errors. */
  92.  
  93.  while (ke)
  94.   {
  95.    s = ke(&ke);
  96.    saveerrno = errno;
  97.    temp = (struct sel *) malloc(sizeof(struct sel));
  98.    if (!temp)
  99.     {
  100.      sel->s = "aack! malloc error";
  101.      sel->len = strlen(sel->s);
  102.      break;
  103.     }
  104.    errno = saveerrno;
  105.    sel->next = temp;
  106.    temp->next = 0;
  107.    sel->s = s;
  108.    sel->len = strlen(s);
  109.    sel = temp;
  110.   }
  111.  
  112.  len = 1;
  113.  for (sel = &head;temp = sel->next;sel = temp)
  114.    len += sel->len;
  115.  
  116.  s = malloc(len);
  117.  if (!s)
  118.    return "aack! malloc error"; /*XXX*/
  119.  
  120.  t = s;
  121.  for (sel = &head;temp = sel->next;sel = temp)
  122.   {
  123.    (void) strcpy(t,sel->s);
  124.    t += sel->len;
  125.    if (sel != &head) /*XXX*/
  126.      free((char *) sel);
  127.   }
  128.  free((char *) sel);
  129.  
  130.  return s;
  131. }
  132.