1 /*- 2 * Copyright (c) 1992, 1993, 1994 Henry Spencer. 3 * Copyright (c) 1992, 1993, 1994 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Henry Spencer of the University of Toronto. 8 * 9 * %sccs.include.redist.c% 10 * 11 * @(#)regerror.c 8.3 (Berkeley) 03/19/94 12 */ 13 14 #if defined(LIBC_SCCS) && !defined(lint) 15 static char sccsid[] = "@(#)regerror.c 8.3 (Berkeley) 03/19/94"; 16 #endif /* LIBC_SCCS and not lint */ 17 18 #include <sys/types.h> 19 #include <stdio.h> 20 #include <string.h> 21 #include <ctype.h> 22 #include <limits.h> 23 #include <stdlib.h> 24 #include <regex.h> 25 26 #include "utils.h" 27 28 /* ========= begin header generated by ./mkh ========= */ 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /* === regerror.c === */ 34 static char *regatoi __P((const regex_t *preg, char *localbuf)); 35 36 #ifdef __cplusplus 37 } 38 #endif 39 /* ========= end header generated by ./mkh ========= */ 40 /* 41 = #define REG_NOMATCH 1 42 = #define REG_BADPAT 2 43 = #define REG_ECOLLATE 3 44 = #define REG_ECTYPE 4 45 = #define REG_EESCAPE 5 46 = #define REG_ESUBREG 6 47 = #define REG_EBRACK 7 48 = #define REG_EPAREN 8 49 = #define REG_EBRACE 9 50 = #define REG_BADBR 10 51 = #define REG_ERANGE 11 52 = #define REG_ESPACE 12 53 = #define REG_BADRPT 13 54 = #define REG_EMPTY 14 55 = #define REG_ASSERT 15 56 = #define REG_INVARG 16 57 = #define REG_ATOI 255 // convert name to number (!) 58 = #define REG_ITOA 0400 // convert number to name (!) 59 */ 60 static struct rerr { 61 int code; 62 char *name; 63 char *explain; 64 } rerrs[] = { 65 REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match", 66 REG_BADPAT, "REG_BADPAT", "invalid regular expression", 67 REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element", 68 REG_ECTYPE, "REG_ECTYPE", "invalid character class", 69 REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)", 70 REG_ESUBREG, "REG_ESUBREG", "invalid backreference number", 71 REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced", 72 REG_EPAREN, "REG_EPAREN", "parentheses not balanced", 73 REG_EBRACE, "REG_EBRACE", "braces not balanced", 74 REG_BADBR, "REG_BADBR", "invalid repetition count(s)", 75 REG_ERANGE, "REG_ERANGE", "invalid character range", 76 REG_ESPACE, "REG_ESPACE", "out of memory", 77 REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid", 78 REG_EMPTY, "REG_EMPTY", "empty (sub)expression", 79 REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug", 80 REG_INVARG, "REG_INVARG", "invalid argument to regex routine", 81 0, "", "*** unknown regexp error code ***", 82 }; 83 84 /* 85 - regerror - the interface to error numbers 86 = extern size_t regerror(int, const regex_t *, char *, size_t); 87 */ 88 /* ARGSUSED */ 89 size_t 90 regerror(errcode, preg, errbuf, errbuf_size) 91 int errcode; 92 const regex_t *preg; 93 char *errbuf; 94 size_t errbuf_size; 95 { 96 register struct rerr *r; 97 register size_t len; 98 register int target = errcode &~ REG_ITOA; 99 register char *s; 100 char convbuf[50]; 101 102 if (errcode == REG_ATOI) 103 s = regatoi(preg, convbuf); 104 else { 105 for (r = rerrs; r->code != 0; r++) 106 if (r->code == target) 107 break; 108 109 if (errcode®_ITOA) { 110 if (r->code != 0) 111 (void) strcpy(convbuf, r->name); 112 else 113 sprintf(convbuf, "REG_0x%x", target); 114 assert(strlen(convbuf) < sizeof(convbuf)); 115 s = convbuf; 116 } else 117 s = r->explain; 118 } 119 120 len = strlen(s) + 1; 121 if (errbuf_size > 0) { 122 if (errbuf_size > len) 123 (void) strcpy(errbuf, s); 124 else { 125 (void) strncpy(errbuf, s, errbuf_size-1); 126 errbuf[errbuf_size-1] = '\0'; 127 } 128 } 129 130 return(len); 131 } 132 133 /* 134 - regatoi - internal routine to implement REG_ATOI 135 == static char *regatoi(const regex_t *preg, char *localbuf); 136 */ 137 static char * 138 regatoi(preg, localbuf) 139 const regex_t *preg; 140 char *localbuf; 141 { 142 register struct rerr *r; 143 register size_t siz; 144 register char *p; 145 146 for (r = rerrs; r->code != 0; r++) 147 if (strcmp(r->name, preg->re_endp) == 0) 148 break; 149 if (r->code == 0) 150 return("0"); 151 152 sprintf(localbuf, "%d", r->code); 153 return(localbuf); 154 } 155