mirror of
https://gitlab.gnome.org/GNOME/libxml2
synced 2025-03-28 21:33:13 +00:00

* parser.c: humm, changed the way the SAX parser work when xmlSubstituteEntitiesDefault(1) is set, it will then do the entity registration and loading by itself in case the user provided SAX getEntity() returns NULL. * testSAX.c: added --noent to test the behaviour. Daniel
738 lines
17 KiB
C
738 lines
17 KiB
C
/*
|
|
* testSAX.c : a small tester program for parsing using the SAX API.
|
|
*
|
|
* See Copyright for the status of this software.
|
|
*
|
|
* daniel@veillard.com
|
|
*/
|
|
|
|
#include "libxml.h"
|
|
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
#include <sys/types.h>
|
|
#endif
|
|
#ifdef HAVE_SYS_STAT_H
|
|
#include <sys/stat.h>
|
|
#endif
|
|
#ifdef HAVE_FCNTL_H
|
|
#include <fcntl.h>
|
|
#endif
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#ifdef HAVE_STDLIB_H
|
|
#include <stdlib.h>
|
|
#endif
|
|
#ifdef HAVE_STRING_H
|
|
#include <string.h>
|
|
#endif
|
|
|
|
|
|
#include <libxml/globals.h>
|
|
#include <libxml/xmlerror.h>
|
|
#include <libxml/parser.h>
|
|
#include <libxml/parserInternals.h> /* only for xmlNewInputFromFile() */
|
|
#include <libxml/tree.h>
|
|
#include <libxml/debugXML.h>
|
|
#include <libxml/xmlmemory.h>
|
|
|
|
static int debug = 0;
|
|
static int copy = 0;
|
|
static int recovery = 0;
|
|
static int push = 0;
|
|
static int speed = 0;
|
|
static int noent = 0;
|
|
|
|
xmlSAXHandler emptySAXHandlerStruct = {
|
|
NULL, /* internalSubset */
|
|
NULL, /* isStandalone */
|
|
NULL, /* hasInternalSubset */
|
|
NULL, /* hasExternalSubset */
|
|
NULL, /* resolveEntity */
|
|
NULL, /* getEntity */
|
|
NULL, /* entityDecl */
|
|
NULL, /* notationDecl */
|
|
NULL, /* attributeDecl */
|
|
NULL, /* elementDecl */
|
|
NULL, /* unparsedEntityDecl */
|
|
NULL, /* setDocumentLocator */
|
|
NULL, /* startDocument */
|
|
NULL, /* endDocument */
|
|
NULL, /* startElement */
|
|
NULL, /* endElement */
|
|
NULL, /* reference */
|
|
NULL, /* characters */
|
|
NULL, /* ignorableWhitespace */
|
|
NULL, /* processingInstruction */
|
|
NULL, /* comment */
|
|
NULL, /* xmlParserWarning */
|
|
NULL, /* xmlParserError */
|
|
NULL, /* xmlParserError */
|
|
NULL, /* getParameterEntity */
|
|
NULL, /* cdataBlock; */
|
|
NULL, /* externalSubset; */
|
|
1
|
|
};
|
|
|
|
xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
|
|
extern xmlSAXHandlerPtr debugSAXHandler;
|
|
|
|
/************************************************************************
|
|
* *
|
|
* Debug Handlers *
|
|
* *
|
|
************************************************************************/
|
|
|
|
/**
|
|
* isStandaloneDebug:
|
|
* @ctxt: An XML parser context
|
|
*
|
|
* Is this document tagged standalone ?
|
|
*
|
|
* Returns 1 if true
|
|
*/
|
|
static int
|
|
isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
|
|
{
|
|
fprintf(stdout, "SAX.isStandalone()\n");
|
|
return(0);
|
|
}
|
|
|
|
/**
|
|
* hasInternalSubsetDebug:
|
|
* @ctxt: An XML parser context
|
|
*
|
|
* Does this document has an internal subset
|
|
*
|
|
* Returns 1 if true
|
|
*/
|
|
static int
|
|
hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
|
|
{
|
|
fprintf(stdout, "SAX.hasInternalSubset()\n");
|
|
return(0);
|
|
}
|
|
|
|
/**
|
|
* hasExternalSubsetDebug:
|
|
* @ctxt: An XML parser context
|
|
*
|
|
* Does this document has an external subset
|
|
*
|
|
* Returns 1 if true
|
|
*/
|
|
static int
|
|
hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
|
|
{
|
|
fprintf(stdout, "SAX.hasExternalSubset()\n");
|
|
return(0);
|
|
}
|
|
|
|
/**
|
|
* internalSubsetDebug:
|
|
* @ctxt: An XML parser context
|
|
*
|
|
* Does this document has an internal subset
|
|
*/
|
|
static void
|
|
internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
|
|
const xmlChar *ExternalID, const xmlChar *SystemID)
|
|
{
|
|
fprintf(stdout, "SAX.internalSubset(%s,", name);
|
|
if (ExternalID == NULL)
|
|
fprintf(stdout, " ,");
|
|
else
|
|
fprintf(stdout, " %s,", ExternalID);
|
|
if (SystemID == NULL)
|
|
fprintf(stdout, " )\n");
|
|
else
|
|
fprintf(stdout, " %s)\n", SystemID);
|
|
}
|
|
|
|
/**
|
|
* externalSubsetDebug:
|
|
* @ctxt: An XML parser context
|
|
*
|
|
* Does this document has an external subset
|
|
*/
|
|
static void
|
|
externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
|
|
const xmlChar *ExternalID, const xmlChar *SystemID)
|
|
{
|
|
fprintf(stdout, "SAX.externalSubset(%s,", name);
|
|
if (ExternalID == NULL)
|
|
fprintf(stdout, " ,");
|
|
else
|
|
fprintf(stdout, " %s,", ExternalID);
|
|
if (SystemID == NULL)
|
|
fprintf(stdout, " )\n");
|
|
else
|
|
fprintf(stdout, " %s)\n", SystemID);
|
|
}
|
|
|
|
/**
|
|
* resolveEntityDebug:
|
|
* @ctxt: An XML parser context
|
|
* @publicId: The public ID of the entity
|
|
* @systemId: The system ID of the entity
|
|
*
|
|
* Special entity resolver, better left to the parser, it has
|
|
* more context than the application layer.
|
|
* The default behaviour is to NOT resolve the entities, in that case
|
|
* the ENTITY_REF nodes are built in the structure (and the parameter
|
|
* values).
|
|
*
|
|
* Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
|
|
*/
|
|
static xmlParserInputPtr
|
|
resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
|
|
{
|
|
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
|
|
|
|
|
|
fprintf(stdout, "SAX.resolveEntity(");
|
|
if (publicId != NULL)
|
|
fprintf(stdout, "%s", (char *)publicId);
|
|
else
|
|
fprintf(stdout, " ");
|
|
if (systemId != NULL)
|
|
fprintf(stdout, ", %s)\n", (char *)systemId);
|
|
else
|
|
fprintf(stdout, ", )\n");
|
|
/*********
|
|
if (systemId != NULL) {
|
|
return(xmlNewInputFromFile(ctxt, (char *) systemId));
|
|
}
|
|
*********/
|
|
return(NULL);
|
|
}
|
|
|
|
/**
|
|
* getEntityDebug:
|
|
* @ctxt: An XML parser context
|
|
* @name: The entity name
|
|
*
|
|
* Get an entity by name
|
|
*
|
|
* Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
|
|
*/
|
|
static xmlEntityPtr
|
|
getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
|
|
{
|
|
fprintf(stdout, "SAX.getEntity(%s)\n", name);
|
|
return(NULL);
|
|
}
|
|
|
|
/**
|
|
* getParameterEntityDebug:
|
|
* @ctxt: An XML parser context
|
|
* @name: The entity name
|
|
*
|
|
* Get a parameter entity by name
|
|
*
|
|
* Returns the xmlParserInputPtr
|
|
*/
|
|
static xmlEntityPtr
|
|
getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
|
|
{
|
|
fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
/**
|
|
* entityDeclDebug:
|
|
* @ctxt: An XML parser context
|
|
* @name: the entity name
|
|
* @type: the entity type
|
|
* @publicId: The public ID of the entity
|
|
* @systemId: The system ID of the entity
|
|
* @content: the entity value (without processing).
|
|
*
|
|
* An entity definition has been parsed
|
|
*/
|
|
static void
|
|
entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
|
|
const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
|
|
{
|
|
fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
|
|
name, type, publicId, systemId, content);
|
|
}
|
|
|
|
/**
|
|
* attributeDeclDebug:
|
|
* @ctxt: An XML parser context
|
|
* @name: the attribute name
|
|
* @type: the attribute type
|
|
*
|
|
* An attribute definition has been parsed
|
|
*/
|
|
static void
|
|
attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *elem, const xmlChar *name,
|
|
int type, int def, const xmlChar *defaultValue,
|
|
xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
|
|
{
|
|
if (defaultValue == NULL)
|
|
fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
|
|
elem, name, type, def);
|
|
else
|
|
fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
|
|
elem, name, type, def, defaultValue);
|
|
}
|
|
|
|
/**
|
|
* elementDeclDebug:
|
|
* @ctxt: An XML parser context
|
|
* @name: the element name
|
|
* @type: the element type
|
|
* @content: the element value (without processing).
|
|
*
|
|
* An element definition has been parsed
|
|
*/
|
|
static void
|
|
elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
|
|
xmlElementContentPtr content ATTRIBUTE_UNUSED)
|
|
{
|
|
fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
|
|
name, type);
|
|
}
|
|
|
|
/**
|
|
* notationDeclDebug:
|
|
* @ctxt: An XML parser context
|
|
* @name: The name of the notation
|
|
* @publicId: The public ID of the entity
|
|
* @systemId: The system ID of the entity
|
|
*
|
|
* What to do when a notation declaration has been parsed.
|
|
*/
|
|
static void
|
|
notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
|
|
const xmlChar *publicId, const xmlChar *systemId)
|
|
{
|
|
fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
|
|
(char *) name, (char *) publicId, (char *) systemId);
|
|
}
|
|
|
|
/**
|
|
* unparsedEntityDeclDebug:
|
|
* @ctxt: An XML parser context
|
|
* @name: The name of the entity
|
|
* @publicId: The public ID of the entity
|
|
* @systemId: The system ID of the entity
|
|
* @notationName: the name of the notation
|
|
*
|
|
* What to do when an unparsed entity declaration is parsed
|
|
*/
|
|
static void
|
|
unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
|
|
const xmlChar *publicId, const xmlChar *systemId,
|
|
const xmlChar *notationName)
|
|
{
|
|
fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
|
|
(char *) name, (char *) publicId, (char *) systemId,
|
|
(char *) notationName);
|
|
}
|
|
|
|
/**
|
|
* setDocumentLocatorDebug:
|
|
* @ctxt: An XML parser context
|
|
* @loc: A SAX Locator
|
|
*
|
|
* Receive the document locator at startup, actually xmlDefaultSAXLocator
|
|
* Everything is available on the context, so this is useless in our case.
|
|
*/
|
|
static void
|
|
setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
|
|
{
|
|
fprintf(stdout, "SAX.setDocumentLocator()\n");
|
|
}
|
|
|
|
/**
|
|
* startDocumentDebug:
|
|
* @ctxt: An XML parser context
|
|
*
|
|
* called when the document start being processed.
|
|
*/
|
|
static void
|
|
startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
|
|
{
|
|
fprintf(stdout, "SAX.startDocument()\n");
|
|
}
|
|
|
|
/**
|
|
* endDocumentDebug:
|
|
* @ctxt: An XML parser context
|
|
*
|
|
* called when the document end has been detected.
|
|
*/
|
|
static void
|
|
endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
|
|
{
|
|
fprintf(stdout, "SAX.endDocument()\n");
|
|
}
|
|
|
|
/**
|
|
* startElementDebug:
|
|
* @ctxt: An XML parser context
|
|
* @name: The element name
|
|
*
|
|
* called when an opening tag has been processed.
|
|
*/
|
|
static void
|
|
startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
|
|
{
|
|
int i;
|
|
|
|
fprintf(stdout, "SAX.startElement(%s", (char *) name);
|
|
if (atts != NULL) {
|
|
for (i = 0;(atts[i] != NULL);i++) {
|
|
fprintf(stdout, ", %s='", atts[i++]);
|
|
if (atts[i] != NULL)
|
|
fprintf(stdout, "%s'", atts[i]);
|
|
}
|
|
}
|
|
fprintf(stdout, ")\n");
|
|
}
|
|
|
|
/**
|
|
* endElementDebug:
|
|
* @ctxt: An XML parser context
|
|
* @name: The element name
|
|
*
|
|
* called when the end of an element has been detected.
|
|
*/
|
|
static void
|
|
endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
|
|
{
|
|
fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
|
|
}
|
|
|
|
/**
|
|
* charactersDebug:
|
|
* @ctxt: An XML parser context
|
|
* @ch: a xmlChar string
|
|
* @len: the number of xmlChar
|
|
*
|
|
* receiving some chars from the parser.
|
|
* Question: how much at a time ???
|
|
*/
|
|
static void
|
|
charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
|
|
{
|
|
char output[40];
|
|
int i;
|
|
|
|
for (i = 0;(i<len) && (i < 30);i++)
|
|
output[i] = ch[i];
|
|
output[i] = 0;
|
|
|
|
fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
|
|
}
|
|
|
|
/**
|
|
* referenceDebug:
|
|
* @ctxt: An XML parser context
|
|
* @name: The entity name
|
|
*
|
|
* called when an entity reference is detected.
|
|
*/
|
|
static void
|
|
referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
|
|
{
|
|
fprintf(stdout, "SAX.reference(%s)\n", name);
|
|
}
|
|
|
|
/**
|
|
* ignorableWhitespaceDebug:
|
|
* @ctxt: An XML parser context
|
|
* @ch: a xmlChar string
|
|
* @start: the first char in the string
|
|
* @len: the number of xmlChar
|
|
*
|
|
* receiving some ignorable whitespaces from the parser.
|
|
* Question: how much at a time ???
|
|
*/
|
|
static void
|
|
ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
|
|
{
|
|
char output[40];
|
|
int i;
|
|
|
|
for (i = 0;(i<len) && (i < 30);i++)
|
|
output[i] = ch[i];
|
|
output[i] = 0;
|
|
fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
|
|
}
|
|
|
|
/**
|
|
* processingInstructionDebug:
|
|
* @ctxt: An XML parser context
|
|
* @target: the target name
|
|
* @data: the PI data's
|
|
* @len: the number of xmlChar
|
|
*
|
|
* A processing instruction has been parsed.
|
|
*/
|
|
static void
|
|
processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
|
|
const xmlChar *data)
|
|
{
|
|
fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
|
|
(char *) target, (char *) data);
|
|
}
|
|
|
|
/**
|
|
* cdataBlockDebug:
|
|
* @ctx: the user data (XML parser context)
|
|
* @value: The pcdata content
|
|
* @len: the block length
|
|
*
|
|
* called when a pcdata block has been parsed
|
|
*/
|
|
static void
|
|
cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
|
|
{
|
|
fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
|
|
(char *) value, len);
|
|
}
|
|
|
|
/**
|
|
* commentDebug:
|
|
* @ctxt: An XML parser context
|
|
* @value: the comment content
|
|
*
|
|
* A comment has been parsed.
|
|
*/
|
|
static void
|
|
commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
|
|
{
|
|
fprintf(stdout, "SAX.comment(%s)\n", value);
|
|
}
|
|
|
|
/**
|
|
* warningDebug:
|
|
* @ctxt: An XML parser context
|
|
* @msg: the message to display/transmit
|
|
* @...: extra parameters for the message display
|
|
*
|
|
* Display and format a warning messages, gives file, line, position and
|
|
* extra parameters.
|
|
*/
|
|
static void
|
|
warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
|
|
{
|
|
va_list args;
|
|
|
|
va_start(args, msg);
|
|
fprintf(stdout, "SAX.warning: ");
|
|
vfprintf(stdout, msg, args);
|
|
va_end(args);
|
|
}
|
|
|
|
/**
|
|
* errorDebug:
|
|
* @ctxt: An XML parser context
|
|
* @msg: the message to display/transmit
|
|
* @...: extra parameters for the message display
|
|
*
|
|
* Display and format a error messages, gives file, line, position and
|
|
* extra parameters.
|
|
*/
|
|
static void
|
|
errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
|
|
{
|
|
va_list args;
|
|
|
|
va_start(args, msg);
|
|
fprintf(stdout, "SAX.error: ");
|
|
vfprintf(stdout, msg, args);
|
|
va_end(args);
|
|
}
|
|
|
|
/**
|
|
* fatalErrorDebug:
|
|
* @ctxt: An XML parser context
|
|
* @msg: the message to display/transmit
|
|
* @...: extra parameters for the message display
|
|
*
|
|
* Display and format a fatalError messages, gives file, line, position and
|
|
* extra parameters.
|
|
*/
|
|
static void
|
|
fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
|
|
{
|
|
va_list args;
|
|
|
|
va_start(args, msg);
|
|
fprintf(stdout, "SAX.fatalError: ");
|
|
vfprintf(stdout, msg, args);
|
|
va_end(args);
|
|
}
|
|
|
|
xmlSAXHandler debugSAXHandlerStruct = {
|
|
internalSubsetDebug,
|
|
isStandaloneDebug,
|
|
hasInternalSubsetDebug,
|
|
hasExternalSubsetDebug,
|
|
resolveEntityDebug,
|
|
getEntityDebug,
|
|
entityDeclDebug,
|
|
notationDeclDebug,
|
|
attributeDeclDebug,
|
|
elementDeclDebug,
|
|
unparsedEntityDeclDebug,
|
|
setDocumentLocatorDebug,
|
|
startDocumentDebug,
|
|
endDocumentDebug,
|
|
startElementDebug,
|
|
endElementDebug,
|
|
referenceDebug,
|
|
charactersDebug,
|
|
ignorableWhitespaceDebug,
|
|
processingInstructionDebug,
|
|
commentDebug,
|
|
warningDebug,
|
|
errorDebug,
|
|
fatalErrorDebug,
|
|
getParameterEntityDebug,
|
|
cdataBlockDebug,
|
|
externalSubsetDebug,
|
|
1
|
|
};
|
|
|
|
xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
|
|
|
|
/************************************************************************
|
|
* *
|
|
* Debug *
|
|
* *
|
|
************************************************************************/
|
|
|
|
static void
|
|
parseAndPrintFile(char *filename) {
|
|
int res;
|
|
|
|
if (push) {
|
|
FILE *f;
|
|
|
|
/*
|
|
* Empty callbacks for checking
|
|
*/
|
|
f = fopen(filename, "r");
|
|
if (f != NULL) {
|
|
int ret;
|
|
char chars[10];
|
|
xmlParserCtxtPtr ctxt;
|
|
|
|
ret = fread(chars, 1, 4, f);
|
|
if (ret > 0) {
|
|
ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
|
|
chars, ret, filename);
|
|
while ((ret = fread(chars, 1, 3, f)) > 0) {
|
|
xmlParseChunk(ctxt, chars, ret, 0);
|
|
}
|
|
xmlParseChunk(ctxt, chars, 0, 1);
|
|
xmlFreeParserCtxt(ctxt);
|
|
}
|
|
fclose(f);
|
|
} else {
|
|
xmlGenericError(xmlGenericErrorContext,
|
|
"Cannot read file %s\n", filename);
|
|
}
|
|
/*
|
|
* Debug callback
|
|
*/
|
|
f = fopen(filename, "r");
|
|
if (f != NULL) {
|
|
int ret;
|
|
char chars[10];
|
|
xmlParserCtxtPtr ctxt;
|
|
|
|
ret = fread(chars, 1, 4, f);
|
|
if (ret > 0) {
|
|
ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
|
|
chars, ret, filename);
|
|
while ((ret = fread(chars, 1, 3, f)) > 0) {
|
|
xmlParseChunk(ctxt, chars, ret, 0);
|
|
}
|
|
ret = xmlParseChunk(ctxt, chars, 0, 1);
|
|
xmlFreeParserCtxt(ctxt);
|
|
if (ret != 0) {
|
|
fprintf(stdout,
|
|
"xmlSAXUserParseFile returned error %d\n", ret);
|
|
}
|
|
}
|
|
fclose(f);
|
|
}
|
|
} else {
|
|
if (!speed) {
|
|
/*
|
|
* Empty callbacks for checking
|
|
*/
|
|
res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
|
|
if (res != 0) {
|
|
fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
|
|
}
|
|
|
|
/*
|
|
* Debug callback
|
|
*/
|
|
res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
|
|
if (res != 0) {
|
|
fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
|
|
}
|
|
} else {
|
|
/*
|
|
* test 100x the SAX parse
|
|
*/
|
|
int i;
|
|
|
|
for (i = 0; i<100;i++)
|
|
res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
|
|
if (res != 0) {
|
|
fprintf(stdout, "xmlSAXUserParseFile returned error %d\n", res);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
int i;
|
|
int files = 0;
|
|
|
|
for (i = 1; i < argc ; i++) {
|
|
if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
|
|
debug++;
|
|
else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
|
|
copy++;
|
|
else if ((!strcmp(argv[i], "-recover")) ||
|
|
(!strcmp(argv[i], "--recover")))
|
|
recovery++;
|
|
else if ((!strcmp(argv[i], "-push")) ||
|
|
(!strcmp(argv[i], "--push")))
|
|
push++;
|
|
else if ((!strcmp(argv[i], "-speed")) ||
|
|
(!strcmp(argv[i], "--speed")))
|
|
speed++;
|
|
else if ((!strcmp(argv[i], "-noent")) ||
|
|
(!strcmp(argv[i], "--noent")))
|
|
noent++;
|
|
}
|
|
if (noent != 0) xmlSubstituteEntitiesDefault(1);
|
|
for (i = 1; i < argc ; i++) {
|
|
if (argv[i][0] != '-') {
|
|
parseAndPrintFile(argv[i]);
|
|
files ++;
|
|
}
|
|
}
|
|
xmlCleanupParser();
|
|
xmlMemoryDump();
|
|
|
|
return(0);
|
|
}
|