xml/libxml2libs/src/libxml2/libxml2_sax2.c
changeset 0 e35f40988205
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 /*
       
     2  * libxml2_sax2.c : Default SAX2 handler to build a tree.
       
     3  *
       
     4  * See Copyright for the status of this software.
       
     5  *
       
     6  * Daniel Veillard <daniel@veillard.com>
       
     7  * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
       
     8  */
       
     9 
       
    10 #define IN_LIBXML
       
    11 
       
    12 #include "xmlenglibxml.h"
       
    13 
       
    14 #include <stdlib.h>
       
    15 #include <string.h>
       
    16 #include <stdapis/libxml2/libxml2_parserinternals.h>
       
    17 #include "libxml2_xmlerror2.h"
       
    18 
       
    19 #ifdef LIBXML_DEBUG_ENABLED
       
    20 #include "libxml2_debugxml.h"
       
    21 #endif
       
    22 
       
    23 #include <stdapis/libxml2/libxml2_uri.h>
       
    24 #include <stdapis/libxml2/libxml2_globals.h>
       
    25 
       
    26 #ifdef LIBXML_HTML_ENABLED
       
    27 #include "libxml2_htmltree.h"
       
    28 #endif
       
    29 
       
    30 /* #define DEBUG_SAX2 */
       
    31 /* #define DEBUG_SAX2_TREE */
       
    32 
       
    33 /**
       
    34  * 
       
    35  *
       
    36  * macro to flag unimplemented blocks
       
    37  * XML_CATALOG_PREFER user env to select between system/public prefered
       
    38  * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
       
    39  *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
       
    40  *> values "system" and "public".  I have made the default be "system" to
       
    41  *> match yours.
       
    42  */
       
    43 #define _TODO_                              \
       
    44     xmlGenericError(xmlGenericErrorContext,             \
       
    45         EMBED_ERRTXT("Unimplemented block at %s:%d\n"),             \
       
    46             __FILE__, __LINE__);
       
    47 
       
    48 /**
       
    49  * xmlValidError:
       
    50  * @param ctxt an XML validation parser context
       
    51  * @param error the error number
       
    52  * @param msg the error message
       
    53  * @param str1 extra data
       
    54  * @param str2 extra data
       
    55  *
       
    56  * Handle a validation error
       
    57  */
       
    58 static void
       
    59 xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
       
    60             const char *msg, const char *str1, const char *str2)
       
    61 {
       
    62     xmlStructuredErrorFunc schannel = NULL;
       
    63 
       
    64     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
       
    65         (ctxt->instate == XML_PARSER_EOF))
       
    66     return;
       
    67     ctxt->errNo = error;
       
    68     if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
       
    69         schannel = ctxt->sax->serror;
       
    70     __xmlRaiseError(schannel,
       
    71                     ctxt->vctxt.error, ctxt->vctxt.userData,
       
    72                     ctxt, NULL, XML_FROM_DTD, error,
       
    73                     XML_ERR_ERROR, NULL, 0, (const char *) str1,
       
    74             (const char *) str2, NULL, 0, 0,
       
    75             msg, (const char *) str1, (const char *) str2);
       
    76     ctxt->valid = 0;
       
    77 }
       
    78 
       
    79 /**
       
    80  * xmlSAX2GetPublicId:
       
    81  * @param ctx the user data (XML parser context)
       
    82  *
       
    83  * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
       
    84  *
       
    85  * Returns a xmlChar *
       
    86  */
       
    87 XMLPUBFUNEXPORT const xmlChar *
       
    88 xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED)
       
    89 {
       
    90     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
       
    91     if(ctx)
       
    92         return NULL; // just to use ctx
       
    93     return(NULL);
       
    94 }
       
    95 
       
    96 /**
       
    97  * xmlSAX2GetSystemId:
       
    98  * @param ctx the user data (XML parser context)
       
    99  *
       
   100  * Provides the system ID, basically URL or filename e.g.
       
   101  * http://www.sgmlsource.com/dtds/memo.dtd
       
   102  *
       
   103  * Returns a xmlChar *
       
   104  */
       
   105 XMLPUBFUNEXPORT const xmlChar *
       
   106 xmlSAX2GetSystemId(void *ctx)
       
   107 {
       
   108     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   109     return((const xmlChar *) ctxt->input->filename);
       
   110 }
       
   111 
       
   112 /**
       
   113  * xmlSAX2GetLineNumber:
       
   114  * @param ctx the user data (XML parser context)
       
   115  *
       
   116  * Provide the line number of the current parsing point.
       
   117  *
       
   118  * Returns an int
       
   119  */
       
   120 XMLPUBFUNEXPORT int
       
   121 xmlSAX2GetLineNumber(void *ctx)
       
   122 {
       
   123     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   124     return(ctxt->input->line);
       
   125 }
       
   126 
       
   127 /**
       
   128  * xmlSAX2GetColumnNumber:
       
   129  * @param ctx the user data (XML parser context)
       
   130  *
       
   131  * Provide the column number of the current parsing point.
       
   132  *
       
   133  * Returns an int
       
   134  */
       
   135 XMLPUBFUNEXPORT int
       
   136 xmlSAX2GetColumnNumber(void *ctx)
       
   137 {
       
   138     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   139     return(ctxt->input->col);
       
   140 }
       
   141 
       
   142 /**
       
   143  * xmlSAX2IsStandalone:
       
   144  * @param ctx the user data (XML parser context)
       
   145  *
       
   146  * Is this document tagged standalone ?
       
   147  *
       
   148  * Returns 1 if true
       
   149  */
       
   150 XMLPUBFUNEXPORT int
       
   151 xmlSAX2IsStandalone(void *ctx)
       
   152 {
       
   153     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   154     return(ctxt->myDoc->standalone == 1);
       
   155 }
       
   156 
       
   157 /**
       
   158  * xmlSAX2HasInternalSubset:
       
   159  * @param ctx the user data (XML parser context)
       
   160  *
       
   161  * Does this document has an internal subset
       
   162  *
       
   163  * Returns 1 if true
       
   164  */
       
   165 XMLPUBFUNEXPORT int
       
   166 xmlSAX2HasInternalSubset(void *ctx)
       
   167 {
       
   168     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   169     return(ctxt->myDoc->intSubset != NULL);
       
   170 }
       
   171 
       
   172 /**
       
   173  * xmlSAX2HasExternalSubset:
       
   174  * @param ctx the user data (XML parser context)
       
   175  *
       
   176  * Does this document has an external subset
       
   177  *
       
   178  * Returns 1 if true
       
   179  */
       
   180 XMLPUBFUNEXPORT int
       
   181 xmlSAX2HasExternalSubset(void *ctx)
       
   182 {
       
   183     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   184     return(ctxt->myDoc->extSubset != NULL);
       
   185 }
       
   186 
       
   187 /**
       
   188  * xmlSAX2InternalSubset:
       
   189  * @param ctx the user data (XML parser context)
       
   190  * @param name the root element name
       
   191  * @param ExternalID the external ID
       
   192  * @param SystemID the SYSTEM ID (e.g. filename or URL)
       
   193  *
       
   194  * Callback on internal subset declaration.
       
   195  */
       
   196 XMLPUBFUNEXPORT void
       
   197 xmlSAX2InternalSubset(void *ctx, const xmlChar *name,
       
   198            const xmlChar *ExternalID, const xmlChar *SystemID)
       
   199 {
       
   200     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   201     xmlDtdPtr dtd;
       
   202 #ifdef DEBUG_SAX
       
   203     xmlGenericError(xmlGenericErrorContext,
       
   204         "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
       
   205             name, ExternalID, SystemID);
       
   206 #endif
       
   207 
       
   208     if (ctxt->myDoc == NULL)
       
   209         return;
       
   210     dtd = xmlGetIntSubset(ctxt->myDoc);
       
   211     if (dtd != NULL) {
       
   212         if (ctxt->html)
       
   213             return;
       
   214         xmlUnlinkNode((xmlNodePtr) dtd);
       
   215         xmlFreeDtd(dtd);
       
   216         ctxt->myDoc->intSubset = NULL;
       
   217     }
       
   218     ctxt->myDoc->intSubset = xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
       
   219 }
       
   220 
       
   221 /**
       
   222  * xmlSAX2ExternalSubset:
       
   223  * @param ctx the user data (XML parser context)
       
   224  * @param name the root element name
       
   225  * @param ExternalID the external ID
       
   226  * @param SystemID the SYSTEM ID (e.g. filename or URL)
       
   227  *
       
   228  * Callback on external subset declaration.
       
   229  */
       
   230 XMLPUBFUNEXPORT void
       
   231 xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
       
   232            const xmlChar *ExternalID, const xmlChar *SystemID)
       
   233 {
       
   234     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   235 #ifdef DEBUG_SAX
       
   236     xmlGenericError(xmlGenericErrorContext,
       
   237         "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
       
   238             name, ExternalID, SystemID);
       
   239 #endif
       
   240     if (((ExternalID != NULL) || (SystemID != NULL)) &&
       
   241         (((ctxt->validate) || (ctxt->loadsubset != 0)) &&
       
   242      (ctxt->wellFormed && ctxt->myDoc))) {
       
   243     /*
       
   244      * Try to fetch and parse the external subset.
       
   245      */
       
   246     xmlParserInputPtr oldinput;
       
   247     int oldinputNr;
       
   248     int oldinputMax;
       
   249     xmlParserInputPtr *oldinputTab;
       
   250     xmlParserInputPtr input = NULL;
       
   251     xmlCharEncoding enc;
       
   252     int oldcharset;
       
   253 
       
   254     /*
       
   255      * Ask the Entity resolver to load the damn thing
       
   256      */
       
   257     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
       
   258         input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
       
   259                                             SystemID);
       
   260     if (input == NULL) {
       
   261         return;
       
   262     }
       
   263 
       
   264     xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
       
   265 
       
   266     /*
       
   267      * make sure we won't destroy the main document context
       
   268      */
       
   269      
       
   270     oldinput = ctxt->input;
       
   271     oldinputNr = ctxt->inputNr;
       
   272     oldinputMax = ctxt->inputMax;
       
   273     oldinputTab = ctxt->inputTab;
       
   274     oldcharset = ctxt->charset;
       
   275 
       
   276     ctxt->inputTab = (xmlParserInputPtr *)
       
   277                      xmlMalloc(5 * sizeof(xmlParserInputPtr));
       
   278     if (ctxt->inputTab == NULL) {
       
   279         ctxt->errNo = XML_ERR_NO_MEMORY;
       
   280         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
   281         ctxt->sax->error(ctxt->userData,
       
   282              EMBED_ERRTXT("xmlSAX2ExternalSubset: out of memory\n"));
       
   283         ctxt->errNo = XML_ERR_NO_MEMORY;
       
   284         ctxt->instate = XML_PARSER_EOF;
       
   285         ctxt->disableSAX = 1;
       
   286         ctxt->input = oldinput;
       
   287         ctxt->inputNr = oldinputNr;
       
   288         ctxt->inputMax = oldinputMax;
       
   289         ctxt->inputTab = oldinputTab;
       
   290         ctxt->charset = oldcharset;
       
   291         return;
       
   292     }
       
   293     ctxt->inputNr = 0;
       
   294     ctxt->inputMax = 5;
       
   295     ctxt->input = NULL;
       
   296     xmlPushInput(ctxt, input);
       
   297 
       
   298     /*
       
   299      * On the fly encoding conversion if needed
       
   300      */
       
   301     if (ctxt->input->length >= 4) {
       
   302         enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
       
   303         xmlSwitchEncoding(ctxt, enc);
       
   304     }
       
   305 
       
   306     if (input->filename == NULL)
       
   307         input->filename = (char *) xmlCanonicPath(SystemID);
       
   308     input->line = 1;
       
   309     input->col = 1;
       
   310     input->base = ctxt->input->cur;
       
   311     input->cur = ctxt->input->cur;
       
   312     input->free = NULL;
       
   313 
       
   314     /*
       
   315      * let's parse that entity knowing it's an external subset.
       
   316      */
       
   317     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
       
   318 
       
   319     /*
       
   320      * Free up the external entities
       
   321      */
       
   322 
       
   323     while (ctxt->inputNr > 1)
       
   324         xmlPopInput(ctxt);
       
   325     xmlFreeInputStream(ctxt->input);
       
   326     xmlFree(ctxt->inputTab);
       
   327 
       
   328     /*
       
   329      * Restore the parsing context of the main entity
       
   330      */
       
   331     ctxt->input = oldinput;
       
   332     ctxt->inputNr = oldinputNr;
       
   333     ctxt->inputMax = oldinputMax;
       
   334     ctxt->inputTab = oldinputTab;
       
   335     ctxt->charset = oldcharset;
       
   336     /* ctxt->wellFormed = oldwellFormed; */
       
   337     }
       
   338 }
       
   339 
       
   340 /**
       
   341  * xmlSAX2ResolveEntity:
       
   342  * @param ctx the user data (XML parser context)
       
   343  * @param publicId The public ID of the entity
       
   344  * @param systemId The system ID of the entity
       
   345  *
       
   346  * The entity loader, to control the loading of external entities,
       
   347  * the application can either:
       
   348  *    - override this xmlSAX2ResolveEntity() callback in the SAX block
       
   349  *    - or better use the xmlSetExternalEntityLoader() function to
       
   350  *      set up it's own entity resolution routine
       
   351  *
       
   352  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
       
   353  */
       
   354 XMLPUBFUNEXPORT xmlParserInputPtr
       
   355 xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
       
   356 {
       
   357     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   358     xmlParserInputPtr ret;
       
   359     xmlChar*     URI;
       
   360     const char*  base = NULL;
       
   361 
       
   362     if (ctxt->input)
       
   363         base = ctxt->input->filename;
       
   364     if (!base)
       
   365         base = ctxt->directory;
       
   366 
       
   367     URI = xmlBuildURI(systemId, (const xmlChar *) base);
       
   368 
       
   369 #ifdef DEBUG_SAX
       
   370     xmlGenericError(xmlGenericErrorContext,
       
   371         "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId);
       
   372 #endif
       
   373 
       
   374     ret = xmlLoadExternalEntity((const char *) URI,
       
   375                 (const char *) publicId, ctxt);
       
   376     if (URI)
       
   377         xmlFree(URI);
       
   378     return(ret);
       
   379 }
       
   380 
       
   381 /**
       
   382  * xmlSAX2GetEntity:
       
   383  * @param ctx the user data (XML parser context)
       
   384  * @param name The entity name
       
   385  *
       
   386  * Get an entity by name
       
   387  *
       
   388  * Returns the xmlEntityPtr if found.
       
   389  */
       
   390 XMLPUBFUNEXPORT xmlEntityPtr
       
   391 xmlSAX2GetEntity(void *ctx, const xmlChar *name)
       
   392 {
       
   393     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   394     xmlEntityPtr ret = NULL;
       
   395 
       
   396 #ifdef DEBUG_SAX
       
   397     xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2GetEntity(%s)\n", name);
       
   398 #endif
       
   399 
       
   400     if (ctxt->inSubset == 0) {
       
   401         ret = xmlGetPredefinedEntity(name);
       
   402         if (ret != NULL)
       
   403             return(ret);
       
   404     }
       
   405     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1))
       
   406     {
       
   407         if (ctxt->inSubset == 2) {
       
   408             ctxt->myDoc->standalone = 0;
       
   409             ret = xmlGetDocEntity(ctxt->myDoc, name);
       
   410             ctxt->myDoc->standalone = 1;
       
   411         } else {
       
   412             ret = xmlGetDocEntity(ctxt->myDoc, name);
       
   413             if (ret == NULL) {
       
   414                 ctxt->myDoc->standalone = 0;
       
   415                 ret = xmlGetDocEntity(ctxt->myDoc, name);
       
   416                 if (ret != NULL) {
       
   417                     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
   418                         ctxt->sax->error(ctxt->userData,
       
   419                                      EMBED_ERRTXT("Entity(%s) document marked standalone but requires external subset\n"),
       
   420                                      name);
       
   421                     ctxt->valid = 0;
       
   422                     ctxt->wellFormed = 0;
       
   423                 }
       
   424                 ctxt->myDoc->standalone = 1;
       
   425             }
       
   426         }
       
   427     } else {
       
   428         ret = xmlGetDocEntity(ctxt->myDoc, name);
       
   429     }
       
   430     if (ret &&
       
   431         ((ctxt->validate) || (ctxt->replaceEntities)) &&
       
   432         !ret->children &&
       
   433         (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))
       
   434     {
       
   435         int val;
       
   436 
       
   437     /*
       
   438      * for validation purposes we really need to fetch and
       
   439      * parse the external entity
       
   440      */
       
   441     xmlNodePtr children;
       
   442 
       
   443         val = xmlParseCtxtExternalEntity(ctxt, ret->URI, ret->ExternalID, &children);
       
   444 
       
   445         if (val == 0) {
       
   446             xmlAddChildList((xmlNodePtr) ret, children);
       
   447         } else {
       
   448             if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
   449                 ctxt->sax->error(ctxt->userData,
       
   450                                  EMBED_ERRTXT("Failure to process entity %s\n"), name);
       
   451             ctxt->wellFormed = 0;
       
   452             ctxt->valid = 0;
       
   453             ctxt->validate = 0;
       
   454             return(NULL);
       
   455         }
       
   456         ret->owner = 1;
       
   457     }
       
   458     return(ret);
       
   459 }
       
   460 
       
   461 /**
       
   462  * xmlSAX2GetParameterEntity:
       
   463  * @param ctx the user data (XML parser context)
       
   464  * @param name The entity name
       
   465  *
       
   466  * Get a parameter entity by name
       
   467  *
       
   468  * Returns the xmlEntityPtr if found.
       
   469  */
       
   470 XMLPUBFUNEXPORT xmlEntityPtr
       
   471 xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
       
   472 {
       
   473     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   474     xmlEntityPtr ret;
       
   475 
       
   476 #ifdef DEBUG_SAX
       
   477     xmlGenericError(xmlGenericErrorContext,
       
   478         "SAX.xmlSAX2GetParameterEntity(%s)\n", name);
       
   479 #endif
       
   480 
       
   481     ret = xmlGetParameterEntity(ctxt->myDoc, name);
       
   482     return(ret);
       
   483 }
       
   484 
       
   485 
       
   486 /**
       
   487  * xmlSAX2EntityDecl:
       
   488  * @param ctx the user data (XML parser context)
       
   489  * @param name the entity name
       
   490  * @param type the entity type
       
   491  * @param publicId The public ID of the entity
       
   492  * @param systemId The system ID of the entity
       
   493  * @param content the entity value (without processing).
       
   494  *
       
   495  * An entity definition has been parsed
       
   496  */
       
   497 XMLPUBFUNEXPORT void
       
   498 xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
       
   499           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
       
   500 {
       
   501     xmlEntityPtr ent;
       
   502     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   503 
       
   504 #ifdef DEBUG_SAX
       
   505     xmlGenericError(xmlGenericErrorContext,
       
   506         "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
       
   507             name, type, publicId, systemId, content);
       
   508 #endif
       
   509     if (ctxt->inSubset == 1)
       
   510     {
       
   511         ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
       
   512                           systemId, content);
       
   513         if (!ent &&
       
   514             ctxt->pedantic &&
       
   515             ctxt->sax && ctxt->sax->warning)
       
   516         {
       
   517             ctxt->sax->warning(ctxt->userData,
       
   518                                 EMBED_ERRTXT("Entity(%s) already defined in the internal subset\n"), name);
       
   519         }
       
   520         if (ent && !ent->URI && systemId)
       
   521         {
       
   522             xmlChar *URI;
       
   523             const char *base = NULL;
       
   524 
       
   525             if (ctxt->input)
       
   526                 base = ctxt->input->filename;
       
   527             if (!base)
       
   528                 base = ctxt->directory;
       
   529 
       
   530             URI = xmlBuildURI(systemId, (const xmlChar *) base);
       
   531             ent->URI = URI;
       
   532         }
       
   533     }
       
   534     else if (ctxt->inSubset == 2)
       
   535     {
       
   536         ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
       
   537                               systemId, content);
       
   538         if (!ent &&
       
   539             ctxt->pedantic &&
       
   540             ctxt->sax &&
       
   541             ctxt->sax->warning)
       
   542         {
       
   543             ctxt->sax->warning(ctxt->userData,
       
   544                                 EMBED_ERRTXT("Entity(%s) already defined in the external subset\n"), name);
       
   545         }
       
   546         if (ent && !ent->URI && systemId)
       
   547         {
       
   548             xmlChar *URI;
       
   549             const char* base = NULL;
       
   550 
       
   551             if (ctxt->input != NULL)
       
   552                 base = ctxt->input->filename;
       
   553             if (!base)
       
   554                 base = ctxt->directory;
       
   555 
       
   556             URI = xmlBuildURI(systemId, (const xmlChar*) base);
       
   557             ent->URI = URI;
       
   558         }
       
   559     }
       
   560     else if (ctxt->sax && ctxt->sax->error)
       
   561     {
       
   562         ctxt->sax->error(ctxt->userData,
       
   563              EMBED_ERRTXT("SAX.xmlSAX2EntityDecl(%s) called while not in subset\n"),
       
   564              name);
       
   565     }
       
   566 }
       
   567 
       
   568 /**
       
   569  * xmlSAX2AttributeDecl:
       
   570  * @param ctx the user data (XML parser context)
       
   571  * @param elem the name of the element
       
   572  * @param fullname the attribute name
       
   573  * @param type the attribute type
       
   574  * @param def the type of default value
       
   575  * @param defaultValue the attribute default value
       
   576  * @param tree the tree of enumerated value set
       
   577  *
       
   578  * An attribute definition has been parsed
       
   579  */
       
   580 XMLPUBFUNEXPORT void
       
   581 xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
       
   582               int type, int def, const xmlChar *defaultValue,
       
   583           xmlEnumerationPtr tree)
       
   584 {
       
   585     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   586 #ifdef LIBXML_VALID_ENABLED
       
   587     xmlAttributePtr attr;
       
   588 #endif
       
   589     xmlChar *name = NULL, *prefix = NULL;
       
   590 
       
   591 #ifdef DEBUG_SAX
       
   592     xmlGenericError(xmlGenericErrorContext,
       
   593         "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
       
   594             elem, fullname, type, def, defaultValue);
       
   595 #endif
       
   596     if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) &&
       
   597         (type != XML_ATTRIBUTE_ID)) {
       
   598     /*
       
   599      * Raise the error but keep the validity flag
       
   600      */
       
   601     int tmp = ctxt->valid;
       
   602     xmlErrValid(ctxt, XML_DTD_XMLID_TYPE,
       
   603           EMBED_ERRTXT("xml:id : attribute type should be ID\n"), NULL, NULL);
       
   604     ctxt->valid = tmp;
       
   605     }
       
   606     
       
   607     name = xmlSplitQName(ctxt, fullname, &prefix);
       
   608     ctxt->vctxt.valid = 1;
       
   609     if (ctxt->inSubset == 1)
       
   610     {
       
   611 #ifdef LIBXML_VALID_ENABLED
       
   612         attr =
       
   613 #endif
       
   614         xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
       
   615            name, prefix, (xmlAttributeType) type,
       
   616            (xmlAttributeDefault) def, defaultValue, tree);
       
   617     }
       
   618     else if (ctxt->inSubset == 2)
       
   619     {
       
   620 #ifdef LIBXML_VALID_ENABLED
       
   621         attr =
       
   622 #endif
       
   623         xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
       
   624             name, prefix, (xmlAttributeType) type,
       
   625             (xmlAttributeDefault) def, defaultValue, tree);
       
   626     }
       
   627     else
       
   628     {
       
   629         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
   630             ctxt->sax->error(ctxt->userData,
       
   631                 EMBED_ERRTXT("SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n"), name);
       
   632                 xmlFreeEnumeration(tree);
       
   633         return;
       
   634     }
       
   635 #ifdef LIBXML_VALID_ENABLED
       
   636     if (ctxt->vctxt.valid == 0)
       
   637         ctxt->valid = 0;
       
   638     if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
       
   639         (ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset != NULL))
       
   640         ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
       
   641                                             attr);
       
   642 #endif /* LIBXML_VALID_ENABLED */
       
   643     if (prefix != NULL)
       
   644         xmlFree(prefix);
       
   645     if (name != NULL)
       
   646         xmlFree(name);
       
   647 }
       
   648 
       
   649 /**
       
   650  * xmlSAX2ElementDecl:
       
   651  * @param ctx the user data (XML parser context)
       
   652  * @param name the element name
       
   653  * @param type the element type
       
   654  * @param content the element value tree
       
   655  *
       
   656  * An element definition has been parsed
       
   657  */
       
   658 XMLPUBFUNEXPORT void
       
   659 xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type,
       
   660             xmlElementContentPtr content)
       
   661 {
       
   662     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   663 #ifdef LIBXML_VALID_ENABLED
       
   664     xmlElementPtr elem = NULL;
       
   665 #endif
       
   666 
       
   667 #ifdef DEBUG_SAX
       
   668     xmlGenericError(xmlGenericErrorContext,
       
   669                     "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type);
       
   670 #endif
       
   671 
       
   672     if (ctxt->inSubset == 1){
       
   673 #ifdef LIBXML_VALID_ENABLED
       
   674         elem =
       
   675 #endif
       
   676         xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
       
   677                                  name, (xmlElementTypeVal) type, content);
       
   678     }
       
   679     else if (ctxt->inSubset == 2)
       
   680     {
       
   681 #ifdef LIBXML_VALID_ENABLED
       
   682         elem =
       
   683 #endif
       
   684         xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
       
   685                                  name, (xmlElementTypeVal) type, content);
       
   686     }
       
   687     else
       
   688     {
       
   689         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
   690             ctxt->sax->error(ctxt->userData,
       
   691                              EMBED_ERRTXT("SAX.xmlSAX2ElementDecl(%s) called while not in subset\n"),
       
   692                              name);
       
   693         return;
       
   694     }
       
   695 #ifdef LIBXML_VALID_ENABLED
       
   696     if (elem == NULL)
       
   697         ctxt->valid = 0;
       
   698     if (ctxt->validate && ctxt->wellFormed &&
       
   699         ctxt->myDoc && ctxt->myDoc->intSubset)
       
   700         ctxt->valid &=
       
   701             xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
       
   702 #endif /* LIBXML_VALID_ENABLED */
       
   703 }
       
   704 
       
   705 /**
       
   706  * xmlSAX2NotationDecl:
       
   707  * @param ctx the user data (XML parser context)
       
   708  * @param name The name of the notation
       
   709  * @param publicId The public ID of the entity
       
   710  * @param systemId The system ID of the entity
       
   711  *
       
   712  * What to do when a notation declaration has been parsed.
       
   713  */
       
   714 XMLPUBFUNEXPORT void
       
   715 xmlSAX2NotationDecl(void *ctx, const xmlChar *name,
       
   716          const xmlChar *publicId, const xmlChar *systemId)
       
   717 {
       
   718     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   719 #ifdef LIBXML_VALID_ENABLED
       
   720     xmlNotationPtr nota = NULL;
       
   721 #endif
       
   722 
       
   723 #ifdef DEBUG_SAX
       
   724     xmlGenericError(xmlGenericErrorContext,
       
   725         "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId);
       
   726 #endif
       
   727 
       
   728     if ((publicId == NULL) && (systemId == NULL)) {
       
   729         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
   730             ctxt->sax->error(ctxt->userData,
       
   731                 EMBED_ERRTXT("SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n"), name);
       
   732         ctxt->valid = 0;
       
   733         ctxt->wellFormed = 0;
       
   734         return;
       
   735     }
       
   736     else if (ctxt->inSubset == 1)
       
   737     {
       
   738 #ifdef LIBXML_VALID_ENABLED
       
   739         nota =
       
   740 #endif
       
   741         xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
       
   742                               publicId, systemId);
       
   743     }
       
   744     else if (ctxt->inSubset == 2)
       
   745     {
       
   746 #ifdef LIBXML_VALID_ENABLED
       
   747         nota =
       
   748 #endif
       
   749         xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
       
   750                               publicId, systemId);
       
   751     }
       
   752     else
       
   753     {
       
   754         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
   755             ctxt->sax->error(ctxt->userData,
       
   756                 EMBED_ERRTXT("SAX.xmlSAX2NotationDecl(%s) called while not in subset\n"), name);
       
   757         return;
       
   758     }
       
   759 #ifdef LIBXML_VALID_ENABLED
       
   760     if (nota == NULL)
       
   761         ctxt->valid = 0;
       
   762     if (ctxt->validate && ctxt->wellFormed &&
       
   763         ctxt->myDoc && ctxt->myDoc->intSubset)
       
   764     ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
       
   765                                            nota);
       
   766 #endif /* LIBXML_VALID_ENABLED */
       
   767 }
       
   768 
       
   769 /**
       
   770  * xmlSAX2UnparsedEntityDecl:
       
   771  * @param ctx the user data (XML parser context)
       
   772  * @param name The name of the entity
       
   773  * @param publicId The public ID of the entity
       
   774  * @param systemId The system ID of the entity
       
   775  * @param notationName the name of the notation
       
   776  *
       
   777  * What to do when an unparsed entity declaration is parsed
       
   778  */
       
   779 XMLPUBFUNEXPORT void
       
   780 xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
       
   781            const xmlChar *publicId, const xmlChar *systemId,
       
   782            const xmlChar *notationName)
       
   783 {
       
   784     xmlEntityPtr ent;
       
   785     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   786 #ifdef DEBUG_SAX
       
   787     xmlGenericError(xmlGenericErrorContext,
       
   788         "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
       
   789             name, publicId, systemId, notationName);
       
   790 #endif
       
   791     if (ctxt->inSubset == 1)
       
   792     {
       
   793         ent = xmlAddDocEntity(ctxt->myDoc, name,
       
   794                             XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
       
   795                             publicId, systemId, notationName);
       
   796         if (!ent && ctxt->pedantic &&
       
   797             ctxt->sax && ctxt->sax->warning)
       
   798         {
       
   799             ctxt->sax->warning(ctxt->userData,
       
   800                 EMBED_ERRTXT("Entity(%s) already defined in the internal subset\n"), name);
       
   801         }
       
   802         if (ent && !ent->URI && systemId)
       
   803         {
       
   804             xmlChar *URI;
       
   805             const char* base = NULL;
       
   806 
       
   807             if (ctxt->input)
       
   808                 base = ctxt->input->filename;
       
   809             if (!base)
       
   810                 base = ctxt->directory;
       
   811 
       
   812             URI = xmlBuildURI(systemId, (const xmlChar *) base);
       
   813             ent->URI = URI;
       
   814         }
       
   815     }
       
   816     else if (ctxt->inSubset == 2)
       
   817     {
       
   818         ent = xmlAddDtdEntity(ctxt->myDoc, name,
       
   819                             XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
       
   820                             publicId, systemId, notationName);
       
   821         if (!ent && ctxt->pedantic &&
       
   822             ctxt->sax && ctxt->sax->warning)
       
   823         {
       
   824             ctxt->sax->warning(ctxt->userData,
       
   825              EMBED_ERRTXT("Entity(%s) already defined in the external subset\n"), name);
       
   826         }
       
   827         if (ent && !ent->URI && systemId)
       
   828         {
       
   829             xmlChar *URI;
       
   830             const char* base = NULL;
       
   831 
       
   832             if (ctxt->input)
       
   833                 base = ctxt->input->filename;
       
   834             if (!base)
       
   835                 base = ctxt->directory;
       
   836 
       
   837             URI = xmlBuildURI(systemId, (const xmlChar*) base);
       
   838             ent->URI = URI;
       
   839         }
       
   840     }
       
   841     else if (ctxt->sax && ctxt->sax->error)
       
   842     {
       
   843         ctxt->sax->error(ctxt->userData,
       
   844                 EMBED_ERRTXT("SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n"), name);
       
   845     }
       
   846 }
       
   847 
       
   848 /**
       
   849  * xmlSAX2SetDocumentLocator:
       
   850  * @param ctx the user data (XML parser context)
       
   851  * @param loc A SAX Locator
       
   852  *
       
   853  * Receive the document locator at startup, actually xmlDefaultSAXLocator
       
   854  * Everything is available on the context, so this is useless in our case.
       
   855  */
       
   856 XMLPUBFUNEXPORT void
       
   857 xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
       
   858 {
       
   859     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
       
   860 #ifdef DEBUG_SAX
       
   861     xmlGenericError(xmlGenericErrorContext,  "SAX.xmlSAX2SetDocumentLocator()\n");
       
   862 #endif
       
   863     if(ctx) return; // just to use ctx
       
   864 }
       
   865 
       
   866 /**
       
   867  * xmlSAX2StartDocument:
       
   868  * @param ctx the user data (XML parser context)
       
   869  *
       
   870  * called when the document start being processed.
       
   871  *
       
   872  * OOM: possible --> check OOM flag
       
   873  */
       
   874 XMLPUBFUNEXPORT void xmlSAX2StartDocument(void *ctx)
       
   875 {
       
   876 	xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   877     xmlDocPtr doc = NULL;
       
   878 
       
   879 #ifdef DEBUG_SAX
       
   880     xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2StartDocument()\n");
       
   881 #endif
       
   882     if (ctxt->html) {
       
   883 
       
   884 #ifdef LIBXML_HTML_ENABLED
       
   885         if (ctxt->myDoc == NULL)
       
   886             doc = ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL); 
       
   887         if (!ctxt->myDoc)
       
   888             goto OOM;
       
   889 #else
       
   890         xmlGenericError(xmlGenericErrorContext, EMBED_ERRTXT("libxml2 built without HTML support\n"));
       
   891         ctxt->errNo = XML_ERR_INTERNAL_ERROR;
       
   892         goto ERR;
       
   893 #endif
       
   894     } else { // not HTML
       
   895         doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
       
   896         if (!doc)
       
   897             goto OOM;
       
   898 
       
   899         if (ctxt->encoding != NULL){
       
   900             doc->encoding = xmlStrdup(ctxt->encoding); 
       
   901             if(! doc->encoding)
       
   902                 goto OOM;
       
   903         }
       
   904         //else
       
   905         //    doc->encoding = NULL; // it is NULL after xmlNewDoc
       
   906         doc->standalone = ctxt->standalone;
       
   907         if (ctxt->dictNames && doc) {
       
   908             doc->dict = ctxt->dict;
       
   909             xmlDictReference(doc->dict);
       
   910         }
       
   911     }
       
   912     if ( /* (ctxt->myDoc != NULL) && : it's NOT NULL here */
       
   913         !doc->URL       &&
       
   914         ctxt->input     &&
       
   915         ctxt->input->filename)
       
   916     {
       
   917         doc->URL = xmlCanonicPath((const xmlChar *) ctxt->input->filename); 
       
   918         if (!doc->URL)
       
   919             doc->URL = xmlStrdup((const xmlChar *) ctxt->input->filename); 
       
   920     }
       
   921     return;
       
   922 //----------------------------
       
   923 OOM:
       
   924     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
   925         ctxt->sax->error(ctxt->userData, EMBED_ERRTXT("SAX.xmlSAX2StartDocument(): out of memory\n"));
       
   926     ctxt->errNo = XML_ERR_NO_MEMORY;
       
   927 ERR:
       
   928     ctxt->instate = XML_PARSER_EOF;
       
   929     ctxt->disableSAX = 1;
       
   930     return;
       
   931 }
       
   932 
       
   933 /**
       
   934  * xmlSAX2EndDocument:
       
   935  * @param ctx the user data (XML parser context)
       
   936  *
       
   937  * called when the document end has been detected.
       
   938  */
       
   939 XMLPUBFUNEXPORT void
       
   940 xmlSAX2EndDocument(void *ctx)
       
   941 {
       
   942     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   943 #ifdef DEBUG_SAX
       
   944     xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndDocument()\n");
       
   945 #endif
       
   946 #ifdef LIBXML_VALID_ENABLED
       
   947     if (ctxt->validate && ctxt->wellFormed &&  ctxt->myDoc && ctxt->myDoc->intSubset)
       
   948         ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
       
   949 #endif /* LIBXML_VALID_ENABLED */
       
   950 
       
   951     /*
       
   952      * Grab the encoding if it was added on-the-fly
       
   953      */
       
   954     if (ctxt->encoding &&
       
   955         ctxt->myDoc    &&
       
   956         !ctxt->myDoc->encoding)
       
   957     {
       
   958         ctxt->myDoc->encoding = ctxt->encoding;
       
   959         ctxt->encoding = NULL;
       
   960     }
       
   961     if (ctxt->inputTab[0]->encoding &&
       
   962         ctxt->myDoc                 &&
       
   963         !ctxt->myDoc->encoding)
       
   964     {
       
   965         ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
       
   966     }
       
   967     if ((ctxt->charset != XML_CHAR_ENCODING_NONE) &&
       
   968         ctxt->myDoc  &&
       
   969         (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE))
       
   970     {
       
   971         ctxt->myDoc->charset = ctxt->charset;
       
   972     }
       
   973 }
       
   974 
       
   975 // Note: old (SAX1) handlers -- name is misleading
       
   976 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED)
       
   977 /**
       
   978  * xmlSAX2AttributeInternal:
       
   979  * @param ctx the user data (XML parser context)
       
   980  * @param fullname The attribute name, including namespace prefix
       
   981  * @param value The attribute value
       
   982  * @param prefix the prefix on the element node
       
   983  *
       
   984  * Handle an attribute that has been read by the parser.
       
   985  * The default handling is to convert the attribute into an
       
   986  * DOM subtree and past it in a new xmlAttr element added to
       
   987  * the element.
       
   988  */
       
   989 static void
       
   990 xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
       
   991              const xmlChar *value, const xmlChar *prefix ATTRIBUTE_UNUSED)
       
   992 {
       
   993     // DONE: Find and refactor all "namespace" variables to not match C++ keyword
       
   994     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
   995     xmlAttrPtr ret;
       
   996     xmlChar *name;
       
   997     xmlChar *ns;
       
   998     xmlChar *nval;
       
   999     xmlNsPtr nameSpace;
       
  1000 
       
  1001     /*
       
  1002      * Split the full name into a namespace prefix and the tag name
       
  1003      */
       
  1004     name = xmlSplitQName(ctxt, fullname, &ns);
       
  1005     if ((name != NULL) && (name[0] == 0)) {
       
  1006         if (xmlStrEqual(ns, BAD_CAST "xmlns")) {
       
  1007             if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
  1008                 ctxt->sax->error(ctxt->userData,
       
  1009                  EMBED_ERRTXT("invalid namespace declaration '%s'\n"), fullname);
       
  1010         } else {
       
  1011             if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
       
  1012             ctxt->sax->warning(ctxt->userData,
       
  1013                  EMBED_ERRTXT("Avoid attribute ending with ':' like '%s'\n"), fullname);
       
  1014         }
       
  1015         if (ns != NULL)
       
  1016             xmlFree(ns);
       
  1017         ns = NULL;
       
  1018         xmlFree(name);
       
  1019         name = xmlStrdup(fullname);
       
  1020     }
       
  1021     if (name == NULL) {
       
  1022         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
  1023             ctxt->sax->error(ctxt->userData,EMBED_ERRTXT("SAX.xmlSAX2StartElement(): out of memory\n"));
       
  1024         ctxt->errNo = XML_ERR_NO_MEMORY;
       
  1025         ctxt->instate = XML_PARSER_EOF;
       
  1026         ctxt->disableSAX = 1;
       
  1027         if (ns != NULL)
       
  1028             xmlFree(ns);
       
  1029         return;
       
  1030     }
       
  1031 
       
  1032 #ifdef LIBXML_VALID_ENABLED
       
  1033     /*
       
  1034      * Do the last stage of the attribute normalization
       
  1035      * Needed for HTML too:
       
  1036      *   http://www.w3.org/TR/html4/types.html#h-6.2
       
  1037      */
       
  1038     ctxt->vctxt.valid = 1;
       
  1039     nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
       
  1040                                        ctxt->myDoc, ctxt->node,
       
  1041                        fullname, value);
       
  1042     if (ctxt->vctxt.valid != 1) {
       
  1043     ctxt->valid = 0;
       
  1044     }
       
  1045     if (nval != NULL)
       
  1046     value = nval;
       
  1047 #else
       
  1048     nval = NULL;
       
  1049 #endif /* LIBXML_VALID_ENABLED */
       
  1050 
       
  1051     /*
       
  1052      * Check whether it's a namespace definition
       
  1053      */
       
  1054     if ((!ctxt->html) && (ns == NULL) &&
       
  1055         (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
       
  1056         (name[3] == 'n') && (name[4] == 's') && (name[5] == 0))
       
  1057     {
       
  1058         xmlNsPtr nsret;
       
  1059         xmlChar *val;
       
  1060 
       
  1061         if (!ctxt->replaceEntities) {
       
  1062             ctxt->depth++;
       
  1063             val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,0,0,0);
       
  1064             ctxt->depth--;
       
  1065         } else {
       
  1066             val = (xmlChar *) value;
       
  1067         }
       
  1068 
       
  1069         if (val[0] != 0) {
       
  1070             xmlURIPtr uri;
       
  1071 
       
  1072             uri = xmlParseURI((const char *)val);
       
  1073             if (uri == NULL) {
       
  1074                 if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
       
  1075                     ctxt->sax->warning(ctxt->userData,
       
  1076                      EMBED_ERRTXT("xmlns: %s not a valid URI\n"), val);
       
  1077                 } else {
       
  1078                 if (uri->scheme == NULL) {
       
  1079                     if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
       
  1080                     ctxt->sax->warning(ctxt->userData,
       
  1081                          EMBED_ERRTXT("xmlns: URI %s is not absolute\n"), val);
       
  1082                 }
       
  1083                 xmlFreeURI(uri);
       
  1084             }
       
  1085         }
       
  1086 
       
  1087         /* a default namespace definition */
       
  1088         nsret = xmlNewNs(ctxt->node, val, NULL);
       
  1089 
       
  1090 #ifdef LIBXML_VALID_ENABLED
       
  1091         /*
       
  1092          * Validate also for namespace decls, they are attributes from
       
  1093          * an XML-1.0 perspective
       
  1094          */
       
  1095         if (nsret != NULL   &&
       
  1096             ctxt->validate  &&
       
  1097             ctxt->wellFormed &&
       
  1098             ctxt->myDoc && ctxt->myDoc->intSubset)
       
  1099         {
       
  1100             ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
       
  1101                            ctxt->node, prefix, nsret, val);
       
  1102         }
       
  1103 #endif /* LIBXML_VALID_ENABLED */
       
  1104         if (name != NULL)
       
  1105             xmlFree(name);
       
  1106         if (nval != NULL)
       
  1107             xmlFree(nval);
       
  1108         if (val != value)
       
  1109             xmlFree(val);
       
  1110         return;
       
  1111     }
       
  1112 
       
  1113     if ((!ctxt->html) &&
       
  1114         (ns != NULL) &&
       
  1115         (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
       
  1116         (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0))
       
  1117     {
       
  1118         xmlNsPtr nsret;
       
  1119         xmlChar *val;
       
  1120 
       
  1121         if (!ctxt->replaceEntities) {
       
  1122             ctxt->depth++;
       
  1123             val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
       
  1124                                       0,0,0);
       
  1125             ctxt->depth--;
       
  1126             if (val == NULL) {
       
  1127                 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
  1128                     ctxt->sax->error(ctxt->userData, EMBED_ERRTXT("SAX.xmlSAX2StartElement(): out of memory\n"));
       
  1129                 ctxt->errNo = XML_ERR_NO_MEMORY;
       
  1130                 ctxt->instate = XML_PARSER_EOF;
       
  1131                 ctxt->disableSAX = 1;
       
  1132                 xmlFree(ns);
       
  1133                 if (name != NULL)
       
  1134                     xmlFree(name);
       
  1135                 return;
       
  1136             }
       
  1137     } else {
       
  1138         val = (xmlChar *) value;
       
  1139     }
       
  1140 
       
  1141     if (val[0] == 0) {
       
  1142         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
  1143             ctxt->sax->error(ctxt->userData, EMBED_ERRTXT("Empty namespace name for prefix %s\n"), name);
       
  1144     }
       
  1145     if ((ctxt->pedantic != 0) && (val[0] != 0)) {
       
  1146         xmlURIPtr uri;
       
  1147 
       
  1148         uri = xmlParseURI((const char *)val);
       
  1149         if (uri == NULL) {
       
  1150         if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
       
  1151             ctxt->sax->warning(ctxt->userData,
       
  1152              EMBED_ERRTXT("xmlns:%s: %s not a valid URI\n"), name, value);
       
  1153         } else {
       
  1154         if (uri->scheme == NULL) {
       
  1155             if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
       
  1156             ctxt->sax->warning(ctxt->userData,
       
  1157                EMBED_ERRTXT("xmlns:%s: URI %s is not absolute\n"), name, value);
       
  1158         }
       
  1159         xmlFreeURI(uri);
       
  1160         }
       
  1161     }
       
  1162 
       
  1163     /* a standard namespace definition */
       
  1164     nsret = xmlNewNs(ctxt->node, val, name);
       
  1165     xmlFree(ns);
       
  1166 #ifdef LIBXML_VALID_ENABLED
       
  1167     /*
       
  1168      * Validate also for namespace decls, they are attributes from
       
  1169      * an XML-1.0 perspective
       
  1170      */
       
  1171         if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
       
  1172         ctxt->myDoc && ctxt->myDoc->intSubset)
       
  1173         ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
       
  1174                        ctxt->node, prefix, nsret, value);
       
  1175 #endif /* LIBXML_VALID_ENABLED */
       
  1176     if (name != NULL)
       
  1177         xmlFree(name);
       
  1178     if (nval != NULL)
       
  1179         xmlFree(nval);
       
  1180     if (val != value)
       
  1181         xmlFree(val);
       
  1182     return;
       
  1183     }
       
  1184 
       
  1185     if (ns != NULL) {
       
  1186     xmlAttrPtr prop;
       
  1187     nameSpace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
       
  1188     if (nameSpace == NULL) {
       
  1189         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
  1190         ctxt->sax->error(ctxt->userData,
       
  1191             EMBED_ERRTXT("Namespace prefix %s of attribute %s is not defined\n"),
       
  1192                      ns, name);
       
  1193     }
       
  1194 
       
  1195     prop = ctxt->node->properties;
       
  1196     while (prop != NULL) {
       
  1197         if (prop->ns != NULL) {
       
  1198         if ((xmlStrEqual(name, prop->name)) &&
       
  1199             ((nameSpace == prop->ns) ||
       
  1200              (xmlStrEqual(nameSpace->href, prop->ns->href)))) {
       
  1201             ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
       
  1202             if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
  1203             ctxt->sax->error(ctxt->userData,
       
  1204                     EMBED_ERRTXT("Attribute %s in %s redefined\n"),
       
  1205                              name, nameSpace->href);
       
  1206             ctxt->wellFormed = 0;
       
  1207             if (ctxt->recovery == 0) ctxt->disableSAX = 1;
       
  1208             goto error;
       
  1209         }
       
  1210         }
       
  1211         prop = prop->next;
       
  1212     }
       
  1213     } else {
       
  1214     nameSpace = NULL;
       
  1215     }
       
  1216 
       
  1217     /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
       
  1218     ret = xmlNewNsPropEatName(ctxt->node, nameSpace, name, NULL);
       
  1219 
       
  1220     if (ret != NULL) {
       
  1221         if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
       
  1222             xmlNodePtr tmp;
       
  1223 
       
  1224             ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
       
  1225             tmp = ret->children;
       
  1226             while (tmp != NULL) {
       
  1227             tmp->parent = (xmlNodePtr) ret;
       
  1228             if (tmp->next == NULL)
       
  1229                 ret->last = tmp;
       
  1230             tmp = tmp->next;
       
  1231         }
       
  1232     } else if (value != NULL) {
       
  1233             ret->children = xmlNewDocText(ctxt->myDoc, value);
       
  1234             ret->last = ret->children;
       
  1235             if (ret->children != NULL)
       
  1236                 ret->children->parent = (xmlNodePtr) ret;
       
  1237         }
       
  1238     }
       
  1239 
       
  1240 #ifdef LIBXML_VALID_ENABLED
       
  1241     if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
       
  1242         ctxt->myDoc && ctxt->myDoc->intSubset)
       
  1243     {
       
  1244         /*
       
  1245          * If we don't substitute entities, the validation should be
       
  1246          * done on a value with replaced entities anyway.
       
  1247          */
       
  1248         if (!ctxt->replaceEntities) {
       
  1249             xmlChar *val;
       
  1250 
       
  1251             ctxt->depth++;
       
  1252             val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,0,0,0);
       
  1253             ctxt->depth--;
       
  1254 
       
  1255             if (val == NULL)
       
  1256                 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, value);
       
  1257             else {
       
  1258                 xmlChar *nvalnorm;
       
  1259 
       
  1260                 /*
       
  1261                  * Do the last stage of the attribute normalization
       
  1262                  * It need to be done twice ... it's an extra burden related
       
  1263                  * to the ability to keep xmlSAX2References in attributes
       
  1264                  */
       
  1265                 nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc, ctxt->node, fullname, val);
       
  1266                 if (nvalnorm != NULL) {
       
  1267                     xmlFree(val);
       
  1268                     val = nvalnorm;
       
  1269                 }
       
  1270 
       
  1271                 ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, val);
       
  1272                 xmlFree(val);
       
  1273             }
       
  1274         } else {
       
  1275             ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, value);
       
  1276         }
       
  1277     } else
       
  1278 #endif /* LIBXML_VALID_ENABLED */
       
  1279            if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
       
  1280            (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
       
  1281             ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
       
  1282      /*
       
  1283      * when validating, the ID registration is done at the attribute
       
  1284      * validation level. Otherwise we have to do specific handling here.
       
  1285      */
       
  1286     if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
       
  1287         xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
       
  1288     else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
       
  1289         xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
       
  1290     else if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
       
  1291         /*
       
  1292          * Add the xml:id value
       
  1293          *
       
  1294          * Open issue: normalization of the value.
       
  1295          */
       
  1296         if (xmlValidateNCName(value, 1) != 0) {
       
  1297             xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
       
  1298                         EMBED_ERRTXT("xml:id : attribute value %s is not an NCName\n"),
       
  1299                         (const char *) value, NULL);
       
  1300         }
       
  1301         xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
       
  1302     }
       
  1303     }
       
  1304 
       
  1305 error:
       
  1306     if (nval != NULL)
       
  1307         xmlFree(nval);
       
  1308     if (ns != NULL)
       
  1309         xmlFree(ns);
       
  1310 }
       
  1311 
       
  1312 /*
       
  1313  * xmlCheckDefaultedAttributes:
       
  1314  *
       
  1315  * Check defaulted attributes from the DTD
       
  1316  */
       
  1317 static void
       
  1318 xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
       
  1319     const xmlChar *prefix, const xmlChar **atts) {
       
  1320     xmlElementPtr elemDecl;
       
  1321     const xmlChar *att;
       
  1322     int internal = 1;
       
  1323     int i;
       
  1324 
       
  1325     elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix);
       
  1326     if (elemDecl == NULL) {
       
  1327         elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix);
       
  1328         internal = 0;
       
  1329     }
       
  1330 
       
  1331 process_external_subset:
       
  1332 
       
  1333     if (elemDecl != NULL) {
       
  1334     xmlAttributePtr attr = elemDecl->attributes;
       
  1335     /*
       
  1336      * Check against defaulted attributes from the external subset
       
  1337      * if the document is stamped as standalone
       
  1338      */
       
  1339     if ((ctxt->myDoc->standalone == 1) &&
       
  1340         (ctxt->myDoc->extSubset != NULL) &&
       
  1341         (ctxt->validate)) {
       
  1342         while (attr != NULL) {
       
  1343         if ((attr->defaultValue != NULL) &&
       
  1344             (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset,
       
  1345                     attr->elem, attr->name,
       
  1346                     attr->prefix) == attr) &&
       
  1347             (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
       
  1348                     attr->elem, attr->name,
       
  1349                     attr->prefix) == NULL)) {
       
  1350             xmlChar *fulln;
       
  1351 
       
  1352             if (attr->prefix != NULL) {
       
  1353             fulln = xmlStrdup(attr->prefix);
       
  1354             fulln = xmlStrcat(fulln, BAD_CAST ":");
       
  1355             fulln = xmlStrcat(fulln, attr->name);
       
  1356             } else {
       
  1357             fulln = xmlStrdup(attr->name);
       
  1358             }
       
  1359 
       
  1360             /*
       
  1361              * Check that the attribute is not declared in the
       
  1362              * serialization
       
  1363              */
       
  1364             att = NULL;
       
  1365             if (atts != NULL) {
       
  1366             i = 0;
       
  1367             att = atts[i];
       
  1368             while (att != NULL) {
       
  1369                 if (xmlStrEqual(att, fulln))
       
  1370                 break;
       
  1371                 i += 2;
       
  1372                 att = atts[i];
       
  1373             }
       
  1374             }
       
  1375             if (att == NULL) {
       
  1376                 xmlErrValid(ctxt, XML_DTD_STANDALONE_DEFAULTED,
       
  1377       EMBED_ERRTXT("standalone: attribute %s on %s defaulted from external subset\n"),
       
  1378                     (const char *)fulln,
       
  1379                     (const char *)attr->elem);
       
  1380             }
       
  1381         }
       
  1382         attr = attr->nexth;
       
  1383         }
       
  1384     }
       
  1385 
       
  1386     /*
       
  1387      * Actually insert defaulted values when needed
       
  1388      */
       
  1389     attr = elemDecl->attributes;
       
  1390     while (attr != NULL) {
       
  1391         /*
       
  1392          * Make sure that attributes redefinition occuring in the
       
  1393          * internal subset are not overriden by definitions in the
       
  1394          * external subset.
       
  1395          */
       
  1396         if (attr->defaultValue != NULL) {
       
  1397         /*
       
  1398          * the element should be instantiated in the tree if:
       
  1399          *  - this is a namespace prefix
       
  1400          *  - the user required for completion in the tree
       
  1401          *    like XSLT
       
  1402          *  - there isn't already an attribute definition
       
  1403          *    in the internal subset overriding it.
       
  1404          */
       
  1405         if (((attr->prefix != NULL) &&
       
  1406              (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
       
  1407             ((attr->prefix == NULL) &&
       
  1408              (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
       
  1409             (ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
       
  1410             xmlAttributePtr tst;
       
  1411 
       
  1412             tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
       
  1413                          attr->elem, attr->name,
       
  1414                          attr->prefix);
       
  1415             if ((tst == attr) || (tst == NULL)) {
       
  1416                 xmlChar fn[50];
       
  1417             xmlChar *fulln;
       
  1418 
       
  1419                         fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50);
       
  1420             if (fulln == NULL) {
       
  1421                 if ((ctxt->sax != NULL) &&
       
  1422                     (ctxt->sax->error != NULL))
       
  1423                 ctxt->sax->error(ctxt->userData,
       
  1424                      EMBED_ERRTXT("SAX.xmlSAX2StartElement(): out of memory\n"));
       
  1425                 ctxt->errNo = XML_ERR_NO_MEMORY;
       
  1426                 ctxt->instate = XML_PARSER_EOF;
       
  1427                 ctxt->disableSAX = 1;
       
  1428                 return;
       
  1429             }
       
  1430 
       
  1431             /*
       
  1432              * Check that the attribute is not declared in the
       
  1433              * serialization
       
  1434              */
       
  1435             att = NULL;
       
  1436             if (atts != NULL) {
       
  1437                 i = 0;
       
  1438                 att = atts[i];
       
  1439                 while (att != NULL) {
       
  1440                 if (xmlStrEqual(att, fulln))
       
  1441                     break;
       
  1442                 i += 2;
       
  1443                 att = atts[i];
       
  1444                 }
       
  1445             }
       
  1446             if (att == NULL) {
       
  1447                 xmlSAX2AttributeInternal(ctxt, fulln,
       
  1448                          attr->defaultValue, prefix);
       
  1449             }
       
  1450             if ((fulln != fn) && (fulln != attr->name))
       
  1451                 xmlFree(fulln);
       
  1452             }
       
  1453         }
       
  1454         }
       
  1455         attr = attr->nexth;
       
  1456     }
       
  1457     if (internal == 1) {
       
  1458         elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
       
  1459                                      name, prefix);
       
  1460         internal = 0;
       
  1461         goto process_external_subset;
       
  1462     }
       
  1463     }
       
  1464 }
       
  1465 
       
  1466 /**
       
  1467  * xmlSAX2StartElement:
       
  1468  * @param ctx the user data (XML parser context)
       
  1469  * @param fullname The element name, including namespace prefix
       
  1470  * @param atts An array of name/value attributes pairs, NULL terminated
       
  1471  *
       
  1472  * called when an opening tag has been processed.
       
  1473  */
       
  1474 XMLPUBFUNEXPORT void
       
  1475 xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
       
  1476 {
       
  1477     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
  1478     xmlNodePtr ret;
       
  1479     xmlNodePtr parent = ctxt->node;
       
  1480     xmlNsPtr ns;
       
  1481     xmlChar *name;
       
  1482     xmlChar *prefix;
       
  1483     const xmlChar *att;
       
  1484     const xmlChar *value;
       
  1485     int i;
       
  1486 
       
  1487 #ifdef DEBUG_SAX
       
  1488     xmlGenericError(xmlGenericErrorContext,
       
  1489         "SAX.xmlSAX2StartElement(%s)\n", fullname);
       
  1490 #endif
       
  1491 
       
  1492     /*
       
  1493      * First check on validity:
       
  1494      */
       
  1495     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
       
  1496         ((ctxt->myDoc->intSubset == NULL) ||
       
  1497      ((ctxt->myDoc->intSubset->notations == NULL) &&
       
  1498       (ctxt->myDoc->intSubset->elements == NULL) &&
       
  1499       (ctxt->myDoc->intSubset->attributes == NULL) &&
       
  1500       (ctxt->myDoc->intSubset->entities == NULL)))) {
       
  1501     xmlErrValid(ctxt, XML_ERR_NO_DTD,
       
  1502       EMBED_ERRTXT("Validation failed: no DTD found !"), NULL, NULL);
       
  1503     ctxt->validate = 0;
       
  1504     }
       
  1505 
       
  1506 
       
  1507     /*
       
  1508      * Split the full name into a namespace prefix and the tag name
       
  1509      */
       
  1510     name = xmlSplitQName(ctxt, fullname, &prefix);
       
  1511 
       
  1512 
       
  1513     /*
       
  1514      * Note : the namespace resolution is deferred until the end of the
       
  1515      *        attributes parsing, since local namespace can be defined as
       
  1516      *        an attribute at this level.
       
  1517      */
       
  1518     ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
       
  1519     if (ret == NULL) {
       
  1520         if (prefix != NULL)
       
  1521             xmlFree(prefix);
       
  1522         ctxt->errNo = XML_ERR_NO_MEMORY;
       
  1523         ctxt->instate = XML_PARSER_EOF;
       
  1524         ctxt->disableSAX = 1;
       
  1525         return;
       
  1526     }
       
  1527     if (ctxt->myDoc->children == NULL) {
       
  1528 #ifdef DEBUG_SAX_TREE
       
  1529         xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
       
  1530 #endif
       
  1531         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
       
  1532     } else if (parent == NULL) {
       
  1533         parent = ctxt->myDoc->children;
       
  1534     }
       
  1535     ctxt->nodemem = -1;
       
  1536 
       
  1537 #ifdef LIBXML_ENABLE_NODE_LINEINFO
       
  1538     if (ctxt->linenumbers) {
       
  1539         if (ctxt->input != NULL) {
       
  1540             if (ctxt->input->line < 65535)
       
  1541                 ret->line = (short) ctxt->input->line;
       
  1542             else
       
  1543                 ret->line = 65535;
       
  1544         }
       
  1545     }
       
  1546 #endif
       
  1547     /*
       
  1548      * We are parsing a new node.
       
  1549      */
       
  1550 #ifdef DEBUG_SAX_TREE
       
  1551     xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
       
  1552 #endif
       
  1553     nodePush(ctxt, ret);
       
  1554 
       
  1555     /*
       
  1556      * Link the child element
       
  1557      */
       
  1558     if (parent != NULL) {
       
  1559         if (parent->type == XML_ELEMENT_NODE) {
       
  1560 #ifdef DEBUG_SAX_TREE
       
  1561         xmlGenericError(xmlGenericErrorContext,"adding child %s to %s\n", name, parent->name);
       
  1562 #endif
       
  1563             xmlAddChild(parent, ret);
       
  1564         } else {
       
  1565 #ifdef DEBUG_SAX_TREE
       
  1566             xmlGenericError(xmlGenericErrorContext,"adding sibling %s to ", name);
       
  1567             xmlDebugDumpOneNode(stderr, parent, 0);
       
  1568 #endif
       
  1569             xmlAddSibling(parent, ret);
       
  1570         }
       
  1571     }
       
  1572 
       
  1573     /*
       
  1574      * Insert all the defaulted attributes from the DTD especially namespaces
       
  1575      */
       
  1576     
       
  1577     if ((!ctxt->html) &&
       
  1578         ((ctxt->myDoc->intSubset != NULL) || (ctxt->myDoc->extSubset != NULL)))
       
  1579     {
       
  1580         xmlCheckDefaultedAttributes(ctxt, name, prefix, atts);
       
  1581     }
       
  1582 
       
  1583     /*
       
  1584      * process all the attributes whose name start with "xmlns"
       
  1585      */
       
  1586     if (atts != NULL) {
       
  1587         i = 0;
       
  1588         att = atts[i++];
       
  1589         value = atts[i++];
       
  1590         if (!ctxt->html) {
       
  1591             while ((att != NULL) && (value != NULL)) {
       
  1592                 if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') &&
       
  1593                     (att[3] == 'n') && (att[4] == 's'))
       
  1594                     xmlSAX2AttributeInternal(ctxt, att, value, prefix);
       
  1595 
       
  1596                 att = atts[i++];
       
  1597                 value = atts[i++];
       
  1598             }
       
  1599         }
       
  1600     }
       
  1601 
       
  1602     /*
       
  1603      * Search the namespace, note that since the attributes have been
       
  1604      * processed, the local namespaces are available.
       
  1605      */
       
  1606     ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
       
  1607     if ((ns == NULL) && (parent != NULL))
       
  1608         ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
       
  1609     
       
  1610     if ((prefix != NULL) && (ns == NULL)) {
       
  1611         ns = xmlNewNs(ret, NULL, prefix);
       
  1612         if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
       
  1613             ctxt->sax->warning(ctxt->userData,EMBED_ERRTXT("Namespace prefix %s is not defined\n"), prefix);
       
  1614     }
       
  1615 
       
  1616     /*
       
  1617      * set the namespace node, making sure that if the default namspace
       
  1618      * is unbound on a parent we simply kee it NULL
       
  1619      */
       
  1620     if ((ns != NULL) && (ns->href != NULL) &&
       
  1621         ((ns->href[0] != 0) || (ns->prefix != NULL)))
       
  1622         xmlSetNs(ret, ns);
       
  1623 
       
  1624     /*
       
  1625      * process all the other attributes
       
  1626      */
       
  1627     if (atts != NULL) {
       
  1628         i = 0;
       
  1629         att = atts[i++];
       
  1630         value = atts[i++];
       
  1631         if (ctxt->html) {
       
  1632             while (att != NULL) {
       
  1633                 xmlSAX2AttributeInternal(ctxt, att, value, NULL);
       
  1634                 att = atts[i++];
       
  1635                 value = atts[i++];
       
  1636             }
       
  1637         } else {
       
  1638             while ((att != NULL) && (value != NULL)) {
       
  1639                 if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') ||
       
  1640                     (att[3] != 'n') || (att[4] != 's'))
       
  1641                     xmlSAX2AttributeInternal(ctxt, att, value, NULL);
       
  1642 
       
  1643                 /*
       
  1644                  * Next ones
       
  1645                  */
       
  1646                 att = atts[i++];
       
  1647                 value = atts[i++];
       
  1648             }
       
  1649         }
       
  1650     }
       
  1651 
       
  1652 #ifdef LIBXML_VALID_ENABLED
       
  1653     /*
       
  1654      * If it's the Document root, finish the DTD validation and
       
  1655      * check the document root element for validity
       
  1656      */
       
  1657     if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
       
  1658     int chk;
       
  1659 
       
  1660     chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
       
  1661     if (chk <= 0)
       
  1662         ctxt->valid = 0;
       
  1663     if (chk < 0)
       
  1664         ctxt->wellFormed = 0;
       
  1665     ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
       
  1666     ctxt->vctxt.finishDtd = 1;
       
  1667     }
       
  1668 #endif /* LIBXML_VALID_ENABLED */
       
  1669 
       
  1670     if (prefix != NULL)
       
  1671     xmlFree(prefix);
       
  1672 
       
  1673 }
       
  1674 
       
  1675 /**
       
  1676  * xmlSAX2EndElement:
       
  1677  * @param ctx the user data (XML parser context)
       
  1678  * @param name The element name
       
  1679  *
       
  1680  * called when the end of an element has been detected.
       
  1681  */
       
  1682 XMLPUBFUNEXPORT void
       
  1683 xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
       
  1684 {
       
  1685     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
  1686     //xmlParserNodeInfo node_info;
       
  1687     xmlNodePtr cur = ctxt->node;
       
  1688 
       
  1689 #ifdef DEBUG_SAX
       
  1690     if (name == NULL)
       
  1691         xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n");
       
  1692     else
       
  1693     xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name);
       
  1694 #endif
       
  1695 
       
  1696 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
  1697     /* Capture end position and add node */
       
  1698     if (cur != NULL && ctxt->record_info) {
       
  1699       node_info.end_pos = ctxt->input->cur - ctxt->input->base;
       
  1700       node_info.end_line = ctxt->input->line;
       
  1701       node_info.node = cur;
       
  1702       xmlParserAddNodeInfo(ctxt, &node_info);
       
  1703     }
       
  1704 #endif // XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
  1705 
       
  1706     ctxt->nodemem = -1;
       
  1707 
       
  1708 #ifdef LIBXML_VALID_ENABLED
       
  1709     if (ctxt->validate && ctxt->wellFormed &&
       
  1710         ctxt->myDoc && ctxt->myDoc->intSubset)
       
  1711         ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
       
  1712                          cur);
       
  1713 #endif /* LIBXML_VALID_ENABLED */
       
  1714 
       
  1715 
       
  1716     /*
       
  1717      * end of parsing of this node.
       
  1718      */
       
  1719 #ifdef DEBUG_SAX_TREE
       
  1720     xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
       
  1721 #endif
       
  1722     nodePop(ctxt);
       
  1723 }
       
  1724 #endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */
       
  1725 
       
  1726 /*
       
  1727  * xmlSAX2TextNode:
       
  1728  * @param ctxt the parser context
       
  1729  * @param str the input string
       
  1730  * @param len the string length
       
  1731  *
       
  1732  * Remove the entities from an attribute value
       
  1733  *
       
  1734  * Returns the newly allocated string or NULL if not needed or error
       
  1735  */
       
  1736 static xmlNodePtr
       
  1737 xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
       
  1738 	LOAD_GS(ctxt)
       
  1739     xmlNodePtr ret;
       
  1740     const xmlChar *intern = NULL;
       
  1741 
       
  1742     /*
       
  1743      * Allocate
       
  1744      */
       
  1745     if (ctxt->freeElems != NULL) {
       
  1746         ret = ctxt->freeElems;
       
  1747         ctxt->freeElems = ret->next;
       
  1748         ctxt->freeElemsNr--;
       
  1749     } else {
       
  1750         ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  1751     }
       
  1752     if (ret == NULL) {
       
  1753 OOM:
       
  1754         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
  1755             ctxt->sax->error(ctxt->userData, EMBED_ERRTXT("SAX.xmlSAX2Characters(): out of memory\n"));
       
  1756         ctxt->errNo = XML_ERR_NO_MEMORY;
       
  1757         ctxt->instate = XML_PARSER_EOF;
       
  1758         ctxt->disableSAX = 1;
       
  1759         return(NULL);
       
  1760     }
       
  1761     /*
       
  1762      * intern the formatting blanks found between tags, or the
       
  1763      * very short strings
       
  1764      */
       
  1765     if (ctxt->dictNames) {
       
  1766         xmlChar cur = str[len];
       
  1767 
       
  1768         if ((len <= 3) && ((cur == '"') || (cur == '\'') ||
       
  1769             ((cur == '<') && (str[len + 1] != '!'))))
       
  1770         {
       
  1771             intern = xmlDictLookup(ctxt->dict, str, len);
       
  1772         }
       
  1773         else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') &&
       
  1774                    (str[len + 1] != '!'))
       
  1775            {
       
  1776                 int i;
       
  1777 
       
  1778                 for (i = 1;i < len;i++) {
       
  1779                     if (!IS_BLANK_CH(str[i])) goto skip;
       
  1780                 }
       
  1781                 intern = xmlDictLookup(ctxt->dict, str, len);
       
  1782             }
       
  1783     }
       
  1784 skip:
       
  1785     memset(ret, 0, sizeof(xmlNode));
       
  1786     ret->type = XML_TEXT_NODE;
       
  1787 
       
  1788     ret->name = xmlStringText;
       
  1789     if (intern == NULL)
       
  1790     	{
       
  1791     	ret->content = xmlStrndup(str, len);
       
  1792     		{
       
  1793     		if(OOM_FLAG)
       
  1794     			{
       
  1795 			    if (ctxt->freeElems != NULL) 
       
  1796 			    	{ 
       
  1797 			    	ctxt->freeElemsNr++;   			
       
  1798 			        ret->next = ctxt->freeElems;
       
  1799 			        ctxt->freeElems = ret;
       
  1800 			    	}
       
  1801 			    else
       
  1802 			    	{
       
  1803 			    	xmlFreeNode(ret);
       
  1804 			    	}
       
  1805 			    goto OOM;
       
  1806     			}
       
  1807     		}
       
  1808     	}
       
  1809     else
       
  1810         ret->content = (xmlChar *) intern;
       
  1811 
       
  1812     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  1813         xmlRegisterNodeDefaultValue(ret);
       
  1814     return(ret);
       
  1815 }
       
  1816 
       
  1817 #ifdef LIBXML_VALID_ENABLED
       
  1818 /*
       
  1819  * xmlSAX2DecodeAttrEntities:
       
  1820  * @param ctxt the parser context
       
  1821  * @param str the input string
       
  1822  * @param len the string length
       
  1823  *
       
  1824  * Remove the entities from an attribute value
       
  1825  *
       
  1826  * Returns the newly allocated string or NULL if not needed or error
       
  1827  */
       
  1828 static xmlChar *
       
  1829 xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
       
  1830                           const xmlChar *end) {
       
  1831     const xmlChar *in;
       
  1832     xmlChar *ret;
       
  1833 
       
  1834     in = str;
       
  1835     while (in < end)
       
  1836         if (*in++ == '&')
       
  1837         goto decode;
       
  1838     return(NULL);
       
  1839 decode:
       
  1840     ctxt->depth++;
       
  1841     ret = xmlStringLenDecodeEntities(ctxt, str, end - str,
       
  1842                      XML_SUBSTITUTE_REF, 0,0,0);
       
  1843     ctxt->depth--;
       
  1844     return(ret);
       
  1845 }
       
  1846 #endif /* LIBXML_VALID_ENABLED */
       
  1847 
       
  1848 
       
  1849 /**
       
  1850  * xmlSAX2AttributeNs:
       
  1851  * @param ctx the user data (XML parser context)
       
  1852  * @param localname the local name of the attribute
       
  1853  * @param prefix the attribute namespace prefix if available
       
  1854  * @param URI the attribute namespace name if available
       
  1855  * @param value Start of the attribute value
       
  1856  * @param valueend end of the attribute value
       
  1857  *
       
  1858  * Handle an attribute that has been read by the parser.
       
  1859  * The default handling is to convert the attribute into an
       
  1860  * DOM subtree and past it in a new xmlAttr element added to
       
  1861  * the element.
       
  1862  */
       
  1863 static void
       
  1864 xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
       
  1865                    const xmlChar* localname,
       
  1866                    const xmlChar* prefix,
       
  1867                    const xmlChar* value,
       
  1868                    const xmlChar* valueend)
       
  1869 {
       
  1870 	LOAD_GS(ctxt)
       
  1871     xmlAttrPtr ret;
       
  1872     xmlNsPtr nameSpace = NULL;
       
  1873     xmlChar *dup = NULL;
       
  1874 
       
  1875     /*
       
  1876      * Note: if prefix == NULL, the attribute is not in the default namespace
       
  1877      */
       
  1878     if (prefix != NULL)
       
  1879         nameSpace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);
       
  1880 
       
  1881     /*
       
  1882      * allocate the node
       
  1883      */
       
  1884     if (ctxt->freeAttrs != NULL)
       
  1885     {
       
  1886         ret = ctxt->freeAttrs;
       
  1887         ctxt->freeAttrs = ret->next;
       
  1888         ctxt->freeAttrsNr--;
       
  1889         memset(ret, 0, sizeof(xmlAttr));
       
  1890         ret->type = XML_ATTRIBUTE_NODE;
       
  1891 
       
  1892         ret->parent = ctxt->node;
       
  1893         ret->doc = ctxt->myDoc;
       
  1894         ret->ns = nameSpace;
       
  1895 
       
  1896         if (ctxt->dictNames)
       
  1897             ret->name = localname;
       
  1898         else
       
  1899             ret->name = xmlStrdup(localname);
       
  1900 
       
  1901             
       
  1902         if (ctxt->node->properties == NULL) {
       
  1903             ctxt->node->properties = ret;
       
  1904         } else {
       
  1905             xmlAttrPtr prev = ctxt->node->properties;
       
  1906 
       
  1907             while (prev->next != NULL) prev = prev->next;
       
  1908             prev->next = ret;
       
  1909             ret->prev = prev;
       
  1910         }
       
  1911 
       
  1912         if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  1913             xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
       
  1914     } else {
       
  1915         if (ctxt->dictNames)
       
  1916             ret = xmlNewNsPropEatName(ctxt->node, nameSpace,
       
  1917                                       (xmlChar *) localname, NULL);
       
  1918         else
       
  1919             ret = xmlNewNsProp(ctxt->node, nameSpace, localname, NULL);
       
  1920         if (ret == NULL) {
       
  1921             ctxt->errNo = XML_ERR_NO_MEMORY;
       
  1922             ctxt->instate = XML_PARSER_EOF;
       
  1923             ctxt->disableSAX = 1;
       
  1924             return;
       
  1925         }
       
  1926     }
       
  1927 
       
  1928     if ((ctxt->replaceEntities == 0) && (!ctxt->html))
       
  1929     {
       
  1930         xmlNodePtr tmp;
       
  1931 
       
  1932         /*
       
  1933          * We know that if there is an entity reference, then
       
  1934          * the string has been dup'ed and terminates with 0
       
  1935          * otherwise with ' or "
       
  1936          */
       
  1937         if (*valueend != 0) {
       
  1938             tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
       
  1939 		    if(OOM_FLAG) 
       
  1940 		    	{
       
  1941 		    	xmlFree(dup);
       
  1942 		    	return;
       
  1943 		    	}
       
  1944             ret->children = tmp;
       
  1945             ret->last = tmp;
       
  1946             if (tmp != NULL) {
       
  1947             tmp->doc = ret->doc;
       
  1948             tmp->parent = (xmlNodePtr) ret;
       
  1949             }
       
  1950         } else {
       
  1951             ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value, valueend - value);
       
  1952             
       
  1953             tmp = ret->children;
       
  1954             while (tmp != NULL) {
       
  1955             tmp->parent = (xmlNodePtr) ret;
       
  1956             if (tmp->next == NULL)
       
  1957                 ret->last = tmp;
       
  1958             tmp = tmp->next;
       
  1959             }
       
  1960         }
       
  1961     } else if (value != NULL) {
       
  1962         xmlNodePtr tmp;
       
  1963 
       
  1964         tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
       
  1965         ret->children = tmp;
       
  1966         ret->last = tmp;
       
  1967         if (tmp != NULL) {
       
  1968             tmp->doc = ret->doc;
       
  1969             tmp->parent = (xmlNodePtr) ret;
       
  1970         }
       
  1971     }
       
  1972 
       
  1973 #ifdef LIBXML_VALID_ENABLED
       
  1974     if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
       
  1975         ctxt->myDoc && ctxt->myDoc->intSubset) {
       
  1976     /*
       
  1977      * If we don't substitute entities, the validation should be
       
  1978      * done on a value with replaced entities anyway.
       
  1979      */
       
  1980         if (!ctxt->replaceEntities) {
       
  1981         dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend);
       
  1982         if (dup == NULL) {
       
  1983             if (*valueend == 0) {
       
  1984             ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
       
  1985                     ctxt->myDoc, ctxt->node, ret, value);
       
  1986         } else {
       
  1987             /*
       
  1988              * That should already be normalized.
       
  1989              * cheaper to finally allocate here than duplicate
       
  1990              * entry points in the full validation code
       
  1991              */
       
  1992             dup = xmlStrndup(value, valueend - value);
       
  1993 
       
  1994             ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
       
  1995                     ctxt->myDoc, ctxt->node, ret, dup);
       
  1996         }
       
  1997         } else {
       
  1998             /*
       
  1999          * dup now contains a string of the flattened attribute
       
  2000          * content with entities substitued. Check if we need to
       
  2001          * apply an extra layer of normalization.
       
  2002          * It need to be done twice ... it's an extra burden related
       
  2003          * to the ability to keep references in attributes
       
  2004          */
       
  2005         if (ctxt->attsSpecial != NULL) {
       
  2006             xmlChar *nvalnorm;
       
  2007             xmlChar fn[50];
       
  2008             xmlChar *fullname;
       
  2009 
       
  2010             fullname = xmlBuildQName(localname, prefix, fn, 50);
       
  2011             if (fullname != NULL) {
       
  2012             ctxt->vctxt.valid = 1;
       
  2013                 nvalnorm = xmlValidCtxtNormalizeAttributeValue(
       
  2014                              &ctxt->vctxt, ctxt->myDoc,
       
  2015                      ctxt->node, fullname, dup);
       
  2016             if (ctxt->vctxt.valid != 1)
       
  2017                 ctxt->valid = 0;
       
  2018 
       
  2019             if ((fullname != fn) && (fullname != localname))
       
  2020                 xmlFree(fullname);
       
  2021             if (nvalnorm != NULL) {
       
  2022                 xmlFree(dup);
       
  2023                 dup = nvalnorm;
       
  2024             }
       
  2025             }
       
  2026         }
       
  2027 
       
  2028         ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
       
  2029                     ctxt->myDoc, ctxt->node, ret, dup);
       
  2030         }
       
  2031     } else {
       
  2032         /*
       
  2033          * if entities already have been substitued, then
       
  2034          * the attribute as passed is already normalized
       
  2035          */
       
  2036         dup = xmlStrndup(value, valueend - value);
       
  2037 
       
  2038         ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
       
  2039                                  ctxt->myDoc, ctxt->node, ret, dup);
       
  2040     }
       
  2041     } else
       
  2042 #endif /* LIBXML_VALID_ENABLED */
       
  2043            if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
       
  2044            (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
       
  2045             ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
       
  2046         /*
       
  2047      * when validating, the ID registration is done at the attribute
       
  2048      * validation level. Otherwise we have to do specific handling here.
       
  2049      */
       
  2050     if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
       
  2051         /* might be worth duplicate entry points and not copy */
       
  2052         if (dup == NULL)
       
  2053             dup = xmlStrndup(value, valueend - value);
       
  2054         xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
       
  2055     } else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
       
  2056         if (dup == NULL)
       
  2057             dup = xmlStrndup(value, valueend - value);
       
  2058         xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret);
       
  2059         } else if ((prefix == ctxt->str_xml) &&
       
  2060                (localname[0] == 'i') && (localname[1] == 'd') &&
       
  2061            (localname[2] == 0)) {
       
  2062         /*
       
  2063          * Add the xml:id value
       
  2064          *
       
  2065          * Open issue: normalization of the value.
       
  2066          */
       
  2067         if (dup == NULL)
       
  2068             dup = xmlStrndup(value, valueend - value);
       
  2069         if (xmlValidateNCName(dup, 1) != 0) {
       
  2070             xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
       
  2071               EMBED_ERRTXT("xml:id : attribute value %s is not an NCName\n"),
       
  2072                 (const char *) dup, NULL);
       
  2073         }
       
  2074         xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
       
  2075     }
       
  2076     }
       
  2077     if (dup != NULL)
       
  2078     xmlFree(dup);
       
  2079 }
       
  2080 
       
  2081 /**
       
  2082  * xmlSAX2StartElementNs:
       
  2083  * @param ctx the user data (XML parser context)
       
  2084  * @param localname the local name of the element
       
  2085  * @param prefix the element namespace prefix if available
       
  2086  * @param URI the element namespace name if available
       
  2087  * @param nb_namespaces number of namespace definitions on that node
       
  2088  * @param namespaces pointer to the array of prefix/URI pairs namespace definitions
       
  2089  * @param nb_attributes the number of attributes on that node
       
  2090  * @param nb_defaulted the number of defaulted attributes.
       
  2091  * @param attributes pointer to the array of (localname/prefix/URI/value/end)
       
  2092  *               attribute values.
       
  2093  *
       
  2094  * SAX2 callback when an element start has been detected by the parser.
       
  2095  * It provides the namespace informations for the element, as well as
       
  2096  * the new namespace declarations on the element.
       
  2097  */
       
  2098 XMLPUBFUNEXPORT void
       
  2099 xmlSAX2StartElementNs(void* ctx,
       
  2100                       const xmlChar *localname,
       
  2101                       const xmlChar *prefix,
       
  2102                       const xmlChar *URI,
       
  2103                       int nb_namespaces,
       
  2104                       const xmlChar **namespaces,
       
  2105                       int nb_attributes,
       
  2106                       int nb_defaulted,
       
  2107                       const xmlChar **attributes)
       
  2108 {
       
  2109 	xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
  2110     xmlNodePtr ret;
       
  2111     xmlNodePtr parent = ctxt->node;
       
  2112     xmlNsPtr last = NULL, ns;
       
  2113     const xmlChar *uri, *pref;
       
  2114     int i, j;
       
  2115 	LOAD_GS_SAFE_CTXT(ctxt)
       
  2116 	
       
  2117     
       
  2118     /*
       
  2119      * First check on validity:
       
  2120      */
       
  2121     if (ctxt->validate &&
       
  2122             (ctxt->myDoc->extSubset == NULL) &&
       
  2123                ((ctxt->myDoc->intSubset == NULL)
       
  2124                     ||
       
  2125                 ((ctxt->myDoc->intSubset->notations == NULL) &&
       
  2126                  (ctxt->myDoc->intSubset->elements  == NULL) &&
       
  2127                  (ctxt->myDoc->intSubset->attributes == NULL)&&
       
  2128                  (ctxt->myDoc->intSubset->entities  == NULL)
       
  2129                  )
       
  2130              )
       
  2131         )
       
  2132     {
       
  2133         xmlErrValid(ctxt, XML_ERR_NO_DTD, EMBED_ERRTXT("Validation failed: no DTD found !"), NULL, NULL);
       
  2134         ctxt->validate = 0;
       
  2135     }
       
  2136 
       
  2137     /*
       
  2138      * allocate the node
       
  2139      */
       
  2140     if (ctxt->freeElems != NULL) {
       
  2141         ret = ctxt->freeElems;
       
  2142         ctxt->freeElems = ret->next;
       
  2143         ctxt->freeElemsNr--;
       
  2144         memset(ret, 0, sizeof(xmlNode));
       
  2145         ret->type = XML_ELEMENT_NODE;
       
  2146 
       
  2147         if (ctxt->dictNames)
       
  2148             ret->name = localname;
       
  2149         else
       
  2150             ret->name = xmlStrdup(localname); 
       
  2151 
       
  2152         if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  2153             xmlRegisterNodeDefaultValue(ret);
       
  2154     } else {
       
  2155         if (ctxt->dictNames)
       
  2156             ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
       
  2157                                        (xmlChar *) localname, NULL);
       
  2158         else
       
  2159             ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
       
  2160 
       
  2161         if (ret == NULL) {
       
  2162             ctxt->errNo = XML_ERR_NO_MEMORY;
       
  2163             ctxt->instate = XML_PARSER_EOF;
       
  2164             ctxt->disableSAX = 1;
       
  2165             return;
       
  2166         }
       
  2167     }
       
  2168 #ifdef LIBXML_ENABLE_NODE_LINEINFO
       
  2169     if (ctxt->linenumbers) {
       
  2170         if (ctxt->input != NULL) {
       
  2171             if (ctxt->input->line < 65535)
       
  2172                 ret->line = (short) ctxt->input->line;
       
  2173             else
       
  2174                 ret->line = 65535;
       
  2175         }
       
  2176     }
       
  2177 #endif
       
  2178 
       
  2179     if (ctxt->myDoc->children == NULL) {
       
  2180         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
       
  2181     } else if (parent == NULL) {
       
  2182         parent = ctxt->myDoc->children;
       
  2183     }
       
  2184     /*
       
  2185      * Build the namespace list
       
  2186      */
       
  2187     for (i = 0,j = 0;j < nb_namespaces;j++)
       
  2188     {
       
  2189         pref = namespaces[i++];
       
  2190         uri = namespaces[i++];
       
  2191         // NULL passed in order to avoid uniqueness check in xmlNewNs(),
       
  2192         ns = xmlNewNs(NULL, uri, pref);
       
  2193         // ... but then we need to link new Ns node manually
       
  2194         if (ns != NULL) {
       
  2195             if (last == NULL) {
       
  2196                 ret->nsDef = last = ns;
       
  2197             } else {
       
  2198                 last->next = ns;
       
  2199                 last = ns;
       
  2200             }
       
  2201             if ((URI != NULL) && (prefix == pref))
       
  2202                 ret->ns = ns;
       
  2203         } else {
       
  2204             ctxt->errNo = XML_ERR_NO_MEMORY;
       
  2205             ctxt->instate = XML_PARSER_EOF;
       
  2206             ctxt->disableSAX = 1;
       
  2207             //DONE: OOM: cleanup:
       
  2208             if(ctxt->myDoc->children != ret)
       
  2209                 xmlFreeNode(ret); // it was not yet inserted in myDoc
       
  2210             return;
       
  2211         }
       
  2212 #ifdef LIBXML_VALID_ENABLED
       
  2213         if (ctxt->validate && (!ctxt->html) && ctxt->wellFormed &&
       
  2214             ctxt->myDoc && ctxt->myDoc->intSubset)
       
  2215         {
       
  2216             ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
       
  2217                                                    ret, prefix, ns, uri);
       
  2218         }
       
  2219 #endif /* LIBXML_VALID_ENABLED */
       
  2220     } // for (i = 0,j = 0;j < nb_namespaces;j++)
       
  2221 
       
  2222     ctxt->nodemem = -1;
       
  2223 
       
  2224     /*
       
  2225      * We are parsing a new node.
       
  2226      */
       
  2227     nodePush(ctxt, ret); 
       
  2228 
       
  2229     /*
       
  2230      * Link the child element
       
  2231      */
       
  2232     if (parent != NULL) {
       
  2233         if (parent->type == XML_ELEMENT_NODE) {
       
  2234             xmlAddChild(parent, ret);
       
  2235         } else {
       
  2236             xmlAddSibling(parent, ret);
       
  2237         }
       
  2238     }
       
  2239 
       
  2240     /*
       
  2241      * Insert the defaulted attributes from the DTD only if requested:
       
  2242      */
       
  2243     if ((nb_defaulted != 0) &&
       
  2244         ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0))
       
  2245     {
       
  2246         nb_attributes -= nb_defaulted;
       
  2247     }
       
  2248 
       
  2249     /*
       
  2250      * Search the namespace if it wasn't already found
       
  2251      */
       
  2252     if ((URI != NULL) && (ret->ns == NULL)) {
       
  2253         ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
       
  2254         if (ret->ns == NULL) {
       
  2255             ns = xmlNewNs(ret, NULL, prefix);
       
  2256             if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
       
  2257             ctxt->sax->warning(ctxt->userData,
       
  2258                  EMBED_ERRTXT("Namespace prefix %s was not found\n"), prefix);
       
  2259         }
       
  2260     }
       
  2261 
       
  2262     /*
       
  2263      * process all the other attributes
       
  2264      */
       
  2265         if (nb_attributes > 0) {
       
  2266             for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
       
  2267             
       
  2268             xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
       
  2269                                attributes[j+3], attributes[j+4]);  
       
  2270 		    if(OOM_FLAG) 
       
  2271 		    	{
       
  2272 		    	return;
       
  2273 		    	}                               
       
  2274         }
       
  2275     }
       
  2276 
       
  2277 #ifdef LIBXML_VALID_ENABLED
       
  2278     /*
       
  2279      * If it's the Document root, finish the DTD validation and
       
  2280      * check the document root element for validity
       
  2281      */
       
  2282     if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
       
  2283     int chk;
       
  2284 
       
  2285     chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
       
  2286     if (chk <= 0)
       
  2287         ctxt->valid = 0;
       
  2288     if (chk < 0)
       
  2289         ctxt->wellFormed = 0;
       
  2290     ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
       
  2291     ctxt->vctxt.finishDtd = 1;
       
  2292     }
       
  2293 #endif /* LIBXML_VALID_ENABLED */
       
  2294 }
       
  2295 
       
  2296 /**
       
  2297  * xmlSAX2EndElementNs:
       
  2298  * @param ctx the user data (XML parser context)
       
  2299  * @param localname the local name of the element
       
  2300  * @param prefix the element namespace prefix if available
       
  2301  * @param URI the element namespace name if available
       
  2302  *
       
  2303  * SAX2 callback when an element end has been detected by the parser.
       
  2304  * It provides the namespace informations for the element.
       
  2305  */
       
  2306 
       
  2307 XMLPUBFUNEXPORT void
       
  2308 xmlSAX2EndElementNs(void *ctx,
       
  2309                     const xmlChar * localname ATTRIBUTE_UNUSED,
       
  2310                     const xmlChar * prefix ATTRIBUTE_UNUSED,
       
  2311             const xmlChar * URI ATTRIBUTE_UNUSED)
       
  2312 {
       
  2313     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
  2314 #if defined(LIBXML_VALID_ENABLED) || defined(XMLENGINE_ENABLE_PARSER_RECORD_INFO)
       
  2315     xmlNodePtr cur = ctxt->node;
       
  2316 #endif
       
  2317 
       
  2318 #ifdef XMLENGINE_ENABLE_PARSER_RECORD_INFO
       
  2319     {
       
  2320     xmlParserNodeInfo node_info;
       
  2321 
       
  2322     /* Capture end position and add node */
       
  2323     if ((ctxt->record_info) && (cur != NULL)) {
       
  2324         node_info.end_pos = ctxt->input->cur - ctxt->input->base;
       
  2325         node_info.end_line = ctxt->input->line;
       
  2326         node_info.node = cur;
       
  2327         xmlParserAddNodeInfo(ctxt, &node_info);
       
  2328     }
       
  2329     }
       
  2330 #endif
       
  2331 
       
  2332     ctxt->nodemem = -1;
       
  2333 
       
  2334 #ifdef LIBXML_VALID_ENABLED
       
  2335     if (ctxt->validate && ctxt->wellFormed &&
       
  2336         ctxt->myDoc && ctxt->myDoc->intSubset)
       
  2337         ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur);
       
  2338 #endif /* LIBXML_VALID_ENABLED */
       
  2339 
       
  2340     /*
       
  2341      * end of parsing of this node.
       
  2342      */
       
  2343     nodePop(ctxt);
       
  2344 }
       
  2345 
       
  2346 /**
       
  2347  * xmlSAX2Reference:
       
  2348  * @param ctx the user data (XML parser context)
       
  2349  * @param name The entity name
       
  2350  *
       
  2351  * called when an entity xmlSAX2Reference is detected.
       
  2352  */
       
  2353 XMLPUBFUNEXPORT void
       
  2354 xmlSAX2Reference(void *ctx, const xmlChar *name)
       
  2355 {
       
  2356     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
  2357     xmlNodePtr ret;
       
  2358 
       
  2359 #ifdef DEBUG_SAX
       
  2360     xmlGenericError(xmlGenericErrorContext,
       
  2361         "SAX.xmlSAX2Reference(%s)\n", name);
       
  2362 #endif
       
  2363     if (name[0] == '#')
       
  2364         ret = xmlNewCharRef(ctxt->myDoc, name);
       
  2365     else
       
  2366         ret = xmlNewReference(ctxt->myDoc, name);
       
  2367 #ifdef DEBUG_SAX_TREE
       
  2368     xmlGenericError(xmlGenericErrorContext,
       
  2369         "add xmlSAX2Reference %s to %s \n", name, ctxt->node->name);
       
  2370 #endif
       
  2371     xmlAddChild(ctxt->node, ret);
       
  2372 }
       
  2373 
       
  2374 /**
       
  2375  * xmlSAX2Characters:
       
  2376  * @param ctx the user data (XML parser context)
       
  2377  * @param ch a xmlChar string
       
  2378  * @param len the number of xmlChar
       
  2379  *
       
  2380  * receiving some chars from the parser.
       
  2381  */
       
  2382 XMLPUBFUNEXPORT void
       
  2383 xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
       
  2384 {
       
  2385     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
  2386     xmlNodePtr lastChild;
       
  2387 
       
  2388 	/*
       
  2389 	 *   SYMBIAN DEF130695 FIX : Ensuring that CTX(xml buffer context) is valid or not. The CTX is being considered 
       
  2390      *                           here while receiving parsed characters using SAX parsing mechanism.	       
       
  2391 	 */
       
  2392 	if(ctx == NULL)
       
  2393 		return;
       
  2394 
       
  2395 
       
  2396 #ifdef DEBUG_SAX
       
  2397     xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len);
       
  2398 #endif
       
  2399     /*
       
  2400      * Handle the data if any. If there is no child
       
  2401      * add it as content, otherwise if the last child is text,
       
  2402      * concatenate it, else create a new node of type text.
       
  2403      */
       
  2404 
       
  2405     if (ctxt->node == NULL) {
       
  2406 #ifdef DEBUG_SAX_TREE
       
  2407         xmlGenericError(xmlGenericErrorContext, "add chars: ctxt->node == NULL !\n");
       
  2408 #endif
       
  2409         return;
       
  2410     }
       
  2411     lastChild = ctxt->node->last;
       
  2412 #ifdef DEBUG_SAX_TREE
       
  2413     xmlGenericError(xmlGenericErrorContext, "add chars to %s \n", ctxt->node->name);
       
  2414 #endif
       
  2415 
       
  2416     /*
       
  2417      * Here we needed an accelerator mechanism in case of very large
       
  2418      * elements. Use an attribute in the structure !!!
       
  2419      */
       
  2420     if (lastChild == NULL) {
       
  2421         lastChild = xmlSAX2TextNode(ctxt, ch, len);
       
  2422         
       
  2423         if (lastChild != NULL) {
       
  2424             ctxt->node->children = lastChild;
       
  2425             ctxt->node->last = lastChild;
       
  2426             lastChild->parent = ctxt->node;
       
  2427             lastChild->doc = ctxt->node->doc;
       
  2428             ctxt->nodelen = len;
       
  2429             ctxt->nodemem = len + 1;
       
  2430         }
       
  2431     } else {
       
  2432     int coalesceText = (lastChild != NULL) &&
       
  2433         (lastChild->type == XML_TEXT_NODE) &&
       
  2434         (lastChild->name == xmlStringText);
       
  2435     if ((coalesceText) && (ctxt->nodemem != 0)) {
       
  2436         /*
       
  2437          * The whole point of maintaining nodelen and nodemem,
       
  2438          * xmlTextConcat is too costly, i.e. compute length,
       
  2439          * reallocate a new buffer, move data, append ch. Here
       
  2440          * We try to minimaze realloc() uses and avoid copying
       
  2441          * and recomputing length over and over.
       
  2442          */
       
  2443         if ((ctxt->nodemem == ctxt->nodelen + 1) &&
       
  2444             (xmlDictOwns(ctxt->dict, lastChild->content)))
       
  2445         {
       
  2446             lastChild->content = xmlStrdup(lastChild->content);
       
  2447         }
       
  2448         if (ctxt->nodelen + len >= ctxt->nodemem) {
       
  2449             xmlChar *newbuf;
       
  2450             int size;
       
  2451 
       
  2452             size = ctxt->nodemem + len;
       
  2453             size *= 2;
       
  2454             newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
       
  2455             if (newbuf == NULL) {
       
  2456                 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
  2457                     ctxt->sax->error(ctxt->userData, EMBED_ERRTXT("SAX.xmlSAX2Characters(): out of memory\n"));
       
  2458                 ctxt->errNo = XML_ERR_NO_MEMORY;
       
  2459                 ctxt->instate = XML_PARSER_EOF;
       
  2460                 ctxt->disableSAX = 1;
       
  2461                 return;
       
  2462             }
       
  2463             ctxt->nodemem = size;
       
  2464             lastChild->content = newbuf;
       
  2465         }
       
  2466         memcpy(&lastChild->content[ctxt->nodelen], ch, len);
       
  2467         ctxt->nodelen += len;
       
  2468         lastChild->content[ctxt->nodelen] = 0;
       
  2469     } else if (coalesceText) {
       
  2470         if (xmlTextConcat(lastChild, ch, len)) {
       
  2471             if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
       
  2472                 ctxt->sax->error(ctxt->userData, EMBED_ERRTXT("SAX.xmlSAX2Characters(): out of memory\n"));
       
  2473             ctxt->errNo = XML_ERR_NO_MEMORY;
       
  2474             ctxt->instate = XML_PARSER_EOF;
       
  2475             ctxt->disableSAX = 1;
       
  2476         }
       
  2477         if (ctxt->node->children != NULL) {
       
  2478             ctxt->nodelen = xmlStrlen(lastChild->content);
       
  2479             ctxt->nodemem = ctxt->nodelen + 1;
       
  2480         }
       
  2481     } else {
       
  2482         /* Mixed content, first time */
       
  2483         lastChild = xmlSAX2TextNode(ctxt, ch, len);
       
  2484         if (lastChild != NULL) {
       
  2485             xmlAddChild(ctxt->node, lastChild);
       
  2486             if (ctxt->node->children != NULL) {
       
  2487                 ctxt->nodelen = len;
       
  2488                 ctxt->nodemem = len + 1;
       
  2489             }
       
  2490         }
       
  2491     }
       
  2492     }
       
  2493 }
       
  2494 
       
  2495 /**
       
  2496  * xmlSAX2IgnorableWhitespace:
       
  2497  * @param ctx the user data (XML parser context)
       
  2498  * @param ch a xmlChar string
       
  2499  * @param len the number of xmlChar
       
  2500  *
       
  2501  * receiving some ignorable whitespaces from the parser.
       
  2502  * UNUSED: by default the DOM building will use xmlSAX2Characters
       
  2503  */
       
  2504 XMLPUBFUNEXPORT void
       
  2505 xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
       
  2506 {
       
  2507     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
       
  2508 #ifdef DEBUG_SAX
       
  2509     xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len);
       
  2510 #endif
       
  2511     if(ctx) return; // just to use ctx
       
  2512 }
       
  2513 
       
  2514 /**
       
  2515  * xmlSAX2ProcessingInstruction:
       
  2516  * @param ctx the user data (XML parser context)
       
  2517  * @param target the target name
       
  2518  * @param data the PI data's
       
  2519  *
       
  2520  * A processing instruction has been parsed.
       
  2521  */
       
  2522 XMLPUBFUNEXPORT void
       
  2523 xmlSAX2ProcessingInstruction(void *ctx,
       
  2524                              const xmlChar *target,
       
  2525                              const xmlChar *data)
       
  2526 {
       
  2527     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
  2528     xmlNodePtr ret;
       
  2529     xmlNodePtr parent = ctxt->node;
       
  2530 
       
  2531 #ifdef DEBUG_SAX
       
  2532     xmlGenericError(xmlGenericErrorContext,
       
  2533         "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data);
       
  2534 #endif
       
  2535 
       
  2536     ret = xmlNewPI(target, data);
       
  2537     if (!ret)
       
  2538         return;
       
  2539     parent = ctxt->node;
       
  2540 
       
  2541     if (ctxt->inSubset == 1) {
       
  2542         xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
       
  2543         return;
       
  2544     } else
       
  2545     if (ctxt->inSubset == 2) {
       
  2546         xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
       
  2547         return;
       
  2548     }
       
  2549     if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
       
  2550 #ifdef DEBUG_SAX_TREE
       
  2551         xmlGenericError(xmlGenericErrorContext,"Setting PI %s as root\n", target);
       
  2552 #endif
       
  2553         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
       
  2554         return;
       
  2555     }
       
  2556     if (parent->type == XML_ELEMENT_NODE) {
       
  2557 #ifdef DEBUG_SAX_TREE
       
  2558         xmlGenericError(xmlGenericErrorContext,
       
  2559             "adding PI %s child to %s\n", target, parent->name);
       
  2560 #endif
       
  2561         xmlAddChild(parent, ret);
       
  2562     } else {
       
  2563 #ifdef DEBUG_SAX_TREE
       
  2564         xmlGenericError(xmlGenericErrorContext, "adding PI %s sibling to ", target);
       
  2565         xmlDebugDumpOneNode(stderr, parent, 0);
       
  2566 #endif
       
  2567         xmlAddSibling(parent, ret);
       
  2568     }
       
  2569 }
       
  2570 
       
  2571 /**
       
  2572  * xmlSAX2Comment:
       
  2573  * @param ctx the user data (XML parser context)
       
  2574  * @param value the xmlSAX2Comment content
       
  2575  *
       
  2576  * A xmlSAX2Comment has been parsed.
       
  2577  */
       
  2578 XMLPUBFUNEXPORT void
       
  2579 xmlSAX2Comment(void *ctx, const xmlChar *value)
       
  2580 {
       
  2581     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
  2582     xmlNodePtr ret;
       
  2583     xmlNodePtr parent = ctxt->node;
       
  2584 
       
  2585 #ifdef DEBUG_SAX
       
  2586     xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value);
       
  2587 #endif
       
  2588     ret = xmlNewDocComment(ctxt->myDoc, value);
       
  2589     if (ret == NULL) return;
       
  2590 
       
  2591     
       
  2592     if (ctxt->inSubset == 1) {
       
  2593         xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
       
  2594         return;
       
  2595     } else if (ctxt->inSubset == 2) {
       
  2596         xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
       
  2597         return;
       
  2598     }
       
  2599     if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
       
  2600 #ifdef DEBUG_SAX_TREE
       
  2601         xmlGenericError(xmlGenericErrorContext,
       
  2602             "Setting xmlSAX2Comment as root\n");
       
  2603 #endif
       
  2604         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
       
  2605         return;
       
  2606     }
       
  2607     if (parent->type == XML_ELEMENT_NODE) {
       
  2608 #ifdef DEBUG_SAX_TREE
       
  2609         xmlGenericError(xmlGenericErrorContext,
       
  2610             "adding xmlSAX2Comment child to %s\n", parent->name);
       
  2611 #endif
       
  2612         xmlAddChild(parent, ret);
       
  2613     } else {
       
  2614 #ifdef DEBUG_SAX_TREE
       
  2615         xmlGenericError(xmlGenericErrorContext,
       
  2616             "adding xmlSAX2Comment sibling to ");
       
  2617         xmlDebugDumpOneNode(stderr, parent, 0);
       
  2618 #endif
       
  2619         xmlAddSibling(parent, ret);
       
  2620     }
       
  2621 }
       
  2622 
       
  2623 /**
       
  2624  * xmlSAX2CDataBlock:
       
  2625  * @param ctx the user data (XML parser context)
       
  2626  * @param value The pcdata content
       
  2627  * @param len the block length
       
  2628  *
       
  2629  * called when a pcdata block has been parsed
       
  2630  */
       
  2631 XMLPUBFUNEXPORT void
       
  2632 xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
       
  2633 {
       
  2634     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
       
  2635     xmlNodePtr ret, lastChild;
       
  2636 
       
  2637 #ifdef DEBUG_SAX
       
  2638     xmlGenericError(xmlGenericErrorContext,"SAX.pcdata(%.10s, %d)\n", value, len);
       
  2639 #endif
       
  2640     lastChild = xmlGetLastChild(ctxt->node);
       
  2641 #ifdef DEBUG_SAX_TREE
       
  2642     xmlGenericError(xmlGenericErrorContext,"add chars to %s \n", ctxt->node->name);
       
  2643 #endif
       
  2644     if ((lastChild != NULL) &&
       
  2645         (lastChild->type == XML_CDATA_SECTION_NODE))
       
  2646     {
       
  2647         xmlTextConcat(lastChild, value, len);
       
  2648     } else {
       
  2649         ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
       
  2650         xmlAddChild(ctxt->node, ret);
       
  2651     }
       
  2652 }
       
  2653 
       
  2654 #ifdef LIBXML_SAX1_ENABLED
       
  2655 /**
       
  2656  * xmlSAXDefaultVersion:
       
  2657  * @param version the version, 1 or 2
       
  2658  *
       
  2659  * Set the default version of SAX used globally by the library.
       
  2660  * Note that this may not be a good thing to do from a library
       
  2661  * it is better to use xmlSAXVersion() to set up specifically the
       
  2662  * version for a given parsing context.
       
  2663  *
       
  2664  * Returns the previous value in case of success and -1 in case of error.
       
  2665  */
       
  2666 XMLPUBFUNEXPORT int
       
  2667 xmlSAXDefaultVersion(int version)
       
  2668 {
       
  2669 	LOAD_GS_DIRECT
       
  2670     int ret = xmlSAX2DefaultVersionValue;
       
  2671 
       
  2672     if ((version != 1) && (version != 2))
       
  2673         return(-1);
       
  2674     xmlSAX2DefaultVersionValue = version;
       
  2675     return(ret);
       
  2676 }
       
  2677 #endif /* LIBXML_SAX1_ENABLED */
       
  2678 
       
  2679 /**
       
  2680  * xmlSAXVersion:
       
  2681  * @param hdlr the SAX handler
       
  2682  * @param version the version, 1 or 2
       
  2683  *
       
  2684  * Initialize the default XML SAX handler according to the version
       
  2685  *
       
  2686  * Returns 0 in case of success and -1 in case of error.
       
  2687  *
       
  2688  * OOM: never
       
  2689  */
       
  2690 XMLPUBFUNEXPORT int
       
  2691 xmlSAXVersion(xmlSAXHandler *hdlr, int version)
       
  2692 {
       
  2693     if (hdlr == NULL) return(-1);
       
  2694     if (version == 2) {
       
  2695         hdlr->startElement = NULL;
       
  2696         hdlr->endElement = NULL;
       
  2697         hdlr->startElementNs = xmlSAX2StartElementNs;
       
  2698         hdlr->endElementNs = xmlSAX2EndElementNs;
       
  2699         hdlr->serror = NULL;
       
  2700         hdlr->initialized = XML_SAX2_MAGIC;
       
  2701 #ifdef LIBXML_SAX1_ENABLED
       
  2702     } else if (version == 1) {
       
  2703         hdlr->startElement = xmlSAX2StartElement;
       
  2704         hdlr->endElement = xmlSAX2EndElement;
       
  2705         hdlr->initialized = 1;
       
  2706 #endif /* LIBXML_SAX1_ENABLED */
       
  2707     } else
       
  2708         return(-1);
       
  2709     hdlr->internalSubset = xmlSAX2InternalSubset;
       
  2710     hdlr->externalSubset = xmlSAX2ExternalSubset;
       
  2711     hdlr->isStandalone = xmlSAX2IsStandalone;
       
  2712     hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
       
  2713     hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
       
  2714     hdlr->resolveEntity = xmlSAX2ResolveEntity;
       
  2715     hdlr->getEntity = xmlSAX2GetEntity;
       
  2716     hdlr->getParameterEntity = xmlSAX2GetParameterEntity;
       
  2717     hdlr->entityDecl = xmlSAX2EntityDecl;
       
  2718     hdlr->attributeDecl = xmlSAX2AttributeDecl;
       
  2719     hdlr->elementDecl = xmlSAX2ElementDecl;
       
  2720     hdlr->notationDecl = xmlSAX2NotationDecl;
       
  2721     hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl;
       
  2722     hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
       
  2723     hdlr->startDocument = xmlSAX2StartDocument;
       
  2724     hdlr->endDocument = xmlSAX2EndDocument;
       
  2725     hdlr->reference = xmlSAX2Reference;
       
  2726     hdlr->characters = xmlSAX2Characters;
       
  2727     hdlr->cdataBlock = xmlSAX2CDataBlock;
       
  2728     hdlr->ignorableWhitespace = xmlSAX2Characters;
       
  2729     hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
       
  2730     hdlr->comment = xmlSAX2Comment;
       
  2731 // XMLENGINE: MODIFIED CODE
       
  2732 // preprocessor directive is used for managing error callbacks
       
  2733 #ifdef _DEBUG_LIBXML
       
  2734     hdlr->warning = xmlParserWarning;
       
  2735     hdlr->error = xmlParserError;
       
  2736     hdlr->fatalError = xmlParserError;
       
  2737 #else
       
  2738     hdlr->warning = NULL;
       
  2739     hdlr->error = NULL;
       
  2740     hdlr->fatalError = NULL;
       
  2741 #endif
       
  2742 // XMLENGINE: BEGINE NEW CODE
       
  2743     // These should be nullified for DOMParser
       
  2744     hdlr->startPrefixMapping = NULL;
       
  2745     hdlr->endPrefixMapping = NULL;
       
  2746 // XMLENGINE: END NEW CODE
       
  2747 
       
  2748     return(0);
       
  2749 }
       
  2750 
       
  2751 #ifdef LIBXML_HTML_ENABLED
       
  2752 /**
       
  2753  * xmlSAX2InitHtmlDefaultSAXHandler:
       
  2754  * @param hdlr the SAX handler
       
  2755  *
       
  2756  * Initialize the default HTML SAX2 handler
       
  2757  */
       
  2758 void
       
  2759 xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr)
       
  2760 {
       
  2761     if(hdlr->initialized != 0)
       
  2762     return;
       
  2763 
       
  2764     hdlr->internalSubset = xmlSAX2InternalSubset;
       
  2765     hdlr->externalSubset = NULL;
       
  2766     hdlr->isStandalone = NULL;
       
  2767     hdlr->hasInternalSubset = NULL;
       
  2768     hdlr->hasExternalSubset = NULL;
       
  2769     hdlr->resolveEntity = NULL;
       
  2770     hdlr->getEntity = xmlSAX2GetEntity;
       
  2771     hdlr->getParameterEntity = NULL;
       
  2772     hdlr->entityDecl = NULL;
       
  2773     hdlr->attributeDecl = NULL;
       
  2774     hdlr->elementDecl = NULL;
       
  2775     hdlr->notationDecl = NULL;
       
  2776     hdlr->unparsedEntityDecl = NULL;
       
  2777     hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
       
  2778     hdlr->startDocument = xmlSAX2StartDocument;
       
  2779     hdlr->endDocument = xmlSAX2EndDocument;
       
  2780     hdlr->startElement = xmlSAX2StartElement;
       
  2781     hdlr->endElement = xmlSAX2EndElement;
       
  2782     hdlr->reference = NULL;
       
  2783     hdlr->characters = xmlSAX2Characters;
       
  2784     hdlr->cdataBlock = xmlSAX2CDataBlock;
       
  2785     hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
       
  2786     hdlr->processingInstruction = NULL;
       
  2787     hdlr->comment = xmlSAX2Comment;
       
  2788     hdlr->warning = xmlParserWarning;
       
  2789     hdlr->error = xmlParserError;
       
  2790     hdlr->fatalError = xmlParserError;
       
  2791 
       
  2792     hdlr->initialized = 1;
       
  2793 }
       
  2794 
       
  2795 
       
  2796 /**
       
  2797  * htmlDefaultSAXHandlerInit:
       
  2798  *
       
  2799  * Initialize the default SAX handler
       
  2800  */
       
  2801 void
       
  2802 htmlDefaultSAXHandlerInit(void)
       
  2803 {
       
  2804 // XMLENGINE: disabled: HTML is never parsed
       
  2805 //    xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr) &htmlDefaultSAXHandler);
       
  2806 }
       
  2807 #endif
       
  2808 
       
  2809 
       
  2810 /**
       
  2811  * xmlSAX2InitDefaultSAXHandler:
       
  2812  * @param hdlr the SAX handler
       
  2813  * @param warning flag if non-zero sets the handler warning procedure
       
  2814  *
       
  2815  * Initialize the default XML SAX2 handler
       
  2816  */
       
  2817 XMLPUBFUNEXPORT void
       
  2818 xmlSAX2InitDefaultSAXHandler(xmlSAXHandler* hdlr, int warning)
       
  2819 {
       
  2820 	LOAD_GS_DIRECT
       
  2821     if ((hdlr == NULL) || (hdlr->initialized != 0))
       
  2822         return;
       
  2823 
       
  2824     xmlSAXVersion(hdlr, xmlSAX2DefaultVersionValue);
       
  2825     // Note: hdlr->warning is NULL after previous line
       
  2826    if(warning)
       
  2827     hdlr->warning = xmlParserWarning;
       
  2828 }
       
  2829 
       
  2830 /**
       
  2831  * xmlDefaultSAXHandlerInit:
       
  2832  *
       
  2833  * Initialize the default SAX2 handler
       
  2834  *
       
  2835  * OOM: never
       
  2836  */
       
  2837 XMLPUBFUNEXPORT void
       
  2838 xmlDefaultSAXHandlerInit(void)
       
  2839 {
       
  2840 #ifdef XMLENGINE_SAX1
       
  2841 #ifdef LIBXML_SAX1_ENABLED
       
  2842     xmlSAXVersion((xmlSAXHandlerPtr) &xmlDefaultSAXHandler, 1);
       
  2843 #endif /* LIBXML_SAX1_ENABLED */
       
  2844 #endif
       
  2845 }
       
  2846 
       
  2847 
       
  2848 #ifdef LIBXML_DOCB_ENABLED
       
  2849 
       
  2850 /**
       
  2851  * xmlSAX2InitDocbDefaultSAXHandler:
       
  2852  * @param hdlr the SAX handler
       
  2853  *
       
  2854  * Initialize the default DocBook SAX2 handler
       
  2855  */
       
  2856 void
       
  2857 xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler *hdlr)
       
  2858 {
       
  2859     if(hdlr->initialized != 0)
       
  2860     return;
       
  2861 
       
  2862     hdlr->internalSubset = xmlSAX2InternalSubset;
       
  2863     hdlr->externalSubset = NULL;
       
  2864     hdlr->isStandalone = xmlSAX2IsStandalone;
       
  2865     hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
       
  2866     hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
       
  2867     hdlr->resolveEntity = xmlSAX2ResolveEntity;
       
  2868     hdlr->getEntity = xmlSAX2GetEntity;
       
  2869     hdlr->getParameterEntity = NULL;
       
  2870     hdlr->entityDecl = xmlSAX2EntityDecl;
       
  2871     hdlr->attributeDecl = NULL;
       
  2872     hdlr->elementDecl = NULL;
       
  2873     hdlr->notationDecl = NULL;
       
  2874     hdlr->unparsedEntityDecl = NULL;
       
  2875     hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
       
  2876     hdlr->startDocument = xmlSAX2StartDocument;
       
  2877     hdlr->endDocument = xmlSAX2EndDocument;
       
  2878     hdlr->startElement = xmlSAX2StartElement;
       
  2879     hdlr->endElement = xmlSAX2EndElement;
       
  2880     hdlr->reference = xmlSAX2Reference;
       
  2881     hdlr->characters = xmlSAX2Characters;
       
  2882     hdlr->cdataBlock = NULL;
       
  2883     hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
       
  2884     hdlr->processingInstruction = NULL;
       
  2885     hdlr->comment = xmlSAX2Comment;
       
  2886     hdlr->warning = xmlParserWarning;
       
  2887     hdlr->error = xmlParserError;
       
  2888     hdlr->fatalError = xmlParserError;
       
  2889 
       
  2890     hdlr->initialized = 1;
       
  2891 }
       
  2892 
       
  2893 /**
       
  2894  * docbDefaultSAXHandlerInit:
       
  2895  *
       
  2896  * Initialize the default SAX handler
       
  2897  */
       
  2898 void
       
  2899 docbDefaultSAXHandlerInit(void)
       
  2900 {
       
  2901     xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr) &docbDefaultSAXHandler);
       
  2902 }
       
  2903 
       
  2904 #endif /* LIBXML_DOCB_ENABLED */
       
  2905