ReactOS Fundraising Campaign 2012
 
€ 3,873 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

SAX2.c
Go to the documentation of this file.
00001 /*
00002  * SAX2.c : Default SAX2 handler to build a tree.
00003  *
00004  * See Copyright for the status of this software.
00005  *
00006  * Daniel Veillard <daniel@veillard.com>
00007  */
00008 
00009 
00010 #define IN_LIBXML
00011 #include "libxml.h"
00012 #include <stdlib.h>
00013 #include <string.h>
00014 #include <limits.h>
00015 #include <libxml/xmlmemory.h>
00016 #include <libxml/tree.h>
00017 #include <libxml/parser.h>
00018 #include <libxml/parserInternals.h>
00019 #include <libxml/valid.h>
00020 #include <libxml/entities.h>
00021 #include <libxml/xmlerror.h>
00022 #include <libxml/debugXML.h>
00023 #include <libxml/xmlIO.h>
00024 #include <libxml/SAX.h>
00025 #include <libxml/uri.h>
00026 #include <libxml/valid.h>
00027 #include <libxml/HTMLtree.h>
00028 #include <libxml/globals.h>
00029 
00030 /* Define SIZE_T_MAX unless defined through <limits.h>. */
00031 #ifndef SIZE_T_MAX
00032 # define SIZE_T_MAX     ((size_t)-1)
00033 #endif /* !SIZE_T_MAX */
00034 
00035 /* #define DEBUG_SAX2 */
00036 /* #define DEBUG_SAX2_TREE */
00037 
00048 #define TODO                                \
00049     xmlGenericError(xmlGenericErrorContext,             \
00050         "Unimplemented block at %s:%d\n",               \
00051             __FILE__, __LINE__);
00052 
00053 /*
00054  * xmlSAX2ErrMemory:
00055  * @ctxt:  an XML validation parser context
00056  * @msg:   a string to accompany the error message
00057  */
00058 static void
00059 xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
00060     if (ctxt != NULL) {
00061     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
00062         ctxt->sax->error(ctxt->userData, "%s: out of memory\n", msg);
00063     ctxt->errNo = XML_ERR_NO_MEMORY;
00064     ctxt->instate = XML_PARSER_EOF;
00065     ctxt->disableSAX = 1;
00066     }
00067 }
00068 
00079 static void
00080 xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
00081             const char *msg, const char *str1, const char *str2)
00082 {
00083     xmlStructuredErrorFunc schannel = NULL;
00084 
00085     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
00086         (ctxt->instate == XML_PARSER_EOF))
00087     return;
00088     if (ctxt != NULL) {
00089     ctxt->errNo = error;
00090     if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
00091         schannel = ctxt->sax->serror;
00092     __xmlRaiseError(schannel,
00093             ctxt->vctxt.error, ctxt->vctxt.userData,
00094             ctxt, NULL, XML_FROM_DTD, error,
00095             XML_ERR_ERROR, NULL, 0, (const char *) str1,
00096             (const char *) str2, NULL, 0, 0,
00097             msg, (const char *) str1, (const char *) str2);
00098     ctxt->valid = 0;
00099     } else {
00100     __xmlRaiseError(schannel,
00101             NULL, NULL,
00102             ctxt, NULL, XML_FROM_DTD, error,
00103             XML_ERR_ERROR, NULL, 0, (const char *) str1,
00104             (const char *) str2, NULL, 0, 0,
00105             msg, (const char *) str1, (const char *) str2);
00106     }
00107 }
00108 
00119 static void
00120 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
00121                const char *msg, const xmlChar *str1, const xmlChar *str2)
00122 {
00123     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
00124         (ctxt->instate == XML_PARSER_EOF))
00125     return;
00126     if (ctxt != NULL)
00127     ctxt->errNo = error;
00128     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
00129                     XML_ERR_FATAL, NULL, 0, 
00130             (const char *) str1, (const char *) str2,
00131             NULL, 0, 0, msg, str1, str2);
00132     if (ctxt != NULL) {
00133     ctxt->wellFormed = 0;
00134     ctxt->valid = 0;
00135     if (ctxt->recovery == 0)
00136         ctxt->disableSAX = 1;
00137     }
00138 }
00139 
00150 static void
00151 xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
00152                const char *msg, const xmlChar *str1)
00153 {
00154     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
00155         (ctxt->instate == XML_PARSER_EOF))
00156     return;
00157     if (ctxt != NULL)
00158     ctxt->errNo = error;
00159     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
00160                     XML_ERR_WARNING, NULL, 0, 
00161             (const char *) str1, NULL,
00162             NULL, 0, 0, msg, str1);
00163 }
00164 
00175 static void
00176 xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
00177             const char *msg, const xmlChar *str1, const xmlChar *str2)
00178 {
00179     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
00180         (ctxt->instate == XML_PARSER_EOF))
00181     return;
00182     if (ctxt != NULL)
00183     ctxt->errNo = error;
00184     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
00185                     XML_ERR_ERROR, NULL, 0, 
00186             (const char *) str1, (const char *) str2,
00187             NULL, 0, 0, msg, str1, str2);
00188 }
00189 
00199 static void
00200 xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
00201              const char *msg, const xmlChar *str1, const xmlChar *str2)
00202 {
00203     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
00204         (ctxt->instate == XML_PARSER_EOF))
00205     return;
00206     if (ctxt != NULL)
00207     ctxt->errNo = error;
00208     __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
00209                     XML_ERR_WARNING, NULL, 0, 
00210             (const char *) str1, (const char *) str2,
00211             NULL, 0, 0, msg, str1, str2);
00212 }
00213 
00222 const xmlChar *
00223 xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED)
00224 {
00225     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
00226     return(NULL);
00227 }
00228 
00238 const xmlChar *
00239 xmlSAX2GetSystemId(void *ctx)
00240 {
00241     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00242     if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL);
00243     return((const xmlChar *) ctxt->input->filename); 
00244 }
00245 
00254 int
00255 xmlSAX2GetLineNumber(void *ctx)
00256 {
00257     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00258     if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
00259     return(ctxt->input->line);
00260 }
00261 
00270 int
00271 xmlSAX2GetColumnNumber(void *ctx)
00272 {
00273     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00274     if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
00275     return(ctxt->input->col);
00276 }
00277 
00286 int
00287 xmlSAX2IsStandalone(void *ctx)
00288 {
00289     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00290     if ((ctx == NULL) || (ctxt->myDoc == NULL)) return(0);
00291     return(ctxt->myDoc->standalone == 1);
00292 }
00293 
00302 int
00303 xmlSAX2HasInternalSubset(void *ctx)
00304 {
00305     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00306     if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
00307     return(ctxt->myDoc->intSubset != NULL);
00308 }
00309 
00318 int
00319 xmlSAX2HasExternalSubset(void *ctx)
00320 {
00321     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00322     if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
00323     return(ctxt->myDoc->extSubset != NULL);
00324 }
00325 
00335 void
00336 xmlSAX2InternalSubset(void *ctx, const xmlChar *name,
00337            const xmlChar *ExternalID, const xmlChar *SystemID)
00338 {
00339     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00340     xmlDtdPtr dtd;
00341     if (ctx == NULL) return;
00342 #ifdef DEBUG_SAX
00343     xmlGenericError(xmlGenericErrorContext,
00344         "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
00345             name, ExternalID, SystemID);
00346 #endif
00347 
00348     if (ctxt->myDoc == NULL)
00349     return;
00350     dtd = xmlGetIntSubset(ctxt->myDoc);
00351     if (dtd != NULL) {
00352     if (ctxt->html)
00353         return;
00354     xmlUnlinkNode((xmlNodePtr) dtd);
00355     xmlFreeDtd(dtd);
00356     ctxt->myDoc->intSubset = NULL;
00357     }
00358     ctxt->myDoc->intSubset = 
00359     xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
00360     if (ctxt->myDoc->intSubset == NULL)
00361         xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset");
00362 }
00363 
00373 void
00374 xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
00375            const xmlChar *ExternalID, const xmlChar *SystemID)
00376 {
00377     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00378     if (ctx == NULL) return;
00379 #ifdef DEBUG_SAX
00380     xmlGenericError(xmlGenericErrorContext,
00381         "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
00382             name, ExternalID, SystemID);
00383 #endif
00384     if (((ExternalID != NULL) || (SystemID != NULL)) &&
00385         (((ctxt->validate) || (ctxt->loadsubset != 0)) &&
00386      (ctxt->wellFormed && ctxt->myDoc))) {
00387     /*
00388      * Try to fetch and parse the external subset.
00389      */
00390     xmlParserInputPtr oldinput;
00391     int oldinputNr;
00392     int oldinputMax;
00393     xmlParserInputPtr *oldinputTab;
00394     xmlParserInputPtr input = NULL;
00395     xmlCharEncoding enc;
00396     int oldcharset;
00397 
00398     /*
00399      * Ask the Entity resolver to load the damn thing
00400      */
00401     if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
00402         input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
00403                                             SystemID);
00404     if (input == NULL) {
00405         return;
00406     }
00407 
00408     xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
00409 
00410     /*
00411      * make sure we won't destroy the main document context
00412      */
00413     oldinput = ctxt->input;
00414     oldinputNr = ctxt->inputNr;
00415     oldinputMax = ctxt->inputMax;
00416     oldinputTab = ctxt->inputTab;
00417     oldcharset = ctxt->charset;
00418 
00419     ctxt->inputTab = (xmlParserInputPtr *)
00420                      xmlMalloc(5 * sizeof(xmlParserInputPtr));
00421     if (ctxt->inputTab == NULL) {
00422         xmlSAX2ErrMemory(ctxt, "xmlSAX2ExternalSubset");
00423         ctxt->input = oldinput;
00424         ctxt->inputNr = oldinputNr;
00425         ctxt->inputMax = oldinputMax;
00426         ctxt->inputTab = oldinputTab;
00427         ctxt->charset = oldcharset;
00428         return;
00429     }
00430     ctxt->inputNr = 0;
00431     ctxt->inputMax = 5;
00432     ctxt->input = NULL;
00433     xmlPushInput(ctxt, input);
00434 
00435     /*
00436      * On the fly encoding conversion if needed
00437      */
00438     if (ctxt->input->length >= 4) {
00439         enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
00440         xmlSwitchEncoding(ctxt, enc);
00441     }
00442 
00443     if (input->filename == NULL)
00444         input->filename = (char *) xmlCanonicPath(SystemID);
00445     input->line = 1;
00446     input->col = 1;
00447     input->base = ctxt->input->cur;
00448     input->cur = ctxt->input->cur;
00449     input->free = NULL;
00450 
00451     /*
00452      * let's parse that entity knowing it's an external subset.
00453      */
00454     xmlParseExternalSubset(ctxt, ExternalID, SystemID);
00455 
00456         /*
00457      * Free up the external entities
00458      */
00459 
00460     while (ctxt->inputNr > 1)
00461         xmlPopInput(ctxt);
00462     xmlFreeInputStream(ctxt->input);
00463         xmlFree(ctxt->inputTab);
00464 
00465     /*
00466      * Restore the parsing context of the main entity
00467      */
00468     ctxt->input = oldinput;
00469     ctxt->inputNr = oldinputNr;
00470     ctxt->inputMax = oldinputMax;
00471     ctxt->inputTab = oldinputTab;
00472     ctxt->charset = oldcharset;
00473     /* ctxt->wellFormed = oldwellFormed; */
00474     }
00475 }
00476 
00491 xmlParserInputPtr
00492 xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
00493 {
00494     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00495     xmlParserInputPtr ret;
00496     xmlChar *URI;
00497     const char *base = NULL;
00498 
00499     if (ctx == NULL) return(NULL);
00500     if (ctxt->input != NULL)
00501     base = ctxt->input->filename;
00502     if (base == NULL)
00503     base = ctxt->directory;
00504 
00505     URI = xmlBuildURI(systemId, (const xmlChar *) base);
00506 
00507 #ifdef DEBUG_SAX
00508     xmlGenericError(xmlGenericErrorContext,
00509         "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId);
00510 #endif
00511 
00512     ret = xmlLoadExternalEntity((const char *) URI,
00513                 (const char *) publicId, ctxt);
00514     if (URI != NULL)
00515     xmlFree(URI);
00516     return(ret);
00517 }
00518 
00528 xmlEntityPtr
00529 xmlSAX2GetEntity(void *ctx, const xmlChar *name)
00530 {
00531     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00532     xmlEntityPtr ret = NULL;
00533 
00534     if (ctx == NULL) return(NULL);
00535 #ifdef DEBUG_SAX
00536     xmlGenericError(xmlGenericErrorContext,
00537         "SAX.xmlSAX2GetEntity(%s)\n", name);
00538 #endif
00539 
00540     if (ctxt->inSubset == 0) {
00541     ret = xmlGetPredefinedEntity(name);
00542     if (ret != NULL)
00543         return(ret);
00544     }
00545     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) {
00546     if (ctxt->inSubset == 2) {
00547         ctxt->myDoc->standalone = 0;
00548         ret = xmlGetDocEntity(ctxt->myDoc, name);
00549         ctxt->myDoc->standalone = 1;
00550     } else {
00551         ret = xmlGetDocEntity(ctxt->myDoc, name);
00552         if (ret == NULL) {
00553         ctxt->myDoc->standalone = 0;
00554         ret = xmlGetDocEntity(ctxt->myDoc, name);
00555         if (ret != NULL) {
00556             xmlFatalErrMsg(ctxt, XML_ERR_NOT_STANDALONE,
00557      "Entity(%s) document marked standalone but requires external subset\n",
00558                    name, NULL);
00559         }
00560         ctxt->myDoc->standalone = 1;
00561         }
00562     }
00563     } else {
00564     ret = xmlGetDocEntity(ctxt->myDoc, name);
00565     }
00566     if ((ret != NULL) &&
00567     ((ctxt->validate) || (ctxt->replaceEntities)) &&
00568     (ret->children == NULL) &&
00569     (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
00570     int val;
00571 
00572     /*
00573      * for validation purposes we really need to fetch and
00574      * parse the external entity
00575      */
00576     xmlNodePtr children;
00577 
00578         val = xmlParseCtxtExternalEntity(ctxt, ret->URI,
00579                                  ret->ExternalID, &children);
00580     if (val == 0) {
00581         xmlAddChildList((xmlNodePtr) ret, children);
00582     } else {
00583         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
00584                    "Failure to process entity %s\n", name, NULL);
00585         ctxt->validate = 0;
00586         return(NULL);
00587     }
00588     ret->owner = 1;
00589     if (ret->checked == 0)
00590         ret->checked = 1;
00591     }
00592     return(ret);
00593 }
00594 
00604 xmlEntityPtr
00605 xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
00606 {
00607     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00608     xmlEntityPtr ret;
00609 
00610     if (ctx == NULL) return(NULL);
00611 #ifdef DEBUG_SAX
00612     xmlGenericError(xmlGenericErrorContext,
00613         "SAX.xmlSAX2GetParameterEntity(%s)\n", name);
00614 #endif
00615 
00616     ret = xmlGetParameterEntity(ctxt->myDoc, name);
00617     return(ret);
00618 }
00619 
00620 
00632 void
00633 xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
00634           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
00635 {
00636     xmlEntityPtr ent;
00637     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00638 
00639     if (ctx == NULL) return;
00640 #ifdef DEBUG_SAX
00641     xmlGenericError(xmlGenericErrorContext,
00642         "SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s)\n",
00643             name, type, publicId, systemId, content);
00644 #endif
00645     if (ctxt->inSubset == 1) {
00646     ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
00647                       systemId, content);
00648     if ((ent == NULL) && (ctxt->pedantic))
00649         xmlWarnMsg(ctxt, XML_WAR_ENTITY_REDEFINED,
00650          "Entity(%s) already defined in the internal subset\n",
00651                    name);
00652     if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
00653         xmlChar *URI;
00654         const char *base = NULL;
00655 
00656         if (ctxt->input != NULL)
00657         base = ctxt->input->filename;
00658         if (base == NULL)
00659         base = ctxt->directory;
00660     
00661         URI = xmlBuildURI(systemId, (const xmlChar *) base);
00662         ent->URI = URI;
00663     }
00664     } else if (ctxt->inSubset == 2) {
00665     ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
00666                       systemId, content);
00667     if ((ent == NULL) && (ctxt->pedantic) &&
00668         (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
00669         ctxt->sax->warning(ctxt->userData, 
00670          "Entity(%s) already defined in the external subset\n", name);
00671     if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
00672         xmlChar *URI;
00673         const char *base = NULL;
00674 
00675         if (ctxt->input != NULL)
00676         base = ctxt->input->filename;
00677         if (base == NULL)
00678         base = ctxt->directory;
00679     
00680         URI = xmlBuildURI(systemId, (const xmlChar *) base);
00681         ent->URI = URI;
00682     }
00683     } else {
00684     xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
00685                    "SAX.xmlSAX2EntityDecl(%s) called while not in subset\n",
00686                name, NULL);
00687     }
00688 }
00689 
00702 void
00703 xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
00704               int type, int def, const xmlChar *defaultValue,
00705           xmlEnumerationPtr tree)
00706 {
00707     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00708     xmlAttributePtr attr;
00709     xmlChar *name = NULL, *prefix = NULL;
00710 
00711     if ((ctxt == NULL) || (ctxt->myDoc == NULL))
00712         return;
00713 
00714 #ifdef DEBUG_SAX
00715     xmlGenericError(xmlGenericErrorContext,
00716         "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
00717             elem, fullname, type, def, defaultValue);
00718 #endif
00719     if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) &&
00720         (type != XML_ATTRIBUTE_ID)) {
00721     /*
00722      * Raise the error but keep the validity flag
00723      */
00724     int tmp = ctxt->valid;
00725     xmlErrValid(ctxt, XML_DTD_XMLID_TYPE,
00726           "xml:id : attribute type should be ID\n", NULL, NULL);
00727     ctxt->valid = tmp;
00728     }
00729     /* TODO: optimize name/prefix allocation */
00730     name = xmlSplitQName(ctxt, fullname, &prefix);
00731     ctxt->vctxt.valid = 1;
00732     if (ctxt->inSubset == 1)
00733     attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
00734            name, prefix, (xmlAttributeType) type,
00735            (xmlAttributeDefault) def, defaultValue, tree);
00736     else if (ctxt->inSubset == 2)
00737     attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
00738        name, prefix, (xmlAttributeType) type, 
00739        (xmlAttributeDefault) def, defaultValue, tree);
00740     else {
00741         xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
00742          "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
00743                    name, NULL);
00744     xmlFreeEnumeration(tree);
00745     return;
00746     }
00747 #ifdef LIBXML_VALID_ENABLED
00748     if (ctxt->vctxt.valid == 0)
00749     ctxt->valid = 0;
00750     if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
00751         (ctxt->myDoc->intSubset != NULL))
00752     ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
00753                                             attr);
00754 #endif /* LIBXML_VALID_ENABLED */
00755     if (prefix != NULL)
00756     xmlFree(prefix);
00757     if (name != NULL)
00758     xmlFree(name);
00759 }
00760 
00770 void
00771 xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type,
00772             xmlElementContentPtr content)
00773 {
00774     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00775     xmlElementPtr elem = NULL;
00776 
00777     if ((ctxt == NULL) || (ctxt->myDoc == NULL))
00778         return;
00779 
00780 #ifdef DEBUG_SAX
00781     xmlGenericError(xmlGenericErrorContext,
00782                     "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type);
00783 #endif
00784 
00785     if (ctxt->inSubset == 1)
00786         elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
00787                                  name, (xmlElementTypeVal) type, content);
00788     else if (ctxt->inSubset == 2)
00789         elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
00790                                  name, (xmlElementTypeVal) type, content);
00791     else {
00792         xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
00793          "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
00794                    name, NULL);
00795         return;
00796     }
00797 #ifdef LIBXML_VALID_ENABLED
00798     if (elem == NULL)
00799         ctxt->valid = 0;
00800     if (ctxt->validate && ctxt->wellFormed &&
00801         ctxt->myDoc && ctxt->myDoc->intSubset)
00802         ctxt->valid &=
00803             xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
00804 #endif /* LIBXML_VALID_ENABLED */
00805 }
00806 
00816 void
00817 xmlSAX2NotationDecl(void *ctx, const xmlChar *name,
00818          const xmlChar *publicId, const xmlChar *systemId)
00819 {
00820     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00821     xmlNotationPtr nota = NULL;
00822 
00823     if ((ctxt == NULL) || (ctxt->myDoc == NULL))
00824         return;
00825 
00826 #ifdef DEBUG_SAX
00827     xmlGenericError(xmlGenericErrorContext,
00828         "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId);
00829 #endif
00830 
00831     if ((publicId == NULL) && (systemId == NULL)) {
00832     xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
00833          "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
00834                    name, NULL);
00835     return;
00836     } else if (ctxt->inSubset == 1)
00837     nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
00838                               publicId, systemId);
00839     else if (ctxt->inSubset == 2)
00840     nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
00841                               publicId, systemId);
00842     else {
00843     xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
00844          "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
00845                    name, NULL);
00846     return;
00847     }
00848 #ifdef LIBXML_VALID_ENABLED
00849     if (nota == NULL) ctxt->valid = 0;
00850     if ((ctxt->validate) && (ctxt->wellFormed) &&
00851         (ctxt->myDoc->intSubset != NULL))
00852     ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
00853                                            nota);
00854 #endif /* LIBXML_VALID_ENABLED */
00855 }
00856 
00867 void
00868 xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
00869            const xmlChar *publicId, const xmlChar *systemId,
00870            const xmlChar *notationName)
00871 {
00872     xmlEntityPtr ent;
00873     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00874     if (ctx == NULL) return;
00875 #ifdef DEBUG_SAX
00876     xmlGenericError(xmlGenericErrorContext,
00877         "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
00878             name, publicId, systemId, notationName);
00879 #endif
00880     if (ctxt->inSubset == 1) {
00881     ent = xmlAddDocEntity(ctxt->myDoc, name,
00882             XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
00883             publicId, systemId, notationName);
00884     if ((ent == NULL) && (ctxt->pedantic) &&
00885         (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
00886         ctxt->sax->warning(ctxt->userData, 
00887          "Entity(%s) already defined in the internal subset\n", name);
00888     if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
00889         xmlChar *URI;
00890         const char *base = NULL;
00891 
00892         if (ctxt->input != NULL)
00893         base = ctxt->input->filename;
00894         if (base == NULL)
00895         base = ctxt->directory;
00896     
00897         URI = xmlBuildURI(systemId, (const xmlChar *) base);
00898         ent->URI = URI;
00899     }
00900     } else if (ctxt->inSubset == 2) {
00901     ent = xmlAddDtdEntity(ctxt->myDoc, name,
00902             XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
00903             publicId, systemId, notationName);
00904     if ((ent == NULL) && (ctxt->pedantic) &&
00905         (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
00906         ctxt->sax->warning(ctxt->userData, 
00907          "Entity(%s) already defined in the external subset\n", name);
00908     if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
00909         xmlChar *URI;
00910         const char *base = NULL;
00911 
00912         if (ctxt->input != NULL)
00913         base = ctxt->input->filename;
00914         if (base == NULL)
00915         base = ctxt->directory;
00916     
00917         URI = xmlBuildURI(systemId, (const xmlChar *) base);
00918         ent->URI = URI;
00919     }
00920     } else {
00921         xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
00922          "SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset\n",
00923                    name, NULL);
00924     }
00925 }
00926 
00935 void
00936 xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
00937 {
00938     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
00939 #ifdef DEBUG_SAX
00940     xmlGenericError(xmlGenericErrorContext,
00941         "SAX.xmlSAX2SetDocumentLocator()\n");
00942 #endif
00943 }
00944 
00951 void
00952 xmlSAX2StartDocument(void *ctx)
00953 {
00954     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
00955     xmlDocPtr doc;
00956 
00957     if (ctx == NULL) return;
00958 
00959 #ifdef DEBUG_SAX
00960     xmlGenericError(xmlGenericErrorContext,
00961         "SAX.xmlSAX2StartDocument()\n");
00962 #endif
00963     if (ctxt->html) {
00964 #ifdef LIBXML_HTML_ENABLED
00965     if (ctxt->myDoc == NULL)
00966         ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
00967     ctxt->myDoc->properties = XML_DOC_HTML;
00968     ctxt->myDoc->parseFlags = ctxt->options;
00969     if (ctxt->myDoc == NULL) {
00970         xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
00971         return;
00972     }
00973 #else
00974         xmlGenericError(xmlGenericErrorContext,
00975         "libxml2 built without HTML support\n");
00976     ctxt->errNo = XML_ERR_INTERNAL_ERROR;
00977     ctxt->instate = XML_PARSER_EOF;
00978     ctxt->disableSAX = 1;
00979     return;
00980 #endif
00981     } else {
00982     doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
00983     if (doc != NULL) {
00984         doc->properties = 0;
00985         if (ctxt->options & XML_PARSE_OLD10)
00986             doc->properties |= XML_DOC_OLD10;
00987         doc->parseFlags = ctxt->options;
00988         if (ctxt->encoding != NULL)
00989         doc->encoding = xmlStrdup(ctxt->encoding);
00990         else
00991         doc->encoding = NULL;
00992         doc->standalone = ctxt->standalone;
00993     } else {
00994         xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
00995         return;
00996     }
00997     if ((ctxt->dictNames) && (doc != NULL)) {
00998         doc->dict = ctxt->dict;
00999         xmlDictReference(doc->dict);
01000     }
01001     }
01002     if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
01003     (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
01004     ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename);
01005     if (ctxt->myDoc->URL == NULL)
01006         xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
01007     }
01008 }
01009 
01016 void
01017 xmlSAX2EndDocument(void *ctx)
01018 {
01019     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
01020 #ifdef DEBUG_SAX
01021     xmlGenericError(xmlGenericErrorContext,
01022         "SAX.xmlSAX2EndDocument()\n");
01023 #endif
01024     if (ctx == NULL) return;
01025 #ifdef LIBXML_VALID_ENABLED
01026     if (ctxt->validate && ctxt->wellFormed &&
01027         ctxt->myDoc && ctxt->myDoc->intSubset)
01028     ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
01029 #endif /* LIBXML_VALID_ENABLED */
01030 
01031     /*
01032      * Grab the encoding if it was added on-the-fly
01033      */
01034     if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
01035     (ctxt->myDoc->encoding == NULL)) {
01036     ctxt->myDoc->encoding = ctxt->encoding;
01037     ctxt->encoding = NULL;
01038     }
01039     if ((ctxt->inputTab != NULL) &&
01040         (ctxt->inputNr > 0) && (ctxt->inputTab[0] != NULL) &&
01041         (ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
01042     (ctxt->myDoc->encoding == NULL)) {
01043     ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
01044     }
01045     if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
01046     (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
01047     ctxt->myDoc->charset = ctxt->charset;
01048     }
01049 }
01050 
01051 #if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
01052 
01064 static void
01065 xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
01066              const xmlChar *value, const xmlChar *prefix ATTRIBUTE_UNUSED)
01067 {
01068     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
01069     xmlAttrPtr ret;
01070     xmlChar *name;
01071     xmlChar *ns;
01072     xmlChar *nval;
01073     xmlNsPtr namespace;
01074 
01075     if (ctxt->html) {
01076     name = xmlStrdup(fullname);
01077     ns = NULL;
01078     namespace = NULL;
01079     } else {
01080     /*
01081      * Split the full name into a namespace prefix and the tag name
01082      */
01083     name = xmlSplitQName(ctxt, fullname, &ns);
01084     if ((name != NULL) && (name[0] == 0)) {
01085         if (xmlStrEqual(ns, BAD_CAST "xmlns")) {
01086         xmlNsErrMsg(ctxt, XML_ERR_NS_DECL_ERROR,
01087                 "invalid namespace declaration '%s'\n",
01088                 fullname, NULL);
01089         } else {
01090         xmlNsWarnMsg(ctxt, XML_WAR_NS_COLUMN,
01091                  "Avoid attribute ending with ':' like '%s'\n",
01092                  fullname, NULL);
01093         }
01094         if (ns != NULL)
01095         xmlFree(ns);
01096         ns = NULL;
01097         xmlFree(name);
01098         name = xmlStrdup(fullname);
01099     }
01100     }
01101     if (name == NULL) {
01102         xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
01103     if (ns != NULL)
01104         xmlFree(ns);
01105     return;
01106     }
01107 
01108 #ifdef LIBXML_HTML_ENABLED
01109     if ((ctxt->html) &&
01110         (value == NULL) && (htmlIsBooleanAttr(fullname))) {
01111             nval = xmlStrdup(fullname);
01112             value = (const xmlChar *) nval;
01113     } else
01114 #endif
01115     {
01116 #ifdef LIBXML_VALID_ENABLED
01117         /*
01118          * Do the last stage of the attribute normalization
01119          * Needed for HTML too:
01120          *   http://www.w3.org/TR/html4/types.html#h-6.2
01121          */
01122         ctxt->vctxt.valid = 1;
01123         nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
01124                                                ctxt->myDoc, ctxt->node,
01125                                                fullname, value);
01126         if (ctxt->vctxt.valid != 1) {
01127             ctxt->valid = 0;
01128         }
01129         if (nval != NULL)
01130             value = nval;
01131 #else
01132         nval = NULL;
01133 #endif /* LIBXML_VALID_ENABLED */
01134     }
01135 
01136     /*
01137      * Check whether it's a namespace definition
01138      */
01139     if ((!ctxt->html) && (ns == NULL) &&
01140         (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
01141         (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
01142     xmlNsPtr nsret;
01143     xmlChar *val;
01144 
01145         if (!ctxt->replaceEntities) {
01146         ctxt->depth++;
01147         val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
01148                                   0,0,0);
01149         ctxt->depth--;
01150     } else {
01151         val = (xmlChar *) value;
01152     }
01153 
01154     if (val[0] != 0) {
01155         xmlURIPtr uri;
01156 
01157         uri = xmlParseURI((const char *)val);
01158         if (uri == NULL) {
01159         if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
01160             ctxt->sax->warning(ctxt->userData, 
01161              "xmlns: %s not a valid URI\n", val);
01162         } else {
01163         if (uri->scheme == NULL) {
01164             if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
01165             ctxt->sax->warning(ctxt->userData, 
01166                  "xmlns: URI %s is not absolute\n", val);
01167         }
01168         xmlFreeURI(uri);
01169         }
01170     }
01171 
01172     /* a default namespace definition */
01173     nsret = xmlNewNs(ctxt->node, val, NULL);
01174 
01175 #ifdef LIBXML_VALID_ENABLED
01176     /*
01177      * Validate also for namespace decls, they are attributes from
01178      * an XML-1.0 perspective
01179      */
01180         if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
01181         ctxt->myDoc && ctxt->myDoc->intSubset)
01182         ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
01183                        ctxt->node, prefix, nsret, val);
01184 #endif /* LIBXML_VALID_ENABLED */
01185     if (name != NULL) 
01186         xmlFree(name);
01187     if (nval != NULL)
01188         xmlFree(nval);
01189     if (val != value)
01190         xmlFree(val);
01191     return;
01192     }
01193     if ((!ctxt->html) &&
01194     (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
01195         (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
01196     xmlNsPtr nsret;
01197     xmlChar *val;
01198 
01199         if (!ctxt->replaceEntities) {
01200         ctxt->depth++;
01201         val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
01202                                   0,0,0);
01203         ctxt->depth--;
01204         if (val == NULL) {
01205             xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
01206             xmlFree(ns);
01207         if (name != NULL) 
01208             xmlFree(name);
01209         return;
01210         }
01211     } else {
01212         val = (xmlChar *) value;
01213     }
01214 
01215     if (val[0] == 0) {
01216         xmlNsErrMsg(ctxt, XML_NS_ERR_EMPTY,
01217                 "Empty namespace name for prefix %s\n", name, NULL);
01218     }
01219     if ((ctxt->pedantic != 0) && (val[0] != 0)) {
01220         xmlURIPtr uri;
01221 
01222         uri = xmlParseURI((const char *)val);
01223         if (uri == NULL) {
01224             xmlNsWarnMsg(ctxt, XML_WAR_NS_URI,
01225              "xmlns:%s: %s not a valid URI\n", name, value);
01226         } else {
01227         if (uri->scheme == NULL) {
01228             xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
01229                "xmlns:%s: URI %s is not absolute\n", name, value);
01230         }
01231         xmlFreeURI(uri);
01232         }
01233     }
01234 
01235     /* a standard namespace definition */
01236     nsret = xmlNewNs(ctxt->node, val, name);
01237     xmlFree(ns);
01238 #ifdef LIBXML_VALID_ENABLED
01239     /*
01240      * Validate also for namespace decls, they are attributes from
01241      * an XML-1.0 perspective
01242      */
01243         if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
01244         ctxt->myDoc && ctxt->myDoc->intSubset)
01245         ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
01246                        ctxt->node, prefix, nsret, value);
01247 #endif /* LIBXML_VALID_ENABLED */
01248     if (name != NULL) 
01249         xmlFree(name);
01250     if (nval != NULL)
01251         xmlFree(nval);
01252     if (val != value)
01253         xmlFree(val);
01254     return;
01255     }
01256 
01257     if (ns != NULL) {
01258     namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
01259 
01260     if (namespace == NULL) {
01261         xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
01262             "Namespace prefix %s of attribute %s is not defined\n",
01263                      ns, name);
01264     } else {
01265             xmlAttrPtr prop;
01266 
01267             prop = ctxt->node->properties;
01268             while (prop != NULL) {
01269                 if (prop->ns != NULL) {
01270                     if ((xmlStrEqual(name, prop->name)) &&
01271                         ((namespace == prop->ns) ||
01272                          (xmlStrEqual(namespace->href, prop->ns->href)))) {
01273                             xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
01274                                     "Attribute %s in %s redefined\n",
01275                                              name, namespace->href);
01276                         ctxt->wellFormed = 0;
01277                         if (ctxt->recovery == 0) ctxt->disableSAX = 1;
01278                         goto error;
01279                     }
01280                 }
01281                 prop = prop->next;
01282             }
01283         }
01284     } else {
01285     namespace = NULL;
01286     }
01287 
01288     /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
01289     ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL);
01290 
01291     if (ret != NULL) {
01292         if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
01293         xmlNodePtr tmp;
01294 
01295         ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
01296         tmp = ret->children;
01297         while (tmp != NULL) {
01298         tmp->parent = (xmlNodePtr) ret;
01299         if (tmp->next == NULL)
01300             ret->last = tmp;
01301         tmp = tmp->next;
01302         }
01303     } else if (value != NULL) {
01304         ret->children = xmlNewDocText(ctxt->myDoc, value);
01305         ret->last = ret->children;
01306         if (ret->children != NULL)
01307         ret->children->parent = (xmlNodePtr) ret;
01308     }
01309     }
01310 
01311 #ifdef LIBXML_VALID_ENABLED
01312     if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
01313         ctxt->myDoc && ctxt->myDoc->intSubset) {
01314     
01315     /*
01316      * If we don't substitute entities, the validation should be
01317      * done on a value with replaced entities anyway.
01318      */
01319         if (!ctxt->replaceEntities) {
01320         xmlChar *val;
01321 
01322         ctxt->depth++;
01323         val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
01324                                   0,0,0);
01325         ctxt->depth--;
01326         
01327         if (val == NULL)
01328         ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
01329                 ctxt->myDoc, ctxt->node, ret, value);
01330         else {
01331         xmlChar *nvalnorm;
01332 
01333         /*
01334          * Do the last stage of the attribute normalization
01335          * It need to be done twice ... it's an extra burden related
01336          * to the ability to keep xmlSAX2References in attributes
01337          */
01338         nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc,
01339                         ctxt->node, fullname, val);
01340         if (nvalnorm != NULL) {
01341             xmlFree(val);
01342             val = nvalnorm;
01343         }
01344 
01345         ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
01346                     ctxt->myDoc, ctxt->node, ret, val);
01347                 xmlFree(val);
01348         }
01349     } else {
01350         ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
01351                            ctxt->node, ret, value);
01352     }
01353     } else
01354 #endif /* LIBXML_VALID_ENABLED */
01355            if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
01356            (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
01357             ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
01358         /*
01359      * when validating, the ID registration is done at the attribute
01360      * validation level. Otherwise we have to do specific handling here.
01361      */
01362     if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
01363         /*
01364          * Add the xml:id value
01365          *
01366          * Open issue: normalization of the value.
01367          */
01368         if (xmlValidateNCName(value, 1) != 0) {
01369             xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
01370               "xml:id : attribute value %s is not an NCName\n",
01371                 (const char *) value, NULL);
01372         }
01373         xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
01374     } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
01375         xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
01376     else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
01377         xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
01378     }
01379 
01380 error:
01381     if (nval != NULL)
01382     xmlFree(nval);
01383     if (ns != NULL) 
01384     xmlFree(ns);
01385 }
01386 
01387 /*
01388  * xmlCheckDefaultedAttributes:
01389  *
01390  * Check defaulted attributes from the DTD
01391  */
01392 static void
01393 xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
01394     const xmlChar *prefix, const xmlChar **atts) {
01395     xmlElementPtr elemDecl;
01396     const xmlChar *att;
01397     int internal = 1;
01398     int i;
01399 
01400     elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix);
01401     if (elemDecl == NULL) {
01402     elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix);
01403     internal = 0;
01404     }
01405 
01406 process_external_subset:
01407 
01408     if (elemDecl != NULL) {
01409     xmlAttributePtr attr = elemDecl->attributes;
01410     /*
01411      * Check against defaulted attributes from the external subset
01412      * if the document is stamped as standalone
01413      */
01414     if ((ctxt->myDoc->standalone == 1) &&
01415         (ctxt->myDoc->extSubset != NULL) &&
01416         (ctxt->validate)) {
01417         while (attr != NULL) {
01418         if ((attr->defaultValue != NULL) &&
01419             (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset,
01420                     attr->elem, attr->name,
01421                     attr->prefix) == attr) &&
01422             (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
01423                     attr->elem, attr->name,
01424                     attr->prefix) == NULL)) {
01425             xmlChar *fulln;
01426 
01427             if (attr->prefix != NULL) {
01428             fulln = xmlStrdup(attr->prefix);
01429             fulln = xmlStrcat(fulln, BAD_CAST ":");
01430             fulln = xmlStrcat(fulln, attr->name);
01431             } else {
01432             fulln = xmlStrdup(attr->name);
01433             }
01434                     if (fulln == NULL) {
01435                         xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
01436                         break;
01437                     }
01438 
01439             /*
01440              * Check that the attribute is not declared in the
01441              * serialization
01442              */
01443             att = NULL;
01444             if (atts != NULL) {
01445             i = 0;
01446             att = atts[i];
01447             while (att != NULL) {
01448                 if (xmlStrEqual(att, fulln))
01449                 break;
01450                 i += 2;
01451                 att = atts[i];
01452             }
01453             }
01454             if (att == NULL) {
01455                 xmlErrValid(ctxt, XML_DTD_STANDALONE_DEFAULTED,
01456       "standalone: attribute %s on %s defaulted from external subset\n",
01457                     (const char *)fulln,
01458                     (const char *)attr->elem);
01459             }
01460                     xmlFree(fulln);
01461         }
01462         attr = attr->nexth;
01463         }
01464     }
01465 
01466     /*
01467      * Actually insert defaulted values when needed
01468      */
01469     attr = elemDecl->attributes;
01470     while (attr != NULL) {
01471         /*
01472          * Make sure that attributes redefinition occuring in the
01473          * internal subset are not overriden by definitions in the
01474          * external subset.
01475          */
01476         if (attr->defaultValue != NULL) {
01477         /*
01478          * the element should be instantiated in the tree if:
01479          *  - this is a namespace prefix
01480          *  - the user required for completion in the tree
01481          *    like XSLT
01482          *  - there isn't already an attribute definition 
01483          *    in the internal subset overriding it.
01484          */
01485         if (((attr->prefix != NULL) &&
01486              (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
01487             ((attr->prefix == NULL) &&
01488              (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
01489             (ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
01490             xmlAttributePtr tst;
01491 
01492             tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
01493                          attr->elem, attr->name,
01494                          attr->prefix);
01495             if ((tst == attr) || (tst == NULL)) {
01496                 xmlChar fn[50];
01497             xmlChar *fulln;
01498 
01499                         fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50);
01500             if (fulln == NULL) {
01501                 xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
01502                 return;
01503             }
01504 
01505             /*
01506              * Check that the attribute is not declared in the
01507              * serialization
01508              */
01509             att = NULL;
01510             if (atts != NULL) {
01511                 i = 0;
01512                 att = atts[i];
01513                 while (att != NULL) {
01514                 if (xmlStrEqual(att, fulln))
01515                     break;
01516                 i += 2;
01517                 att = atts[i];
01518                 }
01519             }
01520             if (att == NULL) {
01521                 xmlSAX2AttributeInternal(ctxt, fulln,
01522                          attr->defaultValue, prefix);
01523             }
01524             if ((fulln != fn) && (fulln != attr->name))
01525                 xmlFree(fulln);
01526             }
01527         }
01528         }
01529         attr = attr->nexth;
01530     }
01531     if (internal == 1) {
01532         elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
01533                                      name, prefix);
01534         internal = 0;
01535         goto process_external_subset;
01536     }
01537     }
01538 }
01539 
01548 void
01549 xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
01550 {
01551     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
01552     xmlNodePtr ret;
01553     xmlNodePtr parent;
01554     xmlNsPtr ns;
01555     xmlChar *name;
01556     xmlChar *prefix;
01557     const xmlChar *att;
01558     const xmlChar *value;
01559     int i;
01560 
01561     if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return;
01562     parent = ctxt->node;
01563 #ifdef DEBUG_SAX
01564     xmlGenericError(xmlGenericErrorContext,
01565         "SAX.xmlSAX2StartElement(%s)\n", fullname);
01566 #endif
01567 
01568     /*
01569      * First check on validity:
01570      */
01571     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 
01572         ((ctxt->myDoc->intSubset == NULL) ||
01573      ((ctxt->myDoc->intSubset->notations == NULL) && 
01574       (ctxt->myDoc->intSubset->elements == NULL) &&
01575       (ctxt->myDoc->intSubset->attributes == NULL) && 
01576       (ctxt->myDoc->intSubset->entities == NULL)))) {
01577     xmlErrValid(ctxt, XML_ERR_NO_DTD,
01578       "Validation failed: no DTD found !", NULL, NULL);
01579     ctxt->validate = 0;
01580     }
01581        
01582 
01583     /*
01584      * Split the full name into a namespace prefix and the tag name
01585      */
01586     name = xmlSplitQName(ctxt, fullname, &prefix);
01587 
01588 
01589     /*
01590      * Note : the namespace resolution is deferred until the end of the
01591      *        attributes parsing, since local namespace can be defined as
01592      *        an attribute at this level.
01593      */
01594     ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
01595     if (ret == NULL) {
01596         if (prefix != NULL)
01597         xmlFree(prefix);
01598     xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
01599         return;
01600     }
01601     if (ctxt->myDoc->children == NULL) {
01602 #ifdef DEBUG_SAX_TREE
01603     xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
01604 #endif
01605         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
01606     } else if (parent == NULL) {
01607         parent = ctxt->myDoc->children;
01608     }
01609     ctxt->nodemem = -1;
01610     if (ctxt->linenumbers) {
01611     if (ctxt->input != NULL) {
01612         if (ctxt->input->line < 65535)
01613         ret->line = (short) ctxt->input->line;
01614         else
01615             ret->line = 65535;
01616     }
01617     }
01618 
01619     /*
01620      * We are parsing a new node.
01621      */
01622 #ifdef DEBUG_SAX_TREE
01623     xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
01624 #endif
01625     nodePush(ctxt, ret);
01626 
01627     /*
01628      * Link the child element
01629      */
01630     if (parent != NULL) {
01631         if (parent->type == XML_ELEMENT_NODE) {
01632 #ifdef DEBUG_SAX_TREE
01633         xmlGenericError(xmlGenericErrorContext,
01634             "adding child %s to %s\n", name, parent->name);
01635 #endif
01636         xmlAddChild(parent, ret);
01637     } else {
01638 #ifdef DEBUG_SAX_TREE
01639         xmlGenericError(xmlGenericErrorContext,
01640             "adding sibling %s to ", name);
01641         xmlDebugDumpOneNode(stderr, parent, 0);
01642 #endif
01643         xmlAddSibling(parent, ret);
01644     }
01645     }
01646 
01647     /*
01648      * Insert all the defaulted attributes from the DTD especially namespaces
01649      */
01650     if ((!ctxt->html) &&
01651     ((ctxt->myDoc->intSubset != NULL) ||
01652      (ctxt->myDoc->extSubset != NULL))) {
01653     xmlCheckDefaultedAttributes(ctxt, name, prefix, atts);
01654     }
01655 
01656     /*
01657      * process all the attributes whose name start with "xmlns"
01658      */
01659     if (atts != NULL) {
01660         i = 0;
01661     att = atts[i++];
01662     value = atts[i++];
01663     if (!ctxt->html) {
01664         while ((att != NULL) && (value != NULL)) {
01665         if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') &&
01666             (att[3] == 'n') && (att[4] == 's'))
01667             xmlSAX2AttributeInternal(ctxt, att, value, prefix);
01668 
01669         att = atts[i++];
01670         value = atts[i++];
01671         }
01672     }
01673     }
01674 
01675     /*
01676      * Search the namespace, note that since the attributes have been
01677      * processed, the local namespaces are available.
01678      */
01679     ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
01680     if ((ns == NULL) && (parent != NULL))
01681     ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
01682     if ((prefix != NULL) && (ns == NULL)) {
01683     ns = xmlNewNs(ret, NULL, prefix);
01684     xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
01685              "Namespace prefix %s is not defined\n",
01686              prefix, NULL);
01687     }
01688 
01689     /*
01690      * set the namespace node, making sure that if the default namspace
01691      * is unbound on a parent we simply kee it NULL
01692      */
01693     if ((ns != NULL) && (ns->href != NULL) &&
01694     ((ns->href[0] != 0) || (ns->prefix != NULL)))
01695     xmlSetNs(ret, ns);
01696 
01697     /*
01698      * process all the other attributes
01699      */
01700     if (atts != NULL) {
01701         i = 0;
01702     att = atts[i++];
01703     value = atts[i++];
01704     if (ctxt->html) {
01705         while (att != NULL) {
01706         xmlSAX2AttributeInternal(ctxt, att, value, NULL);
01707         att = atts[i++];
01708         value = atts[i++];
01709         }
01710     } else {
01711         while ((att != NULL) && (value != NULL)) {
01712         if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') ||
01713             (att[3] != 'n') || (att[4] != 's'))
01714             xmlSAX2AttributeInternal(ctxt, att, value, NULL);
01715 
01716         /*
01717          * Next ones
01718          */
01719         att = atts[i++];
01720         value = atts[i++];
01721         }
01722     }
01723     }
01724 
01725 #ifdef LIBXML_VALID_ENABLED
01726     /*
01727      * If it's the Document root, finish the DTD validation and
01728      * check the document root element for validity
01729      */
01730     if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
01731     int chk;
01732 
01733     chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
01734     if (chk <= 0)
01735         ctxt->valid = 0;
01736     if (chk < 0)
01737         ctxt->wellFormed = 0;
01738     ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
01739     ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
01740     }
01741 #endif /* LIBXML_VALID_ENABLED */
01742 
01743     if (prefix != NULL)
01744     xmlFree(prefix);
01745 
01746 }
01747 
01755 void
01756 xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
01757 {
01758     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
01759     xmlParserNodeInfo node_info;
01760     xmlNodePtr cur;
01761 
01762     if (ctx == NULL) return;
01763     cur = ctxt->node;
01764 #ifdef DEBUG_SAX
01765     if (name == NULL)
01766         xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n");
01767     else
01768     xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name);
01769 #endif
01770     
01771     /* Capture end position and add node */
01772     if (cur != NULL && ctxt->record_info) {
01773       node_info.end_pos = ctxt->input->cur - ctxt->input->base;
01774       node_info.end_line = ctxt->input->line;
01775       node_info.node = cur;
01776       xmlParserAddNodeInfo(ctxt, &node_info);
01777     }
01778     ctxt->nodemem = -1;
01779 
01780 #ifdef LIBXML_VALID_ENABLED
01781     if (ctxt->validate && ctxt->wellFormed &&
01782         ctxt->myDoc && ctxt->myDoc->intSubset)
01783         ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
01784                          cur);
01785 #endif /* LIBXML_VALID_ENABLED */
01786 
01787     
01788     /*
01789      * end of parsing of this node.
01790      */
01791 #ifdef DEBUG_SAX_TREE
01792     xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
01793 #endif
01794     nodePop(ctxt);
01795 }
01796 #endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */
01797 
01798 /*
01799  * xmlSAX2TextNode:
01800  * @ctxt:  the parser context
01801  * @str:  the input string
01802  * @len: the string length
01803  * 
01804  * Remove the entities from an attribute value
01805  *
01806  * Returns the newly allocated string or NULL if not needed or error
01807  */
01808 static xmlNodePtr
01809 xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
01810     xmlNodePtr ret;
01811     const xmlChar *intern = NULL;
01812 
01813     /*
01814      * Allocate
01815      */
01816     if (ctxt->freeElems != NULL) {
01817     ret = ctxt->freeElems;
01818     ctxt->freeElems = ret->next;
01819     ctxt->freeElemsNr--;
01820     } else {
01821     ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
01822     }
01823     if (ret == NULL) {
01824         xmlErrMemory(ctxt, "xmlSAX2Characters");
01825     return(NULL);
01826     }
01827     memset(ret, 0, sizeof(xmlNode));
01828     /*
01829      * intern the formatting blanks found between tags, or the
01830      * very short strings
01831      */
01832     if (ctxt->dictNames) {
01833         xmlChar cur = str[len];
01834 
01835     if ((len < (int) (2 * sizeof(void *))) &&
01836         (ctxt->options & XML_PARSE_COMPACT)) {
01837         /* store the string in the node overrithing properties and nsDef */
01838         xmlChar *tmp = (xmlChar *) &(ret->properties);
01839         memcpy(tmp, str, len);
01840         tmp[len] = 0;
01841         intern = tmp;
01842     } else if ((len <= 3) && ((cur == '"') || (cur == '\'') ||
01843         ((cur == '<') && (str[len + 1] != '!')))) {
01844         intern = xmlDictLookup(ctxt->dict, str, len);
01845     } else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') &&
01846                (str[len + 1] != '!')) {
01847         int i;
01848 
01849         for (i = 1;i < len;i++) {
01850         if (!IS_BLANK_CH(str[i])) goto skip;
01851         }
01852         intern = xmlDictLookup(ctxt->dict, str, len);
01853     }
01854     }
01855 skip:
01856     ret->type = XML_TEXT_NODE;
01857 
01858     ret->name = xmlStringText;
01859     if (intern == NULL) {
01860     ret->content = xmlStrndup(str, len);
01861     if (ret->content == NULL) {
01862         xmlSAX2ErrMemory(ctxt, "xmlSAX2TextNode");
01863         xmlFree(ret);
01864         return(NULL);
01865     }
01866     } else
01867     ret->content = (xmlChar *) intern;
01868 
01869     if (ctxt->input != NULL)
01870         ret->line = ctxt->input->line;
01871 
01872     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
01873     xmlRegisterNodeDefaultValue(ret);
01874     return(ret);
01875 }
01876 
01877 #ifdef LIBXML_VALID_ENABLED
01878 /*
01879  * xmlSAX2DecodeAttrEntities:
01880  * @ctxt:  the parser context
01881  * @str:  the input string
01882  * @len: the string length
01883  * 
01884  * Remove the entities from an attribute value
01885  *
01886  * Returns the newly allocated string or NULL if not needed or error
01887  */
01888 static xmlChar *
01889 xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
01890                           const xmlChar *end) {
01891     const xmlChar *in;
01892     xmlChar *ret;
01893 
01894     in = str;
01895     while (in < end)
01896         if (*in++ == '&')
01897         goto decode;
01898     return(NULL);
01899 decode:
01900     ctxt->depth++;
01901     ret = xmlStringLenDecodeEntities(ctxt, str, end - str,
01902                      XML_SUBSTITUTE_REF, 0,0,0);
01903     ctxt->depth--;
01904     return(ret);
01905 }
01906 #endif /* LIBXML_VALID_ENABLED */
01907 
01922 static void
01923 xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
01924                    const xmlChar * localname,
01925                    const xmlChar * prefix,
01926            const xmlChar * value,
01927            const xmlChar * valueend)
01928 {
01929     xmlAttrPtr ret;
01930     xmlNsPtr namespace = NULL;
01931     xmlChar *dup = NULL;
01932 
01933     /*
01934      * Note: if prefix == NULL, the attribute is not in the default namespace
01935      */
01936     if (prefix != NULL)
01937     namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);
01938 
01939     /*
01940      * allocate the node
01941      */
01942     if (ctxt->freeAttrs != NULL) {
01943         ret = ctxt->freeAttrs;
01944     ctxt->freeAttrs = ret->next;
01945     ctxt->freeAttrsNr--;
01946     memset(ret, 0, sizeof(xmlAttr));
01947     ret->type = XML_ATTRIBUTE_NODE;
01948 
01949     ret->parent = ctxt->node; 
01950     ret->doc = ctxt->myDoc;
01951     ret->ns = namespace;
01952 
01953     if (ctxt->dictNames)
01954         ret->name = localname;
01955     else
01956         ret->name = xmlStrdup(localname);
01957 
01958         /* link at the end to preserv order, TODO speed up with a last */
01959     if (ctxt->node->properties == NULL) {
01960         ctxt->node->properties = ret;
01961     } else {
01962         xmlAttrPtr prev = ctxt->node->properties;
01963 
01964         while (prev->next != NULL) prev = prev->next;
01965         prev->next = ret;
01966         ret->prev = prev;
01967     }
01968 
01969     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
01970         xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
01971     } else {
01972     if (ctxt->dictNames)
01973         ret = xmlNewNsPropEatName(ctxt->node, namespace, 
01974                                   (xmlChar *) localname, NULL);
01975     else
01976         ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL);
01977     if (ret == NULL) {
01978         xmlErrMemory(ctxt, "xmlSAX2AttributeNs");
01979         return;
01980     }
01981     }
01982 
01983     if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
01984     xmlNodePtr tmp;
01985 
01986     /*
01987      * We know that if there is an entity reference, then
01988      * the string has been dup'ed and terminates with 0
01989      * otherwise with ' or "
01990      */
01991     if (*valueend != 0) {
01992         tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
01993         ret->children = tmp;
01994         ret->last = tmp;
01995         if (tmp != NULL) {
01996         tmp->doc = ret->doc;
01997         tmp->parent = (xmlNodePtr) ret;
01998         }
01999     } else {
02000         ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
02001                             valueend - value);
02002         tmp = ret->children;
02003         while (tmp != NULL) {
02004             tmp->doc = ret->doc;
02005         tmp->parent = (xmlNodePtr) ret;
02006         if (tmp->next == NULL)
02007             ret->last = tmp;
02008         tmp = tmp->next;
02009         }
02010     }
02011     } else if (value != NULL) {
02012     xmlNodePtr tmp;
02013 
02014     tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
02015     ret->children = tmp;
02016     ret->last = tmp;
02017     if (tmp != NULL) {
02018         tmp->doc = ret->doc;
02019         tmp->parent = (xmlNodePtr) ret;
02020     }
02021     }
02022 
02023 #ifdef LIBXML_VALID_ENABLED
02024     if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
02025         ctxt->myDoc && ctxt->myDoc->intSubset) {
02026     /*
02027      * If we don't substitute entities, the validation should be
02028      * done on a value with replaced entities anyway.
02029      */
02030         if (!ctxt->replaceEntities) {
02031         dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend);
02032         if (dup == NULL) {
02033             if (*valueend == 0) {
02034             ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
02035                     ctxt->myDoc, ctxt->node, ret, value);
02036         } else {
02037             /*
02038              * That should already be normalized.
02039              * cheaper to finally allocate here than duplicate
02040              * entry points in the full validation code
02041              */
02042             dup = xmlStrndup(value, valueend - value);
02043 
02044             ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
02045                     ctxt->myDoc, ctxt->node, ret, dup);
02046         }
02047         } else {
02048             /*
02049          * dup now contains a string of the flattened attribute
02050          * content with entities substitued. Check if we need to
02051          * apply an extra layer of normalization.
02052          * It need to be done twice ... it's an extra burden related
02053          * to the ability to keep references in attributes
02054          */
02055         if (ctxt->attsSpecial != NULL) {
02056             xmlChar *nvalnorm;
02057             xmlChar fn[50];
02058             xmlChar *fullname;
02059             
02060             fullname = xmlBuildQName(localname, prefix, fn, 50);
02061             if (fullname != NULL) {
02062             ctxt->vctxt.valid = 1;
02063                 nvalnorm = xmlValidCtxtNormalizeAttributeValue(
02064                              &ctxt->vctxt, ctxt->myDoc,
02065                      ctxt->node, fullname, dup);
02066             if (ctxt->vctxt.valid != 1)
02067                 ctxt->valid = 0;
02068 
02069             if ((fullname != fn) && (fullname != localname))
02070                 xmlFree(fullname);
02071             if (nvalnorm != NULL) {
02072                 xmlFree(dup);
02073                 dup = nvalnorm;
02074             }
02075             }
02076         }
02077 
02078         ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
02079                     ctxt->myDoc, ctxt->node, ret, dup);
02080         }
02081     } else {
02082         /*
02083          * if entities already have been substitued, then
02084          * the attribute as passed is already normalized
02085          */
02086         dup = xmlStrndup(value, valueend - value);
02087 
02088         ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
02089                                  ctxt->myDoc, ctxt->node, ret, dup);
02090     }
02091     } else
02092 #endif /* LIBXML_VALID_ENABLED */
02093            if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
02094            (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
02095             ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
02096         /*
02097      * when validating, the ID registration is done at the attribute
02098      * validation level. Otherwise we have to do specific handling here.
02099      */
02100         if ((prefix == ctxt->str_xml) &&
02101                (localname[0] == 'i') && (localname[1] == 'd') &&
02102            (localname[2] == 0)) {
02103         /*
02104          * Add the xml:id value
02105          *
02106          * Open issue: normalization of the value.
02107          */
02108         if (dup == NULL)
02109             dup = xmlStrndup(value, valueend - value);
02110 #ifdef LIBXML_VALID_ENABLED
02111         if (xmlValidateNCName(dup, 1) != 0) {
02112             xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
02113               "xml:id : attribute value %s is not an NCName\n",
02114                 (const char *) dup, NULL);
02115         }
02116 #endif
02117         xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
02118     } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
02119         /* might be worth duplicate entry points and not copy */
02120         if (dup == NULL)
02121             dup = xmlStrndup(value, valueend - value);
02122         xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
02123     } else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
02124         if (dup == NULL)
02125             dup = xmlStrndup(value, valueend - value);
02126         xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret);
02127     }
02128     }
02129     if (dup != NULL)
02130     xmlFree(dup);
02131 }
02132 
02150 void
02151 xmlSAX2StartElementNs(void *ctx,
02152                       const xmlChar *localname,
02153               const xmlChar *prefix,
02154               const xmlChar *URI,
02155               int nb_namespaces,
02156               const xmlChar **namespaces,
02157               int nb_attributes,
02158               int nb_defaulted,
02159               const xmlChar **attributes)
02160 {
02161     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
02162     xmlNodePtr ret;
02163     xmlNodePtr parent;
02164     xmlNsPtr last = NULL, ns;
02165     const xmlChar *uri, *pref;
02166     int i, j;
02167 
02168     if (ctx == NULL) return;
02169     parent = ctxt->node;
02170     /*
02171      * First check on validity:
02172      */
02173     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && 
02174         ((ctxt->myDoc->intSubset == NULL) ||
02175      ((ctxt->myDoc->intSubset->notations == NULL) && 
02176       (ctxt->myDoc->intSubset->elements == NULL) &&
02177       (ctxt->myDoc->intSubset->attributes == NULL) && 
02178       (ctxt->myDoc->intSubset->entities == NULL)))) {
02179     xmlErrValid(ctxt, XML_ERR_NO_DTD,
02180       "Validation failed: no DTD found !", NULL, NULL);
02181     ctxt->validate = 0;
02182     }
02183 
02184     /*
02185      * allocate the node
02186      */
02187     if (ctxt->freeElems != NULL) {
02188         ret = ctxt->freeElems;
02189     ctxt->freeElems = ret->next;
02190     ctxt->freeElemsNr--;
02191     memset(ret, 0, sizeof(xmlNode));
02192     ret->type = XML_ELEMENT_NODE;
02193 
02194     if (ctxt->dictNames)
02195         ret->name = localname;
02196     else {
02197         ret->name = xmlStrdup(localname);
02198         if (ret->name == NULL) {
02199             xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
02200         return;
02201         }
02202     }
02203     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
02204         xmlRegisterNodeDefaultValue(ret);
02205     } else {
02206     if (ctxt->dictNames)
02207         ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, 
02208                                    (xmlChar *) localname, NULL);
02209     else
02210         ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
02211     if (ret == NULL) {
02212         xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
02213         return;
02214     }
02215     }
02216     if (ctxt->linenumbers) {
02217     if (ctxt->input != NULL) {
02218         if (ctxt->input->line < 65535)
02219         ret->line = (short) ctxt->input->line;
02220         else
02221             ret->line = 65535;
02222     }
02223     }
02224 
02225     if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
02226         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
02227     }
02228     /*
02229      * Build the namespace list
02230      */
02231     for (i = 0,j = 0;j < nb_namespaces;j++) {
02232         pref = namespaces[i++];
02233     uri = namespaces[i++];
02234     ns = xmlNewNs(NULL, uri, pref);
02235     if (ns != NULL) {
02236         if (last == NULL) {
02237             ret->nsDef = last = ns;
02238         } else {
02239             last->next = ns;
02240         last = ns;
02241         }
02242         if ((URI != NULL) && (prefix == pref))
02243         ret->ns = ns;
02244     } else {
02245             /*
02246              * any out of memory error would already have been raised
02247              * but we can't be garanteed it's the actual error due to the
02248              * API, best is to skip in this case
02249              */
02250         continue;
02251     }
02252 #ifdef LIBXML_VALID_ENABLED
02253     if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
02254         ctxt->myDoc && ctxt->myDoc->intSubset) {
02255         ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
02256                                                ret, prefix, ns, uri);
02257     }
02258 #endif /* LIBXML_VALID_ENABLED */
02259     }
02260     ctxt->nodemem = -1;
02261 
02262     /*
02263      * We are parsing a new node.
02264      */
02265     nodePush(ctxt, ret);
02266 
02267     /*
02268      * Link the child element
02269      */
02270     if (parent != NULL) {
02271         if (parent->type == XML_ELEMENT_NODE) {
02272         xmlAddChild(parent, ret);
02273     } else {
02274         xmlAddSibling(parent, ret);
02275     }
02276     }
02277 
02278     /*
02279      * Insert the defaulted attributes from the DTD only if requested:
02280      */
02281     if ((nb_defaulted != 0) &&
02282         ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0))
02283     nb_attributes -= nb_defaulted;
02284 
02285     /*
02286      * Search the namespace if it wasn't already found
02287      * Note that, if prefix is NULL, this searches for the default Ns
02288      */
02289     if ((URI != NULL) && (ret->ns == NULL)) {
02290         ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
02291     if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
02292         ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
02293     }
02294     if (ret->ns == NULL) {
02295         ns = xmlNewNs(ret, NULL, prefix);
02296         if (ns == NULL) {
02297 
02298             xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
02299         return;
02300         }
02301             if (prefix != NULL)
02302                 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
02303                              "Namespace prefix %s was not found\n",
02304                              prefix, NULL);
02305             else
02306                 xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
02307                              "Namespace default prefix was not found\n",
02308                              NULL, NULL);
02309     }
02310     }
02311 
02312     /*
02313      * process all the other attributes
02314      */
02315     if (nb_attributes > 0) {
02316         for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
02317         xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
02318                            attributes[j+3], attributes[j+4]);
02319     }
02320     }
02321 
02322 #ifdef LIBXML_VALID_ENABLED
02323     /*
02324      * If it's the Document root, finish the DTD validation and
02325      * check the document root element for validity
02326      */
02327     if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
02328     int chk;
02329 
02330     chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
02331     if (chk <= 0)
02332         ctxt->valid = 0;
02333     if (chk < 0)
02334         ctxt->wellFormed = 0;
02335     ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
02336     ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
02337     }
02338 #endif /* LIBXML_VALID_ENABLED */
02339 }
02340 
02351 void
02352 xmlSAX2EndElementNs(void *ctx,
02353                     const xmlChar * localname ATTRIBUTE_UNUSED,
02354                     const xmlChar * prefix ATTRIBUTE_UNUSED,
02355             const xmlChar * URI ATTRIBUTE_UNUSED)
02356 {
02357     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
02358     xmlParserNodeInfo node_info;
02359     xmlNodePtr cur;
02360 
02361     if (ctx == NULL) return;
02362     cur = ctxt->node;
02363     /* Capture end position and add node */
02364     if ((ctxt->record_info) && (cur != NULL)) {
02365         node_info.end_pos = ctxt->input->cur - ctxt->input->base;
02366         node_info.end_line = ctxt->input->line;
02367         node_info.node = cur;
02368         xmlParserAddNodeInfo(ctxt, &node_info);
02369     }
02370     ctxt->nodemem = -1;
02371 
02372 #ifdef LIBXML_VALID_ENABLED
02373     if (ctxt->validate && ctxt->wellFormed &&
02374         ctxt->myDoc && ctxt->myDoc->intSubset)
02375         ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur);
02376 #endif /* LIBXML_VALID_ENABLED */
02377 
02378     /*
02379      * end of parsing of this node.
02380      */
02381     nodePop(ctxt);
02382 }
02383 
02391 void
02392 xmlSAX2Reference(void *ctx, const xmlChar *name)
02393 {
02394     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
02395     xmlNodePtr ret;
02396 
02397     if (ctx == NULL) return;
02398 #ifdef DEBUG_SAX
02399     xmlGenericError(xmlGenericErrorContext,
02400         "SAX.xmlSAX2Reference(%s)\n", name);
02401 #endif
02402     if (name[0] == '#')
02403     ret = xmlNewCharRef(ctxt->myDoc, name);
02404     else
02405     ret = xmlNewReference(ctxt->myDoc, name);
02406 #ifdef DEBUG_SAX_TREE
02407     xmlGenericError(xmlGenericErrorContext,
02408         "add xmlSAX2Reference %s to %s \n", name, ctxt->node->name);
02409 #endif
02410     if (xmlAddChild(ctxt->node, ret) == NULL) {
02411         xmlFreeNode(ret);
02412     }
02413 }
02414 
02423 void
02424 xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
02425 {
02426     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
02427     xmlNodePtr lastChild;
02428 
02429     if (ctx == NULL) return;
02430 #ifdef DEBUG_SAX
02431     xmlGenericError(xmlGenericErrorContext,
02432         "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len);
02433 #endif
02434     /*
02435      * Handle the data if any. If there is no child
02436      * add it as content, otherwise if the last child is text,
02437      * concatenate it, else create a new node of type text.
02438      */
02439 
02440     if (ctxt->node == NULL) {
02441 #ifdef DEBUG_SAX_TREE
02442     xmlGenericError(xmlGenericErrorContext,
02443         "add chars: ctxt->node == NULL !\n");
02444 #endif
02445         return;
02446     }
02447     lastChild = ctxt->node->last;
02448 #ifdef DEBUG_SAX_TREE
02449     xmlGenericError(xmlGenericErrorContext,
02450         "add chars to %s \n", ctxt->node->name);
02451 #endif
02452 
02453     /*
02454      * Here we needed an accelerator mechanism in case of very large
02455      * elements. Use an attribute in the structure !!!
02456      */
02457     if (lastChild == NULL) {
02458         lastChild = xmlSAX2TextNode(ctxt, ch, len);
02459     if (lastChild != NULL) {
02460         ctxt->node->children = lastChild;
02461         ctxt->node->last = lastChild;
02462         lastChild->parent = ctxt->node;
02463         lastChild->doc = ctxt->node->doc;
02464         ctxt->nodelen = len;
02465         ctxt->nodemem = len + 1;
02466     } else {
02467         xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
02468         return;
02469     }
02470     } else {
02471     int coalesceText = (lastChild != NULL) &&
02472         (lastChild->type == XML_TEXT_NODE) &&
02473         (lastChild->name == xmlStringText);
02474     if ((coalesceText) && (ctxt->nodemem != 0)) {
02475         /*
02476          * The whole point of maintaining nodelen and nodemem,
02477          * xmlTextConcat is too costly, i.e. compute length,
02478          * reallocate a new buffer, move data, append ch. Here
02479          * We try to minimaze realloc() uses and avoid copying
02480          * and recomputing length over and over.
02481          */
02482         if (lastChild->content == (xmlChar *)&(lastChild->properties)) {
02483         lastChild->content = xmlStrdup(lastChild->content);
02484         lastChild->properties = NULL;
02485         } else if ((ctxt->nodemem == ctxt->nodelen + 1) &&
02486                    (xmlDictOwns(ctxt->dict, lastChild->content))) {
02487         lastChild->content = xmlStrdup(lastChild->content);
02488         }
02489             if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) &&
02490                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
02491                 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
02492                 return;
02493             }
02494         if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len || 
02495             (size_t)ctxt->nodemem + (size_t)len > SIZE_T_MAX / 2) {
02496                 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented");
02497                 return;
02498         }
02499         if (ctxt->nodelen + len >= ctxt->nodemem) {
02500         xmlChar *newbuf;
02501         size_t size;
02502 
02503         size = ctxt->nodemem + len;
02504         size *= 2;
02505                 newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
02506         if (newbuf == NULL) {
02507             xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
02508             return;
02509         }
02510         ctxt->nodemem = size;
02511         lastChild->content = newbuf;
02512         }
02513         memcpy(&lastChild->content[ctxt->nodelen], ch, len);
02514         ctxt->nodelen += len;
02515         lastChild->content[ctxt->nodelen] = 0;
02516     } else if (coalesceText) {
02517         if (xmlTextConcat(lastChild, ch, len)) {
02518         xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
02519         }
02520         if (ctxt->node->children != NULL) {
02521         ctxt->nodelen = xmlStrlen(lastChild->content);
02522         ctxt->nodemem = ctxt->nodelen + 1;
02523         }
02524     } else {
02525         /* Mixed content, first time */
02526         lastChild = xmlSAX2TextNode(ctxt, ch, len);
02527         if (lastChild != NULL) {
02528         xmlAddChild(ctxt->node, lastChild);
02529         if (ctxt->node->children != NULL) {
02530             ctxt->nodelen = len;
02531             ctxt->nodemem = len + 1;
02532         }
02533         }
02534     }
02535     }
02536 }
02537 
02547 void
02548 xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
02549 {
02550     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
02551 #ifdef DEBUG_SAX
02552     xmlGenericError(xmlGenericErrorContext,
02553         "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len);
02554 #endif
02555 }
02556 
02565 void
02566 xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
02567                       const xmlChar *data)
02568 {
02569     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
02570     xmlNodePtr ret;
02571     xmlNodePtr parent;
02572 
02573     if (ctx == NULL) return;
02574     parent = ctxt->node;
02575 #ifdef DEBUG_SAX
02576     xmlGenericError(xmlGenericErrorContext,
02577         "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data);
02578 #endif
02579 
02580     ret = xmlNewDocPI(ctxt->myDoc, target, data);
02581     if (ret == NULL) return;
02582 
02583     if (ctxt->linenumbers) {
02584     if (ctxt->input != NULL) {
02585         if (ctxt->input->line < 65535)
02586         ret->line = (short) ctxt->input->line;
02587         else
02588             ret->line = 65535;
02589     }
02590     }
02591     if (ctxt->inSubset == 1) {
02592     xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
02593     return;
02594     } else if (ctxt->inSubset == 2) {
02595     xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
02596     return;
02597     }
02598     if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
02599 #ifdef DEBUG_SAX_TREE
02600         xmlGenericError(xmlGenericErrorContext,
02601             "Setting PI %s as root\n", target);
02602 #endif
02603         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
02604     return;
02605     }
02606     if (parent->type == XML_ELEMENT_NODE) {
02607 #ifdef DEBUG_SAX_TREE
02608     xmlGenericError(xmlGenericErrorContext,
02609         "adding PI %s child to %s\n", target, parent->name);
02610 #endif
02611     xmlAddChild(parent, ret);
02612     } else {
02613 #ifdef DEBUG_SAX_TREE
02614     xmlGenericError(xmlGenericErrorContext,
02615         "adding PI %s sibling to ", target);
02616     xmlDebugDumpOneNode(stderr, parent, 0);
02617 #endif
02618     xmlAddSibling(parent, ret);
02619     }
02620 }
02621 
02629 void
02630 xmlSAX2Comment(void *ctx, const xmlChar *value)
02631 {
02632     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
02633     xmlNodePtr ret;
02634     xmlNodePtr parent;
02635 
02636     if (ctx == NULL) return;
02637     parent = ctxt->node;
02638 #ifdef DEBUG_SAX
02639     xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value);
02640 #endif
02641     ret = xmlNewDocComment(ctxt->myDoc, value);
02642     if (ret == NULL) return;
02643     if (ctxt->linenumbers) {
02644     if (ctxt->input != NULL) {
02645         if (ctxt->input->line < 65535)
02646         ret->line = (short) ctxt->input->line;
02647         else
02648             ret->line = 65535;
02649     }
02650     }
02651 
02652     if (ctxt->inSubset == 1) {
02653     xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
02654     return;
02655     } else if (ctxt->inSubset == 2) {
02656     xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
02657     return;
02658     }
02659     if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
02660 #ifdef DEBUG_SAX_TREE
02661         xmlGenericError(xmlGenericErrorContext,
02662             "Setting xmlSAX2Comment as root\n");
02663 #endif
02664         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
02665     return;
02666     }
02667     if (parent->type == XML_ELEMENT_NODE) {
02668 #ifdef DEBUG_SAX_TREE
02669     xmlGenericError(xmlGenericErrorContext,
02670         "adding xmlSAX2Comment child to %s\n", parent->name);
02671 #endif
02672     xmlAddChild(parent, ret);
02673     } else {
02674 #ifdef DEBUG_SAX_TREE
02675     xmlGenericError(xmlGenericErrorContext,
02676         "adding xmlSAX2Comment sibling to ");
02677     xmlDebugDumpOneNode(stderr, parent, 0);
02678 #endif
02679     xmlAddSibling(parent, ret);
02680     }
02681 }
02682 
02691 void
02692 xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
02693 {
02694     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
02695     xmlNodePtr ret, lastChild;
02696 
02697     if (ctx == NULL) return;
02698 #ifdef DEBUG_SAX
02699     xmlGenericError(xmlGenericErrorContext,
02700         "SAX.pcdata(%.10s, %d)\n", value, len);
02701 #endif
02702     lastChild = xmlGetLastChild(ctxt->node);
02703 #ifdef DEBUG_SAX_TREE
02704     xmlGenericError(xmlGenericErrorContext,
02705         "add chars to %s \n", ctxt->node->name);
02706 #endif
02707     if ((lastChild != NULL) &&
02708         (lastChild->type == XML_CDATA_SECTION_NODE)) {
02709     xmlTextConcat(lastChild, value, len);
02710     } else {
02711     ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
02712     xmlAddChild(ctxt->node, ret);
02713     }
02714 }
02715 
02716 static int xmlSAX2DefaultVersionValue = 2;
02717 
02718 #ifdef LIBXML_SAX1_ENABLED
02719 
02731 int
02732 xmlSAXDefaultVersion(int version)
02733 {
02734     int ret = xmlSAX2DefaultVersionValue;
02735 
02736     if ((version != 1) && (version != 2))
02737         return(-1);
02738     xmlSAX2DefaultVersionValue = version;
02739     return(ret);
02740 }
02741 #endif /* LIBXML_SAX1_ENABLED */
02742 
02752 int
02753 xmlSAXVersion(xmlSAXHandler *hdlr, int version)
02754 {
02755     if (hdlr == NULL) return(-1);
02756     if (version == 2) {
02757     hdlr->startElement = NULL;
02758     hdlr->endElement = NULL;
02759     hdlr->startElementNs = xmlSAX2StartElementNs;
02760     hdlr->endElementNs = xmlSAX2EndElementNs;
02761     hdlr->serror = NULL;
02762     hdlr->initialized = XML_SAX2_MAGIC;
02763 #ifdef LIBXML_SAX1_ENABLED
02764     } else if (version == 1) {
02765     hdlr->startElement = xmlSAX2StartElement;
02766     hdlr->endElement = xmlSAX2EndElement;
02767     hdlr->initialized = 1;
02768 #endif /* LIBXML_SAX1_ENABLED */
02769     } else
02770         return(-1);
02771     hdlr->internalSubset = xmlSAX2InternalSubset;
02772     hdlr->externalSubset = xmlSAX2ExternalSubset;
02773     hdlr->isStandalone = xmlSAX2IsStandalone;
02774     hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
02775     hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
02776     hdlr->resolveEntity = xmlSAX2ResolveEntity;
02777     hdlr->getEntity = xmlSAX2GetEntity;
02778     hdlr->getParameterEntity = xmlSAX2GetParameterEntity;
02779     hdlr->entityDecl = xmlSAX2EntityDecl;
02780     hdlr->attributeDecl = xmlSAX2AttributeDecl;
02781     hdlr->elementDecl = xmlSAX2ElementDecl;
02782     hdlr->notationDecl = xmlSAX2NotationDecl;
02783     hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl;
02784     hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
02785     hdlr->startDocument = xmlSAX2StartDocument;
02786     hdlr->endDocument = xmlSAX2EndDocument;
02787     hdlr->reference = xmlSAX2Reference;
02788     hdlr->characters = xmlSAX2Characters;
02789     hdlr->cdataBlock = xmlSAX2CDataBlock;
02790     hdlr->ignorableWhitespace = xmlSAX2Characters;
02791     hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
02792     hdlr->comment = xmlSAX2Comment;
02793     hdlr->warning = xmlParserWarning;
02794     hdlr->error = xmlParserError;
02795     hdlr->fatalError = xmlParserError;
02796 
02797     return(0);
02798 }
02799 
02807 void
02808 xmlSAX2InitDefaultSAXHandler(xmlSAXHandler *hdlr, int warning)
02809 {
02810     if ((hdlr == NULL) || (hdlr->initialized != 0))
02811     return;
02812 
02813     xmlSAXVersion(hdlr, xmlSAX2DefaultVersionValue);
02814     if (warning == 0)
02815     hdlr->warning = NULL;
02816     else
02817     hdlr->warning = xmlParserWarning;
02818 }
02819 
02825 void
02826 xmlDefaultSAXHandlerInit(void)
02827 {
02828 #ifdef LIBXML_SAX1_ENABLED
02829     xmlSAXVersion((xmlSAXHandlerPtr) &xmlDefaultSAXHandler, 1);
02830 #endif /* LIBXML_SAX1_ENABLED */
02831 }
02832 
02833 #ifdef LIBXML_HTML_ENABLED
02834 
02841 void
02842 xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr)
02843 {
02844     if ((hdlr == NULL) || (hdlr->initialized != 0))
02845     return;
02846 
02847     hdlr->internalSubset = xmlSAX2InternalSubset;
02848     hdlr->externalSubset = NULL;
02849     hdlr->isStandalone = NULL;
02850     hdlr->hasInternalSubset = NULL;
02851     hdlr->hasExternalSubset = NULL;
02852     hdlr->resolveEntity = NULL;
02853     hdlr->getEntity = xmlSAX2GetEntity;
02854     hdlr->getParameterEntity = NULL;
02855     hdlr->entityDecl = NULL;
02856     hdlr->attributeDecl = NULL;
02857     hdlr->elementDecl = NULL;
02858     hdlr->notationDecl = NULL;
02859     hdlr->unparsedEntityDecl = NULL;
02860     hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
02861     hdlr->startDocument = xmlSAX2StartDocument;
02862     hdlr->endDocument = xmlSAX2EndDocument;
02863     hdlr->startElement = xmlSAX2StartElement;
02864     hdlr->endElement = xmlSAX2EndElement;
02865     hdlr->reference = NULL;
02866     hdlr->characters = xmlSAX2Characters;
02867     hdlr->cdataBlock = xmlSAX2CDataBlock;
02868     hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
02869     hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
02870     hdlr->comment = xmlSAX2Comment;
02871     hdlr->warning = xmlParserWarning;
02872     hdlr->error = xmlParserError;
02873     hdlr->fatalError = xmlParserError;
02874 
02875     hdlr->initialized = 1;
02876 }
02877 
02883 void
02884 htmlDefaultSAXHandlerInit(void)
02885 {
02886     xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr) &htmlDefaultSAXHandler);
02887 }
02888 
02889 #endif /* LIBXML_HTML_ENABLED */
02890 
02891 #ifdef LIBXML_DOCB_ENABLED
02892 
02899 void
02900 xmlSAX2InitDocbDefaultSAXHandler(xmlSAXHandler *hdlr)
02901 {
02902     if ((hdlr == NULL) || (hdlr->initialized != 0))
02903     return;
02904 
02905     hdlr->internalSubset = xmlSAX2InternalSubset;
02906     hdlr->externalSubset = NULL;
02907     hdlr->isStandalone = xmlSAX2IsStandalone;
02908     hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
02909     hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
02910     hdlr->resolveEntity = xmlSAX2ResolveEntity;
02911     hdlr->getEntity = xmlSAX2GetEntity;
02912     hdlr->getParameterEntity = NULL;
02913     hdlr->entityDecl = xmlSAX2EntityDecl;
02914     hdlr->attributeDecl = NULL;
02915     hdlr->elementDecl = NULL;
02916     hdlr->notationDecl = NULL;
02917     hdlr->unparsedEntityDecl = NULL;
02918     hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
02919     hdlr->startDocument = xmlSAX2StartDocument;
02920     hdlr->endDocument = xmlSAX2EndDocument;
02921     hdlr->startElement = xmlSAX2StartElement;
02922     hdlr->endElement = xmlSAX2EndElement;
02923     hdlr->reference = xmlSAX2Reference;
02924     hdlr->characters = xmlSAX2Characters;
02925     hdlr->cdataBlock = NULL;
02926     hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
02927     hdlr->processingInstruction = NULL;
02928     hdlr->comment = xmlSAX2Comment;
02929     hdlr->warning = xmlParserWarning;
02930     hdlr->error = xmlParserError;
02931     hdlr->fatalError = xmlParserError;
02932 
02933     hdlr->initialized = 1;
02934 }
02935 
02941 void
02942 docbDefaultSAXHandlerInit(void)
02943 {
02944     xmlSAX2InitDocbDefaultSAXHandler((xmlSAXHandlerPtr) &docbDefaultSAXHandler);
02945 }
02946 
02947 #endif /* LIBXML_DOCB_ENABLED */
02948 #define bottom_SAX2
02949 #include "elfgcchack.h"

Generated on Sat May 19 2012 04:32:28 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.