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