PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/libs/libxml2-2.4.18/error.c

https://github.com/gitpan/AxKit-Needs
C | 408 lines | 254 code | 41 blank | 113 comment | 105 complexity | 3511605baede357ded3e862b6738a269 MD5 | raw file
Possible License(s): LGPL-2.0
  1. /*
  2. * error.c: module displaying/handling XML parser errors
  3. *
  4. * See Copyright for the status of this software.
  5. *
  6. * Daniel Veillard <daniel@veillard.com>
  7. */
  8. #define IN_LIBXML
  9. #include "libxml.h"
  10. #include <stdarg.h>
  11. #include <libxml/parser.h>
  12. #include <libxml/xmlerror.h>
  13. #include <libxml/xmlmemory.h>
  14. #include <libxml/globals.h>
  15. void xmlGenericErrorDefaultFunc (void *ctx ATTRIBUTE_UNUSED,
  16. const char *msg,
  17. ...);
  18. #define XML_GET_VAR_STR(msg, str) { \
  19. int size; \
  20. int chars; \
  21. char *larger; \
  22. va_list ap; \
  23. \
  24. str = (char *) xmlMalloc(150); \
  25. if (str == NULL) \
  26. return; \
  27. \
  28. size = 150; \
  29. \
  30. while (1) { \
  31. va_start(ap, msg); \
  32. chars = vsnprintf(str, size, msg, ap); \
  33. va_end(ap); \
  34. if ((chars > -1) && (chars < size)) \
  35. break; \
  36. if (chars > -1) \
  37. size += chars + 1; \
  38. else \
  39. size += 100; \
  40. if ((larger = (char *) xmlRealloc(str, size)) == NULL) {\
  41. xmlFree(str); \
  42. return; \
  43. } \
  44. str = larger; \
  45. } \
  46. }
  47. /************************************************************************
  48. * *
  49. * Handling of out of context errors *
  50. * *
  51. ************************************************************************/
  52. /**
  53. * xmlGenericErrorDefaultFunc:
  54. * @ctx: an error context
  55. * @msg: the message to display/transmit
  56. * @...: extra parameters for the message display
  57. *
  58. * Default handler for out of context error messages.
  59. */
  60. void
  61. xmlGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
  62. va_list args;
  63. if (xmlGenericErrorContext == NULL)
  64. xmlGenericErrorContext = (void *) stderr;
  65. va_start(args, msg);
  66. vfprintf((FILE *)xmlGenericErrorContext, msg, args);
  67. va_end(args);
  68. }
  69. /**
  70. * initGenericErrorDefaultFunc:
  71. * @handler: the handler
  72. *
  73. * Set or reset (if NULL) the default handler for generic errors
  74. */
  75. void
  76. initGenericErrorDefaultFunc(xmlGenericErrorFunc * handler)
  77. {
  78. if (handler == NULL)
  79. xmlGenericError = xmlGenericErrorDefaultFunc;
  80. else
  81. (*handler) = xmlGenericErrorDefaultFunc;
  82. }
  83. /**
  84. * xmlSetGenericErrorFunc:
  85. * @ctx: the new error handling context
  86. * @handler: the new handler function
  87. *
  88. * Function to reset the handler and the error context for out of
  89. * context error messages.
  90. * This simply means that @handler will be called for subsequent
  91. * error messages while not parsing nor validating. And @ctx will
  92. * be passed as first argument to @handler
  93. * One can simply force messages to be emitted to another FILE * than
  94. * stderr by setting @ctx to this file handle and @handler to NULL.
  95. */
  96. void
  97. xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
  98. xmlGenericErrorContext = ctx;
  99. if (handler != NULL)
  100. xmlGenericError = handler;
  101. else
  102. xmlGenericError = xmlGenericErrorDefaultFunc;
  103. }
  104. /************************************************************************
  105. * *
  106. * Handling of parsing errors *
  107. * *
  108. ************************************************************************/
  109. /**
  110. * xmlParserPrintFileInfo:
  111. * @input: an xmlParserInputPtr input
  112. *
  113. * Displays the associated file and line informations for the current input
  114. */
  115. void
  116. xmlParserPrintFileInfo(xmlParserInputPtr input) {
  117. if (input != NULL) {
  118. if (input->filename)
  119. xmlGenericError(xmlGenericErrorContext,
  120. "%s:%d: ", input->filename,
  121. input->line);
  122. else
  123. xmlGenericError(xmlGenericErrorContext,
  124. "Entity: line %d: ", input->line);
  125. }
  126. }
  127. /**
  128. * xmlParserPrintFileContext:
  129. * @input: an xmlParserInputPtr input
  130. *
  131. * Displays current context within the input content for error tracking
  132. */
  133. void
  134. xmlParserPrintFileContext(xmlParserInputPtr input) {
  135. const xmlChar *cur, *base;
  136. int n;
  137. xmlChar content[81];
  138. xmlChar *ctnt;
  139. if (input == NULL) return;
  140. cur = input->cur;
  141. base = input->base;
  142. /* skip backwards over any end-of-lines */
  143. while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
  144. cur--;
  145. }
  146. n = 0;
  147. /* search backwards for beginning-of-line maximum 80 characters */
  148. while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
  149. cur--;
  150. if ((*cur == '\n') || (*cur == '\r')) cur++;
  151. /* search forward for end-of-line maximum 80 characters */
  152. n = 0;
  153. ctnt = content;
  154. while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
  155. *ctnt++ = *cur++;
  156. n++;
  157. }
  158. *ctnt = 0;
  159. xmlGenericError(xmlGenericErrorContext,"%s\n", content);
  160. /* create blank line with problem pointer */
  161. cur = input->cur;
  162. while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
  163. cur--;
  164. }
  165. n = 0;
  166. ctnt = content;
  167. while ((n++ < 79) && (cur > base) && (*cur != '\n') && (*cur != '\r')) {
  168. *ctnt++ = ' ';
  169. cur--;
  170. }
  171. if (ctnt > content) {
  172. *(--ctnt) = '^';
  173. *(++ctnt) = 0;
  174. } else {
  175. *ctnt = '^';
  176. *(++ctnt) = 0;
  177. }
  178. xmlGenericError(xmlGenericErrorContext,"%s\n", content);
  179. }
  180. #if 0
  181. /**
  182. * xmlGetVarStr:
  183. * @msg: the message format
  184. * @args: a va_list argument list
  185. *
  186. * SGS contribution
  187. * Get an arbitrary-sized string for an error argument
  188. * The caller must free() the returned string
  189. */
  190. static char *
  191. xmlGetVarStr(const char * msg, va_list args) {
  192. int size;
  193. int length;
  194. int chars, left;
  195. char *str, *larger;
  196. va_list ap;
  197. str = (char *) xmlMalloc(150);
  198. if (str == NULL)
  199. return(NULL);
  200. size = 150;
  201. length = 0;
  202. while (1) {
  203. left = size - length;
  204. /* Try to print in the allocated space. */
  205. va_start(msg, ap);
  206. chars = vsnprintf(str + length, left, msg, ap);
  207. va_end(ap);
  208. /* If that worked, we're done. */
  209. if ((chars > -1) && (chars < left ))
  210. break;
  211. /* Else try again with more space. */
  212. if (chars > -1) /* glibc 2.1 */
  213. size += chars + 1; /* precisely what is needed */
  214. else /* glibc 2.0 */
  215. size += 100;
  216. if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
  217. xmlFree(str);
  218. return(NULL);
  219. }
  220. str = larger;
  221. }
  222. return(str);
  223. }
  224. #endif
  225. /**
  226. * xmlParserError:
  227. * @ctx: an XML parser context
  228. * @msg: the message to display/transmit
  229. * @...: extra parameters for the message display
  230. *
  231. * Display and format an error messages, gives file, line, position and
  232. * extra parameters.
  233. */
  234. void
  235. xmlParserError(void *ctx, const char *msg, ...)
  236. {
  237. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  238. xmlParserInputPtr input = NULL;
  239. xmlParserInputPtr cur = NULL;
  240. char * str;
  241. if (ctxt != NULL) {
  242. input = ctxt->input;
  243. if ((input != NULL) && (input->filename == NULL) &&
  244. (ctxt->inputNr > 1)) {
  245. cur = input;
  246. input = ctxt->inputTab[ctxt->inputNr - 2];
  247. }
  248. xmlParserPrintFileInfo(input);
  249. }
  250. xmlGenericError(xmlGenericErrorContext, "error: ");
  251. XML_GET_VAR_STR(msg, str);
  252. xmlGenericError(xmlGenericErrorContext, "%s", str);
  253. if (str != NULL)
  254. xmlFree(str);
  255. if (ctxt != NULL) {
  256. xmlParserPrintFileContext(input);
  257. if (cur != NULL) {
  258. xmlParserPrintFileInfo(cur);
  259. xmlGenericError(xmlGenericErrorContext, "\n");
  260. xmlParserPrintFileContext(cur);
  261. }
  262. }
  263. }
  264. /**
  265. * xmlParserWarning:
  266. * @ctx: an XML parser context
  267. * @msg: the message to display/transmit
  268. * @...: extra parameters for the message display
  269. *
  270. * Display and format a warning messages, gives file, line, position and
  271. * extra parameters.
  272. */
  273. void
  274. xmlParserWarning(void *ctx, const char *msg, ...)
  275. {
  276. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  277. xmlParserInputPtr input = NULL;
  278. xmlParserInputPtr cur = NULL;
  279. char * str;
  280. if (ctxt != NULL) {
  281. input = ctxt->input;
  282. if ((input != NULL) && (input->filename == NULL) &&
  283. (ctxt->inputNr > 1)) {
  284. cur = input;
  285. input = ctxt->inputTab[ctxt->inputNr - 2];
  286. }
  287. xmlParserPrintFileInfo(input);
  288. }
  289. xmlGenericError(xmlGenericErrorContext, "warning: ");
  290. XML_GET_VAR_STR(msg, str);
  291. xmlGenericError(xmlGenericErrorContext, "%s", str);
  292. if (str != NULL)
  293. xmlFree(str);
  294. if (ctxt != NULL) {
  295. xmlParserPrintFileContext(input);
  296. if (cur != NULL) {
  297. xmlParserPrintFileInfo(cur);
  298. xmlGenericError(xmlGenericErrorContext, "\n");
  299. xmlParserPrintFileContext(cur);
  300. }
  301. }
  302. }
  303. /************************************************************************
  304. * *
  305. * Handling of validation errors *
  306. * *
  307. ************************************************************************/
  308. /**
  309. * xmlParserValidityError:
  310. * @ctx: an XML parser context
  311. * @msg: the message to display/transmit
  312. * @...: extra parameters for the message display
  313. *
  314. * Display and format an validity error messages, gives file,
  315. * line, position and extra parameters.
  316. */
  317. void
  318. xmlParserValidityError(void *ctx, const char *msg, ...)
  319. {
  320. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  321. xmlParserInputPtr input = NULL;
  322. char * str;
  323. if (ctxt != NULL) {
  324. input = ctxt->input;
  325. if ((input->filename == NULL) && (ctxt->inputNr > 1))
  326. input = ctxt->inputTab[ctxt->inputNr - 2];
  327. xmlParserPrintFileInfo(input);
  328. }
  329. xmlGenericError(xmlGenericErrorContext, "validity error: ");
  330. XML_GET_VAR_STR(msg, str);
  331. xmlGenericError(xmlGenericErrorContext, "%s", str);
  332. if (str != NULL)
  333. xmlFree(str);
  334. if (ctxt != NULL) {
  335. xmlParserPrintFileContext(input);
  336. }
  337. }
  338. /**
  339. * xmlParserValidityWarning:
  340. * @ctx: an XML parser context
  341. * @msg: the message to display/transmit
  342. * @...: extra parameters for the message display
  343. *
  344. * Display and format a validity warning messages, gives file, line,
  345. * position and extra parameters.
  346. */
  347. void
  348. xmlParserValidityWarning(void *ctx, const char *msg, ...)
  349. {
  350. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  351. xmlParserInputPtr input = NULL;
  352. char * str;
  353. if (ctxt != NULL) {
  354. input = ctxt->input;
  355. if ((input->filename == NULL) && (ctxt->inputNr > 1))
  356. input = ctxt->inputTab[ctxt->inputNr - 2];
  357. xmlParserPrintFileInfo(input);
  358. }
  359. xmlGenericError(xmlGenericErrorContext, "validity warning: ");
  360. XML_GET_VAR_STR(msg, str);
  361. xmlGenericError(xmlGenericErrorContext, "%s", str);
  362. if (str != NULL)
  363. xmlFree(str);
  364. if (ctxt != NULL) {
  365. xmlParserPrintFileContext(input);
  366. }
  367. }