PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/gmrflib/error-handler.c

https://code.google.com/p/inla/
C | 302 lines | 102 code | 17 blank | 183 comment | 18 complexity | 09015aa4b8e93a49bad2c2da769efc0e MD5 | raw file
  1. /* error-handler.c
  2. *
  3. * Copyright (C) 2001-2006 Havard Rue
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. *
  19. * The author's contact information:
  20. *
  21. * H{\aa}vard Rue
  22. * Department of Mathematical Sciences
  23. * The Norwegian University of Science and Technology
  24. * N-7491 Trondheim, Norway
  25. * Voice: +47-7359-3533 URL : http://www.math.ntnu.no/~hrue
  26. * Fax : +47-7359-3524 Email: havard.rue@math.ntnu.no
  27. *
  28. *
  29. */
  30. /*!
  31. \file error-handler.c
  32. \brief Functions to handle error messages.
  33. If an error occurs running the routines from \em GMRFLib, an error message will be issued stating
  34. the type of error, and the function, the file and the line at which the error has occurred. By
  35. default, the program is core dumped and aborted at the occurrence of an error, using the function
  36. \c GMRFLib_error_handler(). This side effect can be overridden by the user, re-defining the error
  37. handling function as described in \c GMRFLib_set_error_handler(), or simply turn-off the
  38. error-handling system using \c GMRFLib_set_error_handler_off().
  39. \note The behaviour when the error-handling system is turned off and the code is \a returnd \a in \a the \a call. Temporary
  40. allocated memory may not be free'd if the error-handling system is turned off or altered such that the program continues. We
  41. hope to fix this in later releases.
  42. Example
  43. \verbinclude example-doxygen-error-handler.txt
  44. */
  45. #include <stdarg.h>
  46. #include <strings.h>
  47. #include <stdio.h>
  48. #if !defined(__FreeBSD__)
  49. #include <malloc.h>
  50. #endif
  51. #include <stdlib.h>
  52. #include "GMRFLib/GMRFLib.h"
  53. #include "GMRFLib/GMRFLibP.h"
  54. #ifndef HGVERSION
  55. #define HGVERSION
  56. #endif
  57. static const char RCSId[] = "file: " __FILE__ " " HGVERSION;
  58. /* Pre-hg-Id: $Id: error-handler.c,v 1.49 2008/08/26 07:07:11 hrue Exp $ */
  59. static GMRFLib_error_handler_tp *handler = NULL;
  60. #pragma omp threadprivate(handler)
  61. /*!
  62. \brief Returns the type of error, given the error code \a errorno.
  63. \param errorno The error id number (see below).
  64. \return A character string, giving the error message corresponding to error number
  65. \a errorno.
  66. \par Error numbers and error messages
  67. 0 : No error, please ignore \n
  68. 1 : Alloc failed \n
  69. 2 : Matrix is not positive definite \n
  70. 3 : Matrix is singular \n
  71. 4 : Invalid argument \n
  72. 5 : Graph is invalid \n
  73. 6 : Error reordering the graph \n
  74. 7 : Error while reading file \n
  75. 8 : Error opening file, file not found or readable \n
  76. 9 : Invalid value of parameter \n
  77. 10 : No index found \n
  78. 11 : Pointer is required to be non-NULL \n
  79. 12 : The Newton-Raphson optimizer did not converge \n
  80. 13 : The Conjugate-Gradient optimizer did not converge \n
  81. 14 : The line-optimizer in the Conjugate-Gradient optimizer did not converge \n
  82. 15 : Error occured in the mapkit-library (hash)\n
  83. 16 : Sparse-matrix-type not implemented yet\n
  84. 17 : Constraints or its covariance matrix is singular\n
  85. 18 : Fitting of the Skew-Normal distribution fail to converge\n
  86. 19 : Geo-coefficients are not available\n
  87. 20 : Error occured in the GSL-Library\n
  88. 21 : This should not happen\n
  89. 22 : Error writing file
  90. 23 : Misc error\n
  91. 24 : (this is an unknown error code) \n
  92. \remarks This function is used within the library generating the \a reason argument
  93. in the default error handling function \c GMRFLib_error_handler().
  94. \sa GMRFLib_error_handler.
  95. */
  96. const char *GMRFLib_error_reason(int errorno)
  97. {
  98. /*
  99. * return a pointer to the reason for error=errorno
  100. */
  101. #define NMSG 25
  102. static const char *reasons[NMSG] = { "No error, please ignore",
  103. "Alloc failed",
  104. "Matrix is not positive definite",
  105. "Matrix is singular",
  106. "Invalid argument or argument combination",
  107. "Graph is invalid",
  108. "Error reordering the graph",
  109. "Error while reading file",
  110. "Error opening file, file not found or readable",
  111. "Invalid value of parameter",
  112. "No index found",
  113. "Pointer is required to be non-NULL",
  114. "The Newton-Raphson optimizer did not converge",
  115. "The Conjugate-Gradient optimizer did not converge",
  116. "The line-optimizer in the Conjugate-Gradient optimizer did not converge",
  117. "Error occured in the mapkit-library (hash)",
  118. "Sparse-matrix-type (or function) not implemented yet",
  119. "Constraints or its covariance matrix is singular",
  120. "Fitting of the Skew-Normal distribution fail to converge",
  121. "Geo-coefficients are not available",
  122. "Error occured in the GSL-Library",
  123. "This should not happen",
  124. "Error writing file",
  125. "Misc error",
  126. "(((this is an unknown errorcode)))"
  127. };
  128. if (errorno < 0 || errorno >= NMSG - 1)
  129. return (const char *) reasons[NMSG - 1]; /* return the last message in this case */
  130. else
  131. return (const char *) reasons[errorno];
  132. #undef NMSG
  133. }
  134. /*!
  135. \brief The default error handling function, of type \c GMRFLib_error_handler_tp().
  136. \param reason A character string describing the reason for the error
  137. (see \c GMRFLib_error_reason()).
  138. \param function The name of the function in which the error occurs.
  139. \param file The file name.
  140. \param line The number of the file.
  141. \param id The RCS Id (version control Id) of the file.
  142. \param errorno The error id number (see <tt> \ref GMRFLib_error_reason()) </tt>.
  143. \param msg Error message.
  144. \return The error number. The function is aborted if reporting an error, so a value
  145. is returned only if \a errorno = 0.
  146. \remarks This is the default error handling function integrated in the library routines. It is
  147. called by the function \c GMRFLib_handle_error(). When an error occurs, the function prints an
  148. error message of the form \verbinclude doxygen_error_1.txt and the program is aborted,
  149. with a core dump. In the example above, the error message states that the command line arguments
  150. of the main program on the file \c test-graph.c is missing. To avoid aborting the program, a new
  151. error handling function can be defined, returning the error code without aborting. To turn off or
  152. change to another error handling function, use \c GMRFLib_set_error_handler_off() or \c
  153. GMRFLib_set_error_handler().
  154. \sa GMRFLib_error_handler_tp, GMRFLib_handle_error, GMRFLib_set_error_handler.
  155. */
  156. int GMRFLib_error_handler(const char *reason, const char *file, const char *function, int line, const char *id, int errorno, const char *msg)
  157. {
  158. /*
  159. * this is the default error-handler
  160. */
  161. fprintf(stderr, "\n\n\tGMRFLib version %1s, has recived error no [%1d]\n", GMRFLib_VERSION, errorno);
  162. if (reason) {
  163. fprintf(stderr, "\tReason : %s\n", reason);
  164. }
  165. if (msg) {
  166. fprintf(stderr, "\tMessage : %s\n", msg);
  167. }
  168. if (function) {
  169. fprintf(stderr, "\tFunction : %s\n", function);
  170. }
  171. if (file) {
  172. fprintf(stderr, "\tFile : %s\n", file);
  173. }
  174. if (1) {
  175. fprintf(stderr, "\tLine : %1d\n", line);
  176. }
  177. if (id) {
  178. fprintf(stderr, "\tRCSId : %s\n", id);
  179. }
  180. fprintf(stderr, "\n");
  181. if (errorno != GMRFLib_SUCCESS) {
  182. abort(); /* no reason to abort if ok */
  183. }
  184. return GMRFLib_SUCCESS;
  185. }
  186. int GMRFLib_error_handler_null(const char *reason, const char *file, const char *function, int line, const char *id, int errorno, const char *msg)
  187. {
  188. /*
  189. * gcc produce warnings here, so i have to fake some code to make them go away
  190. */
  191. int dummy = (reason || file || function || line == 0 || id || msg);
  192. return (dummy ? errorno : errorno);
  193. }
  194. /*!
  195. \brief Turn off the error handler and return the current one.
  196. This function turn off the error handling system and return the current error handler. This
  197. pointer can be passed to \c GMRFLib_set_error_handler() to restore the original beahviour.
  198. \sa GMRFLib_set_error_handler(), GMRFLib_error_handler()
  199. */
  200. GMRFLib_error_handler_tp *GMRFLib_set_error_handler_off(void)
  201. {
  202. GMRFLib_error_handler_tp *h = handler;
  203. GMRFLib_set_error_handler(GMRFLib_error_handler_null);
  204. return h;
  205. }
  206. /*!
  207. \brief Handles the error by calling an internal macro, issuing an error message.
  208. This is the function that is actually called at the occurrence of an error.
  209. \param file The file name.
  210. \param function The name of the function in which the error occurs.
  211. \param line The number of the file.
  212. \param id The RCS Id (version control Id) of the file.
  213. \param errorno The error id number (see <tt> \ref GMRFLib_error_reason()) </tt>.
  214. \param msg Error message.
  215. \sa GMRFLib_error_handler_tp, GMRFLib_error_handler, GMRFLib_set_error_handler.
  216. */
  217. int GMRFLib_handle_error(const char *file, const char *function, int line, const char *id, int errorno, const char *msg)
  218. {
  219. /*
  220. * this function handle an error, and is the one called from the library through the macro 'GMRFLib_ERROR'
  221. */
  222. if (handler) {
  223. (*handler) (GMRFLib_error_reason(errorno), file, function, line, id, errorno, msg);
  224. } else {
  225. GMRFLib_error_handler(GMRFLib_error_reason(errorno), file, function, line, id, errorno, msg);
  226. }
  227. return GMRFLib_SUCCESS;
  228. }
  229. /*!
  230. \brief Sets the error handler function to be the default function or a user specified function.
  231. The default error messages can be overridden by the user by defining a new
  232. error handling function of a specified format, \c GMRFLib_error_handler_tp().
  233. Within the library, a static function pointer \em handler is defined, pointing
  234. to a function of type \c GMRFLib_error_handler_tp(). By default, this is \c NULL,
  235. indicating that the default error handling function, \c GMRFLib_error_handler()
  236. is to be used. To override the default function, \em handler should be set to
  237. point at the user-specified \c GMRFLib_error_handler_tp()-function, which can
  238. be done using \c GMRFLib_set_error_handler().
  239. \param new_error_handler A pointer to a user-specified \c GMRFLib_error_handler_tp()
  240. -function. If \a new_error_handler = \c NULL, the default error handler function is chosen.
  241. \remarks To override the error handling function, the user should write a function with
  242. return value and argument list as defined by the \c GMRFLib_error_handler_tp() template,
  243. and then call \c GMRFLib_set_error_handler(). As a result, the user-specified function
  244. will be called at the occurrence of an error.
  245. \sa GMRFLib_error_handler_tp, GMRFLib_error_handler(), GMRFLib_set_error_handler_off()
  246. */
  247. int GMRFLib_set_error_handler(GMRFLib_error_handler_tp * new_error_handler)
  248. {
  249. /*
  250. * set new error-handler. if the new error-handler is NULL, then the default error-handler is used.
  251. */
  252. handler = new_error_handler;
  253. return GMRFLib_SUCCESS;
  254. }
  255. /*
  256. void Error(char *fmt, ...) {
  257. va_list args;
  258. va_start(args, fmt);
  259. vfprintf(stderr, fmt, args);
  260. va_end(args);
  261. fprintf(stderr, "\nExiting ...\n");
  262. exit(1);
  263. }
  264. */