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