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 }