diff options
Diffstat (limited to 'Source/Swig/error.c')
-rw-r--r-- | Source/Swig/error.c | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/Source/Swig/error.c b/Source/Swig/error.c new file mode 100644 index 0000000..84520d9 --- /dev/null +++ b/Source/Swig/error.c @@ -0,0 +1,277 @@ +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * error.c + * + * Error handling functions. These are used to issue warnings and + * error messages. + * ----------------------------------------------------------------------------- */ + +char cvsroot_error_c[] = "$Id: error.c 11080 2009-01-24 13:15:51Z bhy $"; + +#include "swig.h" +#include <stdarg.h> +#include <ctype.h> + +/* ----------------------------------------------------------------------------- + * Commentary on the warning filter. + * + * The warning filter is a string of numbers prefaced by (-) or (+) to + * indicate whether or not a warning message is displayed. For example: + * + * "-304-201-140+210+201" + * + * The filter string is scanned left to right and the first occurrence + * of a warning number is used to determine printing behavior. + * + * The same number may appear more than once in the string. For example, in the + * above string, "201" appears twice. This simply means that warning 201 + * was disabled after it was previously enabled. This may only be temporary + * setting--the first number may be removed later in which case the warning + * is reenabled. + * ----------------------------------------------------------------------------- */ + +#if defined(_WIN32) +# define DEFAULT_ERROR_MSG_FORMAT EMF_MICROSOFT +#else +# define DEFAULT_ERROR_MSG_FORMAT EMF_STANDARD +#endif +static ErrorMessageFormat msg_format = DEFAULT_ERROR_MSG_FORMAT; +static int silence = 0; /* Silent operation */ +static String *filter = 0; /* Warning filter */ +static int warnall = 0; +static int nwarning = 0; +static int nerrors = 0; + +static int init_fmt = 0; +static char wrn_wnum_fmt[64]; +static char wrn_nnum_fmt[64]; +static char err_line_fmt[64]; +static char err_eof_fmt[64]; + +static String *format_filename(const_String_or_char_ptr filename); + +/* ----------------------------------------------------------------------------- + * Swig_warning() + * + * Issue a warning message + * ----------------------------------------------------------------------------- */ + +void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const char *fmt, ...) { + String *out; + char *msg; + int wrn = 1; + va_list ap; + if (silence) + return; + if (!init_fmt) + Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); + + va_start(ap, fmt); + + out = NewStringEmpty(); + vPrintf(out, fmt, ap); + + msg = Char(out); + if (isdigit((unsigned char) *msg)) { + unsigned long result = strtoul(msg, &msg, 10); + if (msg != Char(out)) { + msg++; + wnum = result; + } + } + + /* Check in the warning filter */ + if (filter) { + char temp[32]; + char *c; + char *f = Char(filter); + sprintf(temp, "%d", wnum); + while (*f != '\0' && (c = strstr(f, temp))) { + if (*(c - 1) == '-') { + wrn = 0; /* Warning disabled */ + break; + } + if (*(c - 1) == '+') { + wrn = 1; /* Warning enabled */ + break; + } + f += strlen(temp); + } + } + if (warnall || wrn) { + String *formatted_filename = format_filename(filename); + if (wnum) { + Printf(stderr, wrn_wnum_fmt, formatted_filename, line, wnum); + } else { + Printf(stderr, wrn_nnum_fmt, formatted_filename, line); + } + Printf(stderr, "%s", msg); + nwarning++; + Delete(formatted_filename); + } + Delete(out); + va_end(ap); +} + +/* ----------------------------------------------------------------------------- + * Swig_error() + * + * Issue an error message + * ----------------------------------------------------------------------------- */ + +void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...) { + va_list ap; + String *formatted_filename = NULL; + + if (silence) + return; + if (!init_fmt) + Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); + + va_start(ap, fmt); + formatted_filename = format_filename(filename); + if (line > 0) { + Printf(stderr, err_line_fmt, formatted_filename, line); + } else { + Printf(stderr, err_eof_fmt, formatted_filename); + } + vPrintf(stderr, fmt, ap); + va_end(ap); + nerrors++; + Delete(formatted_filename); +} + +/* ----------------------------------------------------------------------------- + * Swig_error_count() + * + * Returns number of errors received. + * ----------------------------------------------------------------------------- */ + +int Swig_error_count(void) { + return nerrors; +} + +/* ----------------------------------------------------------------------------- + * Swig_error_silent() + * + * Set silent flag + * ----------------------------------------------------------------------------- */ + +void Swig_error_silent(int s) { + silence = s; +} + + +/* ----------------------------------------------------------------------------- + * Swig_warnfilter() + * + * Takes a comma separate list of warning numbers and puts in the filter. + * ----------------------------------------------------------------------------- */ + +void Swig_warnfilter(const_String_or_char_ptr wlist, int add) { + char *c; + char *cw; + String *s; + if (!filter) + filter = NewStringEmpty(); + + s = NewString(""); + Clear(s); + cw = Char(wlist); + while (*cw != '\0') { + if (*cw != ' ') { + Putc(*cw, s); + } + ++cw; + } + c = Char(s); + c = strtok(c, ", "); + while (c) { + if (isdigit((int) *c) || (*c == '+') || (*c == '-')) { + /* Even if c is a digit, the rest of the string might not be, eg in the case of typemap + * warnings (a bit odd really), eg: %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG) */ + if (add) { + Insert(filter, 0, c); + if (isdigit((int) *c)) { + Insert(filter, 0, "-"); + } + } else { + char *temp = (char *)malloc(sizeof(char)*strlen(c) + 2); + if (isdigit((int) *c)) { + sprintf(temp, "-%s", c); + } else { + strcpy(temp, c); + } + Replace(filter, temp, "", DOH_REPLACE_FIRST); + free(temp); + } + } + c = strtok(NULL, ", "); + } + Delete(s); +} + +void Swig_warnall(void) { + warnall = 1; +} + + +/* ----------------------------------------------------------------------------- + * Swig_warn_count() + * + * Return the number of warnings + * ----------------------------------------------------------------------------- */ + +int Swig_warn_count(void) { + return nwarning; +} + +/* ----------------------------------------------------------------------------- + * Swig_error_msg_format() + * + * Set the type of error/warning message display + * ----------------------------------------------------------------------------- */ + +void Swig_error_msg_format(ErrorMessageFormat format) { + const char *error = "Error"; + const char *warning = "Warning"; + + const char *fmt_eof = 0; + const char *fmt_line = 0; + + /* here 'format' could be directly a string instead of an enum, but + by now a switch is used to translated into one. */ + switch (format) { + case EMF_MICROSOFT: + fmt_line = "%s(%d)"; + fmt_eof = "%s(999999)"; /* Is there a special character for EOF? Just use a large number. */ + break; + case EMF_STANDARD: + default: + fmt_line = "%s:%d"; + fmt_eof = "%s:EOF"; + } + + sprintf(wrn_wnum_fmt, "%s: %s(%%d): ", fmt_line, warning); + sprintf(wrn_nnum_fmt, "%s: %s: ", fmt_line, warning); + sprintf(err_line_fmt, "%s: %s: ", fmt_line, error); + sprintf(err_eof_fmt, "%s: %s: ", fmt_eof, error); + + msg_format = format; + init_fmt = 1; +} + +/* ----------------------------------------------------------------------------- + * format_filename() + * + * Remove double backslashes in Windows filename paths for display + * ----------------------------------------------------------------------------- */ +static String *format_filename(const_String_or_char_ptr filename) { + String *formatted_filename = NewString(filename); +#if defined(_WIN32) + Replaceall(formatted_filename, "\\\\", "\\"); +#endif + return formatted_filename; +} |