1 /*
   2  * Copyright (c) 1992, 1993, 1994 Henry Spencer.
   3  * Copyright (c) 1992, 1993, 1994
   4  *      The Regents of the University of California.  All rights reserved.
   5  *
   6  * This code is derived from software contributed to Berkeley by
   7  * Henry Spencer.
   8  *
   9  * Redistribution and use in source and binary forms, with or without
  10  * modification, are permitted provided that the following conditions
  11  * are met:
  12  * 1. Redistributions of source code must retain the above copyright
  13  *    notice, this list of conditions and the following disclaimer.
  14  * 2. Redistributions in binary form must reproduce the above copyright
  15  *    notice, this list of conditions and the following disclaimer in the
  16  *    documentation and/or other materials provided with the distribution.
  17  * 3. Neither the name of the University nor the names of its contributors
  18  *    may be used to endorse or promote products derived from this software
  19  *    without specific prior written permission.
  20  *
  21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31  * SUCH DAMAGE.
  32  */
  33 
  34 /*
  35  * Copyright 2018 Nexenta Systems, Inc.
  36  */
  37 
  38 #include "lint.h"
  39 
  40 #include <sys/types.h>
  41 
  42 #include <limits.h>
  43 #include <regex.h>
  44 #include <stdlib.h>
  45 #include <string.h>
  46 
  47 #include "../gen/_libc_gettext.h"
  48 
  49 #define RERR(x, msg)    { x, #x, msg }
  50 
  51 static struct rerr {
  52         int code;
  53         const char *name;
  54         const char *explain;
  55 } rerrs[] = {
  56         RERR(REG_NOMATCH,       "regexec() failed to match"),
  57         RERR(REG_BADPAT,        "invalid regular expression"),
  58         RERR(REG_ECOLLATE,      "invalid collating element"),
  59         RERR(REG_ECTYPE,        "invalid character class"),
  60         RERR(REG_EESCAPE,       "trailing backslash (\\)"),
  61         RERR(REG_ESUBREG,       "invalid backreference number"),
  62         RERR(REG_EBRACK,        "brackets ([ ]) not balanced"),
  63         RERR(REG_EPAREN,        "parentheses not balanced"),
  64         RERR(REG_EBRACE,        "braces not balanced"),
  65         RERR(REG_BADBR,         "invalid repetition count(s)"),
  66         RERR(REG_ERANGE,        "invalid character range"),
  67         RERR(REG_ESPACE,        "out of memory"),
  68         RERR(REG_BADRPT,        "repetition-operator operand invalid"),
  69         RERR(REG_EMPTY,         "empty (sub)expression"),
  70         RERR(REG_INVARG,        "invalid argument to regex routine"),
  71         RERR(REG_ILLSEQ,        "illegal byte sequence"),
  72         {0,     "",             "*** unknown regexp error code ***"}
  73 };
  74 
  75 
  76 /*
  77  * The interface to error numbers
  78  */
  79 /* ARGSUSED */
  80 size_t
  81 regerror(int errcode, const regex_t *_RESTRICT_KYWD preg,
  82     char *_RESTRICT_KYWD errbuf, size_t errbuf_size)
  83 {
  84         struct rerr *r;
  85         size_t len;
  86         const char *s;
  87 
  88         for (r = rerrs; r->code != 0; r++) {
  89                 if (r->code == errcode)
  90                         break;
  91         }
  92 
  93         s = _libc_gettext(r->explain);
  94 
  95         len = strlen(s) + 1;
  96         if (errbuf != NULL && errbuf_size > 0) {
  97                 if (errbuf_size > len) {
  98                         (void) strcpy(errbuf, s);
  99                 } else {
 100                         (void) strncpy(errbuf, s, errbuf_size - 1);
 101                         errbuf[errbuf_size - 1] = '\0';
 102                 }
 103         }
 104 
 105         return (len);
 106 }