updated libxml2 to 2.5.10
[TestXSLT.git] / libxml2 / testHTML.c
1 /*
2  * testHTML.c : a small tester program for HTML input.
3  *
4  * See Copyright for the status of this software.
5  *
6  * daniel@veillard.com
7  */
8
9 #include "libxml.h"
10
11 #ifdef LIBXML_HTML_ENABLED
12
13 #include <string.h>
14 #include <stdarg.h>
15
16
17 #ifdef HAVE_SYS_TYPES_H
18 #include <sys/types.h>
19 #endif
20 #ifdef HAVE_SYS_STAT_H
21 #include <sys/stat.h>
22 #endif
23 #ifdef HAVE_FCNTL_H
24 #include <fcntl.h>
25 #endif
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 #ifdef HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif
32
33 #include <libxml/xmlmemory.h>
34 #include <libxml/HTMLparser.h>
35 #include <libxml/HTMLtree.h>
36 #include <libxml/debugXML.h>
37 #include <libxml/xmlerror.h>
38 #include <libxml/globals.h>
39
40 #ifdef LIBXML_DEBUG_ENABLED
41 static int debug = 0;
42 #endif
43 static int copy = 0;
44 static int sax = 0;
45 static int repeat = 0;
46 static int noout = 0;
47 static int push = 0;
48 static char *encoding = NULL;
49
50 xmlSAXHandler emptySAXHandlerStruct = {
51     NULL, /* internalSubset */
52     NULL, /* isStandalone */
53     NULL, /* hasInternalSubset */
54     NULL, /* hasExternalSubset */
55     NULL, /* resolveEntity */
56     NULL, /* getEntity */
57     NULL, /* entityDecl */
58     NULL, /* notationDecl */
59     NULL, /* attributeDecl */
60     NULL, /* elementDecl */
61     NULL, /* unparsedEntityDecl */
62     NULL, /* setDocumentLocator */
63     NULL, /* startDocument */
64     NULL, /* endDocument */
65     NULL, /* startElement */
66     NULL, /* endElement */
67     NULL, /* reference */
68     NULL, /* characters */
69     NULL, /* ignorableWhitespace */
70     NULL, /* processingInstruction */
71     NULL, /* comment */
72     NULL, /* xmlParserWarning */
73     NULL, /* xmlParserError */
74     NULL, /* xmlParserError */
75     NULL, /* getParameterEntity */
76     NULL, /* cdataBlock */
77     NULL, /* externalSubset */
78     1
79 };
80
81 xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
82 extern xmlSAXHandlerPtr debugSAXHandler;
83
84 /************************************************************************
85  *                                                                      *
86  *                              Debug Handlers                          *
87  *                                                                      *
88  ************************************************************************/
89
90 /**
91  * isStandaloneDebug:
92  * @ctxt:  An XML parser context
93  *
94  * Is this document tagged standalone ?
95  *
96  * Returns 1 if true
97  */
98 static int
99 isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
100 {
101     fprintf(stdout, "SAX.isStandalone()\n");
102     return(0);
103 }
104
105 /**
106  * hasInternalSubsetDebug:
107  * @ctxt:  An XML parser context
108  *
109  * Does this document has an internal subset
110  *
111  * Returns 1 if true
112  */
113 static int
114 hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
115 {
116     fprintf(stdout, "SAX.hasInternalSubset()\n");
117     return(0);
118 }
119
120 /**
121  * hasExternalSubsetDebug:
122  * @ctxt:  An XML parser context
123  *
124  * Does this document has an external subset
125  *
126  * Returns 1 if true
127  */
128 static int
129 hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
130 {
131     fprintf(stdout, "SAX.hasExternalSubset()\n");
132     return(0);
133 }
134
135 /**
136  * hasInternalSubsetDebug:
137  * @ctxt:  An XML parser context
138  *
139  * Does this document has an internal subset
140  */
141 static void
142 internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
143                const xmlChar *ExternalID, const xmlChar *SystemID)
144 {
145     fprintf(stdout, "SAX.internalSubset(%s,", name);
146     if (ExternalID == NULL)
147         fprintf(stdout, " ,");
148     else
149         fprintf(stdout, " %s,", ExternalID);
150     if (SystemID == NULL)
151         fprintf(stdout, " )\n");
152     else
153         fprintf(stdout, " %s)\n", SystemID);
154 }
155
156 /**
157  * resolveEntityDebug:
158  * @ctxt:  An XML parser context
159  * @publicId: The public ID of the entity
160  * @systemId: The system ID of the entity
161  *
162  * Special entity resolver, better left to the parser, it has
163  * more context than the application layer.
164  * The default behaviour is to NOT resolve the entities, in that case
165  * the ENTITY_REF nodes are built in the structure (and the parameter
166  * values).
167  *
168  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
169  */
170 static xmlParserInputPtr
171 resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
172 {
173     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
174
175     
176     fprintf(stdout, "SAX.resolveEntity(");
177     if (publicId != NULL)
178         fprintf(stdout, "%s", (char *)publicId);
179     else
180         fprintf(stdout, " ");
181     if (systemId != NULL)
182         fprintf(stdout, ", %s)\n", (char *)systemId);
183     else
184         fprintf(stdout, ", )\n");
185 /*********
186     if (systemId != NULL) {
187         return(xmlNewInputFromFile(ctxt, (char *) systemId));
188     }
189  *********/
190     return(NULL);
191 }
192
193 /**
194  * getEntityDebug:
195  * @ctxt:  An XML parser context
196  * @name: The entity name
197  *
198  * Get an entity by name
199  *
200  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
201  */
202 static xmlEntityPtr
203 getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
204 {
205     fprintf(stdout, "SAX.getEntity(%s)\n", name);
206     return(NULL);
207 }
208
209 /**
210  * getParameterEntityDebug:
211  * @ctxt:  An XML parser context
212  * @name: The entity name
213  *
214  * Get a parameter entity by name
215  *
216  * Returns the xmlParserInputPtr
217  */
218 static xmlEntityPtr
219 getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
220 {
221     fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
222     return(NULL);
223 }
224
225
226 /**
227  * entityDeclDebug:
228  * @ctxt:  An XML parser context
229  * @name:  the entity name 
230  * @type:  the entity type 
231  * @publicId: The public ID of the entity
232  * @systemId: The system ID of the entity
233  * @content: the entity value (without processing).
234  *
235  * An entity definition has been parsed
236  */
237 static void
238 entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
239           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
240 {
241     fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
242             name, type, publicId, systemId, content);
243 }
244
245 /**
246  * attributeDeclDebug:
247  * @ctxt:  An XML parser context
248  * @name:  the attribute name 
249  * @type:  the attribute type 
250  *
251  * An attribute definition has been parsed
252  */
253 static void
254 attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *elem, const xmlChar *name,
255               int type, int def, const xmlChar *defaultValue,
256               xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
257 {
258     fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
259             elem, name, type, def, defaultValue);
260 }
261
262 /**
263  * elementDeclDebug:
264  * @ctxt:  An XML parser context
265  * @name:  the element name 
266  * @type:  the element type 
267  * @content: the element value (without processing).
268  *
269  * An element definition has been parsed
270  */
271 static void
272 elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
273             xmlElementContentPtr content ATTRIBUTE_UNUSED)
274 {
275     fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
276             name, type);
277 }
278
279 /**
280  * notationDeclDebug:
281  * @ctxt:  An XML parser context
282  * @name: The name of the notation
283  * @publicId: The public ID of the entity
284  * @systemId: The system ID of the entity
285  *
286  * What to do when a notation declaration has been parsed.
287  */
288 static void
289 notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
290              const xmlChar *publicId, const xmlChar *systemId)
291 {
292     fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
293             (char *) name, (char *) publicId, (char *) systemId);
294 }
295
296 /**
297  * unparsedEntityDeclDebug:
298  * @ctxt:  An XML parser context
299  * @name: The name of the entity
300  * @publicId: The public ID of the entity
301  * @systemId: The system ID of the entity
302  * @notationName: the name of the notation
303  *
304  * What to do when an unparsed entity declaration is parsed
305  */
306 static void
307 unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
308                    const xmlChar *publicId, const xmlChar *systemId,
309                    const xmlChar *notationName)
310 {
311     fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
312             (char *) name, (char *) publicId, (char *) systemId,
313             (char *) notationName);
314 }
315
316 /**
317  * setDocumentLocatorDebug:
318  * @ctxt:  An XML parser context
319  * @loc: A SAX Locator
320  *
321  * Receive the document locator at startup, actually xmlDefaultSAXLocator
322  * Everything is available on the context, so this is useless in our case.
323  */
324 static void
325 setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
326 {
327     fprintf(stdout, "SAX.setDocumentLocator()\n");
328 }
329
330 /**
331  * startDocumentDebug:
332  * @ctxt:  An XML parser context
333  *
334  * called when the document start being processed.
335  */
336 static void
337 startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
338 {
339     fprintf(stdout, "SAX.startDocument()\n");
340 }
341
342 /**
343  * endDocumentDebug:
344  * @ctxt:  An XML parser context
345  *
346  * called when the document end has been detected.
347  */
348 static void
349 endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
350 {
351     fprintf(stdout, "SAX.endDocument()\n");
352 }
353
354 /**
355  * startElementDebug:
356  * @ctxt:  An XML parser context
357  * @name:  The element name
358  *
359  * called when an opening tag has been processed.
360  */
361 static void
362 startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
363 {
364     int i;
365
366     fprintf(stdout, "SAX.startElement(%s", (char *) name);
367     if (atts != NULL) {
368         for (i = 0;(atts[i] != NULL);i++) {
369             fprintf(stdout, ", %s", atts[i++]);
370             if (atts[i] != NULL) {
371                 unsigned char output[40];
372                 const unsigned char *att = atts[i];
373                 int outlen, attlen;
374                 fprintf(stdout, "='");
375                 while ((attlen = strlen((char*)att)) > 0) {
376                     outlen = sizeof output - 1;
377                     htmlEncodeEntities(output, &outlen, att, &attlen, '\'');
378                     output[outlen] = 0;
379                     fprintf(stdout, "%s", (char *) output);
380                     att += attlen;
381                 }
382                 fprintf(stdout, "'");
383             }
384         }
385     }
386     fprintf(stdout, ")\n");
387 }
388
389 /**
390  * endElementDebug:
391  * @ctxt:  An XML parser context
392  * @name:  The element name
393  *
394  * called when the end of an element has been detected.
395  */
396 static void
397 endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
398 {
399     fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
400 }
401
402 /**
403  * charactersDebug:
404  * @ctxt:  An XML parser context
405  * @ch:  a xmlChar string
406  * @len: the number of xmlChar
407  *
408  * receiving some chars from the parser.
409  * Question: how much at a time ???
410  */
411 static void
412 charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
413 {
414     unsigned char output[40];
415     int inlen = len, outlen = 30;
416
417     htmlEncodeEntities(output, &outlen, ch, &inlen, 0);
418     output[outlen] = 0;
419
420     fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
421 }
422
423 /**
424  * cdataDebug:
425  * @ctxt:  An XML parser context
426  * @ch:  a xmlChar string
427  * @len: the number of xmlChar
428  *
429  * receiving some cdata chars from the parser.
430  * Question: how much at a time ???
431  */
432 static void
433 cdataDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
434 {
435     unsigned char output[40];
436     int inlen = len, outlen = 30;
437
438     htmlEncodeEntities(output, &outlen, ch, &inlen, 0);
439     output[outlen] = 0;
440
441     fprintf(stdout, "SAX.cdata(%s, %d)\n", output, len);
442 }
443
444 /**
445  * referenceDebug:
446  * @ctxt:  An XML parser context
447  * @name:  The entity name
448  *
449  * called when an entity reference is detected. 
450  */
451 static void
452 referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
453 {
454     fprintf(stdout, "SAX.reference(%s)\n", name);
455 }
456
457 /**
458  * ignorableWhitespaceDebug:
459  * @ctxt:  An XML parser context
460  * @ch:  a xmlChar string
461  * @start: the first char in the string
462  * @len: the number of xmlChar
463  *
464  * receiving some ignorable whitespaces from the parser.
465  * Question: how much at a time ???
466  */
467 static void
468 ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
469 {
470     char output[40];
471     int i;
472
473     for (i = 0;(i<len) && (i < 30);i++)
474         output[i] = ch[i];
475     output[i] = 0;
476
477     fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
478 }
479
480 /**
481  * processingInstructionDebug:
482  * @ctxt:  An XML parser context
483  * @target:  the target name
484  * @data: the PI data's
485  * @len: the number of xmlChar
486  *
487  * A processing instruction has been parsed.
488  */
489 static void
490 processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
491                       const xmlChar *data)
492 {
493     fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
494             (char *) target, (char *) data);
495 }
496
497 /**
498  * commentDebug:
499  * @ctxt:  An XML parser context
500  * @value:  the comment content
501  *
502  * A comment has been parsed.
503  */
504 static void
505 commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
506 {
507     fprintf(stdout, "SAX.comment(%s)\n", value);
508 }
509
510 /**
511  * warningDebug:
512  * @ctxt:  An XML parser context
513  * @msg:  the message to display/transmit
514  * @...:  extra parameters for the message display
515  *
516  * Display and format a warning messages, gives file, line, position and
517  * extra parameters.
518  */
519 static void
520 warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
521 {
522     va_list args;
523
524     va_start(args, msg);
525     fprintf(stdout, "SAX.warning: ");
526     vfprintf(stdout, msg, args);
527     va_end(args);
528 }
529
530 /**
531  * errorDebug:
532  * @ctxt:  An XML parser context
533  * @msg:  the message to display/transmit
534  * @...:  extra parameters for the message display
535  *
536  * Display and format a error messages, gives file, line, position and
537  * extra parameters.
538  */
539 static void
540 errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
541 {
542     va_list args;
543
544     va_start(args, msg);
545     fprintf(stdout, "SAX.error: ");
546     vfprintf(stdout, msg, args);
547     va_end(args);
548 }
549
550 /**
551  * fatalErrorDebug:
552  * @ctxt:  An XML parser context
553  * @msg:  the message to display/transmit
554  * @...:  extra parameters for the message display
555  *
556  * Display and format a fatalError messages, gives file, line, position and
557  * extra parameters.
558  */
559 static void
560 fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
561 {
562     va_list args;
563
564     va_start(args, msg);
565     fprintf(stdout, "SAX.fatalError: ");
566     vfprintf(stdout, msg, args);
567     va_end(args);
568 }
569
570 xmlSAXHandler debugSAXHandlerStruct = {
571     internalSubsetDebug,
572     isStandaloneDebug,
573     hasInternalSubsetDebug,
574     hasExternalSubsetDebug,
575     resolveEntityDebug,
576     getEntityDebug,
577     entityDeclDebug,
578     notationDeclDebug,
579     attributeDeclDebug,
580     elementDeclDebug,
581     unparsedEntityDeclDebug,
582     setDocumentLocatorDebug,
583     startDocumentDebug,
584     endDocumentDebug,
585     startElementDebug,
586     endElementDebug,
587     referenceDebug,
588     charactersDebug,
589     ignorableWhitespaceDebug,
590     processingInstructionDebug,
591     commentDebug,
592     warningDebug,
593     errorDebug,
594     fatalErrorDebug,
595     getParameterEntityDebug,
596     cdataDebug,
597     NULL,
598     1
599 };
600
601 xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
602 /************************************************************************
603  *                                                                      *
604  *                              Debug                                   *
605  *                                                                      *
606  ************************************************************************/
607
608 static void
609 parseSAXFile(char *filename) {
610     htmlDocPtr doc = NULL;
611
612     /*
613      * Empty callbacks for checking
614      */
615     if (push) {
616         FILE *f;
617
618         f = fopen(filename, "r");
619         if (f != NULL) {
620             int res, size = 3;
621             char chars[4096];
622             htmlParserCtxtPtr ctxt;
623
624             /* if (repeat) */
625                 size = 4096;
626             res = fread(chars, 1, 4, f);
627             if (res > 0) {
628                 ctxt = htmlCreatePushParserCtxt(emptySAXHandler, NULL,
629                             chars, res, filename, XML_CHAR_ENCODING_NONE);
630                 while ((res = fread(chars, 1, size, f)) > 0) {
631                     htmlParseChunk(ctxt, chars, res, 0);
632                 }
633                 htmlParseChunk(ctxt, chars, 0, 1);
634                 doc = ctxt->myDoc;
635                 htmlFreeParserCtxt(ctxt);
636             }
637             if (doc != NULL) {
638                 fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
639                 xmlFreeDoc(doc);
640             }
641             fclose(f);
642         }
643         if (!noout) {
644             f = fopen(filename, "r");
645             if (f != NULL) {
646                 int res, size = 3;
647                 char chars[4096];
648                 htmlParserCtxtPtr ctxt;
649
650                 /* if (repeat) */
651                     size = 4096;
652                 res = fread(chars, 1, 4, f);
653                 if (res > 0) {
654                     ctxt = htmlCreatePushParserCtxt(debugSAXHandler, NULL,
655                                 chars, res, filename, XML_CHAR_ENCODING_NONE);
656                     while ((res = fread(chars, 1, size, f)) > 0) {
657                         htmlParseChunk(ctxt, chars, res, 0);
658                     }
659                     htmlParseChunk(ctxt, chars, 0, 1);
660                     doc = ctxt->myDoc;
661                     htmlFreeParserCtxt(ctxt);
662                 }
663                 if (doc != NULL) {
664                     fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
665                     xmlFreeDoc(doc);
666                 }
667                 fclose(f);
668             }
669         }
670     } else {    
671         doc = htmlSAXParseFile(filename, NULL, emptySAXHandler, NULL);
672         if (doc != NULL) {
673             fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
674             xmlFreeDoc(doc);
675         }
676
677         if (!noout) {
678             /*
679              * Debug callback
680              */
681             doc = htmlSAXParseFile(filename, NULL, debugSAXHandler, NULL);
682             if (doc != NULL) {
683                 fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
684                 xmlFreeDoc(doc);
685             }
686         }
687     }
688 }
689
690 static void
691 parseAndPrintFile(char *filename) {
692     htmlDocPtr doc = NULL, tmp;
693
694     /*
695      * build an HTML tree from a string;
696      */
697     if (push) {
698         FILE *f;
699
700         f = fopen(filename, "r");
701         if (f != NULL) {
702             int res, size = 3;
703             char chars[4096];
704             htmlParserCtxtPtr ctxt;
705
706             /* if (repeat) */
707                 size = 4096;
708             res = fread(chars, 1, 4, f);
709             if (res > 0) {
710                 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
711                             chars, res, filename, XML_CHAR_ENCODING_NONE);
712                 while ((res = fread(chars, 1, size, f)) > 0) {
713                     htmlParseChunk(ctxt, chars, res, 0);
714                 }
715                 htmlParseChunk(ctxt, chars, 0, 1);
716                 doc = ctxt->myDoc;
717                 htmlFreeParserCtxt(ctxt);
718             }
719             fclose(f);
720         }
721     } else {    
722         doc = htmlParseFile(filename, NULL);
723     }
724     if (doc == NULL) {
725         xmlGenericError(xmlGenericErrorContext,
726                 "Could not parse %s\n", filename);
727     }
728
729     /*
730      * test intermediate copy if needed.
731      */
732     if (copy) {
733         tmp = doc;
734         doc = xmlCopyDoc(doc, 1);
735         xmlFreeDoc(tmp);
736     }
737
738     /*
739      * print it.
740      */
741     if (!noout) { 
742 #ifdef LIBXML_DEBUG_ENABLED
743         if (!debug) {
744             if (encoding)
745                 htmlSaveFileEnc("-", doc, encoding);
746             else
747                 htmlDocDump(stdout, doc);
748         } else
749             xmlDebugDumpDocument(stdout, doc);
750 #else
751         if (encoding)
752             htmlSaveFileEnc("-", doc, encoding);
753         else
754             htmlDocDump(stdout, doc);
755 #endif
756     }   
757
758     /*
759      * free it.
760      */
761     xmlFreeDoc(doc);
762 }
763
764 int main(int argc, char **argv) {
765     int i, count;
766     int files = 0;
767
768     for (i = 1; i < argc ; i++) {
769 #ifdef LIBXML_DEBUG_ENABLED
770         if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
771             debug++;
772         else
773 #endif
774             if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
775             copy++;
776         else if ((!strcmp(argv[i], "-push")) || (!strcmp(argv[i], "--push")))
777             push++;
778         else if ((!strcmp(argv[i], "-sax")) || (!strcmp(argv[i], "--sax")))
779             sax++;
780         else if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout")))
781             noout++;
782         else if ((!strcmp(argv[i], "-repeat")) ||
783                  (!strcmp(argv[i], "--repeat")))
784             repeat++;
785         else if ((!strcmp(argv[i], "-encode")) ||
786                  (!strcmp(argv[i], "--encode"))) {
787             i++;
788             encoding = argv[i];
789         }
790     }
791     for (i = 1; i < argc ; i++) {
792         if ((!strcmp(argv[i], "-encode")) ||
793                  (!strcmp(argv[i], "--encode"))) {
794             i++;
795             continue;
796         }
797         if (argv[i][0] != '-') {
798             if (repeat) {
799                 for (count = 0;count < 100 * repeat;count++) {
800                     if (sax)
801                         parseSAXFile(argv[i]);
802                     else   
803                         parseAndPrintFile(argv[i]);
804                 }    
805             } else {
806                 if (sax)
807                     parseSAXFile(argv[i]);
808                 else   
809                     parseAndPrintFile(argv[i]);
810             }
811             files ++;
812         }
813     }
814     if (files == 0) {
815         printf("Usage : %s [--debug] [--copy] [--copy] HTMLfiles ...\n",
816                argv[0]);
817         printf("\tParse the HTML files and output the result of the parsing\n");
818 #ifdef LIBXML_DEBUG_ENABLED
819         printf("\t--debug : dump a debug tree of the in-memory document\n");
820 #endif
821         printf("\t--copy : used to test the internal copy implementation\n");
822         printf("\t--sax : debug the sequence of SAX callbacks\n");
823         printf("\t--repeat : parse the file 100 times, for timing\n");
824         printf("\t--noout : do not print the result\n");
825         printf("\t--push : use the push mode parser\n");
826         printf("\t--encode encoding : output in the given encoding\n");
827     }
828     xmlCleanupParser();
829     xmlMemoryDump();
830
831     return(0);
832 }
833 #else /* !LIBXML_HTML_ENABLED */
834 #include <stdio.h>
835 int main(int argc, char **argv) {
836     printf("%s : HTML support not compiled in\n", argv[0]);
837     return(0);
838 }
839 #endif