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