blob: 9ba83c60bffa3423fcfd06d8d9540d24752df2ed [file] [log] [blame]
Daniel Veillardeae522a2001-04-23 13:41:34 +00001/*
2 * testDocbook.c : a small tester program for SGML Docbook input.
3 *
4 * See Copyright for the status of this software.
5 *
Daniel Veillardc5d64342001-06-24 12:13:24 +00006 * daniel@veillard.com
Daniel Veillardeae522a2001-04-23 13:41:34 +00007 */
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>
Daniel Veillard3c01b1d2001-10-17 15:58:35 +000038#include <libxml/globals.h>
Daniel Veillardeae522a2001-04-23 13:41:34 +000039
40#ifdef LIBXML_DEBUG_ENABLED
41static int debug = 0;
42#endif
43static int copy = 0;
44static int sax = 0;
45static int repeat = 0;
46static int noout = 0;
Daniel Veillard61b33d52001-04-24 13:55:12 +000047static int noent = 0;
Daniel Veillardeae522a2001-04-23 13:41:34 +000048static int push = 0;
49static char *encoding = NULL;
50
51xmlSAXHandler 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 */
Daniel Veillardd0463562001-10-13 09:15:48 +000078 NULL, /* externalSubset */
79 1
Daniel Veillardeae522a2001-04-23 13:41:34 +000080};
81
82xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
83extern 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 */
99static int
Daniel Veillard01c13b52002-12-10 15:19:08 +0000100isStandaloneDebug(void *ctxt ATTRIBUTE_UNUSED)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000101{
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 */
114static int
Daniel Veillard01c13b52002-12-10 15:19:08 +0000115hasInternalSubsetDebug(void *ctxt ATTRIBUTE_UNUSED)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000116{
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 */
129static int
Daniel Veillard01c13b52002-12-10 15:19:08 +0000130hasExternalSubsetDebug(void *ctxt ATTRIBUTE_UNUSED)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000131{
132 fprintf(stdout, "SAX.hasExternalSubset()\n");
133 return(0);
134}
135
136/**
Daniel Veillard01c13b52002-12-10 15:19:08 +0000137 * internalSubsetDebug:
Daniel Veillardeae522a2001-04-23 13:41:34 +0000138 * @ctxt: An XML parser context
139 *
140 * Does this document has an internal subset
141 */
142static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000143internalSubsetDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillardeae522a2001-04-23 13:41:34 +0000144 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 */
171static xmlParserInputPtr
Daniel Veillard01c13b52002-12-10 15:19:08 +0000172resolveEntityDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000173{
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 */
203static xmlEntityPtr
Daniel Veillard01c13b52002-12-10 15:19:08 +0000204getEntityDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000205{
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 */
219static xmlEntityPtr
Daniel Veillard01c13b52002-12-10 15:19:08 +0000220getParameterEntityDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000221{
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 */
238static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000239entityDeclDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *name, int type,
Daniel Veillardeae522a2001-04-23 13:41:34 +0000240 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 */
254static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000255attributeDeclDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *elem,
Daniel Veillardeae522a2001-04-23 13:41:34 +0000256 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 */
273static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000274elementDeclDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *name, int type,
Daniel Veillardeae522a2001-04-23 13:41:34 +0000275 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 */
290static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000291notationDeclDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillardeae522a2001-04-23 13:41:34 +0000292 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 */
308static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000309unparsedEntityDeclDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillardeae522a2001-04-23 13:41:34 +0000310 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 */
326static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000327setDocumentLocatorDebug(void *ctxt ATTRIBUTE_UNUSED,
Daniel Veillardeae522a2001-04-23 13:41:34 +0000328 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 */
339static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000340startDocumentDebug(void *ctxt ATTRIBUTE_UNUSED)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000341{
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 */
351static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000352endDocumentDebug(void *ctxt ATTRIBUTE_UNUSED)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000353{
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 */
364static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000365startElementDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000366{
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 */
398static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000399endElementDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000400{
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 */
413static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000414charactersDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000415{
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 */
432static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000433referenceDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *name)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000434{
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 */
448static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000449ignorableWhitespaceDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000450{
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 */
470static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000471processingInstructionDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *target,
Daniel Veillardeae522a2001-04-23 13:41:34 +0000472 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 */
485static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000486commentDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *value)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000487{
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 */
499static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000500cdataBlockDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *value, int len)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000501{
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 */
512static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000513externalSubsetDebug(void *ctxt ATTRIBUTE_UNUSED, const xmlChar *name,
Daniel Veillardeae522a2001-04-23 13:41:34 +0000514 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 */
536static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000537warningDebug(void *ctxt ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000538{
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 */
556static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000557errorDebug(void *ctxt ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000558{
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 */
576static void
Daniel Veillard01c13b52002-12-10 15:19:08 +0000577fatalErrorDebug(void *ctxt ATTRIBUTE_UNUSED, const char *msg, ...)
Daniel Veillardeae522a2001-04-23 13:41:34 +0000578{
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
587xmlSAXHandler 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,
Daniel Veillardd0463562001-10-13 09:15:48 +0000614 externalSubsetDebug,
615 1
Daniel Veillardeae522a2001-04-23 13:41:34 +0000616};
617
618xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
619/************************************************************************
620 * *
621 * Debug *
622 * *
623 ************************************************************************/
624
625static void
626parseSAXFile(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, 0);
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, 0);
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
707static void
708parseAndPrintFile(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, 0);
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
780int 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++;
Daniel Veillard61b33d52001-04-24 13:55:12 +0000796 else if ((!strcmp(argv[i], "-noent")) || (!strcmp(argv[i], "--noent")))
797 noent++;
Daniel Veillardeae522a2001-04-23 13:41:34 +0000798 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 }
Daniel Veillard61b33d52001-04-24 13:55:12 +0000809 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillardeae522a2001-04-23 13:41:34 +0000810 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>
854int main(int argc, char **argv) {
855 printf("%s : SGML support not compiled in\n", argv[0]);
856 return(0);
857}
858#endif