PageRenderTime 71ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/third_party/libxml2-2.7.7/xmllint.c

#
C | 3722 lines | 3036 code | 243 blank | 443 comment | 929 complexity | 1aa522b0b00a65af5d43c619f33cf246 MD5 | raw file
Possible License(s): BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * xmllint.c : a small tester program for XML input.
  3. *
  4. * See Copyright for the status of this software.
  5. *
  6. * daniel@veillard.com
  7. */
  8. #include "libxml.h"
  9. #include <string.h>
  10. #include <stdarg.h>
  11. #include <assert.h>
  12. #if defined (_WIN32) && !defined(__CYGWIN__)
  13. #if defined (_MSC_VER) || defined(__BORLANDC__)
  14. #include <winsock2.h>
  15. #pragma comment(lib, "ws2_32.lib")
  16. #define gettimeofday(p1,p2)
  17. #endif /* _MSC_VER */
  18. #endif /* _WIN32 */
  19. #ifdef HAVE_SYS_TIME_H
  20. #include <sys/time.h>
  21. #endif
  22. #ifdef HAVE_TIME_H
  23. #include <time.h>
  24. #endif
  25. #ifdef __MINGW32__
  26. #define _WINSOCKAPI_
  27. #include <wsockcompat.h>
  28. #include <winsock2.h>
  29. #undef XML_SOCKLEN_T
  30. #define XML_SOCKLEN_T unsigned int
  31. #endif
  32. #ifdef HAVE_SYS_TIMEB_H
  33. #include <sys/timeb.h>
  34. #endif
  35. #ifdef HAVE_SYS_TYPES_H
  36. #include <sys/types.h>
  37. #endif
  38. #ifdef HAVE_SYS_STAT_H
  39. #include <sys/stat.h>
  40. #endif
  41. #ifdef HAVE_FCNTL_H
  42. #include <fcntl.h>
  43. #endif
  44. #ifdef HAVE_UNISTD_H
  45. #include <unistd.h>
  46. #endif
  47. #ifdef HAVE_SYS_MMAN_H
  48. #include <sys/mman.h>
  49. /* seems needed for Solaris */
  50. #ifndef MAP_FAILED
  51. #define MAP_FAILED ((void *) -1)
  52. #endif
  53. #endif
  54. #ifdef HAVE_STDLIB_H
  55. #include <stdlib.h>
  56. #endif
  57. #ifdef HAVE_LIBREADLINE
  58. #include <readline/readline.h>
  59. #ifdef HAVE_LIBHISTORY
  60. #include <readline/history.h>
  61. #endif
  62. #endif
  63. #include <libxml/xmlmemory.h>
  64. #include <libxml/parser.h>
  65. #include <libxml/parserInternals.h>
  66. #include <libxml/HTMLparser.h>
  67. #include <libxml/HTMLtree.h>
  68. #include <libxml/tree.h>
  69. #include <libxml/xpath.h>
  70. #include <libxml/debugXML.h>
  71. #include <libxml/xmlerror.h>
  72. #ifdef LIBXML_XINCLUDE_ENABLED
  73. #include <libxml/xinclude.h>
  74. #endif
  75. #ifdef LIBXML_CATALOG_ENABLED
  76. #include <libxml/catalog.h>
  77. #endif
  78. #include <libxml/globals.h>
  79. #include <libxml/xmlreader.h>
  80. #ifdef LIBXML_SCHEMATRON_ENABLED
  81. #include <libxml/schematron.h>
  82. #endif
  83. #ifdef LIBXML_SCHEMAS_ENABLED
  84. #include <libxml/relaxng.h>
  85. #include <libxml/xmlschemas.h>
  86. #endif
  87. #ifdef LIBXML_PATTERN_ENABLED
  88. #include <libxml/pattern.h>
  89. #endif
  90. #ifdef LIBXML_C14N_ENABLED
  91. #include <libxml/c14n.h>
  92. #endif
  93. #ifdef LIBXML_OUTPUT_ENABLED
  94. #include <libxml/xmlsave.h>
  95. #endif
  96. #ifndef XML_XML_DEFAULT_CATALOG
  97. #define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
  98. #endif
  99. typedef enum {
  100. XMLLINT_RETURN_OK = 0, /* No error */
  101. XMLLINT_ERR_UNCLASS = 1, /* Unclassified */
  102. XMLLINT_ERR_DTD = 2, /* Error in DTD */
  103. XMLLINT_ERR_VALID = 3, /* Validation error */
  104. XMLLINT_ERR_RDFILE = 4, /* CtxtReadFile error */
  105. XMLLINT_ERR_SCHEMACOMP = 5, /* Schema compilation */
  106. XMLLINT_ERR_OUT = 6, /* Error writing output */
  107. XMLLINT_ERR_SCHEMAPAT = 7, /* Error in schema pattern */
  108. XMLLINT_ERR_RDREGIS = 8, /* Error in Reader registration */
  109. XMLLINT_ERR_MEM = 9, /* Out of memory error */
  110. XMLLINT_ERR_XPATH = 10 /* XPath evaluation error */
  111. } xmllintReturnCode;
  112. #ifdef LIBXML_DEBUG_ENABLED
  113. static int shell = 0;
  114. static int debugent = 0;
  115. #endif
  116. static int debug = 0;
  117. static int maxmem = 0;
  118. #ifdef LIBXML_TREE_ENABLED
  119. static int copy = 0;
  120. #endif /* LIBXML_TREE_ENABLED */
  121. static int recovery = 0;
  122. static int noent = 0;
  123. static int noblanks = 0;
  124. static int noout = 0;
  125. static int nowrap = 0;
  126. #ifdef LIBXML_OUTPUT_ENABLED
  127. static int format = 0;
  128. static const char *output = NULL;
  129. static int compress = 0;
  130. static int oldout = 0;
  131. #endif /* LIBXML_OUTPUT_ENABLED */
  132. #ifdef LIBXML_VALID_ENABLED
  133. static int valid = 0;
  134. static int postvalid = 0;
  135. static char * dtdvalid = NULL;
  136. static char * dtdvalidfpi = NULL;
  137. #endif
  138. #ifdef LIBXML_SCHEMAS_ENABLED
  139. static char * relaxng = NULL;
  140. static xmlRelaxNGPtr relaxngschemas = NULL;
  141. static char * schema = NULL;
  142. static xmlSchemaPtr wxschemas = NULL;
  143. #endif
  144. #ifdef LIBXML_SCHEMATRON_ENABLED
  145. static char * schematron = NULL;
  146. static xmlSchematronPtr wxschematron = NULL;
  147. #endif
  148. static int repeat = 0;
  149. static int insert = 0;
  150. #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
  151. static int html = 0;
  152. static int xmlout = 0;
  153. #endif
  154. static int htmlout = 0;
  155. #ifdef LIBXML_PUSH_ENABLED
  156. static int push = 0;
  157. #endif /* LIBXML_PUSH_ENABLED */
  158. #ifdef HAVE_SYS_MMAN_H
  159. static int memory = 0;
  160. #endif
  161. static int testIO = 0;
  162. static char *encoding = NULL;
  163. #ifdef LIBXML_XINCLUDE_ENABLED
  164. static int xinclude = 0;
  165. #endif
  166. static int dtdattrs = 0;
  167. static int loaddtd = 0;
  168. static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
  169. static int timing = 0;
  170. static int generate = 0;
  171. static int dropdtd = 0;
  172. #ifdef LIBXML_CATALOG_ENABLED
  173. static int catalogs = 0;
  174. static int nocatalogs = 0;
  175. #endif
  176. #ifdef LIBXML_C14N_ENABLED
  177. static int canonical = 0;
  178. static int canonical_11 = 0;
  179. static int exc_canonical = 0;
  180. #endif
  181. #ifdef LIBXML_READER_ENABLED
  182. static int stream = 0;
  183. static int walker = 0;
  184. #endif /* LIBXML_READER_ENABLED */
  185. static int chkregister = 0;
  186. static int nbregister = 0;
  187. #ifdef LIBXML_SAX1_ENABLED
  188. static int sax1 = 0;
  189. #endif /* LIBXML_SAX1_ENABLED */
  190. #ifdef LIBXML_PATTERN_ENABLED
  191. static const char *pattern = NULL;
  192. static xmlPatternPtr patternc = NULL;
  193. static xmlStreamCtxtPtr patstream = NULL;
  194. #endif
  195. #ifdef LIBXML_XPATH_ENABLED
  196. static const char *xpathquery = NULL;
  197. #endif
  198. static int options = XML_PARSE_COMPACT;
  199. static int sax = 0;
  200. static int oldxml10 = 0;
  201. /************************************************************************
  202. * *
  203. * Entity loading control and customization. *
  204. * *
  205. ************************************************************************/
  206. #define MAX_PATHS 64
  207. #ifdef _WIN32
  208. # define PATH_SEPARATOR ';'
  209. #else
  210. # define PATH_SEPARATOR ':'
  211. #endif
  212. static xmlChar *paths[MAX_PATHS + 1];
  213. static int nbpaths = 0;
  214. static int load_trace = 0;
  215. static
  216. void parsePath(const xmlChar *path) {
  217. const xmlChar *cur;
  218. if (path == NULL)
  219. return;
  220. while (*path != 0) {
  221. if (nbpaths >= MAX_PATHS) {
  222. fprintf(stderr, "MAX_PATHS reached: too many paths\n");
  223. return;
  224. }
  225. cur = path;
  226. while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
  227. cur++;
  228. path = cur;
  229. while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
  230. cur++;
  231. if (cur != path) {
  232. paths[nbpaths] = xmlStrndup(path, cur - path);
  233. if (paths[nbpaths] != NULL)
  234. nbpaths++;
  235. path = cur;
  236. }
  237. }
  238. }
  239. static xmlExternalEntityLoader defaultEntityLoader = NULL;
  240. static xmlParserInputPtr
  241. xmllintExternalEntityLoader(const char *URL, const char *ID,
  242. xmlParserCtxtPtr ctxt) {
  243. xmlParserInputPtr ret;
  244. warningSAXFunc warning = NULL;
  245. errorSAXFunc err = NULL;
  246. int i;
  247. const char *lastsegment = URL;
  248. const char *iter = URL;
  249. if ((nbpaths > 0) && (iter != NULL)) {
  250. while (*iter != 0) {
  251. if (*iter == '/')
  252. lastsegment = iter + 1;
  253. iter++;
  254. }
  255. }
  256. if ((ctxt != NULL) && (ctxt->sax != NULL)) {
  257. warning = ctxt->sax->warning;
  258. err = ctxt->sax->error;
  259. ctxt->sax->warning = NULL;
  260. ctxt->sax->error = NULL;
  261. }
  262. if (defaultEntityLoader != NULL) {
  263. ret = defaultEntityLoader(URL, ID, ctxt);
  264. if (ret != NULL) {
  265. if (warning != NULL)
  266. ctxt->sax->warning = warning;
  267. if (err != NULL)
  268. ctxt->sax->error = err;
  269. if (load_trace) {
  270. fprintf \
  271. (stderr,
  272. "Loaded URL=\"%s\" ID=\"%s\"\n",
  273. URL ? URL : "(null)",
  274. ID ? ID : "(null)");
  275. }
  276. return(ret);
  277. }
  278. }
  279. for (i = 0;i < nbpaths;i++) {
  280. xmlChar *newURL;
  281. newURL = xmlStrdup((const xmlChar *) paths[i]);
  282. newURL = xmlStrcat(newURL, (const xmlChar *) "/");
  283. newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
  284. if (newURL != NULL) {
  285. ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
  286. if (ret != NULL) {
  287. if (warning != NULL)
  288. ctxt->sax->warning = warning;
  289. if (err != NULL)
  290. ctxt->sax->error = err;
  291. if (load_trace) {
  292. fprintf \
  293. (stderr,
  294. "Loaded URL=\"%s\" ID=\"%s\"\n",
  295. newURL,
  296. ID ? ID : "(null)");
  297. }
  298. xmlFree(newURL);
  299. return(ret);
  300. }
  301. xmlFree(newURL);
  302. }
  303. }
  304. if (err != NULL)
  305. ctxt->sax->error = err;
  306. if (warning != NULL) {
  307. ctxt->sax->warning = warning;
  308. if (URL != NULL)
  309. warning(ctxt, "failed to load external entity \"%s\"\n", URL);
  310. else if (ID != NULL)
  311. warning(ctxt, "failed to load external entity \"%s\"\n", ID);
  312. }
  313. return(NULL);
  314. }
  315. /************************************************************************
  316. * *
  317. * Memory allocation consumption debugging *
  318. * *
  319. ************************************************************************/
  320. static void
  321. OOM(void)
  322. {
  323. fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
  324. progresult = XMLLINT_ERR_MEM;
  325. }
  326. static void
  327. myFreeFunc(void *mem)
  328. {
  329. xmlMemFree(mem);
  330. }
  331. static void *
  332. myMallocFunc(size_t size)
  333. {
  334. void *ret;
  335. ret = xmlMemMalloc(size);
  336. if (ret != NULL) {
  337. if (xmlMemUsed() > maxmem) {
  338. OOM();
  339. xmlMemFree(ret);
  340. return (NULL);
  341. }
  342. }
  343. return (ret);
  344. }
  345. static void *
  346. myReallocFunc(void *mem, size_t size)
  347. {
  348. void *ret;
  349. ret = xmlMemRealloc(mem, size);
  350. if (ret != NULL) {
  351. if (xmlMemUsed() > maxmem) {
  352. OOM();
  353. xmlMemFree(ret);
  354. return (NULL);
  355. }
  356. }
  357. return (ret);
  358. }
  359. static char *
  360. myStrdupFunc(const char *str)
  361. {
  362. char *ret;
  363. ret = xmlMemoryStrdup(str);
  364. if (ret != NULL) {
  365. if (xmlMemUsed() > maxmem) {
  366. OOM();
  367. xmlFree(ret);
  368. return (NULL);
  369. }
  370. }
  371. return (ret);
  372. }
  373. /************************************************************************
  374. * *
  375. * Internal timing routines to remove the necessity to have *
  376. * unix-specific function calls. *
  377. * *
  378. ************************************************************************/
  379. #ifndef HAVE_GETTIMEOFDAY
  380. #ifdef HAVE_SYS_TIMEB_H
  381. #ifdef HAVE_SYS_TIME_H
  382. #ifdef HAVE_FTIME
  383. static int
  384. my_gettimeofday(struct timeval *tvp, void *tzp)
  385. {
  386. struct timeb timebuffer;
  387. ftime(&timebuffer);
  388. if (tvp) {
  389. tvp->tv_sec = timebuffer.time;
  390. tvp->tv_usec = timebuffer.millitm * 1000L;
  391. }
  392. return (0);
  393. }
  394. #define HAVE_GETTIMEOFDAY 1
  395. #define gettimeofday my_gettimeofday
  396. #endif /* HAVE_FTIME */
  397. #endif /* HAVE_SYS_TIME_H */
  398. #endif /* HAVE_SYS_TIMEB_H */
  399. #endif /* !HAVE_GETTIMEOFDAY */
  400. #if defined(HAVE_GETTIMEOFDAY)
  401. static struct timeval begin, end;
  402. /*
  403. * startTimer: call where you want to start timing
  404. */
  405. static void
  406. startTimer(void)
  407. {
  408. gettimeofday(&begin, NULL);
  409. }
  410. /*
  411. * endTimer: call where you want to stop timing and to print out a
  412. * message about the timing performed; format is a printf
  413. * type argument
  414. */
  415. static void XMLCDECL
  416. endTimer(const char *fmt, ...)
  417. {
  418. long msec;
  419. va_list ap;
  420. gettimeofday(&end, NULL);
  421. msec = end.tv_sec - begin.tv_sec;
  422. msec *= 1000;
  423. msec += (end.tv_usec - begin.tv_usec) / 1000;
  424. #ifndef HAVE_STDARG_H
  425. #error "endTimer required stdarg functions"
  426. #endif
  427. va_start(ap, fmt);
  428. vfprintf(stderr, fmt, ap);
  429. va_end(ap);
  430. fprintf(stderr, " took %ld ms\n", msec);
  431. }
  432. #elif defined(HAVE_TIME_H)
  433. /*
  434. * No gettimeofday function, so we have to make do with calling clock.
  435. * This is obviously less accurate, but there's little we can do about
  436. * that.
  437. */
  438. #ifndef CLOCKS_PER_SEC
  439. #define CLOCKS_PER_SEC 100
  440. #endif
  441. static clock_t begin, end;
  442. static void
  443. startTimer(void)
  444. {
  445. begin = clock();
  446. }
  447. static void XMLCDECL
  448. endTimer(const char *fmt, ...)
  449. {
  450. long msec;
  451. va_list ap;
  452. end = clock();
  453. msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
  454. #ifndef HAVE_STDARG_H
  455. #error "endTimer required stdarg functions"
  456. #endif
  457. va_start(ap, fmt);
  458. vfprintf(stderr, fmt, ap);
  459. va_end(ap);
  460. fprintf(stderr, " took %ld ms\n", msec);
  461. }
  462. #else
  463. /*
  464. * We don't have a gettimeofday or time.h, so we just don't do timing
  465. */
  466. static void
  467. startTimer(void)
  468. {
  469. /*
  470. * Do nothing
  471. */
  472. }
  473. static void XMLCDECL
  474. endTimer(char *format, ...)
  475. {
  476. /*
  477. * We cannot do anything because we don't have a timing function
  478. */
  479. #ifdef HAVE_STDARG_H
  480. va_start(ap, format);
  481. vfprintf(stderr, format, ap);
  482. va_end(ap);
  483. fprintf(stderr, " was not timed\n", msec);
  484. #else
  485. /* We don't have gettimeofday, time or stdarg.h, what crazy world is
  486. * this ?!
  487. */
  488. #endif
  489. }
  490. #endif
  491. /************************************************************************
  492. * *
  493. * HTML ouput *
  494. * *
  495. ************************************************************************/
  496. static char buffer[50000];
  497. static void
  498. xmlHTMLEncodeSend(void) {
  499. char *result;
  500. result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
  501. if (result) {
  502. xmlGenericError(xmlGenericErrorContext, "%s", result);
  503. xmlFree(result);
  504. }
  505. buffer[0] = 0;
  506. }
  507. /**
  508. * xmlHTMLPrintFileInfo:
  509. * @input: an xmlParserInputPtr input
  510. *
  511. * Displays the associated file and line informations for the current input
  512. */
  513. static void
  514. xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
  515. int len;
  516. xmlGenericError(xmlGenericErrorContext, "<p>");
  517. len = strlen(buffer);
  518. if (input != NULL) {
  519. if (input->filename) {
  520. snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
  521. input->line);
  522. } else {
  523. snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
  524. }
  525. }
  526. xmlHTMLEncodeSend();
  527. }
  528. /**
  529. * xmlHTMLPrintFileContext:
  530. * @input: an xmlParserInputPtr input
  531. *
  532. * Displays current context within the input content for error tracking
  533. */
  534. static void
  535. xmlHTMLPrintFileContext(xmlParserInputPtr input) {
  536. const xmlChar *cur, *base;
  537. int len;
  538. int n;
  539. if (input == NULL) return;
  540. xmlGenericError(xmlGenericErrorContext, "<pre>\n");
  541. cur = input->cur;
  542. base = input->base;
  543. while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
  544. cur--;
  545. }
  546. n = 0;
  547. while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
  548. cur--;
  549. if ((*cur == '\n') || (*cur == '\r')) cur++;
  550. base = cur;
  551. n = 0;
  552. while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
  553. len = strlen(buffer);
  554. snprintf(&buffer[len], sizeof(buffer) - len, "%c",
  555. (unsigned char) *cur++);
  556. n++;
  557. }
  558. len = strlen(buffer);
  559. snprintf(&buffer[len], sizeof(buffer) - len, "\n");
  560. cur = input->cur;
  561. while ((*cur == '\n') || (*cur == '\r'))
  562. cur--;
  563. n = 0;
  564. while ((cur != base) && (n++ < 80)) {
  565. len = strlen(buffer);
  566. snprintf(&buffer[len], sizeof(buffer) - len, " ");
  567. base++;
  568. }
  569. len = strlen(buffer);
  570. snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
  571. xmlHTMLEncodeSend();
  572. xmlGenericError(xmlGenericErrorContext, "</pre>");
  573. }
  574. /**
  575. * xmlHTMLError:
  576. * @ctx: an XML parser context
  577. * @msg: the message to display/transmit
  578. * @...: extra parameters for the message display
  579. *
  580. * Display and format an error messages, gives file, line, position and
  581. * extra parameters.
  582. */
  583. static void XMLCDECL
  584. xmlHTMLError(void *ctx, const char *msg, ...)
  585. {
  586. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  587. xmlParserInputPtr input;
  588. va_list args;
  589. int len;
  590. buffer[0] = 0;
  591. input = ctxt->input;
  592. if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
  593. input = ctxt->inputTab[ctxt->inputNr - 2];
  594. }
  595. xmlHTMLPrintFileInfo(input);
  596. xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
  597. va_start(args, msg);
  598. len = strlen(buffer);
  599. vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
  600. va_end(args);
  601. xmlHTMLEncodeSend();
  602. xmlGenericError(xmlGenericErrorContext, "</p>\n");
  603. xmlHTMLPrintFileContext(input);
  604. xmlHTMLEncodeSend();
  605. }
  606. /**
  607. * xmlHTMLWarning:
  608. * @ctx: an XML parser context
  609. * @msg: the message to display/transmit
  610. * @...: extra parameters for the message display
  611. *
  612. * Display and format a warning messages, gives file, line, position and
  613. * extra parameters.
  614. */
  615. static void XMLCDECL
  616. xmlHTMLWarning(void *ctx, const char *msg, ...)
  617. {
  618. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  619. xmlParserInputPtr input;
  620. va_list args;
  621. int len;
  622. buffer[0] = 0;
  623. input = ctxt->input;
  624. if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
  625. input = ctxt->inputTab[ctxt->inputNr - 2];
  626. }
  627. xmlHTMLPrintFileInfo(input);
  628. xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
  629. va_start(args, msg);
  630. len = strlen(buffer);
  631. vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
  632. va_end(args);
  633. xmlHTMLEncodeSend();
  634. xmlGenericError(xmlGenericErrorContext, "</p>\n");
  635. xmlHTMLPrintFileContext(input);
  636. xmlHTMLEncodeSend();
  637. }
  638. /**
  639. * xmlHTMLValidityError:
  640. * @ctx: an XML parser context
  641. * @msg: the message to display/transmit
  642. * @...: extra parameters for the message display
  643. *
  644. * Display and format an validity error messages, gives file,
  645. * line, position and extra parameters.
  646. */
  647. static void XMLCDECL
  648. xmlHTMLValidityError(void *ctx, const char *msg, ...)
  649. {
  650. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  651. xmlParserInputPtr input;
  652. va_list args;
  653. int len;
  654. buffer[0] = 0;
  655. input = ctxt->input;
  656. if ((input->filename == NULL) && (ctxt->inputNr > 1))
  657. input = ctxt->inputTab[ctxt->inputNr - 2];
  658. xmlHTMLPrintFileInfo(input);
  659. xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
  660. len = strlen(buffer);
  661. va_start(args, msg);
  662. vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
  663. va_end(args);
  664. xmlHTMLEncodeSend();
  665. xmlGenericError(xmlGenericErrorContext, "</p>\n");
  666. xmlHTMLPrintFileContext(input);
  667. xmlHTMLEncodeSend();
  668. progresult = XMLLINT_ERR_VALID;
  669. }
  670. /**
  671. * xmlHTMLValidityWarning:
  672. * @ctx: an XML parser context
  673. * @msg: the message to display/transmit
  674. * @...: extra parameters for the message display
  675. *
  676. * Display and format a validity warning messages, gives file, line,
  677. * position and extra parameters.
  678. */
  679. static void XMLCDECL
  680. xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
  681. {
  682. xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  683. xmlParserInputPtr input;
  684. va_list args;
  685. int len;
  686. buffer[0] = 0;
  687. input = ctxt->input;
  688. if ((input->filename == NULL) && (ctxt->inputNr > 1))
  689. input = ctxt->inputTab[ctxt->inputNr - 2];
  690. xmlHTMLPrintFileInfo(input);
  691. xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
  692. va_start(args, msg);
  693. len = strlen(buffer);
  694. vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
  695. va_end(args);
  696. xmlHTMLEncodeSend();
  697. xmlGenericError(xmlGenericErrorContext, "</p>\n");
  698. xmlHTMLPrintFileContext(input);
  699. xmlHTMLEncodeSend();
  700. }
  701. /************************************************************************
  702. * *
  703. * Shell Interface *
  704. * *
  705. ************************************************************************/
  706. #ifdef LIBXML_DEBUG_ENABLED
  707. #ifdef LIBXML_XPATH_ENABLED
  708. /**
  709. * xmlShellReadline:
  710. * @prompt: the prompt value
  711. *
  712. * Read a string
  713. *
  714. * Returns a pointer to it or NULL on EOF the caller is expected to
  715. * free the returned string.
  716. */
  717. static char *
  718. xmlShellReadline(char *prompt) {
  719. #ifdef HAVE_LIBREADLINE
  720. char *line_read;
  721. /* Get a line from the user. */
  722. line_read = readline (prompt);
  723. /* If the line has any text in it, save it on the history. */
  724. if (line_read && *line_read)
  725. add_history (line_read);
  726. return (line_read);
  727. #else
  728. char line_read[501];
  729. char *ret;
  730. int len;
  731. if (prompt != NULL)
  732. fprintf(stdout, "%s", prompt);
  733. if (!fgets(line_read, 500, stdin))
  734. return(NULL);
  735. line_read[500] = 0;
  736. len = strlen(line_read);
  737. ret = (char *) malloc(len + 1);
  738. if (ret != NULL) {
  739. memcpy (ret, line_read, len + 1);
  740. }
  741. return(ret);
  742. #endif
  743. }
  744. #endif /* LIBXML_XPATH_ENABLED */
  745. #endif /* LIBXML_DEBUG_ENABLED */
  746. /************************************************************************
  747. * *
  748. * I/O Interfaces *
  749. * *
  750. ************************************************************************/
  751. static int myRead(FILE *f, char * buf, int len) {
  752. return(fread(buf, 1, len, f));
  753. }
  754. static void myClose(FILE *f) {
  755. if (f != stdin) {
  756. fclose(f);
  757. }
  758. }
  759. /************************************************************************
  760. * *
  761. * SAX based tests *
  762. * *
  763. ************************************************************************/
  764. /*
  765. * empty SAX block
  766. */
  767. static xmlSAXHandler emptySAXHandlerStruct = {
  768. NULL, /* internalSubset */
  769. NULL, /* isStandalone */
  770. NULL, /* hasInternalSubset */
  771. NULL, /* hasExternalSubset */
  772. NULL, /* resolveEntity */
  773. NULL, /* getEntity */
  774. NULL, /* entityDecl */
  775. NULL, /* notationDecl */
  776. NULL, /* attributeDecl */
  777. NULL, /* elementDecl */
  778. NULL, /* unparsedEntityDecl */
  779. NULL, /* setDocumentLocator */
  780. NULL, /* startDocument */
  781. NULL, /* endDocument */
  782. NULL, /* startElement */
  783. NULL, /* endElement */
  784. NULL, /* reference */
  785. NULL, /* characters */
  786. NULL, /* ignorableWhitespace */
  787. NULL, /* processingInstruction */
  788. NULL, /* comment */
  789. NULL, /* xmlParserWarning */
  790. NULL, /* xmlParserError */
  791. NULL, /* xmlParserError */
  792. NULL, /* getParameterEntity */
  793. NULL, /* cdataBlock; */
  794. NULL, /* externalSubset; */
  795. XML_SAX2_MAGIC,
  796. NULL,
  797. NULL, /* startElementNs */
  798. NULL, /* endElementNs */
  799. NULL /* xmlStructuredErrorFunc */
  800. };
  801. static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
  802. extern xmlSAXHandlerPtr debugSAXHandler;
  803. static int callbacks;
  804. /**
  805. * isStandaloneDebug:
  806. * @ctxt: An XML parser context
  807. *
  808. * Is this document tagged standalone ?
  809. *
  810. * Returns 1 if true
  811. */
  812. static int
  813. isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
  814. {
  815. callbacks++;
  816. if (noout)
  817. return(0);
  818. fprintf(stdout, "SAX.isStandalone()\n");
  819. return(0);
  820. }
  821. /**
  822. * hasInternalSubsetDebug:
  823. * @ctxt: An XML parser context
  824. *
  825. * Does this document has an internal subset
  826. *
  827. * Returns 1 if true
  828. */
  829. static int
  830. hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
  831. {
  832. callbacks++;
  833. if (noout)
  834. return(0);
  835. fprintf(stdout, "SAX.hasInternalSubset()\n");
  836. return(0);
  837. }
  838. /**
  839. * hasExternalSubsetDebug:
  840. * @ctxt: An XML parser context
  841. *
  842. * Does this document has an external subset
  843. *
  844. * Returns 1 if true
  845. */
  846. static int
  847. hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
  848. {
  849. callbacks++;
  850. if (noout)
  851. return(0);
  852. fprintf(stdout, "SAX.hasExternalSubset()\n");
  853. return(0);
  854. }
  855. /**
  856. * internalSubsetDebug:
  857. * @ctxt: An XML parser context
  858. *
  859. * Does this document has an internal subset
  860. */
  861. static void
  862. internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
  863. const xmlChar *ExternalID, const xmlChar *SystemID)
  864. {
  865. callbacks++;
  866. if (noout)
  867. return;
  868. fprintf(stdout, "SAX.internalSubset(%s,", name);
  869. if (ExternalID == NULL)
  870. fprintf(stdout, " ,");
  871. else
  872. fprintf(stdout, " %s,", ExternalID);
  873. if (SystemID == NULL)
  874. fprintf(stdout, " )\n");
  875. else
  876. fprintf(stdout, " %s)\n", SystemID);
  877. }
  878. /**
  879. * externalSubsetDebug:
  880. * @ctxt: An XML parser context
  881. *
  882. * Does this document has an external subset
  883. */
  884. static void
  885. externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
  886. const xmlChar *ExternalID, const xmlChar *SystemID)
  887. {
  888. callbacks++;
  889. if (noout)
  890. return;
  891. fprintf(stdout, "SAX.externalSubset(%s,", name);
  892. if (ExternalID == NULL)
  893. fprintf(stdout, " ,");
  894. else
  895. fprintf(stdout, " %s,", ExternalID);
  896. if (SystemID == NULL)
  897. fprintf(stdout, " )\n");
  898. else
  899. fprintf(stdout, " %s)\n", SystemID);
  900. }
  901. /**
  902. * resolveEntityDebug:
  903. * @ctxt: An XML parser context
  904. * @publicId: The public ID of the entity
  905. * @systemId: The system ID of the entity
  906. *
  907. * Special entity resolver, better left to the parser, it has
  908. * more context than the application layer.
  909. * The default behaviour is to NOT resolve the entities, in that case
  910. * the ENTITY_REF nodes are built in the structure (and the parameter
  911. * values).
  912. *
  913. * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
  914. */
  915. static xmlParserInputPtr
  916. resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
  917. {
  918. callbacks++;
  919. if (noout)
  920. return(NULL);
  921. /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
  922. fprintf(stdout, "SAX.resolveEntity(");
  923. if (publicId != NULL)
  924. fprintf(stdout, "%s", (char *)publicId);
  925. else
  926. fprintf(stdout, " ");
  927. if (systemId != NULL)
  928. fprintf(stdout, ", %s)\n", (char *)systemId);
  929. else
  930. fprintf(stdout, ", )\n");
  931. return(NULL);
  932. }
  933. /**
  934. * getEntityDebug:
  935. * @ctxt: An XML parser context
  936. * @name: The entity name
  937. *
  938. * Get an entity by name
  939. *
  940. * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
  941. */
  942. static xmlEntityPtr
  943. getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
  944. {
  945. callbacks++;
  946. if (noout)
  947. return(NULL);
  948. fprintf(stdout, "SAX.getEntity(%s)\n", name);
  949. return(NULL);
  950. }
  951. /**
  952. * getParameterEntityDebug:
  953. * @ctxt: An XML parser context
  954. * @name: The entity name
  955. *
  956. * Get a parameter entity by name
  957. *
  958. * Returns the xmlParserInputPtr
  959. */
  960. static xmlEntityPtr
  961. getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
  962. {
  963. callbacks++;
  964. if (noout)
  965. return(NULL);
  966. fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
  967. return(NULL);
  968. }
  969. /**
  970. * entityDeclDebug:
  971. * @ctxt: An XML parser context
  972. * @name: the entity name
  973. * @type: the entity type
  974. * @publicId: The public ID of the entity
  975. * @systemId: The system ID of the entity
  976. * @content: the entity value (without processing).
  977. *
  978. * An entity definition has been parsed
  979. */
  980. static void
  981. entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
  982. const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
  983. {
  984. const xmlChar *nullstr = BAD_CAST "(null)";
  985. /* not all libraries handle printing null pointers nicely */
  986. if (publicId == NULL)
  987. publicId = nullstr;
  988. if (systemId == NULL)
  989. systemId = nullstr;
  990. if (content == NULL)
  991. content = (xmlChar *)nullstr;
  992. callbacks++;
  993. if (noout)
  994. return;
  995. fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
  996. name, type, publicId, systemId, content);
  997. }
  998. /**
  999. * attributeDeclDebug:
  1000. * @ctxt: An XML parser context
  1001. * @name: the attribute name
  1002. * @type: the attribute type
  1003. *
  1004. * An attribute definition has been parsed
  1005. */
  1006. static void
  1007. attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
  1008. const xmlChar * name, int type, int def,
  1009. const xmlChar * defaultValue, xmlEnumerationPtr tree)
  1010. {
  1011. callbacks++;
  1012. if (noout)
  1013. return;
  1014. if (defaultValue == NULL)
  1015. fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
  1016. elem, name, type, def);
  1017. else
  1018. fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
  1019. elem, name, type, def, defaultValue);
  1020. xmlFreeEnumeration(tree);
  1021. }
  1022. /**
  1023. * elementDeclDebug:
  1024. * @ctxt: An XML parser context
  1025. * @name: the element name
  1026. * @type: the element type
  1027. * @content: the element value (without processing).
  1028. *
  1029. * An element definition has been parsed
  1030. */
  1031. static void
  1032. elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
  1033. xmlElementContentPtr content ATTRIBUTE_UNUSED)
  1034. {
  1035. callbacks++;
  1036. if (noout)
  1037. return;
  1038. fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
  1039. name, type);
  1040. }
  1041. /**
  1042. * notationDeclDebug:
  1043. * @ctxt: An XML parser context
  1044. * @name: The name of the notation
  1045. * @publicId: The public ID of the entity
  1046. * @systemId: The system ID of the entity
  1047. *
  1048. * What to do when a notation declaration has been parsed.
  1049. */
  1050. static void
  1051. notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
  1052. const xmlChar *publicId, const xmlChar *systemId)
  1053. {
  1054. callbacks++;
  1055. if (noout)
  1056. return;
  1057. fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
  1058. (char *) name, (char *) publicId, (char *) systemId);
  1059. }
  1060. /**
  1061. * unparsedEntityDeclDebug:
  1062. * @ctxt: An XML parser context
  1063. * @name: The name of the entity
  1064. * @publicId: The public ID of the entity
  1065. * @systemId: The system ID of the entity
  1066. * @notationName: the name of the notation
  1067. *
  1068. * What to do when an unparsed entity declaration is parsed
  1069. */
  1070. static void
  1071. unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
  1072. const xmlChar *publicId, const xmlChar *systemId,
  1073. const xmlChar *notationName)
  1074. {
  1075. const xmlChar *nullstr = BAD_CAST "(null)";
  1076. if (publicId == NULL)
  1077. publicId = nullstr;
  1078. if (systemId == NULL)
  1079. systemId = nullstr;
  1080. if (notationName == NULL)
  1081. notationName = nullstr;
  1082. callbacks++;
  1083. if (noout)
  1084. return;
  1085. fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
  1086. (char *) name, (char *) publicId, (char *) systemId,
  1087. (char *) notationName);
  1088. }
  1089. /**
  1090. * setDocumentLocatorDebug:
  1091. * @ctxt: An XML parser context
  1092. * @loc: A SAX Locator
  1093. *
  1094. * Receive the document locator at startup, actually xmlDefaultSAXLocator
  1095. * Everything is available on the context, so this is useless in our case.
  1096. */
  1097. static void
  1098. setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
  1099. {
  1100. callbacks++;
  1101. if (noout)
  1102. return;
  1103. fprintf(stdout, "SAX.setDocumentLocator()\n");
  1104. }
  1105. /**
  1106. * startDocumentDebug:
  1107. * @ctxt: An XML parser context
  1108. *
  1109. * called when the document start being processed.
  1110. */
  1111. static void
  1112. startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
  1113. {
  1114. callbacks++;
  1115. if (noout)
  1116. return;
  1117. fprintf(stdout, "SAX.startDocument()\n");
  1118. }
  1119. /**
  1120. * endDocumentDebug:
  1121. * @ctxt: An XML parser context
  1122. *
  1123. * called when the document end has been detected.
  1124. */
  1125. static void
  1126. endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
  1127. {
  1128. callbacks++;
  1129. if (noout)
  1130. return;
  1131. fprintf(stdout, "SAX.endDocument()\n");
  1132. }
  1133. /**
  1134. * startElementDebug:
  1135. * @ctxt: An XML parser context
  1136. * @name: The element name
  1137. *
  1138. * called when an opening tag has been processed.
  1139. */
  1140. static void
  1141. startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
  1142. {
  1143. int i;
  1144. callbacks++;
  1145. if (noout)
  1146. return;
  1147. fprintf(stdout, "SAX.startElement(%s", (char *) name);
  1148. if (atts != NULL) {
  1149. for (i = 0;(atts[i] != NULL);i++) {
  1150. fprintf(stdout, ", %s='", atts[i++]);
  1151. if (atts[i] != NULL)
  1152. fprintf(stdout, "%s'", atts[i]);
  1153. }
  1154. }
  1155. fprintf(stdout, ")\n");
  1156. }
  1157. /**
  1158. * endElementDebug:
  1159. * @ctxt: An XML parser context
  1160. * @name: The element name
  1161. *
  1162. * called when the end of an element has been detected.
  1163. */
  1164. static void
  1165. endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
  1166. {
  1167. callbacks++;
  1168. if (noout)
  1169. return;
  1170. fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
  1171. }
  1172. /**
  1173. * charactersDebug:
  1174. * @ctxt: An XML parser context
  1175. * @ch: a xmlChar string
  1176. * @len: the number of xmlChar
  1177. *
  1178. * receiving some chars from the parser.
  1179. * Question: how much at a time ???
  1180. */
  1181. static void
  1182. charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
  1183. {
  1184. char out[40];
  1185. int i;
  1186. callbacks++;
  1187. if (noout)
  1188. return;
  1189. for (i = 0;(i<len) && (i < 30);i++)
  1190. out[i] = ch[i];
  1191. out[i] = 0;
  1192. fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
  1193. }
  1194. /**
  1195. * referenceDebug:
  1196. * @ctxt: An XML parser context
  1197. * @name: The entity name
  1198. *
  1199. * called when an entity reference is detected.
  1200. */
  1201. static void
  1202. referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
  1203. {
  1204. callbacks++;
  1205. if (noout)
  1206. return;
  1207. fprintf(stdout, "SAX.reference(%s)\n", name);
  1208. }
  1209. /**
  1210. * ignorableWhitespaceDebug:
  1211. * @ctxt: An XML parser context
  1212. * @ch: a xmlChar string
  1213. * @start: the first char in the string
  1214. * @len: the number of xmlChar
  1215. *
  1216. * receiving some ignorable whitespaces from the parser.
  1217. * Question: how much at a time ???
  1218. */
  1219. static void
  1220. ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
  1221. {
  1222. char out[40];
  1223. int i;
  1224. callbacks++;
  1225. if (noout)
  1226. return;
  1227. for (i = 0;(i<len) && (i < 30);i++)
  1228. out[i] = ch[i];
  1229. out[i] = 0;
  1230. fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
  1231. }
  1232. /**
  1233. * processingInstructionDebug:
  1234. * @ctxt: An XML parser context
  1235. * @target: the target name
  1236. * @data: the PI data's
  1237. * @len: the number of xmlChar
  1238. *
  1239. * A processing instruction has been parsed.
  1240. */
  1241. static void
  1242. processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
  1243. const xmlChar *data)
  1244. {
  1245. callbacks++;
  1246. if (noout)
  1247. return;
  1248. if (data != NULL)
  1249. fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
  1250. (char *) target, (char *) data);
  1251. else
  1252. fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
  1253. (char *) target);
  1254. }
  1255. /**
  1256. * cdataBlockDebug:
  1257. * @ctx: the user data (XML parser context)
  1258. * @value: The pcdata content
  1259. * @len: the block length
  1260. *
  1261. * called when a pcdata block has been parsed
  1262. */
  1263. static void
  1264. cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
  1265. {
  1266. callbacks++;
  1267. if (noout)
  1268. return;
  1269. fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
  1270. (char *) value, len);
  1271. }
  1272. /**
  1273. * commentDebug:
  1274. * @ctxt: An XML parser context
  1275. * @value: the comment content
  1276. *
  1277. * A comment has been parsed.
  1278. */
  1279. static void
  1280. commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
  1281. {
  1282. callbacks++;
  1283. if (noout)
  1284. return;
  1285. fprintf(stdout, "SAX.comment(%s)\n", value);
  1286. }
  1287. /**
  1288. * warningDebug:
  1289. * @ctxt: An XML parser context
  1290. * @msg: the message to display/transmit
  1291. * @...: extra parameters for the message display
  1292. *
  1293. * Display and format a warning messages, gives file, line, position and
  1294. * extra parameters.
  1295. */
  1296. static void XMLCDECL
  1297. warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
  1298. {
  1299. va_list args;
  1300. callbacks++;
  1301. if (noout)
  1302. return;
  1303. va_start(args, msg);
  1304. fprintf(stdout, "SAX.warning: ");
  1305. vfprintf(stdout, msg, args);
  1306. va_end(args);
  1307. }
  1308. /**
  1309. * errorDebug:
  1310. * @ctxt: An XML parser context
  1311. * @msg: the message to display/transmit
  1312. * @...: extra parameters for the message display
  1313. *
  1314. * Display and format a error messages, gives file, line, position and
  1315. * extra parameters.
  1316. */
  1317. static void XMLCDECL
  1318. errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
  1319. {
  1320. va_list args;
  1321. callbacks++;
  1322. if (noout)
  1323. return;
  1324. va_start(args, msg);
  1325. fprintf(stdout, "SAX.error: ");
  1326. vfprintf(stdout, msg, args);
  1327. va_end(args);
  1328. }
  1329. /**
  1330. * fatalErrorDebug:
  1331. * @ctxt: An XML parser context
  1332. * @msg: the message to display/transmit
  1333. * @...: extra parameters for the message display
  1334. *
  1335. * Display and format a fatalError messages, gives file, line, position and
  1336. * extra parameters.
  1337. */
  1338. static void XMLCDECL
  1339. fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
  1340. {
  1341. va_list args;
  1342. callbacks++;
  1343. if (noout)
  1344. return;
  1345. va_start(args, msg);
  1346. fprintf(stdout, "SAX.fatalError: ");
  1347. vfprintf(stdout, msg, args);
  1348. va_end(args);
  1349. }
  1350. static xmlSAXHandler debugSAXHandlerStruct = {
  1351. internalSubsetDebug,
  1352. isStandaloneDebug,
  1353. hasInternalSubsetDebug,
  1354. hasExternalSubsetDebug,
  1355. resolveEntityDebug,
  1356. getEntityDebug,
  1357. entityDeclDebug,
  1358. notationDeclDebug,
  1359. attributeDeclDebug,
  1360. elementDeclDebug,
  1361. unparsedEntityDeclDebug,
  1362. setDocumentLocatorDebug,
  1363. startDocumentDebug,
  1364. endDocumentDebug,
  1365. startElementDebug,
  1366. endElementDebug,
  1367. referenceDebug,
  1368. charactersDebug,
  1369. ignorableWhitespaceDebug,
  1370. processingInstructionDebug,
  1371. commentDebug,
  1372. warningDebug,
  1373. errorDebug,
  1374. fatalErrorDebug,
  1375. getParameterEntityDebug,
  1376. cdataBlockDebug,
  1377. externalSubsetDebug,
  1378. 1,
  1379. NULL,
  1380. NULL,
  1381. NULL,
  1382. NULL
  1383. };
  1384. xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
  1385. /*
  1386. * SAX2 specific callbacks
  1387. */
  1388. /**
  1389. * startElementNsDebug:
  1390. * @ctxt: An XML parser context
  1391. * @name: The element name
  1392. *
  1393. * called when an opening tag has been processed.
  1394. */
  1395. static void
  1396. startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
  1397. const xmlChar *localname,
  1398. const xmlChar *prefix,
  1399. const xmlChar *URI,
  1400. int nb_namespaces,
  1401. const xmlChar **namespaces,
  1402. int nb_attributes,
  1403. int nb_defaulted,
  1404. const xmlChar **attributes)
  1405. {
  1406. int i;
  1407. callbacks++;
  1408. if (noout)
  1409. return;
  1410. fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
  1411. if (prefix == NULL)
  1412. fprintf(stdout, ", NULL");
  1413. else
  1414. fprintf(stdout, ", %s", (char *) prefix);
  1415. if (URI == NULL)
  1416. fprintf(stdout, ", NULL");
  1417. else
  1418. fprintf(stdout, ", '%s'", (char *) URI);
  1419. fprintf(stdout, ", %d", nb_namespaces);
  1420. if (namespaces != NULL) {
  1421. for (i = 0;i < nb_namespaces * 2;i++) {
  1422. fprintf(stdout, ", xmlns");
  1423. if (namespaces[i] != NULL)
  1424. fprintf(stdout, ":%s", namespaces[i]);
  1425. i++;
  1426. fprintf(stdout, "='%s'", namespaces[i]);
  1427. }
  1428. }
  1429. fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
  1430. if (attributes != NULL) {
  1431. for (i = 0;i < nb_attributes * 5;i += 5) {
  1432. if (attributes[i + 1] != NULL)
  1433. fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
  1434. else
  1435. fprintf(stdout, ", %s='", attributes[i]);
  1436. fprintf(stdout, "%.4s...', %d", attributes[i + 3],
  1437. (int)(attributes[i + 4] - attributes[i + 3]));
  1438. }
  1439. }
  1440. fprintf(stdout, ")\n");
  1441. }
  1442. /**
  1443. * endElementDebug:
  1444. * @ctxt: An XML parser context
  1445. * @name: The element name
  1446. *
  1447. * called when the end of an element has been detected.
  1448. */
  1449. static void
  1450. endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
  1451. const xmlChar *localname,
  1452. const xmlChar *prefix,
  1453. const xmlChar *URI)
  1454. {
  1455. callbacks++;
  1456. if (noout)
  1457. return;
  1458. fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
  1459. if (prefix == NULL)
  1460. fprintf(stdout, ", NULL");
  1461. else
  1462. fprintf(stdout, ", %s", (char *) prefix);
  1463. if (URI == NULL)
  1464. fprintf(stdout, ", NULL)\n");
  1465. else
  1466. fprintf(stdout, ", '%s')\n", (char *) URI);
  1467. }
  1468. static xmlSAXHandler debugSAX2HandlerStruct = {
  1469. internalSubsetDebug,
  1470. isStandaloneDebug,
  1471. hasInternalSubsetDebug,
  1472. hasExternalSubsetDebug,
  1473. resolveEntityDebug,
  1474. getEntityDebug,
  1475. entityDeclDebug,
  1476. notationDeclDebug,
  1477. attributeDeclDebug,
  1478. elementDeclDebug,
  1479. unparsedEntityDeclDebug,
  1480. setDocumentLocatorDebug,
  1481. startDocumentDebug,
  1482. endDocumentDebug,
  1483. NULL,
  1484. NULL,
  1485. referenceDebug,
  1486. charactersDebug,
  1487. ignorableWhitespaceDebug,
  1488. processingInstructionDebug,
  1489. commentDebug,
  1490. warningDebug,
  1491. errorDebug,
  1492. fatalErrorDebug,
  1493. getParameterEntityDebug,
  1494. cdataBlockDebug,
  1495. externalSubsetDebug,
  1496. XML_SAX2_MAGIC,
  1497. NULL,
  1498. startElementNsDebug,
  1499. endElementNsDebug,
  1500. NULL
  1501. };
  1502. static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
  1503. static void
  1504. testSAX(const char *filename) {
  1505. xmlSAXHandlerPtr handler;
  1506. const char *user_data = "user_data"; /* mostly for debugging */
  1507. xmlParserInputBufferPtr buf = NULL;
  1508. xmlParserInputPtr inputStream;
  1509. xmlParserCtxtPtr ctxt = NULL;
  1510. xmlSAXHandlerPtr old_sax = NULL;
  1511. callbacks = 0;
  1512. if (noout) {
  1513. handler = emptySAXHandler;
  1514. #ifdef LIBXML_SAX1_ENABLED
  1515. } else if (sax1) {
  1516. handler = debugSAXHandler;
  1517. #endif
  1518. } else {
  1519. handler = debugSAX2Handler;
  1520. }
  1521. /*
  1522. * it's not the simplest code but the most generic in term of I/O
  1523. */
  1524. buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
  1525. if (buf == NULL) {
  1526. goto error;
  1527. }
  1528. #ifdef LIBXML_SCHEMAS_ENABLED
  1529. if (wxschemas != NULL) {
  1530. int ret;
  1531. xmlSchemaValidCtxtPtr vctxt;
  1532. vctxt = xmlSchemaNewValidCtxt(wxschemas);
  1533. xmlSchemaSetValidErrors(vctxt,
  1534. (xmlSchemaValidityErrorFunc) fprintf,
  1535. (xmlSchemaValidityWarningFunc) fprintf,
  1536. stderr);
  1537. ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
  1538. (void *)user_data);
  1539. if (repeat == 0) {
  1540. if (ret == 0) {
  1541. fprintf(stderr, "%s validates\n", filename);
  1542. } else if (ret > 0) {
  1543. fprintf(stderr, "%s fails to validate\n", filename);
  1544. progresult = XMLLINT_ERR_VALID;
  1545. } else {
  1546. fprintf(stderr, "%s validation generated an internal error\n",
  1547. filename);
  1548. progresult = XMLLINT_ERR_VALID;
  1549. }
  1550. }
  1551. xmlSchemaFreeValidCtxt(vctxt);
  1552. } else
  1553. #endif
  1554. {
  1555. /*
  1556. * Create the parser context amd hook the input
  1557. */
  1558. ctxt = xmlNewParserCtxt();
  1559. if (ctxt == NULL) {
  1560. xmlFreeParserInputBuffer(buf);
  1561. goto error;
  1562. }
  1563. old_sax = ctxt->sax;
  1564. ctxt->sax = handler;
  1565. ctxt->userData = (void *) user_data;
  1566. inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
  1567. if (inputStream == NULL) {
  1568. xmlFreeParserInputBuffer(buf);
  1569. goto error;
  1570. }
  1571. inputPush(ctxt, inputStream);
  1572. /* do the parsing */
  1573. xmlParseDocument(ctxt);
  1574. if (ctxt->myDoc != NULL) {
  1575. fprintf(stderr, "SAX generated a doc !\n");
  1576. xmlFreeDoc(ctxt->myDoc);
  1577. ctxt->myDoc = NULL;
  1578. }
  1579. }
  1580. error:
  1581. if (ctxt != NULL) {
  1582. ctxt->sax = old_sax;
  1583. xmlFreeParserCtxt(ctxt);
  1584. }
  1585. }
  1586. /************************************************************************
  1587. * *
  1588. * Stream Test processing *
  1589. * *
  1590. ************************************************************************/
  1591. #ifdef LIBXML_READER_ENABLED
  1592. static void processNode(xmlTextReaderPtr reader) {
  1593. const xmlChar *name, *value;
  1594. int type, empty;
  1595. type = xmlTextReaderNodeType(reader);
  1596. empty = xmlTextReaderIsEmptyElement(reader);
  1597. if (debug) {
  1598. name = xmlTextReaderConstName(reader);
  1599. if (name == NULL)
  1600. name = BAD_CAST "--";
  1601. value = xmlTextReaderConstValue(reader);
  1602. printf("%d %d %s %d %d",
  1603. xmlTextReaderDepth(reader),
  1604. type,
  1605. name,
  1606. empty,
  1607. xmlTextReaderHasValue(reader));
  1608. if (value == NULL)
  1609. printf("\n");
  1610. else {
  1611. printf(" %s\n", value);
  1612. }
  1613. }
  1614. #ifdef LIBXML_PATTERN_ENABLED
  1615. if (patternc) {
  1616. xmlChar *path = NULL;
  1617. int match = -1;
  1618. if (type == XML_READER_TYPE_ELEMENT) {
  1619. /* do the check only on element start */
  1620. match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
  1621. if (match) {
  1622. #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
  1623. path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
  1624. printf("Node %s matches pattern %s\n", path, pattern);
  1625. #else
  1626. printf("Node %s matches pattern %s\n",
  1627. xmlTextReaderConstName(reader), pattern);
  1628. #endif
  1629. }
  1630. }
  1631. if (patstream != NULL) {
  1632. int ret;
  1633. if (type == XML_READER_TYPE_ELEMENT) {
  1634. ret = xmlStreamPush(patstream,
  1635. xmlTextReaderConstLocalName(reader),
  1636. xmlTextReaderConstNamespaceUri(reader));
  1637. if (ret < 0) {
  1638. fprintf(stderr, "xmlStreamPush() failure\n");
  1639. xmlFreeStreamCtxt(patstream);
  1640. patstream = NULL;
  1641. } else if (ret != match) {
  1642. #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
  1643. if (path == NULL) {
  1644. path = xmlGetNodePath(
  1645. xmlTextReaderCurrentNode(reader));
  1646. }
  1647. #endif
  1648. fprintf(stderr,
  1649. "xmlPatternMatch and xmlStreamPush disagree\n");
  1650. if (path != NULL)
  1651. fprintf(stderr, " pattern %s node %s\n",
  1652. pattern, path);
  1653. else
  1654. fprintf(stderr, " pattern %s node %s\n",
  1655. pattern, xmlTextReaderConstName(reader));
  1656. }
  1657. }
  1658. if ((type == XML_READER_TYPE_END_ELEMENT) ||
  1659. ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
  1660. ret = xmlStreamPop(patstream);
  1661. if (ret < 0) {
  1662. fprintf(stderr, "xmlStreamPop() failure\n");
  1663. xmlFreeStreamCtxt(patstream);
  1664. patstream = NULL;
  1665. }
  1666. }
  1667. }
  1668. if (path != NULL)
  1669. xmlFree(path);
  1670. }
  1671. #endif
  1672. }
  1673. static void streamFile(char *filename) {
  1674. xmlTextReaderPtr reader;
  1675. int ret;
  1676. #ifdef HAVE_SYS_MMAN_H
  1677. int fd = -1;
  1678. struct stat info;
  1679. const char *base = NULL;
  1680. xmlParserInputBufferPtr input = NULL;
  1681. if (memory) {
  1682. if (stat(filename, &info) < 0)
  1683. return;
  1684. if ((fd = open(filename, O_RDONLY)) < 0)
  1685. return;
  1686. base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
  1687. if (base == (void *) MAP_FAILED)
  1688. return;
  1689. reader = xmlReaderForMemory(base, info.st_size, filename,
  1690. NULL, options);
  1691. } else
  1692. #endif
  1693. reader = xmlReaderForFile(filename, NULL, options);
  1694. #ifdef LIBXML_PATTERN_ENABLED
  1695. if (pattern != NULL) {
  1696. patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
  1697. if (patternc == NULL) {
  1698. xmlGenericError(xmlGenericErrorContext,
  1699. "Pattern %s failed to compile\n", pattern);
  1700. progresult = XMLLINT_ERR_SCHEMAPAT;
  1701. pattern = NULL;
  1702. }
  1703. }
  1704. if (patternc != NULL) {
  1705. patstream = xmlPatternGetStreamCtxt(patternc);
  1706. if (patstream != NULL) {
  1707. ret = xmlStreamPush(patstream, NULL, NULL);
  1708. if (ret < 0) {
  1709. fprintf(stderr, "xmlStreamPush() failure\n");
  1710. xmlFreeStreamCtxt(patstream);
  1711. patstream = NULL;
  1712. }
  1713. }
  1714. }
  1715. #endif
  1716. if (reader != NULL) {
  1717. #ifdef LIBXML_VALID_ENABLED
  1718. if (valid)
  1719. xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
  1720. else
  1721. #endif /* LIBXML_VALID_ENABLED */
  1722. xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
  1723. #ifdef LIBXML_SCHEMAS_ENABLED
  1724. if (relaxng != NULL) {
  1725. if ((timing) && (!repeat)) {
  1726. startTimer();
  1727. }
  1728. ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
  1729. if (ret < 0) {
  1730. xmlGenericError(xmlGenericErrorContext,
  1731. "Relax-NG schema %s failed to compile\n", relaxng);
  1732. progresult = XMLLINT_ERR_SCHEMACOMP;
  1733. relaxng = NULL;
  1734. }
  1735. if ((timing) && (!repeat)) {
  1736. endTimer("Compiling the schemas");
  1737. }
  1738. }
  1739. if (schema != NULL) {
  1740. if ((timing) && (!repeat)) {
  1741. startTimer();
  1742. }
  1743. ret = xmlTextReaderSchemaValidate(reader, schema);
  1744. if (ret < 0) {
  1745. xmlGenericError(xmlGenericErrorContext,
  1746. "XSD schema %s failed to compile\n", schema);
  1747. progresult = XMLLINT_ERR_SCHEMACOMP;
  1748. schema = NULL;
  1749. }
  1750. if ((timing) && (!repeat)) {
  1751. endTimer("Compiling the schemas");
  1752. }
  1753. }
  1754. #endif
  1755. /*
  1756. * Process all nodes in sequence
  1757. */
  1758. if ((timing) && (!repeat)) {
  1759. startTimer();
  1760. }
  1761. ret = xmlTextReaderRead(reader);
  1762. while (ret == 1) {
  1763. if ((debug)
  1764. #ifdef LIBXML_PATTERN_ENABLED
  1765. || (patternc)
  1766. #endif
  1767. )
  1768. processNode(reader);
  1769. ret = xmlTextReaderRead(reader);
  1770. }
  1771. if ((timing) && (!repeat)) {
  1772. #ifdef LIBXML_SCHEMAS_ENABLED
  1773. if (relaxng != NULL)
  1774. endTimer("Parsing and validating");
  1775. else
  1776. #endif
  1777. #ifdef LIBXML_VALID_ENABLED
  1778. if (valid)
  1779. endTimer("Parsing and validating");
  1780. else
  1781. #endif
  1782. endTimer("Parsing");
  1783. }
  1784. #ifdef LIBXML_VALID_ENABLED
  1785. if (valid) {
  1786. if (xmlTextReaderIsValid(reader) != 1) {
  1787. xmlGenericError(xmlGenericErrorContext,
  1788. "Document %s does not validate\n", filename);
  1789. progresult = XMLLINT_ERR_VALID;
  1790. }
  1791. }
  1792. #endif /* LIBXML_VALID_ENABLED */
  1793. #ifdef LIBXML_SCHEMAS_ENABLED
  1794. if ((relaxng != NULL) || (schema != NULL)) {
  1795. if (xmlTextReaderIsValid(reader) != 1) {
  1796. fprintf(stderr, "%s fails to validate\n", filename);
  1797. progresult = XMLLINT_ERR_VALID;
  1798. } else {
  1799. fprintf(stderr, "%s validates\n", filename);
  1800. }
  1801. }
  1802. #endif
  1803. /*
  1804. * Done, cleanup and status
  1805. */
  1806. xmlFreeTextReader(reader);
  1807. if (ret != 0) {
  1808. fprintf(stderr, "%s : failed to parse\n", filename);
  1809. progresult = XMLLINT_ERR_UNCLASS;
  1810. }
  1811. } else {
  1812. fprintf(stderr, "Unable to open %s\n", filename);
  1813. progresult = XMLLINT_ERR_UNCLASS;
  1814. }
  1815. #ifdef LIBXML_PATTERN_ENABLED
  1816. if (patstream != NULL) {
  1817. xmlFreeStreamCtxt(patstream);
  1818. patstream = NULL;
  1819. }
  1820. #endif
  1821. #ifdef HAVE_SYS_MMAN_H
  1822. if (memory) {
  1823. xmlFreeParserInputBuffer(input);
  1824. munmap((char *) base, info.st_size);
  1825. close(fd);
  1826. }
  1827. #endif
  1828. }
  1829. static void walkDoc(xmlDocPtr doc) {
  1830. xmlTextReaderPtr reader;
  1831. int ret;
  1832. #ifdef LIBXML_PATTERN_ENABLED
  1833. xmlNodePtr root;
  1834. const xmlChar *namespaces[22];
  1835. int i;
  1836. xmlNsPtr ns;
  1837. root = xmlDocGetRootElement(doc);
  1838. for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
  1839. namespaces[i++] = ns->href;
  1840. namespaces[i++] = ns->prefix;
  1841. }
  1842. namespaces[i++] = NULL;
  1843. namespaces[i] = NULL;
  1844. if (pattern != NULL) {
  1845. patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
  1846. 0, &namespaces[0]);
  1847. if (patternc == NULL) {
  1848. xmlGenericError(xmlGenericErrorContext,
  1849. "Pattern %s failed to compile\n", pattern);
  1850. progresult = XMLLINT_ERR_SCHEMAPAT;
  1851. pattern = NULL;
  1852. }
  1853. }
  1854. if (patternc != NULL) {
  1855. patstream = xmlPatternGetStreamCtxt(patternc);
  1856. if (patstream != NULL) {
  1857. ret = xmlStreamPush(patstream, NULL, NULL);
  1858. if (ret < 0) {
  1859. fprintf(stderr, "xmlStreamPush() failure\n");
  1860. xmlFreeStreamCtxt(patstream);
  1861. patstream = NULL;
  1862. }
  1863. }
  1864. }
  1865. #endif /* LIBXML_PATTERN_ENABLED */
  1866. reader = xmlReaderWalker(doc);
  1867. if (reader != NULL) {
  1868. if ((timing) && (!repeat)) {
  1869. startTimer();
  1870. }
  1871. ret = xmlTextReaderRead(reader);
  1872. while (ret == 1) {
  1873. if ((debug)
  1874. #ifdef LIBXML_PATTERN_ENABLED
  1875. || (patternc)
  1876. #endif
  1877. )
  1878. processNode(reader);
  1879. ret = xmlTextReaderRead(reader);
  1880. }
  1881. if ((timing) && (!repeat)) {
  1882. endTimer("walking through the doc");
  1883. }
  1884. xmlFreeTextReader(reader);
  1885. if (ret != 0) {
  1886. fprintf(stderr, "failed to walk through the doc\n");
  1887. progresult = XMLLINT_ERR_UNCLASS;
  1888. }
  1889. } else {
  1890. fprintf(stderr, "Failed to crate a reader from the document\n");
  1891. progresult = XMLLINT_ERR_UNCLASS;
  1892. }
  1893. #ifdef LIBXML_PATTERN_ENABLED
  1894. if (patstream != NULL) {
  1895. xmlFreeStreamCtxt(patstream);
  1896. patstream = NULL;
  1897. }
  1898. #endif
  1899. }
  1900. #endif /* LIBXML_READER_ENABLED */
  1901. #ifdef LIBXML_XPATH_ENABLED
  1902. /************************************************************************
  1903. * *
  1904. * XPath Query *
  1905. * *
  1906. ************************************************************************/
  1907. static void doXPathDump(xmlXPathObjectPtr cur) {
  1908. switch(cur->type) {
  1909. case XPATH_NODESET: {
  1910. int i;
  1911. xmlNodePtr node;
  1912. #ifdef LIBXML_OUTPUT_ENABLED
  1913. xmlSaveCtxtPtr ctxt;
  1914. if (cur->nodesetval->nodeNr <= 0) {

Large files files are truncated, but you can click here to view the full file