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 9#include "libxml.h" 10 11#include <string.h> 12#include <stdarg.h> 13#include <assert.h> 14 15#if defined (_WIN32) && !defined(__CYGWIN__) 16#if defined (_MSC_VER) || defined(__BORLANDC__) 17#include <winsock2.h> 18#pragma comment(lib, "ws2_32.lib") 19#define gettimeofday(p1,p2) 20#endif /* _MSC_VER */ 21#endif /* _WIN32 */ 22 23#ifdef HAVE_SYS_TIME_H 24#include <sys/time.h> 25#endif 26#ifdef HAVE_TIME_H 27#include <time.h> 28#endif 29 30#ifdef __MINGW32__ 31#define _WINSOCKAPI_ 32#include <wsockcompat.h> 33#include <winsock2.h> 34#undef XML_SOCKLEN_T 35#define XML_SOCKLEN_T unsigned int 36#endif 37 38#ifdef HAVE_SYS_TIMEB_H 39#include <sys/timeb.h> 40#endif 41 42#ifdef HAVE_SYS_TYPES_H 43#include <sys/types.h> 44#endif 45#ifdef HAVE_SYS_STAT_H 46#include <sys/stat.h> 47#endif 48#ifdef HAVE_FCNTL_H 49#include <fcntl.h> 50#endif 51#ifdef HAVE_UNISTD_H 52#include <unistd.h> 53#endif 54#ifdef HAVE_SYS_MMAN_H 55#include <sys/mman.h> 56/* seems needed for Solaris */ 57#ifndef MAP_FAILED 58#define MAP_FAILED ((void *) -1) 59#endif 60#endif 61#ifdef HAVE_STDLIB_H 62#include <stdlib.h> 63#endif 64#ifdef HAVE_LIBREADLINE 65#include <readline/readline.h> 66#ifdef HAVE_LIBHISTORY 67#include <readline/history.h> 68#endif 69#endif 70 71#include <libxml/xmlmemory.h> 72#include <libxml/parser.h> 73#include <libxml/parserInternals.h> 74#include <libxml/HTMLparser.h> 75#include <libxml/HTMLtree.h> 76#include <libxml/tree.h> 77#include <libxml/xpath.h> 78#include <libxml/debugXML.h> 79#include <libxml/xmlerror.h> 80#ifdef LIBXML_XINCLUDE_ENABLED 81#include <libxml/xinclude.h> 82#endif 83#ifdef LIBXML_CATALOG_ENABLED 84#include <libxml/catalog.h> 85#endif 86#include <libxml/globals.h> 87#include <libxml/xmlreader.h> 88#ifdef LIBXML_SCHEMATRON_ENABLED 89#include <libxml/schematron.h> 90#endif 91#ifdef LIBXML_SCHEMAS_ENABLED 92#include <libxml/relaxng.h> 93#include <libxml/xmlschemas.h> 94#endif 95#ifdef LIBXML_PATTERN_ENABLED 96#include <libxml/pattern.h> 97#endif 98#ifdef LIBXML_C14N_ENABLED 99#include <libxml/c14n.h> 100#endif 101#ifdef LIBXML_OUTPUT_ENABLED 102#include <libxml/xmlsave.h> 103#endif 104 105#ifndef XML_XML_DEFAULT_CATALOG 106#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog" 107#endif 108 109typedef enum { 110 XMLLINT_RETURN_OK = 0, /* No error */ 111 XMLLINT_ERR_UNCLASS = 1, /* Unclassified */ 112 XMLLINT_ERR_DTD = 2, /* Error in DTD */ 113 XMLLINT_ERR_VALID = 3, /* Validation error */ 114 XMLLINT_ERR_RDFILE = 4, /* CtxtReadFile error */ 115 XMLLINT_ERR_SCHEMACOMP = 5, /* Schema compilation */ 116 XMLLINT_ERR_OUT = 6, /* Error writing output */ 117 XMLLINT_ERR_SCHEMAPAT = 7, /* Error in schema pattern */ 118 XMLLINT_ERR_RDREGIS = 8, /* Error in Reader registration */ 119 XMLLINT_ERR_MEM = 9, /* Out of memory error */ 120 XMLLINT_ERR_XPATH = 10 /* XPath evaluation error */ 121} xmllintReturnCode; 122#ifdef LIBXML_DEBUG_ENABLED 123static int shell = 0; 124static int debugent = 0; 125#endif 126static int debug = 0; 127static int maxmem = 0; 128#ifdef LIBXML_TREE_ENABLED 129static int copy = 0; 130#endif /* LIBXML_TREE_ENABLED */ 131static int recovery = 0; 132static int noent = 0; 133static int noenc = 0; 134static int noblanks = 0; 135static int noout = 0; 136static int nowrap = 0; 137#ifdef LIBXML_OUTPUT_ENABLED 138static int format = 0; 139static const char *output = NULL; 140static int compress = 0; 141static int oldout = 0; 142#endif /* LIBXML_OUTPUT_ENABLED */ 143#ifdef LIBXML_VALID_ENABLED 144static int valid = 0; 145static int postvalid = 0; 146static char * dtdvalid = NULL; 147static char * dtdvalidfpi = NULL; 148#endif 149#ifdef LIBXML_SCHEMAS_ENABLED 150static char * relaxng = NULL; 151static xmlRelaxNGPtr relaxngschemas = NULL; 152static char * schema = NULL; 153static xmlSchemaPtr wxschemas = NULL; 154#endif 155#ifdef LIBXML_SCHEMATRON_ENABLED 156static char * schematron = NULL; 157static xmlSchematronPtr wxschematron = NULL; 158#endif 159static int repeat = 0; 160static int insert = 0; 161#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED) 162static int html = 0; 163static int xmlout = 0; 164#endif 165static int htmlout = 0; 166#if defined(LIBXML_HTML_ENABLED) 167static int nodefdtd = 0; 168#endif 169#ifdef LIBXML_PUSH_ENABLED 170static int push = 0; 171static int pushsize = 4096; 172#endif /* LIBXML_PUSH_ENABLED */ 173#ifdef HAVE_MMAP 174static int memory = 0; 175#endif 176static int testIO = 0; 177static char *encoding = NULL; 178#ifdef LIBXML_XINCLUDE_ENABLED 179static int xinclude = 0; 180#endif 181static int dtdattrs = 0; 182static int loaddtd = 0; 183static xmllintReturnCode progresult = XMLLINT_RETURN_OK; 184static int timing = 0; 185static int generate = 0; 186static int dropdtd = 0; 187#ifdef LIBXML_CATALOG_ENABLED 188static int catalogs = 0; 189static int nocatalogs = 0; 190#endif 191#ifdef LIBXML_C14N_ENABLED 192static int canonical = 0; 193static int canonical_11 = 0; 194static int exc_canonical = 0; 195#endif 196#ifdef LIBXML_READER_ENABLED 197static int stream = 0; 198static int walker = 0; 199#endif /* LIBXML_READER_ENABLED */ 200static int chkregister = 0; 201static int nbregister = 0; 202#ifdef LIBXML_SAX1_ENABLED 203static int sax1 = 0; 204#endif /* LIBXML_SAX1_ENABLED */ 205#ifdef LIBXML_PATTERN_ENABLED 206static const char *pattern = NULL; 207static xmlPatternPtr patternc = NULL; 208static xmlStreamCtxtPtr patstream = NULL; 209#endif 210#ifdef LIBXML_XPATH_ENABLED 211static const char *xpathquery = NULL; 212#endif 213static int options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES; 214static int sax = 0; 215static int oldxml10 = 0; 216 217/************************************************************************ 218 * * 219 * Entity loading control and customization. * 220 * * 221 ************************************************************************/ 222#define MAX_PATHS 64 223#ifdef _WIN32 224# define PATH_SEPARATOR ';' 225#else 226# define PATH_SEPARATOR ':' 227#endif 228static xmlChar *paths[MAX_PATHS + 1]; 229static int nbpaths = 0; 230static int load_trace = 0; 231 232static 233void parsePath(const xmlChar *path) { 234 const xmlChar *cur; 235 236 if (path == NULL) 237 return; 238 while (*path != 0) { 239 if (nbpaths >= MAX_PATHS) { 240 fprintf(stderr, "MAX_PATHS reached: too many paths\n"); 241 return; 242 } 243 cur = path; 244 while ((*cur == ' ') || (*cur == PATH_SEPARATOR)) 245 cur++; 246 path = cur; 247 while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR)) 248 cur++; 249 if (cur != path) { 250 paths[nbpaths] = xmlStrndup(path, cur - path); 251 if (paths[nbpaths] != NULL) 252 nbpaths++; 253 path = cur; 254 } 255 } 256} 257 258static xmlExternalEntityLoader defaultEntityLoader = NULL; 259 260static xmlParserInputPtr 261xmllintExternalEntityLoader(const char *URL, const char *ID, 262 xmlParserCtxtPtr ctxt) { 263 xmlParserInputPtr ret; 264 warningSAXFunc warning = NULL; 265 errorSAXFunc err = NULL; 266 267 int i; 268 const char *lastsegment = URL; 269 const char *iter = URL; 270 271 if ((nbpaths > 0) && (iter != NULL)) { 272 while (*iter != 0) { 273 if (*iter == '/') 274 lastsegment = iter + 1; 275 iter++; 276 } 277 } 278 279 if ((ctxt != NULL) && (ctxt->sax != NULL)) { 280 warning = ctxt->sax->warning; 281 err = ctxt->sax->error; 282 ctxt->sax->warning = NULL; 283 ctxt->sax->error = NULL; 284 } 285 286 if (defaultEntityLoader != NULL) { 287 ret = defaultEntityLoader(URL, ID, ctxt); 288 if (ret != NULL) { 289 if (warning != NULL) 290 ctxt->sax->warning = warning; 291 if (err != NULL) 292 ctxt->sax->error = err; 293 if (load_trace) { 294 fprintf \ 295 (stderr, 296 "Loaded URL=\"%s\" ID=\"%s\"\n", 297 URL ? URL : "(null)", 298 ID ? ID : "(null)"); 299 } 300 return(ret); 301 } 302 } 303 for (i = 0;i < nbpaths;i++) { 304 xmlChar *newURL; 305 306 newURL = xmlStrdup((const xmlChar *) paths[i]); 307 newURL = xmlStrcat(newURL, (const xmlChar *) "/"); 308 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment); 309 if (newURL != NULL) { 310 ret = defaultEntityLoader((const char *)newURL, ID, ctxt); 311 if (ret != NULL) { 312 if (warning != NULL) 313 ctxt->sax->warning = warning; 314 if (err != NULL) 315 ctxt->sax->error = err; 316 if (load_trace) { 317 fprintf \ 318 (stderr, 319 "Loaded URL=\"%s\" ID=\"%s\"\n", 320 newURL, 321 ID ? ID : "(null)"); 322 } 323 xmlFree(newURL); 324 return(ret); 325 } 326 xmlFree(newURL); 327 } 328 } 329 if (err != NULL) 330 ctxt->sax->error = err; 331 if (warning != NULL) { 332 ctxt->sax->warning = warning; 333 if (URL != NULL) 334 warning(ctxt, "failed to load external entity \"%s\"\n", URL); 335 else if (ID != NULL) 336 warning(ctxt, "failed to load external entity \"%s\"\n", ID); 337 } 338 return(NULL); 339} 340/************************************************************************ 341 * * 342 * Memory allocation consumption debugging * 343 * * 344 ************************************************************************/ 345 346static void 347OOM(void) 348{ 349 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem); 350 progresult = XMLLINT_ERR_MEM; 351} 352 353static void 354myFreeFunc(void *mem) 355{ 356 xmlMemFree(mem); 357} 358static void * 359myMallocFunc(size_t size) 360{ 361 void *ret; 362 363 ret = xmlMemMalloc(size); 364 if (ret != NULL) { 365 if (xmlMemUsed() > maxmem) { 366 OOM(); 367 xmlMemFree(ret); 368 return (NULL); 369 } 370 } 371 return (ret); 372} 373static void * 374myReallocFunc(void *mem, size_t size) 375{ 376 void *ret; 377 378 ret = xmlMemRealloc(mem, size); 379 if (ret != NULL) { 380 if (xmlMemUsed() > maxmem) { 381 OOM(); 382 xmlMemFree(ret); 383 return (NULL); 384 } 385 } 386 return (ret); 387} 388static char * 389myStrdupFunc(const char *str) 390{ 391 char *ret; 392 393 ret = xmlMemoryStrdup(str); 394 if (ret != NULL) { 395 if (xmlMemUsed() > maxmem) { 396 OOM(); 397 xmlFree(ret); 398 return (NULL); 399 } 400 } 401 return (ret); 402} 403/************************************************************************ 404 * * 405 * Internal timing routines to remove the necessity to have * 406 * unix-specific function calls. * 407 * * 408 ************************************************************************/ 409 410#ifndef HAVE_GETTIMEOFDAY 411#ifdef HAVE_SYS_TIMEB_H 412#ifdef HAVE_SYS_TIME_H 413#ifdef HAVE_FTIME 414 415static int 416my_gettimeofday(struct timeval *tvp, void *tzp) 417{ 418 struct timeb timebuffer; 419 420 ftime(&timebuffer); 421 if (tvp) { 422 tvp->tv_sec = timebuffer.time; 423 tvp->tv_usec = timebuffer.millitm * 1000L; 424 } 425 return (0); 426} 427#define HAVE_GETTIMEOFDAY 1 428#define gettimeofday my_gettimeofday 429 430#endif /* HAVE_FTIME */ 431#endif /* HAVE_SYS_TIME_H */ 432#endif /* HAVE_SYS_TIMEB_H */ 433#endif /* !HAVE_GETTIMEOFDAY */ 434 435#if defined(HAVE_GETTIMEOFDAY) 436static struct timeval begin, end; 437 438/* 439 * startTimer: call where you want to start timing 440 */ 441static void 442startTimer(void) 443{ 444 gettimeofday(&begin, NULL); 445} 446 447/* 448 * endTimer: call where you want to stop timing and to print out a 449 * message about the timing performed; format is a printf 450 * type argument 451 */ 452static void XMLCDECL LIBXML_ATTR_FORMAT(1,2) 453endTimer(const char *fmt, ...) 454{ 455 long msec; 456 va_list ap; 457 458 gettimeofday(&end, NULL); 459 msec = end.tv_sec - begin.tv_sec; 460 msec *= 1000; 461 msec += (end.tv_usec - begin.tv_usec) / 1000; 462 463#ifndef HAVE_STDARG_H 464#error "endTimer required stdarg functions" 465#endif 466 va_start(ap, fmt); 467 vfprintf(stderr, fmt, ap); 468 va_end(ap); 469 470 fprintf(stderr, " took %ld ms\n", msec); 471} 472#elif defined(HAVE_TIME_H) 473/* 474 * No gettimeofday function, so we have to make do with calling clock. 475 * This is obviously less accurate, but there's little we can do about 476 * that. 477 */ 478#ifndef CLOCKS_PER_SEC 479#define CLOCKS_PER_SEC 100 480#endif 481 482static clock_t begin, end; 483static void 484startTimer(void) 485{ 486 begin = clock(); 487} 488static void XMLCDECL LIBXML_ATTR_FORMAT(1,2) 489endTimer(const char *fmt, ...) 490{ 491 long msec; 492 va_list ap; 493 494 end = clock(); 495 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC; 496 497#ifndef HAVE_STDARG_H 498#error "endTimer required stdarg functions" 499#endif 500 va_start(ap, fmt); 501 vfprintf(stderr, fmt, ap); 502 va_end(ap); 503 fprintf(stderr, " took %ld ms\n", msec); 504} 505#else 506 507/* 508 * We don't have a gettimeofday or time.h, so we just don't do timing 509 */ 510static void 511startTimer(void) 512{ 513 /* 514 * Do nothing 515 */ 516} 517static void XMLCDECL LIBXML_ATTR_FORMAT(1,2) 518endTimer(char *format, ...) 519{ 520 /* 521 * We cannot do anything because we don't have a timing function 522 */ 523#ifdef HAVE_STDARG_H 524 va_list ap; 525 va_start(ap, format); 526 vfprintf(stderr, format, ap); 527 va_end(ap); 528 fprintf(stderr, " was not timed\n"); 529#else 530 /* We don't have gettimeofday, time or stdarg.h, what crazy world is 531 * this ?! 532 */ 533#endif 534} 535#endif 536/************************************************************************ 537 * * 538 * HTML ouput * 539 * * 540 ************************************************************************/ 541static char buffer[50000]; 542 543static void 544xmlHTMLEncodeSend(void) { 545 char *result; 546 547 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer); 548 if (result) { 549 xmlGenericError(xmlGenericErrorContext, "%s", result); 550 xmlFree(result); 551 } 552 buffer[0] = 0; 553} 554 555/** 556 * xmlHTMLPrintFileInfo: 557 * @input: an xmlParserInputPtr input 558 * 559 * Displays the associated file and line informations for the current input 560 */ 561 562static void 563xmlHTMLPrintFileInfo(xmlParserInputPtr input) { 564 int len; 565 xmlGenericError(xmlGenericErrorContext, "<p>"); 566 567 len = strlen(buffer); 568 if (input != NULL) { 569 if (input->filename) { 570 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename, 571 input->line); 572 } else { 573 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line); 574 } 575 } 576 xmlHTMLEncodeSend(); 577} 578 579/** 580 * xmlHTMLPrintFileContext: 581 * @input: an xmlParserInputPtr input 582 * 583 * Displays current context within the input content for error tracking 584 */ 585 586static void 587xmlHTMLPrintFileContext(xmlParserInputPtr input) { 588 const xmlChar *cur, *base; 589 int len; 590 int n; 591 592 if (input == NULL) return; 593 xmlGenericError(xmlGenericErrorContext, "<pre>\n"); 594 cur = input->cur; 595 base = input->base; 596 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) { 597 cur--; 598 } 599 n = 0; 600 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r')) 601 cur--; 602 if ((*cur == '\n') || (*cur == '\r')) cur++; 603 base = cur; 604 n = 0; 605 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) { 606 len = strlen(buffer); 607 snprintf(&buffer[len], sizeof(buffer) - len, "%c", 608 (unsigned char) *cur++); 609 n++; 610 } 611 len = strlen(buffer); 612 snprintf(&buffer[len], sizeof(buffer) - len, "\n"); 613 cur = input->cur; 614 while ((*cur == '\n') || (*cur == '\r')) 615 cur--; 616 n = 0; 617 while ((cur != base) && (n++ < 80)) { 618 len = strlen(buffer); 619 snprintf(&buffer[len], sizeof(buffer) - len, " "); 620 base++; 621 } 622 len = strlen(buffer); 623 snprintf(&buffer[len], sizeof(buffer) - len, "^\n"); 624 xmlHTMLEncodeSend(); 625 xmlGenericError(xmlGenericErrorContext, "</pre>"); 626} 627 628/** 629 * xmlHTMLError: 630 * @ctx: an XML parser context 631 * @msg: the message to display/transmit 632 * @...: extra parameters for the message display 633 * 634 * Display and format an error messages, gives file, line, position and 635 * extra parameters. 636 */ 637static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) 638xmlHTMLError(void *ctx, const char *msg, ...) 639{ 640 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 641 xmlParserInputPtr input; 642 va_list args; 643 int len; 644 645 buffer[0] = 0; 646 input = ctxt->input; 647 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) { 648 input = ctxt->inputTab[ctxt->inputNr - 2]; 649 } 650 651 xmlHTMLPrintFileInfo(input); 652 653 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: "); 654 va_start(args, msg); 655 len = strlen(buffer); 656 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args); 657 va_end(args); 658 xmlHTMLEncodeSend(); 659 xmlGenericError(xmlGenericErrorContext, "</p>\n"); 660 661 xmlHTMLPrintFileContext(input); 662 xmlHTMLEncodeSend(); 663} 664 665/** 666 * xmlHTMLWarning: 667 * @ctx: an XML parser context 668 * @msg: the message to display/transmit 669 * @...: extra parameters for the message display 670 * 671 * Display and format a warning messages, gives file, line, position and 672 * extra parameters. 673 */ 674static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) 675xmlHTMLWarning(void *ctx, const char *msg, ...) 676{ 677 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 678 xmlParserInputPtr input; 679 va_list args; 680 int len; 681 682 buffer[0] = 0; 683 input = ctxt->input; 684 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) { 685 input = ctxt->inputTab[ctxt->inputNr - 2]; 686 } 687 688 689 xmlHTMLPrintFileInfo(input); 690 691 xmlGenericError(xmlGenericErrorContext, "<b>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 699 xmlHTMLPrintFileContext(input); 700 xmlHTMLEncodeSend(); 701} 702 703/** 704 * xmlHTMLValidityError: 705 * @ctx: an XML parser context 706 * @msg: the message to display/transmit 707 * @...: extra parameters for the message display 708 * 709 * Display and format an validity error messages, gives file, 710 * line, position and extra parameters. 711 */ 712static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) 713xmlHTMLValidityError(void *ctx, const char *msg, ...) 714{ 715 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 716 xmlParserInputPtr input; 717 va_list args; 718 int len; 719 720 buffer[0] = 0; 721 input = ctxt->input; 722 if ((input->filename == NULL) && (ctxt->inputNr > 1)) 723 input = ctxt->inputTab[ctxt->inputNr - 2]; 724 725 xmlHTMLPrintFileInfo(input); 726 727 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: "); 728 len = strlen(buffer); 729 va_start(args, msg); 730 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args); 731 va_end(args); 732 xmlHTMLEncodeSend(); 733 xmlGenericError(xmlGenericErrorContext, "</p>\n"); 734 735 xmlHTMLPrintFileContext(input); 736 xmlHTMLEncodeSend(); 737 progresult = XMLLINT_ERR_VALID; 738} 739 740/** 741 * xmlHTMLValidityWarning: 742 * @ctx: an XML parser context 743 * @msg: the message to display/transmit 744 * @...: extra parameters for the message display 745 * 746 * Display and format a validity warning messages, gives file, line, 747 * position and extra parameters. 748 */ 749static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) 750xmlHTMLValidityWarning(void *ctx, const char *msg, ...) 751{ 752 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 753 xmlParserInputPtr input; 754 va_list args; 755 int len; 756 757 buffer[0] = 0; 758 input = ctxt->input; 759 if ((input->filename == NULL) && (ctxt->inputNr > 1)) 760 input = ctxt->inputTab[ctxt->inputNr - 2]; 761 762 xmlHTMLPrintFileInfo(input); 763 764 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: "); 765 va_start(args, msg); 766 len = strlen(buffer); 767 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args); 768 va_end(args); 769 xmlHTMLEncodeSend(); 770 xmlGenericError(xmlGenericErrorContext, "</p>\n"); 771 772 xmlHTMLPrintFileContext(input); 773 xmlHTMLEncodeSend(); 774} 775 776/************************************************************************ 777 * * 778 * Shell Interface * 779 * * 780 ************************************************************************/ 781#ifdef LIBXML_DEBUG_ENABLED 782#ifdef LIBXML_XPATH_ENABLED 783/** 784 * xmlShellReadline: 785 * @prompt: the prompt value 786 * 787 * Read a string 788 * 789 * Returns a pointer to it or NULL on EOF the caller is expected to 790 * free the returned string. 791 */ 792static char * 793xmlShellReadline(char *prompt) { 794#ifdef HAVE_LIBREADLINE 795 char *line_read; 796 797 /* Get a line from the user. */ 798 line_read = readline (prompt); 799 800 /* If the line has any text in it, save it on the history. */ 801 if (line_read && *line_read) 802 add_history (line_read); 803 804 return (line_read); 805#else 806 char line_read[501]; 807 char *ret; 808 int len; 809 810 if (prompt != NULL) 811 fprintf(stdout, "%s", prompt); 812 fflush(stdout); 813 if (!fgets(line_read, 500, stdin)) 814 return(NULL); 815 line_read[500] = 0; 816 len = strlen(line_read); 817 ret = (char *) malloc(len + 1); 818 if (ret != NULL) { 819 memcpy (ret, line_read, len + 1); 820 } 821 return(ret); 822#endif 823} 824#endif /* LIBXML_XPATH_ENABLED */ 825#endif /* LIBXML_DEBUG_ENABLED */ 826 827/************************************************************************ 828 * * 829 * I/O Interfaces * 830 * * 831 ************************************************************************/ 832 833static int myRead(FILE *f, char * buf, int len) { 834 return(fread(buf, 1, len, f)); 835} 836static void myClose(FILE *f) { 837 if (f != stdin) { 838 fclose(f); 839 } 840} 841 842/************************************************************************ 843 * * 844 * SAX based tests * 845 * * 846 ************************************************************************/ 847 848/* 849 * empty SAX block 850 */ 851static xmlSAXHandler emptySAXHandlerStruct = { 852 NULL, /* internalSubset */ 853 NULL, /* isStandalone */ 854 NULL, /* hasInternalSubset */ 855 NULL, /* hasExternalSubset */ 856 NULL, /* resolveEntity */ 857 NULL, /* getEntity */ 858 NULL, /* entityDecl */ 859 NULL, /* notationDecl */ 860 NULL, /* attributeDecl */ 861 NULL, /* elementDecl */ 862 NULL, /* unparsedEntityDecl */ 863 NULL, /* setDocumentLocator */ 864 NULL, /* startDocument */ 865 NULL, /* endDocument */ 866 NULL, /* startElement */ 867 NULL, /* endElement */ 868 NULL, /* reference */ 869 NULL, /* characters */ 870 NULL, /* ignorableWhitespace */ 871 NULL, /* processingInstruction */ 872 NULL, /* comment */ 873 NULL, /* xmlParserWarning */ 874 NULL, /* xmlParserError */ 875 NULL, /* xmlParserError */ 876 NULL, /* getParameterEntity */ 877 NULL, /* cdataBlock; */ 878 NULL, /* externalSubset; */ 879 XML_SAX2_MAGIC, 880 NULL, 881 NULL, /* startElementNs */ 882 NULL, /* endElementNs */ 883 NULL /* xmlStructuredErrorFunc */ 884}; 885 886static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct; 887extern xmlSAXHandlerPtr debugSAXHandler; 888static int callbacks; 889 890/** 891 * isStandaloneDebug: 892 * @ctxt: An XML parser context 893 * 894 * Is this document tagged standalone ? 895 * 896 * Returns 1 if true 897 */ 898static int 899isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED) 900{ 901 callbacks++; 902 if (noout) 903 return(0); 904 fprintf(stdout, "SAX.isStandalone()\n"); 905 return(0); 906} 907 908/** 909 * hasInternalSubsetDebug: 910 * @ctxt: An XML parser context 911 * 912 * Does this document has an internal subset 913 * 914 * Returns 1 if true 915 */ 916static int 917hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED) 918{ 919 callbacks++; 920 if (noout) 921 return(0); 922 fprintf(stdout, "SAX.hasInternalSubset()\n"); 923 return(0); 924} 925 926/** 927 * hasExternalSubsetDebug: 928 * @ctxt: An XML parser context 929 * 930 * Does this document has an external subset 931 * 932 * Returns 1 if true 933 */ 934static int 935hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED) 936{ 937 callbacks++; 938 if (noout) 939 return(0); 940 fprintf(stdout, "SAX.hasExternalSubset()\n"); 941 return(0); 942} 943 944/** 945 * internalSubsetDebug: 946 * @ctxt: An XML parser context 947 * 948 * Does this document has an internal subset 949 */ 950static void 951internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, 952 const xmlChar *ExternalID, const xmlChar *SystemID) 953{ 954 callbacks++; 955 if (noout) 956 return; 957 fprintf(stdout, "SAX.internalSubset(%s,", name); 958 if (ExternalID == NULL) 959 fprintf(stdout, " ,"); 960 else 961 fprintf(stdout, " %s,", ExternalID); 962 if (SystemID == NULL) 963 fprintf(stdout, " )\n"); 964 else 965 fprintf(stdout, " %s)\n", SystemID); 966} 967 968/** 969 * externalSubsetDebug: 970 * @ctxt: An XML parser context 971 * 972 * Does this document has an external subset 973 */ 974static void 975externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, 976 const xmlChar *ExternalID, const xmlChar *SystemID) 977{ 978 callbacks++; 979 if (noout) 980 return; 981 fprintf(stdout, "SAX.externalSubset(%s,", name); 982 if (ExternalID == NULL) 983 fprintf(stdout, " ,"); 984 else 985 fprintf(stdout, " %s,", ExternalID); 986 if (SystemID == NULL) 987 fprintf(stdout, " )\n"); 988 else 989 fprintf(stdout, " %s)\n", SystemID); 990} 991 992/** 993 * resolveEntityDebug: 994 * @ctxt: An XML parser context 995 * @publicId: The public ID of the entity 996 * @systemId: The system ID of the entity 997 * 998 * Special entity resolver, better left to the parser, it has 999 * more context than the application layer. 1000 * The default behaviour is to NOT resolve the entities, in that case 1001 * the ENTITY_REF nodes are built in the structure (and the parameter 1002 * values). 1003 * 1004 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour. 1005 */ 1006static xmlParserInputPtr 1007resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId) 1008{ 1009 callbacks++; 1010 if (noout) 1011 return(NULL); 1012 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ 1013 1014 1015 fprintf(stdout, "SAX.resolveEntity("); 1016 if (publicId != NULL) 1017 fprintf(stdout, "%s", (char *)publicId); 1018 else 1019 fprintf(stdout, " "); 1020 if (systemId != NULL) 1021 fprintf(stdout, ", %s)\n", (char *)systemId); 1022 else 1023 fprintf(stdout, ", )\n"); 1024 return(NULL); 1025} 1026 1027/** 1028 * getEntityDebug: 1029 * @ctxt: An XML parser context 1030 * @name: The entity name 1031 * 1032 * Get an entity by name 1033 * 1034 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour. 1035 */ 1036static xmlEntityPtr 1037getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name) 1038{ 1039 callbacks++; 1040 if (noout) 1041 return(NULL); 1042 fprintf(stdout, "SAX.getEntity(%s)\n", name); 1043 return(NULL); 1044} 1045 1046/** 1047 * getParameterEntityDebug: 1048 * @ctxt: An XML parser context 1049 * @name: The entity name 1050 * 1051 * Get a parameter entity by name 1052 * 1053 * Returns the xmlParserInputPtr 1054 */ 1055static xmlEntityPtr 1056getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name) 1057{ 1058 callbacks++; 1059 if (noout) 1060 return(NULL); 1061 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name); 1062 return(NULL); 1063} 1064 1065 1066/** 1067 * entityDeclDebug: 1068 * @ctxt: An XML parser context 1069 * @name: the entity name 1070 * @type: the entity type 1071 * @publicId: The public ID of the entity 1072 * @systemId: The system ID of the entity 1073 * @content: the entity value (without processing). 1074 * 1075 * An entity definition has been parsed 1076 */ 1077static void 1078entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type, 1079 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 1080{ 1081const xmlChar *nullstr = BAD_CAST "(null)"; 1082 /* not all libraries handle printing null pointers nicely */ 1083 if (publicId == NULL) 1084 publicId = nullstr; 1085 if (systemId == NULL) 1086 systemId = nullstr; 1087 if (content == NULL) 1088 content = (xmlChar *)nullstr; 1089 callbacks++; 1090 if (noout) 1091 return; 1092 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n", 1093 name, type, publicId, systemId, content); 1094} 1095 1096/** 1097 * attributeDeclDebug: 1098 * @ctxt: An XML parser context 1099 * @name: the attribute name 1100 * @type: the attribute type 1101 * 1102 * An attribute definition has been parsed 1103 */ 1104static void 1105attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem, 1106 const xmlChar * name, int type, int def, 1107 const xmlChar * defaultValue, xmlEnumerationPtr tree) 1108{ 1109 callbacks++; 1110 if (noout) 1111 return; 1112 if (defaultValue == NULL) 1113 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n", 1114 elem, name, type, def); 1115 else 1116 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n", 1117 elem, name, type, def, defaultValue); 1118 xmlFreeEnumeration(tree); 1119} 1120 1121/** 1122 * elementDeclDebug: 1123 * @ctxt: An XML parser context 1124 * @name: the element name 1125 * @type: the element type 1126 * @content: the element value (without processing). 1127 * 1128 * An element definition has been parsed 1129 */ 1130static void 1131elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type, 1132 xmlElementContentPtr content ATTRIBUTE_UNUSED) 1133{ 1134 callbacks++; 1135 if (noout) 1136 return; 1137 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n", 1138 name, type); 1139} 1140 1141/** 1142 * notationDeclDebug: 1143 * @ctxt: An XML parser context 1144 * @name: The name of the notation 1145 * @publicId: The public ID of the entity 1146 * @systemId: The system ID of the entity 1147 * 1148 * What to do when a notation declaration has been parsed. 1149 */ 1150static void 1151notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, 1152 const xmlChar *publicId, const xmlChar *systemId) 1153{ 1154 callbacks++; 1155 if (noout) 1156 return; 1157 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n", 1158 (char *) name, (char *) publicId, (char *) systemId); 1159} 1160 1161/** 1162 * unparsedEntityDeclDebug: 1163 * @ctxt: An XML parser context 1164 * @name: The name of the entity 1165 * @publicId: The public ID of the entity 1166 * @systemId: The system ID of the entity 1167 * @notationName: the name of the notation 1168 * 1169 * What to do when an unparsed entity declaration is parsed 1170 */ 1171static void 1172unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, 1173 const xmlChar *publicId, const xmlChar *systemId, 1174 const xmlChar *notationName) 1175{ 1176const xmlChar *nullstr = BAD_CAST "(null)"; 1177 1178 if (publicId == NULL) 1179 publicId = nullstr; 1180 if (systemId == NULL) 1181 systemId = nullstr; 1182 if (notationName == NULL) 1183 notationName = nullstr; 1184 callbacks++; 1185 if (noout) 1186 return; 1187 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n", 1188 (char *) name, (char *) publicId, (char *) systemId, 1189 (char *) notationName); 1190} 1191 1192/** 1193 * setDocumentLocatorDebug: 1194 * @ctxt: An XML parser context 1195 * @loc: A SAX Locator 1196 * 1197 * Receive the document locator at startup, actually xmlDefaultSAXLocator 1198 * Everything is available on the context, so this is useless in our case. 1199 */ 1200static void 1201setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED) 1202{ 1203 callbacks++; 1204 if (noout) 1205 return; 1206 fprintf(stdout, "SAX.setDocumentLocator()\n"); 1207} 1208 1209/** 1210 * startDocumentDebug: 1211 * @ctxt: An XML parser context 1212 * 1213 * called when the document start being processed. 1214 */ 1215static void 1216startDocumentDebug(void *ctx ATTRIBUTE_UNUSED) 1217{ 1218 callbacks++; 1219 if (noout) 1220 return; 1221 fprintf(stdout, "SAX.startDocument()\n"); 1222} 1223 1224/** 1225 * endDocumentDebug: 1226 * @ctxt: An XML parser context 1227 * 1228 * called when the document end has been detected. 1229 */ 1230static void 1231endDocumentDebug(void *ctx ATTRIBUTE_UNUSED) 1232{ 1233 callbacks++; 1234 if (noout) 1235 return; 1236 fprintf(stdout, "SAX.endDocument()\n"); 1237} 1238 1239/** 1240 * startElementDebug: 1241 * @ctxt: An XML parser context 1242 * @name: The element name 1243 * 1244 * called when an opening tag has been processed. 1245 */ 1246static void 1247startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts) 1248{ 1249 int i; 1250 1251 callbacks++; 1252 if (noout) 1253 return; 1254 fprintf(stdout, "SAX.startElement(%s", (char *) name); 1255 if (atts != NULL) { 1256 for (i = 0;(atts[i] != NULL);i++) { 1257 fprintf(stdout, ", %s='", atts[i++]); 1258 if (atts[i] != NULL) 1259 fprintf(stdout, "%s'", atts[i]); 1260 } 1261 } 1262 fprintf(stdout, ")\n"); 1263} 1264 1265/** 1266 * endElementDebug: 1267 * @ctxt: An XML parser context 1268 * @name: The element name 1269 * 1270 * called when the end of an element has been detected. 1271 */ 1272static void 1273endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name) 1274{ 1275 callbacks++; 1276 if (noout) 1277 return; 1278 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name); 1279} 1280 1281/** 1282 * charactersDebug: 1283 * @ctxt: An XML parser context 1284 * @ch: a xmlChar string 1285 * @len: the number of xmlChar 1286 * 1287 * receiving some chars from the parser. 1288 * Question: how much at a time ??? 1289 */ 1290static void 1291charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len) 1292{ 1293 char out[40]; 1294 int i; 1295 1296 callbacks++; 1297 if (noout) 1298 return; 1299 for (i = 0;(i<len) && (i < 30);i++) 1300 out[i] = ch[i]; 1301 out[i] = 0; 1302 1303 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len); 1304} 1305 1306/** 1307 * referenceDebug: 1308 * @ctxt: An XML parser context 1309 * @name: The entity name 1310 * 1311 * called when an entity reference is detected. 1312 */ 1313static void 1314referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name) 1315{ 1316 callbacks++; 1317 if (noout) 1318 return; 1319 fprintf(stdout, "SAX.reference(%s)\n", name); 1320} 1321 1322/** 1323 * ignorableWhitespaceDebug: 1324 * @ctxt: An XML parser context 1325 * @ch: a xmlChar string 1326 * @start: the first char in the string 1327 * @len: the number of xmlChar 1328 * 1329 * receiving some ignorable whitespaces from the parser. 1330 * Question: how much at a time ??? 1331 */ 1332static void 1333ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len) 1334{ 1335 char out[40]; 1336 int i; 1337 1338 callbacks++; 1339 if (noout) 1340 return; 1341 for (i = 0;(i<len) && (i < 30);i++) 1342 out[i] = ch[i]; 1343 out[i] = 0; 1344 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len); 1345} 1346 1347/** 1348 * processingInstructionDebug: 1349 * @ctxt: An XML parser context 1350 * @target: the target name 1351 * @data: the PI data's 1352 * @len: the number of xmlChar 1353 * 1354 * A processing instruction has been parsed. 1355 */ 1356static void 1357processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target, 1358 const xmlChar *data) 1359{ 1360 callbacks++; 1361 if (noout) 1362 return; 1363 if (data != NULL) 1364 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n", 1365 (char *) target, (char *) data); 1366 else 1367 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n", 1368 (char *) target); 1369} 1370 1371/** 1372 * cdataBlockDebug: 1373 * @ctx: the user data (XML parser context) 1374 * @value: The pcdata content 1375 * @len: the block length 1376 * 1377 * called when a pcdata block has been parsed 1378 */ 1379static void 1380cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len) 1381{ 1382 callbacks++; 1383 if (noout) 1384 return; 1385 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n", 1386 (char *) value, len); 1387} 1388 1389/** 1390 * commentDebug: 1391 * @ctxt: An XML parser context 1392 * @value: the comment content 1393 * 1394 * A comment has been parsed. 1395 */ 1396static void 1397commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value) 1398{ 1399 callbacks++; 1400 if (noout) 1401 return; 1402 fprintf(stdout, "SAX.comment(%s)\n", value); 1403} 1404 1405/** 1406 * warningDebug: 1407 * @ctxt: An XML parser context 1408 * @msg: the message to display/transmit 1409 * @...: extra parameters for the message display 1410 * 1411 * Display and format a warning messages, gives file, line, position and 1412 * extra parameters. 1413 */ 1414static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) 1415warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) 1416{ 1417 va_list args; 1418 1419 callbacks++; 1420 if (noout) 1421 return; 1422 va_start(args, msg); 1423 fprintf(stdout, "SAX.warning: "); 1424 vfprintf(stdout, msg, args); 1425 va_end(args); 1426} 1427 1428/** 1429 * errorDebug: 1430 * @ctxt: An XML parser context 1431 * @msg: the message to display/transmit 1432 * @...: extra parameters for the message display 1433 * 1434 * Display and format a error messages, gives file, line, position and 1435 * extra parameters. 1436 */ 1437static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) 1438errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) 1439{ 1440 va_list args; 1441 1442 callbacks++; 1443 if (noout) 1444 return; 1445 va_start(args, msg); 1446 fprintf(stdout, "SAX.error: "); 1447 vfprintf(stdout, msg, args); 1448 va_end(args); 1449} 1450 1451/** 1452 * fatalErrorDebug: 1453 * @ctxt: An XML parser context 1454 * @msg: the message to display/transmit 1455 * @...: extra parameters for the message display 1456 * 1457 * Display and format a fatalError messages, gives file, line, position and 1458 * extra parameters. 1459 */ 1460static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) 1461fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) 1462{ 1463 va_list args; 1464 1465 callbacks++; 1466 if (noout) 1467 return; 1468 va_start(args, msg); 1469 fprintf(stdout, "SAX.fatalError: "); 1470 vfprintf(stdout, msg, args); 1471 va_end(args); 1472} 1473 1474static xmlSAXHandler debugSAXHandlerStruct = { 1475 internalSubsetDebug, 1476 isStandaloneDebug, 1477 hasInternalSubsetDebug, 1478 hasExternalSubsetDebug, 1479 resolveEntityDebug, 1480 getEntityDebug, 1481 entityDeclDebug, 1482 notationDeclDebug, 1483 attributeDeclDebug, 1484 elementDeclDebug, 1485 unparsedEntityDeclDebug, 1486 setDocumentLocatorDebug, 1487 startDocumentDebug, 1488 endDocumentDebug, 1489 startElementDebug, 1490 endElementDebug, 1491 referenceDebug, 1492 charactersDebug, 1493 ignorableWhitespaceDebug, 1494 processingInstructionDebug, 1495 commentDebug, 1496 warningDebug, 1497 errorDebug, 1498 fatalErrorDebug, 1499 getParameterEntityDebug, 1500 cdataBlockDebug, 1501 externalSubsetDebug, 1502 1, 1503 NULL, 1504 NULL, 1505 NULL, 1506 NULL 1507}; 1508 1509xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct; 1510 1511/* 1512 * SAX2 specific callbacks 1513 */ 1514/** 1515 * startElementNsDebug: 1516 * @ctxt: An XML parser context 1517 * @name: The element name 1518 * 1519 * called when an opening tag has been processed. 1520 */ 1521static void 1522startElementNsDebug(void *ctx ATTRIBUTE_UNUSED, 1523 const xmlChar *localname, 1524 const xmlChar *prefix, 1525 const xmlChar *URI, 1526 int nb_namespaces, 1527 const xmlChar **namespaces, 1528 int nb_attributes, 1529 int nb_defaulted, 1530 const xmlChar **attributes) 1531{ 1532 int i; 1533 1534 callbacks++; 1535 if (noout) 1536 return; 1537 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname); 1538 if (prefix == NULL) 1539 fprintf(stdout, ", NULL"); 1540 else 1541 fprintf(stdout, ", %s", (char *) prefix); 1542 if (URI == NULL) 1543 fprintf(stdout, ", NULL"); 1544 else 1545 fprintf(stdout, ", '%s'", (char *) URI); 1546 fprintf(stdout, ", %d", nb_namespaces); 1547 1548 if (namespaces != NULL) { 1549 for (i = 0;i < nb_namespaces * 2;i++) { 1550 fprintf(stdout, ", xmlns"); 1551 if (namespaces[i] != NULL) 1552 fprintf(stdout, ":%s", namespaces[i]); 1553 i++; 1554 fprintf(stdout, "='%s'", namespaces[i]); 1555 } 1556 } 1557 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted); 1558 if (attributes != NULL) { 1559 for (i = 0;i < nb_attributes * 5;i += 5) { 1560 if (attributes[i + 1] != NULL) 1561 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]); 1562 else 1563 fprintf(stdout, ", %s='", attributes[i]); 1564 fprintf(stdout, "%.4s...', %d", attributes[i + 3], 1565 (int)(attributes[i + 4] - attributes[i + 3])); 1566 } 1567 } 1568 fprintf(stdout, ")\n"); 1569} 1570 1571/** 1572 * endElementDebug: 1573 * @ctxt: An XML parser context 1574 * @name: The element name 1575 * 1576 * called when the end of an element has been detected. 1577 */ 1578static void 1579endElementNsDebug(void *ctx ATTRIBUTE_UNUSED, 1580 const xmlChar *localname, 1581 const xmlChar *prefix, 1582 const xmlChar *URI) 1583{ 1584 callbacks++; 1585 if (noout) 1586 return; 1587 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname); 1588 if (prefix == NULL) 1589 fprintf(stdout, ", NULL"); 1590 else 1591 fprintf(stdout, ", %s", (char *) prefix); 1592 if (URI == NULL) 1593 fprintf(stdout, ", NULL)\n"); 1594 else 1595 fprintf(stdout, ", '%s')\n", (char *) URI); 1596} 1597 1598static xmlSAXHandler debugSAX2HandlerStruct = { 1599 internalSubsetDebug, 1600 isStandaloneDebug, 1601 hasInternalSubsetDebug, 1602 hasExternalSubsetDebug, 1603 resolveEntityDebug, 1604 getEntityDebug, 1605 entityDeclDebug, 1606 notationDeclDebug, 1607 attributeDeclDebug, 1608 elementDeclDebug, 1609 unparsedEntityDeclDebug, 1610 setDocumentLocatorDebug, 1611 startDocumentDebug, 1612 endDocumentDebug, 1613 NULL, 1614 NULL, 1615 referenceDebug, 1616 charactersDebug, 1617 ignorableWhitespaceDebug, 1618 processingInstructionDebug, 1619 commentDebug, 1620 warningDebug, 1621 errorDebug, 1622 fatalErrorDebug, 1623 getParameterEntityDebug, 1624 cdataBlockDebug, 1625 externalSubsetDebug, 1626 XML_SAX2_MAGIC, 1627 NULL, 1628 startElementNsDebug, 1629 endElementNsDebug, 1630 NULL 1631}; 1632 1633static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct; 1634 1635static void 1636testSAX(const char *filename) { 1637 xmlSAXHandlerPtr handler; 1638 const char *user_data = "user_data"; /* mostly for debugging */ 1639 xmlParserInputBufferPtr buf = NULL; 1640 xmlParserInputPtr inputStream; 1641 xmlParserCtxtPtr ctxt = NULL; 1642 xmlSAXHandlerPtr old_sax = NULL; 1643 1644 callbacks = 0; 1645 1646 if (noout) { 1647 handler = emptySAXHandler; 1648#ifdef LIBXML_SAX1_ENABLED 1649 } else if (sax1) { 1650 handler = debugSAXHandler; 1651#endif 1652 } else { 1653 handler = debugSAX2Handler; 1654 } 1655 1656 /* 1657 * it's not the simplest code but the most generic in term of I/O 1658 */ 1659 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE); 1660 if (buf == NULL) { 1661 goto error; 1662 } 1663 1664#ifdef LIBXML_SCHEMAS_ENABLED 1665 if (wxschemas != NULL) { 1666 int ret; 1667 xmlSchemaValidCtxtPtr vctxt; 1668 1669 vctxt = xmlSchemaNewValidCtxt(wxschemas); 1670 xmlSchemaSetValidErrors(vctxt, 1671 (xmlSchemaValidityErrorFunc) fprintf, 1672 (xmlSchemaValidityWarningFunc) fprintf, 1673 stderr); 1674 xmlSchemaValidateSetFilename(vctxt, filename); 1675 1676 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler, 1677 (void *)user_data); 1678 if (repeat == 0) { 1679 if (ret == 0) { 1680 fprintf(stderr, "%s validates\n", filename); 1681 } else if (ret > 0) { 1682 fprintf(stderr, "%s fails to validate\n", filename); 1683 progresult = XMLLINT_ERR_VALID; 1684 } else { 1685 fprintf(stderr, "%s validation generated an internal error\n", 1686 filename); 1687 progresult = XMLLINT_ERR_VALID; 1688 } 1689 } 1690 xmlSchemaFreeValidCtxt(vctxt); 1691 } else 1692#endif 1693 { 1694 /* 1695 * Create the parser context amd hook the input 1696 */ 1697 ctxt = xmlNewParserCtxt(); 1698 if (ctxt == NULL) { 1699 xmlFreeParserInputBuffer(buf); 1700 goto error; 1701 } 1702 old_sax = ctxt->sax; 1703 ctxt->sax = handler; 1704 ctxt->userData = (void *) user_data; 1705 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE); 1706 if (inputStream == NULL) { 1707 xmlFreeParserInputBuffer(buf); 1708 goto error; 1709 } 1710 inputPush(ctxt, inputStream); 1711 1712 /* do the parsing */ 1713 xmlParseDocument(ctxt); 1714 1715 if (ctxt->myDoc != NULL) { 1716 fprintf(stderr, "SAX generated a doc !\n"); 1717 xmlFreeDoc(ctxt->myDoc); 1718 ctxt->myDoc = NULL; 1719 } 1720 } 1721 1722error: 1723 if (ctxt != NULL) { 1724 ctxt->sax = old_sax; 1725 xmlFreeParserCtxt(ctxt); 1726 } 1727} 1728 1729/************************************************************************ 1730 * * 1731 * Stream Test processing * 1732 * * 1733 ************************************************************************/ 1734#ifdef LIBXML_READER_ENABLED 1735static void processNode(xmlTextReaderPtr reader) { 1736 const xmlChar *name, *value; 1737 int type, empty; 1738 1739 type = xmlTextReaderNodeType(reader); 1740 empty = xmlTextReaderIsEmptyElement(reader); 1741 1742 if (debug) { 1743 name = xmlTextReaderConstName(reader); 1744 if (name == NULL) 1745 name = BAD_CAST "--"; 1746 1747 value = xmlTextReaderConstValue(reader); 1748 1749 1750 printf("%d %d %s %d %d", 1751 xmlTextReaderDepth(reader), 1752 type, 1753 name, 1754 empty, 1755 xmlTextReaderHasValue(reader)); 1756 if (value == NULL) 1757 printf("\n"); 1758 else { 1759 printf(" %s\n", value); 1760 } 1761 } 1762#ifdef LIBXML_PATTERN_ENABLED 1763 if (patternc) { 1764 xmlChar *path = NULL; 1765 int match = -1; 1766 1767 if (type == XML_READER_TYPE_ELEMENT) { 1768 /* do the check only on element start */ 1769 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader)); 1770 1771 if (match) { 1772#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED) 1773 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader)); 1774 printf("Node %s matches pattern %s\n", path, pattern); 1775#else 1776 printf("Node %s matches pattern %s\n", 1777 xmlTextReaderConstName(reader), pattern); 1778#endif 1779 } 1780 } 1781 if (patstream != NULL) { 1782 int ret; 1783 1784 if (type == XML_READER_TYPE_ELEMENT) { 1785 ret = xmlStreamPush(patstream, 1786 xmlTextReaderConstLocalName(reader), 1787 xmlTextReaderConstNamespaceUri(reader)); 1788 if (ret < 0) { 1789 fprintf(stderr, "xmlStreamPush() failure\n"); 1790 xmlFreeStreamCtxt(patstream); 1791 patstream = NULL; 1792 } else if (ret != match) { 1793#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED) 1794 if (path == NULL) { 1795 path = xmlGetNodePath( 1796 xmlTextReaderCurrentNode(reader)); 1797 } 1798#endif 1799 fprintf(stderr, 1800 "xmlPatternMatch and xmlStreamPush disagree\n"); 1801 if (path != NULL) 1802 fprintf(stderr, " pattern %s node %s\n", 1803 pattern, path); 1804 else 1805 fprintf(stderr, " pattern %s node %s\n", 1806 pattern, xmlTextReaderConstName(reader)); 1807 } 1808 1809 } 1810 if ((type == XML_READER_TYPE_END_ELEMENT) || 1811 ((type == XML_READER_TYPE_ELEMENT) && (empty))) { 1812 ret = xmlStreamPop(patstream); 1813 if (ret < 0) { 1814 fprintf(stderr, "xmlStreamPop() failure\n"); 1815 xmlFreeStreamCtxt(patstream); 1816 patstream = NULL; 1817 } 1818 } 1819 } 1820 if (path != NULL) 1821 xmlFree(path); 1822 } 1823#endif 1824} 1825 1826static void streamFile(char *filename) { 1827 xmlTextReaderPtr reader; 1828 int ret; 1829#ifdef HAVE_MMAP 1830 int fd = -1; 1831 struct stat info; 1832 const char *base = NULL; 1833 xmlParserInputBufferPtr input = NULL; 1834 1835 if (memory) { 1836 if (stat(filename, &info) < 0) 1837 return; 1838 if ((fd = open(filename, O_RDONLY)) < 0) 1839 return; 1840 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ; 1841 if (base == (void *) MAP_FAILED) { 1842 close(fd); 1843 fprintf(stderr, "mmap failure for file %s\n", filename); 1844 progresult = XMLLINT_ERR_RDFILE; 1845 return; 1846 } 1847 1848 reader = xmlReaderForMemory(base, info.st_size, filename, 1849 NULL, options); 1850 } else 1851#endif 1852 reader = xmlReaderForFile(filename, NULL, options); 1853#ifdef LIBXML_PATTERN_ENABLED 1854 if (pattern != NULL) { 1855 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL); 1856 if (patternc == NULL) { 1857 xmlGenericError(xmlGenericErrorContext, 1858 "Pattern %s failed to compile\n", pattern); 1859 progresult = XMLLINT_ERR_SCHEMAPAT; 1860 pattern = NULL; 1861 } 1862 } 1863 if (patternc != NULL) { 1864 patstream = xmlPatternGetStreamCtxt(patternc); 1865 if (patstream != NULL) { 1866 ret = xmlStreamPush(patstream, NULL, NULL); 1867 if (ret < 0) { 1868 fprintf(stderr, "xmlStreamPush() failure\n"); 1869 xmlFreeStreamCtxt(patstream); 1870 patstream = NULL; 1871 } 1872 } 1873 } 1874#endif 1875 1876 1877 if (reader != NULL) { 1878#ifdef LIBXML_VALID_ENABLED 1879 if (valid) 1880 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1); 1881 else 1882#endif /* LIBXML_VALID_ENABLED */ 1883 if (loaddtd) 1884 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1); 1885#ifdef LIBXML_SCHEMAS_ENABLED 1886 if (relaxng != NULL) { 1887 if ((timing) && (!repeat)) { 1888 startTimer(); 1889 } 1890 ret = xmlTextReaderRelaxNGValidate(reader, relaxng); 1891 if (ret < 0) { 1892 xmlGenericError(xmlGenericErrorContext, 1893 "Relax-NG schema %s failed to compile\n", relaxng); 1894 progresult = XMLLINT_ERR_SCHEMACOMP; 1895 relaxng = NULL; 1896 } 1897 if ((timing) && (!repeat)) { 1898 endTimer("Compiling the schemas"); 1899 } 1900 } 1901 if (schema != NULL) { 1902 if ((timing) && (!repeat)) { 1903 startTimer(); 1904 } 1905 ret = xmlTextReaderSchemaValidate(reader, schema); 1906 if (ret < 0) { 1907 xmlGenericError(xmlGenericErrorContext, 1908 "XSD schema %s failed to compile\n", schema); 1909 progresult = XMLLINT_ERR_SCHEMACOMP; 1910 schema = NULL; 1911 } 1912 if ((timing) && (!repeat)) { 1913 endTimer("Compiling the schemas"); 1914 } 1915 } 1916#endif 1917 1918 /* 1919 * Process all nodes in sequence 1920 */ 1921 if ((timing) && (!repeat)) { 1922 startTimer(); 1923 } 1924 ret = xmlTextReaderRead(reader); 1925 while (ret == 1) { 1926 if ((debug) 1927#ifdef LIBXML_PATTERN_ENABLED 1928 || (patternc) 1929#endif 1930 ) 1931 processNode(reader); 1932 ret = xmlTextReaderRead(reader); 1933 } 1934 if ((timing) && (!repeat)) { 1935#ifdef LIBXML_SCHEMAS_ENABLED 1936 if (relaxng != NULL) 1937 endTimer("Parsing and validating"); 1938 else 1939#endif 1940#ifdef LIBXML_VALID_ENABLED 1941 if (valid) 1942 endTimer("Parsing and validating"); 1943 else 1944#endif 1945 endTimer("Parsing"); 1946 } 1947 1948#ifdef LIBXML_VALID_ENABLED 1949 if (valid) { 1950 if (xmlTextReaderIsValid(reader) != 1) { 1951 xmlGenericError(xmlGenericErrorContext, 1952 "Document %s does not validate\n", filename); 1953 progresult = XMLLINT_ERR_VALID; 1954 } 1955 } 1956#endif /* LIBXML_VALID_ENABLED */ 1957#ifdef LIBXML_SCHEMAS_ENABLED 1958 if ((relaxng != NULL) || (schema != NULL)) { 1959 if (xmlTextReaderIsValid(reader) != 1) { 1960 fprintf(stderr, "%s fails to validate\n", filename); 1961 progresult = XMLLINT_ERR_VALID; 1962 } else { 1963 fprintf(stderr, "%s validates\n", filename); 1964 } 1965 } 1966#endif 1967 /* 1968 * Done, cleanup and status 1969 */ 1970 xmlFreeTextReader(reader); 1971 if (ret != 0) { 1972 fprintf(stderr, "%s : failed to parse\n", filename); 1973 progresult = XMLLINT_ERR_UNCLASS; 1974 } 1975 } else { 1976 fprintf(stderr, "Unable to open %s\n", filename); 1977 progresult = XMLLINT_ERR_UNCLASS; 1978 } 1979#ifdef LIBXML_PATTERN_ENABLED 1980 if (patstream != NULL) { 1981 xmlFreeStreamCtxt(patstream); 1982 patstream = NULL; 1983 } 1984#endif 1985#ifdef HAVE_MMAP 1986 if (memory) { 1987 xmlFreeParserInputBuffer(input); 1988 munmap((char *) base, info.st_size); 1989 close(fd); 1990 } 1991#endif 1992} 1993 1994static void walkDoc(xmlDocPtr doc) { 1995 xmlTextReaderPtr reader; 1996 int ret; 1997 1998#ifdef LIBXML_PATTERN_ENABLED 1999 xmlNodePtr root; 2000 const xmlChar *namespaces[22]; 2001 int i; 2002 xmlNsPtr ns; 2003 2004 root = xmlDocGetRootElement(doc); 2005 if (root == NULL ) { 2006 xmlGenericError(xmlGenericErrorContext, 2007 "Document does not have a root element"); 2008 progresult = XMLLINT_ERR_UNCLASS; 2009 return; 2010 } 2011 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) { 2012 namespaces[i++] = ns->href; 2013 namespaces[i++] = ns->prefix; 2014 } 2015 namespaces[i++] = NULL; 2016 namespaces[i] = NULL; 2017 2018 if (pattern != NULL) { 2019 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict, 2020 0, &namespaces[0]); 2021 if (patternc == NULL) { 2022 xmlGenericError(xmlGenericErrorContext, 2023 "Pattern %s failed to compile\n", pattern); 2024 progresult = XMLLINT_ERR_SCHEMAPAT; 2025 pattern = NULL; 2026 } 2027 } 2028 if (patternc != NULL) { 2029 patstream = xmlPatternGetStreamCtxt(patternc); 2030 if (patstream != NULL) { 2031 ret = xmlStreamPush(patstream, NULL, NULL); 2032 if (ret < 0) { 2033 fprintf(stderr, "xmlStreamPush() failure\n"); 2034 xmlFreeStreamCtxt(patstream); 2035 patstream = NULL; 2036 } 2037 } 2038 } 2039#endif /* LIBXML_PATTERN_ENABLED */ 2040 reader = xmlReaderWalker(doc); 2041 if (reader != NULL) { 2042 if ((timing) && (!repeat)) { 2043 startTimer(); 2044 } 2045 ret = xmlTextReaderRead(reader); 2046 while (ret == 1) { 2047 if ((debug) 2048#ifdef LIBXML_PATTERN_ENABLED 2049 || (patternc) 2050#endif 2051 ) 2052 processNode(reader); 2053 ret = xmlTextReaderRead(reader); 2054 } 2055 if ((timing) && (!repeat)) { 2056 endTimer("walking through the doc"); 2057 } 2058 xmlFreeTextReader(reader); 2059 if (ret != 0) { 2060 fprintf(stderr, "failed to walk through the doc\n"); 2061 progresult = XMLLINT_ERR_UNCLASS; 2062 } 2063 } else { 2064 fprintf(stderr, "Failed to crate a reader from the document\n"); 2065 progresult = XMLLINT_ERR_UNCLASS; 2066 } 2067#ifdef LIBXML_PATTERN_ENABLED 2068 if (patstream != NULL) { 2069 xmlFreeStreamCtxt(patstream); 2070 patstream = NULL; 2071 } 2072#endif 2073} 2074#endif /* LIBXML_READER_ENABLED */ 2075 2076#ifdef LIBXML_XPATH_ENABLED 2077/************************************************************************ 2078 * * 2079 * XPath Query * 2080 * * 2081 ************************************************************************/ 2082 2083static void doXPathDump(xmlXPathObjectPtr cur) { 2084 switch(cur->type) { 2085 case XPATH_NODESET: { 2086 int i; 2087 xmlNodePtr node; 2088#ifdef LIBXML_OUTPUT_ENABLED 2089 xmlSaveCtxtPtr ctxt; 2090 2091 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) { 2092 fprintf(stderr, "XPath set is empty\n"); 2093 progresult = XMLLINT_ERR_XPATH; 2094 break; 2095 } 2096 ctxt = xmlSaveToFd(1, NULL, 0); 2097 if (ctxt == NULL) { 2098 fprintf(stderr, "Out of memory for XPath\n"); 2099 progresult = XMLLINT_ERR_MEM; 2100 return; 2101 } 2102 for (i = 0;i < cur->nodesetval->nodeNr;i++) { 2103 node = cur->nodesetval->nodeTab[i]; 2104 xmlSaveTree(ctxt, node); 2105 } 2106 xmlSaveClose(ctxt); 2107#else 2108 printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr); 2109#endif 2110 break; 2111 } 2112 case XPATH_BOOLEAN: 2113 if (cur->boolval) printf("true"); 2114 else printf("false"); 2115 break; 2116 case XPATH_NUMBER: 2117 switch (xmlXPathIsInf(cur->floatval)) { 2118 case 1: 2119 printf("Infinity"); 2120 break; 2121 case -1: 2122 printf("-Infinity"); 2123 break; 2124 default: 2125 if (xmlXPathIsNaN(cur->floatval)) { 2126 printf("NaN"); 2127 } else { 2128 printf("%0g", cur->floatval); 2129 } 2130 } 2131 break; 2132 case XPATH_STRING: 2133 printf("%s", (const char *) cur->stringval); 2134 break; 2135 case XPATH_UNDEFINED: 2136 fprintf(stderr, "XPath Object is uninitialized\n"); 2137 progresult = XMLLINT_ERR_XPATH; 2138 break; 2139 default: 2140 fprintf(stderr, "XPath object of unexpected type\n"); 2141 progresult = XMLLINT_ERR_XPATH; 2142 break; 2143 } 2144} 2145 2146static void doXPathQuery(xmlDocPtr doc, const char *query) { 2147 xmlXPathContextPtr ctxt; 2148 xmlXPathObjectPtr res; 2149 2150 ctxt = xmlXPathNewContext(doc); 2151 if (ctxt == NULL) { 2152 fprintf(stderr, "Out of memory for XPath\n"); 2153 progresult = XMLLINT_ERR_MEM; 2154 return; 2155 } 2156 ctxt->node = (xmlNodePtr) doc; 2157 res = xmlXPathEval(BAD_CAST query, ctxt); 2158 xmlXPathFreeContext(ctxt); 2159 2160 if (res == NULL) { 2161 fprintf(stderr, "XPath evaluation failure\n"); 2162 progresult = XMLLINT_ERR_XPATH; 2163 return; 2164 } 2165 doXPathDump(res); 2166 xmlXPathFreeObject(res); 2167} 2168#endif /* LIBXML_XPATH_ENABLED */ 2169 2170/************************************************************************ 2171 * * 2172 * Tree Test processing * 2173 * * 2174 ************************************************************************/ 2175static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) { 2176 xmlDocPtr doc = NULL; 2177#ifdef LIBXML_TREE_ENABLED 2178 xmlDocPtr tmp; 2179#endif /* LIBXML_TREE_ENABLED */ 2180 2181 if ((timing) && (!repeat)) 2182 startTimer(); 2183 2184 2185#ifdef LIBXML_TREE_ENABLED 2186 if (filename == NULL) { 2187 if (generate) { 2188 xmlNodePtr n; 2189 2190 doc = xmlNewDoc(BAD_CAST "1.0"); 2191 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL); 2192 xmlNodeSetContent(n, BAD_CAST "abc"); 2193 xmlDocSetRootElement(doc, n); 2194 } 2195 } 2196#endif /* LIBXML_TREE_ENABLED */ 2197#ifdef LIBXML_HTML_ENABLED 2198#ifdef LIBXML_PUSH_ENABLED 2199 else if ((html) && (push)) { 2200 FILE *f; 2201 2202#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) 2203 f = fopen(filename, "rb"); 2204#elif defined(__OS400__) 2205 f = fopen(filename, "rb"); 2206#else 2207 f = fopen(filename, "r"); 2208#endif 2209 if (f != NULL) { 2210 int res; 2211 char chars[4096]; 2212 htmlParserCtxtPtr ctxt; 2213 2214 res = fread(chars, 1, 4, f); 2215 if (res > 0) { 2216 ctxt = htmlCreatePushParserCtxt(NULL, NULL, 2217 chars, res, filename, XML_CHAR_ENCODING_NONE); 2218 xmlCtxtUseOptions(ctxt, options); 2219 while ((res = fread(chars, 1, pushsize, f)) > 0) { 2220 htmlParseChunk(ctxt, chars, res, 0); 2221 } 2222 htmlParseChunk(ctxt, chars, 0, 1); 2223 doc = ctxt->myDoc; 2224 htmlFreeParserCtxt(ctxt); 2225 } 2226 fclose(f); 2227 } 2228 } 2229#endif /* LIBXML_PUSH_ENABLED */ 2230#ifdef HAVE_MMAP 2231 else if ((html) && (memory)) { 2232 int fd; 2233 struct stat info; 2234 const char *base; 2235 if (stat(filename, &info) < 0) 2236 return; 2237 if ((fd = open(filename, O_RDONLY)) < 0) 2238 return; 2239 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ; 2240 if (base == (void *) MAP_FAILED) { 2241 close(fd); 2242 fprintf(stderr, "mmap failure for file %s\n", filename); 2243 progresult = XMLLINT_ERR_RDFILE; 2244 return; 2245 } 2246 2247 doc = htmlReadMemory((char *) base, info.st_size, filename, 2248 NULL, options); 2249 2250 munmap((char *) base, info.st_size); 2251 close(fd); 2252 } 2253#endif 2254 else if (html) { 2255 doc = htmlReadFile(filename, NULL, options); 2256 } 2257#endif /* LIBXML_HTML_ENABLED */ 2258 else { 2259#ifdef LIBXML_PUSH_ENABLED 2260 /* 2261 * build an XML tree from a string; 2262 */ 2263 if (push) { 2264 FILE *f; 2265 2266 /* '-' Usually means stdin -<sven@zen.org> */ 2267 if ((filename[0] == '-') && (filename[1] == 0)) { 2268 f = stdin; 2269 } else { 2270#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) 2271 f = fopen(filename, "rb"); 2272#elif defined(__OS400__) 2273 f = fopen(filename, "rb"); 2274#else 2275 f = fopen(filename, "r"); 2276#endif 2277 } 2278 if (f != NULL) { 2279 int ret; 2280 int res, size = 1024; 2281 char chars[1024]; 2282 xmlParserCtxtPtr ctxt; 2283 2284 /* if (repeat) size = 1024; */ 2285 res = fread(chars, 1, 4, f); 2286 if (res > 0) { 2287 ctxt = xmlCreatePushParserCtxt(NULL, NULL, 2288 chars, res, filename); 2289 xmlCtxtUseOptions(ctxt, options); 2290 while ((res = fread(chars, 1, size, f)) > 0) { 2291 xmlParseChunk(ctxt, chars, res, 0); 2292 } 2293 xmlParseChunk(ctxt, chars, 0, 1); 2294 doc = ctxt->myDoc; 2295 ret = ctxt->wellFormed; 2296 xmlFreeParserCtxt(ctxt); 2297 if (!ret) { 2298 xmlFreeDoc(doc); 2299 doc = NULL; 2300 } 2301 } 2302 if (f != stdin) 2303 fclose(f); 2304 } 2305 } else 2306#endif /* LIBXML_PUSH_ENABLED */ 2307 if (testIO) { 2308 if ((filename[0] == '-') && (filename[1] == 0)) { 2309 doc = xmlReadFd(0, NULL, NULL, options); 2310 } else { 2311 FILE *f; 2312 2313#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) 2314 f = fopen(filename, "rb"); 2315#elif defined(__OS400__) 2316 f = fopen(filename, "rb"); 2317#else 2318 f = fopen(filename, "r"); 2319#endif 2320 if (f != NULL) { 2321 if (rectxt == NULL) 2322 doc = xmlReadIO((xmlInputReadCallback) myRead, 2323 (xmlInputCloseCallback) myClose, f, 2324 filename, NULL, options); 2325 else 2326 doc = xmlCtxtReadIO(rectxt, 2327 (xmlInputReadCallback) myRead, 2328 (xmlInputCloseCallback) myClose, f, 2329 filename, NULL, options); 2330 } else 2331 doc = NULL; 2332 } 2333 } else if (htmlout) { 2334 xmlParserCtxtPtr ctxt; 2335 2336 if (rectxt == NULL) 2337 ctxt = xmlNewParserCtxt(); 2338 else 2339 ctxt = rectxt; 2340 if (ctxt == NULL) { 2341 doc = NULL; 2342 } else { 2343 ctxt->sax->error = xmlHTMLError; 2344 ctxt->sax->warning = xmlHTMLWarning; 2345 ctxt->vctxt.error = xmlHTMLValidityError; 2346 ctxt->vctxt.warning = xmlHTMLValidityWarning; 2347 2348 doc = xmlCtxtReadFile(ctxt, filename, NULL, options); 2349 2350 if (rectxt == NULL) 2351 xmlFreeParserCtxt(ctxt); 2352 } 2353#ifdef HAVE_MMAP 2354 } else if (memory) { 2355 int fd; 2356 struct stat info; 2357 const char *base; 2358 if (stat(filename, &info) < 0) 2359 return; 2360 if ((fd = open(filename, O_RDONLY)) < 0) 2361 return; 2362 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ; 2363 if (base == (void *) MAP_FAILED) { 2364 close(fd); 2365 fprintf(stderr, "mmap failure for file %s\n", filename); 2366 progresult = XMLLINT_ERR_RDFILE; 2367 return; 2368 } 2369 2370 if (rectxt == NULL) 2371 doc = xmlReadMemory((char *) base, info.st_size, 2372 filename, NULL, options); 2373 else 2374 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size, 2375 filename, NULL, options); 2376 2377 munmap((char *) base, info.st_size); 2378 close(fd); 2379#endif 2380#ifdef LIBXML_VALID_ENABLED 2381 } else if (valid) { 2382 xmlParserCtxtPtr ctxt = NULL; 2383 2384 if (rectxt == NULL) 2385 ctxt = xmlNewParserCtxt(); 2386 else 2387 ctxt = rectxt; 2388 if (ctxt == NULL) { 2389 doc = NULL; 2390 } else { 2391 doc = xmlCtxtReadFile(ctxt, filename, NULL, options); 2392 2393 if (ctxt->valid == 0) 2394 progresult = XMLLINT_ERR_RDFILE; 2395 if (rectxt == NULL) 2396 xmlFreeParserCtxt(ctxt); 2397 } 2398#endif /* LIBXML_VALID_ENABLED */ 2399 } else { 2400 if (rectxt != NULL) 2401 doc = xmlCtxtReadFile(rectxt, filename, NULL, options); 2402 else { 2403#ifdef LIBXML_SAX1_ENABLED 2404 if (sax1) 2405 doc = xmlParseFile(filename); 2406 else 2407#endif /* LIBXML_SAX1_ENABLED */ 2408 doc = xmlReadFile(filename, NULL, options); 2409 } 2410 } 2411 } 2412 2413 /* 2414 * If we don't have a document we might as well give up. Do we 2415 * want an error message here? <sven@zen.org> */ 2416 if (doc == NULL) { 2417 progresult = XMLLINT_ERR_UNCLASS; 2418 return; 2419 } 2420 2421 if ((timing) && (!repeat)) { 2422 endTimer("Parsing"); 2423 } 2424 2425 /* 2426 * Remove DOCTYPE nodes 2427 */ 2428 if (dropdtd) { 2429 xmlDtdPtr dtd; 2430 2431 dtd = xmlGetIntSubset(doc); 2432 if (dtd != NULL) { 2433 xmlUnlinkNode((xmlNodePtr)dtd); 2434 xmlFreeDtd(dtd); 2435 } 2436 } 2437 2438#ifdef LIBXML_XINCLUDE_ENABLED 2439 if (xinclude) { 2440 if ((timing) && (!repeat)) { 2441 startTimer(); 2442 } 2443 if (xmlXIncludeProcessFlags(doc, options) < 0) 2444 progresult = XMLLINT_ERR_UNCLASS; 2445 if ((timing) && (!repeat)) { 2446 endTimer("Xinclude processing"); 2447 } 2448 } 2449#endif 2450 2451#ifdef LIBXML_XPATH_ENABLED 2452 if (xpathquery != NULL) { 2453 doXPathQuery(doc, xpathquery); 2454 } 2455#endif 2456 2457#ifdef LIBXML_DEBUG_ENABLED 2458#ifdef LIBXML_XPATH_ENABLED 2459 /* 2460 * shell interaction 2461 */ 2462 if (shell) { 2463 xmlXPathOrderDocElems(doc); 2464 xmlShell(doc, filename, xmlShellReadline, stdout); 2465 } 2466#endif 2467#endif 2468 2469#ifdef LIBXML_TREE_ENABLED 2470 /* 2471 * test intermediate copy if needed. 2472 */ 2473 if (copy) { 2474 tmp = doc; 2475 if (timing) { 2476 startTimer(); 2477 } 2478 doc = xmlCopyDoc(doc, 1); 2479 if (timing) { 2480 endTimer("Copying"); 2481 } 2482 if (timing) { 2483 startTimer(); 2484 } 2485 xmlFreeDoc(tmp); 2486 if (timing) { 2487 endTimer("Freeing original"); 2488 } 2489 } 2490#endif /* LIBXML_TREE_ENABLED */ 2491 2492#ifdef LIBXML_VALID_ENABLED 2493 if ((insert) && (!html)) { 2494 const xmlChar* list[256]; 2495 int nb, i; 2496 xmlNodePtr node; 2497 2498 if (doc->children != NULL) { 2499 node = doc->children; 2500 while ((node != NULL) && (node->last == NULL)) node = node->next; 2501 if (node != NULL) { 2502 nb = xmlValidGetValidElements(node->last, NULL, list, 256); 2503 if (nb < 0) { 2504 fprintf(stderr, "could not get valid list of elements\n"); 2505 } else if (nb == 0) { 2506 fprintf(stderr, "No element can be inserted under root\n"); 2507 } else { 2508 fprintf(stderr, "%d element types can be inserted under root:\n", 2509 nb); 2510 for (i = 0;i < nb;i++) { 2511 fprintf(stderr, "%s\n", (char *) list[i]); 2512 } 2513 } 2514 } 2515 } 2516 }else 2517#endif /* LIBXML_VALID_ENABLED */ 2518#ifdef LIBXML_READER_ENABLED 2519 if (walker) { 2520 walkDoc(doc); 2521 } 2522#endif /* LIBXML_READER_ENABLED */ 2523#ifdef LIBXML_OUTPUT_ENABLED 2524 if (noout == 0) { 2525 int ret; 2526 2527 /* 2528 * print it. 2529 */ 2530#ifdef LIBXML_DEBUG_ENABLED 2531 if (!debug) { 2532#endif 2533 if ((timing) && (!repeat)) { 2534 startTimer(); 2535 } 2536#ifdef LIBXML_HTML_ENABLED 2537 if ((html) && (!xmlout)) { 2538 if (compress) { 2539 htmlSaveFile(output ? output : "-", doc); 2540 } 2541 else if (encoding != NULL) { 2542 if (format == 1) { 2543 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1); 2544 } 2545 else { 2546 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0); 2547 } 2548 } 2549 else if (format == 1) { 2550 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1); 2551 } 2552 else { 2553 FILE *out; 2554 if (output == NULL) 2555 out = stdout; 2556 else { 2557 out = fopen(output,"wb"); 2558 } 2559 if (out != NULL) { 2560 if (htmlDocDump(out, doc) < 0) 2561 progresult = XMLLINT_ERR_OUT; 2562 2563 if (output != NULL) 2564 fclose(out); 2565 } else { 2566 fprintf(stderr, "failed to open %s\n", output); 2567 progresult = XMLLINT_ERR_OUT; 2568 } 2569 } 2570 if ((timing) && (!repeat)) { 2571 endTimer("Saving"); 2572 } 2573 } else 2574#endif 2575#ifdef LIBXML_C14N_ENABLED 2576 if (canonical) { 2577 xmlChar *result = NULL; 2578 int size; 2579 2580 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result); 2581 if (size >= 0) { 2582 if (write(1, result, size) == -1) { 2583 fprintf(stderr, "Can't write data\n"); 2584 } 2585 xmlFree(result); 2586 } else { 2587 fprintf(stderr, "Failed to canonicalize\n"); 2588 progresult = XMLLINT_ERR_OUT; 2589 } 2590 } else if (canonical_11) { 2591 xmlChar *result = NULL; 2592 int size; 2593 2594 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result); 2595 if (size >= 0) { 2596 if (write(1, result, size) == -1) { 2597 fprintf(stderr, "Can't write data\n"); 2598 } 2599 xmlFree(result); 2600 } else { 2601 fprintf(stderr, "Failed to canonicalize\n"); 2602 progresult = XMLLINT_ERR_OUT; 2603 } 2604 } else 2605 if (exc_canonical) { 2606 xmlChar *result = NULL; 2607 int size; 2608 2609 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result); 2610 if (size >= 0) { 2611 if (write(1, result, size) == -1) { 2612 fprintf(stderr, "Can't write data\n"); 2613 } 2614 xmlFree(result); 2615 } else { 2616 fprintf(stderr, "Failed to canonicalize\n"); 2617 progresult = XMLLINT_ERR_OUT; 2618 } 2619 } else 2620#endif 2621#ifdef HAVE_MMAP 2622 if (memory) { 2623 xmlChar *result; 2624 int len; 2625 2626 if (encoding != NULL) { 2627 if (format == 1) { 2628 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1); 2629 } else { 2630 xmlDocDumpMemoryEnc(doc, &result, &len, encoding); 2631 } 2632 } else { 2633 if (format == 1) 2634 xmlDocDumpFormatMemory(doc, &result, &len, 1); 2635 else 2636 xmlDocDumpMemory(doc, &result, &len); 2637 } 2638 if (result == NULL) { 2639 fprintf(stderr, "Failed to save\n"); 2640 progresult = XMLLINT_ERR_OUT; 2641 } else { 2642 if (write(1, result, len) == -1) { 2643 fprintf(stderr, "Can't write data\n"); 2644 } 2645 xmlFree(result); 2646 } 2647 2648 } else 2649#endif /* HAVE_MMAP */ 2650 if (compress) { 2651 xmlSaveFile(output ? output : "-", doc); 2652 } else if (oldout) { 2653 if (encoding != NULL) { 2654 if (format == 1) { 2655 ret = xmlSaveFormatFileEnc(output ? output : "-", doc, 2656 encoding, 1); 2657 } 2658 else { 2659 ret = xmlSaveFileEnc(output ? output : "-", doc, 2660 encoding); 2661 } 2662 if (ret < 0) { 2663 fprintf(stderr, "failed save to %s\n", 2664 output ? output : "-"); 2665 progresult = XMLLINT_ERR_OUT; 2666 } 2667 } else if (format == 1) { 2668 ret = xmlSaveFormatFile(output ? output : "-", doc, 1); 2669 if (ret < 0) { 2670 fprintf(stderr, "failed save to %s\n", 2671 output ? output : "-"); 2672 progresult = XMLLINT_ERR_OUT; 2673 } 2674 } else { 2675 FILE *out; 2676 if (output == NULL) 2677 out = stdout; 2678 else { 2679 out = fopen(output,"wb"); 2680 } 2681 if (out != NULL) { 2682 if (xmlDocDump(out, doc) < 0) 2683 progresult = XMLLINT_ERR_OUT; 2684 2685 if (output != NULL) 2686 fclose(out); 2687 } else { 2688 fprintf(stderr, "failed to open %s\n", output); 2689 progresult = XMLLINT_ERR_OUT; 2690 } 2691 } 2692 } else { 2693 xmlSaveCtxtPtr ctxt; 2694 int saveOpts = 0; 2695 2696 if (format == 1) 2697 saveOpts |= XML_SAVE_FORMAT; 2698 else if (format == 2) 2699 saveOpts |= XML_SAVE_WSNONSIG; 2700 2701#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED) 2702 if (xmlout) 2703 saveOpts |= XML_SAVE_AS_XML; 2704#endif 2705 2706 if (output == NULL) 2707 ctxt = xmlSaveToFd(1, encoding, saveOpts); 2708 else 2709 ctxt = xmlSaveToFilename(output, encoding, saveOpts); 2710 2711 if (ctxt != NULL) { 2712 if (xmlSaveDoc(ctxt, doc) < 0) { 2713 fprintf(stderr, "failed save to %s\n", 2714 output ? output : "-"); 2715 progresult = XMLLINT_ERR_OUT; 2716 } 2717 xmlSaveClose(ctxt); 2718 } else { 2719 progresult = XMLLINT_ERR_OUT; 2720 } 2721 } 2722 if ((timing) && (!repeat)) { 2723 endTimer("Saving"); 2724 } 2725#ifdef LIBXML_DEBUG_ENABLED 2726 } else { 2727 FILE *out; 2728 if (output == NULL) 2729 out = stdout; 2730 else { 2731 out = fopen(output,"wb"); 2732 } 2733 if (out != NULL) { 2734 xmlDebugDumpDocument(out, doc); 2735 2736 if (output != NULL) 2737 fclose(out); 2738 } else { 2739 fprintf(stderr, "failed to open %s\n", output); 2740 progresult = XMLLINT_ERR_OUT; 2741 } 2742 } 2743#endif 2744 } 2745#endif /* LIBXML_OUTPUT_ENABLED */ 2746 2747#ifdef LIBXML_VALID_ENABLED 2748 /* 2749 * A posteriori validation test 2750 */ 2751 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) { 2752 xmlDtdPtr dtd; 2753 2754 if ((timing) && (!repeat)) { 2755 startTimer(); 2756 } 2757 if (dtdvalid != NULL) 2758 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid); 2759 else 2760 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL); 2761 if ((timing) && (!repeat)) { 2762 endTimer("Parsing DTD"); 2763 } 2764 if (dtd == NULL) { 2765 if (dtdvalid != NULL) 2766 xmlGenericError(xmlGenericErrorContext, 2767 "Could not parse DTD %s\n", dtdvalid); 2768 else 2769 xmlGenericError(xmlGenericErrorContext, 2770 "Could not parse DTD %s\n", dtdvalidfpi); 2771 progresult = XMLLINT_ERR_DTD; 2772 } else { 2773 xmlValidCtxtPtr cvp; 2774 2775 if ((cvp = xmlNewValidCtxt()) == NULL) { 2776 xmlGenericError(xmlGenericErrorContext, 2777 "Couldn't allocate validation context\n"); 2778 exit(-1); 2779 } 2780 cvp->userData = (void *) stderr; 2781 cvp->error = (xmlValidityErrorFunc) fprintf; 2782 cvp->warning = (xmlValidityWarningFunc) fprintf; 2783 2784 if ((timing) && (!repeat)) { 2785 startTimer(); 2786 } 2787 if (!xmlValidateDtd(cvp, doc, dtd)) { 2788 if (dtdvalid != NULL) 2789 xmlGenericError(xmlGenericErrorContext, 2790 "Document %s does not validate against %s\n", 2791 filename, dtdvalid); 2792 else 2793 xmlGenericError(xmlGenericErrorContext, 2794 "Document %s does not validate against %s\n", 2795 filename, dtdvalidfpi); 2796 progresult = XMLLINT_ERR_VALID; 2797 } 2798 if ((timing) && (!repeat)) { 2799 endTimer("Validating against DTD"); 2800 } 2801 xmlFreeValidCtxt(cvp); 2802 xmlFreeDtd(dtd); 2803 } 2804 } else if (postvalid) { 2805 xmlValidCtxtPtr cvp; 2806 2807 if ((cvp = xmlNewValidCtxt()) == NULL) { 2808 xmlGenericError(xmlGenericErrorContext, 2809 "Couldn't allocate validation context\n"); 2810 exit(-1); 2811 } 2812 2813 if ((timing) && (!repeat)) { 2814 startTimer(); 2815 } 2816 cvp->userData = (void *) stderr; 2817 cvp->error = (xmlValidityErrorFunc) fprintf; 2818 cvp->warning = (xmlValidityWarningFunc) fprintf; 2819 if (!xmlValidateDocument(cvp, doc)) { 2820 xmlGenericError(xmlGenericErrorContext, 2821 "Document %s does not validate\n", filename); 2822 progresult = XMLLINT_ERR_VALID; 2823 } 2824 if ((timing) && (!repeat)) { 2825 endTimer("Validating"); 2826 } 2827 xmlFreeValidCtxt(cvp); 2828 } 2829#endif /* LIBXML_VALID_ENABLED */ 2830#ifdef LIBXML_SCHEMATRON_ENABLED 2831 if (wxschematron != NULL) { 2832 xmlSchematronValidCtxtPtr ctxt; 2833 int ret; 2834 int flag; 2835 2836 if ((timing) && (!repeat)) { 2837 startTimer(); 2838 } 2839 2840 if (debug) 2841 flag = XML_SCHEMATRON_OUT_XML; 2842 else 2843 flag = XML_SCHEMATRON_OUT_TEXT; 2844 if (noout) 2845 flag |= XML_SCHEMATRON_OUT_QUIET; 2846 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag); 2847#if 0 2848 xmlSchematronSetValidErrors(ctxt, 2849 (xmlSchematronValidityErrorFunc) fprintf, 2850 (xmlSchematronValidityWarningFunc) fprintf, 2851 stderr); 2852#endif 2853 ret = xmlSchematronValidateDoc(ctxt, doc); 2854 if (ret == 0) { 2855 fprintf(stderr, "%s validates\n", filename); 2856 } else if (ret > 0) { 2857 fprintf(stderr, "%s fails to validate\n", filename); 2858 progresult = XMLLINT_ERR_VALID; 2859 } else { 2860 fprintf(stderr, "%s validation generated an internal error\n", 2861 filename); 2862 progresult = XMLLINT_ERR_VALID; 2863 } 2864 xmlSchematronFreeValidCtxt(ctxt); 2865 if ((timing) && (!repeat)) { 2866 endTimer("Validating"); 2867 } 2868 } 2869#endif 2870#ifdef LIBXML_SCHEMAS_ENABLED 2871 if (relaxngschemas != NULL) { 2872 xmlRelaxNGValidCtxtPtr ctxt; 2873 int ret; 2874 2875 if ((timing) && (!repeat)) { 2876 startTimer(); 2877 } 2878 2879 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas); 2880 xmlRelaxNGSetValidErrors(ctxt, 2881 (xmlRelaxNGValidityErrorFunc) fprintf, 2882 (xmlRelaxNGValidityWarningFunc) fprintf, 2883 stderr); 2884 ret = xmlRelaxNGValidateDoc(ctxt, doc); 2885 if (ret == 0) { 2886 fprintf(stderr, "%s validates\n", filename); 2887 } else if (ret > 0) { 2888 fprintf(stderr, "%s fails to validate\n", filename); 2889 progresult = XMLLINT_ERR_VALID; 2890 } else { 2891 fprintf(stderr, "%s validation generated an internal error\n", 2892 filename); 2893 progresult = XMLLINT_ERR_VALID; 2894 } 2895 xmlRelaxNGFreeValidCtxt(ctxt); 2896 if ((timing) && (!repeat)) { 2897 endTimer("Validating"); 2898 } 2899 } else if (wxschemas != NULL) { 2900 xmlSchemaValidCtxtPtr ctxt; 2901 int ret; 2902 2903 if ((timing) && (!repeat)) { 2904 startTimer(); 2905 } 2906 2907 ctxt = xmlSchemaNewValidCtxt(wxschemas); 2908 xmlSchemaSetValidErrors(ctxt, 2909 (xmlSchemaValidityErrorFunc) fprintf, 2910 (xmlSchemaValidityWarningFunc) fprintf, 2911 stderr); 2912 ret = xmlSchemaValidateDoc(ctxt, doc); 2913 if (ret == 0) { 2914 fprintf(stderr, "%s validates\n", filename); 2915 } else if (ret > 0) { 2916 fprintf(stderr, "%s fails to validate\n", filename); 2917 progresult = XMLLINT_ERR_VALID; 2918 } else { 2919 fprintf(stderr, "%s validation generated an internal error\n", 2920 filename); 2921 progresult = XMLLINT_ERR_VALID; 2922 } 2923 xmlSchemaFreeValidCtxt(ctxt); 2924 if ((timing) && (!repeat)) { 2925 endTimer("Validating"); 2926 } 2927 } 2928#endif 2929 2930#ifdef LIBXML_DEBUG_ENABLED 2931#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED) 2932 if ((debugent) && (!html)) 2933 xmlDebugDumpEntities(stderr, doc); 2934#endif 2935#endif 2936 2937 /* 2938 * free it. 2939 */ 2940 if ((timing) && (!repeat)) { 2941 startTimer(); 2942 } 2943 xmlFreeDoc(doc); 2944 if ((timing) && (!repeat)) { 2945 endTimer("Freeing"); 2946 } 2947} 2948 2949/************************************************************************ 2950 * * 2951 * Usage and Main * 2952 * * 2953 ************************************************************************/ 2954 2955static void showVersion(const char *name) { 2956 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion); 2957 fprintf(stderr, " compiled with: "); 2958 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads "); 2959 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree "); 2960 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output "); 2961 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push "); 2962 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader "); 2963 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns "); 2964 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer "); 2965 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 "); 2966 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP "); 2967 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP "); 2968 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid "); 2969 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML "); 2970 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy "); 2971 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N "); 2972 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog "); 2973 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath "); 2974 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer "); 2975 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude "); 2976 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv "); 2977 if (xmlHasFeature(XML_WITH_ICU)) fprintf(stderr, "ICU "); 2978 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X "); 2979 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode "); 2980 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps "); 2981 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata "); 2982 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr "); 2983 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas "); 2984 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron "); 2985 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules "); 2986 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug "); 2987 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug "); 2988 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug "); 2989 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib "); 2990 if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma "); 2991 fprintf(stderr, "\n"); 2992} 2993 2994static void usage(const char *name) { 2995 printf("Usage : %s [options] XMLfiles ...\n", name); 2996#ifdef LIBXML_OUTPUT_ENABLED 2997 printf("\tParse the XML files and output the result of the parsing\n"); 2998#else 2999 printf("\tParse the XML files\n"); 3000#endif /* LIBXML_OUTPUT_ENABLED */ 3001 printf("\t--version : display the version of the XML library used\n"); 3002#ifdef LIBXML_DEBUG_ENABLED 3003 printf("\t--debug : dump a debug tree of the in-memory document\n"); 3004 printf("\t--shell : run a navigating shell\n"); 3005 printf("\t--debugent : debug the entities defined in the document\n"); 3006#else 3007#ifdef LIBXML_READER_ENABLED 3008 printf("\t--debug : dump the nodes content when using --stream\n"); 3009#endif /* LIBXML_READER_ENABLED */ 3010#endif 3011#ifdef LIBXML_TREE_ENABLED 3012 printf("\t--copy : used to test the internal copy implementation\n"); 3013#endif /* LIBXML_TREE_ENABLED */ 3014 printf("\t--recover : output what was parsable on broken XML documents\n"); 3015 printf("\t--huge : remove any internal arbitrary parser limits\n"); 3016 printf("\t--noent : substitute entity references by their value\n"); 3017 printf("\t--noenc : ignore any encoding specified inside the document\n"); 3018 printf("\t--noout : don't output the result tree\n"); 3019 printf("\t--path 'paths': provide a set of paths for resources\n"); 3020 printf("\t--load-trace : print trace of all external entities loaded\n"); 3021 printf("\t--nonet : refuse to fetch DTDs or entities over network\n"); 3022 printf("\t--nocompact : do not generate compact text nodes\n"); 3023 printf("\t--htmlout : output results as HTML\n"); 3024 printf("\t--nowrap : do not put HTML doc wrapper\n"); 3025#ifdef LIBXML_VALID_ENABLED 3026 printf("\t--valid : validate the document in addition to std well-formed check\n"); 3027 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n"); 3028 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n"); 3029 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n"); 3030#endif /* LIBXML_VALID_ENABLED */ 3031 printf("\t--timing : print some timings\n"); 3032 printf("\t--output file or -o file: save to a given file\n"); 3033 printf("\t--repeat : repeat 100 times, for timing or profiling\n"); 3034 printf("\t--insert : ad-hoc test for valid insertions\n"); 3035#ifdef LIBXML_OUTPUT_ENABLED 3036#ifdef HAVE_ZLIB_H 3037 printf("\t--compress : turn on gzip compression of output\n"); 3038#endif 3039#endif /* LIBXML_OUTPUT_ENABLED */ 3040#ifdef LIBXML_HTML_ENABLED 3041 printf("\t--html : use the HTML parser\n"); 3042 printf("\t--xmlout : force to use the XML serializer when using --html\n"); 3043 printf("\t--nodefdtd : do not default HTML doctype\n"); 3044#endif 3045#ifdef LIBXML_PUSH_ENABLED 3046 printf("\t--push : use the push mode of the parser\n"); 3047 printf("\t--pushsmall : use the push mode of the parser using tiny increments\n"); 3048#endif /* LIBXML_PUSH_ENABLED */ 3049#ifdef HAVE_MMAP 3050 printf("\t--memory : parse from memory\n"); 3051#endif 3052 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n"); 3053 printf("\t--nowarning : do not emit warnings from parser/validator\n"); 3054 printf("\t--noblanks : drop (ignorable?) blanks spaces\n"); 3055 printf("\t--nocdata : replace cdata section with text nodes\n"); 3056#ifdef LIBXML_OUTPUT_ENABLED 3057 printf("\t--format : reformat/reindent the output\n"); 3058 printf("\t--encode encoding : output in the given encoding\n"); 3059 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n"); 3060 printf("\t--pretty STYLE : pretty-print in a particular style\n"); 3061 printf("\t 0 Do not pretty print\n"); 3062 printf("\t 1 Format the XML content, as --format\n"); 3063 printf("\t 2 Add whitespace inside tags, preserving content\n"); 3064#endif /* LIBXML_OUTPUT_ENABLED */ 3065 printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n"); 3066 printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n"); 3067 printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n"); 3068#ifdef LIBXML_C14N_ENABLED 3069#endif /* LIBXML_C14N_ENABLED */ 3070 printf("\t--nsclean : remove redundant namespace declarations\n"); 3071 printf("\t--testIO : test user I/O support\n"); 3072#ifdef LIBXML_CATALOG_ENABLED 3073 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n"); 3074 printf("\t otherwise XML Catalogs starting from \n"); 3075 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG); 3076 printf("\t--nocatalogs: deactivate all catalogs\n"); 3077#endif 3078 printf("\t--auto : generate a small doc on the fly\n"); 3079#ifdef LIBXML_XINCLUDE_ENABLED 3080 printf("\t--xinclude : do XInclude processing\n"); 3081 printf("\t--noxincludenode : same but do not generate XInclude nodes\n"); 3082 printf("\t--nofixup-base-uris : do not fixup xml:base uris\n"); 3083#endif 3084 printf("\t--loaddtd : fetch external DTD\n"); 3085 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n"); 3086#ifdef LIBXML_READER_ENABLED 3087 printf("\t--stream : use the streaming interface to process very large files\n"); 3088 printf("\t--walker : create a reader and walk though the resulting doc\n"); 3089#endif /* LIBXML_READER_ENABLED */ 3090#ifdef LIBXML_PATTERN_ENABLED 3091 printf("\t--pattern pattern_value : test the pattern support\n"); 3092#endif 3093 printf("\t--chkregister : verify the node registration code\n"); 3094#ifdef LIBXML_SCHEMAS_ENABLED 3095 printf("\t--relaxng schema : do RelaxNG validation against the schema\n"); 3096 printf("\t--schema schema : do validation against the WXS schema\n"); 3097#endif 3098#ifdef LIBXML_SCHEMATRON_ENABLED 3099 printf("\t--schematron schema : do validation against a schematron\n"); 3100#endif 3101#ifdef LIBXML_SAX1_ENABLED 3102 printf("\t--sax1: use the old SAX1 interfaces for processing\n"); 3103#endif 3104 printf("\t--sax: do not build a tree but work just at the SAX level\n"); 3105 printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n"); 3106#ifdef LIBXML_XPATH_ENABLED 3107 printf("\t--xpath expr: evaluate the XPath expression, imply --noout\n"); 3108#endif 3109 3110 printf("\nLibxml project home page: http://xmlsoft.org/\n"); 3111 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n"); 3112} 3113 3114static void registerNode(xmlNodePtr node) 3115{ 3116 node->_private = malloc(sizeof(long)); 3117 if (node->_private == NULL) { 3118 fprintf(stderr, "Out of memory in xmllint:registerNode()\n"); 3119 exit(XMLLINT_ERR_MEM); 3120 } 3121 *(long*)node->_private = (long) 0x81726354; 3122 nbregister++; 3123} 3124 3125static void deregisterNode(xmlNodePtr node) 3126{ 3127 assert(node->_private != NULL); 3128 assert(*(long*)node->_private == (long) 0x81726354); 3129 free(node->_private); 3130 nbregister--; 3131} 3132 3133int 3134main(int argc, char **argv) { 3135 int i, acount; 3136 int files = 0; 3137 int version = 0; 3138 const char* indent; 3139 3140 if (argc <= 1) { 3141 usage(argv[0]); 3142 return(1); 3143 } 3144 LIBXML_TEST_VERSION 3145 for (i = 1; i < argc ; i++) { 3146 if (!strcmp(argv[i], "-")) 3147 break; 3148 3149 if (argv[i][0] != '-') 3150 continue; 3151 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug"))) 3152 debug++; 3153 else 3154#ifdef LIBXML_DEBUG_ENABLED 3155 if ((!strcmp(argv[i], "-shell")) || 3156 (!strcmp(argv[i], "--shell"))) { 3157 shell++; 3158 noout = 1; 3159 } else 3160#endif 3161#ifdef LIBXML_TREE_ENABLED 3162 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy"))) 3163 copy++; 3164 else 3165#endif /* LIBXML_TREE_ENABLED */ 3166 if ((!strcmp(argv[i], "-recover")) || 3167 (!strcmp(argv[i], "--recover"))) { 3168 recovery++; 3169 options |= XML_PARSE_RECOVER; 3170 } else if ((!strcmp(argv[i], "-huge")) || 3171 (!strcmp(argv[i], "--huge"))) { 3172 options |= XML_PARSE_HUGE; 3173 } else if ((!strcmp(argv[i], "-noent")) || 3174 (!strcmp(argv[i], "--noent"))) { 3175 noent++; 3176 options |= XML_PARSE_NOENT; 3177 } else if ((!strcmp(argv[i], "-noenc")) || 3178 (!strcmp(argv[i], "--noenc"))) { 3179 noenc++; 3180 options |= XML_PARSE_IGNORE_ENC; 3181 } else if ((!strcmp(argv[i], "-nsclean")) || 3182 (!strcmp(argv[i], "--nsclean"))) { 3183 options |= XML_PARSE_NSCLEAN; 3184 } else if ((!strcmp(argv[i], "-nocdata")) || 3185 (!strcmp(argv[i], "--nocdata"))) { 3186 options |= XML_PARSE_NOCDATA; 3187 } else if ((!strcmp(argv[i], "-nodict")) || 3188 (!strcmp(argv[i], "--nodict"))) { 3189 options |= XML_PARSE_NODICT; 3190 } else if ((!strcmp(argv[i], "-version")) || 3191 (!strcmp(argv[i], "--version"))) { 3192 showVersion(argv[0]); 3193 version = 1; 3194 } else if ((!strcmp(argv[i], "-noout")) || 3195 (!strcmp(argv[i], "--noout"))) 3196 noout++; 3197#ifdef LIBXML_OUTPUT_ENABLED 3198 else if ((!strcmp(argv[i], "-o")) || 3199 (!strcmp(argv[i], "-output")) || 3200 (!strcmp(argv[i], "--output"))) { 3201 i++; 3202 output = argv[i]; 3203 } 3204#endif /* LIBXML_OUTPUT_ENABLED */ 3205 else if ((!strcmp(argv[i], "-htmlout")) || 3206 (!strcmp(argv[i], "--htmlout"))) 3207 htmlout++; 3208 else if ((!strcmp(argv[i], "-nowrap")) || 3209 (!strcmp(argv[i], "--nowrap"))) 3210 nowrap++; 3211#ifdef LIBXML_HTML_ENABLED 3212 else if ((!strcmp(argv[i], "-html")) || 3213 (!strcmp(argv[i], "--html"))) { 3214 html++; 3215 } 3216 else if ((!strcmp(argv[i], "-xmlout")) || 3217 (!strcmp(argv[i], "--xmlout"))) { 3218 xmlout++; 3219 } else if ((!strcmp(argv[i], "-nodefdtd")) || 3220 (!strcmp(argv[i], "--nodefdtd"))) { 3221 nodefdtd++; 3222 options |= HTML_PARSE_NODEFDTD; 3223 } 3224#endif /* LIBXML_HTML_ENABLED */ 3225 else if ((!strcmp(argv[i], "-loaddtd")) || 3226 (!strcmp(argv[i], "--loaddtd"))) { 3227 loaddtd++; 3228 options |= XML_PARSE_DTDLOAD; 3229 } else if ((!strcmp(argv[i], "-dtdattr")) || 3230 (!strcmp(argv[i], "--dtdattr"))) { 3231 loaddtd++; 3232 dtdattrs++; 3233 options |= XML_PARSE_DTDATTR; 3234 } 3235#ifdef LIBXML_VALID_ENABLED 3236 else if ((!strcmp(argv[i], "-valid")) || 3237 (!strcmp(argv[i], "--valid"))) { 3238 valid++; 3239 options |= XML_PARSE_DTDVALID; 3240 } else if ((!strcmp(argv[i], "-postvalid")) || 3241 (!strcmp(argv[i], "--postvalid"))) { 3242 postvalid++; 3243 loaddtd++; 3244 options |= XML_PARSE_DTDLOAD; 3245 } else if ((!strcmp(argv[i], "-dtdvalid")) || 3246 (!strcmp(argv[i], "--dtdvalid"))) { 3247 i++; 3248 dtdvalid = argv[i]; 3249 loaddtd++; 3250 options |= XML_PARSE_DTDLOAD; 3251 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) || 3252 (!strcmp(argv[i], "--dtdvalidfpi"))) { 3253 i++; 3254 dtdvalidfpi = argv[i]; 3255 loaddtd++; 3256 options |= XML_PARSE_DTDLOAD; 3257 } 3258#endif /* LIBXML_VALID_ENABLED */ 3259 else if ((!strcmp(argv[i], "-dropdtd")) || 3260 (!strcmp(argv[i], "--dropdtd"))) 3261 dropdtd++; 3262 else if ((!strcmp(argv[i], "-insert")) || 3263 (!strcmp(argv[i], "--insert"))) 3264 insert++; 3265 else if ((!strcmp(argv[i], "-timing")) || 3266 (!strcmp(argv[i], "--timing"))) 3267 timing++; 3268 else if ((!strcmp(argv[i], "-auto")) || 3269 (!strcmp(argv[i], "--auto"))) 3270 generate++; 3271 else if ((!strcmp(argv[i], "-repeat")) || 3272 (!strcmp(argv[i], "--repeat"))) { 3273 if (repeat) 3274 repeat *= 10; 3275 else 3276 repeat = 100; 3277 } 3278#ifdef LIBXML_PUSH_ENABLED 3279 else if ((!strcmp(argv[i], "-push")) || 3280 (!strcmp(argv[i], "--push"))) 3281 push++; 3282 else if ((!strcmp(argv[i], "-pushsmall")) || 3283 (!strcmp(argv[i], "--pushsmall"))) { 3284 push++; 3285 pushsize = 10; 3286 } 3287#endif /* LIBXML_PUSH_ENABLED */ 3288#ifdef HAVE_MMAP 3289 else if ((!strcmp(argv[i], "-memory")) || 3290 (!strcmp(argv[i], "--memory"))) 3291 memory++; 3292#endif 3293 else if ((!strcmp(argv[i], "-testIO")) || 3294 (!strcmp(argv[i], "--testIO"))) 3295 testIO++; 3296#ifdef LIBXML_XINCLUDE_ENABLED 3297 else if ((!strcmp(argv[i], "-xinclude")) || 3298 (!strcmp(argv[i], "--xinclude"))) { 3299 xinclude++; 3300 options |= XML_PARSE_XINCLUDE; 3301 } 3302 else if ((!strcmp(argv[i], "-noxincludenode")) || 3303 (!strcmp(argv[i], "--noxincludenode"))) { 3304 xinclude++; 3305 options |= XML_PARSE_XINCLUDE; 3306 options |= XML_PARSE_NOXINCNODE; 3307 } 3308 else if ((!strcmp(argv[i], "-nofixup-base-uris")) || 3309 (!strcmp(argv[i], "--nofixup-base-uris"))) { 3310 xinclude++; 3311 options |= XML_PARSE_XINCLUDE; 3312 options |= XML_PARSE_NOBASEFIX; 3313 } 3314#endif 3315#ifdef LIBXML_OUTPUT_ENABLED 3316#ifdef HAVE_ZLIB_H 3317 else if ((!strcmp(argv[i], "-compress")) || 3318 (!strcmp(argv[i], "--compress"))) { 3319 compress++; 3320 xmlSetCompressMode(9); 3321 } 3322#endif 3323#endif /* LIBXML_OUTPUT_ENABLED */ 3324 else if ((!strcmp(argv[i], "-nowarning")) || 3325 (!strcmp(argv[i], "--nowarning"))) { 3326 xmlGetWarningsDefaultValue = 0; 3327 xmlPedanticParserDefault(0); 3328 options |= XML_PARSE_NOWARNING; 3329 } 3330 else if ((!strcmp(argv[i], "-pedantic")) || 3331 (!strcmp(argv[i], "--pedantic"))) { 3332 xmlGetWarningsDefaultValue = 1; 3333 xmlPedanticParserDefault(1); 3334 options |= XML_PARSE_PEDANTIC; 3335 } 3336#ifdef LIBXML_DEBUG_ENABLED 3337 else if ((!strcmp(argv[i], "-debugent")) || 3338 (!strcmp(argv[i], "--debugent"))) { 3339 debugent++; 3340 xmlParserDebugEntities = 1; 3341 } 3342#endif 3343#ifdef LIBXML_C14N_ENABLED 3344 else if ((!strcmp(argv[i], "-c14n")) || 3345 (!strcmp(argv[i], "--c14n"))) { 3346 canonical++; 3347 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD; 3348 } 3349 else if ((!strcmp(argv[i], "-c14n11")) || 3350 (!strcmp(argv[i], "--c14n11"))) { 3351 canonical_11++; 3352 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD; 3353 } 3354 else if ((!strcmp(argv[i], "-exc-c14n")) || 3355 (!strcmp(argv[i], "--exc-c14n"))) { 3356 exc_canonical++; 3357 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD; 3358 } 3359#endif 3360#ifdef LIBXML_CATALOG_ENABLED 3361 else if ((!strcmp(argv[i], "-catalogs")) || 3362 (!strcmp(argv[i], "--catalogs"))) { 3363 catalogs++; 3364 } else if ((!strcmp(argv[i], "-nocatalogs")) || 3365 (!strcmp(argv[i], "--nocatalogs"))) { 3366 nocatalogs++; 3367 } 3368#endif 3369 else if ((!strcmp(argv[i], "-encode")) || 3370 (!strcmp(argv[i], "--encode"))) { 3371 i++; 3372 encoding = argv[i]; 3373 /* 3374 * OK it's for testing purposes 3375 */ 3376 xmlAddEncodingAlias("UTF-8", "DVEnc"); 3377 } 3378 else if ((!strcmp(argv[i], "-noblanks")) || 3379 (!strcmp(argv[i], "--noblanks"))) { 3380 noblanks++; 3381 xmlKeepBlanksDefault(0); 3382 options |= XML_PARSE_NOBLANKS; 3383 } 3384 else if ((!strcmp(argv[i], "-maxmem")) || 3385 (!strcmp(argv[i], "--maxmem"))) { 3386 i++; 3387 if (sscanf(argv[i], "%d", &maxmem) == 1) { 3388 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc, 3389 myStrdupFunc); 3390 } else { 3391 maxmem = 0; 3392 } 3393 } 3394 else if ((!strcmp(argv[i], "-format")) || 3395 (!strcmp(argv[i], "--format"))) { 3396 noblanks++; 3397#ifdef LIBXML_OUTPUT_ENABLED 3398 format = 1; 3399#endif /* LIBXML_OUTPUT_ENABLED */ 3400 xmlKeepBlanksDefault(0); 3401 } 3402 else if ((!strcmp(argv[i], "-pretty")) || 3403 (!strcmp(argv[i], "--pretty"))) { 3404 i++; 3405#ifdef LIBXML_OUTPUT_ENABLED 3406 if (argv[i] != NULL) { 3407 format = atoi(argv[i]); 3408 if (format == 1) { 3409 noblanks++; 3410 xmlKeepBlanksDefault(0); 3411 } 3412 } 3413#endif /* LIBXML_OUTPUT_ENABLED */ 3414 } 3415#ifdef LIBXML_READER_ENABLED 3416 else if ((!strcmp(argv[i], "-stream")) || 3417 (!strcmp(argv[i], "--stream"))) { 3418 stream++; 3419 } 3420 else if ((!strcmp(argv[i], "-walker")) || 3421 (!strcmp(argv[i], "--walker"))) { 3422 walker++; 3423 noout++; 3424 } 3425#endif /* LIBXML_READER_ENABLED */ 3426#ifdef LIBXML_SAX1_ENABLED 3427 else if ((!strcmp(argv[i], "-sax1")) || 3428 (!strcmp(argv[i], "--sax1"))) { 3429 sax1++; 3430 options |= XML_PARSE_SAX1; 3431 } 3432#endif /* LIBXML_SAX1_ENABLED */ 3433 else if ((!strcmp(argv[i], "-sax")) || 3434 (!strcmp(argv[i], "--sax"))) { 3435 sax++; 3436 } 3437 else if ((!strcmp(argv[i], "-chkregister")) || 3438 (!strcmp(argv[i], "--chkregister"))) { 3439 chkregister++; 3440#ifdef LIBXML_SCHEMAS_ENABLED 3441 } else if ((!strcmp(argv[i], "-relaxng")) || 3442 (!strcmp(argv[i], "--relaxng"))) { 3443 i++; 3444 relaxng = argv[i]; 3445 noent++; 3446 options |= XML_PARSE_NOENT; 3447 } else if ((!strcmp(argv[i], "-schema")) || 3448 (!strcmp(argv[i], "--schema"))) { 3449 i++; 3450 schema = argv[i]; 3451 noent++; 3452#endif 3453#ifdef LIBXML_SCHEMATRON_ENABLED 3454 } else if ((!strcmp(argv[i], "-schematron")) || 3455 (!strcmp(argv[i], "--schematron"))) { 3456 i++; 3457 schematron = argv[i]; 3458 noent++; 3459#endif 3460 } else if ((!strcmp(argv[i], "-nonet")) || 3461 (!strcmp(argv[i], "--nonet"))) { 3462 options |= XML_PARSE_NONET; 3463 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader); 3464 } else if ((!strcmp(argv[i], "-nocompact")) || 3465 (!strcmp(argv[i], "--nocompact"))) { 3466 options &= ~XML_PARSE_COMPACT; 3467 } else if ((!strcmp(argv[i], "-load-trace")) || 3468 (!strcmp(argv[i], "--load-trace"))) { 3469 load_trace++; 3470 } else if ((!strcmp(argv[i], "-path")) || 3471 (!strcmp(argv[i], "--path"))) { 3472 i++; 3473 parsePath(BAD_CAST argv[i]); 3474#ifdef LIBXML_PATTERN_ENABLED 3475 } else if ((!strcmp(argv[i], "-pattern")) || 3476 (!strcmp(argv[i], "--pattern"))) { 3477 i++; 3478 pattern = argv[i]; 3479#endif 3480#ifdef LIBXML_XPATH_ENABLED 3481 } else if ((!strcmp(argv[i], "-xpath")) || 3482 (!strcmp(argv[i], "--xpath"))) { 3483 i++; 3484 noout++; 3485 xpathquery = argv[i]; 3486#endif 3487 } else if ((!strcmp(argv[i], "-oldxml10")) || 3488 (!strcmp(argv[i], "--oldxml10"))) { 3489 oldxml10++; 3490 options |= XML_PARSE_OLD10; 3491 } else { 3492 fprintf(stderr, "Unknown option %s\n", argv[i]); 3493 usage(argv[0]); 3494 return(1); 3495 } 3496 } 3497 3498#ifdef LIBXML_CATALOG_ENABLED 3499 if (nocatalogs == 0) { 3500 if (catalogs) { 3501 const char *catal; 3502 3503 catal = getenv("SGML_CATALOG_FILES"); 3504 if (catal != NULL) { 3505 xmlLoadCatalogs(catal); 3506 } else { 3507 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n"); 3508 } 3509 } 3510 } 3511#endif 3512 3513#ifdef LIBXML_SAX1_ENABLED 3514 if (sax1) 3515 xmlSAXDefaultVersion(1); 3516 else 3517 xmlSAXDefaultVersion(2); 3518#endif /* LIBXML_SAX1_ENABLED */ 3519 3520 if (chkregister) { 3521 xmlRegisterNodeDefault(registerNode); 3522 xmlDeregisterNodeDefault(deregisterNode); 3523 } 3524 3525 indent = getenv("XMLLINT_INDENT"); 3526 if(indent != NULL) { 3527 xmlTreeIndentString = indent; 3528 } 3529 3530 3531 defaultEntityLoader = xmlGetExternalEntityLoader(); 3532 xmlSetExternalEntityLoader(xmllintExternalEntityLoader); 3533 3534 xmlLineNumbersDefault(1); 3535 if (loaddtd != 0) 3536 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS; 3537 if (dtdattrs) 3538 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS; 3539 if (noent != 0) xmlSubstituteEntitiesDefault(1); 3540#ifdef LIBXML_VALID_ENABLED 3541 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1; 3542#endif /* LIBXML_VALID_ENABLED */ 3543 if ((htmlout) && (!nowrap)) { 3544 xmlGenericError(xmlGenericErrorContext, 3545 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n"); 3546 xmlGenericError(xmlGenericErrorContext, 3547 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n"); 3548 xmlGenericError(xmlGenericErrorContext, 3549 "<html><head><title>%s output</title></head>\n", 3550 argv[0]); 3551 xmlGenericError(xmlGenericErrorContext, 3552 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n", 3553 argv[0]); 3554 } 3555 3556#ifdef LIBXML_SCHEMATRON_ENABLED 3557 if ((schematron != NULL) && (sax == 0) 3558#ifdef LIBXML_READER_ENABLED 3559 && (stream == 0) 3560#endif /* LIBXML_READER_ENABLED */ 3561 ) { 3562 xmlSchematronParserCtxtPtr ctxt; 3563 3564 /* forces loading the DTDs */ 3565 xmlLoadExtDtdDefaultValue |= 1; 3566 options |= XML_PARSE_DTDLOAD; 3567 if (timing) { 3568 startTimer(); 3569 } 3570 ctxt = xmlSchematronNewParserCtxt(schematron); 3571#if 0 3572 xmlSchematronSetParserErrors(ctxt, 3573 (xmlSchematronValidityErrorFunc) fprintf, 3574 (xmlSchematronValidityWarningFunc) fprintf, 3575 stderr); 3576#endif 3577 wxschematron = xmlSchematronParse(ctxt); 3578 if (wxschematron == NULL) { 3579 xmlGenericError(xmlGenericErrorContext, 3580 "Schematron schema %s failed to compile\n", schematron); 3581 progresult = XMLLINT_ERR_SCHEMACOMP; 3582 schematron = NULL; 3583 } 3584 xmlSchematronFreeParserCtxt(ctxt); 3585 if (timing) { 3586 endTimer("Compiling the schemas"); 3587 } 3588 } 3589#endif 3590#ifdef LIBXML_SCHEMAS_ENABLED 3591 if ((relaxng != NULL) && (sax == 0) 3592#ifdef LIBXML_READER_ENABLED 3593 && (stream == 0) 3594#endif /* LIBXML_READER_ENABLED */ 3595 ) { 3596 xmlRelaxNGParserCtxtPtr ctxt; 3597 3598 /* forces loading the DTDs */ 3599 xmlLoadExtDtdDefaultValue |= 1; 3600 options |= XML_PARSE_DTDLOAD; 3601 if (timing) { 3602 startTimer(); 3603 } 3604 ctxt = xmlRelaxNGNewParserCtxt(relaxng); 3605 xmlRelaxNGSetParserErrors(ctxt, 3606 (xmlRelaxNGValidityErrorFunc) fprintf, 3607 (xmlRelaxNGValidityWarningFunc) fprintf, 3608 stderr); 3609 relaxngschemas = xmlRelaxNGParse(ctxt); 3610 if (relaxngschemas == NULL) { 3611 xmlGenericError(xmlGenericErrorContext, 3612 "Relax-NG schema %s failed to compile\n", relaxng); 3613 progresult = XMLLINT_ERR_SCHEMACOMP; 3614 relaxng = NULL; 3615 } 3616 xmlRelaxNGFreeParserCtxt(ctxt); 3617 if (timing) { 3618 endTimer("Compiling the schemas"); 3619 } 3620 } else if ((schema != NULL) 3621#ifdef LIBXML_READER_ENABLED 3622 && (stream == 0) 3623#endif 3624 ) { 3625 xmlSchemaParserCtxtPtr ctxt; 3626 3627 if (timing) { 3628 startTimer(); 3629 } 3630 ctxt = xmlSchemaNewParserCtxt(schema); 3631 xmlSchemaSetParserErrors(ctxt, 3632 (xmlSchemaValidityErrorFunc) fprintf, 3633 (xmlSchemaValidityWarningFunc) fprintf, 3634 stderr); 3635 wxschemas = xmlSchemaParse(ctxt); 3636 if (wxschemas == NULL) { 3637 xmlGenericError(xmlGenericErrorContext, 3638 "WXS schema %s failed to compile\n", schema); 3639 progresult = XMLLINT_ERR_SCHEMACOMP; 3640 schema = NULL; 3641 } 3642 xmlSchemaFreeParserCtxt(ctxt); 3643 if (timing) { 3644 endTimer("Compiling the schemas"); 3645 } 3646 } 3647#endif /* LIBXML_SCHEMAS_ENABLED */ 3648#ifdef LIBXML_PATTERN_ENABLED 3649 if ((pattern != NULL) 3650#ifdef LIBXML_READER_ENABLED 3651 && (walker == 0) 3652#endif 3653 ) { 3654 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL); 3655 if (patternc == NULL) { 3656 xmlGenericError(xmlGenericErrorContext, 3657 "Pattern %s failed to compile\n", pattern); 3658 progresult = XMLLINT_ERR_SCHEMAPAT; 3659 pattern = NULL; 3660 } 3661 } 3662#endif /* LIBXML_PATTERN_ENABLED */ 3663 for (i = 1; i < argc ; i++) { 3664 if ((!strcmp(argv[i], "-encode")) || 3665 (!strcmp(argv[i], "--encode"))) { 3666 i++; 3667 continue; 3668 } else if ((!strcmp(argv[i], "-o")) || 3669 (!strcmp(argv[i], "-output")) || 3670 (!strcmp(argv[i], "--output"))) { 3671 i++; 3672 continue; 3673 } 3674#ifdef LIBXML_VALID_ENABLED 3675 if ((!strcmp(argv[i], "-dtdvalid")) || 3676 (!strcmp(argv[i], "--dtdvalid"))) { 3677 i++; 3678 continue; 3679 } 3680 if ((!strcmp(argv[i], "-path")) || 3681 (!strcmp(argv[i], "--path"))) { 3682 i++; 3683 continue; 3684 } 3685 if ((!strcmp(argv[i], "-dtdvalidfpi")) || 3686 (!strcmp(argv[i], "--dtdvalidfpi"))) { 3687 i++; 3688 continue; 3689 } 3690#endif /* LIBXML_VALID_ENABLED */ 3691 if ((!strcmp(argv[i], "-relaxng")) || 3692 (!strcmp(argv[i], "--relaxng"))) { 3693 i++; 3694 continue; 3695 } 3696 if ((!strcmp(argv[i], "-maxmem")) || 3697 (!strcmp(argv[i], "--maxmem"))) { 3698 i++; 3699 continue; 3700 } 3701 if ((!strcmp(argv[i], "-pretty")) || 3702 (!strcmp(argv[i], "--pretty"))) { 3703 i++; 3704 continue; 3705 } 3706 if ((!strcmp(argv[i], "-schema")) || 3707 (!strcmp(argv[i], "--schema"))) { 3708 i++; 3709 continue; 3710 } 3711 if ((!strcmp(argv[i], "-schematron")) || 3712 (!strcmp(argv[i], "--schematron"))) { 3713 i++; 3714 continue; 3715 } 3716#ifdef LIBXML_PATTERN_ENABLED 3717 if ((!strcmp(argv[i], "-pattern")) || 3718 (!strcmp(argv[i], "--pattern"))) { 3719 i++; 3720 continue; 3721 } 3722#endif 3723#ifdef LIBXML_XPATH_ENABLED 3724 if ((!strcmp(argv[i], "-xpath")) || 3725 (!strcmp(argv[i], "--xpath"))) { 3726 i++; 3727 continue; 3728 } 3729#endif 3730 if ((timing) && (repeat)) 3731 startTimer(); 3732 /* Remember file names. "-" means stdin. <sven@zen.org> */ 3733 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) { 3734 if (repeat) { 3735 xmlParserCtxtPtr ctxt = NULL; 3736 3737 for (acount = 0;acount < repeat;acount++) { 3738#ifdef LIBXML_READER_ENABLED 3739 if (stream != 0) { 3740 streamFile(argv[i]); 3741 } else { 3742#endif /* LIBXML_READER_ENABLED */ 3743 if (sax) { 3744 testSAX(argv[i]); 3745 } else { 3746 if (ctxt == NULL) 3747 ctxt = xmlNewParserCtxt(); 3748 parseAndPrintFile(argv[i], ctxt); 3749 } 3750#ifdef LIBXML_READER_ENABLED 3751 } 3752#endif /* LIBXML_READER_ENABLED */ 3753 } 3754 if (ctxt != NULL) 3755 xmlFreeParserCtxt(ctxt); 3756 } else { 3757 nbregister = 0; 3758 3759#ifdef LIBXML_READER_ENABLED 3760 if (stream != 0) 3761 streamFile(argv[i]); 3762 else 3763#endif /* LIBXML_READER_ENABLED */ 3764 if (sax) { 3765 testSAX(argv[i]); 3766 } else { 3767 parseAndPrintFile(argv[i], NULL); 3768 } 3769 3770 if ((chkregister) && (nbregister != 0)) { 3771 fprintf(stderr, "Registration count off: %d\n", nbregister); 3772 progresult = XMLLINT_ERR_RDREGIS; 3773 } 3774 } 3775 files ++; 3776 if ((timing) && (repeat)) { 3777 endTimer("%d iterations", repeat); 3778 } 3779 } 3780 } 3781 if (generate) 3782 parseAndPrintFile(NULL, NULL); 3783 if ((htmlout) && (!nowrap)) { 3784 xmlGenericError(xmlGenericErrorContext, "</body></html>\n"); 3785 } 3786 if ((files == 0) && (!generate) && (version == 0)) { 3787 usage(argv[0]); 3788 } 3789#ifdef LIBXML_SCHEMATRON_ENABLED 3790 if (wxschematron != NULL) 3791 xmlSchematronFree(wxschematron); 3792#endif 3793#ifdef LIBXML_SCHEMAS_ENABLED 3794 if (relaxngschemas != NULL) 3795 xmlRelaxNGFree(relaxngschemas); 3796 if (wxschemas != NULL) 3797 xmlSchemaFree(wxschemas); 3798 xmlRelaxNGCleanupTypes(); 3799#endif 3800#ifdef LIBXML_PATTERN_ENABLED 3801 if (patternc != NULL) 3802 xmlFreePattern(patternc); 3803#endif 3804 xmlCleanupParser(); 3805 xmlMemoryDump(); 3806 3807 return(progresult); 3808} 3809 3810