PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/bullet-2.75/Extras/LibXML/error.c

https://bitbucket.org/bitshifter/bullet
C | 986 lines | 673 code | 70 blank | 243 comment | 345 complexity | 1f7a0efdb8fdc8ce29e2512802641a7e MD5 | raw file
Possible License(s): Zlib, BSD-3-Clause, LGPL-2.0, LGPL-2.1
  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 <string.h>
  11. #include <stdarg.h>
  12. #include <libxml/parser.h>
  13. #include <libxml/xmlerror.h>
  14. #include <libxml/xmlmemory.h>
  15. #include <libxml/globals.h>
  16. void XMLCDECL xmlGenericErrorDefaultFunc (void *ctx ATTRIBUTE_UNUSED,
  17. const char *msg,
  18. ...);
  19. #define XML_GET_VAR_STR(msg, str) { \
  20. int size, prev_size = -1; \
  21. int chars; \
  22. char *larger; \
  23. va_list ap; \
  24. \
  25. str = (char *) xmlMalloc(150); \
  26. if (str != NULL) { \
  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. if (prev_size == chars) { \
  36. break; \
  37. } else { \
  38. prev_size = chars; \
  39. } \
  40. } \
  41. if (chars > -1) \
  42. size += chars + 1; \
  43. else \
  44. size += 100; \
  45. if ((larger = (char *) xmlRealloc(str, size)) == NULL) {\
  46. break; \
  47. } \
  48. str = larger; \
  49. }} \
  50. }
  51. /************************************************************************
  52. * *
  53. * Handling of out of context errors *
  54. * *
  55. ************************************************************************/
  56. /**
  57. * xmlGenericErrorDefaultFunc:
  58. * @ctx: an error context
  59. * @msg: the message to display/transmit
  60. * @...: extra parameters for the message display
  61. *
  62. * Default handler for out of context error messages.
  63. */
  64. void XMLCDECL
  65. xmlGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
  66. va_list args;
  67. if (xmlGenericErrorContext == NULL)
  68. xmlGenericErrorContext = (void *) stderr;
  69. va_start(args, msg);
  70. vfprintf((FILE *)xmlGenericErrorContext, msg, args);
  71. va_end(args);
  72. }
  73. /**
  74. * initGenericErrorDefaultFunc:
  75. * @handler: the handler
  76. *
  77. * Set or reset (if NULL) the default handler for generic errors
  78. * to the builtin error function.
  79. */
  80. void
  81. initGenericErrorDefaultFunc(xmlGenericErrorFunc * handler)
  82. {
  83. if (handler == NULL)
  84. xmlGenericError = xmlGenericErrorDefaultFunc;
  85. else
  86. xmlGenericError = (*handler);
  87. }
  88. /**
  89. * xmlSetGenericErrorFunc:
  90. * @ctx: the new error handling context
  91. * @handler: the new handler function
  92. *
  93. * Function to reset the handler and the error context for out of
  94. * context error messages.
  95. * This simply means that @handler will be called for subsequent
  96. * error messages while not parsing nor validating. And @ctx will
  97. * be passed as first argument to @handler
  98. * One can simply force messages to be emitted to another FILE * than
  99. * stderr by setting @ctx to this file handle and @handler to NULL.
  100. * For multi-threaded applications, this must be set separately for each thread.
  101. */
  102. void
  103. xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
  104. xmlGenericErrorContext = ctx;
  105. if (handler != NULL)
  106. xmlGenericError = handler;
  107. else
  108. xmlGenericError = xmlGenericErrorDefaultFunc;
  109. }
  110. /**
  111. * xmlSetStructuredErrorFunc:
  112. * @ctx: the new error handling context
  113. * @handler: the new handler function
  114. *
  115. * Function to reset the handler and the error context for out of
  116. * context structured error messages.
  117. * This simply means that @handler will be called for subsequent
  118. * error messages while not parsing nor validating. And @ctx will
  119. * be passed as first argument to @handler
  120. * For multi-threaded applications, this must be set separately for each thread.
  121. */
  122. void
  123. xmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
  124. xmlGenericErrorContext = ctx;
  125. xmlStructuredError = handler;
  126. }
  127. /************************************************************************
  128. * *
  129. * Handling of parsing errors *
  130. * *
  131. ************************************************************************/
  132. /**
  133. * xmlParserPrintFileInfo:
  134. * @input: an xmlParserInputPtr input
  135. *
  136. * Displays the associated file and line informations for the current input
  137. */
  138. void
  139. xmlParserPrintFileInfo(xmlParserInputPtr input) {
  140. if (input != NULL) {
  141. if (input->filename)
  142. xmlGenericError(xmlGenericErrorContext,
  143. "%s:%d: ", input->filename,
  144. input->line);
  145. else
  146. xmlGenericError(xmlGenericErrorContext,
  147. "Entity: line %d: ", input->line);
  148. }
  149. }
  150. /**
  151. * xmlParserPrintFileContext:
  152. * @input: an xmlParserInputPtr input
  153. *
  154. * Displays current context within the input content for error tracking
  155. */
  156. static void
  157. xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
  158. xmlGenericErrorFunc channel, void *data ) {
  159. const xmlChar *cur, *base;
  160. unsigned int n, col; /* GCC warns if signed, because compared with sizeof() */
  161. xmlChar content[81]; /* space for 80 chars + line terminator */
  162. xmlChar *ctnt;
  163. if (input == NULL) return;
  164. cur = input->cur;
  165. base = input->base;
  166. /* skip backwards over any end-of-lines */
  167. while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
  168. cur--;
  169. }
  170. n = 0;
  171. /* search backwards for beginning-of-line (to max buff size) */
  172. while ((n++ < (sizeof(content)-1)) && (cur > base) &&
  173. (*(cur) != '\n') && (*(cur) != '\r'))
  174. cur--;
  175. if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
  176. /* calculate the error position in terms of the current position */
  177. col = input->cur - cur;
  178. /* search forward for end-of-line (to max buff size) */
  179. n = 0;
  180. ctnt = content;
  181. /* copy selected text to our buffer */
  182. while ((*cur != 0) && (*(cur) != '\n') &&
  183. (*(cur) != '\r') && (n < sizeof(content)-1)) {
  184. *ctnt++ = *cur++;
  185. n++;
  186. }
  187. *ctnt = 0;
  188. /* print out the selected text */
  189. channel(data ,"%s\n", content);
  190. /* create blank line with problem pointer */
  191. n = 0;
  192. ctnt = content;
  193. /* (leave buffer space for pointer + line terminator) */
  194. while ((n<col) && (n++ < sizeof(content)-2) && (*ctnt != 0)) {
  195. if (*(ctnt) != '\t')
  196. *(ctnt) = ' ';
  197. ctnt++;
  198. }
  199. *ctnt++ = '^';
  200. *ctnt = 0;
  201. channel(data ,"%s\n", content);
  202. }
  203. /**
  204. * xmlParserPrintFileContext:
  205. * @input: an xmlParserInputPtr input
  206. *
  207. * Displays current context within the input content for error tracking
  208. */
  209. void
  210. xmlParserPrintFileContext(xmlParserInputPtr input) {
  211. xmlParserPrintFileContextInternal(input, xmlGenericError,
  212. xmlGenericErrorContext);
  213. }
  214. /**
  215. * xmlReportError:
  216. * @err: the error
  217. * @ctx: the parser context or NULL
  218. * @str: the formatted error message
  219. *
  220. * Report an erro with its context, replace the 4 old error/warning
  221. * routines.
  222. */
  223. static void
  224. xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str,
  225. xmlGenericErrorFunc channel, void *data)
  226. {
  227. char *file = NULL;
  228. int line = 0;
  229. int code = -1;
  230. int domain;
  231. const xmlChar *name = NULL;
  232. xmlNodePtr node;
  233. xmlErrorLevel level;
  234. xmlParserInputPtr input = NULL;
  235. xmlParserInputPtr cur = NULL;
  236. if (err == NULL)
  237. return;
  238. if (channel == NULL) {
  239. channel = xmlGenericError;
  240. data = xmlGenericErrorContext;
  241. }
  242. file = err->file;
  243. line = err->line;
  244. code = err->code;
  245. domain = err->domain;
  246. level = err->level;
  247. node = err->node;
  248. if (code == XML_ERR_OK)
  249. return;
  250. if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
  251. name = node->name;
  252. /*
  253. * Maintain the compatibility with the legacy error handling
  254. */
  255. if (ctxt != NULL) {
  256. input = ctxt->input;
  257. if ((input != NULL) && (input->filename == NULL) &&
  258. (ctxt->inputNr > 1)) {
  259. cur = input;
  260. input = ctxt->inputTab[ctxt->inputNr - 2];
  261. }
  262. if (input != NULL) {
  263. if (input->filename)
  264. channel(data, "%s:%d: ", input->filename, input->line);
  265. else if ((line != 0) && (domain == XML_FROM_PARSER))
  266. channel(data, "Entity: line %d: ", input->line);
  267. }
  268. } else {
  269. if (file != NULL)
  270. channel(data, "%s:%d: ", file, line);
  271. else if ((line != 0) && (domain == XML_FROM_PARSER))
  272. channel(data, "Entity: line %d: ", line);
  273. }
  274. if (name != NULL) {
  275. channel(data, "element %s: ", name);
  276. }
  277. switch (domain) {
  278. case XML_FROM_PARSER:
  279. channel(data, "parser ");
  280. break;
  281. case XML_FROM_NAMESPACE:
  282. channel(data, "namespace ");
  283. break;
  284. case XML_FROM_DTD:
  285. case XML_FROM_VALID:
  286. channel(data, "validity ");
  287. break;
  288. case XML_FROM_HTML:
  289. channel(data, "HTML parser ");
  290. break;
  291. case XML_FROM_MEMORY:
  292. channel(data, "memory ");
  293. break;
  294. case XML_FROM_OUTPUT:
  295. channel(data, "output ");
  296. break;
  297. case XML_FROM_IO:
  298. channel(data, "I/O ");
  299. break;
  300. case XML_FROM_XINCLUDE:
  301. channel(data, "XInclude ");
  302. break;
  303. case XML_FROM_XPATH:
  304. channel(data, "XPath ");
  305. break;
  306. case XML_FROM_XPOINTER:
  307. channel(data, "parser ");
  308. break;
  309. case XML_FROM_REGEXP:
  310. channel(data, "regexp ");
  311. break;
  312. case XML_FROM_MODULE:
  313. channel(data, "module ");
  314. break;
  315. case XML_FROM_SCHEMASV:
  316. channel(data, "Schemas validity ");
  317. break;
  318. case XML_FROM_SCHEMASP:
  319. channel(data, "Schemas parser ");
  320. break;
  321. case XML_FROM_RELAXNGP:
  322. channel(data, "Relax-NG parser ");
  323. break;
  324. case XML_FROM_RELAXNGV:
  325. channel(data, "Relax-NG validity ");
  326. break;
  327. case XML_FROM_CATALOG:
  328. channel(data, "Catalog ");
  329. break;
  330. case XML_FROM_C14N:
  331. channel(data, "C14N ");
  332. break;
  333. case XML_FROM_XSLT:
  334. channel(data, "XSLT ");
  335. break;
  336. case XML_FROM_I18N:
  337. channel(data, "encoding ");
  338. break;
  339. default:
  340. break;
  341. }
  342. switch (level) {
  343. case XML_ERR_NONE:
  344. channel(data, ": ");
  345. break;
  346. case XML_ERR_WARNING:
  347. channel(data, "warning : ");
  348. break;
  349. case XML_ERR_ERROR:
  350. channel(data, "error : ");
  351. break;
  352. case XML_ERR_FATAL:
  353. channel(data, "error : ");
  354. break;
  355. }
  356. if (str != NULL) {
  357. int len;
  358. len = xmlStrlen((const xmlChar *)str);
  359. if ((len > 0) && (str[len - 1] != '\n'))
  360. channel(data, "%s\n", str);
  361. else
  362. channel(data, "%s", str);
  363. } else {
  364. channel(data, "%s\n", "out of memory error");
  365. }
  366. if (ctxt != NULL) {
  367. xmlParserPrintFileContextInternal(input, channel, data);
  368. if (cur != NULL) {
  369. if (cur->filename)
  370. channel(data, "%s:%d: \n", cur->filename, cur->line);
  371. else if ((line != 0) && (domain == XML_FROM_PARSER))
  372. channel(data, "Entity: line %d: \n", cur->line);
  373. xmlParserPrintFileContextInternal(cur, channel, data);
  374. }
  375. }
  376. if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
  377. (err->int1 < 100) &&
  378. (err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
  379. xmlChar buf[150];
  380. int i;
  381. channel(data, "%s\n", err->str1);
  382. for (i=0;i < err->int1;i++)
  383. buf[i] = ' ';
  384. buf[i++] = '^';
  385. buf[i] = 0;
  386. channel(data, "%s\n", buf);
  387. }
  388. }
  389. /**
  390. * __xmlRaiseError:
  391. * @schannel: the structured callback channel
  392. * @channel: the old callback channel
  393. * @data: the callback data
  394. * @ctx: the parser context or NULL
  395. * @ctx: the parser context or NULL
  396. * @domain: the domain for the error
  397. * @code: the code for the error
  398. * @level: the xmlErrorLevel for the error
  399. * @file: the file source of the error (or NULL)
  400. * @line: the line of the error or 0 if N/A
  401. * @str1: extra string info
  402. * @str2: extra string info
  403. * @str3: extra string info
  404. * @int1: extra int info
  405. * @col: column number of the error or 0 if N/A
  406. * @msg: the message to display/transmit
  407. * @...: extra parameters for the message display
  408. *
  409. * Update the appropriate global or contextual error structure,
  410. * then forward the error message down the parser or generic
  411. * error callback handler
  412. */
  413. void XMLCDECL
  414. __xmlRaiseError(xmlStructuredErrorFunc schannel,
  415. xmlGenericErrorFunc channel, void *data, void *ctx,
  416. void *nod, int domain, int code, xmlErrorLevel level,
  417. const char *file, int line, const char *str1,
  418. const char *str2, const char *str3, int int1, int col,
  419. const char *msg, ...)
  420. {
  421. xmlParserCtxtPtr ctxt = NULL;
  422. xmlNodePtr node = (xmlNodePtr) nod;
  423. char *str = NULL;
  424. xmlParserInputPtr input = NULL;
  425. xmlErrorPtr to = &xmlLastError;
  426. xmlNodePtr baseptr = NULL;
  427. if ((xmlGetWarningsDefaultValue == 0) && (level == XML_ERR_WARNING))
  428. return;
  429. if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
  430. (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
  431. (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
  432. ctxt = (xmlParserCtxtPtr) ctx;
  433. if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) &&
  434. (ctxt->sax->initialized == XML_SAX2_MAGIC))
  435. schannel = ctxt->sax->serror;
  436. }
  437. /*
  438. * Check if structured error handler set
  439. */
  440. if (schannel == NULL) {
  441. schannel = xmlStructuredError;
  442. /*
  443. * if user has defined handler, change data ptr to user's choice
  444. */
  445. if (schannel != NULL)
  446. data = xmlGenericErrorContext;
  447. }
  448. if ((domain == XML_FROM_VALID) &&
  449. ((channel == xmlParserValidityError) ||
  450. (channel == xmlParserValidityWarning))) {
  451. ctxt = (xmlParserCtxtPtr) ctx;
  452. if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) &&
  453. (ctxt->sax->initialized == XML_SAX2_MAGIC))
  454. schannel = ctxt->sax->serror;
  455. }
  456. if (code == XML_ERR_OK)
  457. return;
  458. /*
  459. * Formatting the message
  460. */
  461. if (msg == NULL) {
  462. str = (char *) xmlStrdup(BAD_CAST "No error message provided");
  463. } else {
  464. XML_GET_VAR_STR(msg, str);
  465. }
  466. /*
  467. * specific processing if a parser context is provided
  468. */
  469. if (ctxt != NULL) {
  470. if (file == NULL) {
  471. input = ctxt->input;
  472. if ((input != NULL) && (input->filename == NULL) &&
  473. (ctxt->inputNr > 1)) {
  474. input = ctxt->inputTab[ctxt->inputNr - 2];
  475. }
  476. if (input != NULL) {
  477. file = input->filename;
  478. line = input->line;
  479. col = input->col;
  480. }
  481. }
  482. to = &ctxt->lastError;
  483. } else if ((node != NULL) && (file == NULL)) {
  484. int i;
  485. if ((node->doc != NULL) && (node->doc->URL != NULL)) {
  486. baseptr = node;
  487. /* file = (const char *) node->doc->URL; */
  488. }
  489. for (i = 0;
  490. ((i < 10) && (node != NULL) && (node->type != XML_ELEMENT_NODE));
  491. i++)
  492. node = node->parent;
  493. if ((baseptr == NULL) && (node != NULL) &&
  494. (node->doc != NULL) && (node->doc->URL != NULL))
  495. baseptr = node;
  496. if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
  497. line = node->line;
  498. }
  499. /*
  500. * Save the information about the error
  501. */
  502. xmlResetError(to);
  503. to->domain = domain;
  504. to->code = code;
  505. to->message = str;
  506. to->level = level;
  507. if (file != NULL)
  508. to->file = (char *) xmlStrdup((const xmlChar *) file);
  509. else if (baseptr != NULL) {
  510. #ifdef LIBXML_XINCLUDE_ENABLED
  511. /*
  512. * We check if the error is within an XInclude section and,
  513. * if so, attempt to print out the href of the XInclude instead
  514. * of the usual "base" (doc->URL) for the node (bug 152623).
  515. */
  516. xmlNodePtr prev = baseptr;
  517. int inclcount = 0;
  518. while (prev != NULL) {
  519. if (prev->prev == NULL)
  520. prev = prev->parent;
  521. else {
  522. prev = prev->prev;
  523. if (prev->type == XML_XINCLUDE_START) {
  524. if (--inclcount < 0)
  525. break;
  526. } else if (prev->type == XML_XINCLUDE_END)
  527. inclcount++;
  528. }
  529. }
  530. if (prev != NULL) {
  531. if (prev->type == XML_XINCLUDE_START) {
  532. prev->type = XML_ELEMENT_NODE;
  533. to->file = (char *) xmlGetProp(prev, BAD_CAST "href");
  534. prev->type = XML_XINCLUDE_START;
  535. } else {
  536. to->file = (char *) xmlGetProp(prev, BAD_CAST "href");
  537. }
  538. } else
  539. #endif
  540. to->file = (char *) xmlStrdup(baseptr->doc->URL);
  541. if ((to->file == NULL) && (node != NULL) && (node->doc != NULL)) {
  542. to->file = (char *) xmlStrdup(node->doc->URL);
  543. }
  544. file = to->file;
  545. }
  546. to->line = line;
  547. if (str1 != NULL)
  548. to->str1 = (char *) xmlStrdup((const xmlChar *) str1);
  549. if (str2 != NULL)
  550. to->str2 = (char *) xmlStrdup((const xmlChar *) str2);
  551. if (str3 != NULL)
  552. to->str3 = (char *) xmlStrdup((const xmlChar *) str3);
  553. to->int1 = int1;
  554. to->int2 = col;
  555. to->node = node;
  556. to->ctxt = ctx;
  557. if (to != &xmlLastError)
  558. xmlCopyError(to,&xmlLastError);
  559. /*
  560. * Find the callback channel if channel param is NULL
  561. */
  562. if ((ctxt != NULL) && (channel == NULL) && (xmlStructuredError == NULL) && (ctxt->sax != NULL)) {
  563. if (level == XML_ERR_WARNING)
  564. channel = ctxt->sax->warning;
  565. else
  566. channel = ctxt->sax->error;
  567. data = ctxt->userData;
  568. } else if (channel == NULL) {
  569. if (xmlStructuredError != NULL)
  570. schannel = xmlStructuredError;
  571. else
  572. channel = xmlGenericError;
  573. if (!data) {
  574. data = xmlGenericErrorContext;
  575. }
  576. }
  577. if (schannel != NULL) {
  578. schannel(data, to);
  579. return;
  580. }
  581. if (channel == NULL)
  582. return;
  583. if ((channel == xmlParserError) ||
  584. (channel == xmlParserWarning) ||
  585. (channel == xmlParserValidityError) ||
  586. (channel == xmlParserValidityWarning))
  587. xmlReportError(to, ctxt, str, NULL, NULL);
  588. else if ((channel == (xmlGenericErrorFunc) fprintf) ||
  589. (channel == xmlGenericErrorDefaultFunc))
  590. xmlReportError(to, ctxt, str, channel, data);
  591. else
  592. channel(data, "%s", str);
  593. }
  594. /**
  595. * __xmlSimpleError:
  596. * @domain: where the error comes from
  597. * @code: the error code
  598. * @node: the context node
  599. * @extra: extra informations
  600. *
  601. * Handle an out of memory condition
  602. */
  603. void
  604. __xmlSimpleError(int domain, int code, xmlNodePtr node,
  605. const char *msg, const char *extra)
  606. {
  607. if (code == XML_ERR_NO_MEMORY) {
  608. if (extra)
  609. __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
  610. XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
  611. NULL, NULL, 0, 0,
  612. "Memory allocation failed : %s\n", extra);
  613. else
  614. __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
  615. XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
  616. NULL, NULL, 0, 0, "Memory allocation failed\n");
  617. } else {
  618. __xmlRaiseError(NULL, NULL, NULL, NULL, node, domain,
  619. code, XML_ERR_ERROR, NULL, 0, extra,
  620. NULL, NULL, 0, 0, msg, extra);
  621. }
  622. }
  623. /**
  624. * xmlParserError:
  625. * @ctx: an XML parser context
  626. * @msg: the message to display/transmit
  627. * @...: extra parameters for the message display
  628. *
  629. * Display and format an error messages, gives file, line, position and
  630. * extra parameters.
  631. */
  632. void XMLCDECL
  633. xmlParserError(void *ctx, const char *msg, ...)
  634. {
  635. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  636. xmlParserInputPtr input = NULL;
  637. xmlParserInputPtr cur = NULL;
  638. char * str;
  639. if (ctxt != NULL) {
  640. input = ctxt->input;
  641. if ((input != NULL) && (input->filename == NULL) &&
  642. (ctxt->inputNr > 1)) {
  643. cur = input;
  644. input = ctxt->inputTab[ctxt->inputNr - 2];
  645. }
  646. xmlParserPrintFileInfo(input);
  647. }
  648. xmlGenericError(xmlGenericErrorContext, "error: ");
  649. XML_GET_VAR_STR(msg, str);
  650. xmlGenericError(xmlGenericErrorContext, "%s", str);
  651. if (str != NULL)
  652. xmlFree(str);
  653. if (ctxt != NULL) {
  654. xmlParserPrintFileContext(input);
  655. if (cur != NULL) {
  656. xmlParserPrintFileInfo(cur);
  657. xmlGenericError(xmlGenericErrorContext, "\n");
  658. xmlParserPrintFileContext(cur);
  659. }
  660. }
  661. }
  662. /**
  663. * xmlParserWarning:
  664. * @ctx: an XML parser context
  665. * @msg: the message to display/transmit
  666. * @...: extra parameters for the message display
  667. *
  668. * Display and format a warning messages, gives file, line, position and
  669. * extra parameters.
  670. */
  671. void XMLCDECL
  672. xmlParserWarning(void *ctx, const char *msg, ...)
  673. {
  674. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  675. xmlParserInputPtr input = NULL;
  676. xmlParserInputPtr cur = NULL;
  677. char * str;
  678. if (ctxt != NULL) {
  679. input = ctxt->input;
  680. if ((input != NULL) && (input->filename == NULL) &&
  681. (ctxt->inputNr > 1)) {
  682. cur = input;
  683. input = ctxt->inputTab[ctxt->inputNr - 2];
  684. }
  685. xmlParserPrintFileInfo(input);
  686. }
  687. xmlGenericError(xmlGenericErrorContext, "warning: ");
  688. XML_GET_VAR_STR(msg, str);
  689. xmlGenericError(xmlGenericErrorContext, "%s", str);
  690. if (str != NULL)
  691. xmlFree(str);
  692. if (ctxt != NULL) {
  693. xmlParserPrintFileContext(input);
  694. if (cur != NULL) {
  695. xmlParserPrintFileInfo(cur);
  696. xmlGenericError(xmlGenericErrorContext, "\n");
  697. xmlParserPrintFileContext(cur);
  698. }
  699. }
  700. }
  701. /************************************************************************
  702. * *
  703. * Handling of validation errors *
  704. * *
  705. ************************************************************************/
  706. /**
  707. * xmlParserValidityError:
  708. * @ctx: an XML parser context
  709. * @msg: the message to display/transmit
  710. * @...: extra parameters for the message display
  711. *
  712. * Display and format an validity error messages, gives file,
  713. * line, position and extra parameters.
  714. */
  715. void XMLCDECL
  716. xmlParserValidityError(void *ctx, const char *msg, ...)
  717. {
  718. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  719. xmlParserInputPtr input = NULL;
  720. char * str;
  721. int len = xmlStrlen((const xmlChar *) msg);
  722. static int had_info = 0;
  723. if ((len > 1) && (msg[len - 2] != ':')) {
  724. if (ctxt != NULL) {
  725. input = ctxt->input;
  726. if ((input->filename == NULL) && (ctxt->inputNr > 1))
  727. input = ctxt->inputTab[ctxt->inputNr - 2];
  728. if (had_info == 0) {
  729. xmlParserPrintFileInfo(input);
  730. }
  731. }
  732. xmlGenericError(xmlGenericErrorContext, "validity error: ");
  733. had_info = 0;
  734. } else {
  735. had_info = 1;
  736. }
  737. XML_GET_VAR_STR(msg, str);
  738. xmlGenericError(xmlGenericErrorContext, "%s", str);
  739. if (str != NULL)
  740. xmlFree(str);
  741. if ((ctxt != NULL) && (input != NULL)) {
  742. xmlParserPrintFileContext(input);
  743. }
  744. }
  745. /**
  746. * xmlParserValidityWarning:
  747. * @ctx: an XML parser context
  748. * @msg: the message to display/transmit
  749. * @...: extra parameters for the message display
  750. *
  751. * Display and format a validity warning messages, gives file, line,
  752. * position and extra parameters.
  753. */
  754. void XMLCDECL
  755. xmlParserValidityWarning(void *ctx, const char *msg, ...)
  756. {
  757. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  758. xmlParserInputPtr input = NULL;
  759. char * str;
  760. int len = xmlStrlen((const xmlChar *) msg);
  761. if ((ctxt != NULL) && (len != 0) && (msg[len - 1] != ':')) {
  762. input = ctxt->input;
  763. if ((input->filename == NULL) && (ctxt->inputNr > 1))
  764. input = ctxt->inputTab[ctxt->inputNr - 2];
  765. xmlParserPrintFileInfo(input);
  766. }
  767. xmlGenericError(xmlGenericErrorContext, "validity warning: ");
  768. XML_GET_VAR_STR(msg, str);
  769. xmlGenericError(xmlGenericErrorContext, "%s", str);
  770. if (str != NULL)
  771. xmlFree(str);
  772. if (ctxt != NULL) {
  773. xmlParserPrintFileContext(input);
  774. }
  775. }
  776. /************************************************************************
  777. * *
  778. * Extended Error Handling *
  779. * *
  780. ************************************************************************/
  781. /**
  782. * xmlGetLastError:
  783. *
  784. * Get the last global error registered. This is per thread if compiled
  785. * with thread support.
  786. *
  787. * Returns NULL if no error occured or a pointer to the error
  788. */
  789. xmlErrorPtr
  790. xmlGetLastError(void)
  791. {
  792. if (xmlLastError.code == XML_ERR_OK)
  793. return (NULL);
  794. return (&xmlLastError);
  795. }
  796. /**
  797. * xmlResetError:
  798. * @err: pointer to the error.
  799. *
  800. * Cleanup the error.
  801. */
  802. void
  803. xmlResetError(xmlErrorPtr err)
  804. {
  805. if (err == NULL)
  806. return;
  807. if (err->code == XML_ERR_OK)
  808. return;
  809. if (err->message != NULL)
  810. xmlFree(err->message);
  811. if (err->file != NULL)
  812. xmlFree(err->file);
  813. if (err->str1 != NULL)
  814. xmlFree(err->str1);
  815. if (err->str2 != NULL)
  816. xmlFree(err->str2);
  817. if (err->str3 != NULL)
  818. xmlFree(err->str3);
  819. memset(err, 0, sizeof(xmlError));
  820. err->code = XML_ERR_OK;
  821. }
  822. /**
  823. * xmlResetLastError:
  824. *
  825. * Cleanup the last global error registered. For parsing error
  826. * this does not change the well-formedness result.
  827. */
  828. void
  829. xmlResetLastError(void)
  830. {
  831. if (xmlLastError.code == XML_ERR_OK)
  832. return;
  833. xmlResetError(&xmlLastError);
  834. }
  835. /**
  836. * xmlCtxtGetLastError:
  837. * @ctx: an XML parser context
  838. *
  839. * Get the last parsing error registered.
  840. *
  841. * Returns NULL if no error occured or a pointer to the error
  842. */
  843. xmlErrorPtr
  844. xmlCtxtGetLastError(void *ctx)
  845. {
  846. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  847. if (ctxt == NULL)
  848. return (NULL);
  849. if (ctxt->lastError.code == XML_ERR_OK)
  850. return (NULL);
  851. return (&ctxt->lastError);
  852. }
  853. /**
  854. * xmlCtxtResetLastError:
  855. * @ctx: an XML parser context
  856. *
  857. * Cleanup the last global error registered. For parsing error
  858. * this does not change the well-formedness result.
  859. */
  860. void
  861. xmlCtxtResetLastError(void *ctx)
  862. {
  863. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  864. if (ctxt == NULL)
  865. return;
  866. if (ctxt->lastError.code == XML_ERR_OK)
  867. return;
  868. xmlResetError(&ctxt->lastError);
  869. }
  870. /**
  871. * xmlCopyError:
  872. * @from: a source error
  873. * @to: a target error
  874. *
  875. * Save the original error to the new place.
  876. *
  877. * Returns 0 in case of success and -1 in case of error.
  878. */
  879. int
  880. xmlCopyError(xmlErrorPtr from, xmlErrorPtr to) {
  881. char *message, *file, *str1, *str2, *str3;
  882. if ((from == NULL) || (to == NULL))
  883. return(-1);
  884. message = (char *) xmlStrdup((xmlChar *) from->message);
  885. file = (char *) xmlStrdup ((xmlChar *) from->file);
  886. str1 = (char *) xmlStrdup ((xmlChar *) from->str1);
  887. str2 = (char *) xmlStrdup ((xmlChar *) from->str2);
  888. str3 = (char *) xmlStrdup ((xmlChar *) from->str3);
  889. if (to->message != NULL)
  890. xmlFree(to->message);
  891. if (to->file != NULL)
  892. xmlFree(to->file);
  893. if (to->str1 != NULL)
  894. xmlFree(to->str1);
  895. if (to->str2 != NULL)
  896. xmlFree(to->str2);
  897. if (to->str3 != NULL)
  898. xmlFree(to->str3);
  899. to->domain = from->domain;
  900. to->code = from->code;
  901. to->level = from->level;
  902. to->line = from->line;
  903. to->node = from->node;
  904. to->int1 = from->int1;
  905. to->int2 = from->int2;
  906. to->node = from->node;
  907. to->ctxt = from->ctxt;
  908. to->message = message;
  909. to->file = file;
  910. to->str1 = str1;
  911. to->str2 = str2;
  912. to->str3 = str3;
  913. return 0;
  914. }
  915. #define bottom_error
  916. #include "elfgcchack.h"