1/* ----------------------------------------------------------------------------- 2 * See the LICENSE file for information on copyright, usage and redistribution 3 * of SWIG, and the README file for authors - http://www.swig.org/release.html. 4 * 5 * error.c 6 * 7 * Error handling functions. These are used to issue warnings and 8 * error messages. 9 * ----------------------------------------------------------------------------- */ 10 11char cvsroot_error_c[] = "$Id: error.c 11080 2009-01-24 13:15:51Z bhy $"; 12 13#include "swig.h" 14#include <stdarg.h> 15#include <ctype.h> 16 17/* ----------------------------------------------------------------------------- 18 * Commentary on the warning filter. 19 * 20 * The warning filter is a string of numbers prefaced by (-) or (+) to 21 * indicate whether or not a warning message is displayed. For example: 22 * 23 * "-304-201-140+210+201" 24 * 25 * The filter string is scanned left to right and the first occurrence 26 * of a warning number is used to determine printing behavior. 27 * 28 * The same number may appear more than once in the string. For example, in the 29 * above string, "201" appears twice. This simply means that warning 201 30 * was disabled after it was previously enabled. This may only be temporary 31 * setting--the first number may be removed later in which case the warning 32 * is reenabled. 33 * ----------------------------------------------------------------------------- */ 34 35#if defined(_WIN32) 36# define DEFAULT_ERROR_MSG_FORMAT EMF_MICROSOFT 37#else 38# define DEFAULT_ERROR_MSG_FORMAT EMF_STANDARD 39#endif 40static ErrorMessageFormat msg_format = DEFAULT_ERROR_MSG_FORMAT; 41static int silence = 0; /* Silent operation */ 42static String *filter = 0; /* Warning filter */ 43static int warnall = 0; 44static int nwarning = 0; 45static int nerrors = 0; 46 47static int init_fmt = 0; 48static char wrn_wnum_fmt[64]; 49static char wrn_nnum_fmt[64]; 50static char err_line_fmt[64]; 51static char err_eof_fmt[64]; 52 53static String *format_filename(const_String_or_char_ptr filename); 54 55/* ----------------------------------------------------------------------------- 56 * Swig_warning() 57 * 58 * Issue a warning message 59 * ----------------------------------------------------------------------------- */ 60 61void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const char *fmt, ...) { 62 String *out; 63 char *msg; 64 int wrn = 1; 65 va_list ap; 66 if (silence) 67 return; 68 if (!init_fmt) 69 Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); 70 71 va_start(ap, fmt); 72 73 out = NewStringEmpty(); 74 vPrintf(out, fmt, ap); 75 76 msg = Char(out); 77 if (isdigit((unsigned char) *msg)) { 78 unsigned long result = strtoul(msg, &msg, 10); 79 if (msg != Char(out)) { 80 msg++; 81 wnum = result; 82 } 83 } 84 85 /* Check in the warning filter */ 86 if (filter) { 87 char temp[32]; 88 char *c; 89 char *f = Char(filter); 90 sprintf(temp, "%d", wnum); 91 while (*f != '\0' && (c = strstr(f, temp))) { 92 if (*(c - 1) == '-') { 93 wrn = 0; /* Warning disabled */ 94 break; 95 } 96 if (*(c - 1) == '+') { 97 wrn = 1; /* Warning enabled */ 98 break; 99 } 100 f += strlen(temp); 101 } 102 } 103 if (warnall || wrn) { 104 String *formatted_filename = format_filename(filename); 105 if (wnum) { 106 Printf(stderr, wrn_wnum_fmt, formatted_filename, line, wnum); 107 } else { 108 Printf(stderr, wrn_nnum_fmt, formatted_filename, line); 109 } 110 Printf(stderr, "%s", msg); 111 nwarning++; 112 Delete(formatted_filename); 113 } 114 Delete(out); 115 va_end(ap); 116} 117 118/* ----------------------------------------------------------------------------- 119 * Swig_error() 120 * 121 * Issue an error message 122 * ----------------------------------------------------------------------------- */ 123 124void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...) { 125 va_list ap; 126 String *formatted_filename = NULL; 127 128 if (silence) 129 return; 130 if (!init_fmt) 131 Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); 132 133 va_start(ap, fmt); 134 formatted_filename = format_filename(filename); 135 if (line > 0) { 136 Printf(stderr, err_line_fmt, formatted_filename, line); 137 } else { 138 Printf(stderr, err_eof_fmt, formatted_filename); 139 } 140 vPrintf(stderr, fmt, ap); 141 va_end(ap); 142 nerrors++; 143 Delete(formatted_filename); 144} 145 146/* ----------------------------------------------------------------------------- 147 * Swig_error_count() 148 * 149 * Returns number of errors received. 150 * ----------------------------------------------------------------------------- */ 151 152int Swig_error_count(void) { 153 return nerrors; 154} 155 156/* ----------------------------------------------------------------------------- 157 * Swig_error_silent() 158 * 159 * Set silent flag 160 * ----------------------------------------------------------------------------- */ 161 162void Swig_error_silent(int s) { 163 silence = s; 164} 165 166 167/* ----------------------------------------------------------------------------- 168 * Swig_warnfilter() 169 * 170 * Takes a comma separate list of warning numbers and puts in the filter. 171 * ----------------------------------------------------------------------------- */ 172 173void Swig_warnfilter(const_String_or_char_ptr wlist, int add) { 174 char *c; 175 char *cw; 176 String *s; 177 if (!filter) 178 filter = NewStringEmpty(); 179 180 s = NewString(""); 181 Clear(s); 182 cw = Char(wlist); 183 while (*cw != '\0') { 184 if (*cw != ' ') { 185 Putc(*cw, s); 186 } 187 ++cw; 188 } 189 c = Char(s); 190 c = strtok(c, ", "); 191 while (c) { 192 if (isdigit((int) *c) || (*c == '+') || (*c == '-')) { 193 /* Even if c is a digit, the rest of the string might not be, eg in the case of typemap 194 * warnings (a bit odd really), eg: %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG) */ 195 if (add) { 196 Insert(filter, 0, c); 197 if (isdigit((int) *c)) { 198 Insert(filter, 0, "-"); 199 } 200 } else { 201 char *temp = (char *)malloc(sizeof(char)*strlen(c) + 2); 202 if (isdigit((int) *c)) { 203 sprintf(temp, "-%s", c); 204 } else { 205 strcpy(temp, c); 206 } 207 Replace(filter, temp, "", DOH_REPLACE_FIRST); 208 free(temp); 209 } 210 } 211 c = strtok(NULL, ", "); 212 } 213 Delete(s); 214} 215 216void Swig_warnall(void) { 217 warnall = 1; 218} 219 220 221/* ----------------------------------------------------------------------------- 222 * Swig_warn_count() 223 * 224 * Return the number of warnings 225 * ----------------------------------------------------------------------------- */ 226 227int Swig_warn_count(void) { 228 return nwarning; 229} 230 231/* ----------------------------------------------------------------------------- 232 * Swig_error_msg_format() 233 * 234 * Set the type of error/warning message display 235 * ----------------------------------------------------------------------------- */ 236 237void Swig_error_msg_format(ErrorMessageFormat format) { 238 const char *error = "Error"; 239 const char *warning = "Warning"; 240 241 const char *fmt_eof = 0; 242 const char *fmt_line = 0; 243 244 /* here 'format' could be directly a string instead of an enum, but 245 by now a switch is used to translated into one. */ 246 switch (format) { 247 case EMF_MICROSOFT: 248 fmt_line = "%s(%d)"; 249 fmt_eof = "%s(999999)"; /* Is there a special character for EOF? Just use a large number. */ 250 break; 251 case EMF_STANDARD: 252 default: 253 fmt_line = "%s:%d"; 254 fmt_eof = "%s:EOF"; 255 } 256 257 sprintf(wrn_wnum_fmt, "%s: %s(%%d): ", fmt_line, warning); 258 sprintf(wrn_nnum_fmt, "%s: %s: ", fmt_line, warning); 259 sprintf(err_line_fmt, "%s: %s: ", fmt_line, error); 260 sprintf(err_eof_fmt, "%s: %s: ", fmt_eof, error); 261 262 msg_format = format; 263 init_fmt = 1; 264} 265 266/* ----------------------------------------------------------------------------- 267 * format_filename() 268 * 269 * Remove double backslashes in Windows filename paths for display 270 * ----------------------------------------------------------------------------- */ 271static String *format_filename(const_String_or_char_ptr filename) { 272 String *formatted_filename = NewString(filename); 273#if defined(_WIN32) 274 Replaceall(formatted_filename, "\\\\", "\\"); 275#endif 276 return formatted_filename; 277} 278