Header And Logo

PostgreSQL
| The world's most advanced open source database.

regerror.c

Go to the documentation of this file.
00001 /*
00002  * regerror - error-code expansion
00003  *
00004  * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
00005  *
00006  * Development of this software was funded, in part, by Cray Research Inc.,
00007  * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
00008  * Corporation, none of whom are responsible for the results.  The author
00009  * thanks all of them.
00010  *
00011  * Redistribution and use in source and binary forms -- with or without
00012  * modification -- are permitted for any purpose, provided that
00013  * redistributions in source form retain this entire copyright notice and
00014  * indicate the origin and nature of any modifications.
00015  *
00016  * I'd appreciate being given credit for this package in the documentation
00017  * of software which uses it, but that is not a requirement.
00018  *
00019  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
00020  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00021  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
00022  * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00023  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00024  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00025  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00027  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00028  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  * src/backend/regex/regerror.c
00031  *
00032  */
00033 
00034 #include "regex/regguts.h"
00035 
00036 /* unknown-error explanation */
00037 static char unk[] = "*** unknown regex error code 0x%x ***";
00038 
00039 /* struct to map among codes, code names, and explanations */
00040 static struct rerr
00041 {
00042     int         code;
00043     const char *name;
00044     const char *explain;
00045 }   rerrs[] =
00046 
00047 {
00048     /* the actual table is built from regex.h */
00049 #include "regex/regerrs.h"      /* pgrminclude ignore */
00050     {
00051         -1, "", "oops"
00052     },                          /* explanation special-cased in code */
00053 };
00054 
00055 /*
00056  * pg_regerror - the interface to error numbers
00057  */
00058 /* ARGSUSED */
00059 size_t                          /* actual space needed (including NUL) */
00060 pg_regerror(int errcode,        /* error code, or REG_ATOI or REG_ITOA */
00061             const regex_t *preg,    /* associated regex_t (unused at present) */
00062             char *errbuf,       /* result buffer (unless errbuf_size==0) */
00063             size_t errbuf_size) /* available space in errbuf, can be 0 */
00064 {
00065     struct rerr *r;
00066     const char *msg;
00067     char        convbuf[sizeof(unk) + 50];      /* 50 = plenty for int */
00068     size_t      len;
00069     int         icode;
00070 
00071     switch (errcode)
00072     {
00073         case REG_ATOI:          /* convert name to number */
00074             for (r = rerrs; r->code >= 0; r++)
00075                 if (strcmp(r->name, errbuf) == 0)
00076                     break;
00077             sprintf(convbuf, "%d", r->code);    /* -1 for unknown */
00078             msg = convbuf;
00079             break;
00080         case REG_ITOA:          /* convert number to name */
00081             icode = atoi(errbuf);       /* not our problem if this fails */
00082             for (r = rerrs; r->code >= 0; r++)
00083                 if (r->code == icode)
00084                     break;
00085             if (r->code >= 0)
00086                 msg = r->name;
00087             else
00088             {                   /* unknown; tell him the number */
00089                 sprintf(convbuf, "REG_%u", (unsigned) icode);
00090                 msg = convbuf;
00091             }
00092             break;
00093         default:                /* a real, normal error code */
00094             for (r = rerrs; r->code >= 0; r++)
00095                 if (r->code == errcode)
00096                     break;
00097             if (r->code >= 0)
00098                 msg = r->explain;
00099             else
00100             {                   /* unknown; say so */
00101                 sprintf(convbuf, unk, errcode);
00102                 msg = convbuf;
00103             }
00104             break;
00105     }
00106 
00107     len = strlen(msg) + 1;      /* space needed, including NUL */
00108     if (errbuf_size > 0)
00109     {
00110         if (errbuf_size > len)
00111             strcpy(errbuf, msg);
00112         else
00113         {                       /* truncate to fit */
00114             strncpy(errbuf, msg, errbuf_size - 1);
00115             errbuf[errbuf_size - 1] = '\0';
00116         }
00117     }
00118 
00119     return len;
00120 }