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