00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <sys/types.h>
00038 #include <stdio.h>
00039 #include <string.h>
00040 #include <ctype.h>
00041 #include <limits.h>
00042 #include <stdlib.h>
00043 #include <regex.h>
00044
00045 #include "utils.h"
00046
00047 static char *regatoi(const regex_t *, char *, int);
00048
00049 static struct rerr {
00050 int code;
00051 char *name;
00052 char *explain;
00053 } rerrs[] = {
00054 { REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match" },
00055 { REG_BADPAT, "REG_BADPAT", "invalid regular expression" },
00056 { REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element" },
00057 { REG_ECTYPE, "REG_ECTYPE", "invalid character class" },
00058 { REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)" },
00059 { REG_ESUBREG, "REG_ESUBREG", "invalid backreference number" },
00060 { REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced" },
00061 { REG_EPAREN, "REG_EPAREN", "parentheses not balanced" },
00062 { REG_EBRACE, "REG_EBRACE", "braces not balanced" },
00063 { REG_BADBR, "REG_BADBR", "invalid repetition count(s)" },
00064 { REG_ERANGE, "REG_ERANGE", "invalid character range" },
00065 { REG_ESPACE, "REG_ESPACE", "out of memory" },
00066 { REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid" },
00067 { REG_EMPTY, "REG_EMPTY", "empty (sub)expression" },
00068 { REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug" },
00069 { REG_INVARG, "REG_INVARG", "invalid argument to regex routine" },
00070 { 0, "", "*** unknown regexp error code ***" }
00071 };
00072
00073
00074
00075
00076
00077
00078 size_t
00079 regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
00080 {
00081 struct rerr *r;
00082 size_t len;
00083 int target = errcode &~ REG_ITOA;
00084 char *s;
00085 char convbuf[50];
00086
00087 if (errcode == REG_ATOI)
00088 s = regatoi(preg, convbuf, sizeof convbuf);
00089 else {
00090 for (r = rerrs; r->code != 0; r++)
00091 if (r->code == target)
00092 break;
00093
00094 if (errcode®_ITOA) {
00095 if (r->code != 0) {
00096 assert(strlen(r->name) < sizeof(convbuf));
00097 (void) strlcpy(convbuf, r->name, sizeof convbuf);
00098 } else
00099 (void)snprintf(convbuf, sizeof convbuf,
00100 "REG_0x%x", target);
00101 s = convbuf;
00102 } else
00103 s = r->explain;
00104 }
00105
00106 len = strlen(s) + 1;
00107 if (errbuf_size > 0) {
00108 strlcpy(errbuf, s, errbuf_size);
00109 }
00110
00111 return(len);
00112 }
00113
00114
00115
00116
00117 static char *
00118 regatoi(const regex_t *preg, char *localbuf, int localbufsize)
00119 {
00120 struct rerr *r;
00121
00122 for (r = rerrs; r->code != 0; r++)
00123 if (strcmp(r->name, preg->re_endp) == 0)
00124 break;
00125 if (r->code == 0)
00126 return("0");
00127
00128 (void)snprintf(localbuf, localbufsize, "%d", r->code);
00129 return(localbuf);
00130 }