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®_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