home *** CD-ROM | disk | FTP | other *** search
- /* History:
- 5/1/91 DJB baseline public domain
- */
-
- #include <stdio.h>
- #include <errno.h>
- extern int errno;
- extern int sys_nerr;
- extern char *sys_errlist[];
- #include <strings.h>
- #include "mallocfree.h"
- #include "strerr.h"
-
- char *strerrtaberr(ke,err,tab,n,dfl)
- strerrfun *ke;
- int err; /* error number */
- struct strerrtab *tab; /* error table */
- int n; /* size of tab */
- char *dfl; /* what to say if err isn't in tab */
- {
- int i;
- if ((err < 0) || (err >= n))
- {
- *ke = 0;
- return dfl;
- }
- if (tab[err].err != err)
- {
- for (i = 0;i < n;++i)
- if (tab[i].err == err)
- break;
- if (i == n)
- {
- *ke = 0;
- return dfl;
- }
- }
- else
- i = err; /* fastest this way */
- /* So now tab[i].err == err. */
- *ke = tab[i].next;
- return tab[i].s;
- }
-
- char *strerrstr(ke,s)
- strerrfun *ke;
- char *s;
- {
- *ke = 0;
- return s;
- }
-
- char *strerrsys(ke)
- strerrfun *ke;
- {
- *ke = strerrno;
- return ": ";
- }
-
- static char unk[30];
-
- char *strerrno(ke)
- strerrfun *ke;
- {
- *ke = 0;
- if ((errno < 0) || (errno > sys_nerr))
- {
- (void) sprintf(unk,"unknown error %d",errno);
- return unk;
- }
- return sys_errlist[errno];
- }
-
- struct sel { struct sel *next; char *s; unsigned len; } ;
-
- char *strerr(ke)
- strerrfun ke;
- {
- char *s;
- char *t;
- struct sel head;
- struct sel *sel;
- struct sel *temp;
- int saveerrno; /*XXX: what if malloc messes up other errors? */
- unsigned len;
-
- head.next = 0;
- sel = &head;
-
- /* Note that *sel is always allocated. We do this so that we can */
- /* better handle malloc errors. */
-
- while (ke)
- {
- s = ke(&ke);
- saveerrno = errno;
- temp = (struct sel *) malloc(sizeof(struct sel));
- if (!temp)
- {
- sel->s = "aack! malloc error";
- sel->len = strlen(sel->s);
- break;
- }
- errno = saveerrno;
- sel->next = temp;
- temp->next = 0;
- sel->s = s;
- sel->len = strlen(s);
- sel = temp;
- }
-
- len = 1;
- for (sel = &head;temp = sel->next;sel = temp)
- len += sel->len;
-
- s = malloc(len);
- if (!s)
- return "aack! malloc error"; /*XXX*/
-
- t = s;
- for (sel = &head;temp = sel->next;sel = temp)
- {
- (void) strcpy(t,sel->s);
- t += sel->len;
- if (sel != &head) /*XXX*/
- free((char *) sel);
- }
- free((char *) sel);
-
- return s;
- }
-