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