PageRenderTime 26ms CodeModel.GetById 10ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Source/Swig/error.c

#
C | 346 lines | 214 code | 45 blank | 87 comment | 49 complexity | 5cdd9d9ac062389e878244c32356a5df MD5 | raw file
  1/* ----------------------------------------------------------------------------- 
  2 * This file is part of SWIG, which is licensed as a whole under version 3 
  3 * (or any later version) of the GNU General Public License. Some additional
  4 * terms also apply to certain portions of SWIG. The full details of the SWIG
  5 * license and copyrights can be found in the LICENSE and COPYRIGHT files
  6 * included with the SWIG source code as distributed by the SWIG developers
  7 * and at http://www.swig.org/legal.html.
  8 *
  9 * error.c
 10 *
 11 * Error handling functions.   These are used to issue warnings and
 12 * error messages.
 13 * ----------------------------------------------------------------------------- */
 14
 15char cvsroot_error_c[] = "$Id: error.c 12221 2010-09-15 20:17:11Z wsfulton $";
 16
 17#include "swig.h"
 18#include <stdarg.h>
 19#include <ctype.h>
 20
 21/* -----------------------------------------------------------------------------
 22 * Commentary on the warning filter.
 23 *
 24 * The warning filter is a string of numbers prefaced by (-) or (+) to
 25 * indicate whether or not a warning message is displayed.  For example:
 26 *
 27 *      "-304-201-140+210+201"
 28 *
 29 * The filter string is scanned left to right and the first occurrence
 30 * of a warning number is used to determine printing behavior.
 31 *
 32 * The same number may appear more than once in the string.  For example, in the 
 33 * above string, "201" appears twice.  This simply means that warning 201
 34 * was disabled after it was previously enabled.  This may only be temporary
 35 * setting--the first number may be removed later in which case the warning
 36 * is reenabled.
 37 * ----------------------------------------------------------------------------- */
 38
 39#if defined(_WIN32)
 40#  define  DEFAULT_ERROR_MSG_FORMAT EMF_MICROSOFT
 41#else
 42#  define  DEFAULT_ERROR_MSG_FORMAT EMF_STANDARD
 43#endif
 44static ErrorMessageFormat msg_format = DEFAULT_ERROR_MSG_FORMAT;
 45static int silence = 0;		/* Silent operation */
 46static String *filter = 0;	/* Warning filter */
 47static int warnall = 0;
 48static int nwarning = 0;
 49static int nerrors = 0;
 50
 51static int init_fmt = 0;
 52static char wrn_wnum_fmt[64];
 53static char wrn_nnum_fmt[64];
 54static char err_line_fmt[64];
 55static char err_eof_fmt[64];
 56static char diag_line_fmt[64];
 57static char diag_eof_fmt[64];
 58
 59static String *format_filename(const_String_or_char_ptr filename);
 60
 61/* -----------------------------------------------------------------------------
 62 * Swig_warning()
 63 *
 64 * Issue a warning message on stderr.
 65 * ----------------------------------------------------------------------------- */
 66
 67void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const char *fmt, ...) {
 68  String *out;
 69  char *msg;
 70  int wrn = 1;
 71  va_list ap;
 72  if (silence)
 73    return;
 74  if (!init_fmt)
 75    Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT);
 76
 77  va_start(ap, fmt);
 78
 79  out = NewStringEmpty();
 80  vPrintf(out, fmt, ap);
 81
 82  msg = Char(out);
 83  if (isdigit((unsigned char) *msg)) {
 84    unsigned long result = strtoul(msg, &msg, 10);
 85    if (msg != Char(out)) {
 86      msg++;
 87      wnum = result;
 88    }
 89  }
 90
 91  /* Check in the warning filter */
 92  if (filter) {
 93    char temp[32];
 94    char *c;
 95    char *f = Char(filter);
 96    sprintf(temp, "%d", wnum);
 97    while (*f != '\0' && (c = strstr(f, temp))) {
 98      if (*(c - 1) == '-') {
 99	wrn = 0;		/* Warning disabled */
100        break;
101      }
102      if (*(c - 1) == '+') {
103	wrn = 1;		/* Warning enabled */
104        break;
105      }
106      f += strlen(temp);
107    }
108  }
109  if (warnall || wrn) {
110    String *formatted_filename = format_filename(filename);
111    if (wnum) {
112      Printf(stderr, wrn_wnum_fmt, formatted_filename, line, wnum);
113    } else {
114      Printf(stderr, wrn_nnum_fmt, formatted_filename, line);
115    }
116    Printf(stderr, "%s", msg);
117    nwarning++;
118    Delete(formatted_filename);
119  }
120  Delete(out);
121  va_end(ap);
122}
123
124/* -----------------------------------------------------------------------------
125 * Swig_error()
126 *
127 * Issue an error message on stderr.
128 * ----------------------------------------------------------------------------- */
129
130void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...) {
131  va_list ap;
132  String *formatted_filename = NULL;
133
134  if (silence)
135    return;
136  if (!init_fmt)
137    Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT);
138
139  va_start(ap, fmt);
140  formatted_filename = format_filename(filename);
141  if (line > 0) {
142    Printf(stderr, err_line_fmt, formatted_filename, line);
143  } else {
144    Printf(stderr, err_eof_fmt, formatted_filename);
145  }
146  vPrintf(stderr, fmt, ap);
147  va_end(ap);
148  nerrors++;
149  Delete(formatted_filename);
150}
151
152/* -----------------------------------------------------------------------------
153 * Swig_error_count()
154 *
155 * Returns number of errors received.
156 * ----------------------------------------------------------------------------- */
157
158int Swig_error_count(void) {
159  return nerrors;
160}
161
162/* -----------------------------------------------------------------------------
163 * Swig_error_silent()
164 *
165 * Set silent flag
166 * ----------------------------------------------------------------------------- */
167
168void Swig_error_silent(int s) {
169  silence = s;
170}
171
172
173/* -----------------------------------------------------------------------------
174 * Swig_warnfilter()
175 *
176 * Takes a comma separate list of warning numbers and puts in the filter.
177 * ----------------------------------------------------------------------------- */
178
179void Swig_warnfilter(const_String_or_char_ptr wlist, int add) {
180  char *c;
181  char *cw;
182  String *s;
183  if (!filter)
184    filter = NewStringEmpty();
185
186  s = NewString("");
187  Clear(s);
188  cw = Char(wlist);
189  while (*cw != '\0') {
190    if (*cw != ' ') {
191      Putc(*cw, s);
192    }
193    ++cw;
194  }
195  c = Char(s);
196  c = strtok(c, ", ");
197  while (c) {
198    if (isdigit((int) *c) || (*c == '+') || (*c == '-')) {
199      /* Even if c is a digit, the rest of the string might not be, eg in the case of typemap 
200       * warnings (a bit odd really), eg: %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG) */
201      if (add) {
202	Insert(filter, 0, c);
203	if (isdigit((int) *c)) {
204	  Insert(filter, 0, "-");
205	}
206      } else {
207	char *temp = (char *)malloc(sizeof(char)*strlen(c) + 2);
208	if (isdigit((int) *c)) {
209	  sprintf(temp, "-%s", c);
210	} else {
211	  strcpy(temp, c);
212	}
213	Replace(filter, temp, "", DOH_REPLACE_FIRST);
214        free(temp);
215      }
216    }
217    c = strtok(NULL, ", ");
218  }
219  Delete(s);
220}
221
222void Swig_warnall(void) {
223  warnall = 1;
224}
225
226
227/* ----------------------------------------------------------------------------- 
228 * Swig_warn_count()
229 *
230 * Return the number of warnings
231 * ----------------------------------------------------------------------------- */
232
233int Swig_warn_count(void) {
234  return nwarning;
235}
236
237/* -----------------------------------------------------------------------------
238 * Swig_error_msg_format()
239 *
240 * Set the type of error/warning message display
241 * ----------------------------------------------------------------------------- */
242
243void Swig_error_msg_format(ErrorMessageFormat format) {
244  const char *error = "Error";
245  const char *warning = "Warning";
246
247  const char *fmt_eof = 0;
248  const char *fmt_line = 0;
249
250  /* here 'format' could be directly a string instead of an enum, but
251     by now a switch is used to translated into one. */
252  switch (format) {
253  case EMF_MICROSOFT:
254    fmt_line = "%s(%d) ";
255    fmt_eof = "%s(999999) ";	/* Is there a special character for EOF? Just use a large number. */
256    break;
257  case EMF_STANDARD:
258  default:
259    fmt_line = "%s:%d";
260    fmt_eof = "%s:EOF";
261  }
262
263  sprintf(wrn_wnum_fmt, "%s: %s %%d: ", fmt_line, warning);
264  sprintf(wrn_nnum_fmt, "%s: %s: ", fmt_line, warning);
265  sprintf(err_line_fmt, "%s: %s: ", fmt_line, error);
266  sprintf(err_eof_fmt, "%s: %s: ", fmt_eof, error);
267  sprintf(diag_line_fmt, "%s: ", fmt_line);
268  sprintf(diag_eof_fmt, "%s: ", fmt_eof);
269
270  msg_format = format;
271  init_fmt = 1;
272}
273
274/* -----------------------------------------------------------------------------
275 * format_filename()
276 *
277 * Remove double backslashes in Windows filename paths for display
278 * ----------------------------------------------------------------------------- */
279static String *format_filename(const_String_or_char_ptr filename) {
280  String *formatted_filename = NewString(filename);
281#if defined(_WIN32)
282  Replaceall(formatted_filename, "\\\\", "\\");
283#endif
284  return formatted_filename;
285}
286
287/* -----------------------------------------------------------------------------
288 * Swig_stringify_with_location()
289 *
290 * Return a string representation of any DOH object with line and file location
291 * information in the appropriate error message format. The string representation
292 * is enclosed within [] brackets after the line and file information.
293 * ----------------------------------------------------------------------------- */
294
295String *Swig_stringify_with_location(DOH *object) {
296  String *str = NewStringEmpty();
297
298  if (!init_fmt)
299    Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT);
300
301  if (object) {
302    int line = Getline(object);
303    String *formatted_filename = format_filename(Getfile(object));
304    if (line > 0) {
305      Printf(str, diag_line_fmt, formatted_filename, line);
306    } else {
307      Printf(str, diag_eof_fmt, formatted_filename);
308    }
309    if (Len(object) == 0) {
310      Printf(str, "[EMPTY]");
311    } else {
312      Printf(str, "[%s]", object);
313    }
314    Delete(formatted_filename);
315  } else {
316    Printf(str, "[NULL]");
317  }
318
319  return str;
320}
321
322/* -----------------------------------------------------------------------------
323 * Swig_diagnostic()
324 *
325 * Issue a diagnostic message on stdout.
326 * ----------------------------------------------------------------------------- */
327
328void Swig_diagnostic(const_String_or_char_ptr filename, int line, const char *fmt, ...) {
329  va_list ap;
330  String *formatted_filename = NULL;
331
332  if (!init_fmt)
333    Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT);
334
335  va_start(ap, fmt);
336  formatted_filename = format_filename(filename);
337  if (line > 0) {
338    Printf(stdout, diag_line_fmt, formatted_filename, line);
339  } else {
340    Printf(stdout, diag_eof_fmt, formatted_filename);
341  }
342  vPrintf(stdout, fmt, ap);
343  va_end(ap);
344  Delete(formatted_filename);
345}
346