Back to index

php5  5.3.10
regerror.c
Go to the documentation of this file.
00001 #include <sys/types.h>
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include <ctype.h>
00005 #include <limits.h>
00006 #include <stdlib.h>
00007 
00008 #include "regex.h"
00009 #include "utils.h"
00010 #include "regerror.ih"
00011 #include "php.h"
00012 
00013 /*
00014  = #define    REG_OKAY       0
00015  = #define    REG_NOMATCH    1
00016  = #define    REG_BADPAT     2
00017  = #define    REG_ECOLLATE   3
00018  = #define    REG_ECTYPE     4
00019  = #define    REG_EESCAPE    5
00020  = #define    REG_ESUBREG    6
00021  = #define    REG_EBRACK     7
00022  = #define    REG_EPAREN     8
00023  = #define    REG_EBRACE     9
00024  = #define    REG_BADBR     10
00025  = #define    REG_ERANGE    11
00026  = #define    REG_ESPACE    12
00027  = #define    REG_BADRPT    13
00028  = #define    REG_EMPTY     14
00029  = #define    REG_ASSERT    15
00030  = #define    REG_INVARG    16
00031  = #define    REG_ATOI      255    // convert name to number (!)
00032  = #define    REG_ITOA      0400   // convert number to name (!)
00033  */
00034 static const struct rerr {
00035        int code;
00036        const char *name;
00037        const char *explain;
00038 } rerrs[] = {
00039        {REG_OKAY,    "REG_OKAY",   "no errors detected"},
00040        {REG_NOMATCH, "REG_NOMATCH",       "regexec() failed to match"},
00041        {REG_BADPAT,  "REG_BADPAT", "invalid regular expression"},
00042        {REG_ECOLLATE,       "REG_ECOLLATE",      "invalid collating element"},
00043        {REG_ECTYPE,  "REG_ECTYPE", "invalid character class"},
00044        {REG_EESCAPE, "REG_EESCAPE",       "trailing backslash (\\)"},
00045        {REG_ESUBREG, "REG_ESUBREG",       "invalid backreference number"},
00046        {REG_EBRACK,  "REG_EBRACK", "brackets ([ ]) not balanced"},
00047        {REG_EPAREN,  "REG_EPAREN", "parentheses not balanced"},
00048        {REG_EBRACE,  "REG_EBRACE", "braces not balanced"},
00049        {REG_BADBR,   "REG_BADBR",  "invalid repetition count(s)"},
00050        {REG_ERANGE,  "REG_ERANGE", "invalid character range"},
00051        {REG_ESPACE,  "REG_ESPACE", "out of memory"},
00052        {REG_BADRPT,  "REG_BADRPT", "repetition-operator operand invalid"},
00053        {REG_EMPTY,   "REG_EMPTY",  "empty (sub)expression"},
00054        {REG_ASSERT,  "REG_ASSERT", "\"can't happen\" -- you found a bug"},
00055        {REG_INVARG,  "REG_INVARG", "invalid argument to regex routine"},
00056        {-1,          "",           "*** unknown regexp error code ***"},
00057 };
00058 
00059 /*
00060  - regerror - the interface to error numbers
00061  = API_EXPORT(size_t) regerror(int, const regex_t *, char *, size_t);
00062  */
00063 /* ARGSUSED */
00064 API_EXPORT(size_t)
00065 regerror(
00066 int errcode,
00067 const regex_t *preg,
00068 char *errbuf,
00069 size_t errbuf_size)
00070 {
00071        register const struct rerr *r;
00072        register size_t len;
00073        register int target = errcode &~ REG_ITOA;
00074        register const char *s;
00075        char convbuf[50];
00076 
00077        if (errcode == REG_ATOI)
00078               s = regatoi(preg, convbuf, sizeof(convbuf));
00079        else {
00080               for (r = rerrs; r->code >= 0; r++)
00081                      if (r->code == target)
00082                             break;
00083        
00084               if (errcode&REG_ITOA) {
00085                      if (r->code >= 0) {
00086                             (void) strncpy(convbuf, r->name, sizeof(convbuf) - 1);
00087                             convbuf[sizeof(convbuf) - 1] = '\0';
00088                      } else {
00089                             snprintf(convbuf, sizeof(convbuf), "REG_0x%x", target);
00090                      }
00091                      assert(strlen(convbuf) < sizeof(convbuf));
00092                      s = convbuf;
00093               } else
00094                      s = r->explain;
00095        }
00096 
00097        len = strlen(s) + 1;
00098        if (errbuf_size > 0) {
00099               if (errbuf_size > len)
00100                      (void) strcpy(errbuf, s);
00101               else {
00102                      (void) strncpy(errbuf, s, errbuf_size-1);
00103                      errbuf[errbuf_size-1] = '\0';
00104               }
00105        }
00106 
00107        return(len);
00108 }
00109 
00110 /*
00111  - regatoi - internal routine to implement REG_ATOI
00112  == static char *regatoi(const regex_t *preg, char *localbuf, int bufsize);
00113  */
00114 static char *
00115 regatoi(preg, localbuf, bufsize)
00116 const regex_t *preg;
00117 char *localbuf;
00118 int bufsize;
00119 {
00120        register const struct rerr *r;
00121 
00122        for (r = rerrs; r->code >= 0; r++)
00123               if (strcmp(r->name, preg->re_endp) == 0)
00124                      break;
00125        if (r->code < 0)
00126               return("0");
00127 
00128        snprintf(localbuf, bufsize, "%d", r->code);
00129        return(localbuf);
00130 }