Imported Upstream version 2.5.1
[debian/amanda] / regex-src / regerror.c
1 #include "amanda.h"
2 #include <regex.h>
3 #include "utils.h"
4 #include "regerror.ih"
5
6 /*
7  = #define      REG_OKAY         0
8  = #define      REG_NOMATCH      1
9  = #define      REG_BADPAT       2
10  = #define      REG_ECOLLATE     3
11  = #define      REG_ECTYPE       4
12  = #define      REG_EESCAPE      5
13  = #define      REG_ESUBREG      6
14  = #define      REG_EBRACK       7
15  = #define      REG_EPAREN       8
16  = #define      REG_EBRACE       9
17  = #define      REG_BADBR       10
18  = #define      REG_ERANGE      11
19  = #define      REG_ESPACE      12
20  = #define      REG_BADRPT      13
21  = #define      REG_EMPTY       14
22  = #define      REG_ASSERT      15
23  = #define      REG_INVARG      16
24  = #define      REG_ATOI        255     // convert name to number (!)
25  = #define      REG_ITOA        0400    // convert number to name (!)
26  */
27 static struct rerr {
28         int code;
29         char *name;
30         char *explain;
31 } rerrs[] = {
32         { REG_OKAY,     "REG_OKAY",     "no errors detected"},
33         { REG_NOMATCH,  "REG_NOMATCH",  "regexec() failed to match"},
34         { REG_BADPAT,   "REG_BADPAT",   "invalid regular expression"},
35         { REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"},
36         { REG_ECTYPE,   "REG_ECTYPE",   "invalid character class"},
37         { REG_EESCAPE,  "REG_EESCAPE",  "trailing backslash (\\)"},
38         { REG_ESUBREG,  "REG_ESUBREG",  "invalid backreference number"},
39         { REG_EBRACK,   "REG_EBRACK",   "brackets ([ ]) not balanced"},
40         { REG_EPAREN,   "REG_EPAREN",   "parentheses not balanced"},
41         { REG_EBRACE,   "REG_EBRACE",   "braces not balanced"},
42         { REG_BADBR,    "REG_BADBR",    "invalid repetition count(s)"},
43         { REG_ERANGE,   "REG_ERANGE",   "invalid character range"},
44         { REG_ESPACE,   "REG_ESPACE",   "out of memory"},
45         { REG_BADRPT,   "REG_BADRPT",   "repetition-operator operand invalid"},
46         { REG_EMPTY,    "REG_EMPTY",    "empty (sub)expression"},
47         { REG_ASSERT,   "REG_ASSERT",   "\"can't happen\" -- you found a bug"},
48         { REG_INVARG,   "REG_INVARG",   "invalid argument to regex routine"},
49         { -1,           "",             "*** unknown regexp error code ***"}
50 };
51
52 /*
53  - regerror - the interface to error numbers
54  = extern size_t regerror(int, const regex_t *, char *, size_t);
55  */
56 /* ARGSUSED */
57 size_t
58 regerror(
59     int            errcode,
60     const regex_t *preg,
61     char *         errbuf,
62     size_t         errbuf_size)
63 {
64         register struct rerr *r;
65         register size_t len;
66         register int target = errcode &~ REG_ITOA;
67         register char *s;
68         char convbuf[50];
69
70         if (errcode == REG_ATOI)
71                 s = regatoi(preg, convbuf, SIZEOF(convbuf));
72         else {
73                 for (r = rerrs; r->code >= 0; r++)
74                         if (r->code == target)
75                                 break;
76
77                 if (errcode&REG_ITOA) {
78                         if (r->code >= 0) {
79                                 strncpy(convbuf, r->name, SIZEOF(convbuf)-1);
80                                 convbuf[SIZEOF(convbuf)-1] = '\0';
81                         } else {
82                                 snprintf(convbuf, SIZEOF(convbuf),
83                                             "REG_0x%x", (unsigned)target);
84                         }
85                         assert(strlen(convbuf) < SIZEOF(convbuf));
86                         s = convbuf;
87                 } else
88                         s = r->explain;
89         }
90
91         len = strlen(s) + 1;
92         if (errbuf_size > 0) {
93                 (void) strncpy(errbuf, s, errbuf_size-1);
94                 errbuf[errbuf_size-1] = '\0';
95         }
96
97         return(len);
98 }
99
100 /*
101  - regatoi - internal routine to implement REG_ATOI
102  == static char *regatoi(const regex_t *preg, char *localbuf, size_t buflen);
103  */
104 static char *
105 regatoi(
106     const regex_t *     preg,
107     char *              localbuf,
108     size_t              buflen)
109 {
110         register struct rerr *r;
111
112         for (r = rerrs; r->code >= 0; r++) {
113                 /*@ignore@*/
114                 if (strcmp(r->name, preg->re_endp) == 0)
115                         break;
116                 /*@end@*/
117         }
118         if (r->code < 0)
119                 return("0");
120
121         snprintf(localbuf, buflen, "%d", r->code);
122         return(localbuf);
123 }