/*
* parserInternals.c : Internal routines (and obsolete ones) needed for the
* XML and HTML parsers.
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*/
#define IN_LIBXML
#include "libxml.h"
#if defined(WIN32) && !defined (__CYGWIN__)
#else
#endif
#include <string.h>
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_SYS_STAT_H
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
#include <libxml/xmlmemory.h>
#include <libxml/parserInternals.h>
#include <libxml/entities.h>
#include <libxml/xmlerror.h>
#include <libxml/encoding.h>
#ifdef LIBXML_CATALOG_ENABLED
#endif
/*
* Various global defaults for parsing
*/
/**
* xmlCheckVersion:
* @version: the include version number
*
* check the compiled lib version against the include one.
* This can warn or immediately kill the application
*/
void
"Fatal: program compiled against libxml %d using libxml %d\n",
"Fatal: program compiled against libxml %d using libxml %d\n",
}
"Warning: program compiled against libxml %d using older %d\n",
}
}
/************************************************************************
* *
* Some factorized error routines *
* *
************************************************************************/
/**
* xmlErrMemory:
* @ctxt: an XML parser context
* @extra: extra informations
*
* Handle a redefinition of attribute error
*/
void
{
return;
}
if (extra)
"Memory allocation failed : %s\n", extra);
else
}
/**
* __xmlErrEncoding:
* @ctxt: an XML parser context
* @xmlerr: the error number
* @msg: the error message
* @str1: an string info
* @str2: an string info
*
* Handle an encoding error
*/
void
{
return;
ctxt->wellFormed = 0;
}
}
/**
* xmlErrInternal:
* @ctxt: an XML parser context
* @msg: the error message
* @str: error informations
*
* Handle an internal error
*/
static void
{
return;
ctxt->wellFormed = 0;
}
}
/**
* xmlErrEncodingInt:
* @ctxt: an XML parser context
* @error: the error number
* @msg: the error message
* @val: an integer value
*
* n encoding error
*/
static void
{
return;
ctxt->wellFormed = 0;
}
}
/**
* xmlIsLetter:
* @c: an unicode character (int)
*
* Check whether the character is allowed by the production
* [84] Letter ::= BaseChar | Ideographic
*
* Returns 0 if not, non-zero otherwise
*/
int
xmlIsLetter(int c) {
return(IS_BASECHAR(c) || IS_IDEOGRAPHIC(c));
}
/************************************************************************
* *
* Input handling functions for progressive parsing *
* *
************************************************************************/
/* #define DEBUG_INPUT */
/* #define DEBUG_STACK */
/* #define DEBUG_PUSH */
/* we need to keep enough input to show errors in context */
#ifdef DEBUG_INPUT
static
"xmlParserInput: base mismatch problem\n");
}
"xmlParserInput: cur < base problem\n");
}
"xmlParserInput: cur > base + use problem\n");
}
}
#else
#endif
/**
* xmlParserInputRead:
* @in: an XML parser input
* @len: an indicative size for the lookahead
*
* This function refresh the input for the parser. It doesn't try to
* preserve pointers to the input buffer, and discard already read data
*
* Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
* end of this entity
*/
int
int ret;
int used;
int indx;
#ifdef DEBUG_INPUT
#endif
if (ret > 0) {
}
/*
* the buffer has been reallocated
*/
}
return(ret);
}
/**
* xmlParserInputGrow:
* @in: an XML parser input
* @len: an indicative size for the lookahead
*
* This function increase the input for the parser. It tries to
* preserve pointers to the input buffer, and keep already read data
*
* Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
* end of this entity
*/
int
int ret;
int indx;
#ifdef DEBUG_INPUT
#endif
return(0);
}
else
return(0);
/*
* NOTE : in->base may be a "dangling" i.e. freed pointer in this
* block, but we use it really as an integer to do some
* pointer arithmetic. Insure will raise it as a bug but in
* that specific case, that's not !
*/
/*
* the buffer has been reallocated
*/
}
return(ret);
}
/**
* xmlParserInputShrink:
* @in: an XML parser input
*
* This function removes used input for the parser.
*/
void
int used;
int ret;
int indx;
#ifdef DEBUG_INPUT
#endif
/*
* Do not shrink on large buffers whose only a tiny fraction
* was consumed
*/
if (used > INPUT_CHUNK) {
if (ret > 0) {
}
}
return;
}
/*
* the buffer has been reallocated
*/
}
}
/************************************************************************
* *
* UTF8 character input and related functions *
* *
************************************************************************/
/**
* xmlNextChar:
* @ctxt: the XML parser context
*
* Skip to the next char input char.
*/
void
{
return;
/*
* If we are at the end of the current entity and
* the context allows it, we pop consumed entities
* automatically.
* the auto closing should be blocked in other cases
*/
} else {
const unsigned char *cur;
unsigned char c;
/*
* 2.11 End-of-Line Handling
* the literal two-character sequence "#xD#xA" or a standalone
* literal #xD, an XML processor must pass to the application
* the single character #xA.
*/
} else
/*
* We are supposed to handle UTF8, check it's valid
* From rfc2044: encoding of the Unicode values on UTF-8:
*
* UCS-4 range (hex.) UTF-8 octet sequence (binary)
* 0000 0000-0000 007F 0xxxxxxx
* 0000 0080-0000 07FF 110xxxxx 10xxxxxx
* 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
*
* Check for the 0x110000 limit too
*/
c = *cur;
if (c & 0x80) {
if (c == 0xC0)
goto encoding_error;
if (cur[1] == 0)
goto encoding_error;
if ((c & 0xe0) == 0xe0) {
unsigned int val;
if (cur[2] == 0)
goto encoding_error;
if ((c & 0xf0) == 0xf0) {
if (cur[3] == 0)
if (((c & 0xf8) != 0xf0) ||
goto encoding_error;
/* 4-byte code */
} else {
/* 3-byte code */
}
(val >= 0x110000)) {
"Char 0x%X out of allowed range\n",
val);
}
} else
/* 2-byte code */
} else
/* 1-byte code */
}
} else {
/*
* Assume it's a fixed length encoding (1) with
* a compatible encoding for the ASCII set, since
* XML constructs only use < 128 chars
*/
} else
}
return;
/*
* If we detect an UTF8 error that probably mean that the
* input encoding didn't get properly advertised in the
* declaration header. Report the error and switch the encoding
* to ISO-Latin-1 (if you don't like this policy, just declare the
* encoding !)
*/
"Input is not proper UTF-8, indicate encoding !\n",
} else {
"Input is not proper UTF-8, indicate encoding !\n%s",
}
return;
}
/**
* xmlCurrentChar:
* @ctxt: the XML parser context
* @len: pointer to the length of the char read
*
* The current char value, if using UTF-8 this may actually span multiple
* bytes in the input buffer. Implement the end of line normalization:
* 2.11 End-of-Line Handling
* Wherever an external parsed entity or the literal entity value
* of an internal parsed entity contains either the literal two-character
* sequence "#xD#xA" or a standalone literal #xD, an XML processor
* must pass to the application the single character #xA.
* This behavior can conveniently be produced by normalizing all
* line breaks to #xA on input, before parsing.)
*
* Returns the current char value and its length
*/
int
return(0);
*len = 1;
}
/*
* We are supposed to handle UTF8, check it's valid
* From rfc2044: encoding of the Unicode values on UTF-8:
*
* UCS-4 range (hex.) UTF-8 octet sequence (binary)
* 0000 0000-0000 007F 0xxxxxxx
* 0000 0080-0000 07FF 110xxxxx 10xxxxxx
* 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
*
* Check for the 0x110000 limit too
*/
unsigned char c;
unsigned int val;
c = *cur;
if (c & 0x80) {
if (((c & 0x40) == 0) || (c == 0xC0))
goto encoding_error;
if (cur[1] == 0)
goto encoding_error;
if ((c & 0xe0) == 0xe0) {
if (cur[2] == 0)
goto encoding_error;
if ((c & 0xf0) == 0xf0) {
if (cur[3] == 0)
if (((c & 0xf8) != 0xf0) ||
goto encoding_error;
/* 4-byte code */
*len = 4;
if (val < 0x10000)
goto encoding_error;
} else {
/* 3-byte code */
*len = 3;
if (val < 0x800)
goto encoding_error;
}
} else {
/* 2-byte code */
*len = 2;
if (val < 0x80)
goto encoding_error;
}
"Char 0x%X out of allowed range\n", val);
}
return(val);
} else {
/* 1-byte code */
*len = 1;
"Char 0x0 out of allowed range\n", 0);
}
}
return(0xA);
}
}
}
/*
* Assume it's a fixed length encoding (1) with
* a compatible encoding for the ASCII set, since
* XML constructs only use < 128 chars
*/
*len = 1;
}
return(0xA);
}
/*
* An encoding problem may arise from a truncated input buffer
* splitting a character in the middle. In that case do not raise
* an error but return 0 to endicate an end of stream problem
*/
*len = 0;
return(0);
}
/*
* If we detect an UTF8 error that probably mean that the
* input encoding didn't get properly advertised in the
* declaration header. Report the error and switch the encoding
* to ISO-Latin-1 (if you don't like this policy, just declare the
* encoding !)
*/
{
"Input is not proper UTF-8, indicate encoding !\n%s",
}
*len = 1;
}
/**
* xmlStringCurrentChar:
* @ctxt: the XML parser context
* @cur: pointer to the beginning of the char
* @len: pointer to the length of the char read
*
* The current char value, if using UTF-8 this may actually span multiple
* bytes in the input buffer.
*
* Returns the current char value and its length
*/
int
{
/*
* We are supposed to handle UTF8, check it's valid
* From rfc2044: encoding of the Unicode values on UTF-8:
*
* UCS-4 range (hex.) UTF-8 octet sequence (binary)
* 0000 0000-0000 007F 0xxxxxxx
* 0000 0080-0000 07FF 110xxxxx 10xxxxxx
* 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
*
* Check for the 0x110000 limit too
*/
unsigned char c;
unsigned int val;
c = *cur;
if (c & 0x80) {
goto encoding_error;
if ((c & 0xe0) == 0xe0) {
goto encoding_error;
if ((c & 0xf0) == 0xf0) {
goto encoding_error;
/* 4-byte code */
*len = 4;
} else {
/* 3-byte code */
*len = 3;
}
} else {
/* 2-byte code */
*len = 2;
}
"Char 0x%X out of allowed range\n", val);
}
return (val);
} else {
/* 1-byte code */
*len = 1;
return ((int) *cur);
}
}
/*
* Assume it's a fixed length encoding (1) with
* a compatible encoding for the ASCII set, since
* XML constructs only use < 128 chars
*/
*len = 1;
return ((int) *cur);
/*
* An encoding problem may arise from a truncated input buffer
* splitting a character in the middle. In that case do not raise
* an error but return 0 to endicate an end of stream problem
*/
*len = 0;
return(0);
}
/*
* If we detect an UTF8 error that probably mean that the
* input encoding didn't get properly advertised in the
* declaration header. Report the error and switch the encoding
* to ISO-Latin-1 (if you don't like this policy, just declare the
* encoding !)
*/
{
"Input is not proper UTF-8, indicate encoding !\n%s",
}
*len = 1;
return ((int) *cur);
}
/**
* xmlCopyCharMultiByte:
* @out: pointer to an array of xmlChar
* @val: the char value
*
* append the char value in the array
*
* Returns the number of xmlChar written
*/
int
/*
* We are supposed to handle UTF8, check it's valid
* From rfc2044: encoding of the Unicode values on UTF-8:
*
* UCS-4 range (hex.) UTF-8 octet sequence (binary)
* 0000 0000-0000 007F 0xxxxxxx
* 0000 0080-0000 07FF 110xxxxx 10xxxxxx
* 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
*/
if (val >= 0x80) {
int bits;
else {
"Internal error, xmlCopyCharMultiByte 0x%X out of bound\n",
val);
return(0);
}
}
return 1;
}
/**
* xmlCopyChar:
* @len: Ignored, compatibility
* @out: pointer to an array of xmlChar
* @val: the char value
*
* append the char value in the array
*
* Returns the number of xmlChar written
*/
int
/* the len parameter is ignored */
if (val >= 0x80) {
}
return 1;
}
/************************************************************************
* *
* Commodity functions to switch encodings *
* *
************************************************************************/
/**
* xmlSwitchEncoding:
* @ctxt: the parser context
* @enc: the encoding value (number)
*
* change the input functions when discovering the character encoding
* of a given entity.
*
* Returns 0 in case of success, -1 otherwise
*/
int
{
switch (enc) {
case XML_CHAR_ENCODING_ERROR:
return(-1);
case XML_CHAR_ENCODING_NONE:
/* let's assume it's UTF-8 without the XML decl */
return(0);
case XML_CHAR_ENCODING_UTF8:
/* default encoding, no conversion should be needed */
/*
* Errata on XML-1.0 June 20 2001
* Specific handling of the Byte Order Mark for
* UTF-8
*/
}
return(0);
/*The raw input characters are encoded
*in UTF-16. As we expect this function
*to be called after xmlCharEncInFunc, we expect
*ctxt->input->cur to contain UTF-8 encoded characters.
*So the raw UTF16 Byte Order Mark
*has also been converted into
*an UTF-8 BOM. Let's skip that BOM.
*/
}
break ;
default:
break;
}
/*
* Default handlers.
*/
switch (enc) {
case XML_CHAR_ENCODING_ASCII:
/* default encoding, no conversion should be needed */
return(0);
break;
break;
case XML_CHAR_ENCODING_UCS4LE:
"encoding not supported %s\n",
break;
case XML_CHAR_ENCODING_UCS4BE:
"encoding not supported %s\n",
break;
case XML_CHAR_ENCODING_EBCDIC:
"encoding not supported %s\n",
break;
"encoding not supported %s\n",
break;
"encoding not supported %s\n",
break;
case XML_CHAR_ENCODING_UCS2:
"encoding not supported %s\n",
break;
case XML_CHAR_ENCODING_8859_1:
case XML_CHAR_ENCODING_8859_2:
case XML_CHAR_ENCODING_8859_3:
case XML_CHAR_ENCODING_8859_4:
case XML_CHAR_ENCODING_8859_5:
case XML_CHAR_ENCODING_8859_6:
case XML_CHAR_ENCODING_8859_7:
case XML_CHAR_ENCODING_8859_8:
case XML_CHAR_ENCODING_8859_9:
/*
* We used to keep the internal content in the
* document encoding however this turns being unmaintainable
* So xmlGetCharEncodingHandler() will return non-null
* values for this now.
*/
}
return(0);
"encoding not supported %s\n",
break;
"encoding not supported %s\n",
break;
case XML_CHAR_ENCODING_EUC_JP:
"encoding not supported %s\n",
break;
default:
break;
}
}
return(-1);
}
/**
* xmlSwitchInputEncoding:
* @ctxt: the parser context
* @input: the input stream
* @handler: the encoding handler
*
* change the input functions when discovering the character encoding
* of a given entity.
*
* Returns 0 in case of success, -1 otherwise
*/
int
{
int nbchars;
return (-1);
return (-1);
/*
* Check in case the auto encoding detetection triggered
* in already.
*/
return (0);
/*
* "UTF-16" can be used for both LE and BE
if ((!xmlStrncmp(BAD_CAST input->buf->encoder->name,
BAD_CAST "UTF-16", 6)) &&
(!xmlStrncmp(BAD_CAST handler->name,
BAD_CAST "UTF-16", 6))) {
return(0);
}
*/
/*
* Note: this is a bit dangerous, but that's what it
* takes to use nearly compatible signature for different
* encodings.
*/
return (0);
}
/*
* Is there already some content down the pipe to convert ?
*/
int processed;
unsigned int use;
/*
* Specific handling of the Byte Order Mark for
* UTF-16
*/
}
}
/*
* Errata on XML-1.0 June 20 2001
* Specific handling of the Byte Order Mark for
* UTF-8
*/
}
/*
* Shrink the current input buffer.
* Move it as the raw buffer and create a new input buffer
*/
/*
* convert as much as possible of the buffer
*/
} else {
/*
* convert just enough to get
* '<?xml version="1.0" encoding="xxx"?>'
* parsed with the autodetected encoding
* into the parser reading buffer.
*/
}
if (nbchars < 0) {
"switching encoding: encoder error\n",
NULL);
return (-1);
}
}
return (0);
/*
* When parsing a static memory array one must know the
* size to be able to convert the buffer.
*/
return (-1);
}
return (0);
}
/**
* xmlSwitchToEncoding:
* @ctxt: the parser context
* @handler: the encoding handler
*
* change the input functions when discovering the character encoding
* of a given entity.
*
* Returns 0 in case of success, -1 otherwise
*/
int
{
int ret = 0;
} else {
NULL);
return(-1);
}
/*
* The parsing is now done in UTF8 natively
*/
} else
return(-1);
return(ret);
}
/************************************************************************
* *
* Commodity functions to handle entities processing *
* *
************************************************************************/
/**
* xmlFreeInputStream:
* @input: an xmlParserInputPtr
*
* Free up an input stream.
*/
void
}
/**
* xmlNewInputStream:
* @ctxt: an XML parser context
*
* Create a new input stream structure
* Returns the new input stream or NULL
*/
static int id = 0;
return(NULL);
}
/*
* we don't care about thread reentrancy unicity for a single
* parser context (and hence thread) is sufficient.
*/
return(input);
}
/**
* xmlNewIOInputStream:
* @ctxt: an XML parser context
* @input: an I/O Input
* @enc: the charset encoding if known
*
* Create a new input stream structure encapsulating the @input into
* a stream suitable for the parser.
*
* Returns the new input stream or NULL
*/
if (inputStream == NULL) {
return(NULL);
}
if (enc != XML_CHAR_ENCODING_NONE) {
}
return(inputStream);
}
/**
* xmlNewEntityInputStream:
* @ctxt: an XML parser context
* @entity: an Entity pointer
*
* Create a new input stream based on an xmlEntityPtr
*
* Returns the new input stream or NULL
*/
NULL);
return(NULL);
}
break;
"Internal entity %s without content !\n",
break;
"Internal parameter entity %s without content !\n",
break;
"Predefined entity %s without content !\n",
break;
}
return(NULL);
}
return(NULL);
}
return(input);
}
/**
* xmlNewStringInputStream:
* @ctxt: an XML parser context
* @buffer: an memory buffer
*
* Create a new input stream based on a memory buffer.
* Returns the new input stream
*/
NULL);
return(NULL);
}
"new fixed input: %.30s\n", buffer);
return(NULL);
}
return(input);
}
/**
* xmlNewInputFromFile:
* @ctxt: an XML parser context
* @filename: the filename to use as entity
*
* Create a new input stream based on a file or an URL.
*
* Returns the new input stream or NULL in case of error
*/
"new input from file: %s\n", filename);
"failed to load external entity: NULL filename \n",
NULL);
else
(const char *) filename);
return(NULL);
}
if (inputStream == NULL)
return(NULL);
if (inputStream == NULL)
return(NULL);
else
return(inputStream);
}
/************************************************************************
* *
* Commodity functions to handle parser contexts *
* *
************************************************************************/
/**
* xmlInitParserCtxt:
* @ctxt: an XML parser context
*
* Initialize a parser context
*
* Returns 0 in case of success and -1 in case of error
*/
int
{
return(-1);
}
return(-1);
}
return(-1);
}
else
/* Allocate the Input stack */
}
return(-1);
}
}
ctxt->hasExternalSubset = 0;
/* Allocate the Node stack */
}
return(-1);
}
/* Allocate the Name stack */
}
return(-1);
}
/* Allocate the space stack */
}
return(-1);
}
if (ctxt->keepBlanks == 0)
if (xmlGetWarningsDefaultValue == 0)
else
}
ctxt->record_info = 0;
ctxt->checkIndex = 0;
ctxt->nbentities = 0;
ctxt->sizeentities = 0;
ctxt->sizeentcopy = 0;
return(0);
}
/**
* xmlFreeParserCtxt:
* @ctxt: an XML parser context
*
* Free all the memory used by a parser context. However the parsed
* document in ctxt->myDoc is not freed.
*/
void
{
}
#ifdef LIBXML_SAX1_ENABLED
#else
#endif /* LIBXML_SAX1_ENABLED */
}
}
}
}
/*
* cleanup the error strings
*/
#ifdef LIBXML_CATALOG_ENABLED
#endif
}
/**
* xmlNewParserCtxt:
*
* Allocate and initialize a new parser context.
*
* Returns the xmlParserCtxtPtr or NULL
*/
xmlNewParserCtxt(void)
{
return(NULL);
}
if (xmlInitParserCtxt(ctxt) < 0) {
return(NULL);
}
return(ctxt);
}
/************************************************************************
* *
* Handling of node informations *
* *
************************************************************************/
/**
* xmlClearParserCtxt:
* @ctxt: an XML parser context
*
* Clear (release owned resources) and reinitialize a parser context
*/
void
{
return;
}
/**
* xmlParserFindNodeInfo:
* @ctx: an XML parser context
* @node: an XML node within the tree
*
* Find the parser node info struct for a given node
*
* Returns an xmlParserNodeInfo block pointer or NULL
*/
const xmlParserNodeInfo *
{
unsigned long pos;
return (NULL);
/* Find position where node should be at */
else
return NULL;
}
/**
* xmlInitNodeInfoSeq:
* @seq: a node info sequence pointer
*
* -- Initialize (set to initial state) node info sequence
*/
void
{
return;
}
/**
* xmlClearNodeInfoSeq:
* @seq: a node info sequence pointer
*
* -- Clear (release memory and reinitialize) node
* info sequence
*/
void
{
return;
}
/**
* xmlParserFindNodeInfoIndex:
* @seq: a node info sequence pointer
* @node: an XML node pointer
*
*
* xmlParserFindNodeInfoIndex : Find the index that the info record for
* the given node is or should be at in a sorted sequence
*
* Returns a long indicating the position of the record
*/
unsigned long
const xmlNodePtr node)
{
int found = 0;
return ((unsigned long) -1);
/* Do a binary search for the key */
lower = 1;
middle = 0;
found = 1;
else
}
/* Return position */
return middle;
else
return middle - 1;
}
/**
* xmlParserAddNodeInfo:
* @ctxt: an XML parser context
* @info: a node info sequence pointer
*
* Insert node info record into the sorted sequence
*/
void
const xmlParserNodeInfoPtr info)
{
unsigned long pos;
/* Find pos and check to see if node is already in the sequence */
}
/* Otherwise, we need to add new node to buffer */
else {
unsigned int byte_size;
else
if (tmp_buffer == NULL) {
return;
}
}
/* If position is not at end, move elements out of the way */
unsigned long i;
}
/* Copy element and increase length */
}
}
/************************************************************************
* *
* Defaults settings *
* *
************************************************************************/
/**
* xmlPedanticParserDefault:
* @val: int 0 or 1
*
* Set and return the previous value for enabling pedantic warnings.
*
* Returns the last value for 0 for no substitution, 1 for substitution.
*/
int
return(old);
}
/**
* xmlLineNumbersDefault:
* @val: int 0 or 1
*
* Set and return the previous value for enabling line numbers in elements
* contents. This may break on old application and is turned off by default.
*
* Returns the last value for 0 for no substitution, 1 for substitution.
*/
int
return(old);
}
/**
* xmlSubstituteEntitiesDefault:
* @val: int 0 or 1
*
* Set and return the previous value for default entity support.
* Initially the parser always keep entity references instead of substituting
* entity values in the output. This function has to be used to change the
* default parser behavior
* SAX::substituteEntities() has to be used for changing that on a file by
* file basis.
*
* Returns the last value for 0 for no substitution, 1 for substitution.
*/
int
return(old);
}
/**
* xmlKeepBlanksDefault:
* @val: int 0 or 1
*
* Set and return the previous value for default blanks text nodes support.
* The 1.x version of the parser used an heuristic to try to detect
* ignorable white spaces. As a result the SAX callback was generating
* xmlSAX2IgnorableWhitespace() callbacks instead of characters() one, and when
* using the DOM output text nodes containing those blanks were not generated.
* The 2.x and later version will switch to the XML standard way and
* ignorableWhitespace() are only generated when running the parser in
* validating mode and when the current element doesn't allow CDATA or
* mixed content.
* This function is provided as a way to force the standard behavior
* on 1.X libs and to switch back to the old mode for compatibility when
* running 1.X client code on 2.X . Upgrade of 1.X code should be done
* by using xmlIsBlankNode() commodity function to detect the "empty"
* nodes generated.
* This value also affect autogeneration of indentation when saving code
* if blanks sections are kept, indentation is not generated.
*
* Returns the last value for 0 for no substitution, 1 for substitution.
*/
int
return(old);
}
#define bottom_parserInternals
#include "elfgcchack.h"