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