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