PageRenderTime 69ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/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
  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) {
  1915. fprintf(stderr, "XPath set is empty\n");
  1916. progresult = XMLLINT_ERR_XPATH;
  1917. break;
  1918. }
  1919. ctxt = xmlSaveToFd(1, NULL, 0);
  1920. if (ctxt == NULL) {
  1921. fprintf(stderr, "Out of memory for XPath\n");
  1922. progresult = XMLLINT_ERR_MEM;
  1923. return;
  1924. }
  1925. for (i = 0;i < cur->nodesetval->nodeNr;i++) {
  1926. node = cur->nodesetval->nodeTab[i];
  1927. xmlSaveTree(ctxt, node);
  1928. }
  1929. xmlSaveClose(ctxt);
  1930. #else
  1931. printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
  1932. #endif
  1933. break;
  1934. }
  1935. case XPATH_BOOLEAN:
  1936. if (cur->boolval) printf("true");
  1937. else printf("false");
  1938. break;
  1939. case XPATH_NUMBER:
  1940. switch (xmlXPathIsInf(cur->floatval)) {
  1941. case 1:
  1942. printf("Infinity");
  1943. break;
  1944. case -1:
  1945. printf("-Infinity");
  1946. break;
  1947. default:
  1948. if (xmlXPathIsNaN(cur->floatval)) {
  1949. printf("NaN");
  1950. } else {
  1951. printf("%0g", cur->floatval);
  1952. }
  1953. }
  1954. break;
  1955. case XPATH_STRING:
  1956. printf("%s", (const char *) cur->stringval);
  1957. break;
  1958. case XPATH_UNDEFINED:
  1959. fprintf(stderr, "XPath Object is uninitialized\n");
  1960. progresult = XMLLINT_ERR_XPATH;
  1961. break;
  1962. default:
  1963. fprintf(stderr, "XPath object of unexpected type\n");
  1964. progresult = XMLLINT_ERR_XPATH;
  1965. break;
  1966. }
  1967. }
  1968. static void doXPathQuery(xmlDocPtr doc, const char *query) {
  1969. xmlXPathContextPtr ctxt;
  1970. xmlXPathObjectPtr res;
  1971. ctxt = xmlXPathNewContext(doc);
  1972. if (ctxt == NULL) {
  1973. fprintf(stderr, "Out of memory for XPath\n");
  1974. progresult = XMLLINT_ERR_MEM;
  1975. return;
  1976. }
  1977. ctxt->node = xmlDocGetRootElement(doc);
  1978. res = xmlXPathEval(BAD_CAST query, ctxt);
  1979. xmlXPathFreeContext(ctxt);
  1980. if (res == NULL) {
  1981. fprintf(stderr, "XPath evaluation failure\n");
  1982. progresult = XMLLINT_ERR_XPATH;
  1983. return;
  1984. }
  1985. doXPathDump(res);
  1986. xmlXPathFreeObject(res);
  1987. }
  1988. #endif /* LIBXML_XPATH_ENABLED */
  1989. /************************************************************************
  1990. * *
  1991. * Tree Test processing *
  1992. * *
  1993. ************************************************************************/
  1994. static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
  1995. xmlDocPtr doc = NULL;
  1996. #ifdef LIBXML_TREE_ENABLED
  1997. xmlDocPtr tmp;
  1998. #endif /* LIBXML_TREE_ENABLED */
  1999. if ((timing) && (!repeat))
  2000. startTimer();
  2001. #ifdef LIBXML_TREE_ENABLED
  2002. if (filename == NULL) {
  2003. if (generate) {
  2004. xmlNodePtr n;
  2005. doc = xmlNewDoc(BAD_CAST "1.0");
  2006. n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
  2007. xmlNodeSetContent(n, BAD_CAST "abc");
  2008. xmlDocSetRootElement(doc, n);
  2009. }
  2010. }
  2011. #endif /* LIBXML_TREE_ENABLED */
  2012. #ifdef LIBXML_HTML_ENABLED
  2013. #ifdef LIBXML_PUSH_ENABLED
  2014. else if ((html) && (push)) {
  2015. FILE *f;
  2016. #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
  2017. f = fopen(filename, "rb");
  2018. #else
  2019. f = fopen(filename, "r");
  2020. #endif
  2021. if (f != NULL) {
  2022. int res, size = 3;
  2023. char chars[4096];
  2024. htmlParserCtxtPtr ctxt;
  2025. /* if (repeat) */
  2026. size = 4096;
  2027. res = fread(chars, 1, 4, f);
  2028. if (res > 0) {
  2029. ctxt = htmlCreatePushParserCtxt(NULL, NULL,
  2030. chars, res, filename, XML_CHAR_ENCODING_NONE);
  2031. while ((res = fread(chars, 1, size, f)) > 0) {
  2032. htmlParseChunk(ctxt, chars, res, 0);
  2033. }
  2034. htmlParseChunk(ctxt, chars, 0, 1);
  2035. doc = ctxt->myDoc;
  2036. htmlFreeParserCtxt(ctxt);
  2037. }
  2038. fclose(f);
  2039. }
  2040. }
  2041. #endif /* LIBXML_PUSH_ENABLED */
  2042. #ifdef HAVE_SYS_MMAN_H
  2043. else if ((html) && (memory)) {
  2044. int fd;
  2045. struct stat info;
  2046. const char *base;
  2047. if (stat(filename, &info) < 0)
  2048. return;
  2049. if ((fd = open(filename, O_RDONLY)) < 0)
  2050. return;
  2051. base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
  2052. if (base == (void *) MAP_FAILED)
  2053. return;
  2054. doc = htmlReadMemory((char *) base, info.st_size, filename,
  2055. NULL, options);
  2056. munmap((char *) base, info.st_size);
  2057. close(fd);
  2058. }
  2059. #endif
  2060. else if (html) {
  2061. doc = htmlReadFile(filename, NULL, options);
  2062. }
  2063. #endif /* LIBXML_HTML_ENABLED */
  2064. else {
  2065. #ifdef LIBXML_PUSH_ENABLED
  2066. /*
  2067. * build an XML tree from a string;
  2068. */
  2069. if (push) {
  2070. FILE *f;
  2071. /* '-' Usually means stdin -<sven@zen.org> */
  2072. if ((filename[0] == '-') && (filename[1] == 0)) {
  2073. f = stdin;
  2074. } else {
  2075. #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
  2076. f = fopen(filename, "rb");
  2077. #else
  2078. f = fopen(filename, "r");
  2079. #endif
  2080. }
  2081. if (f != NULL) {
  2082. int ret;
  2083. int res, size = 1024;
  2084. char chars[1024];
  2085. xmlParserCtxtPtr ctxt;
  2086. /* if (repeat) size = 1024; */
  2087. res = fread(chars, 1, 4, f);
  2088. if (res > 0) {
  2089. ctxt = xmlCreatePushParserCtxt(NULL, NULL,
  2090. chars, res, filename);
  2091. xmlCtxtUseOptions(ctxt, options);
  2092. while ((res = fread(chars, 1, size, f)) > 0) {
  2093. xmlParseChunk(ctxt, chars, res, 0);
  2094. }
  2095. xmlParseChunk(ctxt, chars, 0, 1);
  2096. doc = ctxt->myDoc;
  2097. ret = ctxt->wellFormed;
  2098. xmlFreeParserCtxt(ctxt);
  2099. if (!ret) {
  2100. xmlFreeDoc(doc);
  2101. doc = NULL;
  2102. }
  2103. }
  2104. if (f != stdin)
  2105. fclose(f);
  2106. }
  2107. } else
  2108. #endif /* LIBXML_PUSH_ENABLED */
  2109. if (testIO) {
  2110. if ((filename[0] == '-') && (filename[1] == 0)) {
  2111. doc = xmlReadFd(0, NULL, NULL, options);
  2112. } else {
  2113. FILE *f;
  2114. #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
  2115. f = fopen(filename, "rb");
  2116. #else
  2117. f = fopen(filename, "r");
  2118. #endif
  2119. if (f != NULL) {
  2120. if (rectxt == NULL)
  2121. doc = xmlReadIO((xmlInputReadCallback) myRead,
  2122. (xmlInputCloseCallback) myClose, f,
  2123. filename, NULL, options);
  2124. else
  2125. doc = xmlCtxtReadIO(rectxt,
  2126. (xmlInputReadCallback) myRead,
  2127. (xmlInputCloseCallback) myClose, f,
  2128. filename, NULL, options);
  2129. } else
  2130. doc = NULL;
  2131. }
  2132. } else if (htmlout) {
  2133. xmlParserCtxtPtr ctxt;
  2134. if (rectxt == NULL)
  2135. ctxt = xmlNewParserCtxt();
  2136. else
  2137. ctxt = rectxt;
  2138. if (ctxt == NULL) {
  2139. doc = NULL;
  2140. } else {
  2141. ctxt->sax->error = xmlHTMLError;
  2142. ctxt->sax->warning = xmlHTMLWarning;
  2143. ctxt->vctxt.error = xmlHTMLValidityError;
  2144. ctxt->vctxt.warning = xmlHTMLValidityWarning;
  2145. doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
  2146. if (rectxt == NULL)
  2147. xmlFreeParserCtxt(ctxt);
  2148. }
  2149. #ifdef HAVE_SYS_MMAN_H
  2150. } else if (memory) {
  2151. int fd;
  2152. struct stat info;
  2153. const char *base;
  2154. if (stat(filename, &info) < 0)
  2155. return;
  2156. if ((fd = open(filename, O_RDONLY)) < 0)
  2157. return;
  2158. base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
  2159. if (base == (void *) MAP_FAILED)
  2160. return;
  2161. if (rectxt == NULL)
  2162. doc = xmlReadMemory((char *) base, info.st_size,
  2163. filename, NULL, options);
  2164. else
  2165. doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
  2166. filename, NULL, options);
  2167. munmap((char *) base, info.st_size);
  2168. close(fd);
  2169. #endif
  2170. #ifdef LIBXML_VALID_ENABLED
  2171. } else if (valid) {
  2172. xmlParserCtxtPtr ctxt = NULL;
  2173. if (rectxt == NULL)
  2174. ctxt = xmlNewParserCtxt();
  2175. else
  2176. ctxt = rectxt;
  2177. if (ctxt == NULL) {
  2178. doc = NULL;
  2179. } else {
  2180. doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
  2181. if (ctxt->valid == 0)
  2182. progresult = XMLLINT_ERR_RDFILE;
  2183. if (rectxt == NULL)
  2184. xmlFreeParserCtxt(ctxt);
  2185. }
  2186. #endif /* LIBXML_VALID_ENABLED */
  2187. } else {
  2188. if (rectxt != NULL)
  2189. doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
  2190. else {
  2191. #ifdef LIBXML_SAX1_ENABLED
  2192. if (sax1)
  2193. doc = xmlParseFile(filename);
  2194. else
  2195. #endif /* LIBXML_SAX1_ENABLED */
  2196. doc = xmlReadFile(filename, NULL, options);
  2197. }
  2198. }
  2199. }
  2200. /*
  2201. * If we don't have a document we might as well give up. Do we
  2202. * want an error message here? <sven@zen.org> */
  2203. if (doc == NULL) {
  2204. progresult = XMLLINT_ERR_UNCLASS;
  2205. return;
  2206. }
  2207. if ((timing) && (!repeat)) {
  2208. endTimer("Parsing");
  2209. }
  2210. /*
  2211. * Remove DOCTYPE nodes
  2212. */
  2213. if (dropdtd) {
  2214. xmlDtdPtr dtd;
  2215. dtd = xmlGetIntSubset(doc);
  2216. if (dtd != NULL) {
  2217. xmlUnlinkNode((xmlNodePtr)dtd);
  2218. xmlFreeDtd(dtd);
  2219. }
  2220. }
  2221. #ifdef LIBXML_XINCLUDE_ENABLED
  2222. if (xinclude) {
  2223. if ((timing) && (!repeat)) {
  2224. startTimer();
  2225. }
  2226. if (xmlXIncludeProcessFlags(doc, options) < 0)
  2227. progresult = XMLLINT_ERR_UNCLASS;
  2228. if ((timing) && (!repeat)) {
  2229. endTimer("Xinclude processing");
  2230. }
  2231. }
  2232. #endif
  2233. #ifdef LIBXML_XPATH_ENABLED
  2234. if (xpathquery != NULL) {
  2235. doXPathQuery(doc, xpathquery);
  2236. }
  2237. #endif
  2238. #ifdef LIBXML_DEBUG_ENABLED
  2239. #ifdef LIBXML_XPATH_ENABLED
  2240. /*
  2241. * shell interaction
  2242. */
  2243. if (shell) {
  2244. xmlXPathOrderDocElems(doc);
  2245. xmlShell(doc, filename, xmlShellReadline, stdout);
  2246. }
  2247. #endif
  2248. #endif
  2249. #ifdef LIBXML_TREE_ENABLED
  2250. /*
  2251. * test intermediate copy if needed.
  2252. */
  2253. if (copy) {
  2254. tmp = doc;
  2255. if (timing) {
  2256. startTimer();
  2257. }
  2258. doc = xmlCopyDoc(doc, 1);
  2259. if (timing) {
  2260. endTimer("Copying");
  2261. }
  2262. if (timing) {
  2263. startTimer();
  2264. }
  2265. xmlFreeDoc(tmp);
  2266. if (timing) {
  2267. endTimer("Freeing original");
  2268. }
  2269. }
  2270. #endif /* LIBXML_TREE_ENABLED */
  2271. #ifdef LIBXML_VALID_ENABLED
  2272. if ((insert) && (!html)) {
  2273. const xmlChar* list[256];
  2274. int nb, i;
  2275. xmlNodePtr node;
  2276. if (doc->children != NULL) {
  2277. node = doc->children;
  2278. while ((node != NULL) && (node->last == NULL)) node = node->next;
  2279. if (node != NULL) {
  2280. nb = xmlValidGetValidElements(node->last, NULL, list, 256);
  2281. if (nb < 0) {
  2282. fprintf(stderr, "could not get valid list of elements\n");
  2283. } else if (nb == 0) {
  2284. fprintf(stderr, "No element can be inserted under root\n");
  2285. } else {
  2286. fprintf(stderr, "%d element types can be inserted under root:\n",
  2287. nb);
  2288. for (i = 0;i < nb;i++) {
  2289. fprintf(stderr, "%s\n", (char *) list[i]);
  2290. }
  2291. }
  2292. }
  2293. }
  2294. }else
  2295. #endif /* LIBXML_VALID_ENABLED */
  2296. #ifdef LIBXML_READER_ENABLED
  2297. if (walker) {
  2298. walkDoc(doc);
  2299. }
  2300. #endif /* LIBXML_READER_ENABLED */
  2301. #ifdef LIBXML_OUTPUT_ENABLED
  2302. if (noout == 0) {
  2303. int ret;
  2304. /*
  2305. * print it.
  2306. */
  2307. #ifdef LIBXML_DEBUG_ENABLED
  2308. if (!debug) {
  2309. #endif
  2310. if ((timing) && (!repeat)) {
  2311. startTimer();
  2312. }
  2313. #ifdef LIBXML_HTML_ENABLED
  2314. if ((html) && (!xmlout)) {
  2315. if (compress) {
  2316. htmlSaveFile(output ? output : "-", doc);
  2317. }
  2318. else if (encoding != NULL) {
  2319. if ( format ) {
  2320. htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
  2321. }
  2322. else {
  2323. htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
  2324. }
  2325. }
  2326. else if (format) {
  2327. htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
  2328. }
  2329. else {
  2330. FILE *out;
  2331. if (output == NULL)
  2332. out = stdout;
  2333. else {
  2334. out = fopen(output,"wb");
  2335. }
  2336. if (out != NULL) {
  2337. if (htmlDocDump(out, doc) < 0)
  2338. progresult = XMLLINT_ERR_OUT;
  2339. if (output != NULL)
  2340. fclose(out);
  2341. } else {
  2342. fprintf(stderr, "failed to open %s\n", output);
  2343. progresult = XMLLINT_ERR_OUT;
  2344. }
  2345. }
  2346. if ((timing) && (!repeat)) {
  2347. endTimer("Saving");
  2348. }
  2349. } else
  2350. #endif
  2351. #ifdef LIBXML_C14N_ENABLED
  2352. if (canonical) {
  2353. xmlChar *result = NULL;
  2354. int size;
  2355. size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
  2356. if (size >= 0) {
  2357. write(1, result, size);
  2358. xmlFree(result);
  2359. } else {
  2360. fprintf(stderr, "Failed to canonicalize\n");
  2361. progresult = XMLLINT_ERR_OUT;
  2362. }
  2363. } else if (canonical) {
  2364. xmlChar *result = NULL;
  2365. int size;
  2366. size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
  2367. if (size >= 0) {
  2368. write(1, result, size);
  2369. xmlFree(result);
  2370. } else {
  2371. fprintf(stderr, "Failed to canonicalize\n");
  2372. progresult = XMLLINT_ERR_OUT;
  2373. }
  2374. } else
  2375. if (exc_canonical) {
  2376. xmlChar *result = NULL;
  2377. int size;
  2378. size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
  2379. if (size >= 0) {
  2380. write(1, result, size);
  2381. xmlFree(result);
  2382. } else {
  2383. fprintf(stderr, "Failed to canonicalize\n");
  2384. progresult = XMLLINT_ERR_OUT;
  2385. }
  2386. } else
  2387. #endif
  2388. #ifdef HAVE_SYS_MMAN_H
  2389. if (memory) {
  2390. xmlChar *result;
  2391. int len;
  2392. if (encoding != NULL) {
  2393. if ( format ) {
  2394. xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
  2395. } else {
  2396. xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
  2397. }
  2398. } else {
  2399. if (format)
  2400. xmlDocDumpFormatMemory(doc, &result, &len, 1);
  2401. else
  2402. xmlDocDumpMemory(doc, &result, &len);
  2403. }
  2404. if (result == NULL) {
  2405. fprintf(stderr, "Failed to save\n");
  2406. progresult = XMLLINT_ERR_OUT;
  2407. } else {
  2408. write(1, result, len);
  2409. xmlFree(result);
  2410. }
  2411. } else
  2412. #endif /* HAVE_SYS_MMAN_H */
  2413. if (compress) {
  2414. xmlSaveFile(output ? output : "-", doc);
  2415. } else if (oldout) {
  2416. if (encoding != NULL) {
  2417. if ( format ) {
  2418. ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
  2419. encoding, 1);
  2420. }
  2421. else {
  2422. ret = xmlSaveFileEnc(output ? output : "-", doc,
  2423. encoding);
  2424. }
  2425. if (ret < 0) {
  2426. fprintf(stderr, "failed save to %s\n",
  2427. output ? output : "-");
  2428. progresult = XMLLINT_ERR_OUT;
  2429. }
  2430. } else if (format) {
  2431. ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
  2432. if (ret < 0) {
  2433. fprintf(stderr, "failed save to %s\n",
  2434. output ? output : "-");
  2435. progresult = XMLLINT_ERR_OUT;
  2436. }
  2437. } else {
  2438. FILE *out;
  2439. if (output == NULL)
  2440. out = stdout;
  2441. else {
  2442. out = fopen(output,"wb");
  2443. }
  2444. if (out != NULL) {
  2445. if (xmlDocDump(out, doc) < 0)
  2446. progresult = XMLLINT_ERR_OUT;
  2447. if (output != NULL)
  2448. fclose(out);
  2449. } else {
  2450. fprintf(stderr, "failed to open %s\n", output);
  2451. progresult = XMLLINT_ERR_OUT;
  2452. }
  2453. }
  2454. } else {
  2455. xmlSaveCtxtPtr ctxt;
  2456. int saveOpts = 0;
  2457. if (format)
  2458. saveOpts |= XML_SAVE_FORMAT;
  2459. #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
  2460. if (xmlout)
  2461. saveOpts |= XML_SAVE_AS_XML;
  2462. #endif
  2463. if (output == NULL)
  2464. ctxt = xmlSaveToFd(1, encoding, saveOpts);
  2465. else
  2466. ctxt = xmlSaveToFilename(output, encoding, saveOpts);
  2467. if (ctxt != NULL) {
  2468. if (xmlSaveDoc(ctxt, doc) < 0) {
  2469. fprintf(stderr, "failed save to %s\n",
  2470. output ? output : "-");
  2471. progresult = XMLLINT_ERR_OUT;
  2472. }
  2473. xmlSaveClose(ctxt);
  2474. } else {
  2475. progresult = XMLLINT_ERR_OUT;
  2476. }
  2477. }
  2478. if ((timing) && (!repeat)) {
  2479. endTimer("Saving");
  2480. }
  2481. #ifdef LIBXML_DEBUG_ENABLED
  2482. } else {
  2483. FILE *out;
  2484. if (output == NULL)
  2485. out = stdout;
  2486. else {
  2487. out = fopen(output,"wb");
  2488. }
  2489. if (out != NULL) {
  2490. xmlDebugDumpDocument(out, doc);
  2491. if (output != NULL)
  2492. fclose(out);
  2493. } else {
  2494. fprintf(stderr, "failed to open %s\n", output);
  2495. progresult = XMLLINT_ERR_OUT;
  2496. }
  2497. }
  2498. #endif
  2499. }
  2500. #endif /* LIBXML_OUTPUT_ENABLED */
  2501. #ifdef LIBXML_VALID_ENABLED
  2502. /*
  2503. * A posteriori validation test
  2504. */
  2505. if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
  2506. xmlDtdPtr dtd;
  2507. if ((timing) && (!repeat)) {
  2508. startTimer();
  2509. }
  2510. if (dtdvalid != NULL)
  2511. dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
  2512. else
  2513. dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
  2514. if ((timing) && (!repeat)) {
  2515. endTimer("Parsing DTD");
  2516. }
  2517. if (dtd == NULL) {
  2518. if (dtdvalid != NULL)
  2519. xmlGenericError(xmlGenericErrorContext,
  2520. "Could not parse DTD %s\n", dtdvalid);
  2521. else
  2522. xmlGenericError(xmlGenericErrorContext,
  2523. "Could not parse DTD %s\n", dtdvalidfpi);
  2524. progresult = XMLLINT_ERR_DTD;
  2525. } else {
  2526. xmlValidCtxtPtr cvp;
  2527. if ((cvp = xmlNewValidCtxt()) == NULL) {
  2528. xmlGenericError(xmlGenericErrorContext,
  2529. "Couldn't allocate validation context\n");
  2530. exit(-1);
  2531. }
  2532. cvp->userData = (void *) stderr;
  2533. cvp->error = (xmlValidityErrorFunc) fprintf;
  2534. cvp->warning = (xmlValidityWarningFunc) fprintf;
  2535. if ((timing) && (!repeat)) {
  2536. startTimer();
  2537. }
  2538. if (!xmlValidateDtd(cvp, doc, dtd)) {
  2539. if (dtdvalid != NULL)
  2540. xmlGenericError(xmlGenericErrorContext,
  2541. "Document %s does not validate against %s\n",
  2542. filename, dtdvalid);
  2543. else
  2544. xmlGenericError(xmlGenericErrorContext,
  2545. "Document %s does not validate against %s\n",
  2546. filename, dtdvalidfpi);
  2547. progresult = XMLLINT_ERR_VALID;
  2548. }
  2549. if ((timing) && (!repeat)) {
  2550. endTimer("Validating against DTD");
  2551. }
  2552. xmlFreeValidCtxt(cvp);
  2553. xmlFreeDtd(dtd);
  2554. }
  2555. } else if (postvalid) {
  2556. xmlValidCtxtPtr cvp;
  2557. if ((cvp = xmlNewValidCtxt()) == NULL) {
  2558. xmlGenericError(xmlGenericErrorContext,
  2559. "Couldn't allocate validation context\n");
  2560. exit(-1);
  2561. }
  2562. if ((timing) && (!repeat)) {
  2563. startTimer();
  2564. }
  2565. cvp->userData = (void *) stderr;
  2566. cvp->error = (xmlValidityErrorFunc) fprintf;
  2567. cvp->warning = (xmlValidityWarningFunc) fprintf;
  2568. if (!xmlValidateDocument(cvp, doc)) {
  2569. xmlGenericError(xmlGenericErrorContext,
  2570. "Document %s does not validate\n", filename);
  2571. progresult = XMLLINT_ERR_VALID;
  2572. }
  2573. if ((timing) && (!repeat)) {
  2574. endTimer("Validating");
  2575. }
  2576. xmlFreeValidCtxt(cvp);
  2577. }
  2578. #endif /* LIBXML_VALID_ENABLED */
  2579. #ifdef LIBXML_SCHEMATRON_ENABLED
  2580. if (wxschematron != NULL) {
  2581. xmlSchematronValidCtxtPtr ctxt;
  2582. int ret;
  2583. int flag;
  2584. if ((timing) && (!repeat)) {
  2585. startTimer();
  2586. }
  2587. if (debug)
  2588. flag = XML_SCHEMATRON_OUT_XML;
  2589. else
  2590. flag = XML_SCHEMATRON_OUT_TEXT;
  2591. if (noout)
  2592. flag |= XML_SCHEMATRON_OUT_QUIET;
  2593. ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
  2594. #if 0
  2595. xmlSchematronSetValidErrors(ctxt,
  2596. (xmlSchematronValidityErrorFunc) fprintf,
  2597. (xmlSchematronValidityWarningFunc) fprintf,
  2598. stderr);
  2599. #endif
  2600. ret = xmlSchematronValidateDoc(ctxt, doc);
  2601. if (ret == 0) {
  2602. fprintf(stderr, "%s validates\n", filename);
  2603. } else if (ret > 0) {
  2604. fprintf(stderr, "%s fails to validate\n", filename);
  2605. progresult = XMLLINT_ERR_VALID;
  2606. } else {
  2607. fprintf(stderr, "%s validation generated an internal error\n",
  2608. filename);
  2609. progresult = XMLLINT_ERR_VALID;
  2610. }
  2611. xmlSchematronFreeValidCtxt(ctxt);
  2612. if ((timing) && (!repeat)) {
  2613. endTimer("Validating");
  2614. }
  2615. }
  2616. #endif
  2617. #ifdef LIBXML_SCHEMAS_ENABLED
  2618. if (relaxngschemas != NULL) {
  2619. xmlRelaxNGValidCtxtPtr ctxt;
  2620. int ret;
  2621. if ((timing) && (!repeat)) {
  2622. startTimer();
  2623. }
  2624. ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
  2625. xmlRelaxNGSetValidErrors(ctxt,
  2626. (xmlRelaxNGValidityErrorFunc) fprintf,
  2627. (xmlRelaxNGValidityWarningFunc) fprintf,
  2628. stderr);
  2629. ret = xmlRelaxNGValidateDoc(ctxt, doc);
  2630. if (ret == 0) {
  2631. fprintf(stderr, "%s validates\n", filename);
  2632. } else if (ret > 0) {
  2633. fprintf(stderr, "%s fails to validate\n", filename);
  2634. progresult = XMLLINT_ERR_VALID;
  2635. } else {
  2636. fprintf(stderr, "%s validation generated an internal error\n",
  2637. filename);
  2638. progresult = XMLLINT_ERR_VALID;
  2639. }
  2640. xmlRelaxNGFreeValidCtxt(ctxt);
  2641. if ((timing) && (!repeat)) {
  2642. endTimer("Validating");
  2643. }
  2644. } else if (wxschemas != NULL) {
  2645. xmlSchemaValidCtxtPtr ctxt;
  2646. int ret;
  2647. if ((timing) && (!repeat)) {
  2648. startTimer();
  2649. }
  2650. ctxt = xmlSchemaNewValidCtxt(wxschemas);
  2651. xmlSchemaSetValidErrors(ctxt,
  2652. (xmlSchemaValidityErrorFunc) fprintf,
  2653. (xmlSchemaValidityWarningFunc) fprintf,
  2654. stderr);
  2655. ret = xmlSchemaValidateDoc(ctxt, doc);
  2656. if (ret == 0) {
  2657. fprintf(stderr, "%s validates\n", filename);
  2658. } else if (ret > 0) {
  2659. fprintf(stderr, "%s fails to validate\n", filename);
  2660. progresult = XMLLINT_ERR_VALID;
  2661. } else {
  2662. fprintf(stderr, "%s validation generated an internal error\n",
  2663. filename);
  2664. progresult = XMLLINT_ERR_VALID;
  2665. }
  2666. xmlSchemaFreeValidCtxt(ctxt);
  2667. if ((timing) && (!repeat)) {
  2668. endTimer("Validating");
  2669. }
  2670. }
  2671. #endif
  2672. #ifdef LIBXML_DEBUG_ENABLED
  2673. #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
  2674. if ((debugent) && (!html))
  2675. xmlDebugDumpEntities(stderr, doc);
  2676. #endif
  2677. #endif
  2678. /*
  2679. * free it.
  2680. */
  2681. if ((timing) && (!repeat)) {
  2682. startTimer();
  2683. }
  2684. xmlFreeDoc(doc);
  2685. if ((timing) && (!repeat)) {
  2686. endTimer("Freeing");
  2687. }
  2688. }
  2689. /************************************************************************
  2690. * *
  2691. * Usage and Main *
  2692. * *
  2693. ************************************************************************/
  2694. static void showVersion(const char *name) {
  2695. fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
  2696. fprintf(stderr, " compiled with: ");
  2697. if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
  2698. if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
  2699. if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
  2700. if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
  2701. if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
  2702. if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
  2703. if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
  2704. if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
  2705. if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
  2706. if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
  2707. if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
  2708. if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
  2709. if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
  2710. if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
  2711. if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
  2712. if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
  2713. if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
  2714. if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
  2715. if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
  2716. if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
  2717. if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
  2718. if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
  2719. if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
  2720. if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
  2721. if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
  2722. if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
  2723. if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
  2724. if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
  2725. if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
  2726. if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
  2727. if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
  2728. fprintf(stderr, "\n");
  2729. }
  2730. static void usage(const char *name) {
  2731. printf("Usage : %s [options] XMLfiles ...\n", name);
  2732. #ifdef LIBXML_OUTPUT_ENABLED
  2733. printf("\tParse the XML files and output the result of the parsing\n");
  2734. #else
  2735. printf("\tParse the XML files\n");
  2736. #endif /* LIBXML_OUTPUT_ENABLED */
  2737. printf("\t--version : display the version of the XML library used\n");
  2738. #ifdef LIBXML_DEBUG_ENABLED
  2739. printf("\t--debug : dump a debug tree of the in-memory document\n");
  2740. printf("\t--shell : run a navigating shell\n");
  2741. printf("\t--debugent : debug the entities defined in the document\n");
  2742. #else
  2743. #ifdef LIBXML_READER_ENABLED
  2744. printf("\t--debug : dump the nodes content when using --stream\n");
  2745. #endif /* LIBXML_READER_ENABLED */
  2746. #endif
  2747. #ifdef LIBXML_TREE_ENABLED
  2748. printf("\t--copy : used to test the internal copy implementation\n");
  2749. #endif /* LIBXML_TREE_ENABLED */
  2750. printf("\t--recover : output what was parsable on broken XML documents\n");
  2751. printf("\t--huge : remove any internal arbitrary parser limits\n");
  2752. printf("\t--noent : substitute entity references by their value\n");
  2753. printf("\t--noout : don't output the result tree\n");
  2754. printf("\t--path 'paths': provide a set of paths for resources\n");
  2755. printf("\t--load-trace : print trace of all external entites loaded\n");
  2756. printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
  2757. printf("\t--nocompact : do not generate compact text nodes\n");
  2758. printf("\t--htmlout : output results as HTML\n");
  2759. printf("\t--nowrap : do not put HTML doc wrapper\n");
  2760. #ifdef LIBXML_VALID_ENABLED
  2761. printf("\t--valid : validate the document in addition to std well-formed check\n");
  2762. printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
  2763. printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
  2764. printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
  2765. #endif /* LIBXML_VALID_ENABLED */
  2766. printf("\t--timing : print some timings\n");
  2767. printf("\t--output file or -o file: save to a given file\n");
  2768. printf("\t--repeat : repeat 100 times, for timing or profiling\n");
  2769. printf("\t--insert : ad-hoc test for valid insertions\n");
  2770. #ifdef LIBXML_OUTPUT_ENABLED
  2771. #ifdef HAVE_ZLIB_H
  2772. printf("\t--compress : turn on gzip compression of output\n");
  2773. #endif
  2774. #endif /* LIBXML_OUTPUT_ENABLED */
  2775. #ifdef LIBXML_HTML_ENABLED
  2776. printf("\t--html : use the HTML parser\n");
  2777. printf("\t--xmlout : force to use the XML serializer when using --html\n");
  2778. #endif
  2779. #ifdef LIBXML_PUSH_ENABLED
  2780. printf("\t--push : use the push mode of the parser\n");
  2781. #endif /* LIBXML_PUSH_ENABLED */
  2782. #ifdef HAVE_SYS_MMAN_H
  2783. printf("\t--memory : parse from memory\n");
  2784. #endif
  2785. printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
  2786. printf("\t--nowarning : do not emit warnings from parser/validator\n");
  2787. printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
  2788. printf("\t--nocdata : replace cdata section with text nodes\n");
  2789. #ifdef LIBXML_OUTPUT_ENABLED
  2790. printf("\t--format : reformat/reindent the input\n");
  2791. printf("\t--encode encoding : output in the given encoding\n");
  2792. printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
  2793. #endif /* LIBXML_OUTPUT_ENABLED */
  2794. printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
  2795. printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
  2796. printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
  2797. #ifdef LIBXML_C14N_ENABLED
  2798. #endif /* LIBXML_C14N_ENABLED */
  2799. printf("\t--nsclean : remove redundant namespace declarations\n");
  2800. printf("\t--testIO : test user I/O support\n");
  2801. #ifdef LIBXML_CATALOG_ENABLED
  2802. printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
  2803. printf("\t otherwise XML Catalogs starting from \n");
  2804. printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
  2805. printf("\t--nocatalogs: deactivate all catalogs\n");
  2806. #endif
  2807. printf("\t--auto : generate a small doc on the fly\n");
  2808. #ifdef LIBXML_XINCLUDE_ENABLED
  2809. printf("\t--xinclude : do XInclude processing\n");
  2810. printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
  2811. printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
  2812. #endif
  2813. printf("\t--loaddtd : fetch external DTD\n");
  2814. printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
  2815. #ifdef LIBXML_READER_ENABLED
  2816. printf("\t--stream : use the streaming interface to process very large files\n");
  2817. printf("\t--walker : create a reader and walk though the resulting doc\n");
  2818. #endif /* LIBXML_READER_ENABLED */
  2819. #ifdef LIBXML_PATTERN_ENABLED
  2820. printf("\t--pattern pattern_value : test the pattern support\n");
  2821. #endif
  2822. printf("\t--chkregister : verify the node registration code\n");
  2823. #ifdef LIBXML_SCHEMAS_ENABLED
  2824. printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
  2825. printf("\t--schema schema : do validation against the WXS schema\n");
  2826. #endif
  2827. #ifdef LIBXML_SCHEMATRON_ENABLED
  2828. printf("\t--schematron schema : do validation against a schematron\n");
  2829. #endif
  2830. #ifdef LIBXML_SAX1_ENABLED
  2831. printf("\t--sax1: use the old SAX1 interfaces for processing\n");
  2832. #endif
  2833. printf("\t--sax: do not build a tree but work just at the SAX level\n");
  2834. printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
  2835. #ifdef LIBXML_XPATH_ENABLED
  2836. printf("\t--xpath expr: evaluate the XPath expression, inply --noout\n");
  2837. #endif
  2838. printf("\nLibxml project home page: http://xmlsoft.org/\n");
  2839. printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
  2840. }
  2841. static void registerNode(xmlNodePtr node)
  2842. {
  2843. node->_private = malloc(sizeof(long));
  2844. *(long*)node->_private = (long) 0x81726354;
  2845. nbregister++;
  2846. }
  2847. static void deregisterNode(xmlNodePtr node)
  2848. {
  2849. assert(node->_private != NULL);
  2850. assert(*(long*)node->_private == (long) 0x81726354);
  2851. free(node->_private);
  2852. nbregister--;
  2853. }
  2854. int
  2855. main(int argc, char **argv) {
  2856. int i, acount;
  2857. int files = 0;
  2858. int version = 0;
  2859. const char* indent;
  2860. if (argc <= 1) {
  2861. usage(argv[0]);
  2862. return(1);
  2863. }
  2864. LIBXML_TEST_VERSION
  2865. for (i = 1; i < argc ; i++) {
  2866. if (!strcmp(argv[i], "-"))
  2867. break;
  2868. if (argv[i][0] != '-')
  2869. continue;
  2870. if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
  2871. debug++;
  2872. else
  2873. #ifdef LIBXML_DEBUG_ENABLED
  2874. if ((!strcmp(argv[i], "-shell")) ||
  2875. (!strcmp(argv[i], "--shell"))) {
  2876. shell++;
  2877. noout = 1;
  2878. } else
  2879. #endif
  2880. #ifdef LIBXML_TREE_ENABLED
  2881. if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
  2882. copy++;
  2883. else
  2884. #endif /* LIBXML_TREE_ENABLED */
  2885. if ((!strcmp(argv[i], "-recover")) ||
  2886. (!strcmp(argv[i], "--recover"))) {
  2887. recovery++;
  2888. options |= XML_PARSE_RECOVER;
  2889. } else if ((!strcmp(argv[i], "-huge")) ||
  2890. (!strcmp(argv[i], "--huge"))) {
  2891. options |= XML_PARSE_HUGE;
  2892. } else if ((!strcmp(argv[i], "-noent")) ||
  2893. (!strcmp(argv[i], "--noent"))) {
  2894. noent++;
  2895. options |= XML_PARSE_NOENT;
  2896. } else if ((!strcmp(argv[i], "-nsclean")) ||
  2897. (!strcmp(argv[i], "--nsclean"))) {
  2898. options |= XML_PARSE_NSCLEAN;
  2899. } else if ((!strcmp(argv[i], "-nocdata")) ||
  2900. (!strcmp(argv[i], "--nocdata"))) {
  2901. options |= XML_PARSE_NOCDATA;
  2902. } else if ((!strcmp(argv[i], "-nodict")) ||
  2903. (!strcmp(argv[i], "--nodict"))) {
  2904. options |= XML_PARSE_NODICT;
  2905. } else if ((!strcmp(argv[i], "-version")) ||
  2906. (!strcmp(argv[i], "--version"))) {
  2907. showVersion(argv[0]);
  2908. version = 1;
  2909. } else if ((!strcmp(argv[i], "-noout")) ||
  2910. (!strcmp(argv[i], "--noout")))
  2911. noout++;
  2912. #ifdef LIBXML_OUTPUT_ENABLED
  2913. else if ((!strcmp(argv[i], "-o")) ||
  2914. (!strcmp(argv[i], "-output")) ||
  2915. (!strcmp(argv[i], "--output"))) {
  2916. i++;
  2917. output = argv[i];
  2918. }
  2919. #endif /* LIBXML_OUTPUT_ENABLED */
  2920. else if ((!strcmp(argv[i], "-htmlout")) ||
  2921. (!strcmp(argv[i], "--htmlout")))
  2922. htmlout++;
  2923. else if ((!strcmp(argv[i], "-nowrap")) ||
  2924. (!strcmp(argv[i], "--nowrap")))
  2925. nowrap++;
  2926. #ifdef LIBXML_HTML_ENABLED
  2927. else if ((!strcmp(argv[i], "-html")) ||
  2928. (!strcmp(argv[i], "--html"))) {
  2929. html++;
  2930. }
  2931. else if ((!strcmp(argv[i], "-xmlout")) ||
  2932. (!strcmp(argv[i], "--xmlout"))) {
  2933. xmlout++;
  2934. }
  2935. #endif /* LIBXML_HTML_ENABLED */
  2936. else if ((!strcmp(argv[i], "-loaddtd")) ||
  2937. (!strcmp(argv[i], "--loaddtd"))) {
  2938. loaddtd++;
  2939. options |= XML_PARSE_DTDLOAD;
  2940. } else if ((!strcmp(argv[i], "-dtdattr")) ||
  2941. (!strcmp(argv[i], "--dtdattr"))) {
  2942. loaddtd++;
  2943. dtdattrs++;
  2944. options |= XML_PARSE_DTDATTR;
  2945. }
  2946. #ifdef LIBXML_VALID_ENABLED
  2947. else if ((!strcmp(argv[i], "-valid")) ||
  2948. (!strcmp(argv[i], "--valid"))) {
  2949. valid++;
  2950. options |= XML_PARSE_DTDVALID;
  2951. } else if ((!strcmp(argv[i], "-postvalid")) ||
  2952. (!strcmp(argv[i], "--postvalid"))) {
  2953. postvalid++;
  2954. loaddtd++;
  2955. options |= XML_PARSE_DTDLOAD;
  2956. } else if ((!strcmp(argv[i], "-dtdvalid")) ||
  2957. (!strcmp(argv[i], "--dtdvalid"))) {
  2958. i++;
  2959. dtdvalid = argv[i];
  2960. loaddtd++;
  2961. options |= XML_PARSE_DTDLOAD;
  2962. } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
  2963. (!strcmp(argv[i], "--dtdvalidfpi"))) {
  2964. i++;
  2965. dtdvalidfpi = argv[i];
  2966. loaddtd++;
  2967. options |= XML_PARSE_DTDLOAD;
  2968. }
  2969. #endif /* LIBXML_VALID_ENABLED */
  2970. else if ((!strcmp(argv[i], "-dropdtd")) ||
  2971. (!strcmp(argv[i], "--dropdtd")))
  2972. dropdtd++;
  2973. else if ((!strcmp(argv[i], "-insert")) ||
  2974. (!strcmp(argv[i], "--insert")))
  2975. insert++;
  2976. else if ((!strcmp(argv[i], "-timing")) ||
  2977. (!strcmp(argv[i], "--timing")))
  2978. timing++;
  2979. else if ((!strcmp(argv[i], "-auto")) ||
  2980. (!strcmp(argv[i], "--auto")))
  2981. generate++;
  2982. else if ((!strcmp(argv[i], "-repeat")) ||
  2983. (!strcmp(argv[i], "--repeat"))) {
  2984. if (repeat)
  2985. repeat *= 10;
  2986. else
  2987. repeat = 100;
  2988. }
  2989. #ifdef LIBXML_PUSH_ENABLED
  2990. else if ((!strcmp(argv[i], "-push")) ||
  2991. (!strcmp(argv[i], "--push")))
  2992. push++;
  2993. #endif /* LIBXML_PUSH_ENABLED */
  2994. #ifdef HAVE_SYS_MMAN_H
  2995. else if ((!strcmp(argv[i], "-memory")) ||
  2996. (!strcmp(argv[i], "--memory")))
  2997. memory++;
  2998. #endif
  2999. else if ((!strcmp(argv[i], "-testIO")) ||
  3000. (!strcmp(argv[i], "--testIO")))
  3001. testIO++;
  3002. #ifdef LIBXML_XINCLUDE_ENABLED
  3003. else if ((!strcmp(argv[i], "-xinclude")) ||
  3004. (!strcmp(argv[i], "--xinclude"))) {
  3005. xinclude++;
  3006. options |= XML_PARSE_XINCLUDE;
  3007. }
  3008. else if ((!strcmp(argv[i], "-noxincludenode")) ||
  3009. (!strcmp(argv[i], "--noxincludenode"))) {
  3010. xinclude++;
  3011. options |= XML_PARSE_XINCLUDE;
  3012. options |= XML_PARSE_NOXINCNODE;
  3013. }
  3014. else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
  3015. (!strcmp(argv[i], "--nofixup-base-uris"))) {
  3016. xinclude++;
  3017. options |= XML_PARSE_XINCLUDE;
  3018. options |= XML_PARSE_NOBASEFIX;
  3019. }
  3020. #endif
  3021. #ifdef LIBXML_OUTPUT_ENABLED
  3022. #ifdef HAVE_ZLIB_H
  3023. else if ((!strcmp(argv[i], "-compress")) ||
  3024. (!strcmp(argv[i], "--compress"))) {
  3025. compress++;
  3026. xmlSetCompressMode(9);
  3027. }
  3028. #endif
  3029. #endif /* LIBXML_OUTPUT_ENABLED */
  3030. else if ((!strcmp(argv[i], "-nowarning")) ||
  3031. (!strcmp(argv[i], "--nowarning"))) {
  3032. xmlGetWarningsDefaultValue = 0;
  3033. xmlPedanticParserDefault(0);
  3034. options |= XML_PARSE_NOWARNING;
  3035. }
  3036. else if ((!strcmp(argv[i], "-pedantic")) ||
  3037. (!strcmp(argv[i], "--pedantic"))) {
  3038. xmlGetWarningsDefaultValue = 1;
  3039. xmlPedanticParserDefault(1);
  3040. options |= XML_PARSE_PEDANTIC;
  3041. }
  3042. #ifdef LIBXML_DEBUG_ENABLED
  3043. else if ((!strcmp(argv[i], "-debugent")) ||
  3044. (!strcmp(argv[i], "--debugent"))) {
  3045. debugent++;
  3046. xmlParserDebugEntities = 1;
  3047. }
  3048. #endif
  3049. #ifdef LIBXML_C14N_ENABLED
  3050. else if ((!strcmp(argv[i], "-c14n")) ||
  3051. (!strcmp(argv[i], "--c14n"))) {
  3052. canonical++;
  3053. options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
  3054. }
  3055. else if ((!strcmp(argv[i], "-c14n11")) ||
  3056. (!strcmp(argv[i], "--c14n11"))) {
  3057. canonical_11++;
  3058. options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
  3059. }
  3060. else if ((!strcmp(argv[i], "-exc-c14n")) ||
  3061. (!strcmp(argv[i], "--exc-c14n"))) {
  3062. exc_canonical++;
  3063. options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
  3064. }
  3065. #endif
  3066. #ifdef LIBXML_CATALOG_ENABLED
  3067. else if ((!strcmp(argv[i], "-catalogs")) ||
  3068. (!strcmp(argv[i], "--catalogs"))) {
  3069. catalogs++;
  3070. } else if ((!strcmp(argv[i], "-nocatalogs")) ||
  3071. (!strcmp(argv[i], "--nocatalogs"))) {
  3072. nocatalogs++;
  3073. }
  3074. #endif
  3075. else if ((!strcmp(argv[i], "-encode")) ||
  3076. (!strcmp(argv[i], "--encode"))) {
  3077. i++;
  3078. encoding = argv[i];
  3079. /*
  3080. * OK it's for testing purposes
  3081. */
  3082. xmlAddEncodingAlias("UTF-8", "DVEnc");
  3083. }
  3084. else if ((!strcmp(argv[i], "-noblanks")) ||
  3085. (!strcmp(argv[i], "--noblanks"))) {
  3086. noblanks++;
  3087. xmlKeepBlanksDefault(0);
  3088. }
  3089. else if ((!strcmp(argv[i], "-maxmem")) ||
  3090. (!strcmp(argv[i], "--maxmem"))) {
  3091. i++;
  3092. if (sscanf(argv[i], "%d", &maxmem) == 1) {
  3093. xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
  3094. myStrdupFunc);
  3095. } else {
  3096. maxmem = 0;
  3097. }
  3098. }
  3099. else if ((!strcmp(argv[i], "-format")) ||
  3100. (!strcmp(argv[i], "--format"))) {
  3101. noblanks++;
  3102. #ifdef LIBXML_OUTPUT_ENABLED
  3103. format++;
  3104. #endif /* LIBXML_OUTPUT_ENABLED */
  3105. xmlKeepBlanksDefault(0);
  3106. }
  3107. #ifdef LIBXML_READER_ENABLED
  3108. else if ((!strcmp(argv[i], "-stream")) ||
  3109. (!strcmp(argv[i], "--stream"))) {
  3110. stream++;
  3111. }
  3112. else if ((!strcmp(argv[i], "-walker")) ||
  3113. (!strcmp(argv[i], "--walker"))) {
  3114. walker++;
  3115. noout++;
  3116. }
  3117. #endif /* LIBXML_READER_ENABLED */
  3118. #ifdef LIBXML_SAX1_ENABLED
  3119. else if ((!strcmp(argv[i], "-sax1")) ||
  3120. (!strcmp(argv[i], "--sax1"))) {
  3121. sax1++;
  3122. options |= XML_PARSE_SAX1;
  3123. }
  3124. #endif /* LIBXML_SAX1_ENABLED */
  3125. else if ((!strcmp(argv[i], "-sax")) ||
  3126. (!strcmp(argv[i], "--sax"))) {
  3127. sax++;
  3128. }
  3129. else if ((!strcmp(argv[i], "-chkregister")) ||
  3130. (!strcmp(argv[i], "--chkregister"))) {
  3131. chkregister++;
  3132. #ifdef LIBXML_SCHEMAS_ENABLED
  3133. } else if ((!strcmp(argv[i], "-relaxng")) ||
  3134. (!strcmp(argv[i], "--relaxng"))) {
  3135. i++;
  3136. relaxng = argv[i];
  3137. noent++;
  3138. options |= XML_PARSE_NOENT;
  3139. } else if ((!strcmp(argv[i], "-schema")) ||
  3140. (!strcmp(argv[i], "--schema"))) {
  3141. i++;
  3142. schema = argv[i];
  3143. noent++;
  3144. #endif
  3145. #ifdef LIBXML_SCHEMATRON_ENABLED
  3146. } else if ((!strcmp(argv[i], "-schematron")) ||
  3147. (!strcmp(argv[i], "--schematron"))) {
  3148. i++;
  3149. schematron = argv[i];
  3150. noent++;
  3151. #endif
  3152. } else if ((!strcmp(argv[i], "-nonet")) ||
  3153. (!strcmp(argv[i], "--nonet"))) {
  3154. options |= XML_PARSE_NONET;
  3155. xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
  3156. } else if ((!strcmp(argv[i], "-nocompact")) ||
  3157. (!strcmp(argv[i], "--nocompact"))) {
  3158. options &= ~XML_PARSE_COMPACT;
  3159. } else if ((!strcmp(argv[i], "-load-trace")) ||
  3160. (!strcmp(argv[i], "--load-trace"))) {
  3161. load_trace++;
  3162. } else if ((!strcmp(argv[i], "-path")) ||
  3163. (!strcmp(argv[i], "--path"))) {
  3164. i++;
  3165. parsePath(BAD_CAST argv[i]);
  3166. #ifdef LIBXML_PATTERN_ENABLED
  3167. } else if ((!strcmp(argv[i], "-pattern")) ||
  3168. (!strcmp(argv[i], "--pattern"))) {
  3169. i++;
  3170. pattern = argv[i];
  3171. #endif
  3172. #ifdef LIBXML_XPATH_ENABLED
  3173. } else if ((!strcmp(argv[i], "-xpath")) ||
  3174. (!strcmp(argv[i], "--xpath"))) {
  3175. i++;
  3176. noout++;
  3177. xpathquery = argv[i];
  3178. #endif
  3179. } else if ((!strcmp(argv[i], "-oldxml10")) ||
  3180. (!strcmp(argv[i], "--oldxml10"))) {
  3181. oldxml10++;
  3182. options |= XML_PARSE_OLD10;
  3183. } else {
  3184. fprintf(stderr, "Unknown option %s\n", argv[i]);
  3185. usage(argv[0]);
  3186. return(1);
  3187. }
  3188. }
  3189. #ifdef LIBXML_CATALOG_ENABLED
  3190. if (nocatalogs == 0) {
  3191. if (catalogs) {
  3192. const char *catal;
  3193. catal = getenv("SGML_CATALOG_FILES");
  3194. if (catal != NULL) {
  3195. xmlLoadCatalogs(catal);
  3196. } else {
  3197. fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
  3198. }
  3199. }
  3200. }
  3201. #endif
  3202. #ifdef LIBXML_SAX1_ENABLED
  3203. if (sax1)
  3204. xmlSAXDefaultVersion(1);
  3205. else
  3206. xmlSAXDefaultVersion(2);
  3207. #endif /* LIBXML_SAX1_ENABLED */
  3208. if (chkregister) {
  3209. xmlRegisterNodeDefault(registerNode);
  3210. xmlDeregisterNodeDefault(deregisterNode);
  3211. }
  3212. indent = getenv("XMLLINT_INDENT");
  3213. if(indent != NULL) {
  3214. xmlTreeIndentString = indent;
  3215. }
  3216. defaultEntityLoader = xmlGetExternalEntityLoader();
  3217. xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
  3218. xmlLineNumbersDefault(1);
  3219. if (loaddtd != 0)
  3220. xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
  3221. if (dtdattrs)
  3222. xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
  3223. if (noent != 0) xmlSubstituteEntitiesDefault(1);
  3224. #ifdef LIBXML_VALID_ENABLED
  3225. if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
  3226. #endif /* LIBXML_VALID_ENABLED */
  3227. if ((htmlout) && (!nowrap)) {
  3228. xmlGenericError(xmlGenericErrorContext,
  3229. "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
  3230. xmlGenericError(xmlGenericErrorContext,
  3231. "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
  3232. xmlGenericError(xmlGenericErrorContext,
  3233. "<html><head><title>%s output</title></head>\n",
  3234. argv[0]);
  3235. xmlGenericError(xmlGenericErrorContext,
  3236. "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
  3237. argv[0]);
  3238. }
  3239. #ifdef LIBXML_SCHEMATRON_ENABLED
  3240. if ((schematron != NULL) && (sax == 0)
  3241. #ifdef LIBXML_READER_ENABLED
  3242. && (stream == 0)
  3243. #endif /* LIBXML_READER_ENABLED */
  3244. ) {
  3245. xmlSchematronParserCtxtPtr ctxt;
  3246. /* forces loading the DTDs */
  3247. xmlLoadExtDtdDefaultValue |= 1;
  3248. options |= XML_PARSE_DTDLOAD;
  3249. if (timing) {
  3250. startTimer();
  3251. }
  3252. ctxt = xmlSchematronNewParserCtxt(schematron);
  3253. #if 0
  3254. xmlSchematronSetParserErrors(ctxt,
  3255. (xmlSchematronValidityErrorFunc) fprintf,
  3256. (xmlSchematronValidityWarningFunc) fprintf,
  3257. stderr);
  3258. #endif
  3259. wxschematron = xmlSchematronParse(ctxt);
  3260. if (wxschematron == NULL) {
  3261. xmlGenericError(xmlGenericErrorContext,
  3262. "Schematron schema %s failed to compile\n", schematron);
  3263. progresult = XMLLINT_ERR_SCHEMACOMP;
  3264. schematron = NULL;
  3265. }
  3266. xmlSchematronFreeParserCtxt(ctxt);
  3267. if (timing) {
  3268. endTimer("Compiling the schemas");
  3269. }
  3270. }
  3271. #endif
  3272. #ifdef LIBXML_SCHEMAS_ENABLED
  3273. if ((relaxng != NULL) && (sax == 0)
  3274. #ifdef LIBXML_READER_ENABLED
  3275. && (stream == 0)
  3276. #endif /* LIBXML_READER_ENABLED */
  3277. ) {
  3278. xmlRelaxNGParserCtxtPtr ctxt;
  3279. /* forces loading the DTDs */
  3280. xmlLoadExtDtdDefaultValue |= 1;
  3281. options |= XML_PARSE_DTDLOAD;
  3282. if (timing) {
  3283. startTimer();
  3284. }
  3285. ctxt = xmlRelaxNGNewParserCtxt(relaxng);
  3286. xmlRelaxNGSetParserErrors(ctxt,
  3287. (xmlRelaxNGValidityErrorFunc) fprintf,
  3288. (xmlRelaxNGValidityWarningFunc) fprintf,
  3289. stderr);
  3290. relaxngschemas = xmlRelaxNGParse(ctxt);
  3291. if (relaxngschemas == NULL) {
  3292. xmlGenericError(xmlGenericErrorContext,
  3293. "Relax-NG schema %s failed to compile\n", relaxng);
  3294. progresult = XMLLINT_ERR_SCHEMACOMP;
  3295. relaxng = NULL;
  3296. }
  3297. xmlRelaxNGFreeParserCtxt(ctxt);
  3298. if (timing) {
  3299. endTimer("Compiling the schemas");
  3300. }
  3301. } else if ((schema != NULL)
  3302. #ifdef LIBXML_READER_ENABLED
  3303. && (stream == 0)
  3304. #endif
  3305. ) {
  3306. xmlSchemaParserCtxtPtr ctxt;
  3307. if (timing) {
  3308. startTimer();
  3309. }
  3310. ctxt = xmlSchemaNewParserCtxt(schema);
  3311. xmlSchemaSetParserErrors(ctxt,
  3312. (xmlSchemaValidityErrorFunc) fprintf,
  3313. (xmlSchemaValidityWarningFunc) fprintf,
  3314. stderr);
  3315. wxschemas = xmlSchemaParse(ctxt);
  3316. if (wxschemas == NULL) {
  3317. xmlGenericError(xmlGenericErrorContext,
  3318. "WXS schema %s failed to compile\n", schema);
  3319. progresult = XMLLINT_ERR_SCHEMACOMP;
  3320. schema = NULL;
  3321. }
  3322. xmlSchemaFreeParserCtxt(ctxt);
  3323. if (timing) {
  3324. endTimer("Compiling the schemas");
  3325. }
  3326. }
  3327. #endif /* LIBXML_SCHEMAS_ENABLED */
  3328. #ifdef LIBXML_PATTERN_ENABLED
  3329. if ((pattern != NULL)
  3330. #ifdef LIBXML_READER_ENABLED
  3331. && (walker == 0)
  3332. #endif
  3333. ) {
  3334. patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
  3335. if (patternc == NULL) {
  3336. xmlGenericError(xmlGenericErrorContext,
  3337. "Pattern %s failed to compile\n", pattern);
  3338. progresult = XMLLINT_ERR_SCHEMAPAT;
  3339. pattern = NULL;
  3340. }
  3341. }
  3342. #endif /* LIBXML_PATTERN_ENABLED */
  3343. for (i = 1; i < argc ; i++) {
  3344. if ((!strcmp(argv[i], "-encode")) ||
  3345. (!strcmp(argv[i], "--encode"))) {
  3346. i++;
  3347. continue;
  3348. } else if ((!strcmp(argv[i], "-o")) ||
  3349. (!strcmp(argv[i], "-output")) ||
  3350. (!strcmp(argv[i], "--output"))) {
  3351. i++;
  3352. continue;
  3353. }
  3354. #ifdef LIBXML_VALID_ENABLED
  3355. if ((!strcmp(argv[i], "-dtdvalid")) ||
  3356. (!strcmp(argv[i], "--dtdvalid"))) {
  3357. i++;
  3358. continue;
  3359. }
  3360. if ((!strcmp(argv[i], "-path")) ||
  3361. (!strcmp(argv[i], "--path"))) {
  3362. i++;
  3363. continue;
  3364. }
  3365. if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
  3366. (!strcmp(argv[i], "--dtdvalidfpi"))) {
  3367. i++;
  3368. continue;
  3369. }
  3370. #endif /* LIBXML_VALID_ENABLED */
  3371. if ((!strcmp(argv[i], "-relaxng")) ||
  3372. (!strcmp(argv[i], "--relaxng"))) {
  3373. i++;
  3374. continue;
  3375. }
  3376. if ((!strcmp(argv[i], "-maxmem")) ||
  3377. (!strcmp(argv[i], "--maxmem"))) {
  3378. i++;
  3379. continue;
  3380. }
  3381. if ((!strcmp(argv[i], "-schema")) ||
  3382. (!strcmp(argv[i], "--schema"))) {
  3383. i++;
  3384. continue;
  3385. }
  3386. if ((!strcmp(argv[i], "-schematron")) ||
  3387. (!strcmp(argv[i], "--schematron"))) {
  3388. i++;
  3389. continue;
  3390. }
  3391. #ifdef LIBXML_PATTERN_ENABLED
  3392. if ((!strcmp(argv[i], "-pattern")) ||
  3393. (!strcmp(argv[i], "--pattern"))) {
  3394. i++;
  3395. continue;
  3396. }
  3397. #endif
  3398. #ifdef LIBXML_XPATH_ENABLED
  3399. if ((!strcmp(argv[i], "-xpath")) ||
  3400. (!strcmp(argv[i], "--xpath"))) {
  3401. i++;
  3402. continue;
  3403. }
  3404. #endif
  3405. if ((timing) && (repeat))
  3406. startTimer();
  3407. /* Remember file names. "-" means stdin. <sven@zen.org> */
  3408. if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
  3409. if (repeat) {
  3410. xmlParserCtxtPtr ctxt = NULL;
  3411. for (acount = 0;acount < repeat;acount++) {
  3412. #ifdef LIBXML_READER_ENABLED
  3413. if (stream != 0) {
  3414. streamFile(argv[i]);
  3415. } else {
  3416. #endif /* LIBXML_READER_ENABLED */
  3417. if (sax) {
  3418. testSAX(argv[i]);
  3419. } else {
  3420. if (ctxt == NULL)
  3421. ctxt = xmlNewParserCtxt();
  3422. parseAndPrintFile(argv[i], ctxt);
  3423. }
  3424. #ifdef LIBXML_READER_ENABLED
  3425. }
  3426. #endif /* LIBXML_READER_ENABLED */
  3427. }
  3428. if (ctxt != NULL)
  3429. xmlFreeParserCtxt(ctxt);
  3430. } else {
  3431. nbregister = 0;
  3432. #ifdef LIBXML_READER_ENABLED
  3433. if (stream != 0)
  3434. streamFile(argv[i]);
  3435. else
  3436. #endif /* LIBXML_READER_ENABLED */
  3437. if (sax) {
  3438. testSAX(argv[i]);
  3439. } else {
  3440. parseAndPrintFile(argv[i], NULL);
  3441. }
  3442. if ((chkregister) && (nbregister != 0)) {
  3443. fprintf(stderr, "Registration count off: %d\n", nbregister);
  3444. progresult = XMLLINT_ERR_RDREGIS;
  3445. }
  3446. }
  3447. files ++;
  3448. if ((timing) && (repeat)) {
  3449. endTimer("%d iterations", repeat);
  3450. }
  3451. }
  3452. }
  3453. if (generate)
  3454. parseAndPrintFile(NULL, NULL);
  3455. if ((htmlout) && (!nowrap)) {
  3456. xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
  3457. }
  3458. if ((files == 0) && (!generate) && (version == 0)) {
  3459. usage(argv[0]);
  3460. }
  3461. #ifdef LIBXML_SCHEMATRON_ENABLED
  3462. if (wxschematron != NULL)
  3463. xmlSchematronFree(wxschematron);
  3464. #endif
  3465. #ifdef LIBXML_SCHEMAS_ENABLED
  3466. if (relaxngschemas != NULL)
  3467. xmlRelaxNGFree(relaxngschemas);
  3468. if (wxschemas != NULL)
  3469. xmlSchemaFree(wxschemas);
  3470. xmlRelaxNGCleanupTypes();
  3471. #endif
  3472. #ifdef LIBXML_PATTERN_ENABLED
  3473. if (patternc != NULL)
  3474. xmlFreePattern(patternc);
  3475. #endif
  3476. xmlCleanupParser();
  3477. xmlMemoryDump();
  3478. return(progresult);
  3479. }