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