xref: /freebsd/contrib/nvi/regex/regerror.c (revision f0957ccae4f402b93cf27b125542343d28b53109)
1*f0957ccaSPeter Wemm /*	$NetBSD: regerror.c,v 1.2 2008/12/05 22:51:43 christos Exp $ */
2*f0957ccaSPeter Wemm 
3*f0957ccaSPeter Wemm /*-
4*f0957ccaSPeter Wemm  * Copyright (c) 1992, 1993, 1994 Henry Spencer.
5*f0957ccaSPeter Wemm  * Copyright (c) 1992, 1993, 1994
6*f0957ccaSPeter Wemm  *	The Regents of the University of California.  All rights reserved.
7*f0957ccaSPeter Wemm  *
8*f0957ccaSPeter Wemm  * This code is derived from software contributed to Berkeley by
9*f0957ccaSPeter Wemm  * Henry Spencer of the University of Toronto.
10*f0957ccaSPeter Wemm  *
11*f0957ccaSPeter Wemm  * Redistribution and use in source and binary forms, with or without
12*f0957ccaSPeter Wemm  * modification, are permitted provided that the following conditions
13*f0957ccaSPeter Wemm  * are met:
14*f0957ccaSPeter Wemm  * 1. Redistributions of source code must retain the above copyright
15*f0957ccaSPeter Wemm  *    notice, this list of conditions and the following disclaimer.
16*f0957ccaSPeter Wemm  * 2. Redistributions in binary form must reproduce the above copyright
17*f0957ccaSPeter Wemm  *    notice, this list of conditions and the following disclaimer in the
18*f0957ccaSPeter Wemm  *    documentation and/or other materials provided with the distribution.
19*f0957ccaSPeter Wemm  * 3. All advertising materials mentioning features or use of this software
20*f0957ccaSPeter Wemm  *    must display the following acknowledgement:
21*f0957ccaSPeter Wemm  *	This product includes software developed by the University of
22*f0957ccaSPeter Wemm  *	California, Berkeley and its contributors.
23*f0957ccaSPeter Wemm  * 4. Neither the name of the University nor the names of its contributors
24*f0957ccaSPeter Wemm  *    may be used to endorse or promote products derived from this software
25*f0957ccaSPeter Wemm  *    without specific prior written permission.
26*f0957ccaSPeter Wemm  *
27*f0957ccaSPeter Wemm  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28*f0957ccaSPeter Wemm  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29*f0957ccaSPeter Wemm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30*f0957ccaSPeter Wemm  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31*f0957ccaSPeter Wemm  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32*f0957ccaSPeter Wemm  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33*f0957ccaSPeter Wemm  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34*f0957ccaSPeter Wemm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35*f0957ccaSPeter Wemm  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36*f0957ccaSPeter Wemm  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37*f0957ccaSPeter Wemm  * SUCH DAMAGE.
38*f0957ccaSPeter Wemm  *
39*f0957ccaSPeter Wemm  *	@(#)regerror.c	8.3 (Berkeley) 3/19/94
40*f0957ccaSPeter Wemm  */
41*f0957ccaSPeter Wemm 
42*f0957ccaSPeter Wemm #if defined(LIBC_SCCS) && !defined(lint)
43*f0957ccaSPeter Wemm static char sccsid[] = "@(#)regerror.c	8.3 (Berkeley) 3/19/94";
44*f0957ccaSPeter Wemm #endif /* LIBC_SCCS and not lint */
45*f0957ccaSPeter Wemm 
46*f0957ccaSPeter Wemm #include <sys/types.h>
47*f0957ccaSPeter Wemm #include <stdio.h>
48*f0957ccaSPeter Wemm #include <string.h>
49*f0957ccaSPeter Wemm #include <ctype.h>
50*f0957ccaSPeter Wemm #include <limits.h>
51*f0957ccaSPeter Wemm #include <stdlib.h>
52*f0957ccaSPeter Wemm #include <regex.h>
53*f0957ccaSPeter Wemm 
54*f0957ccaSPeter Wemm #include "utils.h"
55*f0957ccaSPeter Wemm 
56*f0957ccaSPeter Wemm /* ========= begin header generated by ./mkh ========= */
57*f0957ccaSPeter Wemm #ifdef __cplusplus
58*f0957ccaSPeter Wemm extern "C" {
59*f0957ccaSPeter Wemm #endif
60*f0957ccaSPeter Wemm 
61*f0957ccaSPeter Wemm /* === regerror.c === */
62*f0957ccaSPeter Wemm static char *regatoi __P((const regex_t *preg, char *localbuf));
63*f0957ccaSPeter Wemm 
64*f0957ccaSPeter Wemm #ifdef __cplusplus
65*f0957ccaSPeter Wemm }
66*f0957ccaSPeter Wemm #endif
67*f0957ccaSPeter Wemm /* ========= end header generated by ./mkh ========= */
68*f0957ccaSPeter Wemm /*
69*f0957ccaSPeter Wemm  = #define	REG_NOMATCH	 1
70*f0957ccaSPeter Wemm  = #define	REG_BADPAT	 2
71*f0957ccaSPeter Wemm  = #define	REG_ECOLLATE	 3
72*f0957ccaSPeter Wemm  = #define	REG_ECTYPE	 4
73*f0957ccaSPeter Wemm  = #define	REG_EESCAPE	 5
74*f0957ccaSPeter Wemm  = #define	REG_ESUBREG	 6
75*f0957ccaSPeter Wemm  = #define	REG_EBRACK	 7
76*f0957ccaSPeter Wemm  = #define	REG_EPAREN	 8
77*f0957ccaSPeter Wemm  = #define	REG_EBRACE	 9
78*f0957ccaSPeter Wemm  = #define	REG_BADBR	10
79*f0957ccaSPeter Wemm  = #define	REG_ERANGE	11
80*f0957ccaSPeter Wemm  = #define	REG_ESPACE	12
81*f0957ccaSPeter Wemm  = #define	REG_BADRPT	13
82*f0957ccaSPeter Wemm  = #define	REG_EMPTY	14
83*f0957ccaSPeter Wemm  = #define	REG_ASSERT	15
84*f0957ccaSPeter Wemm  = #define	REG_INVARG	16
85*f0957ccaSPeter Wemm  = #define	REG_ATOI	255	// convert name to number (!)
86*f0957ccaSPeter Wemm  = #define	REG_ITOA	0400	// convert number to name (!)
87*f0957ccaSPeter Wemm  */
88*f0957ccaSPeter Wemm static struct rerr {
89*f0957ccaSPeter Wemm 	int code;
90*f0957ccaSPeter Wemm 	const char *name;
91*f0957ccaSPeter Wemm 	const char *explain;
92*f0957ccaSPeter Wemm } rerrs[] = {
93*f0957ccaSPeter Wemm 	{ REG_NOMATCH,	"REG_NOMATCH",	"regexec() failed to match" },
94*f0957ccaSPeter Wemm 	{ REG_BADPAT,	"REG_BADPAT",	"invalid regular expression" },
95*f0957ccaSPeter Wemm 	{ REG_ECOLLATE,	"REG_ECOLLATE",	"invalid collating element" },
96*f0957ccaSPeter Wemm 	{ REG_ECTYPE,	"REG_ECTYPE",	"invalid character class" },
97*f0957ccaSPeter Wemm 	{ REG_EESCAPE,	"REG_EESCAPE",	"trailing backslash (\\)" },
98*f0957ccaSPeter Wemm 	{ REG_ESUBREG,	"REG_ESUBREG",	"invalid backreference number" },
99*f0957ccaSPeter Wemm 	{ REG_EBRACK,	"REG_EBRACK",	"brackets ([ ]) not balanced" },
100*f0957ccaSPeter Wemm 	{ REG_EPAREN,	"REG_EPAREN",	"parentheses not balanced" },
101*f0957ccaSPeter Wemm 	{ REG_EBRACE,	"REG_EBRACE",	"braces not balanced" },
102*f0957ccaSPeter Wemm 	{ REG_BADBR,	"REG_BADBR",	"invalid repetition count(s)" },
103*f0957ccaSPeter Wemm 	{ REG_ERANGE,	"REG_ERANGE",	"invalid character range" },
104*f0957ccaSPeter Wemm 	{ REG_ESPACE,	"REG_ESPACE",	"out of memory" },
105*f0957ccaSPeter Wemm 	{ REG_BADRPT,	"REG_BADRPT",	"repetition-operator operand invalid" },
106*f0957ccaSPeter Wemm 	{ REG_EMPTY,	"REG_EMPTY",	"empty (sub)expression" },
107*f0957ccaSPeter Wemm 	{ REG_ASSERT,	"REG_ASSERT",	"\"can't happen\" -- you found a bug" },
108*f0957ccaSPeter Wemm 	{ REG_INVARG,	"REG_INVARG",	"invalid argument to regex routine" },
109*f0957ccaSPeter Wemm 	{ 0,		"",		"*** unknown regexp error code ***" },
110*f0957ccaSPeter Wemm };
111*f0957ccaSPeter Wemm 
112*f0957ccaSPeter Wemm /*
113*f0957ccaSPeter Wemm  - regerror - the interface to error numbers
114*f0957ccaSPeter Wemm  = extern size_t regerror(int, const regex_t *, char *, size_t);
115*f0957ccaSPeter Wemm  */
116*f0957ccaSPeter Wemm /* ARGSUSED */
117*f0957ccaSPeter Wemm size_t
118*f0957ccaSPeter Wemm regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
119*f0957ccaSPeter Wemm {
120*f0957ccaSPeter Wemm 	register struct rerr *r;
121*f0957ccaSPeter Wemm 	register size_t len;
122*f0957ccaSPeter Wemm 	register int target = errcode &~ REG_ITOA;
123*f0957ccaSPeter Wemm 	register const char *s;
124*f0957ccaSPeter Wemm 	char convbuf[50];
125*f0957ccaSPeter Wemm 
126*f0957ccaSPeter Wemm 	if (errcode == REG_ATOI)
127*f0957ccaSPeter Wemm 		s = regatoi(preg, convbuf);
128*f0957ccaSPeter Wemm 	else {
129*f0957ccaSPeter Wemm 		for (r = rerrs; r->code != 0; r++)
130*f0957ccaSPeter Wemm 			if (r->code == target)
131*f0957ccaSPeter Wemm 				break;
132*f0957ccaSPeter Wemm 
133*f0957ccaSPeter Wemm 		if (errcode&REG_ITOA) {
134*f0957ccaSPeter Wemm 			if (r->code != 0) {
135*f0957ccaSPeter Wemm 				assert(strlen(r->name) < sizeof(convbuf));
136*f0957ccaSPeter Wemm 				(void) strlcpy(convbuf, r->name, sizeof(convbuf));
137*f0957ccaSPeter Wemm 			} else
138*f0957ccaSPeter Wemm 				(void) snprintf(convbuf, sizeof(convbuf),
139*f0957ccaSPeter Wemm 				    "REG_0x%x", target);
140*f0957ccaSPeter Wemm 			s = convbuf;
141*f0957ccaSPeter Wemm 		} else
142*f0957ccaSPeter Wemm 			s = r->explain;
143*f0957ccaSPeter Wemm 	}
144*f0957ccaSPeter Wemm 
145*f0957ccaSPeter Wemm 	len = strlen(s) + 1;
146*f0957ccaSPeter Wemm 	if (errbuf_size > 0) {
147*f0957ccaSPeter Wemm 		(void) strlcpy(errbuf, s, errbuf_size);
148*f0957ccaSPeter Wemm 	}
149*f0957ccaSPeter Wemm 
150*f0957ccaSPeter Wemm 	return(len);
151*f0957ccaSPeter Wemm }
152*f0957ccaSPeter Wemm 
153*f0957ccaSPeter Wemm /*
154*f0957ccaSPeter Wemm  - regatoi - internal routine to implement REG_ATOI
155*f0957ccaSPeter Wemm  == static char *regatoi(const regex_t *preg, char *localbuf);
156*f0957ccaSPeter Wemm  */
157*f0957ccaSPeter Wemm static char *
158*f0957ccaSPeter Wemm regatoi(const regex_t *preg, char *localbuf)
159*f0957ccaSPeter Wemm {
160*f0957ccaSPeter Wemm #if 0 /* we don't seem to use this and it gives a warning. */
161*f0957ccaSPeter Wemm 	register struct rerr *r;
162*f0957ccaSPeter Wemm 	register size_t siz;
163*f0957ccaSPeter Wemm 	register char *p;
164*f0957ccaSPeter Wemm 
165*f0957ccaSPeter Wemm 	for (r = rerrs; r->code != 0; r++)
166*f0957ccaSPeter Wemm 		if (strcmp(r->name, preg->re_endp) == 0)
167*f0957ccaSPeter Wemm 			break;
168*f0957ccaSPeter Wemm 	if (r->code == 0)
169*f0957ccaSPeter Wemm 		return("0");
170*f0957ccaSPeter Wemm 
171*f0957ccaSPeter Wemm 	sprintf(localbuf, "%d", r->code);
172*f0957ccaSPeter Wemm #else
173*f0957ccaSPeter Wemm 	*localbuf = '\0';
174*f0957ccaSPeter Wemm #endif
175*f0957ccaSPeter Wemm 	return(localbuf);
176*f0957ccaSPeter Wemm }
177