]> git.saurik.com Git - wxWidgets.git/blobdiff - src/regex/regerror.c
reduce black background flicker a bit - there is still some left sometimes initially...
[wxWidgets.git] / src / regex / regerror.c
index e53dafcfbf4b5ae026e2323a907f3dcbe16c6330..9b2a31b27441733005d8ed0873c7fd42df6d93c1 100644 (file)
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <regex.h>
-
-#include "utils.h"
-#include "regerror.ih"
-
 /*
- = #define     REG_OKAY         0
- = #define     REG_NOMATCH      1
- = #define     REG_BADPAT       2
- = #define     REG_ECOLLATE     3
- = #define     REG_ECTYPE       4
- = #define     REG_EESCAPE      5
- = #define     REG_ESUBREG      6
- = #define     REG_EBRACK       7
- = #define     REG_EPAREN       8
- = #define     REG_EBRACE       9
- = #define     REG_BADBR       10
- = #define     REG_ERANGE      11
- = #define     REG_ESPACE      12
- = #define     REG_BADRPT      13
- = #define     REG_EMPTY       14
- = #define     REG_ASSERT      15
- = #define     REG_INVARG      16
- = #define     REG_ATOI        255     // convert name to number (!)
- = #define     REG_ITOA        0400    // convert number to name (!)
+ * regerror - error-code expansion
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+ * 
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results.  The author
+ * thanks all of them. 
+ * 
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ * 
+ * I'd appreciate being given credit for this package in the documentation
+ * of software which uses it, but that is not a requirement.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
  */
+
+#include "regguts.h"
+
+/* unknown-error explanation */
+static char unk[] = "*** unknown regex error code 0x%x ***";
+
+/* struct to map among codes, code names, and explanations */
 static struct rerr {
        int code;
        char *name;
        char *explain;
 } rerrs[] = {
-       REG_OKAY,       "REG_OKAY",     "no errors detected",
-       REG_NOMATCH,    "REG_NOMATCH",  "regexec() failed to match",
-       REG_BADPAT,     "REG_BADPAT",   "invalid regular expression",
-       REG_ECOLLATE,   "REG_ECOLLATE", "invalid collating element",
-       REG_ECTYPE,     "REG_ECTYPE",   "invalid character class",
-       REG_EESCAPE,    "REG_EESCAPE",  "trailing backslash (\\)",
-       REG_ESUBREG,    "REG_ESUBREG",  "invalid backreference number",
-       REG_EBRACK,     "REG_EBRACK",   "brackets ([ ]) not balanced",
-       REG_EPAREN,     "REG_EPAREN",   "parentheses not balanced",
-       REG_EBRACE,     "REG_EBRACE",   "braces not balanced",
-       REG_BADBR,      "REG_BADBR",    "invalid repetition count(s)",
-       REG_ERANGE,     "REG_ERANGE",   "invalid character range",
-       REG_ESPACE,     "REG_ESPACE",   "out of memory",
-       REG_BADRPT,     "REG_BADRPT",   "repetition-operator operand invalid",
-       REG_EMPTY,      "REG_EMPTY",    "empty (sub)expression",
-       REG_ASSERT,     "REG_ASSERT",   "\"can't happen\" -- you found a bug",
-       REG_INVARG,     "REG_INVARG",   "invalid argument to regex routine",
-       -1,             "",             "*** unknown regexp error code ***",
+       /* the actual table is built from regex.h */
+#      include "regerrs.h"
+       { -1,   "",     "oops" },       /* explanation special-cased in code */
 };
 
 /*
  - regerror - the interface to error numbers
- = extern size_t regerror(int, const regex_t *, char *, size_t);
  */
 /* ARGSUSED */
-size_t
-regerror(errcode, preg, errbuf, errbuf_size)
-int errcode;
-const regex_t *preg;
-char *errbuf;
-size_t errbuf_size;
+size_t                         /* actual space needed (including NUL) */
+regerror(rxerrcode, preg, errbuf, errbuf_size)
+int rxerrcode;                 /* error code, or REG_ATOI or REG_ITOA */
+CONST regex_t *preg;           /* associated regex_t (unused at present) */
+char *errbuf;                  /* result buffer (unless errbuf_size==0) */
+size_t errbuf_size;            /* available space in errbuf, can be 0 */
 {
-       register struct rerr *r;
-       register size_t len;
-       register int target = errcode &~ REG_ITOA;
-       register char *s;
-       char convbuf[50];
+       struct rerr *r;
+       char *msg;
+       char convbuf[sizeof(unk)+50];   /* 50 = plenty for int */
+       size_t len;
+       int icode;
 
-       if (errcode == REG_ATOI)
-               s = regatoi(preg, convbuf);
-       else {
+       switch (rxerrcode) {
+       case REG_ATOI:          /* convert name to number */
+               for (r = rerrs; r->code >= 0; r++)
+                       if (strcmp(r->name, errbuf) == 0)
+                               break;
+               sprintf(convbuf, "%d", r->code);        /* -1 for unknown */
+               msg = convbuf;
+               break;
+       case REG_ITOA:          /* convert number to name */
+               icode = atoi(errbuf);   /* not our problem if this fails */
+               for (r = rerrs; r->code >= 0; r++)
+                       if (r->code == icode)
+                               break;
+               if (r->code >= 0)
+                       msg = r->name;
+               else {                  /* unknown; tell him the number */
+                       sprintf(convbuf, "REG_%u", (unsigned)icode);
+                       msg = convbuf;
+               }
+               break;
+       default:                /* a real, normal error code */
                for (r = rerrs; r->code >= 0; r++)
-                       if (r->code == target)
+                       if (r->code == rxerrcode)
                                break;
-       
-               if (errcode&REG_ITOA) {
-                       if (r->code >= 0)
-                               (void) strcpy(convbuf, r->name);
-                       else
-                               sprintf(convbuf, "REG_0x%x", target);
-                       assert(strlen(convbuf) < sizeof(convbuf));
-                       s = convbuf;
-               } else
-                       s = r->explain;
+               if (r->code >= 0)
+                       msg = r->explain;
+               else {                  /* unknown; say so */
+                       sprintf(convbuf, unk, rxerrcode);
+                       msg = convbuf;
+               }
+               break;
        }
 
-       len = strlen(s) + 1;
+       len = strlen(msg) + 1;          /* space needed, including NUL */
        if (errbuf_size > 0) {
                if (errbuf_size > len)
-                       (void) strcpy(errbuf, s);
-               else {
-                       (void) strncpy(errbuf, s, errbuf_size-1);
+                       strcpy(errbuf, msg);
+               else {                  /* truncate to fit */
+                       strncpy(errbuf, msg, errbuf_size-1);
                        errbuf[errbuf_size-1] = '\0';
                }
        }
 
-       return(len);
-}
-
-/*
- - regatoi - internal routine to implement REG_ATOI
- == static char *regatoi(const regex_t *preg, char *localbuf);
- */
-static char *
-regatoi(preg, localbuf)
-const regex_t *preg;
-char *localbuf;
-{
-       register struct rerr *r;
-
-       for (r = rerrs; r->code >= 0; r++)
-               if (strcmp(r->name, preg->re_endp) == 0)
-                       break;
-       if (r->code < 0)
-               return("0");
-
-       sprintf(localbuf, "%d", r->code);
-       return(localbuf);
+       return len;
 }