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