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 #endif /* LIBXML_READER_ENABLED */ 184 static int chkregister = 0; 185 static int nbregister = 0; 186 #ifdef LIBXML_SAX1_ENABLED 187 static int sax1 = 0; 188 #endif /* LIBXML_SAX1_ENABLED */ 189 #ifdef LIBXML_PATTERN_ENABLED 190 static const char *pattern = NULL; 191 static xmlPatternPtr patternc = NULL; 192 static xmlStreamCtxtPtr patstream = NULL; 193 #endif 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 ouput * 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, 1656 (xmlSchemaValidityErrorFunc) fprintf, 1657 (xmlSchemaValidityWarningFunc) fprintf, 1658 stderr); 1659 xmlSchemaValidateSetFilename(vctxt, filename); 1660 1661 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler, 1662 (void *)user_data); 1663 if (repeat == 0) { 1664 if (ret == 0) { 1665 fprintf(stderr, "%s validates\n", filename); 1666 } else if (ret > 0) { 1667 fprintf(stderr, "%s fails to validate\n", filename); 1668 progresult = XMLLINT_ERR_VALID; 1669 } else { 1670 fprintf(stderr, "%s validation generated an internal error\n", 1671 filename); 1672 progresult = XMLLINT_ERR_VALID; 1673 } 1674 } 1675 xmlSchemaFreeValidCtxt(vctxt); 1676 } else 1677 #endif 1678 { 1679 /* 1680 * Create the parser context amd hook the input 1681 */ 1682 ctxt = xmlNewParserCtxt(); 1683 if (ctxt == NULL) { 1684 xmlFreeParserInputBuffer(buf); 1685 goto error; 1686 } 1687 old_sax = ctxt->sax; 1688 ctxt->sax = handler; 1689 ctxt->userData = (void *) user_data; 1690 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE); 1691 if (inputStream == NULL) { 1692 xmlFreeParserInputBuffer(buf); 1693 goto error; 1694 } 1695 inputPush(ctxt, inputStream); 1696 1697 /* do the parsing */ 1698 xmlParseDocument(ctxt); 1699 1700 if (ctxt->myDoc != NULL) { 1701 fprintf(stderr, "SAX generated a doc !\n"); 1702 xmlFreeDoc(ctxt->myDoc); 1703 ctxt->myDoc = NULL; 1704 } 1705 } 1706 1707 error: 1708 if (ctxt != NULL) { 1709 ctxt->sax = old_sax; 1710 xmlFreeParserCtxt(ctxt); 1711 } 1712 } 1713 1714 /************************************************************************ 1715 * * 1716 * Stream Test processing * 1717 * * 1718 ************************************************************************/ 1719 #ifdef LIBXML_READER_ENABLED 1720 static void processNode(xmlTextReaderPtr reader) { 1721 const xmlChar *name, *value; 1722 int type, empty; 1723 1724 type = xmlTextReaderNodeType(reader); 1725 empty = xmlTextReaderIsEmptyElement(reader); 1726 1727 if (debug) { 1728 name = xmlTextReaderConstName(reader); 1729 if (name == NULL) 1730 name = BAD_CAST "--"; 1731 1732 value = xmlTextReaderConstValue(reader); 1733 1734 1735 printf("%d %d %s %d %d", 1736 xmlTextReaderDepth(reader), 1737 type, 1738 name, 1739 empty, 1740 xmlTextReaderHasValue(reader)); 1741 if (value == NULL) 1742 printf("\n"); 1743 else { 1744 printf(" %s\n", value); 1745 } 1746 } 1747 #ifdef LIBXML_PATTERN_ENABLED 1748 if (patternc) { 1749 xmlChar *path = NULL; 1750 int match = -1; 1751 1752 if (type == XML_READER_TYPE_ELEMENT) { 1753 /* do the check only on element start */ 1754 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader)); 1755 1756 if (match) { 1757 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED) 1758 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader)); 1759 printf("Node %s matches pattern %s\n", path, pattern); 1760 #else 1761 printf("Node %s matches pattern %s\n", 1762 xmlTextReaderConstName(reader), pattern); 1763 #endif 1764 } 1765 } 1766 if (patstream != NULL) { 1767 int ret; 1768 1769 if (type == XML_READER_TYPE_ELEMENT) { 1770 ret = xmlStreamPush(patstream, 1771 xmlTextReaderConstLocalName(reader), 1772 xmlTextReaderConstNamespaceUri(reader)); 1773 if (ret < 0) { 1774 fprintf(stderr, "xmlStreamPush() failure\n"); 1775 xmlFreeStreamCtxt(patstream); 1776 patstream = NULL; 1777 } else if (ret != match) { 1778 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED) 1779 if (path == NULL) { 1780 path = xmlGetNodePath( 1781 xmlTextReaderCurrentNode(reader)); 1782 } 1783 #endif 1784 fprintf(stderr, 1785 "xmlPatternMatch and xmlStreamPush disagree\n"); 1786 if (path != NULL) 1787 fprintf(stderr, " pattern %s node %s\n", 1788 pattern, path); 1789 else 1790 fprintf(stderr, " pattern %s node %s\n", 1791 pattern, xmlTextReaderConstName(reader)); 1792 } 1793 1794 } 1795 if ((type == XML_READER_TYPE_END_ELEMENT) || 1796 ((type == XML_READER_TYPE_ELEMENT) && (empty))) { 1797 ret = xmlStreamPop(patstream); 1798 if (ret < 0) { 1799 fprintf(stderr, "xmlStreamPop() failure\n"); 1800 xmlFreeStreamCtxt(patstream); 1801 patstream = NULL; 1802 } 1803 } 1804 } 1805 if (path != NULL) 1806 xmlFree(path); 1807 } 1808 #endif 1809 } 1810 1811 static void streamFile(char *filename) { 1812 xmlTextReaderPtr reader; 1813 int ret; 1814 #ifdef HAVE_MMAP 1815 int fd = -1; 1816 struct stat info; 1817 const char *base = NULL; 1818 xmlParserInputBufferPtr input = NULL; 1819 1820 if (memory) { 1821 if (stat(filename, &info) < 0) 1822 return; 1823 if ((fd = open(filename, O_RDONLY)) < 0) 1824 return; 1825 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ; 1826 if (base == (void *) MAP_FAILED) { 1827 close(fd); 1828 fprintf(stderr, "mmap failure for file %s\n", filename); 1829 progresult = XMLLINT_ERR_RDFILE; 1830 return; 1831 } 1832 1833 reader = xmlReaderForMemory(base, info.st_size, filename, 1834 NULL, options); 1835 } else 1836 #endif 1837 reader = xmlReaderForFile(filename, NULL, options); 1838 #ifdef LIBXML_PATTERN_ENABLED 1839 if (pattern != NULL) { 1840 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL); 1841 if (patternc == NULL) { 1842 xmlGenericError(xmlGenericErrorContext, 1843 "Pattern %s failed to compile\n", pattern); 1844 progresult = XMLLINT_ERR_SCHEMAPAT; 1845 pattern = NULL; 1846 } 1847 } 1848 if (patternc != NULL) { 1849 patstream = xmlPatternGetStreamCtxt(patternc); 1850 if (patstream != NULL) { 1851 ret = xmlStreamPush(patstream, NULL, NULL); 1852 if (ret < 0) { 1853 fprintf(stderr, "xmlStreamPush() failure\n"); 1854 xmlFreeStreamCtxt(patstream); 1855 patstream = NULL; 1856 } 1857 } 1858 } 1859 #endif 1860 1861 1862 if (reader != NULL) { 1863 #ifdef LIBXML_VALID_ENABLED 1864 if (valid) 1865 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1); 1866 else 1867 #endif /* LIBXML_VALID_ENABLED */ 1868 if (loaddtd) 1869 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1); 1870 #ifdef LIBXML_SCHEMAS_ENABLED 1871 if (relaxng != NULL) { 1872 if ((timing) && (!repeat)) { 1873 startTimer(); 1874 } 1875 ret = xmlTextReaderRelaxNGValidate(reader, relaxng); 1876 if (ret < 0) { 1877 xmlGenericError(xmlGenericErrorContext, 1878 "Relax-NG schema %s failed to compile\n", relaxng); 1879 progresult = XMLLINT_ERR_SCHEMACOMP; 1880 relaxng = NULL; 1881 } 1882 if ((timing) && (!repeat)) { 1883 endTimer("Compiling the schemas"); 1884 } 1885 } 1886 if (schema != NULL) { 1887 if ((timing) && (!repeat)) { 1888 startTimer(); 1889 } 1890 ret = xmlTextReaderSchemaValidate(reader, schema); 1891 if (ret < 0) { 1892 xmlGenericError(xmlGenericErrorContext, 1893 "XSD schema %s failed to compile\n", schema); 1894 progresult = XMLLINT_ERR_SCHEMACOMP; 1895 schema = NULL; 1896 } 1897 if ((timing) && (!repeat)) { 1898 endTimer("Compiling the schemas"); 1899 } 1900 } 1901 #endif 1902 1903 /* 1904 * Process all nodes in sequence 1905 */ 1906 if ((timing) && (!repeat)) { 1907 startTimer(); 1908 } 1909 ret = xmlTextReaderRead(reader); 1910 while (ret == 1) { 1911 if ((debug) 1912 #ifdef LIBXML_PATTERN_ENABLED 1913 || (patternc) 1914 #endif 1915 ) 1916 processNode(reader); 1917 ret = xmlTextReaderRead(reader); 1918 } 1919 if ((timing) && (!repeat)) { 1920 #ifdef LIBXML_SCHEMAS_ENABLED 1921 if (relaxng != NULL) 1922 endTimer("Parsing and validating"); 1923 else 1924 #endif 1925 #ifdef LIBXML_VALID_ENABLED 1926 if (valid) 1927 endTimer("Parsing and validating"); 1928 else 1929 #endif 1930 endTimer("Parsing"); 1931 } 1932 1933 #ifdef LIBXML_VALID_ENABLED 1934 if (valid) { 1935 if (xmlTextReaderIsValid(reader) != 1) { 1936 xmlGenericError(xmlGenericErrorContext, 1937 "Document %s does not validate\n", filename); 1938 progresult = XMLLINT_ERR_VALID; 1939 } 1940 } 1941 #endif /* LIBXML_VALID_ENABLED */ 1942 #ifdef LIBXML_SCHEMAS_ENABLED 1943 if ((relaxng != NULL) || (schema != NULL)) { 1944 if (xmlTextReaderIsValid(reader) != 1) { 1945 fprintf(stderr, "%s fails to validate\n", filename); 1946 progresult = XMLLINT_ERR_VALID; 1947 } else { 1948 fprintf(stderr, "%s validates\n", filename); 1949 } 1950 } 1951 #endif 1952 /* 1953 * Done, cleanup and status 1954 */ 1955 xmlFreeTextReader(reader); 1956 if (ret != 0) { 1957 fprintf(stderr, "%s : failed to parse\n", filename); 1958 progresult = XMLLINT_ERR_UNCLASS; 1959 } 1960 } else { 1961 fprintf(stderr, "Unable to open %s\n", filename); 1962 progresult = XMLLINT_ERR_UNCLASS; 1963 } 1964 #ifdef LIBXML_PATTERN_ENABLED 1965 if (patstream != NULL) { 1966 xmlFreeStreamCtxt(patstream); 1967 patstream = NULL; 1968 } 1969 #endif 1970 #ifdef HAVE_MMAP 1971 if (memory) { 1972 xmlFreeParserInputBuffer(input); 1973 munmap((char *) base, info.st_size); 1974 close(fd); 1975 } 1976 #endif 1977 } 1978 1979 static void walkDoc(xmlDocPtr doc) { 1980 xmlTextReaderPtr reader; 1981 int ret; 1982 1983 #ifdef LIBXML_PATTERN_ENABLED 1984 xmlNodePtr root; 1985 const xmlChar *namespaces[22]; 1986 int i; 1987 xmlNsPtr ns; 1988 1989 root = xmlDocGetRootElement(doc); 1990 if (root == NULL ) { 1991 xmlGenericError(xmlGenericErrorContext, 1992 "Document does not have a root element"); 1993 progresult = XMLLINT_ERR_UNCLASS; 1994 return; 1995 } 1996 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) { 1997 namespaces[i++] = ns->href; 1998 namespaces[i++] = ns->prefix; 1999 } 2000 namespaces[i++] = NULL; 2001 namespaces[i] = NULL; 2002 2003 if (pattern != NULL) { 2004 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict, 2005 0, &namespaces[0]); 2006 if (patternc == NULL) { 2007 xmlGenericError(xmlGenericErrorContext, 2008 "Pattern %s failed to compile\n", pattern); 2009 progresult = XMLLINT_ERR_SCHEMAPAT; 2010 pattern = NULL; 2011 } 2012 } 2013 if (patternc != NULL) { 2014 patstream = xmlPatternGetStreamCtxt(patternc); 2015 if (patstream != NULL) { 2016 ret = xmlStreamPush(patstream, NULL, NULL); 2017 if (ret < 0) { 2018 fprintf(stderr, "xmlStreamPush() failure\n"); 2019 xmlFreeStreamCtxt(patstream); 2020 patstream = NULL; 2021 } 2022 } 2023 } 2024 #endif /* LIBXML_PATTERN_ENABLED */ 2025 reader = xmlReaderWalker(doc); 2026 if (reader != NULL) { 2027 if ((timing) && (!repeat)) { 2028 startTimer(); 2029 } 2030 ret = xmlTextReaderRead(reader); 2031 while (ret == 1) { 2032 if ((debug) 2033 #ifdef LIBXML_PATTERN_ENABLED 2034 || (patternc) 2035 #endif 2036 ) 2037 processNode(reader); 2038 ret = xmlTextReaderRead(reader); 2039 } 2040 if ((timing) && (!repeat)) { 2041 endTimer("walking through the doc"); 2042 } 2043 xmlFreeTextReader(reader); 2044 if (ret != 0) { 2045 fprintf(stderr, "failed to walk through the doc\n"); 2046 progresult = XMLLINT_ERR_UNCLASS; 2047 } 2048 } else { 2049 fprintf(stderr, "Failed to crate a reader from the document\n"); 2050 progresult = XMLLINT_ERR_UNCLASS; 2051 } 2052 #ifdef LIBXML_PATTERN_ENABLED 2053 if (patstream != NULL) { 2054 xmlFreeStreamCtxt(patstream); 2055 patstream = NULL; 2056 } 2057 #endif 2058 } 2059 #endif /* LIBXML_READER_ENABLED */ 2060 2061 #ifdef LIBXML_XPATH_ENABLED 2062 /************************************************************************ 2063 * * 2064 * XPath Query * 2065 * * 2066 ************************************************************************/ 2067 2068 static void doXPathDump(xmlXPathObjectPtr cur) { 2069 switch(cur->type) { 2070 case XPATH_NODESET: { 2071 int i; 2072 xmlNodePtr node; 2073 #ifdef LIBXML_OUTPUT_ENABLED 2074 xmlSaveCtxtPtr ctxt; 2075 2076 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) { 2077 fprintf(stderr, "XPath set is empty\n"); 2078 progresult = XMLLINT_ERR_XPATH; 2079 break; 2080 } 2081 ctxt = xmlSaveToFd(1, NULL, 0); 2082 if (ctxt == NULL) { 2083 fprintf(stderr, "Out of memory for XPath\n"); 2084 progresult = XMLLINT_ERR_MEM; 2085 return; 2086 } 2087 for (i = 0;i < cur->nodesetval->nodeNr;i++) { 2088 node = cur->nodesetval->nodeTab[i]; 2089 xmlSaveTree(ctxt, node); 2090 } 2091 xmlSaveClose(ctxt); 2092 #else 2093 printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr); 2094 #endif 2095 break; 2096 } 2097 case XPATH_BOOLEAN: 2098 if (cur->boolval) printf("true"); 2099 else printf("false"); 2100 break; 2101 case XPATH_NUMBER: 2102 switch (xmlXPathIsInf(cur->floatval)) { 2103 case 1: 2104 printf("Infinity"); 2105 break; 2106 case -1: 2107 printf("-Infinity"); 2108 break; 2109 default: 2110 if (xmlXPathIsNaN(cur->floatval)) { 2111 printf("NaN"); 2112 } else { 2113 printf("%0g", cur->floatval); 2114 } 2115 } 2116 break; 2117 case XPATH_STRING: 2118 printf("%s", (const char *) cur->stringval); 2119 break; 2120 case XPATH_UNDEFINED: 2121 fprintf(stderr, "XPath Object is uninitialized\n"); 2122 progresult = XMLLINT_ERR_XPATH; 2123 break; 2124 default: 2125 fprintf(stderr, "XPath object of unexpected type\n"); 2126 progresult = XMLLINT_ERR_XPATH; 2127 break; 2128 } 2129 } 2130 2131 static void doXPathQuery(xmlDocPtr doc, const char *query) { 2132 xmlXPathContextPtr ctxt; 2133 xmlXPathObjectPtr res; 2134 2135 ctxt = xmlXPathNewContext(doc); 2136 if (ctxt == NULL) { 2137 fprintf(stderr, "Out of memory for XPath\n"); 2138 progresult = XMLLINT_ERR_MEM; 2139 return; 2140 } 2141 ctxt->node = (xmlNodePtr) doc; 2142 res = xmlXPathEval(BAD_CAST query, ctxt); 2143 xmlXPathFreeContext(ctxt); 2144 2145 if (res == NULL) { 2146 fprintf(stderr, "XPath evaluation failure\n"); 2147 progresult = XMLLINT_ERR_XPATH; 2148 return; 2149 } 2150 doXPathDump(res); 2151 xmlXPathFreeObject(res); 2152 } 2153 #endif /* LIBXML_XPATH_ENABLED */ 2154 2155 /************************************************************************ 2156 * * 2157 * Tree Test processing * 2158 * * 2159 ************************************************************************/ 2160 static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) { 2161 xmlDocPtr doc = NULL; 2162 #ifdef LIBXML_TREE_ENABLED 2163 xmlDocPtr tmp; 2164 #endif /* LIBXML_TREE_ENABLED */ 2165 2166 if ((timing) && (!repeat)) 2167 startTimer(); 2168 2169 2170 #ifdef LIBXML_TREE_ENABLED 2171 if (filename == NULL) { 2172 if (generate) { 2173 xmlNodePtr n; 2174 2175 doc = xmlNewDoc(BAD_CAST "1.0"); 2176 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL); 2177 xmlNodeSetContent(n, BAD_CAST "abc"); 2178 xmlDocSetRootElement(doc, n); 2179 } 2180 } 2181 #endif /* LIBXML_TREE_ENABLED */ 2182 #ifdef LIBXML_HTML_ENABLED 2183 #ifdef LIBXML_PUSH_ENABLED 2184 else if ((html) && (push)) { 2185 FILE *f; 2186 2187 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) 2188 f = fopen(filename, "rb"); 2189 #elif defined(__OS400__) 2190 f = fopen(filename, "rb"); 2191 #else 2192 f = fopen(filename, "r"); 2193 #endif 2194 if (f != NULL) { 2195 int res; 2196 char chars[4096]; 2197 htmlParserCtxtPtr ctxt; 2198 2199 res = fread(chars, 1, 4, f); 2200 if (res > 0) { 2201 ctxt = htmlCreatePushParserCtxt(NULL, NULL, 2202 chars, res, filename, XML_CHAR_ENCODING_NONE); 2203 xmlCtxtUseOptions(ctxt, options); 2204 while ((res = fread(chars, 1, pushsize, f)) > 0) { 2205 htmlParseChunk(ctxt, chars, res, 0); 2206 } 2207 htmlParseChunk(ctxt, chars, 0, 1); 2208 doc = ctxt->myDoc; 2209 htmlFreeParserCtxt(ctxt); 2210 } 2211 fclose(f); 2212 } 2213 } 2214 #endif /* LIBXML_PUSH_ENABLED */ 2215 #ifdef HAVE_MMAP 2216 else if ((html) && (memory)) { 2217 int fd; 2218 struct stat info; 2219 const char *base; 2220 if (stat(filename, &info) < 0) 2221 return; 2222 if ((fd = open(filename, O_RDONLY)) < 0) 2223 return; 2224 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ; 2225 if (base == (void *) MAP_FAILED) { 2226 close(fd); 2227 fprintf(stderr, "mmap failure for file %s\n", filename); 2228 progresult = XMLLINT_ERR_RDFILE; 2229 return; 2230 } 2231 2232 doc = htmlReadMemory((char *) base, info.st_size, filename, 2233 NULL, options); 2234 2235 munmap((char *) base, info.st_size); 2236 close(fd); 2237 } 2238 #endif 2239 else if (html) { 2240 doc = htmlReadFile(filename, NULL, options); 2241 } 2242 #endif /* LIBXML_HTML_ENABLED */ 2243 else { 2244 #ifdef LIBXML_PUSH_ENABLED 2245 /* 2246 * build an XML tree from a string; 2247 */ 2248 if (push) { 2249 FILE *f; 2250 2251 /* '-' Usually means stdin -<sven@zen.org> */ 2252 if ((filename[0] == '-') && (filename[1] == 0)) { 2253 f = stdin; 2254 } else { 2255 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) 2256 f = fopen(filename, "rb"); 2257 #elif defined(__OS400__) 2258 f = fopen(filename, "rb"); 2259 #else 2260 f = fopen(filename, "r"); 2261 #endif 2262 } 2263 if (f != NULL) { 2264 int ret; 2265 int res, size = 1024; 2266 char chars[1024]; 2267 xmlParserCtxtPtr ctxt; 2268 2269 /* if (repeat) size = 1024; */ 2270 res = fread(chars, 1, 4, f); 2271 if (res > 0) { 2272 ctxt = xmlCreatePushParserCtxt(NULL, NULL, 2273 chars, res, filename); 2274 xmlCtxtUseOptions(ctxt, options); 2275 while ((res = fread(chars, 1, size, f)) > 0) { 2276 xmlParseChunk(ctxt, chars, res, 0); 2277 } 2278 xmlParseChunk(ctxt, chars, 0, 1); 2279 doc = ctxt->myDoc; 2280 ret = ctxt->wellFormed; 2281 xmlFreeParserCtxt(ctxt); 2282 if (!ret) { 2283 xmlFreeDoc(doc); 2284 doc = NULL; 2285 } 2286 } 2287 if (f != stdin) 2288 fclose(f); 2289 } 2290 } else 2291 #endif /* LIBXML_PUSH_ENABLED */ 2292 if (testIO) { 2293 if ((filename[0] == '-') && (filename[1] == 0)) { 2294 doc = xmlReadFd(0, NULL, NULL, options); 2295 } else { 2296 FILE *f; 2297 2298 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) 2299 f = fopen(filename, "rb"); 2300 #elif defined(__OS400__) 2301 f = fopen(filename, "rb"); 2302 #else 2303 f = fopen(filename, "r"); 2304 #endif 2305 if (f != NULL) { 2306 if (rectxt == NULL) 2307 doc = xmlReadIO(myRead, myClose, f, filename, NULL, 2308 options); 2309 else 2310 doc = xmlCtxtReadIO(rectxt, myRead, myClose, f, 2311 filename, NULL, options); 2312 } else 2313 doc = NULL; 2314 } 2315 } else if (htmlout) { 2316 xmlParserCtxtPtr ctxt; 2317 2318 if (rectxt == NULL) 2319 ctxt = xmlNewParserCtxt(); 2320 else 2321 ctxt = rectxt; 2322 if (ctxt == NULL) { 2323 doc = NULL; 2324 } else { 2325 ctxt->sax->error = xmlHTMLError; 2326 ctxt->sax->warning = xmlHTMLWarning; 2327 ctxt->vctxt.error = xmlHTMLValidityError; 2328 ctxt->vctxt.warning = xmlHTMLValidityWarning; 2329 2330 doc = xmlCtxtReadFile(ctxt, filename, NULL, options); 2331 2332 if (rectxt == NULL) 2333 xmlFreeParserCtxt(ctxt); 2334 } 2335 #ifdef HAVE_MMAP 2336 } else if (memory) { 2337 int fd; 2338 struct stat info; 2339 const char *base; 2340 if (stat(filename, &info) < 0) 2341 return; 2342 if ((fd = open(filename, O_RDONLY)) < 0) 2343 return; 2344 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ; 2345 if (base == (void *) MAP_FAILED) { 2346 close(fd); 2347 fprintf(stderr, "mmap failure for file %s\n", filename); 2348 progresult = XMLLINT_ERR_RDFILE; 2349 return; 2350 } 2351 2352 if (rectxt == NULL) 2353 doc = xmlReadMemory((char *) base, info.st_size, 2354 filename, NULL, options); 2355 else 2356 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size, 2357 filename, NULL, options); 2358 2359 munmap((char *) base, info.st_size); 2360 close(fd); 2361 #endif 2362 #ifdef LIBXML_VALID_ENABLED 2363 } else if (valid) { 2364 xmlParserCtxtPtr ctxt = NULL; 2365 2366 if (rectxt == NULL) 2367 ctxt = xmlNewParserCtxt(); 2368 else 2369 ctxt = rectxt; 2370 if (ctxt == NULL) { 2371 doc = NULL; 2372 } else { 2373 doc = xmlCtxtReadFile(ctxt, filename, NULL, options); 2374 2375 if (ctxt->valid == 0) 2376 progresult = XMLLINT_ERR_RDFILE; 2377 if (rectxt == NULL) 2378 xmlFreeParserCtxt(ctxt); 2379 } 2380 #endif /* LIBXML_VALID_ENABLED */ 2381 } else { 2382 if (rectxt != NULL) 2383 doc = xmlCtxtReadFile(rectxt, filename, NULL, options); 2384 else { 2385 #ifdef LIBXML_SAX1_ENABLED 2386 if (sax1) 2387 doc = xmlParseFile(filename); 2388 else 2389 #endif /* LIBXML_SAX1_ENABLED */ 2390 doc = xmlReadFile(filename, NULL, options); 2391 } 2392 } 2393 } 2394 2395 /* 2396 * If we don't have a document we might as well give up. Do we 2397 * want an error message here? <sven@zen.org> */ 2398 if (doc == NULL) { 2399 progresult = XMLLINT_ERR_UNCLASS; 2400 return; 2401 } 2402 2403 if ((timing) && (!repeat)) { 2404 endTimer("Parsing"); 2405 } 2406 2407 /* 2408 * Remove DOCTYPE nodes 2409 */ 2410 if (dropdtd) { 2411 xmlDtdPtr dtd; 2412 2413 dtd = xmlGetIntSubset(doc); 2414 if (dtd != NULL) { 2415 xmlUnlinkNode((xmlNodePtr)dtd); 2416 xmlFreeDtd(dtd); 2417 } 2418 } 2419 2420 #ifdef LIBXML_XINCLUDE_ENABLED 2421 if (xinclude) { 2422 if ((timing) && (!repeat)) { 2423 startTimer(); 2424 } 2425 if (xmlXIncludeProcessFlags(doc, options) < 0) 2426 progresult = XMLLINT_ERR_UNCLASS; 2427 if ((timing) && (!repeat)) { 2428 endTimer("Xinclude processing"); 2429 } 2430 } 2431 #endif 2432 2433 #ifdef LIBXML_XPATH_ENABLED 2434 if (xpathquery != NULL) { 2435 doXPathQuery(doc, xpathquery); 2436 } 2437 #endif 2438 2439 #ifdef LIBXML_DEBUG_ENABLED 2440 #ifdef LIBXML_XPATH_ENABLED 2441 /* 2442 * shell interaction 2443 */ 2444 if (shell) { 2445 xmlXPathOrderDocElems(doc); 2446 xmlShell(doc, filename, xmlShellReadline, stdout); 2447 } 2448 #endif 2449 #endif 2450 2451 #ifdef LIBXML_TREE_ENABLED 2452 /* 2453 * test intermediate copy if needed. 2454 */ 2455 if (copy) { 2456 tmp = doc; 2457 if (timing) { 2458 startTimer(); 2459 } 2460 doc = xmlCopyDoc(doc, 1); 2461 if (timing) { 2462 endTimer("Copying"); 2463 } 2464 if (timing) { 2465 startTimer(); 2466 } 2467 xmlFreeDoc(tmp); 2468 if (timing) { 2469 endTimer("Freeing original"); 2470 } 2471 } 2472 #endif /* LIBXML_TREE_ENABLED */ 2473 2474 #ifdef LIBXML_VALID_ENABLED 2475 if ((insert) && (!html)) { 2476 const xmlChar* list[256]; 2477 int nb, i; 2478 xmlNodePtr node; 2479 2480 if (doc->children != NULL) { 2481 node = doc->children; 2482 while ((node != NULL) && (node->last == NULL)) node = node->next; 2483 if (node != NULL) { 2484 nb = xmlValidGetValidElements(node->last, NULL, list, 256); 2485 if (nb < 0) { 2486 fprintf(stderr, "could not get valid list of elements\n"); 2487 } else if (nb == 0) { 2488 fprintf(stderr, "No element can be inserted under root\n"); 2489 } else { 2490 fprintf(stderr, "%d element types can be inserted under root:\n", 2491 nb); 2492 for (i = 0;i < nb;i++) { 2493 fprintf(stderr, "%s\n", (char *) list[i]); 2494 } 2495 } 2496 } 2497 } 2498 }else 2499 #endif /* LIBXML_VALID_ENABLED */ 2500 #ifdef LIBXML_READER_ENABLED 2501 if (walker) { 2502 walkDoc(doc); 2503 } 2504 #endif /* LIBXML_READER_ENABLED */ 2505 #ifdef LIBXML_OUTPUT_ENABLED 2506 if (noout == 0) { 2507 int ret; 2508 2509 /* 2510 * print it. 2511 */ 2512 #ifdef LIBXML_DEBUG_ENABLED 2513 if (!debug) { 2514 #endif 2515 if ((timing) && (!repeat)) { 2516 startTimer(); 2517 } 2518 #ifdef LIBXML_HTML_ENABLED 2519 if ((html) && (!xmlout)) { 2520 if (compress) { 2521 htmlSaveFile(output ? output : "-", doc); 2522 } 2523 else if (encoding != NULL) { 2524 if (format == 1) { 2525 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1); 2526 } 2527 else { 2528 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0); 2529 } 2530 } 2531 else if (format == 1) { 2532 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1); 2533 } 2534 else { 2535 FILE *out; 2536 if (output == NULL) 2537 out = stdout; 2538 else { 2539 out = fopen(output,"wb"); 2540 } 2541 if (out != NULL) { 2542 if (htmlDocDump(out, doc) < 0) 2543 progresult = XMLLINT_ERR_OUT; 2544 2545 if (output != NULL) 2546 fclose(out); 2547 } else { 2548 fprintf(stderr, "failed to open %s\n", output); 2549 progresult = XMLLINT_ERR_OUT; 2550 } 2551 } 2552 if ((timing) && (!repeat)) { 2553 endTimer("Saving"); 2554 } 2555 } else 2556 #endif 2557 #ifdef LIBXML_C14N_ENABLED 2558 if (canonical) { 2559 xmlChar *result = NULL; 2560 int size; 2561 2562 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result); 2563 if (size >= 0) { 2564 if (write(1, result, size) == -1) { 2565 fprintf(stderr, "Can't write data\n"); 2566 } 2567 xmlFree(result); 2568 } else { 2569 fprintf(stderr, "Failed to canonicalize\n"); 2570 progresult = XMLLINT_ERR_OUT; 2571 } 2572 } else if (canonical_11) { 2573 xmlChar *result = NULL; 2574 int size; 2575 2576 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result); 2577 if (size >= 0) { 2578 if (write(1, result, size) == -1) { 2579 fprintf(stderr, "Can't write data\n"); 2580 } 2581 xmlFree(result); 2582 } else { 2583 fprintf(stderr, "Failed to canonicalize\n"); 2584 progresult = XMLLINT_ERR_OUT; 2585 } 2586 } else 2587 if (exc_canonical) { 2588 xmlChar *result = NULL; 2589 int size; 2590 2591 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result); 2592 if (size >= 0) { 2593 if (write(1, result, size) == -1) { 2594 fprintf(stderr, "Can't write data\n"); 2595 } 2596 xmlFree(result); 2597 } else { 2598 fprintf(stderr, "Failed to canonicalize\n"); 2599 progresult = XMLLINT_ERR_OUT; 2600 } 2601 } else 2602 #endif 2603 #ifdef HAVE_MMAP 2604 if (memory) { 2605 xmlChar *result; 2606 int len; 2607 2608 if (encoding != NULL) { 2609 if (format == 1) { 2610 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1); 2611 } else { 2612 xmlDocDumpMemoryEnc(doc, &result, &len, encoding); 2613 } 2614 } else { 2615 if (format == 1) 2616 xmlDocDumpFormatMemory(doc, &result, &len, 1); 2617 else 2618 xmlDocDumpMemory(doc, &result, &len); 2619 } 2620 if (result == NULL) { 2621 fprintf(stderr, "Failed to save\n"); 2622 progresult = XMLLINT_ERR_OUT; 2623 } else { 2624 if (write(1, result, len) == -1) { 2625 fprintf(stderr, "Can't write data\n"); 2626 } 2627 xmlFree(result); 2628 } 2629 2630 } else 2631 #endif /* HAVE_MMAP */ 2632 if (compress) { 2633 xmlSaveFile(output ? output : "-", doc); 2634 } else if (oldout) { 2635 if (encoding != NULL) { 2636 if (format == 1) { 2637 ret = xmlSaveFormatFileEnc(output ? output : "-", doc, 2638 encoding, 1); 2639 } 2640 else { 2641 ret = xmlSaveFileEnc(output ? output : "-", doc, 2642 encoding); 2643 } 2644 if (ret < 0) { 2645 fprintf(stderr, "failed save to %s\n", 2646 output ? output : "-"); 2647 progresult = XMLLINT_ERR_OUT; 2648 } 2649 } else if (format == 1) { 2650 ret = xmlSaveFormatFile(output ? output : "-", doc, 1); 2651 if (ret < 0) { 2652 fprintf(stderr, "failed save to %s\n", 2653 output ? output : "-"); 2654 progresult = XMLLINT_ERR_OUT; 2655 } 2656 } else { 2657 FILE *out; 2658 if (output == NULL) 2659 out = stdout; 2660 else { 2661 out = fopen(output,"wb"); 2662 } 2663 if (out != NULL) { 2664 if (xmlDocDump(out, doc) < 0) 2665 progresult = XMLLINT_ERR_OUT; 2666 2667 if (output != NULL) 2668 fclose(out); 2669 } else { 2670 fprintf(stderr, "failed to open %s\n", output); 2671 progresult = XMLLINT_ERR_OUT; 2672 } 2673 } 2674 } else { 2675 xmlSaveCtxtPtr ctxt; 2676 int saveOpts = 0; 2677 2678 if (format == 1) 2679 saveOpts |= XML_SAVE_FORMAT; 2680 else if (format == 2) 2681 saveOpts |= XML_SAVE_WSNONSIG; 2682 2683 #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED) 2684 if (xmlout) 2685 saveOpts |= XML_SAVE_AS_XML; 2686 #endif 2687 2688 if (output == NULL) 2689 ctxt = xmlSaveToFd(1, encoding, saveOpts); 2690 else 2691 ctxt = xmlSaveToFilename(output, encoding, saveOpts); 2692 2693 if (ctxt != NULL) { 2694 if (xmlSaveDoc(ctxt, doc) < 0) { 2695 fprintf(stderr, "failed save to %s\n", 2696 output ? output : "-"); 2697 progresult = XMLLINT_ERR_OUT; 2698 } 2699 xmlSaveClose(ctxt); 2700 } else { 2701 progresult = XMLLINT_ERR_OUT; 2702 } 2703 } 2704 if ((timing) && (!repeat)) { 2705 endTimer("Saving"); 2706 } 2707 #ifdef LIBXML_DEBUG_ENABLED 2708 } else { 2709 FILE *out; 2710 if (output == NULL) 2711 out = stdout; 2712 else { 2713 out = fopen(output,"wb"); 2714 } 2715 if (out != NULL) { 2716 xmlDebugDumpDocument(out, doc); 2717 2718 if (output != NULL) 2719 fclose(out); 2720 } else { 2721 fprintf(stderr, "failed to open %s\n", output); 2722 progresult = XMLLINT_ERR_OUT; 2723 } 2724 } 2725 #endif 2726 } 2727 #endif /* LIBXML_OUTPUT_ENABLED */ 2728 2729 #ifdef LIBXML_VALID_ENABLED 2730 /* 2731 * A posteriori validation test 2732 */ 2733 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) { 2734 xmlDtdPtr dtd; 2735 2736 if ((timing) && (!repeat)) { 2737 startTimer(); 2738 } 2739 if (dtdvalid != NULL) 2740 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid); 2741 else 2742 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL); 2743 if ((timing) && (!repeat)) { 2744 endTimer("Parsing DTD"); 2745 } 2746 if (dtd == NULL) { 2747 if (dtdvalid != NULL) 2748 xmlGenericError(xmlGenericErrorContext, 2749 "Could not parse DTD %s\n", dtdvalid); 2750 else 2751 xmlGenericError(xmlGenericErrorContext, 2752 "Could not parse DTD %s\n", dtdvalidfpi); 2753 progresult = XMLLINT_ERR_DTD; 2754 } else { 2755 xmlValidCtxtPtr cvp; 2756 2757 if ((cvp = xmlNewValidCtxt()) == NULL) { 2758 xmlGenericError(xmlGenericErrorContext, 2759 "Couldn't allocate validation context\n"); 2760 exit(-1); 2761 } 2762 cvp->userData = (void *) stderr; 2763 cvp->error = (xmlValidityErrorFunc) fprintf; 2764 cvp->warning = (xmlValidityWarningFunc) fprintf; 2765 2766 if ((timing) && (!repeat)) { 2767 startTimer(); 2768 } 2769 if (!xmlValidateDtd(cvp, doc, dtd)) { 2770 if (dtdvalid != NULL) 2771 xmlGenericError(xmlGenericErrorContext, 2772 "Document %s does not validate against %s\n", 2773 filename, dtdvalid); 2774 else 2775 xmlGenericError(xmlGenericErrorContext, 2776 "Document %s does not validate against %s\n", 2777 filename, dtdvalidfpi); 2778 progresult = XMLLINT_ERR_VALID; 2779 } 2780 if ((timing) && (!repeat)) { 2781 endTimer("Validating against DTD"); 2782 } 2783 xmlFreeValidCtxt(cvp); 2784 xmlFreeDtd(dtd); 2785 } 2786 } else if (postvalid) { 2787 xmlValidCtxtPtr cvp; 2788 2789 if ((cvp = xmlNewValidCtxt()) == NULL) { 2790 xmlGenericError(xmlGenericErrorContext, 2791 "Couldn't allocate validation context\n"); 2792 exit(-1); 2793 } 2794 2795 if ((timing) && (!repeat)) { 2796 startTimer(); 2797 } 2798 cvp->userData = (void *) stderr; 2799 cvp->error = (xmlValidityErrorFunc) fprintf; 2800 cvp->warning = (xmlValidityWarningFunc) fprintf; 2801 if (!xmlValidateDocument(cvp, doc)) { 2802 xmlGenericError(xmlGenericErrorContext, 2803 "Document %s does not validate\n", filename); 2804 progresult = XMLLINT_ERR_VALID; 2805 } 2806 if ((timing) && (!repeat)) { 2807 endTimer("Validating"); 2808 } 2809 xmlFreeValidCtxt(cvp); 2810 } 2811 #endif /* LIBXML_VALID_ENABLED */ 2812 #ifdef LIBXML_SCHEMATRON_ENABLED 2813 if (wxschematron != NULL) { 2814 xmlSchematronValidCtxtPtr ctxt; 2815 int ret; 2816 int flag; 2817 2818 if ((timing) && (!repeat)) { 2819 startTimer(); 2820 } 2821 2822 if (debug) 2823 flag = XML_SCHEMATRON_OUT_XML; 2824 else 2825 flag = XML_SCHEMATRON_OUT_TEXT; 2826 if (noout) 2827 flag |= XML_SCHEMATRON_OUT_QUIET; 2828 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag); 2829 #if 0 2830 xmlSchematronSetValidErrors(ctxt, 2831 (xmlSchematronValidityErrorFunc) fprintf, 2832 (xmlSchematronValidityWarningFunc) fprintf, 2833 stderr); 2834 #endif 2835 ret = xmlSchematronValidateDoc(ctxt, doc); 2836 if (ret == 0) { 2837 fprintf(stderr, "%s validates\n", filename); 2838 } else if (ret > 0) { 2839 fprintf(stderr, "%s fails to validate\n", filename); 2840 progresult = XMLLINT_ERR_VALID; 2841 } else { 2842 fprintf(stderr, "%s validation generated an internal error\n", 2843 filename); 2844 progresult = XMLLINT_ERR_VALID; 2845 } 2846 xmlSchematronFreeValidCtxt(ctxt); 2847 if ((timing) && (!repeat)) { 2848 endTimer("Validating"); 2849 } 2850 } 2851 #endif 2852 #ifdef LIBXML_SCHEMAS_ENABLED 2853 if (relaxngschemas != NULL) { 2854 xmlRelaxNGValidCtxtPtr ctxt; 2855 int ret; 2856 2857 if ((timing) && (!repeat)) { 2858 startTimer(); 2859 } 2860 2861 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas); 2862 xmlRelaxNGSetValidErrors(ctxt, 2863 (xmlRelaxNGValidityErrorFunc) fprintf, 2864 (xmlRelaxNGValidityWarningFunc) fprintf, 2865 stderr); 2866 ret = xmlRelaxNGValidateDoc(ctxt, doc); 2867 if (ret == 0) { 2868 fprintf(stderr, "%s validates\n", filename); 2869 } else if (ret > 0) { 2870 fprintf(stderr, "%s fails to validate\n", filename); 2871 progresult = XMLLINT_ERR_VALID; 2872 } else { 2873 fprintf(stderr, "%s validation generated an internal error\n", 2874 filename); 2875 progresult = XMLLINT_ERR_VALID; 2876 } 2877 xmlRelaxNGFreeValidCtxt(ctxt); 2878 if ((timing) && (!repeat)) { 2879 endTimer("Validating"); 2880 } 2881 } else if (wxschemas != NULL) { 2882 xmlSchemaValidCtxtPtr ctxt; 2883 int ret; 2884 2885 if ((timing) && (!repeat)) { 2886 startTimer(); 2887 } 2888 2889 ctxt = xmlSchemaNewValidCtxt(wxschemas); 2890 xmlSchemaSetValidErrors(ctxt, 2891 (xmlSchemaValidityErrorFunc) fprintf, 2892 (xmlSchemaValidityWarningFunc) fprintf, 2893 stderr); 2894 ret = xmlSchemaValidateDoc(ctxt, doc); 2895 if (ret == 0) { 2896 fprintf(stderr, "%s validates\n", filename); 2897 } else if (ret > 0) { 2898 fprintf(stderr, "%s fails to validate\n", filename); 2899 progresult = XMLLINT_ERR_VALID; 2900 } else { 2901 fprintf(stderr, "%s validation generated an internal error\n", 2902 filename); 2903 progresult = XMLLINT_ERR_VALID; 2904 } 2905 xmlSchemaFreeValidCtxt(ctxt); 2906 if ((timing) && (!repeat)) { 2907 endTimer("Validating"); 2908 } 2909 } 2910 #endif 2911 2912 #ifdef LIBXML_DEBUG_ENABLED 2913 #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED) 2914 if ((debugent) && (!html)) 2915 xmlDebugDumpEntities(stderr, doc); 2916 #endif 2917 #endif 2918 2919 /* 2920 * free it. 2921 */ 2922 if ((timing) && (!repeat)) { 2923 startTimer(); 2924 } 2925 xmlFreeDoc(doc); 2926 if ((timing) && (!repeat)) { 2927 endTimer("Freeing"); 2928 } 2929 } 2930 2931 /************************************************************************ 2932 * * 2933 * Usage and Main * 2934 * * 2935 ************************************************************************/ 2936 2937 static void showVersion(const char *name) { 2938 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion); 2939 fprintf(stderr, " compiled with: "); 2940 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads "); 2941 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree "); 2942 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output "); 2943 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push "); 2944 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader "); 2945 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns "); 2946 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer "); 2947 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 "); 2948 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP "); 2949 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP "); 2950 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid "); 2951 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML "); 2952 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy "); 2953 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N "); 2954 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog "); 2955 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath "); 2956 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer "); 2957 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude "); 2958 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv "); 2959 if (xmlHasFeature(XML_WITH_ICU)) fprintf(stderr, "ICU "); 2960 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X "); 2961 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode "); 2962 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps "); 2963 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata "); 2964 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr "); 2965 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas "); 2966 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron "); 2967 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules "); 2968 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug "); 2969 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug "); 2970 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug "); 2971 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib "); 2972 if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma "); 2973 fprintf(stderr, "\n"); 2974 } 2975 2976 static void usage(FILE *f, const char *name) { 2977 fprintf(f, "Usage : %s [options] XMLfiles ...\n", name); 2978 #ifdef LIBXML_OUTPUT_ENABLED 2979 fprintf(f, "\tParse the XML files and output the result of the parsing\n"); 2980 #else 2981 fprintf(f, "\tParse the XML files\n"); 2982 #endif /* LIBXML_OUTPUT_ENABLED */ 2983 fprintf(f, "\t--version : display the version of the XML library used\n"); 2984 #ifdef LIBXML_DEBUG_ENABLED 2985 fprintf(f, "\t--debug : dump a debug tree of the in-memory document\n"); 2986 fprintf(f, "\t--shell : run a navigating shell\n"); 2987 fprintf(f, "\t--debugent : debug the entities defined in the document\n"); 2988 #else 2989 #ifdef LIBXML_READER_ENABLED 2990 fprintf(f, "\t--debug : dump the nodes content when using --stream\n"); 2991 #endif /* LIBXML_READER_ENABLED */ 2992 #endif 2993 #ifdef LIBXML_TREE_ENABLED 2994 fprintf(f, "\t--copy : used to test the internal copy implementation\n"); 2995 #endif /* LIBXML_TREE_ENABLED */ 2996 fprintf(f, "\t--recover : output what was parsable on broken XML documents\n"); 2997 fprintf(f, "\t--huge : remove any internal arbitrary parser limits\n"); 2998 fprintf(f, "\t--noent : substitute entity references by their value\n"); 2999 fprintf(f, "\t--noenc : ignore any encoding specified inside the document\n"); 3000 fprintf(f, "\t--noout : don't output the result tree\n"); 3001 fprintf(f, "\t--path 'paths': provide a set of paths for resources\n"); 3002 fprintf(f, "\t--load-trace : print trace of all external entities loaded\n"); 3003 fprintf(f, "\t--nonet : refuse to fetch DTDs or entities over network\n"); 3004 fprintf(f, "\t--nocompact : do not generate compact text nodes\n"); 3005 fprintf(f, "\t--htmlout : output results as HTML\n"); 3006 fprintf(f, "\t--nowrap : do not put HTML doc wrapper\n"); 3007 #ifdef LIBXML_VALID_ENABLED 3008 fprintf(f, "\t--valid : validate the document in addition to std well-formed check\n"); 3009 fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n"); 3010 fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n"); 3011 fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n"); 3012 #endif /* LIBXML_VALID_ENABLED */ 3013 fprintf(f, "\t--timing : print some timings\n"); 3014 fprintf(f, "\t--output file or -o file: save to a given file\n"); 3015 fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n"); 3016 fprintf(f, "\t--insert : ad-hoc test for valid insertions\n"); 3017 #ifdef LIBXML_OUTPUT_ENABLED 3018 #ifdef LIBXML_ZLIB_ENABLED 3019 fprintf(f, "\t--compress : turn on gzip compression of output\n"); 3020 #endif 3021 #endif /* LIBXML_OUTPUT_ENABLED */ 3022 #ifdef LIBXML_HTML_ENABLED 3023 fprintf(f, "\t--html : use the HTML parser\n"); 3024 fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n"); 3025 fprintf(f, "\t--nodefdtd : do not default HTML doctype\n"); 3026 #endif 3027 #ifdef LIBXML_PUSH_ENABLED 3028 fprintf(f, "\t--push : use the push mode of the parser\n"); 3029 fprintf(f, "\t--pushsmall : use the push mode of the parser using tiny increments\n"); 3030 #endif /* LIBXML_PUSH_ENABLED */ 3031 #ifdef HAVE_MMAP 3032 fprintf(f, "\t--memory : parse from memory\n"); 3033 #endif 3034 fprintf(f, "\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n"); 3035 fprintf(f, "\t--nowarning : do not emit warnings from parser/validator\n"); 3036 fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n"); 3037 fprintf(f, "\t--nocdata : replace cdata section with text nodes\n"); 3038 #ifdef LIBXML_OUTPUT_ENABLED 3039 fprintf(f, "\t--format : reformat/reindent the output\n"); 3040 fprintf(f, "\t--encode encoding : output in the given encoding\n"); 3041 fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n"); 3042 fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n"); 3043 fprintf(f, "\t 0 Do not pretty print\n"); 3044 fprintf(f, "\t 1 Format the XML content, as --format\n"); 3045 fprintf(f, "\t 2 Add whitespace inside tags, preserving content\n"); 3046 #endif /* LIBXML_OUTPUT_ENABLED */ 3047 fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n"); 3048 fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n"); 3049 fprintf(f, "\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n"); 3050 #ifdef LIBXML_C14N_ENABLED 3051 #endif /* LIBXML_C14N_ENABLED */ 3052 fprintf(f, "\t--nsclean : remove redundant namespace declarations\n"); 3053 fprintf(f, "\t--testIO : test user I/O support\n"); 3054 #ifdef LIBXML_CATALOG_ENABLED 3055 fprintf(f, "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n"); 3056 fprintf(f, "\t otherwise XML Catalogs starting from \n"); 3057 fprintf(f, "\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG); 3058 fprintf(f, "\t--nocatalogs: deactivate all catalogs\n"); 3059 #endif 3060 fprintf(f, "\t--auto : generate a small doc on the fly\n"); 3061 #ifdef LIBXML_XINCLUDE_ENABLED 3062 fprintf(f, "\t--xinclude : do XInclude processing\n"); 3063 fprintf(f, "\t--noxincludenode : same but do not generate XInclude nodes\n"); 3064 fprintf(f, "\t--nofixup-base-uris : do not fixup xml:base uris\n"); 3065 #endif 3066 fprintf(f, "\t--loaddtd : fetch external DTD\n"); 3067 fprintf(f, "\t--dtdattr : loaddtd + populate the tree with inherited attributes \n"); 3068 #ifdef LIBXML_READER_ENABLED 3069 fprintf(f, "\t--stream : use the streaming interface to process very large files\n"); 3070 fprintf(f, "\t--walker : create a reader and walk though the resulting doc\n"); 3071 #endif /* LIBXML_READER_ENABLED */ 3072 #ifdef LIBXML_PATTERN_ENABLED 3073 fprintf(f, "\t--pattern pattern_value : test the pattern support\n"); 3074 #endif 3075 fprintf(f, "\t--chkregister : verify the node registration code\n"); 3076 #ifdef LIBXML_SCHEMAS_ENABLED 3077 fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n"); 3078 fprintf(f, "\t--schema schema : do validation against the WXS schema\n"); 3079 #endif 3080 #ifdef LIBXML_SCHEMATRON_ENABLED 3081 fprintf(f, "\t--schematron schema : do validation against a schematron\n"); 3082 #endif 3083 #ifdef LIBXML_SAX1_ENABLED 3084 fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n"); 3085 #endif 3086 fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n"); 3087 fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n"); 3088 #ifdef LIBXML_XPATH_ENABLED 3089 fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n"); 3090 #endif 3091 3092 fprintf(f, "\nLibxml project home page: http://xmlsoft.org/\n"); 3093 fprintf(f, "To report bugs or get some help check: http://xmlsoft.org/bugs.html\n"); 3094 } 3095 3096 static void registerNode(xmlNodePtr node) 3097 { 3098 node->_private = malloc(sizeof(long)); 3099 if (node->_private == NULL) { 3100 fprintf(stderr, "Out of memory in xmllint:registerNode()\n"); 3101 exit(XMLLINT_ERR_MEM); 3102 } 3103 *(long*)node->_private = (long) 0x81726354; 3104 nbregister++; 3105 } 3106 3107 static void deregisterNode(xmlNodePtr node) 3108 { 3109 assert(node->_private != NULL); 3110 assert(*(long*)node->_private == (long) 0x81726354); 3111 free(node->_private); 3112 nbregister--; 3113 } 3114 3115 int 3116 main(int argc, char **argv) { 3117 int i, acount; 3118 int files = 0; 3119 int version = 0; 3120 const char* indent; 3121 3122 if (argc <= 1) { 3123 usage(stderr, argv[0]); 3124 return(1); 3125 } 3126 LIBXML_TEST_VERSION 3127 for (i = 1; i < argc ; i++) { 3128 if (!strcmp(argv[i], "-")) 3129 break; 3130 3131 if (argv[i][0] != '-') 3132 continue; 3133 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug"))) 3134 debug++; 3135 else 3136 #ifdef LIBXML_DEBUG_ENABLED 3137 if ((!strcmp(argv[i], "-shell")) || 3138 (!strcmp(argv[i], "--shell"))) { 3139 shell++; 3140 noout = 1; 3141 } else 3142 #endif 3143 #ifdef LIBXML_TREE_ENABLED 3144 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy"))) 3145 copy++; 3146 else 3147 #endif /* LIBXML_TREE_ENABLED */ 3148 if ((!strcmp(argv[i], "-recover")) || 3149 (!strcmp(argv[i], "--recover"))) { 3150 recovery++; 3151 options |= XML_PARSE_RECOVER; 3152 } else if ((!strcmp(argv[i], "-huge")) || 3153 (!strcmp(argv[i], "--huge"))) { 3154 options |= XML_PARSE_HUGE; 3155 } else if ((!strcmp(argv[i], "-noent")) || 3156 (!strcmp(argv[i], "--noent"))) { 3157 noent++; 3158 options |= XML_PARSE_NOENT; 3159 } else if ((!strcmp(argv[i], "-noenc")) || 3160 (!strcmp(argv[i], "--noenc"))) { 3161 noenc++; 3162 options |= XML_PARSE_IGNORE_ENC; 3163 } else if ((!strcmp(argv[i], "-nsclean")) || 3164 (!strcmp(argv[i], "--nsclean"))) { 3165 options |= XML_PARSE_NSCLEAN; 3166 } else if ((!strcmp(argv[i], "-nocdata")) || 3167 (!strcmp(argv[i], "--nocdata"))) { 3168 options |= XML_PARSE_NOCDATA; 3169 } else if ((!strcmp(argv[i], "-nodict")) || 3170 (!strcmp(argv[i], "--nodict"))) { 3171 options |= XML_PARSE_NODICT; 3172 } else if ((!strcmp(argv[i], "-version")) || 3173 (!strcmp(argv[i], "--version"))) { 3174 showVersion(argv[0]); 3175 version = 1; 3176 } else if ((!strcmp(argv[i], "-noout")) || 3177 (!strcmp(argv[i], "--noout"))) 3178 noout++; 3179 #ifdef LIBXML_OUTPUT_ENABLED 3180 else if ((!strcmp(argv[i], "-o")) || 3181 (!strcmp(argv[i], "-output")) || 3182 (!strcmp(argv[i], "--output"))) { 3183 i++; 3184 output = argv[i]; 3185 } 3186 #endif /* LIBXML_OUTPUT_ENABLED */ 3187 else if ((!strcmp(argv[i], "-htmlout")) || 3188 (!strcmp(argv[i], "--htmlout"))) 3189 htmlout++; 3190 else if ((!strcmp(argv[i], "-nowrap")) || 3191 (!strcmp(argv[i], "--nowrap"))) 3192 nowrap++; 3193 #ifdef LIBXML_HTML_ENABLED 3194 else if ((!strcmp(argv[i], "-html")) || 3195 (!strcmp(argv[i], "--html"))) { 3196 html++; 3197 } 3198 else if ((!strcmp(argv[i], "-xmlout")) || 3199 (!strcmp(argv[i], "--xmlout"))) { 3200 xmlout++; 3201 } else if ((!strcmp(argv[i], "-nodefdtd")) || 3202 (!strcmp(argv[i], "--nodefdtd"))) { 3203 nodefdtd++; 3204 options |= HTML_PARSE_NODEFDTD; 3205 } 3206 #endif /* LIBXML_HTML_ENABLED */ 3207 else if ((!strcmp(argv[i], "-loaddtd")) || 3208 (!strcmp(argv[i], "--loaddtd"))) { 3209 loaddtd++; 3210 options |= XML_PARSE_DTDLOAD; 3211 } else if ((!strcmp(argv[i], "-dtdattr")) || 3212 (!strcmp(argv[i], "--dtdattr"))) { 3213 loaddtd++; 3214 dtdattrs++; 3215 options |= XML_PARSE_DTDATTR; 3216 } 3217 #ifdef LIBXML_VALID_ENABLED 3218 else if ((!strcmp(argv[i], "-valid")) || 3219 (!strcmp(argv[i], "--valid"))) { 3220 valid++; 3221 options |= XML_PARSE_DTDVALID; 3222 } else if ((!strcmp(argv[i], "-postvalid")) || 3223 (!strcmp(argv[i], "--postvalid"))) { 3224 postvalid++; 3225 loaddtd++; 3226 options |= XML_PARSE_DTDLOAD; 3227 } else if ((!strcmp(argv[i], "-dtdvalid")) || 3228 (!strcmp(argv[i], "--dtdvalid"))) { 3229 i++; 3230 dtdvalid = argv[i]; 3231 loaddtd++; 3232 options |= XML_PARSE_DTDLOAD; 3233 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) || 3234 (!strcmp(argv[i], "--dtdvalidfpi"))) { 3235 i++; 3236 dtdvalidfpi = argv[i]; 3237 loaddtd++; 3238 options |= XML_PARSE_DTDLOAD; 3239 } 3240 #endif /* LIBXML_VALID_ENABLED */ 3241 else if ((!strcmp(argv[i], "-dropdtd")) || 3242 (!strcmp(argv[i], "--dropdtd"))) 3243 dropdtd++; 3244 else if ((!strcmp(argv[i], "-insert")) || 3245 (!strcmp(argv[i], "--insert"))) 3246 insert++; 3247 else if ((!strcmp(argv[i], "-timing")) || 3248 (!strcmp(argv[i], "--timing"))) 3249 timing++; 3250 else if ((!strcmp(argv[i], "-auto")) || 3251 (!strcmp(argv[i], "--auto"))) 3252 generate++; 3253 else if ((!strcmp(argv[i], "-repeat")) || 3254 (!strcmp(argv[i], "--repeat"))) { 3255 if (repeat) 3256 repeat *= 10; 3257 else 3258 repeat = 100; 3259 } 3260 #ifdef LIBXML_PUSH_ENABLED 3261 else if ((!strcmp(argv[i], "-push")) || 3262 (!strcmp(argv[i], "--push"))) 3263 push++; 3264 else if ((!strcmp(argv[i], "-pushsmall")) || 3265 (!strcmp(argv[i], "--pushsmall"))) { 3266 push++; 3267 pushsize = 10; 3268 } 3269 #endif /* LIBXML_PUSH_ENABLED */ 3270 #ifdef HAVE_MMAP 3271 else if ((!strcmp(argv[i], "-memory")) || 3272 (!strcmp(argv[i], "--memory"))) 3273 memory++; 3274 #endif 3275 else if ((!strcmp(argv[i], "-testIO")) || 3276 (!strcmp(argv[i], "--testIO"))) 3277 testIO++; 3278 #ifdef LIBXML_XINCLUDE_ENABLED 3279 else if ((!strcmp(argv[i], "-xinclude")) || 3280 (!strcmp(argv[i], "--xinclude"))) { 3281 xinclude++; 3282 options |= XML_PARSE_XINCLUDE; 3283 } 3284 else if ((!strcmp(argv[i], "-noxincludenode")) || 3285 (!strcmp(argv[i], "--noxincludenode"))) { 3286 xinclude++; 3287 options |= XML_PARSE_XINCLUDE; 3288 options |= XML_PARSE_NOXINCNODE; 3289 } 3290 else if ((!strcmp(argv[i], "-nofixup-base-uris")) || 3291 (!strcmp(argv[i], "--nofixup-base-uris"))) { 3292 xinclude++; 3293 options |= XML_PARSE_XINCLUDE; 3294 options |= XML_PARSE_NOBASEFIX; 3295 } 3296 #endif 3297 #ifdef LIBXML_OUTPUT_ENABLED 3298 #ifdef LIBXML_ZLIB_ENABLED 3299 else if ((!strcmp(argv[i], "-compress")) || 3300 (!strcmp(argv[i], "--compress"))) { 3301 compress++; 3302 xmlSetCompressMode(9); 3303 } 3304 #endif 3305 #endif /* LIBXML_OUTPUT_ENABLED */ 3306 else if ((!strcmp(argv[i], "-nowarning")) || 3307 (!strcmp(argv[i], "--nowarning"))) { 3308 xmlGetWarningsDefaultValue = 0; 3309 xmlPedanticParserDefault(0); 3310 options |= XML_PARSE_NOWARNING; 3311 } 3312 else if ((!strcmp(argv[i], "-pedantic")) || 3313 (!strcmp(argv[i], "--pedantic"))) { 3314 xmlGetWarningsDefaultValue = 1; 3315 xmlPedanticParserDefault(1); 3316 options |= XML_PARSE_PEDANTIC; 3317 } 3318 #ifdef LIBXML_DEBUG_ENABLED 3319 else if ((!strcmp(argv[i], "-debugent")) || 3320 (!strcmp(argv[i], "--debugent"))) { 3321 debugent++; 3322 xmlParserDebugEntities = 1; 3323 } 3324 #endif 3325 #ifdef LIBXML_C14N_ENABLED 3326 else if ((!strcmp(argv[i], "-c14n")) || 3327 (!strcmp(argv[i], "--c14n"))) { 3328 canonical++; 3329 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD; 3330 } 3331 else if ((!strcmp(argv[i], "-c14n11")) || 3332 (!strcmp(argv[i], "--c14n11"))) { 3333 canonical_11++; 3334 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD; 3335 } 3336 else if ((!strcmp(argv[i], "-exc-c14n")) || 3337 (!strcmp(argv[i], "--exc-c14n"))) { 3338 exc_canonical++; 3339 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD; 3340 } 3341 #endif 3342 #ifdef LIBXML_CATALOG_ENABLED 3343 else if ((!strcmp(argv[i], "-catalogs")) || 3344 (!strcmp(argv[i], "--catalogs"))) { 3345 catalogs++; 3346 } else if ((!strcmp(argv[i], "-nocatalogs")) || 3347 (!strcmp(argv[i], "--nocatalogs"))) { 3348 nocatalogs++; 3349 } 3350 #endif 3351 else if ((!strcmp(argv[i], "-encode")) || 3352 (!strcmp(argv[i], "--encode"))) { 3353 i++; 3354 encoding = argv[i]; 3355 /* 3356 * OK it's for testing purposes 3357 */ 3358 xmlAddEncodingAlias("UTF-8", "DVEnc"); 3359 } 3360 else if ((!strcmp(argv[i], "-noblanks")) || 3361 (!strcmp(argv[i], "--noblanks"))) { 3362 noblanks++; 3363 xmlKeepBlanksDefault(0); 3364 options |= XML_PARSE_NOBLANKS; 3365 } 3366 else if ((!strcmp(argv[i], "-maxmem")) || 3367 (!strcmp(argv[i], "--maxmem"))) { 3368 i++; 3369 if (sscanf(argv[i], "%d", &maxmem) == 1) { 3370 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc, 3371 myStrdupFunc); 3372 } else { 3373 maxmem = 0; 3374 } 3375 } 3376 else if ((!strcmp(argv[i], "-format")) || 3377 (!strcmp(argv[i], "--format"))) { 3378 noblanks++; 3379 #ifdef LIBXML_OUTPUT_ENABLED 3380 format = 1; 3381 #endif /* LIBXML_OUTPUT_ENABLED */ 3382 xmlKeepBlanksDefault(0); 3383 } 3384 else if ((!strcmp(argv[i], "-pretty")) || 3385 (!strcmp(argv[i], "--pretty"))) { 3386 i++; 3387 #ifdef LIBXML_OUTPUT_ENABLED 3388 if (argv[i] != NULL) { 3389 format = atoi(argv[i]); 3390 if (format == 1) { 3391 noblanks++; 3392 xmlKeepBlanksDefault(0); 3393 } 3394 } 3395 #endif /* LIBXML_OUTPUT_ENABLED */ 3396 } 3397 #ifdef LIBXML_READER_ENABLED 3398 else if ((!strcmp(argv[i], "-stream")) || 3399 (!strcmp(argv[i], "--stream"))) { 3400 stream++; 3401 } 3402 else if ((!strcmp(argv[i], "-walker")) || 3403 (!strcmp(argv[i], "--walker"))) { 3404 walker++; 3405 noout++; 3406 } 3407 #endif /* LIBXML_READER_ENABLED */ 3408 #ifdef LIBXML_SAX1_ENABLED 3409 else if ((!strcmp(argv[i], "-sax1")) || 3410 (!strcmp(argv[i], "--sax1"))) { 3411 sax1++; 3412 options |= XML_PARSE_SAX1; 3413 } 3414 #endif /* LIBXML_SAX1_ENABLED */ 3415 else if ((!strcmp(argv[i], "-sax")) || 3416 (!strcmp(argv[i], "--sax"))) { 3417 sax++; 3418 } 3419 else if ((!strcmp(argv[i], "-chkregister")) || 3420 (!strcmp(argv[i], "--chkregister"))) { 3421 chkregister++; 3422 #ifdef LIBXML_SCHEMAS_ENABLED 3423 } else if ((!strcmp(argv[i], "-relaxng")) || 3424 (!strcmp(argv[i], "--relaxng"))) { 3425 i++; 3426 relaxng = argv[i]; 3427 noent++; 3428 options |= XML_PARSE_NOENT; 3429 } else if ((!strcmp(argv[i], "-schema")) || 3430 (!strcmp(argv[i], "--schema"))) { 3431 i++; 3432 schema = argv[i]; 3433 noent++; 3434 #endif 3435 #ifdef LIBXML_SCHEMATRON_ENABLED 3436 } else if ((!strcmp(argv[i], "-schematron")) || 3437 (!strcmp(argv[i], "--schematron"))) { 3438 i++; 3439 schematron = argv[i]; 3440 noent++; 3441 #endif 3442 } else if ((!strcmp(argv[i], "-nonet")) || 3443 (!strcmp(argv[i], "--nonet"))) { 3444 options |= XML_PARSE_NONET; 3445 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader); 3446 } else if ((!strcmp(argv[i], "-nocompact")) || 3447 (!strcmp(argv[i], "--nocompact"))) { 3448 options &= ~XML_PARSE_COMPACT; 3449 } else if ((!strcmp(argv[i], "-load-trace")) || 3450 (!strcmp(argv[i], "--load-trace"))) { 3451 load_trace++; 3452 } else if ((!strcmp(argv[i], "-path")) || 3453 (!strcmp(argv[i], "--path"))) { 3454 i++; 3455 parsePath(BAD_CAST argv[i]); 3456 #ifdef LIBXML_PATTERN_ENABLED 3457 } else if ((!strcmp(argv[i], "-pattern")) || 3458 (!strcmp(argv[i], "--pattern"))) { 3459 i++; 3460 pattern = argv[i]; 3461 #endif 3462 #ifdef LIBXML_XPATH_ENABLED 3463 } else if ((!strcmp(argv[i], "-xpath")) || 3464 (!strcmp(argv[i], "--xpath"))) { 3465 i++; 3466 noout++; 3467 xpathquery = argv[i]; 3468 #endif 3469 } else if ((!strcmp(argv[i], "-oldxml10")) || 3470 (!strcmp(argv[i], "--oldxml10"))) { 3471 oldxml10++; 3472 options |= XML_PARSE_OLD10; 3473 } else { 3474 fprintf(stderr, "Unknown option %s\n", argv[i]); 3475 usage(stderr, argv[0]); 3476 return(1); 3477 } 3478 } 3479 3480 #ifdef LIBXML_CATALOG_ENABLED 3481 if (nocatalogs == 0) { 3482 if (catalogs) { 3483 const char *catal; 3484 3485 catal = getenv("SGML_CATALOG_FILES"); 3486 if (catal != NULL) { 3487 xmlLoadCatalogs(catal); 3488 } else { 3489 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n"); 3490 } 3491 } 3492 } 3493 #endif 3494 3495 #ifdef LIBXML_SAX1_ENABLED 3496 if (sax1) 3497 xmlSAXDefaultVersion(1); 3498 else 3499 xmlSAXDefaultVersion(2); 3500 #endif /* LIBXML_SAX1_ENABLED */ 3501 3502 if (chkregister) { 3503 xmlRegisterNodeDefault(registerNode); 3504 xmlDeregisterNodeDefault(deregisterNode); 3505 } 3506 3507 indent = getenv("XMLLINT_INDENT"); 3508 if(indent != NULL) { 3509 xmlTreeIndentString = indent; 3510 } 3511 3512 3513 defaultEntityLoader = xmlGetExternalEntityLoader(); 3514 xmlSetExternalEntityLoader(xmllintExternalEntityLoader); 3515 3516 xmlLineNumbersDefault(1); 3517 if (loaddtd != 0) 3518 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS; 3519 if (dtdattrs) 3520 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS; 3521 if (noent != 0) xmlSubstituteEntitiesDefault(1); 3522 #ifdef LIBXML_VALID_ENABLED 3523 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1; 3524 #endif /* LIBXML_VALID_ENABLED */ 3525 if ((htmlout) && (!nowrap)) { 3526 xmlGenericError(xmlGenericErrorContext, 3527 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n"); 3528 xmlGenericError(xmlGenericErrorContext, 3529 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n"); 3530 xmlGenericError(xmlGenericErrorContext, 3531 "<html><head><title>%s output</title></head>\n", 3532 argv[0]); 3533 xmlGenericError(xmlGenericErrorContext, 3534 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n", 3535 argv[0]); 3536 } 3537 3538 #ifdef LIBXML_SCHEMATRON_ENABLED 3539 if ((schematron != NULL) && (sax == 0) 3540 #ifdef LIBXML_READER_ENABLED 3541 && (stream == 0) 3542 #endif /* LIBXML_READER_ENABLED */ 3543 ) { 3544 xmlSchematronParserCtxtPtr ctxt; 3545 3546 /* forces loading the DTDs */ 3547 xmlLoadExtDtdDefaultValue |= 1; 3548 options |= XML_PARSE_DTDLOAD; 3549 if (timing) { 3550 startTimer(); 3551 } 3552 ctxt = xmlSchematronNewParserCtxt(schematron); 3553 #if 0 3554 xmlSchematronSetParserErrors(ctxt, 3555 (xmlSchematronValidityErrorFunc) fprintf, 3556 (xmlSchematronValidityWarningFunc) fprintf, 3557 stderr); 3558 #endif 3559 wxschematron = xmlSchematronParse(ctxt); 3560 if (wxschematron == NULL) { 3561 xmlGenericError(xmlGenericErrorContext, 3562 "Schematron schema %s failed to compile\n", schematron); 3563 progresult = XMLLINT_ERR_SCHEMACOMP; 3564 schematron = NULL; 3565 } 3566 xmlSchematronFreeParserCtxt(ctxt); 3567 if (timing) { 3568 endTimer("Compiling the schemas"); 3569 } 3570 } 3571 #endif 3572 #ifdef LIBXML_SCHEMAS_ENABLED 3573 if ((relaxng != NULL) && (sax == 0) 3574 #ifdef LIBXML_READER_ENABLED 3575 && (stream == 0) 3576 #endif /* LIBXML_READER_ENABLED */ 3577 ) { 3578 xmlRelaxNGParserCtxtPtr ctxt; 3579 3580 /* forces loading the DTDs */ 3581 xmlLoadExtDtdDefaultValue |= 1; 3582 options |= XML_PARSE_DTDLOAD; 3583 if (timing) { 3584 startTimer(); 3585 } 3586 ctxt = xmlRelaxNGNewParserCtxt(relaxng); 3587 xmlRelaxNGSetParserErrors(ctxt, 3588 (xmlRelaxNGValidityErrorFunc) fprintf, 3589 (xmlRelaxNGValidityWarningFunc) fprintf, 3590 stderr); 3591 relaxngschemas = xmlRelaxNGParse(ctxt); 3592 if (relaxngschemas == NULL) { 3593 xmlGenericError(xmlGenericErrorContext, 3594 "Relax-NG schema %s failed to compile\n", relaxng); 3595 progresult = XMLLINT_ERR_SCHEMACOMP; 3596 relaxng = NULL; 3597 } 3598 xmlRelaxNGFreeParserCtxt(ctxt); 3599 if (timing) { 3600 endTimer("Compiling the schemas"); 3601 } 3602 } else if ((schema != NULL) 3603 #ifdef LIBXML_READER_ENABLED 3604 && (stream == 0) 3605 #endif 3606 ) { 3607 xmlSchemaParserCtxtPtr ctxt; 3608 3609 if (timing) { 3610 startTimer(); 3611 } 3612 ctxt = xmlSchemaNewParserCtxt(schema); 3613 xmlSchemaSetParserErrors(ctxt, 3614 (xmlSchemaValidityErrorFunc) fprintf, 3615 (xmlSchemaValidityWarningFunc) fprintf, 3616 stderr); 3617 wxschemas = xmlSchemaParse(ctxt); 3618 if (wxschemas == NULL) { 3619 xmlGenericError(xmlGenericErrorContext, 3620 "WXS schema %s failed to compile\n", schema); 3621 progresult = XMLLINT_ERR_SCHEMACOMP; 3622 schema = NULL; 3623 } 3624 xmlSchemaFreeParserCtxt(ctxt); 3625 if (timing) { 3626 endTimer("Compiling the schemas"); 3627 } 3628 } 3629 #endif /* LIBXML_SCHEMAS_ENABLED */ 3630 #ifdef LIBXML_PATTERN_ENABLED 3631 if ((pattern != NULL) 3632 #ifdef LIBXML_READER_ENABLED 3633 && (walker == 0) 3634 #endif 3635 ) { 3636 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL); 3637 if (patternc == NULL) { 3638 xmlGenericError(xmlGenericErrorContext, 3639 "Pattern %s failed to compile\n", pattern); 3640 progresult = XMLLINT_ERR_SCHEMAPAT; 3641 pattern = NULL; 3642 } 3643 } 3644 #endif /* LIBXML_PATTERN_ENABLED */ 3645 for (i = 1; i < argc ; i++) { 3646 if ((!strcmp(argv[i], "-encode")) || 3647 (!strcmp(argv[i], "--encode"))) { 3648 i++; 3649 continue; 3650 } else if ((!strcmp(argv[i], "-o")) || 3651 (!strcmp(argv[i], "-output")) || 3652 (!strcmp(argv[i], "--output"))) { 3653 i++; 3654 continue; 3655 } 3656 #ifdef LIBXML_VALID_ENABLED 3657 if ((!strcmp(argv[i], "-dtdvalid")) || 3658 (!strcmp(argv[i], "--dtdvalid"))) { 3659 i++; 3660 continue; 3661 } 3662 if ((!strcmp(argv[i], "-path")) || 3663 (!strcmp(argv[i], "--path"))) { 3664 i++; 3665 continue; 3666 } 3667 if ((!strcmp(argv[i], "-dtdvalidfpi")) || 3668 (!strcmp(argv[i], "--dtdvalidfpi"))) { 3669 i++; 3670 continue; 3671 } 3672 #endif /* LIBXML_VALID_ENABLED */ 3673 if ((!strcmp(argv[i], "-relaxng")) || 3674 (!strcmp(argv[i], "--relaxng"))) { 3675 i++; 3676 continue; 3677 } 3678 if ((!strcmp(argv[i], "-maxmem")) || 3679 (!strcmp(argv[i], "--maxmem"))) { 3680 i++; 3681 continue; 3682 } 3683 if ((!strcmp(argv[i], "-pretty")) || 3684 (!strcmp(argv[i], "--pretty"))) { 3685 i++; 3686 continue; 3687 } 3688 if ((!strcmp(argv[i], "-schema")) || 3689 (!strcmp(argv[i], "--schema"))) { 3690 i++; 3691 continue; 3692 } 3693 if ((!strcmp(argv[i], "-schematron")) || 3694 (!strcmp(argv[i], "--schematron"))) { 3695 i++; 3696 continue; 3697 } 3698 #ifdef LIBXML_PATTERN_ENABLED 3699 if ((!strcmp(argv[i], "-pattern")) || 3700 (!strcmp(argv[i], "--pattern"))) { 3701 i++; 3702 continue; 3703 } 3704 #endif 3705 #ifdef LIBXML_XPATH_ENABLED 3706 if ((!strcmp(argv[i], "-xpath")) || 3707 (!strcmp(argv[i], "--xpath"))) { 3708 i++; 3709 continue; 3710 } 3711 #endif 3712 if ((timing) && (repeat)) 3713 startTimer(); 3714 /* Remember file names. "-" means stdin. <sven@zen.org> */ 3715 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) { 3716 if (repeat) { 3717 xmlParserCtxtPtr ctxt = NULL; 3718 3719 for (acount = 0;acount < repeat;acount++) { 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 if (ctxt == NULL) 3729 ctxt = xmlNewParserCtxt(); 3730 parseAndPrintFile(argv[i], ctxt); 3731 } 3732 #ifdef LIBXML_READER_ENABLED 3733 } 3734 #endif /* LIBXML_READER_ENABLED */ 3735 } 3736 if (ctxt != NULL) 3737 xmlFreeParserCtxt(ctxt); 3738 } else { 3739 nbregister = 0; 3740 3741 #ifdef LIBXML_READER_ENABLED 3742 if (stream != 0) 3743 streamFile(argv[i]); 3744 else 3745 #endif /* LIBXML_READER_ENABLED */ 3746 if (sax) { 3747 testSAX(argv[i]); 3748 } else { 3749 parseAndPrintFile(argv[i], NULL); 3750 } 3751 3752 if ((chkregister) && (nbregister != 0)) { 3753 fprintf(stderr, "Registration count off: %d\n", nbregister); 3754 progresult = XMLLINT_ERR_RDREGIS; 3755 } 3756 } 3757 files ++; 3758 if ((timing) && (repeat)) { 3759 endTimer("%d iterations", repeat); 3760 } 3761 } 3762 } 3763 if (generate) 3764 parseAndPrintFile(NULL, NULL); 3765 if ((htmlout) && (!nowrap)) { 3766 xmlGenericError(xmlGenericErrorContext, "</body></html>\n"); 3767 } 3768 if ((files == 0) && (!generate) && (version == 0)) { 3769 usage(stderr, argv[0]); 3770 } 3771 #ifdef LIBXML_SCHEMATRON_ENABLED 3772 if (wxschematron != NULL) 3773 xmlSchematronFree(wxschematron); 3774 #endif 3775 #ifdef LIBXML_SCHEMAS_ENABLED 3776 if (relaxngschemas != NULL) 3777 xmlRelaxNGFree(relaxngschemas); 3778 if (wxschemas != NULL) 3779 xmlSchemaFree(wxschemas); 3780 xmlRelaxNGCleanupTypes(); 3781 #endif 3782 #ifdef LIBXML_PATTERN_ENABLED 3783 if (patternc != NULL) 3784 xmlFreePattern(patternc); 3785 #endif 3786 xmlCleanupParser(); 3787 xmlMemoryDump(); 3788 3789 return(progresult); 3790 } 3791 3792