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