PageRenderTime 67ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/Source/Swig/error.c

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