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 >
Wrap
C/C++ Source or Header
|
1991-05-06
|
2KB
|
132 lines
/* 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;
}