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