Back to index

php5  5.3.10
compat.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Sterling Hughes <sterling@php.net>                          |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 #include "php.h"
00020 #if defined(HAVE_LIBXML) && (defined(HAVE_XML) || defined(HAVE_XMLRPC)) && !defined(HAVE_LIBEXPAT)
00021 #include "expat_compat.h"
00022 
00023 typedef struct _php_xml_ns {
00024        xmlNsPtr nsptr;
00025        int ref_count;
00026        void *next;
00027        void *prev;
00028 } php_xml_ns;
00029 
00030 #ifdef LIBXML_EXPAT_COMPAT
00031 
00032 #define IS_NS_DECL(__ns) \
00033        ((__ns) != NULL && strlen(__ns) == 5 && *(__ns) == 'x' && *((__ns)+1) == 'm' && \
00034         *((__ns)+2) == 'l' && *((__ns)+3) == 'n' && *((__ns)+4) == 's')
00035 
00036 static void 
00037 _qualify_namespace(XML_Parser parser, const xmlChar *name, const xmlChar *URI, xmlChar **qualified)
00038 {
00039        if (URI) {
00040                      /* Use libxml functions otherwise its memory deallocation is screwed up */
00041                      *qualified = xmlStrdup(URI);
00042                      *qualified = xmlStrncat(*qualified, parser->_ns_seperator, 1);
00043                      *qualified = xmlStrncat(*qualified, name, xmlStrlen(name));
00044        } else {
00045               *qualified = xmlStrdup(name);
00046        }
00047 }
00048 
00049 static void
00050 _start_element_handler(void *user, const xmlChar *name, const xmlChar **attributes)
00051 {
00052        XML_Parser  parser = (XML_Parser) user;
00053        xmlChar    *qualified_name = NULL;
00054 
00055        if (parser->h_start_element == NULL) {
00056               if (parser->h_default) {
00057                      int attno = 0;
00058 
00059                      qualified_name = xmlStrncatNew((xmlChar *)"<", name, xmlStrlen(name));
00060                      if (attributes) {
00061                             while (attributes[attno] != NULL) {
00062                                    int att_len;
00063                                    char *att_string, *att_name, *att_value;
00064 
00065                                    att_name = (char *)attributes[attno++];
00066                                    att_value = (char *)attributes[attno++];
00067 
00068                                    att_len = spprintf(&att_string, 0, " %s=\"%s\"", att_name, att_value);
00069 
00070                                    qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_string, att_len);
00071                                    efree(att_string);
00072                             }
00073 
00074                      }
00075                      qualified_name = xmlStrncat(qualified_name, (xmlChar *)">", 1);
00076                      parser->h_default(parser->user, (const XML_Char *) qualified_name, xmlStrlen(qualified_name));
00077                      xmlFree(qualified_name);
00078               }
00079               return;
00080        }
00081 
00082        qualified_name = xmlStrdup(name);
00083 
00084        parser->h_start_element(parser->user, (const XML_Char *) qualified_name, (const XML_Char **) attributes);
00085 
00086        xmlFree(qualified_name);
00087 }
00088 
00089 static void
00090 _start_element_handler_ns(void *user, const xmlChar *name, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, const xmlChar ** attributes)
00091 {
00092        XML_Parser  parser = (XML_Parser) user;
00093        xmlChar    *qualified_name = NULL;
00094        xmlChar **attrs = NULL;
00095        int i;
00096        int z = 0;
00097        int y = 0;
00098        
00099        if (nb_namespaces > 0 && parser->h_start_ns != NULL) {
00100               for (i = 0; i < nb_namespaces; i += 1) {
00101                      parser->h_start_ns(parser->user, (const XML_Char *) namespaces[y], (const XML_Char *) namespaces[y+1]);
00102                      y += 2;
00103               }
00104               y = 0;
00105        }
00106        
00107        if (parser->h_start_element == NULL) {
00108               if (parser->h_default) {
00109 
00110                      if (prefix) {
00111                             qualified_name = xmlStrncatNew((xmlChar *)"<", prefix, xmlStrlen(prefix));
00112                             qualified_name = xmlStrncat(qualified_name, (xmlChar *)":", 1);
00113                             qualified_name = xmlStrncat(qualified_name, name, xmlStrlen(name));
00114                      } else {
00115                             qualified_name = xmlStrncatNew((xmlChar *)"<", name, xmlStrlen(name));
00116                      }
00117                      
00118                      if (namespaces) {
00119                             int i, j;
00120                             for (i = 0,j = 0;j < nb_namespaces;j++) {
00121                                    int ns_len;
00122                                    char *ns_string, *ns_prefix, *ns_url;
00123                                    
00124                                    ns_prefix = (char *) namespaces[i++];
00125                                    ns_url = (char *) namespaces[i++];
00126                                    
00127                                    if (ns_prefix) {
00128                                           ns_len = spprintf(&ns_string, 0, " xmlns:%s=\"%s\"", ns_prefix, ns_url);
00129                                    } else {
00130                                           ns_len = spprintf(&ns_string, 0, " xmlns=\"%s\"", ns_url);
00131                                    }
00132                                    qualified_name = xmlStrncat(qualified_name, (xmlChar *)ns_string, ns_len);
00133                                    
00134                                    efree(ns_string);
00135                             }
00136                      }
00137                      
00138                      if (attributes) {
00139                             for (i = 0; i < nb_attributes; i += 1) {
00140                                    int att_len;
00141                                    char *att_string, *att_name, *att_value, *att_prefix, *att_valueend;
00142 
00143                                    att_name = (char *) attributes[y++];
00144                                    att_prefix = (char *)attributes[y++];
00145                                    y++;
00146                                    att_value = (char *)attributes[y++];
00147                                    att_valueend = (char *)attributes[y++];
00148 
00149                                    if (att_prefix) {
00150                                           att_len = spprintf(&att_string, 0, " %s:%s=\"", att_prefix, att_name);
00151                                    } else {
00152                                           att_len = spprintf(&att_string, 0, " %s=\"", att_name);
00153                                    }
00154 
00155                                    qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_string, att_len);
00156                                    qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_value, att_valueend - att_value);
00157                                    qualified_name = xmlStrncat(qualified_name, (xmlChar *)"\"", 1);
00158                                    
00159                                    efree(att_string);
00160                             }
00161 
00162                      }
00163                      qualified_name = xmlStrncat(qualified_name, (xmlChar *)">", 1);
00164                      parser->h_default(parser->user, (const XML_Char *) qualified_name, xmlStrlen(qualified_name));
00165                      xmlFree(qualified_name);
00166               }
00167               return;
00168        }
00169        _qualify_namespace(parser, name, URI, &qualified_name);
00170        
00171        if (attributes != NULL) {
00172               xmlChar    *qualified_name_attr = NULL;
00173               attrs = safe_emalloc((nb_attributes  * 2) + 1, sizeof(int *), 0);
00174 
00175               for (i = 0; i < nb_attributes; i += 1) {
00176 
00177                      if (attributes[y+1] != NULL) {
00178                             _qualify_namespace(parser, attributes[y] , attributes[y + 2], &qualified_name_attr);
00179                      } else {
00180                             qualified_name_attr = xmlStrdup(attributes[y]);
00181                      }
00182                      attrs[z] = qualified_name_attr;
00183                      attrs[z + 1] = xmlStrndup(attributes[y + 3] , (int) (attributes[y + 4] - attributes[y + 3]));
00184                      z += 2;
00185                      y += 5;
00186               }
00187 
00188               attrs[z] = NULL;
00189        }
00190        parser->h_start_element(parser->user, (const XML_Char *) qualified_name, (const XML_Char **) attrs);
00191        if (attrs) {
00192               for (i = 0; i < z; i++) {
00193                      xmlFree(attrs[i]);
00194               }
00195               efree(attrs);
00196        }
00197        xmlFree(qualified_name);
00198 }
00199 
00200 static void
00201 _namespace_handler(XML_Parser parser, xmlNsPtr nsptr)
00202 {
00203        if (nsptr != NULL) {
00204               _namespace_handler(parser, nsptr->next);
00205               parser->h_end_ns(parser->user, nsptr->prefix);
00206        }
00207 }
00208 
00209 static void
00210 _end_element_handler(void *user, const xmlChar *name)
00211 {
00212        xmlChar    *qualified_name;
00213        XML_Parser  parser = (XML_Parser) user;
00214 
00215        if (parser->h_end_element == NULL) {
00216               if (parser->h_default) {
00217                      char *end_element;
00218 
00219                      spprintf(&end_element, 0, "</%s>", (char *)name);
00220                      parser->h_default(parser->user, (const XML_Char *) end_element, strlen(end_element));
00221                      efree(end_element);
00222               }
00223               return;
00224        }
00225        
00226        qualified_name = xmlStrdup(name);
00227 
00228        parser->h_end_element(parser->user, (const XML_Char *) qualified_name);
00229 
00230        xmlFree(qualified_name);
00231 }
00232 
00233 static void
00234 _end_element_handler_ns(void *user, const xmlChar *name, const xmlChar * prefix, const xmlChar *URI)
00235 {
00236        xmlChar    *qualified_name;
00237        XML_Parser  parser = (XML_Parser) user;
00238 
00239        if (parser->h_end_element == NULL) {
00240               if (parser->h_default) {
00241                      char *end_element;
00242                      int end_element_len;
00243 
00244                      if (prefix) {
00245                             end_element_len = spprintf(&end_element, 0, "</%s:%s>", (char *) prefix, (char *)name);
00246                      } else {
00247                             end_element_len = spprintf(&end_element, 0, "</%s>", (char *)name);
00248                      }
00249                      parser->h_default(parser->user, (const XML_Char *) end_element, end_element_len);
00250                      efree(end_element);
00251               }
00252               return;
00253        }
00254 
00255        _qualify_namespace(parser, name, URI,  &qualified_name);
00256 
00257        parser->h_end_element(parser->user, (const XML_Char *) qualified_name);
00258 
00259        xmlFree(qualified_name);
00260 }
00261 
00262 static void
00263 _cdata_handler(void *user, const xmlChar *cdata, int cdata_len)
00264 {
00265        XML_Parser parser = (XML_Parser) user;
00266 
00267        if (parser->h_cdata == NULL) {
00268               if (parser->h_default) {
00269                      parser->h_default(parser->user, (const XML_Char *) cdata, cdata_len);
00270               }
00271               return;
00272        }
00273 
00274        parser->h_cdata(parser->user, (const XML_Char *) cdata, cdata_len);
00275 }
00276 
00277 static void
00278 _pi_handler(void *user, const xmlChar *target, const xmlChar *data)
00279 {
00280        XML_Parser parser = (XML_Parser) user;
00281 
00282        if (parser->h_pi == NULL) {
00283               if (parser->h_default) {
00284                      char    *full_pi;
00285                      spprintf(&full_pi, 0, "<?%s %s?>", (char *)target, (char *)data);
00286                      parser->h_default(parser->user, (const XML_Char *) full_pi, strlen(full_pi));
00287                      efree(full_pi);
00288               }
00289               return;
00290        }
00291 
00292        parser->h_pi(parser->user, (const XML_Char *) target, (const XML_Char *) data);
00293 }
00294 
00295 static void
00296 _unparsed_entity_decl_handler(void *user, 
00297                               const xmlChar *name, 
00298                                                    const xmlChar *pub_id, 
00299                                                    const xmlChar *sys_id, 
00300                                                    const xmlChar *notation)
00301 {
00302        XML_Parser parser = (XML_Parser) user;
00303 
00304        if (parser->h_unparsed_entity_decl == NULL) {
00305               return;
00306        }
00307 
00308        parser->h_unparsed_entity_decl(parser->user, name, NULL, sys_id, pub_id, notation);
00309 }
00310 
00311 static void
00312 _notation_decl_handler(void *user, const xmlChar *notation, const xmlChar *pub_id, const xmlChar *sys_id)
00313 {
00314        XML_Parser parser = (XML_Parser) user;
00315 
00316        if (parser->h_notation_decl == NULL) {
00317               return;
00318        }
00319 
00320        parser->h_notation_decl(parser->user, notation, NULL, sys_id, pub_id);
00321 }
00322 
00323 static void
00324 _build_comment(const xmlChar *data, int data_len, xmlChar **comment, int *comment_len)
00325 {
00326        *comment_len = data_len + 7;
00327        
00328        *comment = xmlMalloc(*comment_len + 1);
00329        memcpy(*comment, "<!--", 4);
00330        memcpy(*comment + 4, data, data_len);
00331        memcpy(*comment + 4 + data_len, "-->", 3);
00332 
00333        (*comment)[*comment_len] = '\0';
00334 }
00335 
00336 static void
00337 _comment_handler(void *user, const xmlChar *comment)
00338 {
00339        XML_Parser parser = (XML_Parser) user;
00340 
00341        if (parser->h_default) {
00342               xmlChar *d_comment;
00343               int      d_comment_len;
00344 
00345               _build_comment(comment, xmlStrlen(comment), &d_comment, &d_comment_len);
00346               parser->h_default(parser->user, d_comment, d_comment_len);
00347               xmlFree(d_comment);
00348        }
00349 }
00350 
00351 static void
00352 _build_entity(const xmlChar *name, int len, xmlChar **entity, int *entity_len) 
00353 {
00354        *entity_len = len + 2;
00355        *entity = xmlMalloc(*entity_len + 1);
00356        (*entity)[0] = '&';
00357        memcpy(*entity+1, name, len);
00358        (*entity)[len+1] = ';';
00359        (*entity)[*entity_len] = '\0';
00360 }
00361 
00362 static void
00363 _external_entity_ref_handler(void *user, const xmlChar *names, int type, const xmlChar *sys_id, const xmlChar *pub_id, xmlChar *content)
00364 {
00365        XML_Parser parser = (XML_Parser) user;
00366 
00367        if (parser->h_external_entity_ref == NULL) {
00368               return;
00369        }
00370 
00371        parser->h_external_entity_ref(parser, names, "", sys_id, pub_id);
00372 }
00373 
00374 static xmlEntityPtr
00375 _get_entity(void *user, const xmlChar *name)
00376 {
00377        XML_Parser parser = (XML_Parser) user;
00378        xmlEntityPtr ret = NULL;
00379 
00380        if (parser->parser->inSubset == 0) {
00381               ret = xmlGetPredefinedEntity(name);
00382               if (ret == NULL)
00383                      ret = xmlGetDocEntity(parser->parser->myDoc, name);
00384 
00385               if (ret == NULL || (parser->parser->instate != XML_PARSER_ENTITY_VALUE && parser->parser->instate != XML_PARSER_ATTRIBUTE_VALUE)) {
00386                      if (ret == NULL || ret->etype == XML_INTERNAL_GENERAL_ENTITY || ret->etype == XML_INTERNAL_PARAMETER_ENTITY || ret->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
00387                             /* Predefined entities will expand unless no cdata handler is present */
00388                             if (parser->h_default && ! (ret && ret->etype == XML_INTERNAL_PREDEFINED_ENTITY && parser->h_cdata)) {
00389                                    xmlChar *entity;
00390                                    int      len;
00391                                    
00392                                    _build_entity(name, xmlStrlen(name), &entity, &len);
00393                                    parser->h_default(parser->user, (const xmlChar *) entity, len);
00394                                    xmlFree(entity);
00395                             } else {
00396                                    /* expat will not expand internal entities if default handler is present otherwise
00397                                    it will expand and pass them to cdata handler */
00398                                    if (parser->h_cdata && ret) {
00399                                           parser->h_cdata(parser->user, ret->content, xmlStrlen(ret->content));
00400                                    }
00401                             }
00402                      } else {
00403                             if (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
00404                                    _external_entity_ref_handler(user, ret->name, ret->etype, ret->SystemID, ret->ExternalID, NULL);
00405                             }
00406                      }
00407               }
00408        }
00409 
00410        return ret;
00411 }
00412 
00413 static xmlSAXHandler 
00414 php_xml_compat_handlers = {
00415        NULL, /* internalSubset */
00416        NULL, /* isStandalone */
00417        NULL, /* hasInternalSubset */
00418        NULL, /* hasExternalSubset */
00419        NULL, /* resolveEntity */
00420        _get_entity, /* getEntity */
00421        NULL, /* entityDecl */
00422        _notation_decl_handler,
00423        NULL, /* attributeDecl */
00424        NULL, /* elementDecl */
00425        _unparsed_entity_decl_handler, /* unparsedEntity */
00426        NULL, /* setDocumentLocator */
00427        NULL, /* startDocument */
00428        NULL, /* endDocument */
00429        _start_element_handler, /* startElement */
00430        _end_element_handler, /* endElement */
00431        NULL, /* reference */
00432        _cdata_handler,
00433        NULL, /* ignorableWhitespace */
00434        _pi_handler,
00435        _comment_handler, /* comment */
00436        NULL, /* warning */
00437        NULL, /* error */
00438        NULL,  /* fatalError */
00439        NULL,  /* getParameterEntity */
00440        _cdata_handler, /* cdataBlock */
00441        NULL, /* externalSubset */
00442        XML_SAX2_MAGIC,
00443        NULL,
00444        _start_element_handler_ns,
00445        _end_element_handler_ns,
00446        NULL   
00447 };
00448 
00449 PHPAPI XML_Parser 
00450 XML_ParserCreate(const XML_Char *encoding)
00451 {
00452        return XML_ParserCreate_MM(encoding, NULL, NULL);
00453 }
00454 
00455 PHPAPI XML_Parser
00456 XML_ParserCreateNS(const XML_Char *encoding, const XML_Char sep)
00457 {
00458        XML_Char tmp[2];
00459        tmp[0] = sep;
00460        tmp[1] = '\0';
00461        return XML_ParserCreate_MM(encoding, NULL, tmp);
00462 }
00463 
00464 PHPAPI XML_Parser
00465 XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, const XML_Char *sep)
00466 {
00467        XML_Parser parser;
00468 
00469        parser = (XML_Parser) emalloc(sizeof(struct _XML_Parser));
00470        memset(parser, 0, sizeof(struct _XML_Parser));
00471        parser->use_namespace = 0;
00472        parser->_ns_seperator = NULL;
00473 
00474        parser->parser = xmlCreatePushParserCtxt((xmlSAXHandlerPtr) &php_xml_compat_handlers, (void *) parser, NULL, 0, NULL);
00475        if (parser->parser == NULL) {
00476               efree(parser);
00477               return NULL;
00478        }
00479 #if LIBXML_VERSION <= 20617
00480        /* for older versions of libxml2, allow correct detection of
00481         * charset in documents with a BOM: */
00482        parser->parser->charset = XML_CHAR_ENCODING_NONE;
00483 #endif
00484 
00485 #if LIBXML_VERSION >= 20703
00486        xmlCtxtUseOptions(parser->parser, XML_PARSE_OLDSAX);
00487 #endif
00488 
00489        parser->parser->replaceEntities = 1;
00490        parser->parser->wellFormed = 0;
00491        if (sep != NULL) {
00492               parser->use_namespace = 1;
00493               parser->parser->sax2 = 1;
00494               parser->_ns_seperator = xmlStrdup(sep);
00495        } else {
00496               /* Reset flag as XML_SAX2_MAGIC is needed for xmlCreatePushParserCtxt 
00497               so must be set in the handlers */
00498               parser->parser->sax->initialized = 1;
00499        }
00500        return parser;
00501 }
00502 
00503 PHPAPI void
00504 XML_SetUserData(XML_Parser parser, void *user)
00505 {
00506        parser->user = user;
00507 }
00508 
00509 PHPAPI void *
00510 XML_GetUserData(XML_Parser parser)
00511 {
00512        return parser->user;
00513 }
00514 
00515 PHPAPI void
00516 XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end)
00517 {
00518        parser->h_start_element = start;
00519        parser->h_end_element = end;
00520 }
00521 
00522 PHPAPI void
00523 XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler cdata)
00524 {
00525        parser->h_cdata = cdata;
00526 }
00527 
00528 PHPAPI void
00529 XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler pi)
00530 {
00531        parser->h_pi = pi;
00532 }
00533 
00534 PHPAPI void
00535 XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler comment)
00536 {
00537        parser->h_comment = comment;
00538 }
00539 
00540 PHPAPI void 
00541 XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler d)
00542 {
00543        parser->h_default = d;
00544 }
00545 
00546 PHPAPI void
00547 XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler unparsed_decl)
00548 {
00549        parser->h_unparsed_entity_decl = unparsed_decl;
00550 }
00551 
00552 PHPAPI void
00553 XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler notation_decl)
00554 {
00555        parser->h_notation_decl = notation_decl;
00556 }
00557 
00558 PHPAPI void
00559 XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler ext_entity)
00560 {
00561        parser->h_external_entity_ref = ext_entity;
00562 }
00563 
00564 PHPAPI void
00565 XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start_ns)
00566 {
00567        parser->h_start_ns = start_ns;
00568 }
00569 
00570 PHPAPI void
00571 XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end_ns)
00572 {
00573        parser->h_end_ns = end_ns;
00574 }
00575 
00576 PHPAPI int
00577 XML_Parse(XML_Parser parser, const XML_Char *data, int data_len, int is_final)
00578 {
00579        int error;
00580 
00581 /* The following is a hack to keep BC with PHP 4 while avoiding 
00582 the inifite loop in libxml <= 2.6.17 which occurs when no encoding 
00583 has been defined and none can be detected */
00584 #if LIBXML_VERSION <= 20617
00585        if (parser->parser->charset == XML_CHAR_ENCODING_NONE) {
00586               if (data_len >= 4 || (parser->parser->input->buf->buffer->use + data_len >= 4)) {
00587                      xmlChar start[4];
00588                      int char_count;
00589 
00590                      char_count = parser->parser->input->buf->buffer->use;
00591                      if (char_count > 4) {
00592                             char_count = 4;
00593                      }
00594 
00595                      memcpy(start, parser->parser->input->buf->buffer->content, (size_t)char_count);
00596                      memcpy(start + char_count, data, (size_t)(4 - char_count));
00597 
00598                      if (xmlDetectCharEncoding(&start[0], 4) == XML_CHAR_ENCODING_NONE) {
00599                             parser->parser->charset = XML_CHAR_ENCODING_UTF8;
00600                      }
00601               }
00602        }
00603 #endif
00604 
00605        error = xmlParseChunk(parser->parser, data, data_len, is_final);
00606        if (!error) {
00607               return 1;
00608        } else if (parser->parser->lastError.level > XML_ERR_WARNING ){
00609               return 0;
00610        } else {
00611               return 1;
00612        }
00613 }
00614 
00615 PHPAPI int
00616 XML_GetErrorCode(XML_Parser parser)
00617 {
00618        return parser->parser->errNo;
00619 }
00620 
00621 static const XML_Char *const error_mapping[] = {
00622        "No error",
00623        "No memory",
00624        "Invalid document start",
00625        "Empty document",
00626        "Not well-formed (invalid token)",
00627        "Invalid document end",
00628        "Invalid hexadecimal character reference",
00629        "Invalid decimal character reference",
00630        "Invalid character reference",
00631        "Invalid character",
00632        "XML_ERR_CHARREF_AT_EOF",
00633        "XML_ERR_CHARREF_IN_PROLOG",
00634        "XML_ERR_CHARREF_IN_EPILOG",
00635        "XML_ERR_CHARREF_IN_DTD",
00636        "XML_ERR_ENTITYREF_AT_EOF",
00637        "XML_ERR_ENTITYREF_IN_PROLOG",
00638        "XML_ERR_ENTITYREF_IN_EPILOG",
00639        "XML_ERR_ENTITYREF_IN_DTD",
00640        "PEReference at end of document",
00641        "PEReference in prolog",
00642        "PEReference in epilog",
00643        "PEReference: forbidden within markup decl in internal subset",
00644        "XML_ERR_ENTITYREF_NO_NAME",
00645        "EntityRef: expecting ';'",
00646        "PEReference: no name",
00647        "PEReference: expecting ';'",
00648        "Undeclared entity error",
00649        "Undeclared entity warning",
00650        "Unparsed Entity",
00651        "XML_ERR_ENTITY_IS_EXTERNAL",
00652        "XML_ERR_ENTITY_IS_PARAMETER",
00653        "Unknown encoding",
00654        "Unsupported encoding",
00655        "String not started expecting ' or \"",
00656        "String not closed expecting \" or '",
00657        "Namespace declaration error",
00658        "EntityValue: \" or ' expected",
00659        "EntityValue: \" or ' expected",
00660        "< in attribute",
00661        "Attribute not started",
00662        "Attribute not finished",
00663        "Attribute without value",
00664        "Attribute redefined",
00665        "SystemLiteral \" or ' expected",
00666        "SystemLiteral \" or ' expected",
00667        /* "XML_ERR_COMMENT_NOT_STARTED", <= eliminated on purpose */
00668        "Comment not finished",
00669        "Processing Instruction not started",
00670        "Processing Instruction not finished",
00671        "NOTATION: Name expected here",
00672        "'>' required to close NOTATION declaration",
00673        "'(' required to start ATTLIST enumeration",
00674        "'(' required to start ATTLIST enumeration",
00675        "MixedContentDecl : '|' or ')*' expected",
00676        "XML_ERR_MIXED_NOT_FINISHED",
00677        "ELEMENT in DTD not started",
00678        "ELEMENT in DTD not finished",
00679        "XML declaration not started",
00680        "XML declaration not finished",
00681        "XML_ERR_CONDSEC_NOT_STARTED",
00682        "XML conditional section not closed",
00683        "Content error in the external subset",
00684        "DOCTYPE not finished",
00685        "Sequence ']]>' not allowed in content",
00686        "CDATA not finished",
00687        "Reserved XML Name",
00688        "Space required",
00689        "XML_ERR_SEPARATOR_REQUIRED",
00690        "NmToken expected in ATTLIST enumeration",
00691        "XML_ERR_NAME_REQUIRED",
00692        "MixedContentDecl : '#PCDATA' expected",
00693        "SYSTEM or PUBLIC, the URI is missing",
00694        "PUBLIC, the Public Identifier is missing",
00695        "< required",
00696        "> required",
00697        "</ required",
00698        "= required",
00699        "Mismatched tag",
00700        "Tag not finished",
00701        "standalone accepts only 'yes' or 'no'",
00702        "Invalid XML encoding name",
00703        "Comment must not contain '--' (double-hyphen)",
00704        "Invalid encoding",
00705        "external parsed entities cannot be standalone",
00706        "XML conditional section '[' expected",
00707        "Entity value required",
00708        "chunk is not well balanced",
00709        "extra content at the end of well balanced chunk",
00710     "XML_ERR_ENTITY_CHAR_ERROR",
00711     "PEReferences forbidden in internal subset",
00712     "Detected an entity reference loop",
00713     "XML_ERR_ENTITY_BOUNDARY",
00714     "Invalid URI",
00715     "Fragment not allowed",
00716     "XML_WAR_CATALOG_PI",
00717     "XML_ERR_NO_DTD",
00718     "conditional section INCLUDE or IGNORE keyword expected", /* 95 */
00719     "Version in XML Declaration missing", /* 96 */
00720     "XML_WAR_UNKNOWN_VERSION", /* 97 */
00721     "XML_WAR_LANG_VALUE", /* 98 */
00722     "XML_WAR_NS_URI", /* 99 */
00723     "XML_WAR_NS_URI_RELATIVE", /* 100 */
00724     "Missing encoding in text declaration" /* 101 */
00725 };
00726 
00727 PHPAPI const XML_Char *
00728 XML_ErrorString(int code)
00729 {
00730        if (code < 0 || code >= (int)(sizeof(error_mapping) / sizeof(error_mapping[0]))) {
00731               return "Unknown";
00732        }
00733        return error_mapping[code];
00734 }
00735 
00736 PHPAPI int
00737 XML_GetCurrentLineNumber(XML_Parser parser)
00738 {
00739        return parser->parser->input->line;
00740 }
00741 
00742 PHPAPI int
00743 XML_GetCurrentColumnNumber(XML_Parser parser)
00744 {
00745        return parser->parser->input->col;
00746 }
00747 
00748 PHPAPI int
00749 XML_GetCurrentByteIndex(XML_Parser parser)
00750 {
00751        return parser->parser->input->consumed +
00752                      (parser->parser->input->cur - parser->parser->input->base);
00753 }
00754 
00755 PHPAPI int
00756 XML_GetCurrentByteCount(XML_Parser parser)
00757 {
00758        /* WARNING: this is identical to ByteIndex; it should probably
00759         * be different */
00760        return parser->parser->input->consumed +
00761                      (parser->parser->input->cur - parser->parser->input->base);
00762 }
00763 
00764 PHPAPI const XML_Char *XML_ExpatVersion(void)
00765 {
00766        return "1.0";
00767 }
00768 
00769 PHPAPI void
00770 XML_ParserFree(XML_Parser parser)
00771 {
00772        if (parser->use_namespace) {
00773               if (parser->_ns_seperator) {
00774                      xmlFree(parser->_ns_seperator);
00775               }
00776        }
00777        if (parser->parser->myDoc) {
00778               xmlFreeDoc(parser->parser->myDoc);
00779               parser->parser->myDoc = NULL;
00780        }
00781        xmlFreeParserCtxt(parser->parser);
00782        efree(parser);
00783 }
00784 
00785 #endif /* LIBXML_EXPAT_COMPAT */
00786 #endif
00787