xref: /illumos-gate/usr/src/lib/libc/port/regex/regerror.c (revision 490fea6b)
14297a3b0SGarrett D'Amore /*
20e8139c7SGarrett D'Amore  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
34297a3b0SGarrett D'Amore  * Copyright (c) 1992, 1993, 1994 Henry Spencer.
44297a3b0SGarrett D'Amore  * Copyright (c) 1992, 1993, 1994
54297a3b0SGarrett D'Amore  *	The Regents of the University of California.  All rights reserved.
64297a3b0SGarrett D'Amore  *
74297a3b0SGarrett D'Amore  * This code is derived from software contributed to Berkeley by
84297a3b0SGarrett D'Amore  * Henry Spencer.
94297a3b0SGarrett D'Amore  *
104297a3b0SGarrett D'Amore  * Redistribution and use in source and binary forms, with or without
114297a3b0SGarrett D'Amore  * modification, are permitted provided that the following conditions
124297a3b0SGarrett D'Amore  * are met:
134297a3b0SGarrett D'Amore  * 1. Redistributions of source code must retain the above copyright
144297a3b0SGarrett D'Amore  *    notice, this list of conditions and the following disclaimer.
154297a3b0SGarrett D'Amore  * 2. Redistributions in binary form must reproduce the above copyright
164297a3b0SGarrett D'Amore  *    notice, this list of conditions and the following disclaimer in the
174297a3b0SGarrett D'Amore  *    documentation and/or other materials provided with the distribution.
187641c5eaSYuri Pankov  * 3. Neither the name of the University nor the names of its contributors
194297a3b0SGarrett D'Amore  *    may be used to endorse or promote products derived from this software
204297a3b0SGarrett D'Amore  *    without specific prior written permission.
214297a3b0SGarrett D'Amore  *
224297a3b0SGarrett D'Amore  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
234297a3b0SGarrett D'Amore  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
244297a3b0SGarrett D'Amore  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
254297a3b0SGarrett D'Amore  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
264297a3b0SGarrett D'Amore  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
274297a3b0SGarrett D'Amore  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
284297a3b0SGarrett D'Amore  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
294297a3b0SGarrett D'Amore  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
304297a3b0SGarrett D'Amore  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
314297a3b0SGarrett D'Amore  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
324297a3b0SGarrett D'Amore  * SUCH DAMAGE.
334297a3b0SGarrett D'Amore  */
344297a3b0SGarrett D'Amore 
354297a3b0SGarrett D'Amore #include "lint.h"
364297a3b0SGarrett D'Amore #include "file64.h"
374297a3b0SGarrett D'Amore #include <sys/types.h>
384297a3b0SGarrett D'Amore #include <stdio.h>
394297a3b0SGarrett D'Amore #include <string.h>
404297a3b0SGarrett D'Amore #include <limits.h>
414297a3b0SGarrett D'Amore #include <stdlib.h>
424297a3b0SGarrett D'Amore #include <regex.h>
434297a3b0SGarrett D'Amore 
444297a3b0SGarrett D'Amore #include "utils.h"
450e8139c7SGarrett D'Amore #include "../gen/_libc_gettext.h"
460e8139c7SGarrett D'Amore 
47*490fea6bSYuri Pankov static const char *regatoi(const regex_t *preg, char *localbuf);
48*490fea6bSYuri Pankov 
490e8139c7SGarrett D'Amore #define	RERR(x, msg)	{ x, #x, msg }
504297a3b0SGarrett D'Amore 
514297a3b0SGarrett D'Amore static struct rerr {
524297a3b0SGarrett D'Amore 	int code;
537641c5eaSYuri Pankov 	const char *name;
547641c5eaSYuri Pankov 	const char *explain;
554297a3b0SGarrett D'Amore } rerrs[] = {
560e8139c7SGarrett D'Amore 	RERR(REG_NOMATCH,	"regexec() failed to match"),
570e8139c7SGarrett D'Amore 	RERR(REG_BADPAT,	"invalid regular expression"),
580e8139c7SGarrett D'Amore 	RERR(REG_ECOLLATE,	"invalid collating element"),
590e8139c7SGarrett D'Amore 	RERR(REG_ECTYPE,	"invalid character class"),
600e8139c7SGarrett D'Amore 	RERR(REG_EESCAPE,	"trailing backslash (\\)"),
610e8139c7SGarrett D'Amore 	RERR(REG_ESUBREG,	"invalid backreference number"),
620e8139c7SGarrett D'Amore 	RERR(REG_EBRACK,	"brackets ([ ]) not balanced"),
630e8139c7SGarrett D'Amore 	RERR(REG_EPAREN,	"parentheses not balanced"),
640e8139c7SGarrett D'Amore 	RERR(REG_EBRACE,	"braces not balanced"),
650e8139c7SGarrett D'Amore 	RERR(REG_BADBR,		"invalid repetition count(s)"),
660e8139c7SGarrett D'Amore 	RERR(REG_ERANGE,	"invalid character range"),
670e8139c7SGarrett D'Amore 	RERR(REG_ESPACE,	"out of memory"),
680e8139c7SGarrett D'Amore 	RERR(REG_BADRPT,	"repetition-operator operand invalid"),
694297a3b0SGarrett D'Amore #ifdef	REG_EMPTY
700e8139c7SGarrett D'Amore 	RERR(REG_EMPTY,		"empty (sub)expression"),
714297a3b0SGarrett D'Amore #endif
720e8139c7SGarrett D'Amore 	RERR(REG_EFATAL,	"fatal internal error"),
734297a3b0SGarrett D'Amore #ifdef	REG_INVARG
740e8139c7SGarrett D'Amore 	RERR(REG_INVARG,	"invalid argument to regex routine"),
754297a3b0SGarrett D'Amore #endif
760e8139c7SGarrett D'Amore 	RERR(REG_ECHAR,		"illegal byte sequence"),
770e8139c7SGarrett D'Amore 	RERR(REG_ENOSYS,	"function not supported"),
780e8139c7SGarrett D'Amore 	RERR(REG_STACK,		"backtrack stack overflow"),
790e8139c7SGarrett D'Amore 	RERR(REG_ENSUB,		"more than 9 \\( \\) pairs"),
800e8139c7SGarrett D'Amore 	RERR(REG_ENEWLINE,	"\n found before end of pattern"),
810e8139c7SGarrett D'Amore 	{0,	"",		"*** unknown regexp error code ***"}
824297a3b0SGarrett D'Amore };
834297a3b0SGarrett D'Amore 
844297a3b0SGarrett D'Amore 
854297a3b0SGarrett D'Amore /*
864297a3b0SGarrett D'Amore  * regerror - the interface to error numbers
874297a3b0SGarrett D'Amore  */
884297a3b0SGarrett D'Amore /* ARGSUSED */
894297a3b0SGarrett D'Amore size_t
regerror(int errcode,const regex_t * _RESTRICT_KYWD preg,char * _RESTRICT_KYWD errbuf,size_t errbuf_size)904297a3b0SGarrett D'Amore regerror(int errcode, const regex_t *_RESTRICT_KYWD preg,
914297a3b0SGarrett D'Amore     char *_RESTRICT_KYWD errbuf, size_t errbuf_size)
924297a3b0SGarrett D'Amore {
934297a3b0SGarrett D'Amore 	struct rerr *r;
944297a3b0SGarrett D'Amore 	size_t len;
95*490fea6bSYuri Pankov 	int target = errcode &~ REG_ITOA;
967641c5eaSYuri Pankov 	const char *s;
97*490fea6bSYuri Pankov 	char convbuf[50];
984297a3b0SGarrett D'Amore 
99*490fea6bSYuri Pankov 	if (errcode == REG_ATOI) {
100*490fea6bSYuri Pankov 		s = regatoi(preg, convbuf);
101*490fea6bSYuri Pankov 	} else {
102*490fea6bSYuri Pankov 		for (r = rerrs; r->code != 0; r++) {
103*490fea6bSYuri Pankov 			if (r->code == target)
104*490fea6bSYuri Pankov 				break;
105*490fea6bSYuri Pankov 		}
1064297a3b0SGarrett D'Amore 
107*490fea6bSYuri Pankov 		if (errcode&REG_ITOA) {
108*490fea6bSYuri Pankov 			if (r->code != 0)
109*490fea6bSYuri Pankov 				(void) strcpy(convbuf, r->name);
110*490fea6bSYuri Pankov 			else
111*490fea6bSYuri Pankov 				(void) sprintf(convbuf, "REG_0x%x", target);
112*490fea6bSYuri Pankov 			assert(strlen(convbuf) < sizeof (convbuf));
113*490fea6bSYuri Pankov 			s = convbuf;
114*490fea6bSYuri Pankov 		} else {
115*490fea6bSYuri Pankov 			s = _libc_gettext(r->explain);
116*490fea6bSYuri Pankov 		}
117*490fea6bSYuri Pankov 	}
1184297a3b0SGarrett D'Amore 
1194297a3b0SGarrett D'Amore 	len = strlen(s) + 1;
1204297a3b0SGarrett D'Amore 	if (errbuf_size > 0) {
121*490fea6bSYuri Pankov 		if (errbuf_size > len) {
1224297a3b0SGarrett D'Amore 			(void) strcpy(errbuf, s);
123*490fea6bSYuri Pankov 		} else {
1244297a3b0SGarrett D'Amore 			(void) strncpy(errbuf, s, errbuf_size-1);
1254297a3b0SGarrett D'Amore 			errbuf[errbuf_size-1] = '\0';
1264297a3b0SGarrett D'Amore 		}
1274297a3b0SGarrett D'Amore 	}
1284297a3b0SGarrett D'Amore 
1294297a3b0SGarrett D'Amore 	return (len);
1304297a3b0SGarrett D'Amore }
131*490fea6bSYuri Pankov 
132*490fea6bSYuri Pankov /*
133*490fea6bSYuri Pankov  * regatoi - internal routine to implement REG_ATOI
134*490fea6bSYuri Pankov  */
135*490fea6bSYuri Pankov static const char *
regatoi(const regex_t * preg,char * localbuf)136*490fea6bSYuri Pankov regatoi(const regex_t *preg, char *localbuf)
137*490fea6bSYuri Pankov {
138*490fea6bSYuri Pankov 	struct rerr *r;
139*490fea6bSYuri Pankov 
140*490fea6bSYuri Pankov 	for (r = rerrs; r->code != 0; r++) {
141*490fea6bSYuri Pankov 		if (strcmp(r->name, preg->re_endp) == 0)
142*490fea6bSYuri Pankov 			break;
143*490fea6bSYuri Pankov 	}
144*490fea6bSYuri Pankov 	if (r->code == 0)
145*490fea6bSYuri Pankov 		return ("0");
146*490fea6bSYuri Pankov 
147*490fea6bSYuri Pankov 	(void) sprintf(localbuf, "%d", r->code);
148*490fea6bSYuri Pankov 	return (localbuf);
149*490fea6bSYuri Pankov }
150