diff options
author | robot-piglet <[email protected]> | 2025-08-28 14:27:58 +0300 |
---|---|---|
committer | robot-piglet <[email protected]> | 2025-08-28 14:57:06 +0300 |
commit | 81d828c32c8d5477cb2f0ce5da06a1a8d9392ca3 (patch) | |
tree | 3081d566f0d5158d76e9093261344f6406fd09f7 /contrib/tools/swig/Source/Swig/error.c | |
parent | 77ea11423f959e51795cc3ef36a48d808b4ffb98 (diff) |
Intermediate changes
commit_hash:d5b1af16dbe9030537a04c27eb410c88c2f496cd
Diffstat (limited to 'contrib/tools/swig/Source/Swig/error.c')
-rw-r--r-- | contrib/tools/swig/Source/Swig/error.c | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/contrib/tools/swig/Source/Swig/error.c b/contrib/tools/swig/Source/Swig/error.c new file mode 100644 index 00000000000..c85f16df29d --- /dev/null +++ b/contrib/tools/swig/Source/Swig/error.c @@ -0,0 +1,350 @@ +/* ----------------------------------------------------------------------------- + * This file is part of SWIG, which is licensed as a whole under version 3 + * (or any later version) of the GNU General Public License. Some additional + * terms also apply to certain portions of SWIG. The full details of the SWIG + * license and copyrights can be found in the LICENSE and COPYRIGHT files + * included with the SWIG source code as distributed by the SWIG developers + * and at https://www.swig.org/legal.html. + * + * error.c + * + * Error handling functions. These are used to issue warnings and + * error messages. + * ----------------------------------------------------------------------------- */ + +#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 char diag_line_fmt[64]; +static char diag_eof_fmt[64]; + +static String *format_filename(const_String_or_char_ptr filename); + +/* ----------------------------------------------------------------------------- + * Swig_warning() + * + * Issue a warning message on stderr. + * ----------------------------------------------------------------------------- */ + +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); + String *full_message = NewString(""); + if (wnum) { + Printf(full_message, wrn_wnum_fmt, formatted_filename, line, wnum); + } else { + Printf(full_message, wrn_nnum_fmt, formatted_filename, line); + } + Printf(full_message, "%s", msg); + Printv(stderr, full_message, NIL); + nwarning++; + Delete(full_message); + Delete(formatted_filename); + } + Delete(out); + va_end(ap); +} + +/* ----------------------------------------------------------------------------- + * Swig_error() + * + * Issue an error message on stderr. + * ----------------------------------------------------------------------------- */ + +void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...) { + va_list ap; + String *formatted_filename = NULL; + String *full_message = NULL; + + if (silence) + return; + if (!init_fmt) + Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); + + va_start(ap, fmt); + formatted_filename = format_filename(filename); + full_message = NewString(""); + if (line > 0) { + Printf(full_message, err_line_fmt, formatted_filename, line); + } else { + Printf(full_message, err_eof_fmt, formatted_filename); + } + vPrintf(full_message, fmt, ap); + Printv(stderr, full_message, NIL); + va_end(ap); + nerrors++; + Delete(full_message); + 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(""); + 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); + sprintf(diag_line_fmt, "%s: ", fmt_line); + sprintf(diag_eof_fmt, "%s: ", fmt_eof); + + 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; +} + +/* ----------------------------------------------------------------------------- + * Swig_stringify_with_location() + * + * Return a string representation of any DOH object with line and file location + * information in the appropriate error message format. The string representation + * is enclosed within [] brackets after the line and file information. + * ----------------------------------------------------------------------------- */ + +String *Swig_stringify_with_location(DOH *object) { + String *str = NewStringEmpty(); + + if (!init_fmt) + Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); + + if (object) { + int line = Getline(object); + String *formatted_filename = format_filename(Getfile(object)); + if (line > 0) { + Printf(str, diag_line_fmt, formatted_filename, line); + } else { + Printf(str, diag_eof_fmt, formatted_filename); + } + if (Len(object) == 0) { + Printf(str, "[EMPTY]"); + } else { + Printf(str, "[%s]", object); + } + Delete(formatted_filename); + } else { + Printf(str, "[NULL]"); + } + + return str; +} + +/* ----------------------------------------------------------------------------- + * Swig_diagnostic() + * + * Issue a diagnostic message on stdout. + * ----------------------------------------------------------------------------- */ + +void Swig_diagnostic(const_String_or_char_ptr filename, int line, const char *fmt, ...) { + va_list ap; + String *formatted_filename = NULL; + + if (!init_fmt) + Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); + + va_start(ap, fmt); + formatted_filename = format_filename(filename); + if (line > 0) { + Printf(stdout, diag_line_fmt, formatted_filename, line); + } else { + Printf(stdout, diag_eof_fmt, formatted_filename); + } + vPrintf(stdout, fmt, ap); + va_end(ap); + Delete(formatted_filename); +} + |