blob: 2ce82cb6075ca8b123fffb0edd1e01ae34da990a [file] [log] [blame]
Daniel Veillard5099ae81999-04-21 20:12:07 +00001/*
2 * tester.c : a small tester program for parsing using the SAX API.
3 *
4 * See Copyright for the status of this software.
5 *
6 * Daniel.Veillard@w3.org
7 */
8
9#ifdef WIN32
10#define HAVE_FCNTL_H
11#include <io.h>
12#else
13#include <config.h>
14#endif
15#include <sys/types.h>
16#ifdef HAVE_SYS_STAT_H
17#include <sys/stat.h>
18#endif
19#ifdef HAVE_FCNTL_H
20#include <fcntl.h>
21#endif
22#ifdef HAVE_UNISTD_H
23#include <unistd.h>
24#endif
25#include <stdio.h>
26#include <string.h>
27#include <stdlib.h>
28#include <stdarg.h>
29
30#include "parser.h"
31#include "tree.h"
32#include "debugXML.h"
33
34static int debug = 0;
35static int copy = 0;
36static int recovery = 0;
37
38xmlSAXHandler emptySAXHandlerStruct = {
39 NULL, /* internalSubset */
40 NULL, /* isStandalone */
41 NULL, /* hasInternalSubset */
42 NULL, /* hasExternalSubset */
43 NULL, /* resolveEntity */
44 NULL, /* getEntity */
45 NULL, /* entityDecl */
46 NULL, /* notationDecl */
47 NULL, /* attributeDecl */
48 NULL, /* elementDecl */
49 NULL, /* unparsedEntityDecl */
50 NULL, /* setDocumentLocator */
51 NULL, /* startDocument */
52 NULL, /* endDocument */
53 NULL, /* startElement */
54 NULL, /* endElement */
55 NULL, /* reference */
56 NULL, /* characters */
57 NULL, /* ignorableWhitespace */
58 NULL, /* processingInstruction */
59 NULL, /* comment */
60 NULL, /* xmlParserWarning */
61 NULL, /* xmlParserError */
62 NULL, /* xmlParserError */
63};
64
65xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
66
67/*
68 * Note: there is a couple of errors introduced on purpose.
69 */
70static CHAR buffer[] =
71"<?xml version=\"1.0\"?>\n\
72<?xml:namespace ns = \"http://www.ietf.org/standards/dav/\" prefix = \"D\"?>\n\
73<?xml:namespace ns = \"http://www.w3.com/standards/z39.50/\" prefix = \"Z\"?>\n\
74<D:propertyupdate>\n\
75<D:set a=\"'toto'\" b>\n\
76 <D:prop>\n\
77 <Z:authors>\n\
78 <Z:Author>Jim Whitehead</Z:Author>\n\
79 <Z:Author>Roy Fielding</Z:Author>\n\
80 </Z:authors>\n\
81 </D:prop>\n\
82 </D:set>\n\
83 <D:remove>\n\
84 <D:prop><Z:Copyright-Owner/></D:prop>\n\
85 </D:remove>\n\
86</D:propertyupdate>\n\
87\n\
88";
89
90/************************************************************************
91 * *
92 * Debug Handlers *
93 * *
94 ************************************************************************/
95
96/**
97 * isStandaloneDebug:
98 * @ctxt: An XML parser context
99 *
100 * Is this document tagged standalone ?
101 *
102 * Returns 1 if true
103 */
104int
105isStandaloneDebug(xmlParserCtxtPtr ctxt)
106{
107 fprintf(stderr, "SAX.isStandalone()\n");
108 return(0);
109}
110
111/**
112 * hasInternalSubsetDebug:
113 * @ctxt: An XML parser context
114 *
115 * Does this document has an internal subset
116 *
117 * Returns 1 if true
118 */
119int
120hasInternalSubsetDebug(xmlParserCtxtPtr ctxt)
121{
122 fprintf(stderr, "SAX.hasInternalSubset()\n");
123 return(0);
124}
125
126/**
127 * hasExternalSubsetDebug:
128 * @ctxt: An XML parser context
129 *
130 * Does this document has an external subset
131 *
132 * Returns 1 if true
133 */
134int
135hasExternalSubsetDebug(xmlParserCtxtPtr ctxt)
136{
137 fprintf(stderr, "SAX.hasExternalSubset()\n");
138 return(0);
139}
140
141/**
142 * hasInternalSubsetDebug:
143 * @ctxt: An XML parser context
144 *
145 * Does this document has an internal subset
146 */
147void
148internalSubsetDebug(xmlParserCtxtPtr ctxt, const CHAR *name,
149 const CHAR *ExternalID, const CHAR *SystemID)
150{
151 fprintf(stderr, "SAX.internalSubset(%s, %s, %s)\n",
152 name, ExternalID, SystemID);
153}
154
155/**
156 * resolveEntityDebug:
157 * @ctxt: An XML parser context
158 * @publicId: The public ID of the entity
159 * @systemId: The system ID of the entity
160 *
161 * Special entity resolver, better left to the parser, it has
162 * more context than the application layer.
163 * The default behaviour is to NOT resolve the entities, in that case
164 * the ENTITY_REF nodes are built in the structure (and the parameter
165 * values).
166 *
167 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
168 */
169xmlParserInputPtr
170resolveEntityDebug(xmlParserCtxtPtr ctxt, const CHAR *publicId, const CHAR *systemId)
171{
172 fprintf(stderr, "SAX.resolveEntity(%s, %s)\n",
173 (char *)publicId, (char *)systemId);
174 return(NULL);
175}
176
177/**
178 * getEntityDebug:
179 * @ctxt: An XML parser context
180 * @name: The entity name
181 *
182 * Get an entity by name
183 *
184 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
185 */
186xmlEntityPtr
187getEntityDebug(xmlParserCtxtPtr ctxt, const CHAR *name)
188{
189 fprintf(stderr, "SAX.getEntity(%s)\n", name);
190 return(NULL);
191}
192
193
194/**
195 * entityDeclDebug:
196 * @ctxt: An XML parser context
197 * @name: the entity name
198 * @type: the entity type
199 * @publicId: The public ID of the entity
200 * @systemId: The system ID of the entity
201 * @content: the entity value (without processing).
202 *
203 * An entity definition has been parsed
204 */
205void
206entityDeclDebug(xmlParserCtxtPtr ctxt, const CHAR *name, int type,
207 const CHAR *publicId, const CHAR *systemId, CHAR *content)
208{
209 fprintf(stderr, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
210 name, type, publicId, systemId, content);
211}
212
213/**
214 * attributeDeclDebug:
215 * @ctxt: An XML parser context
216 * @name: the attribute name
217 * @type: the attribute type
218 *
219 * An attribute definition has been parsed
220 */
221void
222attributeDeclDebug(xmlParserCtxtPtr ctxt, const CHAR *elem, const CHAR *name,
223 int type, int def, const CHAR *defaultValue,
224 xmlEnumerationPtr tree)
225{
226 fprintf(stderr, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
227 elem, name, type, def, defaultValue);
228}
229
230/**
231 * elementDeclDebug:
232 * @ctxt: An XML parser context
233 * @name: the element name
234 * @type: the element type
235 * @content: the element value (without processing).
236 *
237 * An element definition has been parsed
238 */
239void
240elementDeclDebug(xmlParserCtxtPtr ctxt, const CHAR *name, int type,
241 xmlElementContentPtr content)
242{
243 fprintf(stderr, "SAX.elementDecl(%s, %d, ...)\n",
244 name, type);
245}
246
247/**
248 * notationDeclDebug:
249 * @ctxt: An XML parser context
250 * @name: The name of the notation
251 * @publicId: The public ID of the entity
252 * @systemId: The system ID of the entity
253 *
254 * What to do when a notation declaration has been parsed.
255 * TODO Not handled currently.
256 */
257void
258notationDeclDebug(xmlParserCtxtPtr ctxt, const CHAR *name,
259 const CHAR *publicId, const CHAR *systemId)
260{
261 fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n",
262 (char *) name, (char *) publicId, (char *) systemId);
263}
264
265/**
266 * unparsedEntityDeclDebug:
267 * @ctxt: An XML parser context
268 * @name: The name of the entity
269 * @publicId: The public ID of the entity
270 * @systemId: The system ID of the entity
271 * @notationName: the name of the notation
272 *
273 * What to do when an unparsed entity declaration is parsed
274 * TODO Create an Entity node.
275 */
276void
277unparsedEntityDeclDebug(xmlParserCtxtPtr ctxt, const CHAR *name,
278 const CHAR *publicId, const CHAR *systemId,
279 const CHAR *notationName)
280{
281 fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
282 (char *) name, (char *) publicId, (char *) systemId,
283 (char *) notationName);
284}
285
286/**
287 * setDocumentLocatorDebug:
288 * @ctxt: An XML parser context
289 * @loc: A SAX Locator
290 *
291 * Receive the document locator at startup, actually xmlDefaultSAXLocator
292 * Everything is available on the context, so this is useless in our case.
293 */
294void
295setDocumentLocatorDebug(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc)
296{
297 fprintf(stderr, "SAX.setDocumentLocator()\n");
298}
299
300/**
301 * startDocumentDebug:
302 * @ctxt: An XML parser context
303 *
304 * called when the document start being processed.
305 */
306void
307startDocumentDebug(xmlParserCtxtPtr ctxt)
308{
309 fprintf(stderr, "SAX.startDocument()\n");
310}
311
312/**
313 * endDocumentDebug:
314 * @ctxt: An XML parser context
315 *
316 * called when the document end has been detected.
317 */
318void
319endDocumentDebug(xmlParserCtxtPtr ctxt)
320{
321 fprintf(stderr, "SAX.endDocument()\n");
322}
323
324/**
325 * startElementDebug:
326 * @ctxt: An XML parser context
327 * @name: The element name
328 *
329 * called when an opening tag has been processed.
330 * TODO We currently have a small pblm with the arguments ...
331 */
332void
333startElementDebug(xmlParserCtxtPtr ctxt, const CHAR *name, const CHAR **atts)
334{
335 int i;
336
337 fprintf(stderr, "SAX.startElement(%s", (char *) name);
338 if (atts != NULL) {
339 for (i = 0;(atts[i] != NULL);i++) {
340 fprintf(stderr, ", %s='", atts[i++]);
341 fprintf(stderr, "%s'", atts[i]);
342 }
343 }
344 fprintf(stderr, ")\n");
345}
346
347/**
348 * endElementDebug:
349 * @ctxt: An XML parser context
350 * @name: The element name
351 *
352 * called when the end of an element has been detected.
353 */
354void
355endElementDebug(xmlParserCtxtPtr ctxt, const CHAR *name)
356{
357 fprintf(stderr, "SAX.endElement(%s)\n", (char *) name);
358}
359
360/**
361 * charactersDebug:
362 * @ctxt: An XML parser context
363 * @ch: a CHAR string
364 * @len: the number of CHAR
365 *
366 * receiving some chars from the parser.
367 * Question: how much at a time ???
368 */
369void
370charactersDebug(xmlParserCtxtPtr ctxt, const CHAR *ch, int len)
371{
372 fprintf(stderr, "SAX.characters(%.30s, %d)\n", (char *) ch, len);
373}
374
375/**
376 * referenceDebug:
377 * @ctxt: An XML parser context
378 * @name: The entity name
379 *
380 * called when an entity reference is detected.
381 */
382void
383referenceDebug(xmlParserCtxtPtr ctxt, const CHAR *name)
384{
385 fprintf(stderr, "SAX.reference(%s)\n", name);
386}
387
388/**
389 * ignorableWhitespaceDebug:
390 * @ctxt: An XML parser context
391 * @ch: a CHAR string
392 * @start: the first char in the string
393 * @len: the number of CHAR
394 *
395 * receiving some ignorable whitespaces from the parser.
396 * Question: how much at a time ???
397 */
398void
399ignorableWhitespaceDebug(xmlParserCtxtPtr ctxt, const CHAR *ch, int len)
400{
401 fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d)\n",
402 (char *) ch, len);
403}
404
405/**
406 * processingInstructionDebug:
407 * @ctxt: An XML parser context
408 * @target: the target name
409 * @data: the PI data's
410 * @len: the number of CHAR
411 *
412 * A processing instruction has been parsed.
413 */
414void
415processingInstructionDebug(xmlParserCtxtPtr ctxt, const CHAR *target,
416 const CHAR *data)
417{
418 fprintf(stderr, "SAX.processingInstruction(%s, %s)\n",
419 (char *) target, (char *) data);
420}
421
422/**
423 * commentDebug:
424 * @ctxt: An XML parser context
425 * @value: the comment content
426 *
427 * A comment has been parsed.
428 */
429void
430commentDebug(xmlParserCtxtPtr ctxt, const CHAR *value)
431{
432 fprintf(stderr, "SAX.comment(%s)\n", value);
433}
434
435/**
436 * warningDebug:
437 * @ctxt: An XML parser context
438 * @msg: the message to display/transmit
439 * @...: extra parameters for the message display
440 *
441 * Display and format a warning messages, gives file, line, position and
442 * extra parameters.
443 */
444void
445warningDebug(xmlParserCtxtPtr ctxt, const char *msg, ...)
446{
447 va_list args;
448
449 va_start(args, msg);
450 fprintf(stderr, "SAX.warning: ");
451 vfprintf(stderr, msg, args);
452 va_end(args);
453}
454
455/**
456 * errorDebug:
457 * @ctxt: An XML parser context
458 * @msg: the message to display/transmit
459 * @...: extra parameters for the message display
460 *
461 * Display and format a error messages, gives file, line, position and
462 * extra parameters.
463 */
464void
465errorDebug(xmlParserCtxtPtr ctxt, const char *msg, ...)
466{
467 va_list args;
468
469 va_start(args, msg);
470 fprintf(stderr, "SAX.error: ");
471 vfprintf(stderr, msg, args);
472 va_end(args);
473}
474
475/**
476 * fatalErrorDebug:
477 * @ctxt: An XML parser context
478 * @msg: the message to display/transmit
479 * @...: extra parameters for the message display
480 *
481 * Display and format a fatalError messages, gives file, line, position and
482 * extra parameters.
483 */
484void
485fatalErrorDebug(xmlParserCtxtPtr ctxt, const char *msg, ...)
486{
487 va_list args;
488
489 va_start(args, msg);
490 fprintf(stderr, "SAX.fatalError: ");
491 vfprintf(stderr, msg, args);
492 va_end(args);
493}
494
495xmlSAXHandler debugSAXHandlerStruct = {
496 internalSubsetDebug,
497 isStandaloneDebug,
498 hasInternalSubsetDebug,
499 hasExternalSubsetDebug,
500 resolveEntityDebug,
501 getEntityDebug,
502 entityDeclDebug,
503 notationDeclDebug,
504 attributeDeclDebug,
505 elementDeclDebug,
506 unparsedEntityDeclDebug,
507 setDocumentLocatorDebug,
508 startDocumentDebug,
509 endDocumentDebug,
510 startElementDebug,
511 endElementDebug,
512 referenceDebug,
513 charactersDebug,
514 ignorableWhitespaceDebug,
515 processingInstructionDebug,
516 commentDebug,
517 warningDebug,
518 errorDebug,
519 fatalErrorDebug,
520};
521
522xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
523
524/************************************************************************
525 * *
526 * Debug *
527 * *
528 ************************************************************************/
529
530void parseAndPrintFile(char *filename) {
531 xmlDocPtr doc;
532
533 /*
534 * Empty callbacks for checking
535 */
536 doc = xmlSAXParseFile(emptySAXHandler, filename, 0);
537 if (doc != NULL) {
538 fprintf(stderr, "xmlSAXParseFile returned non-NULL\n");
539 xmlDocDump(stdout, doc);
540 }
541
542 /*
543 * Debug callback
544 */
545 doc = xmlSAXParseFile(debugSAXHandler, filename, 0);
546 if (doc != NULL) {
547 fprintf(stderr, "xmlSAXParseFile returned non-NULL\n");
548 xmlDocDump(stdout, doc);
549 }
550}
551
552void parseAndPrintBuffer(CHAR *buf) {
553 xmlDocPtr doc;
554
555 /*
556 * Empty callbacks for checking
557 */
558 doc = xmlSAXParseDoc(emptySAXHandler, buf, 0);
559 if (doc != NULL) {
560 fprintf(stderr, "xmlSAXParseDoc returned non-NULL\n");
561 xmlDocDump(stdout, doc);
562 }
563
564 /*
565 * Debug callback
566 */
567 doc = xmlSAXParseDoc(debugSAXHandler, buf, 0);
568 if (doc != NULL) {
569 fprintf(stderr, "xmlSAXParseDoc returned non-NULL\n");
570 xmlDocDump(stdout, doc);
571 }
572}
573
574int main(int argc, char **argv) {
575 int i;
576 int files = 0;
577
578 for (i = 1; i < argc ; i++) {
579 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
580 debug++;
581 else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
582 copy++;
583 else if ((!strcmp(argv[i], "-recover")) ||
584 (!strcmp(argv[i], "--recover")))
585 recovery++;
586 }
587 for (i = 1; i < argc ; i++) {
588 if (argv[i][0] != '-') {
589 parseAndPrintFile(argv[i]);
590 files ++;
591 }
592 }
593 if (files == 0) {
594 printf("\nFirst test for the parser, with errors\n");
595 parseAndPrintBuffer(buffer);
596 }
597
598 return(0);
599}