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