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