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