/*-1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright (c) 1992, 1993, 1994 Henry Spencer.4* Copyright (c) 1992, 1993, 19945* The Regents of the University of California. All rights reserved.6*7* This code is derived from software contributed to Berkeley by8* Henry Spencer.9*10* Redistribution and use in source and binary forms, with or without11* modification, are permitted provided that the following conditions12* are met:13* 1. Redistributions of source code must retain the above copyright14* notice, this list of conditions and the following disclaimer.15* 2. Redistributions in binary form must reproduce the above copyright16* notice, this list of conditions and the following disclaimer in the17* documentation and/or other materials provided with the distribution.18* 3. Neither the name of the University nor the names of its contributors19* may be used to endorse or promote products derived from this software20* without specific prior written permission.21*22* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND23* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE24* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE25* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE26* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL27* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS28* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)29* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT30* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY31* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF32* SUCH DAMAGE.33*/3435#include <sys/types.h>36#include <stdio.h>37#include <string.h>38#include <limits.h>39#include <stdlib.h>40#include <regex.h>4142#include "utils.h"4344/* ========= begin header generated by ./mkh ========= */45#ifdef __cplusplus46extern "C" {47#endif4849/* === regerror.c === */50static const char *regatoi(const regex_t *preg, char *localbuf);5152#ifdef __cplusplus53}54#endif55/* ========= end header generated by ./mkh ========= */56/*57= #define REG_NOMATCH 158= #define REG_BADPAT 259= #define REG_ECOLLATE 360= #define REG_ECTYPE 461= #define REG_EESCAPE 562= #define REG_ESUBREG 663= #define REG_EBRACK 764= #define REG_EPAREN 865= #define REG_EBRACE 966= #define REG_BADBR 1067= #define REG_ERANGE 1168= #define REG_ESPACE 1269= #define REG_BADRPT 1370= #define REG_EMPTY 1471= #define REG_ASSERT 1572= #define REG_INVARG 1673= #define REG_ILLSEQ 1774= #define REG_ATOI 255 // convert name to number (!)75= #define REG_ITOA 0400 // convert number to name (!)76*/77static struct rerr {78int code;79const char *name;80const char *explain;81} rerrs[] = {82{REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"},83{REG_BADPAT, "REG_BADPAT", "invalid regular expression"},84{REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"},85{REG_ECTYPE, "REG_ECTYPE", "invalid character class"},86{REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)"},87{REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"},88{REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced"},89{REG_EPAREN, "REG_EPAREN", "parentheses not balanced"},90{REG_EBRACE, "REG_EBRACE", "braces not balanced"},91{REG_BADBR, "REG_BADBR", "invalid repetition count(s)"},92{REG_ERANGE, "REG_ERANGE", "invalid character range"},93{REG_ESPACE, "REG_ESPACE", "out of memory"},94{REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid"},95{REG_EMPTY, "REG_EMPTY", "empty (sub)expression"},96{REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"},97{REG_INVARG, "REG_INVARG", "invalid argument to regex routine"},98{REG_ILLSEQ, "REG_ILLSEQ", "illegal byte sequence"},99{0, "", "*** unknown regexp error code ***"}100};101102/*103- regerror - the interface to error numbers104= extern size_t regerror(int, const regex_t *, char *, size_t);105*/106/* ARGSUSED */107size_t108regerror(int errcode,109const regex_t * __restrict preg,110char * __restrict errbuf,111size_t errbuf_size)112{113struct rerr *r;114size_t len;115int target = errcode &~ REG_ITOA;116const char *s;117char convbuf[50];118119if (errcode == REG_ATOI)120s = regatoi(preg, convbuf);121else {122for (r = rerrs; r->code != 0; r++)123if (r->code == target)124break;125126if (errcode®_ITOA) {127if (r->code != 0)128(void) strcpy(convbuf, r->name);129else130sprintf(convbuf, "REG_0x%x", target);131assert(strlen(convbuf) < sizeof(convbuf));132s = convbuf;133} else134s = r->explain;135}136137len = strlen(s) + 1;138if (errbuf_size > 0) {139if (errbuf_size > len)140(void) strcpy(errbuf, s);141else {142(void) strncpy(errbuf, s, errbuf_size-1);143errbuf[errbuf_size-1] = '\0';144}145}146147return(len);148}149150/*151- regatoi - internal routine to implement REG_ATOI152== static char *regatoi(const regex_t *preg, char *localbuf);153*/154static const char *155regatoi(const regex_t *preg, char *localbuf)156{157struct rerr *r;158159for (r = rerrs; r->code != 0; r++)160if (strcmp(r->name, preg->re_endp) == 0)161break;162if (r->code == 0)163return("0");164165sprintf(localbuf, "%d", r->code);166return(localbuf);167}168169170