1 /*
2  * regerror - error-code expansion
3  *
4  * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
5  *
6  * Development of this software was funded, in part, by Cray Research Inc.,
7  * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
8  * Corporation, none of whom are responsible for the results.  The author
9  * thanks all of them.
10  *
11  * Redistribution and use in source and binary forms -- with or without
12  * modification -- are permitted for any purpose, provided that
13  * redistributions in source form retain this entire copyright notice and
14  * indicate the origin and nature of any modifications.
15  *
16  * I'd appreciate being given credit for this package in the documentation of
17  * software which uses it, but that is not a requirement.
18  *
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
22  * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  */
31 
32 #include "regguts.h"
33 
34 /*
35  * Unknown-error explanation.
36  */
37 
38 static const char unk[] = "*** unknown regex error code 0x%x ***";
39 
40 /*
41  * Struct to map among codes, code names, and explanations.
42  */
43 
44 static struct rerr {
45     int code;
46     const char *name;
47     const char *explain;
48 } rerrs[] = {
49     /* The actual table is built from regex.h */
50 #include "regerrs.h"
51     { -1, "", "oops" },		/* explanation special-cased in code */
52 };
53 
54 /*
55  - regerror - the interface to error numbers
56  */
57 /* ARGSUSED */
58 size_t				/* Actual space needed (including NUL) */
regerror(int code,const regex_t * preg,char * errbuf,size_t errbuf_size)59 regerror(
60     int code,			/* Error code, or REG_ATOI or REG_ITOA */
61     const regex_t *preg,	/* Associated regex_t (unused at present) */
62     char *errbuf,		/* Result buffer (unless errbuf_size==0) */
63     size_t errbuf_size)		/* Available space in errbuf, can be 0 */
64 {
65     struct rerr *r;
66     const char *msg;
67     char convbuf[sizeof(unk)+50]; /* 50 = plenty for int */
68     size_t len;
69     int icode;
70 
71     switch (code) {
72     case REG_ATOI:		/* Convert name to number */
73 	for (r = rerrs; r->code >= 0; r++) {
74 	    if (strcmp(r->name, errbuf) == 0) {
75 		break;
76 	    }
77 	}
78 	sprintf(convbuf, "%d", r->code); /* -1 for unknown */
79 	msg = convbuf;
80 	break;
81     case REG_ITOA:		/* Convert number to name */
82 	icode = atoi(errbuf);	/* Not our problem if this fails */
83 	for (r = rerrs; r->code >= 0; r++) {
84 	    if (r->code == icode) {
85 		break;
86 	    }
87 	}
88 	if (r->code >= 0) {
89 	    msg = r->name;
90 	} else {		/* Unknown; tell him the number */
91 	    sprintf(convbuf, "REG_%u", (unsigned)icode);
92 	    msg = convbuf;
93 	}
94 	break;
95     default:			/* A real, normal error code */
96 	for (r = rerrs; r->code >= 0; r++) {
97 	    if (r->code == code) {
98 		break;
99 	    }
100 	}
101 	if (r->code >= 0) {
102 	    msg = r->explain;
103 	} else {		/* Unknown; say so */
104 	    sprintf(convbuf, unk, code);
105 	    msg = convbuf;
106 	}
107 	break;
108     }
109 
110     len = strlen(msg) + 1;	/* Space needed, including NUL */
111     if (errbuf_size > 0) {
112 	if (errbuf_size > len) {
113 	    strcpy(errbuf, msg);
114 	} else {		/* Truncate to fit */
115 	    strncpy(errbuf, msg, errbuf_size-1);
116 	    errbuf[errbuf_size-1] = '\0';
117 	}
118     }
119 
120     return len;
121 }
122 
123 /*
124  * Local Variables:
125  * mode: c
126  * c-basic-offset: 4
127  * fill-column: 78
128  * End:
129  */
130