]> git.saurik.com Git - wxWidgets.git/blobdiff - src/regex/regerror.c
Fixed refresh bug on early versions of MacOS X by
[wxWidgets.git] / src / regex / regerror.c
index aca13aade03913e5c2d2b25dc761cf36d91b7389..1bb1ec1ce842d5cb19e2657ad737359956586589 100644 (file)
-/*
- * 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"
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "regex.h"
 
-/* unknown-error explanation */
-static char unk[] = "*** unknown regex error code 0x%x ***";
+#include "utils.h"
+#include "regerror.ih"
 
-/* struct to map among codes, code names, and explanations */
+/*
+ = #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 (!)
+ */
 static struct rerr {
        int code;
        char *name;
        char *explain;
 } rerrs[] = {
-       /* the actual table is built from regex.h */
-#      include "regerrs.h"
-       { -1,   "",     "oops" },       /* explanation special-cased in code */
+       { 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 ***" },
 };
 
 /*
  - regerror - the interface to error numbers
+ = extern size_t regerror(int, const regex_t *, char *, size_t);
  */
 /* ARGSUSED */
-size_t                         /* actual space needed (including NUL) */
+size_t
 regerror(errcode, preg, errbuf, errbuf_size)
-int errcode;                   /* 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 */
+int errcode;
+const regex_t *preg;
+char *errbuf;
+size_t errbuf_size;
 {
-       struct rerr *r;
-       char *msg;
-       char convbuf[sizeof(unk)+50];   /* 50 = plenty for int */
-       size_t len;
-       int icode;
+       register struct rerr *r;
+       register size_t len;
+       register int target = errcode &~ REG_ITOA;
+       register char *s;
+       char convbuf[50];
 
-       switch (errcode) {
-       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 */
+       if (errcode == REG_ATOI)
+               s = regatoi(preg, convbuf);
+       else {
                for (r = rerrs; r->code >= 0; r++)
-                       if (r->code == errcode)
+                       if (r->code == target)
                                break;
-               if (r->code >= 0)
-                       msg = r->explain;
-               else {                  /* unknown; say so */
-                       sprintf(convbuf, unk, errcode);
-                       msg = convbuf;
-               }
-               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;
        }
 
-       len = strlen(msg) + 1;          /* space needed, including NUL */
+       len = strlen(s) + 1;
        if (errbuf_size > 0) {
                if (errbuf_size > len)
-                       strcpy(errbuf, msg);
-               else {                  /* truncate to fit */
-                       strncpy(errbuf, msg, errbuf_size-1);
+                       (void) strcpy(errbuf, s);
+               else {
+                       (void) strncpy(errbuf, s, errbuf_size-1);
                        errbuf[errbuf_size-1] = '\0';
                }
        }
 
-       return len;
+       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);
 }