xml/libxml2libs/src/libxml2/libxml2_tree.c
changeset 0 e35f40988205
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 /*
       
     2  * libxml2_tree.c : implementation of access function for an XML tree.
       
     3  *
       
     4  * References:
       
     5  *   XHTML 1.0 W3C REC: http://www.w3.org/TR/2002/REC-xhtml1-20020801/
       
     6  *
       
     7  * See Copyright for the status of this software.
       
     8  *
       
     9  * daniel@veillard.com
       
    10  *
       
    11  * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
       
    12  *
       
    13  */
       
    14 #pragma warning(disable: 4127 4132)
       
    15 
       
    16 #define IN_LIBXML
       
    17 
       
    18 #include "xmlenglibxml.h"
       
    19 
       
    20 #include <stdlib.h>
       
    21 #include <string.h> /* for memset() only ! */
       
    22 
       
    23 
       
    24 #ifdef HAVE_CTYPE_H
       
    25 #include <ctype.h>
       
    26 #endif
       
    27 #ifdef HAVE_STDLIB_H
       
    28 #include <stdlib.h>
       
    29 #endif
       
    30 #ifdef HAVE_ZLIB_H
       
    31 #include <zlib.h>
       
    32 #endif
       
    33 
       
    34 #include <stdapis/libxml2/libxml2_globals.h>
       
    35 #include <stdapis/libxml2/libxml2_uri.h>
       
    36 #include <stdapis/libxml2/libxml2_parserinternals.h>
       
    37 #include "libxml2_xmlerror2.h"
       
    38 
       
    39 #ifdef LIBXML_HTML_ENABLED
       
    40 #include "libxml2_htmltree.h"
       
    41 #endif
       
    42 
       
    43 
       
    44 xmlNsPtr xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
       
    45 
       
    46 /************************************************************************
       
    47  *                                                                      *
       
    48  *      Tree memory error handler                                       *
       
    49  *                                                                      *
       
    50  ************************************************************************/
       
    51 /**
       
    52  * xmlTreeErrMemory:
       
    53  * @param extra extra informations
       
    54  *
       
    55  * Handle an out of memory condition
       
    56  */
       
    57 static void
       
    58 xmlTreeErrMemory(const char *extra)
       
    59 {
       
    60     __xmlSimpleError(XML_FROM_TREE, XML_ERR_NO_MEMORY, NULL, NULL, extra);
       
    61 }
       
    62 
       
    63 /**
       
    64  * xmlTreeErr:
       
    65  * @param code the error number
       
    66  * @param extra extra informations
       
    67  *
       
    68  * Handle an out of memory condition
       
    69  */
       
    70 static void
       
    71 xmlTreeErr(int code, xmlNodePtr node, const char *extra)
       
    72 {
       
    73     const char *msg = NULL;
       
    74 
       
    75     switch(code) {
       
    76         case XML_TREE_INVALID_HEX:
       
    77         msg = EMBED_ERRTXT("invalid hexadecimal character value");
       
    78         break;
       
    79     case XML_TREE_INVALID_DEC:
       
    80         msg = "invalid decimal character value";
       
    81         break;
       
    82     case XML_TREE_UNTERMINATED_ENTITY:
       
    83         msg = EMBED_ERRTXT("unterminated entity reference %15s");
       
    84         break;
       
    85     default:
       
    86         msg = EMBED_ERRTXT("unexpected error number");
       
    87     }
       
    88     __xmlSimpleError(XML_FROM_TREE, code, node, msg, extra);
       
    89 }
       
    90 
       
    91 
       
    92 /************************************************************************
       
    93  *                                                                      *
       
    94  *      A few static variables and macros                               *
       
    95  *                                                                      *
       
    96  ************************************************************************/
       
    97 
       
    98 
       
    99 #define UPDATE_LAST_CHILD_AND_PARENT(n)                             \
       
   100     if ((n) != NULL) {                                              \
       
   101         xmlNodePtr ulccur = (n)->children;                          \
       
   102         if (ulccur == NULL) {                                       \
       
   103             (n)->last = NULL;                                       \
       
   104         } else {                                                    \
       
   105             while (ulccur->next != NULL) {                          \
       
   106                 ulccur->parent = (n);                               \
       
   107             ulccur = ulccur->next;                                  \
       
   108         }                                                           \
       
   109         ulccur->parent = (n);                                       \
       
   110         (n)->last = ulccur;                                         \
       
   111     }}
       
   112 
       
   113 /* #define DEBUG_BUFFER */
       
   114 /* #define DEBUG_TREE */
       
   115 
       
   116 /************************************************************************
       
   117  *                                                                      *
       
   118  *      Functions to move to entities.c once the                        *
       
   119  *      API freeze is smoothen and they can be made public.             *
       
   120  *                                                                      *
       
   121  ************************************************************************/
       
   122 //#include "libxml/Libxml2_hash.h" // included via parser.h
       
   123 
       
   124 #ifdef LIBXML_TREE_ENABLED
       
   125 /**
       
   126  * xmlGetEntityFromDtd:
       
   127  * @param dtd A pointer to the DTD to search
       
   128  * @param name The entity name
       
   129  *
       
   130  * Do an entity lookup in the DTD entity hash table and
       
   131  * return the corresponding entity, if found.
       
   132  *
       
   133  * Returns A pointer to the entity structure or NULL if not found.
       
   134  */
       
   135 static xmlEntityPtr
       
   136 xmlGetEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
       
   137     xmlEntitiesTablePtr table;
       
   138 
       
   139     if((dtd != NULL) && (dtd->entities != NULL)) {
       
   140         table = (xmlEntitiesTablePtr) dtd->entities;
       
   141         return((xmlEntityPtr) xmlHashLookup(table, name));
       
   142         /* return(xmlGetEntityFromTable(table, name)); */
       
   143     }
       
   144     return(NULL);
       
   145 }
       
   146 /**
       
   147  * xmlGetParameterEntityFromDtd:
       
   148  * @param dtd A pointer to the DTD to search
       
   149  * @param name The entity name
       
   150  *
       
   151  * Do an entity lookup in the DTD pararmeter entity hash table and
       
   152  * return the corresponding entity, if found.
       
   153  *
       
   154  * Returns A pointer to the entity structure or NULL if not found.
       
   155  */
       
   156 static xmlEntityPtr
       
   157 xmlGetParameterEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
       
   158     xmlEntitiesTablePtr table;
       
   159 
       
   160     if ((dtd != NULL) && (dtd->pentities != NULL)) {
       
   161     table = (xmlEntitiesTablePtr) dtd->pentities;
       
   162     return((xmlEntityPtr) xmlHashLookup(table, name));
       
   163     /* return(xmlGetEntityFromTable(table, name)); */
       
   164     }
       
   165     return(NULL);
       
   166 }
       
   167 #endif /* LIBXML_TREE_ENABLED */
       
   168 
       
   169 /************************************************************************
       
   170  *                                                                      *
       
   171  *          QName handling helper                                       *
       
   172  *                                                                      *
       
   173  ************************************************************************/
       
   174 
       
   175 /**
       
   176  * xmlBuildQName:
       
   177  * @param ncname the Name
       
   178  * @param prefix the prefix
       
   179  * @param memory preallocated memory
       
   180  * @param len preallocated memory length
       
   181  *
       
   182  * Builds the QName prefix:ncname in memory if there is enough space
       
   183  * and prefix is not NULL nor empty, otherwise allocate a new string.
       
   184  * If prefix is NULL or empty it returns ncname.
       
   185  *
       
   186  * Returns the new string which must be freed by the caller if different from
       
   187  *         memory and ncname or NULL in case of error
       
   188  *
       
   189  * OOM: possible --> returns NULL, OOM flag is set
       
   190  */
       
   191 XMLPUBFUNEXPORT xmlChar*
       
   192 xmlBuildQName(const xmlChar* ncname, const xmlChar* prefix,
       
   193               xmlChar* memory, int len)
       
   194 {
       
   195     int lenn, lenp;
       
   196     xmlChar* ret;
       
   197 
       
   198     if (!ncname || !prefix)
       
   199         return((xmlChar*)ncname);
       
   200 
       
   201     lenn = strlen((char*) ncname);
       
   202     lenp = strlen((char*) prefix);
       
   203 
       
   204     if (!memory || (len < lenn + lenp + 2))
       
   205     {
       
   206         ret = (xmlChar*) xmlMallocAtomic(lenn + lenp + 2);
       
   207         if (!ret) {
       
   208             xmlTreeErrMemory(EMBED_ERRTXT("building QName"));
       
   209             return(ret);
       
   210         }
       
   211     } else {
       
   212         ret = memory;
       
   213     }
       
   214     memcpy(&ret[0], prefix, lenp);
       
   215     ret[lenp] = ':';
       
   216     memcpy(&ret[lenp + 1], ncname, lenn);
       
   217     ret[lenn + lenp + 1] = 0;
       
   218     return(ret);
       
   219 }
       
   220 
       
   221 /**
       
   222  * xmlSplitQName2:
       
   223  * @param name the full QName
       
   224  * @param prefix a xmlChar **
       
   225  *
       
   226  * parse an XML qualified name string
       
   227  *
       
   228  * [NS 5] QName ::= (Prefix ':')? LocalPart
       
   229  *
       
   230  * [NS 6] Prefix ::= NCName
       
   231  *
       
   232  * [NS 7] LocalPart ::= NCName
       
   233  *
       
   234  * Returns NULL if not a QName, otherwise the local part, and prefix
       
   235  *   is updated to get the Prefix if any.
       
   236  *
       
   237  * OOM: possible --> when returns NULL and OOM flag is set
       
   238  */
       
   239 
       
   240 XMLPUBFUNEXPORT xmlChar*
       
   241 xmlSplitQName2(const xmlChar *name, xmlChar **prefix)
       
   242 {
       
   243     int len;
       
   244     xmlChar* ret; // = NULL;
       
   245 
       
   246     *prefix = NULL;
       
   247     if (!name)
       
   248         return(NULL);
       
   249 
       
   250 #ifndef XML_XML_NAMESPACE
       
   251     /* xml: prefix is not really a namespace */
       
   252     if ((name[0] == 'x') && (name[1] == 'm') &&
       
   253         (name[2] == 'l') && (name[3] == ':'))
       
   254         return(NULL);
       
   255 #endif
       
   256 
       
   257     /* nasty but valid */
       
   258     if (name[0] == ':')
       
   259         return(NULL);
       
   260 
       
   261     /*
       
   262      * we are not trying to validate but just to cut, and yes it will
       
   263      * work even if this is as set of UTF-8 encoded chars
       
   264      */
       
   265     len = 0;
       
   266     while ((name[len] != 0) && (name[len] != ':'))
       
   267         len++;
       
   268 
       
   269     if (name[len] == 0)
       
   270         return(NULL);
       
   271 
       
   272     *prefix = xmlStrndup(name, len);
       
   273     if (!*prefix)
       
   274         goto OOM_exit;
       
   275 
       
   276     ret = xmlStrdup(&name[len + 1]);
       
   277     if (!ret) {
       
   278         if (*prefix) {
       
   279             xmlFree(*prefix);
       
   280             *prefix = NULL;
       
   281         }
       
   282 OOM_exit:
       
   283         xmlTreeErrMemory(EMBED_ERRTXT("QName split"));
       
   284         return(NULL);
       
   285     }
       
   286 
       
   287     return(ret);
       
   288 }
       
   289 
       
   290 /**
       
   291  * xmlSplitQName3:
       
   292  * @param name the full QName
       
   293  * @param len an int *
       
   294  *
       
   295  * parse an XML qualified name string,i
       
   296  *
       
   297  * returns NULL if it is not a Qualified Name, otherwise, update len
       
   298  *         with the lenght in byte of the prefix and return a pointer
       
   299  */
       
   300 
       
   301 XMLPUBFUNEXPORT const xmlChar *
       
   302 xmlSplitQName3(const xmlChar *name, int *len) {
       
   303     int i = 0;
       
   304 
       
   305     if (name == NULL) return(NULL);
       
   306     if (len == NULL) return(NULL);
       
   307 
       
   308     /* nasty but valid */
       
   309     if (name[0] == ':')
       
   310         return(NULL);
       
   311 
       
   312     /*
       
   313      * we are not trying to validate but just to cut, and yes it will
       
   314      * work even if this is as set of UTF-8 encoded chars
       
   315      */
       
   316     while ((name[i] != 0) && (name[i] != ':'))
       
   317         i++;
       
   318 
       
   319     if (name[i] == 0)
       
   320         return(NULL);
       
   321 
       
   322     *len = i;
       
   323 
       
   324     return(&name[i+1]);
       
   325 }
       
   326 
       
   327 /************************************************************************
       
   328  *                                                                      *
       
   329  *      Check Name, NCName and QName strings                            *
       
   330  *                                                                      *
       
   331  ************************************************************************/
       
   332 
       
   333 #define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l)
       
   334 
       
   335 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
       
   336 /**
       
   337  * xmlValidateNCName:
       
   338  * @param value the value to check
       
   339  * @param space allow spaces in front and end of the string
       
   340  *
       
   341  * Check that a value conforms to the lexical space of NCName
       
   342  *
       
   343  * Returns 0 if this validates, a positive error code number otherwise
       
   344  *         and -1 in case of internal or API error.
       
   345  */
       
   346 XMLPUBFUNEXPORT int
       
   347 xmlValidateNCName(const xmlChar *value, int space) {
       
   348     const xmlChar *cur = value;
       
   349     int c,l;
       
   350 
       
   351     /*
       
   352      * First quick algorithm for ASCII range
       
   353      */
       
   354     if (space)
       
   355     while (IS_BLANK_CH(*cur)) cur++;
       
   356     if (((*cur >= 'a') && (*cur <= 'z')) ||
       
   357         ((*cur >= 'A') && (*cur <= 'Z')) ||
       
   358         (*cur == '_'))
       
   359         cur++;
       
   360     else
       
   361         goto try_complex;
       
   362 
       
   363     while (((*cur >= 'a') && (*cur <= 'z')) ||
       
   364         ((*cur >= 'A') && (*cur <= 'Z')) ||
       
   365         ((*cur >= '0') && (*cur <= '9')) ||
       
   366          (*cur == '_') || (*cur == '-') || (*cur == '.'))
       
   367     {
       
   368         cur++;
       
   369     }
       
   370     if (space)
       
   371         while (IS_BLANK_CH(*cur)) cur++;
       
   372 
       
   373     if (*cur == 0)
       
   374         return(0);
       
   375 
       
   376 try_complex:
       
   377     /*
       
   378      * Second check for chars outside the ASCII range
       
   379      */
       
   380     cur = value;
       
   381     c = CUR_SCHAR(cur, l);
       
   382     if (space) {
       
   383         while (IS_BLANK(c)) {
       
   384             cur += l;
       
   385             c = CUR_SCHAR(cur, l);
       
   386         }
       
   387     }
       
   388     if ((!IS_LETTER(c)) && (c != '_'))
       
   389         return(1);
       
   390 
       
   391     cur += l;
       
   392     c = CUR_SCHAR(cur, l);
       
   393     while (IS_LETTER(c) || IS_DIGIT(c) ||
       
   394           (c == '.') || (c == '-') || (c == '_') ||
       
   395            IS_COMBINING(c) || IS_EXTENDER(c))
       
   396     {
       
   397         cur += l;
       
   398         c = CUR_SCHAR(cur, l);
       
   399     }
       
   400     if (space) {
       
   401         while (IS_BLANK(c)) {
       
   402             cur += l;
       
   403             c = CUR_SCHAR(cur, l);
       
   404         }
       
   405     }
       
   406     if (c != 0)
       
   407         return(1);
       
   408 
       
   409     return(0);
       
   410 }
       
   411 #endif
       
   412 
       
   413 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
       
   414 /**
       
   415  * xmlValidateQName:
       
   416  * @param value the value to check
       
   417  * @param space allow spaces in front and end of the string
       
   418  *
       
   419  * Check that a value conforms to the lexical space of QName
       
   420  *
       
   421  * Returns 0 if this validates, a positive error code number otherwise
       
   422  *         and -1 in case of internal or API error.
       
   423  */
       
   424 XMLPUBFUNEXPORT int
       
   425 xmlValidateQName(const xmlChar *value, int space) {
       
   426     const xmlChar *cur = value;
       
   427     int c,l;
       
   428 
       
   429     /*
       
   430      * First quick algorithm for ASCII range
       
   431      */
       
   432     if (space)
       
   433     while (IS_BLANK_CH(*cur)) cur++;
       
   434     if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) ||
       
   435     (*cur == '_'))
       
   436     cur++;
       
   437     else
       
   438     goto try_complex;
       
   439     while (((*cur >= 'a') && (*cur <= 'z')) ||
       
   440        ((*cur >= 'A') && (*cur <= 'Z')) ||
       
   441        ((*cur >= '0') && (*cur <= '9')) ||
       
   442        (*cur == '_') || (*cur == '-') || (*cur == '.'))
       
   443     cur++;
       
   444     if (*cur == ':') {
       
   445     cur++;
       
   446     if (((*cur >= 'a') && (*cur <= 'z')) ||
       
   447         ((*cur >= 'A') && (*cur <= 'Z')) ||
       
   448         (*cur == '_'))
       
   449         cur++;
       
   450     else
       
   451         goto try_complex;
       
   452     while (((*cur >= 'a') && (*cur <= 'z')) ||
       
   453            ((*cur >= 'A') && (*cur <= 'Z')) ||
       
   454            ((*cur >= '0') && (*cur <= '9')) ||
       
   455            (*cur == '_') || (*cur == '-') || (*cur == '.'))
       
   456         cur++;
       
   457     }
       
   458     if (space)
       
   459     while (IS_BLANK_CH(*cur)) cur++;
       
   460     if (*cur == 0)
       
   461     return(0);
       
   462 
       
   463 try_complex:
       
   464     /*
       
   465      * Second check for chars outside the ASCII range
       
   466      */
       
   467     cur = value;
       
   468     c = CUR_SCHAR(cur, l);
       
   469     if (space) {
       
   470     while (IS_BLANK(c)) {
       
   471         cur += l;
       
   472         c = CUR_SCHAR(cur, l);
       
   473     }
       
   474     }
       
   475     if ((!IS_LETTER(c)) && (c != '_'))
       
   476     return(1);
       
   477     cur += l;
       
   478     c = CUR_SCHAR(cur, l);
       
   479     while (IS_LETTER(c) || IS_DIGIT(c) || (c == '.') ||
       
   480        (c == '-') || (c == '_') || IS_COMBINING(c) ||
       
   481        IS_EXTENDER(c)) {
       
   482     cur += l;
       
   483     c = CUR_SCHAR(cur, l);
       
   484     }
       
   485     if (c == ':') {
       
   486     cur += l;
       
   487     c = CUR_SCHAR(cur, l);
       
   488     if ((!IS_LETTER(c)) && (c != '_'))
       
   489         return(1);
       
   490     cur += l;
       
   491     c = CUR_SCHAR(cur, l);
       
   492     while (IS_LETTER(c) || IS_DIGIT(c) || (c == '.') ||
       
   493            (c == '-') || (c == '_') || IS_COMBINING(c) ||
       
   494            IS_EXTENDER(c)) {
       
   495         cur += l;
       
   496         c = CUR_SCHAR(cur, l);
       
   497     }
       
   498     }
       
   499     if (space) {
       
   500     while (IS_BLANK(c)) {
       
   501         cur += l;
       
   502         c = CUR_SCHAR(cur, l);
       
   503     }
       
   504     }
       
   505     if (c != 0)
       
   506     return(1);
       
   507     return(0);
       
   508 }
       
   509 
       
   510 /**
       
   511  * xmlValidateName:
       
   512  * @param value the value to check
       
   513  * @param space allow spaces in front and end of the string
       
   514  *
       
   515  * Check that a value conforms to the lexical space of Name
       
   516  *
       
   517  * Returns 0 if this validates, a positive error code number otherwise
       
   518  *         and -1 in case of internal or API error.
       
   519  */
       
   520 XMLPUBFUNEXPORT int
       
   521 xmlValidateName(const xmlChar *value, int space) {
       
   522     const xmlChar *cur = value;
       
   523     int c,l;
       
   524 
       
   525     /*
       
   526      * First quick algorithm for ASCII range
       
   527      */
       
   528     if (space)
       
   529     while (IS_BLANK_CH(*cur)) cur++;
       
   530     if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) ||
       
   531     (*cur == '_') || (*cur == ':'))
       
   532     cur++;
       
   533     else
       
   534     goto try_complex;
       
   535     while (((*cur >= 'a') && (*cur <= 'z')) ||
       
   536        ((*cur >= 'A') && (*cur <= 'Z')) ||
       
   537        ((*cur >= '0') && (*cur <= '9')) ||
       
   538        (*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':'))
       
   539     cur++;
       
   540     if (space)
       
   541     while (IS_BLANK_CH(*cur)) cur++;
       
   542     if (*cur == 0)
       
   543     return(0);
       
   544 
       
   545 try_complex:
       
   546     /*
       
   547      * Second check for chars outside the ASCII range
       
   548      */
       
   549     cur = value;
       
   550     c = CUR_SCHAR(cur, l);
       
   551     if (space) {
       
   552     while (IS_BLANK(c)) {
       
   553         cur += l;
       
   554         c = CUR_SCHAR(cur, l);
       
   555     }
       
   556     }
       
   557     if ((!IS_LETTER(c)) && (c != '_') && (c != ':'))
       
   558     return(1);
       
   559     cur += l;
       
   560     c = CUR_SCHAR(cur, l);
       
   561     while (IS_LETTER(c) || IS_DIGIT(c) || (c == '.') || (c == ':') ||
       
   562        (c == '-') || (c == '_') || IS_COMBINING(c) || IS_EXTENDER(c)) {
       
   563     cur += l;
       
   564     c = CUR_SCHAR(cur, l);
       
   565     }
       
   566     if (space) {
       
   567     while (IS_BLANK(c)) {
       
   568         cur += l;
       
   569         c = CUR_SCHAR(cur, l);
       
   570     }
       
   571     }
       
   572     if (c != 0)
       
   573     return(1);
       
   574     return(0);
       
   575 }
       
   576 
       
   577 /**
       
   578  * xmlValidateNMToken:
       
   579  * @param value the value to check
       
   580  * @param space allow spaces in front and end of the string
       
   581  *
       
   582  * Check that a value conforms to the lexical space of NMToken
       
   583  *
       
   584  * Returns 0 if this validates, a positive error code number otherwise
       
   585  *         and -1 in case of internal or API error.
       
   586  */
       
   587 XMLPUBFUNEXPORT int
       
   588 xmlValidateNMToken(const xmlChar *value, int space) {
       
   589     const xmlChar *cur = value;
       
   590     int c,l;
       
   591 
       
   592     /*
       
   593      * First quick algorithm for ASCII range
       
   594      */
       
   595     if (space)
       
   596     while (IS_BLANK_CH(*cur)) cur++;
       
   597     if (((*cur >= 'a') && (*cur <= 'z')) ||
       
   598         ((*cur >= 'A') && (*cur <= 'Z')) ||
       
   599         ((*cur >= '0') && (*cur <= '9')) ||
       
   600         (*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':'))
       
   601     cur++;
       
   602     else
       
   603     goto try_complex;
       
   604     while (((*cur >= 'a') && (*cur <= 'z')) ||
       
   605        ((*cur >= 'A') && (*cur <= 'Z')) ||
       
   606        ((*cur >= '0') && (*cur <= '9')) ||
       
   607        (*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':'))
       
   608     cur++;
       
   609     if (space)
       
   610     while (IS_BLANK_CH(*cur)) cur++;
       
   611     if (*cur == 0)
       
   612     return(0);
       
   613 
       
   614 try_complex:
       
   615     /*
       
   616      * Second check for chars outside the ASCII range
       
   617      */
       
   618     cur = value;
       
   619     c = CUR_SCHAR(cur, l);
       
   620     if (space) {
       
   621     while (IS_BLANK(c)) {
       
   622         cur += l;
       
   623         c = CUR_SCHAR(cur, l);
       
   624     }
       
   625     }
       
   626     if (!(IS_LETTER(c) || IS_DIGIT(c) || (c == '.') || (c == ':') ||
       
   627         (c == '-') || (c == '_') || IS_COMBINING(c) || IS_EXTENDER(c)))
       
   628     return(1);
       
   629     cur += l;
       
   630     c = CUR_SCHAR(cur, l);
       
   631     while (IS_LETTER(c) || IS_DIGIT(c) || (c == '.') || (c == ':') ||
       
   632        (c == '-') || (c == '_') || IS_COMBINING(c) || IS_EXTENDER(c)) {
       
   633     cur += l;
       
   634     c = CUR_SCHAR(cur, l);
       
   635     }
       
   636     if (space) {
       
   637     while (IS_BLANK(c)) {
       
   638         cur += l;
       
   639         c = CUR_SCHAR(cur, l);
       
   640     }
       
   641     }
       
   642     if (c != 0)
       
   643     return(1);
       
   644     return(0);
       
   645 }
       
   646 #endif /* LIBXML_TREE_ENABLED */
       
   647 
       
   648 /************************************************************************
       
   649  *                                  *
       
   650  *      Allocation and deallocation of basic structures     *
       
   651  *                                  *
       
   652  ************************************************************************/
       
   653 
       
   654 /**
       
   655  * xmlSetBufferAllocationScheme:
       
   656  * @param scheme allocation method to use
       
   657  *
       
   658  * Set the buffer allocation method.  Types are
       
   659  * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
       
   660  * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
       
   661  *                             improves performance
       
   662  */
       
   663 XMLPUBFUNEXPORT void
       
   664 xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
       
   665 	LOAD_GS_DIRECT
       
   666     xmlBufferAllocScheme = scheme;
       
   667 }
       
   668 
       
   669 #ifndef XMLENGINE_EXCLUDE_UNUSED
       
   670 /**
       
   671  * xmlGetBufferAllocationScheme:
       
   672  *
       
   673  * Types are
       
   674  * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
       
   675  * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
       
   676  *                             improves performance
       
   677  *
       
   678  * Returns the current allocation scheme
       
   679  */
       
   680 xmlBufferAllocationScheme
       
   681 xmlGetBufferAllocationScheme(void) {
       
   682     
       
   683     return(xmlBufferAllocScheme);
       
   684 }
       
   685 #endif /* ifndef XMLENGINE_EXCLUDE_UNUSED */
       
   686 
       
   687 /**
       
   688  * xmlNewNs:
       
   689  * @param node:  the element carrying the namespace
       
   690  * @param href:  the URI associated
       
   691  * @param prefix:  the prefix for the namespace
       
   692  *
       
   693  * Creation of a new Namespace. This function will refuse to create
       
   694  * a namespace with a similar prefix than an existing one present on this
       
   695  * node.
       
   696  * We use href==NULL in the case of an element creation where the namespace
       
   697  * was not defined.
       
   698  * Returns a new namespace pointer or NULL
       
   699  *
       
   700  * OOM: possible --> sets OOM flag and returns NULL
       
   701  *    Check OOM flag always!  (NULL may be if node!=NULL && prefix is already bound)
       
   702  */
       
   703 XMLPUBFUNEXPORT xmlNsPtr
       
   704 xmlNewNs(xmlNodePtr node, const xmlChar* href, const xmlChar* prefix)
       
   705 {
       
   706 	xmlNsPtr cur;
       
   707 	LOAD_GS_SAFE_NODE(node)
       
   708 	
       
   709     if ( (  node &&
       
   710             node->type != XML_ELEMENT_NODE )
       
   711             ||
       
   712          ( prefix &&
       
   713            xmlStrEqual(prefix, BAD_CAST "xml") ) )
       
   714     {
       
   715         return(NULL);
       
   716     }
       
   717     /*
       
   718      * Allocate a new Namespace and fill the fields.
       
   719      */
       
   720      
       
   721     cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
       
   722     if (!cur)
       
   723         goto OOM;
       
   724 
       
   725     memset(cur, 0, sizeof(xmlNs));
       
   726     cur->type = XML_LOCAL_NAMESPACE;
       
   727 
       
   728     cur->href   = href   ? xmlStrdup(href)  : href   /* NULL */;
       
   729     cur->prefix = prefix ? xmlStrdup(prefix): prefix /* NULL */;
       
   730 
       
   731     if (OOM_FLAG){
       
   732         xmlFreeNs(cur);
       
   733 OOM:
       
   734         xmlTreeErrMemory(EMBED_ERRTXT("building namespace"));
       
   735         return(NULL);
       
   736     }
       
   737     /*
       
   738      * Add it at the end to preserve parsing order ...
       
   739      * and checks for existing use of the prefix
       
   740      */
       
   741     if (node) {
       
   742         if (!node->nsDef) {
       
   743             // No namespaces so far, so add this new as the only one
       
   744             node->nsDef = cur;
       
   745         } else {
       
   746 
       
   747             xmlNsPtr prev = node->nsDef;
       
   748 
       
   749             if ((!prev->prefix && !cur->prefix) ||
       
   750                  xmlStrEqual(prev->prefix, cur->prefix))
       
   751              {
       
   752                 // there is already such namespace {pref and URI} active
       
   753                 // so do nothing
       
   754                 xmlFreeNs(cur);
       
   755                 return(NULL);
       
   756             }
       
   757             while (prev->next)
       
   758             {
       
   759                 prev = prev->next;
       
   760                 
       
   761                 if ((!prev->prefix && !cur->prefix) ||
       
   762                     xmlStrEqual(prev->prefix, cur->prefix))
       
   763                 {
       
   764                     xmlFreeNs(cur);
       
   765                     return(NULL);
       
   766                 }
       
   767             }
       
   768             prev->next = cur;
       
   769         }
       
   770     }
       
   771     return(cur);
       
   772 }
       
   773 
       
   774 
       
   775 /**
       
   776  * xmlSetNs:
       
   777  * @param node a node in the document
       
   778  * @param ns a namespace pointer
       
   779  *
       
   780  * Associate a namespace to a node, a posteriori.
       
   781  */
       
   782 XMLPUBFUNEXPORT void
       
   783 xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
       
   784     if (!node) {
       
   785 #ifdef DEBUG_TREE
       
   786         xmlGenericError(xmlGenericErrorContext, "xmlSetNs: node == NULL\n");
       
   787 #endif
       
   788         return;
       
   789     }
       
   790     node->ns = ns;
       
   791 }
       
   792 
       
   793 /**
       
   794  * xmlFreeNs:
       
   795  * @param cur the namespace pointer
       
   796  *
       
   797  * Free up the structures associated to a namespace
       
   798  *
       
   799  * OOM: never
       
   800  * Precondition: cur is not NULL
       
   801  */
       
   802 XMLPUBFUNEXPORT void
       
   803 xmlFreeNs(xmlNsPtr cur)
       
   804 {
       
   805 #ifdef DEBUG_TREE
       
   806     if (!cur) {
       
   807         xmlGenericError(xmlGenericErrorContext, "xmlFreeNs : ns == NULL\n");
       
   808         return;
       
   809     }
       
   810 #endif
       
   811     if (cur->href)
       
   812         xmlFree((char*) cur->href);
       
   813     if (cur->prefix)
       
   814         xmlFree((char*) cur->prefix);
       
   815     xmlFree(cur);
       
   816 }
       
   817 
       
   818 /**
       
   819  * xmlFreeNsList:
       
   820  * @param cur the first namespace pointer
       
   821  *
       
   822  * Free up all the structures associated to the chained namespaces.
       
   823  *
       
   824  * OOM: never
       
   825  */
       
   826 XMLPUBFUNEXPORT void
       
   827 xmlFreeNsList(xmlNsPtr cur)
       
   828 {
       
   829     xmlNsPtr next;
       
   830 
       
   831 #ifdef DEBUG_TREE
       
   832     if (cur == NULL) {
       
   833         xmlGenericError(xmlGenericErrorContext, "xmlFreeNsList : ns == NULL\n");
       
   834         return;
       
   835     }
       
   836 #endif
       
   837     
       
   838     while (cur != NULL) {
       
   839         next = cur->next;
       
   840         xmlFreeNs(cur);
       
   841         cur = next;
       
   842     }
       
   843 }
       
   844 
       
   845 /**
       
   846  * xmlNewDtd:
       
   847  * @param doc the document pointer
       
   848  * @param name the DTD name
       
   849  * @param ExternalID the external ID
       
   850  * @param SystemID the system ID
       
   851  *
       
   852  * Creation of a new DTD for the external subset. To create an
       
   853  * internal subset, use xmlCreateIntSubset().
       
   854  *
       
   855  * Returns a pointer to the new DTD structure
       
   856  *
       
   857  * OOM: possible --> if returns NULL,  OOM flag is set too
       
   858  */
       
   859 XMLPUBFUNEXPORT xmlDtdPtr
       
   860 xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
       
   861                     const xmlChar *ExternalID, const xmlChar *SystemID) {
       
   862     xmlDtdPtr cur;
       
   863     LOAD_GS_SAFE_DOC(doc)                    
       
   864 
       
   865     if (doc && doc->extSubset) {
       
   866 #ifdef DEBUG_TREE
       
   867         xmlGenericError(xmlGenericErrorContext,
       
   868         "xmlNewDtd(%s): document %s already have a DTD %s\n",
       
   869         /* !!! */ (char *) name, doc->name,
       
   870         /* !!! */ (char *)doc->extSubset->name);
       
   871 #endif
       
   872         return(NULL);
       
   873     }
       
   874 
       
   875     /*
       
   876      * Allocate a new DTD and fill the fields.
       
   877      */
       
   878     cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
       
   879     if (!cur)
       
   880         goto OOM;
       
   881 
       
   882     memset(cur, 0 , sizeof(xmlDtd));
       
   883     cur->type = XML_DTD_NODE;
       
   884 
       
   885     cur->name       = name       ? xmlStrdup(name)       : name /* NULL */;
       
   886     cur->ExternalID = ExternalID ? xmlStrdup(ExternalID) : ExternalID /* NULL */;
       
   887     cur->SystemID   = SystemID   ? xmlStrdup(SystemID)   : SystemID /* NULL */;
       
   888 
       
   889     if(OOM_FLAG){
       
   890         
       
   891         if(cur->name)
       
   892             xmlFree((void*)cur->name);
       
   893         if(cur->ExternalID)
       
   894             xmlFree((void*)cur->ExternalID);
       
   895         if(cur->SystemID)
       
   896             xmlFree((void*)cur->SystemID);
       
   897         xmlFree(cur);
       
   898 OOM:
       
   899         xmlTreeErrMemory(EMBED_ERRTXT("building DTD"));
       
   900         return(NULL);
       
   901     }
       
   902 
       
   903     if (doc){
       
   904         cur->doc = doc;
       
   905         doc->extSubset = cur;
       
   906     }
       
   907 
       
   908     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)){
       
   909         
       
   910         xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
       
   911     }
       
   912     return(cur);
       
   913 }
       
   914 
       
   915 /**
       
   916  * xmlGetIntSubset:
       
   917  * @param doc the document pointer
       
   918  *
       
   919  * Get the internal subset of a document
       
   920  * Returns a pointer to the DTD structure or NULL if not found
       
   921  */
       
   922 
       
   923 XMLPUBFUNEXPORT xmlDtdPtr
       
   924 xmlGetIntSubset(xmlDocPtr doc) {
       
   925     xmlNodePtr cur;
       
   926 
       
   927     if (doc == NULL)
       
   928         return(NULL);
       
   929 
       
   930     cur = doc->children;
       
   931     while (cur != NULL) {
       
   932         if (cur->type == XML_DTD_NODE)
       
   933             return((xmlDtdPtr) cur);
       
   934         cur = cur->next;
       
   935     }
       
   936     return((xmlDtdPtr) doc->intSubset);
       
   937 }
       
   938 
       
   939 /**
       
   940  * xmlCreateIntSubset:
       
   941  * @param doc the document pointer
       
   942  * @param name the DTD name
       
   943  * @param ExternalID the external (PUBLIC) ID
       
   944  * @param SystemID the system ID
       
   945  *
       
   946  * Create the internal subset of a document
       
   947  * Returns a pointer to the new DTD structure
       
   948  */
       
   949 XMLPUBFUNEXPORT xmlDtdPtr
       
   950 xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
       
   951                    const xmlChar *ExternalID, const xmlChar *SystemID) {
       
   952     xmlDtdPtr cur;
       
   953     LOAD_GS_SAFE_DOC(doc)                   
       
   954 
       
   955     if ((doc != NULL) && (xmlGetIntSubset(doc) != NULL)) {
       
   956 #ifdef DEBUG_TREE
       
   957         xmlGenericError(xmlGenericErrorContext,
       
   958              "xmlCreateIntSubset(): document %s already have an internal subset\n",
       
   959             doc->name);
       
   960 #endif
       
   961     return(NULL);
       
   962     }
       
   963 
       
   964     /*
       
   965      * Allocate a new DTD and fill the fields.
       
   966      */
       
   967     cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
       
   968     if (cur == NULL) {
       
   969         xmlTreeErrMemory(EMBED_ERRTXT("building internal subset"));
       
   970         return(NULL);
       
   971     }
       
   972     memset(cur, 0, sizeof(xmlDtd));
       
   973     cur->type = XML_DTD_NODE;
       
   974 
       
   975     if (name != NULL)
       
   976     cur->name = xmlStrdup(name);
       
   977     if (ExternalID != NULL)
       
   978     cur->ExternalID = xmlStrdup(ExternalID);
       
   979     if (SystemID != NULL)
       
   980     cur->SystemID = xmlStrdup(SystemID);
       
   981     if (doc != NULL) {
       
   982         doc->intSubset = cur;
       
   983         cur->parent = doc;
       
   984         cur->doc = doc;
       
   985         if (doc->children == NULL) {
       
   986             doc->children = (xmlNodePtr) cur;
       
   987             doc->last = (xmlNodePtr) cur;
       
   988         } else {
       
   989             if (doc->type == XML_HTML_DOCUMENT_NODE) {
       
   990                 xmlNodePtr prev;
       
   991 
       
   992                 prev = doc->children;
       
   993                 prev->prev = (xmlNodePtr) cur;
       
   994                 cur->next = prev;
       
   995                 doc->children = (xmlNodePtr) cur;
       
   996             } else {
       
   997                 xmlNodePtr next;
       
   998 
       
   999                 next = doc->children;
       
  1000                 while ((next != NULL) && (next->type != XML_ELEMENT_NODE))
       
  1001                     next = next->next;
       
  1002                 if (next == NULL) {
       
  1003                     cur->prev = doc->last;
       
  1004                     cur->prev->next = (xmlNodePtr) cur;
       
  1005                     cur->next = NULL;
       
  1006                     doc->last = (xmlNodePtr) cur;
       
  1007                 } else {
       
  1008                     cur->next = next;
       
  1009                     cur->prev = next->prev;
       
  1010                     if (cur->prev == NULL)
       
  1011                     doc->children = (xmlNodePtr) cur;
       
  1012                     else
       
  1013                     cur->prev->next = (xmlNodePtr) cur;
       
  1014                     next->prev = (xmlNodePtr) cur;
       
  1015                 }
       
  1016             }
       
  1017         }
       
  1018     }
       
  1019 
       
  1020     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  1021     xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
       
  1022     return(cur);
       
  1023 }
       
  1024 
       
  1025 /**
       
  1026  * DICT_FREE:
       
  1027  * @param str a string
       
  1028  *
       
  1029  * Free a string if it is not owned by the "dict" dictionnary in the
       
  1030  * current scope
       
  1031  */
       
  1032 #define DICT_FREE(str)                      \
       
  1033     if ((str) && ((!dict) ||                \
       
  1034         (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
       
  1035         xmlFree((char *)(str));
       
  1036 
       
  1037 /**
       
  1038  * xmlFreeDtd:
       
  1039  * @param cur the DTD structure to free up
       
  1040  *
       
  1041  * Free a DTD structure.
       
  1042  */
       
  1043 XMLPUBFUNEXPORT void
       
  1044 xmlFreeDtd(xmlDtdPtr cur) {
       
  1045     xmlDictPtr dict = NULL;
       
  1046     LOAD_GS_SAFE_DTD(cur)
       
  1047 
       
  1048     if (cur == NULL) {
       
  1049     return;
       
  1050     }
       
  1051     if (cur->doc)
       
  1052         dict = cur->doc->dict;
       
  1053 
       
  1054     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
       
  1055     xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
       
  1056 
       
  1057     if (cur->children != NULL) {
       
  1058     xmlNodePtr next, c = cur->children;
       
  1059 
       
  1060     /*
       
  1061      * Cleanup all the DTD comments they are not in the DTD
       
  1062      * indexes.
       
  1063      */
       
  1064         while (c != NULL) {
       
  1065         next = c->next;
       
  1066         if ((c->type == XML_COMMENT_NODE) || (c->type == XML_PI_NODE)) {
       
  1067         xmlUnlinkNode(c);
       
  1068         xmlFreeNode(c);
       
  1069         }
       
  1070         c = next;
       
  1071     }
       
  1072     }
       
  1073     DICT_FREE(cur->name)
       
  1074     DICT_FREE(cur->SystemID)
       
  1075     DICT_FREE(cur->ExternalID)
       
  1076     
       
  1077     if (cur->notations != NULL)
       
  1078         xmlFreeNotationTable((xmlNotationTablePtr) cur->notations);
       
  1079 
       
  1080     if (cur->elements != NULL)
       
  1081         xmlFreeElementTable((xmlElementTablePtr) cur->elements);
       
  1082     if (cur->attributes != NULL)
       
  1083         xmlFreeAttributeTable((xmlAttributeTablePtr) cur->attributes);
       
  1084     if (cur->entities != NULL)
       
  1085         xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities);
       
  1086     if (cur->pentities != NULL)
       
  1087         xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->pentities);
       
  1088 
       
  1089     xmlFree(cur);
       
  1090 }
       
  1091 
       
  1092 /**
       
  1093  * xmlNewDoc:
       
  1094  * @param version xmlChar string giving the version of XML "1.0"
       
  1095  *
       
  1096  * Creates a new XML document
       
  1097  *
       
  1098  * Returns a new document
       
  1099  *
       
  1100  * OOM: possible --> returns NULL, OOM flag is set
       
  1101  */
       
  1102 XMLPUBFUNEXPORT xmlDocPtr
       
  1103 xmlNewDoc(const xmlChar *version) {
       
  1104 	DEFINE_GS_PROXY
       
  1105     xmlDocPtr cur;
       
  1106     int i = 0;    
       
  1107 
       
  1108     if (!version)
       
  1109         version = (const xmlChar *) "1.0";
       
  1110 
       
  1111     /*
       
  1112      * Allocate a new document and fill the fields.
       
  1113      */
       
  1114     cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
       
  1115     if (!cur)
       
  1116         goto OOM;
       
  1117 
       
  1118     memset(cur, 0, sizeof(xmlDoc));
       
  1119     cur->type = XML_DOCUMENT_NODE;
       
  1120 #ifdef XE_ENABLE_GS_CACHING /*LIBXML_ENABLE_GS_CACHING_IN_DOC*/
       
  1121     cur->cachedGs = xmlGetGlobalState();
       
  1122     SET_GS_PROXY(cur->cachedGs)
       
  1123 #endif
       
  1124 
       
  1125     cur->version = xmlStrdup(version);
       
  1126     if(! cur->version)
       
  1127         goto OOM;
       
  1128 
       
  1129     cur->standalone = -1;
       
  1130     cur->compression = -1; /* not initialized */
       
  1131     cur->doc = cur;
       
  1132     /*
       
  1133      * The in memory encoding is always UTF8
       
  1134      * This field will never change and would
       
  1135      * be obsolete if not for binary compatibility.
       
  1136      */
       
  1137     
       
  1138     cur->charset = XML_CHAR_ENCODING_UTF8;
       
  1139 
       
  1140     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)){
       
  1141         
       
  1142         xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
       
  1143     }
       
  1144     
       
  1145     /*
       
  1146      * Initialize array of node pointers to nodes that store external data references.
       
  1147      * Added in S60 3.2 release.
       
  1148      */
       
  1149     cur->dataNodeMax = 10;
       
  1150     cur->dataNodeList = (xmlNodePtr*) xmlMalloc(cur->dataNodeMax * sizeof(xmlNodePtr));
       
  1151     if (!cur->dataNodeList)
       
  1152         goto OOM; 
       
  1153     for( i = 0; i < cur->dataNodeMax; i++)
       
  1154     	{
       
  1155     	cur->dataNodeList[i] = NULL;
       
  1156     	}
       
  1157    
       
  1158     return(cur);
       
  1159 //------------------
       
  1160 OOM:
       
  1161     xmlTreeErrMemory(EMBED_ERRTXT("building doc"));
       
  1162     xmlFreeDoc(cur);
       
  1163     return NULL;
       
  1164 }
       
  1165 
       
  1166 /**
       
  1167  * xmlFreeDoc:
       
  1168  * @param cur pointer to the document
       
  1169  *
       
  1170  * Free up all the structures used by a document, tree included.
       
  1171  */
       
  1172 XMLPUBFUNEXPORT void
       
  1173 xmlFreeDoc(xmlDocPtr cur) {
       
  1174     xmlDtdPtr extSubset, intSubset;
       
  1175     xmlDictPtr dict;// unneeded = NULL;
       
  1176     LOAD_GS_SAFE_DOC(cur)
       
  1177 
       
  1178     if (!cur) {
       
  1179 #ifdef DEBUG_TREE
       
  1180         xmlGenericError(xmlGenericErrorContext, "xmlFreeDoc : document == NULL\n");
       
  1181 #endif
       
  1182         return;
       
  1183     }
       
  1184     dict = cur->dict;
       
  1185 
       
  1186     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
       
  1187         xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
       
  1188 
       
  1189     /*
       
  1190      * Do this before freeing the children list to avoid ID lookups
       
  1191      */
       
  1192     if (cur->ids)
       
  1193         xmlFreeIDTable((xmlIDTablePtr) cur->ids);
       
  1194     cur->ids = NULL;
       
  1195     if (cur->refs)
       
  1196         xmlFreeRefTable((xmlRefTablePtr) cur->refs);
       
  1197     cur->refs = NULL;
       
  1198     extSubset = cur->extSubset;
       
  1199     intSubset = cur->intSubset;
       
  1200     if (intSubset == extSubset)
       
  1201         extSubset = NULL;
       
  1202     if (extSubset) {
       
  1203         xmlUnlinkNode((xmlNodePtr) cur->extSubset);
       
  1204         cur->extSubset = NULL;
       
  1205         xmlFreeDtd(extSubset);
       
  1206     }
       
  1207     if (intSubset) {
       
  1208         xmlUnlinkNode((xmlNodePtr) cur->intSubset);
       
  1209         cur->intSubset = NULL;
       
  1210         xmlFreeDtd(intSubset);
       
  1211     }
       
  1212 
       
  1213     if (cur->children)
       
  1214         xmlFreeNodeList(cur->children);
       
  1215     if (cur->oldNs)
       
  1216         xmlFreeNsList(cur->oldNs);
       
  1217 	if(cur->dataNodeList)    
       
  1218     	xmlFree(cur->dataNodeList);
       
  1219 
       
  1220     DICT_FREE(cur->version)
       
  1221     DICT_FREE(cur->name)
       
  1222     DICT_FREE(cur->encoding)
       
  1223     DICT_FREE(cur->URL)
       
  1224     xmlFree(cur);
       
  1225     if (dict) xmlDictFree(dict);
       
  1226 }
       
  1227 
       
  1228 /**
       
  1229  * xmlStringLenGetNodeList:
       
  1230  * @param doc the document
       
  1231  * @param value the value of the text
       
  1232  * @param len the length of the string value
       
  1233  *
       
  1234  * Parse the value string and build the node list associated. Should
       
  1235  * produce a flat tree with only TEXTs and ENTITY_REFs.
       
  1236  * Returns a pointer to the first child
       
  1237  */
       
  1238 XMLPUBFUNEXPORT xmlNodePtr
       
  1239 xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
       
  1240     xmlNodePtr ret = NULL, last = NULL;
       
  1241     xmlNodePtr node;
       
  1242     xmlChar *val;
       
  1243     const xmlChar *cur = value, *end = cur + len;
       
  1244     const xmlChar *q;
       
  1245     xmlEntityPtr ent;
       
  1246 
       
  1247     if (value == NULL) return(NULL);
       
  1248 
       
  1249     q = cur;
       
  1250 
       
  1251     while ((cur < end) && (*cur != 0)) {
       
  1252         if (cur[0] == '&') {
       
  1253             int charval = 0;
       
  1254             xmlChar tmp;
       
  1255 
       
  1256             /*
       
  1257             * Save the current text.
       
  1258             */
       
  1259             if (cur != q) {
       
  1260                 if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
       
  1261                     xmlNodeAddContentLen(last, q, cur - q);
       
  1262                 } else {
       
  1263                     node = xmlNewDocTextLen(doc, q, cur - q);
       
  1264                     if (node == NULL) return(ret);
       
  1265                     if (last == NULL)
       
  1266                     last = ret = node;
       
  1267                     else {
       
  1268                     last->next = node;
       
  1269                     node->prev = last;
       
  1270                     last = node;
       
  1271                     }
       
  1272                 }
       
  1273             }
       
  1274             q = cur;
       
  1275             if ((cur + 2 < end) && (cur[1] == '#') && (cur[2] == 'x')) {
       
  1276                 cur += 3;
       
  1277                 if (cur < end)
       
  1278                     tmp = *cur;
       
  1279                 else
       
  1280                     tmp = 0;
       
  1281                 while (tmp != ';') { /* Non input consuming loop */
       
  1282                     if ((tmp >= '0') && (tmp <= '9'))
       
  1283                         charval = charval * 16 + (tmp - '0');
       
  1284                     else if ((tmp >= 'a') && (tmp <= 'f'))
       
  1285                         charval = charval * 16 + (tmp - 'a') + 10;
       
  1286                     else if ((tmp >= 'A') && (tmp <= 'F'))
       
  1287                         charval = charval * 16 + (tmp - 'A') + 10;
       
  1288                     else {
       
  1289                         xmlTreeErr(XML_TREE_INVALID_HEX, (xmlNodePtr) doc, NULL);
       
  1290                         charval = 0;
       
  1291                         break;
       
  1292                     }
       
  1293                     cur++;
       
  1294                     if (cur < end)
       
  1295                         tmp = *cur;
       
  1296                     else
       
  1297                         tmp = 0;
       
  1298                 }
       
  1299                 if (tmp == ';')
       
  1300                     cur++;
       
  1301                 q = cur;
       
  1302             }
       
  1303             else
       
  1304                 if ((cur + 1 < end) && (cur[1] == '#')) {
       
  1305                     cur += 2;
       
  1306                     if (cur < end)
       
  1307                         tmp = *cur;
       
  1308                     else
       
  1309                         tmp = 0;
       
  1310                     while (tmp != ';') { /* Non input consuming loops */
       
  1311                         if ((tmp >= '0') && (tmp <= '9'))
       
  1312                             charval = charval * 10 + (tmp - '0');
       
  1313                         else {
       
  1314                             xmlTreeErr(XML_TREE_INVALID_DEC, (xmlNodePtr) doc, NULL);
       
  1315                             charval = 0;
       
  1316                             break;
       
  1317                         }
       
  1318                         cur++;
       
  1319                         if (cur < end)
       
  1320                             tmp = *cur;
       
  1321                         else
       
  1322                             tmp = 0;
       
  1323                     }
       
  1324                     if (tmp == ';')
       
  1325                         cur++;
       
  1326                     q = cur;
       
  1327                 }
       
  1328                 else
       
  1329                 {
       
  1330                     /*
       
  1331                     * Read the entity string
       
  1332                     */
       
  1333                     cur++;
       
  1334                     q = cur;
       
  1335                     while ((cur < end) && (*cur != 0) && (*cur != ';')) cur++;
       
  1336 
       
  1337                     if ((cur >= end) || (*cur == 0)) {
       
  1338                         xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY, (xmlNodePtr) doc, (const char *) q);
       
  1339                         return(ret);
       
  1340                     }
       
  1341                     if (cur != q) {
       
  1342                         /*
       
  1343                         * Predefined entities don't generate nodes
       
  1344                         */
       
  1345                         val = xmlStrndup(q, cur - q);
       
  1346                         ent = xmlGetDocEntity(doc, val);
       
  1347                         if ((ent != NULL) &&
       
  1348                             (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY))
       
  1349                         {
       
  1350                             if (last == NULL) {
       
  1351                                 node = xmlNewDocText(doc, ent->content);
       
  1352                                 last = ret = node;
       
  1353                             } else if (last->type != XML_TEXT_NODE) {
       
  1354                                 node = xmlNewDocText(doc, ent->content);
       
  1355                                 last = xmlAddNextSibling(last, node);
       
  1356                             } else
       
  1357                                 xmlNodeAddContent(last, ent->content);
       
  1358 
       
  1359                         } else {
       
  1360                         /*
       
  1361                         * Create a new REFERENCE_REF node
       
  1362                         */
       
  1363                             node = xmlNewReference(doc, val);
       
  1364                             if (node == NULL) {
       
  1365                                 if (val != NULL) xmlFree(val);
       
  1366                                 return(ret);
       
  1367                             }
       
  1368                             else if ((ent != NULL) && (ent->children == NULL)) {
       
  1369                                 xmlNodePtr temp;
       
  1370 
       
  1371                                 ent->children = xmlStringGetNodeList(doc, (const xmlChar*)node->content);
       
  1372                                 ent->owner = 1;
       
  1373                                 temp = ent->children;
       
  1374                                 while (temp) {
       
  1375                                     temp->parent = (xmlNodePtr)ent;
       
  1376                                     temp = temp->next;
       
  1377                                 }
       
  1378                             }
       
  1379                             if (last == NULL) {
       
  1380                                 last = ret = node;
       
  1381                             } else {
       
  1382                                 last = xmlAddNextSibling(last, node);
       
  1383                             }
       
  1384                         }
       
  1385                         xmlFree(val);
       
  1386                     }
       
  1387                     cur++;
       
  1388                     q = cur;
       
  1389                 }
       
  1390             if (charval != 0) {
       
  1391                 xmlChar buf[10];
       
  1392                 int l;
       
  1393 
       
  1394                 l = xmlCopyCharMultiByte(buf, charval);
       
  1395                 buf[l] = 0;
       
  1396                 node = xmlNewDocText(doc, buf);
       
  1397                 if (node != NULL) {
       
  1398                     if (last == NULL) {
       
  1399                         last = ret = node;
       
  1400                     } else {
       
  1401                         last = xmlAddNextSibling(last, node);
       
  1402                     }
       
  1403                 }
       
  1404                 charval = 0;
       
  1405             }
       
  1406         } else
       
  1407             cur++;
       
  1408     } // while ((cur < end) && (*cur != 0))
       
  1409 
       
  1410     if ((cur != q) || (ret == NULL))
       
  1411     {
       
  1412         /*
       
  1413         * Handle the last piece of text.
       
  1414         */
       
  1415         if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
       
  1416             xmlNodeAddContentLen(last, q, cur - q);
       
  1417         } else {
       
  1418             node = xmlNewDocTextLen(doc, q, cur - q);
       
  1419             if (node == NULL) return(ret);
       
  1420             if (last == NULL) {
       
  1421                 last = ret = node;
       
  1422             } else {
       
  1423                 last = xmlAddNextSibling(last, node);
       
  1424             }
       
  1425         }
       
  1426     } // if ((cur != q) || (ret == NULL))
       
  1427     return(ret);
       
  1428 }
       
  1429 
       
  1430 /**
       
  1431  * xmlStringGetNodeList:
       
  1432  * @param doc the document
       
  1433  * @param value the value of the attribute
       
  1434  *
       
  1435  * Parse the value string and build the node list associated. Should
       
  1436  * produce a flat tree with only TEXTs and ENTITY_REFs.
       
  1437  * Returns a pointer to the first child
       
  1438  *
       
  1439  * OOM: possible --> iif returms NULL for value!=NULL and OOM flag is set
       
  1440  */
       
  1441 XMLPUBFUNEXPORT xmlNodePtr
       
  1442 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
       
  1443     xmlNodePtr ret = NULL, last = NULL;
       
  1444     xmlNodePtr node;
       
  1445     xmlChar* val;
       
  1446     const xmlChar *cur = value;
       
  1447     const xmlChar *q;
       
  1448     xmlEntityPtr ent;
       
  1449     LOAD_GS_SAFE_DOC(doc)
       
  1450 
       
  1451     if (value == NULL) return(NULL);
       
  1452 
       
  1453     q = cur;
       
  1454     while (*cur != 0) {
       
  1455     if (cur[0] == '&') {
       
  1456         int charval = 0;
       
  1457         xmlChar tmp;
       
  1458 
       
  1459         /*
       
  1460          * Save the current text.
       
  1461          */
       
  1462          if (cur != q)
       
  1463          {
       
  1464             if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
       
  1465                 xmlNodeAddContentLen(last, q, cur - q); // may set OOM flag
       
  1466                 if(OOM_FLAG)
       
  1467                     goto OOM;
       
  1468             } else {
       
  1469                 node = xmlNewDocTextLen(doc, q, cur - q); // may set OOM flag
       
  1470                 if (node == NULL)
       
  1471                     goto OOM;
       
  1472 
       
  1473                 if (last == NULL){
       
  1474                     last = ret = node;
       
  1475                 }else{
       
  1476                     last->next = node;
       
  1477                     node->prev = last;
       
  1478                     last = node;
       
  1479                 }
       
  1480             }
       
  1481         }
       
  1482         q = cur;
       
  1483         if ((cur[1] == '#') && (cur[2] == 'x'))
       
  1484         {
       
  1485             cur += 3;
       
  1486             tmp = *cur;
       
  1487             while (tmp != ';')
       
  1488             { /* Non input consuming loop */
       
  1489                 if ((tmp >= '0') && (tmp <= '9'))
       
  1490                     charval = charval * 16 + (tmp - '0');
       
  1491                 else if ((tmp >= 'a') && (tmp <= 'f'))
       
  1492                     charval = charval * 16 + (tmp - 'a') + 10;
       
  1493                 else if ((tmp >= 'A') && (tmp <= 'F'))
       
  1494                     charval = charval * 16 + (tmp - 'A') + 10;
       
  1495                 else {
       
  1496                     xmlTreeErr(XML_TREE_INVALID_HEX, (xmlNodePtr) doc, NULL);
       
  1497                     charval = 0;
       
  1498                     break;
       
  1499                 }
       
  1500                 cur++;
       
  1501                 tmp = *cur;
       
  1502             }
       
  1503             if (tmp == ';')
       
  1504                 cur++;
       
  1505             q = cur;
       
  1506         } else if  (cur[1] == '#') {
       
  1507             cur += 2;
       
  1508             tmp = *cur;
       
  1509             while (tmp != ';')
       
  1510             { /* Non input consuming loops */
       
  1511                 if ((tmp >= '0') && (tmp <= '9'))
       
  1512                     charval = charval * 10 + (tmp - '0');
       
  1513                 else {
       
  1514                     xmlTreeErr(XML_TREE_INVALID_DEC, (xmlNodePtr) doc, NULL);
       
  1515                     charval = 0;
       
  1516                     break;
       
  1517                 }
       
  1518                 cur++;
       
  1519                 tmp = *cur;
       
  1520             }
       
  1521             if (tmp == ';')
       
  1522                 cur++;
       
  1523             q = cur;
       
  1524         } else {
       
  1525             /*
       
  1526             * Read the entity string
       
  1527             */
       
  1528             cur++;
       
  1529             q = cur;
       
  1530             while ((*cur != 0) && (*cur != ';'))
       
  1531             {
       
  1532                 cur++;
       
  1533             }
       
  1534             if (*cur == 0) {
       
  1535                 xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY, (xmlNodePtr) doc, (const char *) q);
       
  1536                 return(ret); 
       
  1537             }
       
  1538             if (cur != q)
       
  1539             {
       
  1540                 /*
       
  1541                 * Predefined entities don't generate nodes
       
  1542                 */
       
  1543                 val = xmlStrndup(q, cur - q);
       
  1544                 if(!val)
       
  1545                     goto OOM;
       
  1546 
       
  1547                 ent = xmlGetDocEntity(doc, val);
       
  1548                 if ((ent != NULL) && (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY))
       
  1549                 {
       
  1550                     if (last == NULL) {
       
  1551                         node = xmlNewDocText(doc, ent->content); // may set OOM flag
       
  1552                         if(!node)
       
  1553                             goto OOM_val;
       
  1554 
       
  1555                         last = ret = node;
       
  1556                     } else if (last->type != XML_TEXT_NODE) {
       
  1557                         node = xmlNewDocText(doc, ent->content);
       
  1558                         if(!node)
       
  1559                             goto OOM_val;
       
  1560 
       
  1561                         last = xmlAddNextSibling(last, node); // NULL in OOM
       
  1562                         if(!last)
       
  1563                             goto OOM_val;
       
  1564                     } else {
       
  1565                         xmlNodeAddContent(last, ent->content);
       
  1566                         if(OOM_FLAG)
       
  1567                             goto OOM_val;
       
  1568                     }
       
  1569                 } else {
       
  1570                     /*
       
  1571                     * Create a new REFERENCE_REF node
       
  1572                     */
       
  1573                     node = xmlNewReference(doc, val);
       
  1574                     if (!node)
       
  1575                     {
       
  1576                         goto OOM_val;
       
  1577                     }
       
  1578                     else if ((ent != NULL) && (ent->children == NULL))
       
  1579                     {
       
  1580                         xmlNodePtr temp;
       
  1581                         
       
  1582 
       
  1583                         // NOTE: Recursive call!
       
  1584                         ent->children = xmlStringGetNodeList(doc, (const xmlChar*)node->content);
       
  1585                         if(OOM_FLAG)
       
  1586                             goto OOM_node_val;
       
  1587 
       
  1588                         ent->owner = 1;
       
  1589                         temp = ent->children;
       
  1590                         while (temp) {
       
  1591                             temp->parent = (xmlNodePtr)ent;
       
  1592                             temp = temp->next;
       
  1593                         }
       
  1594                     }
       
  1595                     if (last == NULL) {
       
  1596                         last = ret = node;
       
  1597                     } else {
       
  1598                         last = xmlAddNextSibling(last, node); // NULL in OOM
       
  1599                         if(!last)
       
  1600                             goto OOM_node_val;
       
  1601                     }
       
  1602                 }
       
  1603                 xmlFree(val);
       
  1604             }
       
  1605             cur++;
       
  1606             q = cur;
       
  1607         }
       
  1608         if (charval != 0) {
       
  1609             xmlChar buf[10];
       
  1610             int len;
       
  1611 
       
  1612             len = xmlCopyCharMultiByte(buf, charval);
       
  1613             buf[len] = 0;
       
  1614             node = xmlNewDocText(doc, buf);
       
  1615             if (!node)
       
  1616                 goto OOM;
       
  1617             if (last == NULL) {
       
  1618                 last = ret = node;
       
  1619             } else {
       
  1620                 last = xmlAddNextSibling(last, node);
       
  1621                 if(!last){
       
  1622                     xmlFreeNode(node);
       
  1623                     goto OOM;
       
  1624                 }
       
  1625             }
       
  1626             charval = 0;
       
  1627         }
       
  1628     } else
       
  1629         cur++;
       
  1630     }
       
  1631     if ((cur != q) || (ret == NULL))
       
  1632     {
       
  1633         /*
       
  1634         * Handle the last piece of text.
       
  1635         */
       
  1636         if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
       
  1637             xmlNodeAddContentLen(last, q, cur - q);
       
  1638             if(OOM_FLAG)
       
  1639                 goto OOM;
       
  1640         } else {
       
  1641             node = xmlNewDocTextLen(doc, q, cur - q);
       
  1642             if (node == NULL)
       
  1643                 goto OOM;
       
  1644             if (last == NULL) {
       
  1645                 last = ret = node;
       
  1646             } else {
       
  1647                 last = xmlAddNextSibling(last, node);
       
  1648                 if (!last){
       
  1649                     xmlFreeNode(node);
       
  1650                     goto OOM;
       
  1651                 }
       
  1652             }
       
  1653         }
       
  1654     }
       
  1655     return(ret);
       
  1656 //----------------------------
       
  1657 OOM_node_val:
       
  1658     xmlFreeNode(node);
       
  1659 OOM_val:
       
  1660     if(val) xmlFree(val);
       
  1661 OOM:
       
  1662     xmlFreeNodeList(ret);
       
  1663     return NULL;
       
  1664 }
       
  1665 
       
  1666 /**
       
  1667  * xmlNodeListGetString:
       
  1668  * @param doc:  the document
       
  1669  * @param list:  a Node list
       
  1670  * @param inLine:  should we replace entity contents or show their external form
       
  1671  *
       
  1672  * Build the string equivalent to the text contained in the Node list
       
  1673  * made of TEXTs and ENTITY_REFs
       
  1674  *
       
  1675  * Returns a pointer to the string copy, the caller must free it with xmlFree().
       
  1676  *
       
  1677  * OOM: global flag is set in OOM when NULL is returned --> flag should be checked
       
  1678  */
       
  1679 XMLPUBFUNEXPORT xmlChar*
       
  1680 xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine)
       
  1681 {
       
  1682     xmlNodePtr node = list;
       
  1683     xmlChar *ret = NULL;
       
  1684     xmlEntityPtr ent;
       
  1685     LOAD_GS_SAFE_DOC(doc)
       
  1686 
       
  1687     if (list == NULL)
       
  1688         return (NULL);
       
  1689 
       
  1690     while (node != NULL) {
       
  1691         if ((node->type == XML_TEXT_NODE) ||
       
  1692             (node->type == XML_CDATA_SECTION_NODE)) {
       
  1693             if (inLine) {
       
  1694                 ret = xmlStrcat(ret, node->content);
       
  1695             } else {
       
  1696                 xmlChar *buffer;
       
  1697 
       
  1698                 buffer = xmlEncodeEntitiesReentrant(doc, node->content); // OOM handling below
       
  1699                 if (buffer != NULL) {
       
  1700                     ret = xmlStrcat(ret, buffer);
       
  1701                     xmlFree(buffer);
       
  1702                 }
       
  1703             }
       
  1704         } else if (node->type == XML_ENTITY_REF_NODE) {
       
  1705             if (inLine) {
       
  1706                 ent = xmlGetDocEntity(doc, node->name);
       
  1707                 if (ent != NULL) {
       
  1708                     xmlChar *buffer;
       
  1709 
       
  1710                     /* an entity content can be any "well balanced chunk",
       
  1711                      * i.e. the result of the content [43] production:
       
  1712                      * http://www.w3.org/TR/REC-xml#NT-content.
       
  1713                      * So it can contain text, CDATA section or nested
       
  1714                      * entity reference nodes (among others).
       
  1715                      * -> we recursive  call xmlNodeListGetString()
       
  1716                      * which handles these types */
       
  1717                     buffer = xmlNodeListGetString(doc, ent->children, 1); // may set OOM flag (the check is below)
       
  1718                     if (buffer != NULL) {
       
  1719                         ret = xmlStrcat(ret, buffer); // may set OOM flag
       
  1720                         xmlFree(buffer);
       
  1721                     }
       
  1722                 } else {
       
  1723                     ret = xmlStrcat(ret, node->content);// may set OOM flag
       
  1724                 }
       
  1725             } else {
       
  1726                 
       
  1727                 
       
  1728                 xmlChar buf[2];
       
  1729                 // xmlStr(n)cat calls may set OOM flag
       
  1730                 buf[0] = '&';
       
  1731                 buf[1] = 0;
       
  1732                 ret = xmlStrncat(ret, buf, 1);
       
  1733                 ret = xmlStrcat(ret, node->name);
       
  1734                 buf[0] = ';';
       
  1735                 buf[1] = 0;
       
  1736                 ret = xmlStrncat(ret, buf, 1);
       
  1737             }
       
  1738         }
       
  1739 #if 0
       
  1740         else {
       
  1741             xmlGenericError(xmlGenericErrorContext,
       
  1742                             "xmlGetNodeListString : invalid node type %d\n",
       
  1743                             node->type);
       
  1744         }
       
  1745 #endif
       
  1746         if(OOM_FLAG){
       
  1747             if(ret)
       
  1748                 xmlFree(ret);
       
  1749             return NULL;
       
  1750         }
       
  1751         node = node->next;
       
  1752     }
       
  1753     return (ret);
       
  1754 }
       
  1755 
       
  1756 #ifdef LIBXML_TREE_ENABLED
       
  1757 /**
       
  1758  * xmlNodeListGetRawString:
       
  1759  * @param doc the document
       
  1760  * @param list a Node list
       
  1761  * @param inLine should we replace entity contents or show their external form
       
  1762  *
       
  1763  * Builds the string equivalent to the text contained in the Node list
       
  1764  * made of TEXTs and ENTITY_REFs, contrary to xmlNodeListGetString()
       
  1765  * this function doesn't do any character encoding handling.
       
  1766  *
       
  1767  * Returns a pointer to the string copy, the caller must free it with xmlFree().
       
  1768  */
       
  1769 XMLPUBFUNEXPORT xmlChar*
       
  1770 xmlNodeListGetRawString(xmlDocPtr doc, xmlNodePtr list, int inLine)
       
  1771 {
       
  1772     xmlNodePtr   node = list;
       
  1773     xmlChar*     ret = NULL;
       
  1774     xmlEntityPtr ent;
       
  1775 
       
  1776     if (!list)
       
  1777         return (NULL);
       
  1778 
       
  1779     while (node) {
       
  1780         if ((node->type == XML_TEXT_NODE) ||
       
  1781             (node->type == XML_CDATA_SECTION_NODE)) {
       
  1782             if (inLine) {
       
  1783                 ret = xmlStrcat(ret, node->content);
       
  1784             } else {
       
  1785                 xmlChar *buffer;
       
  1786 
       
  1787                 buffer = xmlEncodeSpecialChars(doc, node->content);
       
  1788                 if (buffer != NULL) {
       
  1789                     ret = xmlStrcat(ret, buffer);
       
  1790                     xmlFree(buffer);
       
  1791                 }
       
  1792             }
       
  1793         } else if (node->type == XML_ENTITY_REF_NODE) {
       
  1794             if (inLine) {
       
  1795                 ent = xmlGetDocEntity(doc, node->name);
       
  1796                 if (ent) {
       
  1797                     xmlChar *buffer;
       
  1798 
       
  1799                     /* an entity content can be any "well balanced chunk",
       
  1800                      * i.e. the result of the content [43] production:
       
  1801                      * http://www.w3.org/TR/REC-xml#NT-content.
       
  1802                      * So it can contain text, CDATA section or nested
       
  1803                      * entity reference nodes (among others).
       
  1804                      * -> we recursive  call xmlNodeListGetRawString()
       
  1805                      * which handles these types */
       
  1806                     buffer = xmlNodeListGetRawString(doc, ent->children, 1);
       
  1807                     if (buffer) {
       
  1808                         ret = xmlStrcat(ret, buffer);
       
  1809                         xmlFree(buffer);
       
  1810                     }
       
  1811                 } else {
       
  1812                     ret = xmlStrcat(ret, node->content);
       
  1813                 }
       
  1814             } else {
       
  1815                 xmlChar buf[2];
       
  1816 
       
  1817                 buf[0] = '&';
       
  1818                 buf[1] = 0;
       
  1819                 ret = xmlStrncat(ret, buf, 1);
       
  1820                 ret = xmlStrcat(ret, node->name);
       
  1821                 buf[0] = ';';
       
  1822                 buf[1] = 0;
       
  1823                 ret = xmlStrncat(ret, buf, 1);
       
  1824             }
       
  1825         }
       
  1826 #if 0
       
  1827         else {
       
  1828             xmlGenericError(xmlGenericErrorContext,
       
  1829                             "xmlGetNodeListString : invalid node type %d\n",
       
  1830                             node->type);
       
  1831         }
       
  1832 #endif
       
  1833         node = node->next;
       
  1834     }
       
  1835     return (ret);
       
  1836 }
       
  1837 #endif /* LIBXML_TREE_ENABLED */
       
  1838 
       
  1839 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED)
       
  1840 /**
       
  1841  * xmlNewProp:
       
  1842  * @param node the holding node
       
  1843  * @param name the name of the attribute
       
  1844  * @param value the value of the attribute
       
  1845  *
       
  1846  * Create a new property carried by a node.
       
  1847  * Returns a pointer to the attribute
       
  1848  *
       
  1849  * OOM: possible --> sets OOM flag and returns NULL for name!=NULL && node is element
       
  1850  */
       
  1851 XMLPUBFUNEXPORT xmlAttrPtr
       
  1852 xmlNewProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
       
  1853     xmlAttrPtr cur;
       
  1854     xmlDocPtr doc;
       
  1855     xmlChar *buffer;
       
  1856     LOAD_GS_SAFE_NODE(node)
       
  1857 
       
  1858     if (name == NULL) {
       
  1859 #ifdef DEBUG_TREE
       
  1860         xmlGenericError(xmlGenericErrorContext, "xmlNewProp : name == NULL\n");
       
  1861 #endif
       
  1862         return(NULL);
       
  1863     }
       
  1864     if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
       
  1865         return(NULL);
       
  1866 
       
  1867     /*
       
  1868      * Allocate a new property and fill the fields.
       
  1869      */
       
  1870     cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
       
  1871     if (cur == NULL) {
       
  1872         xmlTreeErrMemory(EMBED_ERRTXT("building attribute"));
       
  1873         return(NULL);
       
  1874     }
       
  1875 
       
  1876     memset(cur, 0, sizeof(xmlAttr));
       
  1877     cur->type = XML_ATTRIBUTE_NODE;
       
  1878 
       
  1879     cur->parent = node;
       
  1880     cur->doc = doc = (node ? node->doc : NULL);
       
  1881     cur->name = xmlStrdup(name);
       
  1882     if(!cur->name)
       
  1883         goto OOM;
       
  1884     //
       
  1885     if (value)
       
  1886     {
       
  1887         xmlNodePtr tmp;
       
  1888         // value != NULL, so returned buffer==NULL only if OOM happens
       
  1889         buffer = xmlEncodeEntitiesReentrant(doc, value);
       
  1890         // if buffer==NULL, then xmlStringGetNodeList will return NULL as in OOM
       
  1891         cur->children = xmlStringGetNodeList(doc, buffer);
       
  1892         if(!cur->children)
       
  1893             goto OOM_buffer;
       
  1894 
       
  1895         cur->last = NULL;
       
  1896         tmp = cur->children;
       
  1897         while (tmp) {
       
  1898             tmp->parent = (xmlNodePtr) cur;
       
  1899             tmp->doc = doc;
       
  1900             if (tmp->next == NULL)
       
  1901                 cur->last = tmp;
       
  1902             tmp = tmp->next;
       
  1903         }
       
  1904         xmlFree(buffer);
       
  1905     }
       
  1906 
       
  1907     /*
       
  1908      * Add it at the end to preserve parsing order ...
       
  1909      */
       
  1910     if (node != NULL) {
       
  1911         if (node->properties == NULL) {
       
  1912             node->properties = cur;
       
  1913         } else {
       
  1914             xmlAttrPtr prev = node->properties;
       
  1915 
       
  1916             while (prev->next != NULL)
       
  1917                 prev = prev->next;
       
  1918             prev->next = cur;
       
  1919             cur->prev = prev;
       
  1920         }
       
  1921     }
       
  1922 
       
  1923     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)){
       
  1924         
       
  1925         xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
       
  1926     }
       
  1927     return(cur);
       
  1928 //------------------
       
  1929 OOM_buffer:
       
  1930     xmlFree(buffer);
       
  1931 OOM:
       
  1932     xmlFreeProp(cur);
       
  1933     return NULL;
       
  1934 }
       
  1935 #endif /* LIBXML_TREE_ENABLED */
       
  1936 
       
  1937 /**
       
  1938  * xmlNewNsProp:
       
  1939  * @param node the holding node
       
  1940  * @param ns the namespace
       
  1941  * @param name the name of the attribute
       
  1942  * @param value the value of the attribute
       
  1943  *
       
  1944  * Create a new property tagged with a namespace and carried by a node.
       
  1945  * Returns a pointer to the attribute
       
  1946  */
       
  1947 XMLPUBFUNEXPORT xmlAttrPtr
       
  1948 xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, const xmlChar *value)
       
  1949 {
       
  1950     xmlAttrPtr cur;
       
  1951     xmlDocPtr doc = NULL;
       
  1952     LOAD_GS_SAFE_NODE(node)
       
  1953 
       
  1954     if (name == NULL) {
       
  1955 #ifdef DEBUG_TREE
       
  1956         xmlGenericError(xmlGenericErrorContext, "xmlNewNsProp : name == NULL\n");
       
  1957 #endif
       
  1958         return(NULL);
       
  1959     }
       
  1960 
       
  1961     /*
       
  1962      * Allocate a new property and fill the fields.
       
  1963      */
       
  1964 
       
  1965     cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
       
  1966     if (cur == NULL) {
       
  1967         xmlTreeErrMemory(EMBED_ERRTXT("building attribute"));
       
  1968         return(NULL);
       
  1969     }
       
  1970     memset(cur, 0, sizeof(xmlAttr));
       
  1971     cur->type = XML_ATTRIBUTE_NODE;
       
  1972 
       
  1973     cur->parent = node;
       
  1974     if (node != NULL) {
       
  1975         doc = node->doc;
       
  1976         cur->doc = doc;
       
  1977     }
       
  1978     cur->ns = ns;
       
  1979     if (name)
       
  1980     	{
       
  1981     	cur->name = xmlStrdup(name);
       
  1982     	if (!cur->name)
       
  1983     		{
       
  1984     		xmlFreeProp(cur);
       
  1985     		xmlTreeErrMemory(EMBED_ERRTXT("building attribute"));
       
  1986         	return(NULL);
       
  1987     		}
       
  1988     	}
       
  1989     
       
  1990     
       
  1991     if (value != NULL) {
       
  1992         xmlChar *buffer;
       
  1993         xmlNodePtr tmp;
       
  1994 
       
  1995         buffer = xmlEncodeEntitiesReentrant(doc, value);
       
  1996         if (!buffer)
       
  1997         	{
       
  1998 			xmlFreeProp(cur);
       
  1999     		xmlTreeErrMemory(EMBED_ERRTXT("building attribute"));
       
  2000         	return(NULL);        	
       
  2001         	}
       
  2002         cur->children = xmlStringGetNodeList(doc, buffer);
       
  2003         if(!cur->children)
       
  2004         	{
       
  2005 			xmlFreeProp(cur);
       
  2006 			xmlFree(buffer);
       
  2007     		xmlTreeErrMemory(EMBED_ERRTXT("building attribute"));
       
  2008         	return(NULL);
       
  2009             }
       
  2010         cur->last = NULL;
       
  2011         tmp = cur->children;
       
  2012         while (tmp != NULL) {
       
  2013             tmp->parent = (xmlNodePtr) cur;
       
  2014             if (tmp->next == NULL)
       
  2015                 cur->last = tmp;
       
  2016             tmp = tmp->next;
       
  2017         }
       
  2018         xmlFree(buffer);
       
  2019     }
       
  2020 
       
  2021     /*
       
  2022      * Add it at the end to preserve parsing order ...
       
  2023      */
       
  2024     if (node != NULL) {
       
  2025         if (node->properties == NULL) {
       
  2026             node->properties = cur;
       
  2027         } else {
       
  2028             xmlAttrPtr prev = node->properties;
       
  2029 
       
  2030             while (prev->next != NULL) prev = prev->next;
       
  2031             prev->next = cur;
       
  2032             cur->prev = prev;
       
  2033         }
       
  2034     }
       
  2035 
       
  2036     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)){
       
  2037         xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
       
  2038     }
       
  2039     return(cur);
       
  2040 }
       
  2041 
       
  2042 /**
       
  2043  * xmlNewNsPropEatName:
       
  2044  * @param node the holding node
       
  2045  * @param ns the namespace
       
  2046  * @param name the name of the attribute
       
  2047  * @param value the value of the attribute
       
  2048  *
       
  2049  * Create a new property tagged with a namespace and carried by a node.
       
  2050  * Returns a pointer to the attribute
       
  2051  */
       
  2052 XMLPUBFUNEXPORT xmlAttrPtr
       
  2053 xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name,
       
  2054            const xmlChar *value)
       
  2055 {
       
  2056     xmlAttrPtr cur;
       
  2057     xmlDocPtr doc = NULL;
       
  2058     LOAD_GS_SAFE_NODE(node)
       
  2059 
       
  2060     if (name == NULL) {
       
  2061 #ifdef DEBUG_TREE
       
  2062         xmlGenericError(xmlGenericErrorContext, "xmlNewNsPropEatName : name == NULL\n");
       
  2063 #endif
       
  2064         return(NULL);
       
  2065     }
       
  2066 
       
  2067     /*
       
  2068      * Allocate a new property and fill the fields.
       
  2069      */
       
  2070     cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
       
  2071     if (cur == NULL) {
       
  2072         xmlTreeErrMemory(EMBED_ERRTXT("building attribute"));
       
  2073         xmlFree(name);
       
  2074         return(NULL);
       
  2075     }
       
  2076     memset(cur, 0, sizeof(xmlAttr));
       
  2077     cur->type = XML_ATTRIBUTE_NODE;
       
  2078 
       
  2079     cur->parent = node;
       
  2080     if (node != NULL) {
       
  2081             doc = node->doc;
       
  2082             cur->doc = doc;
       
  2083     }
       
  2084     cur->ns = ns;
       
  2085     cur->name = name;
       
  2086     if (value != NULL) {
       
  2087         xmlChar *buffer;
       
  2088         xmlNodePtr tmp;
       
  2089 
       
  2090         buffer = xmlEncodeEntitiesReentrant(doc, value);
       
  2091         cur->children = xmlStringGetNodeList(doc, buffer);
       
  2092         cur->last = NULL;
       
  2093         tmp = cur->children;
       
  2094         while (tmp != NULL) {
       
  2095             tmp->parent = (xmlNodePtr) cur;
       
  2096             if (tmp->next == NULL)
       
  2097                 cur->last = tmp;
       
  2098             tmp = tmp->next;
       
  2099         }
       
  2100         xmlFree(buffer);
       
  2101     }
       
  2102 
       
  2103     /*
       
  2104      * Add it at the end to preserve parsing order ...
       
  2105      */
       
  2106     if (node != NULL) {
       
  2107         if (node->properties == NULL) {
       
  2108             node->properties = cur;
       
  2109         } else {
       
  2110             xmlAttrPtr prev = node->properties;
       
  2111 
       
  2112             while (prev->next != NULL)
       
  2113                 prev = prev->next;
       
  2114             prev->next = cur;
       
  2115             cur->prev = prev;
       
  2116         }
       
  2117     }
       
  2118 
       
  2119     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  2120         xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
       
  2121     return(cur);
       
  2122 }
       
  2123 
       
  2124 /**
       
  2125  * xmlNewDocProp:
       
  2126  * @param doc the document
       
  2127  * @param name the name of the attribute
       
  2128  * @param value the value of the attribute
       
  2129  *
       
  2130  * Create a new property carried by a document.
       
  2131  * Returns a pointer to the attribute
       
  2132  *
       
  2133  * OOM: possible ->  NULL is returned for name!=NULL, OOM flag is set
       
  2134  */
       
  2135 XMLPUBFUNEXPORT xmlAttrPtr
       
  2136 xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value) {
       
  2137     xmlAttrPtr cur;
       
  2138     LOAD_GS_SAFE_DOC(doc)
       
  2139 
       
  2140     if (name == NULL) {
       
  2141 #ifdef DEBUG_TREE
       
  2142         xmlGenericError(xmlGenericErrorContext, "xmlNewDocProp : name == NULL\n");
       
  2143 #endif
       
  2144         return(NULL);
       
  2145     }
       
  2146 
       
  2147     /*
       
  2148      * Allocate a new property and fill the fields.
       
  2149      */
       
  2150     cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
       
  2151     if (!cur)
       
  2152         goto OOM_exit;
       
  2153 
       
  2154     memset(cur, 0, sizeof(xmlAttr));
       
  2155     cur->type = XML_ATTRIBUTE_NODE;
       
  2156     cur->name = xmlStrdup(name);
       
  2157     if(!cur->name)
       
  2158         goto OOM;
       
  2159 
       
  2160     cur->doc = doc;
       
  2161     if (value != NULL) {
       
  2162         xmlNodePtr tmp;
       
  2163 
       
  2164         cur->children = xmlStringGetNodeList(doc, value);
       
  2165         if(OOM_FLAG)
       
  2166             goto OOM;
       
  2167 
       
  2168         cur->last = NULL;
       
  2169 
       
  2170         tmp = cur->children;
       
  2171         while (tmp != NULL) {
       
  2172             tmp->parent = (xmlNodePtr) cur;
       
  2173             if (tmp->next == NULL)
       
  2174                 cur->last = tmp;
       
  2175             tmp = tmp->next;
       
  2176         }
       
  2177     }
       
  2178 
       
  2179     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)){
       
  2180         
       
  2181         xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
       
  2182     }
       
  2183     return(cur);
       
  2184 //---------------------------
       
  2185 OOM:
       
  2186     xmlFreeProp(cur);
       
  2187 OOM_exit:
       
  2188     xmlTreeErrMemory(EMBED_ERRTXT("building attribute"));
       
  2189     return NULL;
       
  2190 }
       
  2191 
       
  2192 /**
       
  2193  * xmlFreePropList:
       
  2194  * @param cur the first property in the list
       
  2195  *
       
  2196  * Free a property and all its siblings, all the children are freed too.
       
  2197  */
       
  2198 
       
  2199 XMLPUBFUNEXPORT void
       
  2200 xmlFreePropList(xmlAttrPtr cur) {
       
  2201     xmlAttrPtr next;
       
  2202     // O.K.: What a @#^#&! code
       
  2203     //REMOVED: if (cur == NULL) return;
       
  2204 
       
  2205     while (cur != NULL) {
       
  2206         next = cur->next;
       
  2207         xmlFreeProp(cur);
       
  2208         cur = next;
       
  2209     }
       
  2210 }
       
  2211 
       
  2212 /**
       
  2213  * xmlFreeProp:
       
  2214  * @param cur an attribute
       
  2215  *
       
  2216  * Free one attribute, all the content is freed too
       
  2217  *
       
  2218  * OOM: never
       
  2219  */
       
  2220 XMLPUBFUNEXPORT void
       
  2221 xmlFreeProp(xmlAttrPtr cur) {
       
  2222     xmlDictPtr dict = NULL;
       
  2223     LOAD_GS_SAFE_ATTR(cur)
       
  2224     if (cur == NULL) return;
       
  2225 
       
  2226     if (cur->doc != NULL) dict = cur->doc->dict;
       
  2227 
       
  2228     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
       
  2229     xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
       
  2230 
       
  2231     
       
  2232 
       
  2233     /* Check for ID removal -> leading to invalid references ! */
       
  2234     if ((cur->parent != NULL) && (cur->parent->doc != NULL) &&
       
  2235     ((cur->parent->doc->intSubset != NULL) ||
       
  2236      (cur->parent->doc->extSubset != NULL))) {
       
  2237         if (xmlIsID(cur->parent->doc, cur->parent, cur))
       
  2238         xmlRemoveID(cur->parent->doc, cur);
       
  2239     }
       
  2240     if (cur->children != NULL) xmlFreeNodeList(cur->children);
       
  2241     DICT_FREE(cur->name)
       
  2242 
       
  2243     xmlFree(cur);
       
  2244 }
       
  2245 
       
  2246 #ifdef LIBXML_TREE_ENABLED
       
  2247 /**
       
  2248  * xmlRemoveProp:
       
  2249  * @param cur an attribute
       
  2250  *
       
  2251  * Unlink and free one attribute, all the content is freed too
       
  2252  * Note this doesn't work for namespace definition attributes
       
  2253  *
       
  2254  * Returns 0 if success and -1 in case of error.
       
  2255  */
       
  2256 XMLPUBFUNEXPORT int
       
  2257 xmlRemoveProp(xmlAttrPtr cur) {
       
  2258     xmlAttrPtr tmp;
       
  2259     if (cur == NULL) {
       
  2260 #ifdef DEBUG_TREE
       
  2261         xmlGenericError(xmlGenericErrorContext, "xmlRemoveProp : cur == NULL\n");
       
  2262 #endif
       
  2263         return(-1);
       
  2264     }
       
  2265     if (cur->parent == NULL) {
       
  2266 #ifdef DEBUG_TREE
       
  2267         xmlGenericError(xmlGenericErrorContext, "xmlRemoveProp : cur->parent == NULL\n");
       
  2268 #endif
       
  2269         return(-1);
       
  2270     }
       
  2271     tmp = cur->parent->properties;
       
  2272     if (tmp == cur) {
       
  2273         cur->parent->properties = cur->next;
       
  2274         xmlFreeProp(cur);
       
  2275         return(0);
       
  2276     }
       
  2277     while (tmp != NULL) {
       
  2278         if (tmp->next == cur) {
       
  2279             tmp->next = cur->next;
       
  2280             if (tmp->next != NULL)
       
  2281                 tmp->next->prev = tmp;
       
  2282             xmlFreeProp(cur);
       
  2283             return(0);
       
  2284         }
       
  2285         tmp = tmp->next;
       
  2286     }
       
  2287 #ifdef DEBUG_TREE
       
  2288     xmlGenericError(xmlGenericErrorContext, "xmlRemoveProp : attribute not owned by its node\n");
       
  2289 #endif
       
  2290     return(-1);
       
  2291 }
       
  2292 #endif /* LIBXML_TREE_ENABLED */
       
  2293 
       
  2294 
       
  2295 /**
       
  2296  * xmlNewDocPI:
       
  2297  * @param doc the target document
       
  2298  * @param name the processing instruction name
       
  2299  * @param content the PI content
       
  2300  *
       
  2301  * Creation of a processing instruction element.
       
  2302  * Returns a pointer to the new node object.
       
  2303  */
       
  2304 xmlNodePtr
       
  2305 xmlNewDocPI(xmlDocPtr doc, const xmlChar *name, const xmlChar *content) {
       
  2306     xmlNodePtr cur;
       
  2307     LOAD_GS_SAFE_DOC(doc)
       
  2308 
       
  2309     if (name == NULL) {
       
  2310 #ifdef DEBUG_TREE
       
  2311         xmlGenericError(xmlGenericErrorContext,
       
  2312                 "xmlNewPI : name == NULL\n");
       
  2313 #endif
       
  2314         return(NULL);
       
  2315     }
       
  2316 
       
  2317     /*
       
  2318      * Allocate a new node and fill the fields.
       
  2319      */
       
  2320     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  2321     if (cur == NULL) {
       
  2322         xmlTreeErrMemory("building PI");
       
  2323         return(NULL);
       
  2324     }
       
  2325     memset(cur, 0, sizeof(xmlNode));
       
  2326     cur->type = XML_PI_NODE;
       
  2327 
       
  2328     if ((doc != NULL) && (doc->dict != NULL))
       
  2329         cur->name = xmlDictLookup(doc->dict, name, -1);
       
  2330     else
       
  2331         cur->name = xmlStrdup(name);
       
  2332     if (content != NULL) {
       
  2333         cur->content = xmlStrdup(content);
       
  2334     }
       
  2335     cur->doc = doc;
       
  2336 
       
  2337     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  2338         xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
       
  2339     return(cur);
       
  2340 }
       
  2341 
       
  2342 /**
       
  2343  * xmlNewPI:
       
  2344  * @param name the processing instruction name
       
  2345  * @param content the PI content
       
  2346  *
       
  2347  * Creation of a processing instruction element.
       
  2348  * Returns a pointer to the new node object.
       
  2349  *
       
  2350  * OOM: possible --> returns NULL for name!=NULL; OOM flag is set
       
  2351  */
       
  2352 XMLPUBFUNEXPORT xmlNodePtr
       
  2353 xmlNewPI(const xmlChar *name, const xmlChar *content) {
       
  2354 	LOAD_GS_DIRECT
       
  2355     xmlNodePtr cur;
       
  2356 
       
  2357     if (!name) {
       
  2358 #ifdef DEBUG_TREE
       
  2359         xmlGenericError(xmlGenericErrorContext, "xmlNewPI : name == NULL\n");
       
  2360 #endif
       
  2361         return(NULL);
       
  2362     }
       
  2363 
       
  2364     /*
       
  2365      * Allocate a new node and fill the fields.
       
  2366      */
       
  2367     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  2368     if (!cur)
       
  2369         goto OOM_exit;
       
  2370 
       
  2371     memset(cur, 0, sizeof(xmlNode));
       
  2372     cur->type = XML_PI_NODE;
       
  2373 
       
  2374     cur->name = xmlStrdup(name);
       
  2375     if(!cur->name)
       
  2376         goto OOM;
       
  2377 
       
  2378     if (content) {
       
  2379         cur->content = xmlStrdup(content);
       
  2380         if(!cur->content){
       
  2381             xmlFree((void*)cur->name);
       
  2382 OOM:
       
  2383             xmlFree(cur);
       
  2384 OOM_exit:
       
  2385             xmlTreeErrMemory(EMBED_ERRTXT("building PI"));
       
  2386             return(NULL);
       
  2387         }
       
  2388     }
       
  2389 
       
  2390     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  2391     {   
       
  2392         xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
       
  2393     }
       
  2394     return(cur);
       
  2395 }
       
  2396 
       
  2397 /**
       
  2398  * xmlNewNode:
       
  2399  * @param ns namespace if any
       
  2400  * @param name the node name
       
  2401  *
       
  2402  * Creation of a new node element. ns is optional (NULL).
       
  2403  *
       
  2404  * Returns a pointer to the new node object. Uses xmlStrdup() to make
       
  2405  * copy of name.
       
  2406  */
       
  2407 XMLPUBFUNEXPORT xmlNodePtr
       
  2408 xmlNewNode(xmlNsPtr ns, const xmlChar* name)
       
  2409 {
       
  2410 	LOAD_GS_DIRECT
       
  2411     xmlNodePtr cur;
       
  2412 
       
  2413     if (!name) {
       
  2414 #ifdef DEBUG_TREE
       
  2415         xmlGenericError(xmlGenericErrorContext, "xmlNewNode : name == NULL\n");
       
  2416 #endif
       
  2417         return(NULL);
       
  2418     }
       
  2419 
       
  2420     /*
       
  2421      * Allocate a new node and fill the fields.
       
  2422      */
       
  2423     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  2424     if (!cur)
       
  2425         goto OOM_exit;
       
  2426 
       
  2427     memset(cur, 0, sizeof(xmlNode));
       
  2428     cur->type = XML_ELEMENT_NODE;
       
  2429 
       
  2430     cur->name = xmlStrdup(name);
       
  2431     if(!cur->name){
       
  2432         xmlFree(cur); // a Node is freed!
       
  2433 OOM_exit:
       
  2434         xmlTreeErrMemory(EMBED_ERRTXT("building node"));
       
  2435         return(NULL);
       
  2436     }
       
  2437 
       
  2438     cur->ns = ns;
       
  2439 
       
  2440     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)){
       
  2441         
       
  2442         xmlRegisterNodeDefaultValue(cur);
       
  2443     }
       
  2444     return(cur);
       
  2445 }
       
  2446 
       
  2447 /**
       
  2448  * xmlNewNodeEatName:
       
  2449  * @param ns namespace if any
       
  2450  * @param name the node name
       
  2451  *
       
  2452  * Creation of a new node element. ns is optional (NULL).
       
  2453  *
       
  2454  * Returns a pointer to the new node object, with pointer name as
       
  2455  * new node's name. Use xmlNewNode() if a copy of name string is
       
  2456  * is needed as new node's name.
       
  2457  */
       
  2458 XMLPUBFUNEXPORT xmlNodePtr
       
  2459 xmlNewNodeEatName(xmlNsPtr ns, xmlChar* name) {
       
  2460 	LOAD_GS_DIRECT
       
  2461     xmlNodePtr cur;
       
  2462 
       
  2463     if (name == NULL) {
       
  2464 #ifdef DEBUG_TREE
       
  2465         xmlGenericError(xmlGenericErrorContext, "xmlNewNode : name == NULL\n");
       
  2466 #endif
       
  2467         return(NULL);
       
  2468     }
       
  2469 
       
  2470     /*
       
  2471      * Allocate a new node and fill the fields.
       
  2472      */
       
  2473     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  2474     if (cur == NULL) {
       
  2475         xmlTreeErrMemory(EMBED_ERRTXT("building node"));
       
  2476         xmlFree(name);
       
  2477         return(NULL);
       
  2478     }
       
  2479     memset(cur, 0, sizeof(xmlNode));
       
  2480     cur->type = XML_ELEMENT_NODE;
       
  2481 
       
  2482     cur->name = name;
       
  2483     cur->ns = ns;
       
  2484 
       
  2485     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)){
       
  2486         
       
  2487         xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
       
  2488     }
       
  2489     return(cur);
       
  2490 }
       
  2491 
       
  2492 /**
       
  2493  * xmlNewDocNode:
       
  2494  * @param doc the document
       
  2495  * @param ns namespace if any
       
  2496  * @param name the node name
       
  2497  * @param content the XML text content if any
       
  2498  *
       
  2499  * Creation of a new node element within a document. ns and content
       
  2500  * are optional (NULL).
       
  2501  * NOTE: content is supposed to be a piece of XML CDATA, so it allow entities
       
  2502  *       references, but XML special chars need to be escaped first by using
       
  2503  *       xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
       
  2504  *       need entities support.
       
  2505  *
       
  2506  * Returns a pointer to the new node object.
       
  2507  */
       
  2508 XMLPUBFUNEXPORT xmlNodePtr
       
  2509 xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
       
  2510               const xmlChar *name, const xmlChar *content)
       
  2511 {
       
  2512     xmlNodePtr cur;
       
  2513 
       
  2514     cur = xmlNewNode(ns, name);
       
  2515     if (cur != NULL) {
       
  2516         cur->doc = doc;
       
  2517         if (content != NULL) {
       
  2518             cur->children = xmlStringGetNodeList(doc, content);
       
  2519             UPDATE_LAST_CHILD_AND_PARENT(cur)
       
  2520         }
       
  2521     }
       
  2522 
       
  2523     return(cur);
       
  2524 }
       
  2525 
       
  2526 /**
       
  2527  * xmlNewDocNodeEatName:
       
  2528  * @param doc the document
       
  2529  * @param ns namespace if any
       
  2530  * @param name the node name
       
  2531  * @param content the XML text content if any
       
  2532  *
       
  2533  * Creation of a new node element within a document. ns and content
       
  2534  * are optional (NULL).
       
  2535  * NOTE: content is supposed to be a piece of XML CDATA, so it allow entities
       
  2536  *       references, but XML special chars need to be escaped first by using
       
  2537  *       xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
       
  2538  *       need entities support.
       
  2539  *
       
  2540  * Returns a pointer to the new node object.
       
  2541  */
       
  2542 XMLPUBFUNEXPORT xmlNodePtr
       
  2543 xmlNewDocNodeEatName(xmlDocPtr doc, xmlNsPtr ns,
       
  2544               xmlChar *name, const xmlChar *content) {
       
  2545     xmlNodePtr cur;
       
  2546 
       
  2547     cur = xmlNewNodeEatName(ns, name);
       
  2548     if (cur != NULL) {
       
  2549         cur->doc = doc;
       
  2550     if (content != NULL) {
       
  2551         cur->children = xmlStringGetNodeList(doc, content);
       
  2552         UPDATE_LAST_CHILD_AND_PARENT(cur)
       
  2553     }
       
  2554     }
       
  2555     return(cur);
       
  2556 }
       
  2557 
       
  2558 #ifdef LIBXML_TREE_ENABLED
       
  2559 /**
       
  2560  * xmlNewDocRawNode:
       
  2561  * @param doc the document
       
  2562  * @param ns namespace if any
       
  2563  * @param name the node name
       
  2564  * @param content the text content if any
       
  2565  *
       
  2566  * Creation of a new node element within a document. ns and content
       
  2567  * are optional (NULL).
       
  2568  *
       
  2569  * Returns a pointer to the new node object.
       
  2570  */
       
  2571 XMLPUBFUNEXPORT xmlNodePtr
       
  2572 xmlNewDocRawNode(xmlDocPtr doc, xmlNsPtr ns,
       
  2573                  const xmlChar *name, const xmlChar *content)
       
  2574 {
       
  2575     xmlNodePtr cur;
       
  2576 
       
  2577     cur = xmlNewNode(ns, name);
       
  2578     if (cur != NULL) {
       
  2579         cur->doc = doc;
       
  2580         if (content != NULL) {
       
  2581             cur->children = xmlNewDocText(doc, content);
       
  2582             
       
  2583             UPDATE_LAST_CHILD_AND_PARENT(cur)
       
  2584         }
       
  2585     }
       
  2586     return(cur);
       
  2587 }
       
  2588 
       
  2589 /**
       
  2590  * xmlNewDocFragment:
       
  2591  * @param doc the document owning the fragment
       
  2592  *
       
  2593  * Creation of a new Fragment node.
       
  2594  * Returns a pointer to the new node object.
       
  2595  *
       
  2596  * OOM: possible --> returns NULL; OOM flag is set
       
  2597  */
       
  2598 XMLPUBFUNEXPORT xmlNodePtr
       
  2599 xmlNewDocFragment(xmlDocPtr doc) {
       
  2600     xmlNodePtr cur;
       
  2601     LOAD_GS_SAFE_DOC(doc)
       
  2602 
       
  2603     /*
       
  2604      * Allocate a new DocumentFragment node and fill the fields.
       
  2605      */
       
  2606     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  2607     if (cur == NULL) {
       
  2608         xmlTreeErrMemory(EMBED_ERRTXT("building fragment")); // may set OOM flag
       
  2609         return(NULL);
       
  2610     }
       
  2611     memset(cur, 0, sizeof(xmlNode));
       
  2612     cur->type = XML_DOCUMENT_FRAG_NODE;
       
  2613 
       
  2614     cur->doc = doc;
       
  2615 
       
  2616     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  2617         { 
       
  2618         xmlRegisterNodeDefaultValue(cur);
       
  2619         }
       
  2620     return(cur);
       
  2621 }
       
  2622 #endif /* LIBXML_TREE_ENABLED */
       
  2623 
       
  2624 /**
       
  2625  * xmlNewText:
       
  2626  * @param content the text content
       
  2627  *
       
  2628  * Creation of a new text node.
       
  2629  * Returns a pointer to the new node object.
       
  2630  *
       
  2631  * OOM: possible --> returns NULL and sets OOM flag
       
  2632  */
       
  2633 XMLPUBFUNEXPORT xmlNodePtr
       
  2634 xmlNewText(const xmlChar *content)
       
  2635 {
       
  2636 	LOAD_GS_DIRECT
       
  2637     xmlNodePtr cur;
       
  2638 
       
  2639     /*
       
  2640      * Allocate a new node and fill the fields.
       
  2641      */
       
  2642     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  2643     if (!cur)
       
  2644         goto OOM_exit;
       
  2645 
       
  2646     memset(cur, 0, sizeof(xmlNode));
       
  2647     cur->type = XML_TEXT_NODE;
       
  2648 
       
  2649     cur->name = xmlStringText;
       
  2650     if (content) {
       
  2651         cur->content = xmlStrdup(content); // may set OOM flag
       
  2652         if(!cur->content){
       
  2653             xmlFree(cur);
       
  2654 OOM_exit:
       
  2655             xmlTreeErrMemory(EMBED_ERRTXT("building text"));
       
  2656             return(NULL);
       
  2657         }
       
  2658     }
       
  2659 
       
  2660     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  2661     {   
       
  2662         xmlRegisterNodeDefaultValue(cur);
       
  2663     }
       
  2664     return(cur);
       
  2665 }
       
  2666 
       
  2667 #ifdef LIBXML_TREE_ENABLED
       
  2668 /**
       
  2669  * xmlNewTextChild:
       
  2670  * @param parent the parent node
       
  2671  * @param ns a namespace if any
       
  2672  * @param name the name of the child
       
  2673  * @param content the text content of the child if any.
       
  2674  *
       
  2675  * Creation of a new child element, added at the end of parent children list.
       
  2676  * ns and content parameters are optional (NULL). If ns is NULL, the newly
       
  2677  * created element inherits the namespace of parent. If content is non NULL,
       
  2678  * a child TEXT node will be created containing the string content.
       
  2679  * NOTE: Use xmlNewChild() if content will contain entities that need to be
       
  2680  * preserved. Use this function, xmlNewTextChild(), if you need to ensure that
       
  2681  * reserved XML chars that might appear in content, such as the ampersand,
       
  2682  * greater-than or less-than signs, are automatically replaced by their XML
       
  2683  * escaped entity representations.
       
  2684  *
       
  2685  * Returns a pointer to the new node object.
       
  2686  */
       
  2687 XMLPUBFUNEXPORT xmlNodePtr
       
  2688 xmlNewTextChild(xmlNodePtr parent, xmlNsPtr ns,
       
  2689             const xmlChar *name, const xmlChar *content) {
       
  2690     xmlNodePtr cur, prev;
       
  2691 
       
  2692     if (parent == NULL) {
       
  2693 #ifdef DEBUG_TREE
       
  2694         xmlGenericError(xmlGenericErrorContext, "xmlNewTextChild : parent == NULL\n");
       
  2695 #endif
       
  2696         return(NULL);
       
  2697     }
       
  2698 
       
  2699     if (name == NULL) {
       
  2700 #ifdef DEBUG_TREE
       
  2701         xmlGenericError(xmlGenericErrorContext, "xmlNewTextChild : name == NULL\n");
       
  2702 #endif
       
  2703         return(NULL);
       
  2704     }
       
  2705 
       
  2706     /*
       
  2707      * Allocate a new node
       
  2708      */
       
  2709     if (parent->type == XML_ELEMENT_NODE) {
       
  2710         if (ns == NULL)
       
  2711             cur = xmlNewDocRawNode(parent->doc, parent->ns, name, content);
       
  2712         else
       
  2713             cur = xmlNewDocRawNode(parent->doc, ns, name, content);
       
  2714     } else if ((parent->type == XML_DOCUMENT_NODE) ||
       
  2715            (parent->type == XML_HTML_DOCUMENT_NODE))
       
  2716     {
       
  2717         if (ns == NULL)
       
  2718             cur = xmlNewDocRawNode((xmlDocPtr) parent, NULL, name, content);
       
  2719         else
       
  2720             cur = xmlNewDocRawNode((xmlDocPtr) parent, ns, name, content);
       
  2721     } else if (parent->type == XML_DOCUMENT_FRAG_NODE) {
       
  2722         cur = xmlNewDocRawNode( parent->doc, ns, name, content);
       
  2723     } else {
       
  2724         return(NULL);
       
  2725     }
       
  2726     if (cur == NULL) return(NULL);
       
  2727 
       
  2728     /*
       
  2729      * add the new element at the end of the children list.
       
  2730      */
       
  2731     cur->type = XML_ELEMENT_NODE;
       
  2732     cur->parent = parent;
       
  2733     cur->doc = parent->doc;
       
  2734     if (parent->children == NULL) {
       
  2735         parent->children = cur;
       
  2736         parent->last = cur;
       
  2737     } else {
       
  2738         prev = parent->last;
       
  2739         prev->next = cur;
       
  2740         cur->prev = prev;
       
  2741         parent->last = cur;
       
  2742     }
       
  2743 
       
  2744     return(cur);
       
  2745 }
       
  2746 #endif /* LIBXML_TREE_ENABLED */
       
  2747 
       
  2748 /**
       
  2749  * xmlNewCharRef:
       
  2750  * @param doc the document
       
  2751  * @param name the char ref string, starting with # or "&# ... ;"
       
  2752  *
       
  2753  * Creation of a new character reference node.
       
  2754  * Returns a pointer to the new node object.
       
  2755  */
       
  2756 XMLPUBFUNEXPORT xmlNodePtr
       
  2757 xmlNewCharRef(xmlDocPtr doc, const xmlChar *name) {
       
  2758     xmlNodePtr cur;
       
  2759     LOAD_GS_SAFE_DOC(doc)
       
  2760 
       
  2761     /*
       
  2762      * Allocate a new node and fill the fields.
       
  2763      */
       
  2764     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  2765     if (cur == NULL) {
       
  2766     xmlTreeErrMemory(EMBED_ERRTXT("building character reference"));
       
  2767     return(NULL);
       
  2768     }
       
  2769     memset(cur, 0, sizeof(xmlNode));
       
  2770     cur->type = XML_ENTITY_REF_NODE;
       
  2771 
       
  2772     cur->doc = doc;
       
  2773     if (name[0] == '&') {
       
  2774         int len;
       
  2775         name++;
       
  2776     len = xmlStrlen(name);
       
  2777     if (name[len - 1] == ';')
       
  2778         cur->name = xmlStrndup(name, len - 1);
       
  2779     else
       
  2780         cur->name = xmlStrndup(name, len);
       
  2781     } else
       
  2782     cur->name = xmlStrdup(name);
       
  2783 
       
  2784     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  2785     xmlRegisterNodeDefaultValue(cur);
       
  2786     return(cur);
       
  2787 }
       
  2788 
       
  2789 /**
       
  2790  * xmlNewReference:
       
  2791  * @param doc the document
       
  2792  * @param name the reference name, or the reference string with & and ;
       
  2793  *
       
  2794  * Creation of a new reference node.
       
  2795  * Returns a pointer to the new node object.
       
  2796  *
       
  2797  * OOM: returns NULL, sets OOM flag
       
  2798  */
       
  2799 XMLPUBFUNEXPORT xmlNodePtr
       
  2800 xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
       
  2801     xmlNodePtr cur;
       
  2802     xmlEntityPtr ent;
       
  2803     LOAD_GS_SAFE_DOC(doc)
       
  2804 
       
  2805     if (!name)
       
  2806         return(NULL);
       
  2807 
       
  2808     /*
       
  2809      * Allocate a new node and fill the fields.
       
  2810      */
       
  2811     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  2812     if (!cur)
       
  2813         goto OOM_exit;
       
  2814 
       
  2815     memset(cur, 0, sizeof(xmlNode));
       
  2816     cur->type = XML_ENTITY_REF_NODE;
       
  2817 
       
  2818     cur->doc = doc;
       
  2819     if (name[0] == '&') {
       
  2820         int len;
       
  2821         name++;
       
  2822         len = xmlStrlen(name);
       
  2823         if (name[len - 1] == ';')
       
  2824             cur->name = xmlStrndup(name, len - 1);
       
  2825         else
       
  2826             cur->name = xmlStrndup(name, len);
       
  2827     } else
       
  2828         cur->name = xmlStrdup(name);
       
  2829 
       
  2830     if(!cur->name){
       
  2831         xmlFree(cur);
       
  2832 OOM_exit:
       
  2833         xmlTreeErrMemory(EMBED_ERRTXT("building reference"));
       
  2834         return(NULL);
       
  2835     };
       
  2836 
       
  2837     ent = xmlGetDocEntity(doc, cur->name);
       
  2838     if (ent) {
       
  2839         cur->content = ent->content;
       
  2840         /*
       
  2841          * The parent pointer in entity is a DTD pointer and thus is NOT
       
  2842          * updated.  Not sure if this is 100% correct.
       
  2843          *  -George
       
  2844          */
       
  2845         cur->children = (xmlNodePtr) ent;
       
  2846         cur->last = (xmlNodePtr) ent;
       
  2847     }
       
  2848 
       
  2849     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)){
       
  2850         
       
  2851         xmlRegisterNodeDefaultValue(cur);
       
  2852     }
       
  2853     return(cur);
       
  2854 }
       
  2855 
       
  2856 /**
       
  2857  * xmlNewDocText:
       
  2858  * @param doc the document
       
  2859  * @param content the text content
       
  2860  *
       
  2861  * Creation of a new text node within a document.
       
  2862  * Returns a pointer to the new node object.
       
  2863  *
       
  2864  * OOM: possible --> returns NULL and sets OOM flag
       
  2865  */
       
  2866 XMLPUBFUNEXPORT xmlNodePtr
       
  2867 xmlNewDocText(xmlDocPtr doc, const xmlChar *content) {
       
  2868     xmlNodePtr cur;
       
  2869 
       
  2870     cur = xmlNewText(content);
       
  2871     if (cur != NULL)
       
  2872         cur->doc = doc;
       
  2873     return(cur);
       
  2874 }
       
  2875 
       
  2876 /**
       
  2877  * xmlNewTextLen:
       
  2878  * @param content the text content
       
  2879  * @param len the text len.
       
  2880  *
       
  2881  * Creation of a new text node with an extra parameter for the content's length
       
  2882  * Returns a pointer to the new node object.
       
  2883  *
       
  2884  * OOM: possible --> returns NULL, sets OOM flag
       
  2885  */
       
  2886 XMLPUBFUNEXPORT xmlNodePtr
       
  2887 xmlNewTextLen(const xmlChar *content, int len) {
       
  2888 	LOAD_GS_DIRECT
       
  2889     xmlNodePtr cur;
       
  2890 
       
  2891     /*
       
  2892      * Allocate a new node and fill the fields.
       
  2893      */
       
  2894     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  2895     if (!cur)
       
  2896         goto OOM_exit;
       
  2897 
       
  2898     memset(cur, 0, sizeof(xmlNode));
       
  2899     cur->type = XML_TEXT_NODE;
       
  2900 
       
  2901     cur->name = xmlStringText;
       
  2902 
       
  2903     if (content) {
       
  2904         cur->content = xmlStrndup(content, len); // sets OOM flag
       
  2905         
       
  2906         if(!cur->content){
       
  2907             xmlFree(cur);
       
  2908 OOM_exit:
       
  2909             xmlTreeErrMemory(EMBED_ERRTXT("building text")); // sets OOM flag
       
  2910             return(NULL);
       
  2911         }
       
  2912     }
       
  2913 
       
  2914     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)){
       
  2915         
       
  2916         xmlRegisterNodeDefaultValue(cur);
       
  2917     }
       
  2918     return(cur);
       
  2919 }
       
  2920 
       
  2921 /**
       
  2922  * xmlNewDocTextLen:
       
  2923  * @param doc the document
       
  2924  * @param content the text content
       
  2925  * @param len the text len.
       
  2926  *
       
  2927  * Creation of a new text node with an extra content length parameter. The
       
  2928  * text node pertain to a given document.
       
  2929  * Returns a pointer to the new node object.
       
  2930  *
       
  2931  * OOM: possible --> returns NULL and sets OOM flag
       
  2932  */
       
  2933 XMLPUBFUNEXPORT xmlNodePtr
       
  2934 xmlNewDocTextLen(xmlDocPtr doc, const xmlChar *content, int len) {
       
  2935     xmlNodePtr cur;
       
  2936 
       
  2937     cur = xmlNewTextLen(content, len);
       
  2938     if (cur != NULL)
       
  2939         cur->doc = doc;
       
  2940     return(cur);
       
  2941 }
       
  2942 
       
  2943 
       
  2944 
       
  2945 
       
  2946 /**
       
  2947  * xmlNewComment:
       
  2948  * @param content the comment content
       
  2949  *
       
  2950  * Creation of a new node containing a comment.
       
  2951  * Returns a pointer to the new node object.
       
  2952  *
       
  2953  * OOM: possible --> returns NULL; OOM flag is set
       
  2954  */
       
  2955 XMLPUBFUNEXPORT xmlNodePtr
       
  2956 xmlNewComment(const xmlChar *content) {
       
  2957 	LOAD_GS_DIRECT
       
  2958     xmlNodePtr cur;
       
  2959 
       
  2960     /*
       
  2961      * Allocate a new node and fill the fields.
       
  2962      */
       
  2963     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  2964     if (!cur)
       
  2965         goto OOM_exit;
       
  2966 
       
  2967     memset(cur, 0, sizeof(xmlNode));
       
  2968 
       
  2969     cur->type = XML_COMMENT_NODE;
       
  2970     cur->name = xmlStringComment;
       
  2971 
       
  2972     if (content) {
       
  2973         cur->content = xmlStrdup(content);
       
  2974         if(!cur->content){
       
  2975             xmlFree(cur);
       
  2976 OOM_exit:
       
  2977             xmlTreeErrMemory(EMBED_ERRTXT("building comment"));
       
  2978             return(NULL);
       
  2979          }
       
  2980     }
       
  2981 
       
  2982     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  2983     {   
       
  2984         xmlRegisterNodeDefaultValue(cur);
       
  2985     }
       
  2986     return(cur);
       
  2987 }
       
  2988 
       
  2989 // NOTE: CDATABlock accepts length of data, should other "new" methods do the same??
       
  2990 /**
       
  2991  * xmlNewCDataBlock:
       
  2992  * @param doc the document
       
  2993  * @param content the CDATA block content content
       
  2994  * @param len the length of the block
       
  2995  *
       
  2996  * Creation of a new node containing a CDATA block.
       
  2997  * Returns a pointer to the new node object.
       
  2998  *
       
  2999  * OOM: possible --> returns NULL; sets OOM flag
       
  3000  */
       
  3001 XMLPUBFUNEXPORT xmlNodePtr
       
  3002 xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len) {
       
  3003     xmlNodePtr cur;
       
  3004     LOAD_GS_SAFE_DOC(doc)
       
  3005 
       
  3006     /*
       
  3007      * Allocate a new node and fill the fields.
       
  3008      */
       
  3009     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  3010     if (!cur)
       
  3011         goto OOM_exit;
       
  3012 
       
  3013     memset(cur, 0, sizeof(xmlNode));
       
  3014     cur->type = XML_CDATA_SECTION_NODE;
       
  3015     cur->doc = doc;
       
  3016 
       
  3017     if (content) {
       
  3018         cur->content = xmlStrndup(content, len);
       
  3019         if(!cur->content){
       
  3020             xmlFree(cur);
       
  3021 OOM_exit:
       
  3022             xmlTreeErrMemory(EMBED_ERRTXT("building CDATA"));
       
  3023             return(NULL);
       
  3024         }
       
  3025     }
       
  3026 
       
  3027     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)){
       
  3028         
       
  3029         xmlRegisterNodeDefaultValue(cur);
       
  3030     }
       
  3031     return(cur);
       
  3032 }
       
  3033 
       
  3034 /**
       
  3035  * xmlNewDocComment:
       
  3036  * @param doc the document
       
  3037  * @param content the comment content
       
  3038  *
       
  3039  * Creation of a new node containing a comment within a document.
       
  3040  * Returns a pointer to the new node object.
       
  3041  */
       
  3042 XMLPUBFUNEXPORT xmlNodePtr
       
  3043 xmlNewDocComment(xmlDocPtr doc, const xmlChar *content) {
       
  3044     xmlNodePtr cur;
       
  3045 
       
  3046     cur = xmlNewComment(content);
       
  3047     if (cur != NULL) cur->doc = doc;
       
  3048     return(cur);
       
  3049 }
       
  3050 
       
  3051 /**
       
  3052  * xmlSetTreeDoc:
       
  3053  * @param tree the top element
       
  3054  * @param doc the document
       
  3055  *
       
  3056  * update all nodes under the tree to point to the right document
       
  3057  *
       
  3058  */
       
  3059 XMLPUBFUNEXPORT void
       
  3060 xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
       
  3061     xmlAttrPtr prop;
       
  3062     LOAD_GS_SAFE_DOC(doc)
       
  3063 
       
  3064     if (tree == NULL)
       
  3065         return;
       
  3066     if (tree->doc != doc) {
       
  3067         if(tree->type == XML_ELEMENT_NODE) {
       
  3068             prop = tree->properties;
       
  3069             while (prop != NULL) {
       
  3070                 prop->doc = doc;
       
  3071                 xmlSetListDoc(prop->children, doc);
       
  3072                 prop = prop->next;
       
  3073             }
       
  3074         }
       
  3075         if (tree->children != NULL)
       
  3076             xmlSetListDoc(tree->children, doc);
       
  3077         if( IS_DATA_NODE(tree) ){
       
  3078         	xmlRemoveFromDataList(tree, tree->doc);
       
  3079         	xmlAppendDataList(tree, doc);
       
  3080         	if(OOM_FLAG)
       
  3081         		return;	
       
  3082         }        
       
  3083         tree->doc = doc;
       
  3084     }
       
  3085 }
       
  3086 
       
  3087 /**
       
  3088  * xmlSetListDoc:
       
  3089  * @param list the first element
       
  3090  * @param doc the document
       
  3091  *
       
  3092  * update all nodes in the list to point to the right document
       
  3093  *
       
  3094  * OOM: never
       
  3095  */
       
  3096 XMLPUBFUNEXPORT void
       
  3097 xmlSetListDoc(xmlNodePtr list, xmlDocPtr doc) {
       
  3098     xmlNodePtr cur;
       
  3099 
       
  3100     if (list == NULL)
       
  3101         return;
       
  3102     cur = list;
       
  3103     while (cur != NULL)
       
  3104     {
       
  3105         if (cur->doc != doc)
       
  3106             xmlSetTreeDoc(cur, doc);
       
  3107         cur = cur->next;
       
  3108     }
       
  3109 }
       
  3110 
       
  3111 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
       
  3112 /**
       
  3113  * xmlNewChild:
       
  3114  * @param parent the parent node
       
  3115  * @param ns a namespace if any
       
  3116  * @param name the name of the child
       
  3117  * @param content the XML content of the child if any.
       
  3118  *
       
  3119  * Creation of a new child element, added at the end of parent children list.
       
  3120  * ns and content parameters are optional (NULL). If ns is NULL, the newly
       
  3121  * created element inherits the namespace of parent. If content is non NULL,
       
  3122  * a child list containing the TEXTs and ENTITY_REFs node will be created.
       
  3123  * NOTE: content is supposed to be a piece of XML CDATA, so it allows entity
       
  3124  *       references. XML special chars must be escaped first by using
       
  3125  *       xmlEncodeEntitiesReentrant(), or xmlNewTextChild() should be used.
       
  3126  *
       
  3127  * Returns a pointer to the new node object.
       
  3128  */
       
  3129 XMLPUBFUNEXPORT xmlNodePtr
       
  3130 xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
       
  3131             const xmlChar *name, const xmlChar *content) {
       
  3132     xmlNodePtr cur, prev;
       
  3133 
       
  3134     if (parent == NULL) {
       
  3135 #ifdef DEBUG_TREE
       
  3136         xmlGenericError(xmlGenericErrorContext, "xmlNewChild : parent == NULL\n");
       
  3137 #endif
       
  3138     return(NULL);
       
  3139     }
       
  3140 
       
  3141     if (name == NULL) {
       
  3142 #ifdef DEBUG_TREE
       
  3143         xmlGenericError(xmlGenericErrorContext, "xmlNewChild : name == NULL\n");
       
  3144 #endif
       
  3145         return(NULL);
       
  3146     }
       
  3147 
       
  3148     /*
       
  3149      * Allocate a new node
       
  3150      */
       
  3151     if (parent->type == XML_ELEMENT_NODE) {
       
  3152         if (ns == NULL)
       
  3153             cur = xmlNewDocNode(parent->doc, parent->ns, name, content);
       
  3154         else
       
  3155             cur = xmlNewDocNode(parent->doc, ns, name, content);
       
  3156     } else
       
  3157     
       
  3158     if ((parent->type == XML_DOCUMENT_NODE) ||
       
  3159         (parent->type == XML_HTML_DOCUMENT_NODE))
       
  3160     {
       
  3161         /*
       
  3162         if (ns == NULL)
       
  3163             cur = xmlNewDocNode((xmlDocPtr) parent, NULL, name, content);
       
  3164         else
       
  3165             cur = xmlNewDocNode((xmlDocPtr) parent, ns, name, content);
       
  3166         */
       
  3167         // XMLENGINE: REPLACED CODE -- see above and below :)
       
  3168         cur = xmlNewDocNode((xmlDocPtr) parent, ns, name, content);
       
  3169     } else
       
  3170     if (parent->type == XML_DOCUMENT_FRAG_NODE) {
       
  3171             cur = xmlNewDocNode( parent->doc, ns, name, content);
       
  3172     } else {
       
  3173             return(NULL);
       
  3174     }
       
  3175     if (cur == NULL) return(NULL);
       
  3176 
       
  3177     /*
       
  3178      * add the new element at the end of the children list.
       
  3179      */
       
  3180     cur->type = XML_ELEMENT_NODE;
       
  3181     cur->parent = parent;
       
  3182     cur->doc = parent->doc;
       
  3183     if (parent->children == NULL) {
       
  3184         parent->children = cur;
       
  3185     parent->last = cur;
       
  3186     } else {
       
  3187         prev = parent->last;
       
  3188     prev->next = cur;
       
  3189     cur->prev = prev;
       
  3190     parent->last = cur;
       
  3191     }
       
  3192 
       
  3193     return(cur);
       
  3194 }
       
  3195 #endif /* LIBXML_TREE_ENABLED */
       
  3196 
       
  3197 /**
       
  3198  * xmlAddNextSibling:
       
  3199  * @param cur the child node
       
  3200  * @param elem the new node
       
  3201  *
       
  3202  * Add a new node elem as the next sibling of cur
       
  3203  * If the new node was already inserted in a document it is
       
  3204  * first unlinked from its existing context.
       
  3205  * As a result of text merging elem may be freed.
       
  3206  * If the new node is ATTRIBUTE, it is added into properties instead of children.
       
  3207  * If there is an attribute with equal name, it is first destroyed.
       
  3208  *
       
  3209  * Returns the new node or NULL in case of error.
       
  3210  *
       
  3211  * OOM: possible --> sets OOM flag,  returns NULL
       
  3212  *                   elem is not freed in OOM
       
  3213  */
       
  3214 XMLPUBFUNEXPORT xmlNodePtr
       
  3215 xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
       
  3216 	LOAD_GS_SAFE_NODE(cur)
       
  3217     if (cur == NULL) {
       
  3218 #ifdef DEBUG_TREE
       
  3219         xmlGenericError(xmlGenericErrorContext, "xmlAddNextSibling : cur == NULL\n");
       
  3220 #endif
       
  3221         return(NULL);
       
  3222     }
       
  3223     if (elem == NULL) {
       
  3224 #ifdef DEBUG_TREE
       
  3225         xmlGenericError(xmlGenericErrorContext, "xmlAddNextSibling : elem == NULL\n");
       
  3226 #endif
       
  3227         return(NULL);
       
  3228     }
       
  3229     
       
  3230     xmlUnlinkNode(elem);
       
  3231 
       
  3232     if (elem->type == XML_TEXT_NODE) {
       
  3233         if (cur->type == XML_TEXT_NODE) {
       
  3234             xmlNodeAddContent(cur, elem->content);
       
  3235             if(OOM_FLAG)
       
  3236                 return NULL;
       
  3237             xmlFreeNode(elem);
       
  3238             return(cur);
       
  3239         }
       
  3240         if ((cur->next != NULL) &&
       
  3241             (cur->next->type == XML_TEXT_NODE) &&
       
  3242             (cur->name == cur->next->name))
       
  3243         {
       
  3244             xmlChar* tmp;
       
  3245             xmlChar* tmp2;
       
  3246 
       
  3247             tmp = xmlStrdup(elem->content);
       
  3248             if(!tmp)
       
  3249                 return NULL;
       
  3250             tmp2 = xmlStrcat(tmp, cur->next->content);
       
  3251             if(OOM_FLAG)
       
  3252             {
       
  3253                 xmlFree(tmp);
       
  3254                 return NULL;
       
  3255             }
       
  3256             
       
  3257             xmlNodeSetContent(cur->next, tmp2);
       
  3258             xmlFree(tmp2);
       
  3259             if (OOM_FLAG)
       
  3260                 return NULL;
       
  3261             xmlFreeNode(elem);
       
  3262             return(cur->next);
       
  3263         }
       
  3264     } else if (elem->type == XML_ATTRIBUTE_NODE) {
       
  3265         /* check if an attribute with the same name exists */
       
  3266         xmlAttrPtr attr;
       
  3267 
       
  3268         if (elem->ns == NULL)
       
  3269             attr = xmlHasProp(cur->parent, elem->name);
       
  3270         else
       
  3271             attr = xmlHasNsProp(cur->parent, elem->name, elem->ns->href);
       
  3272 
       
  3273         if(!attr){
       
  3274             if(OOM_FLAG){
       
  3275                 xmlFreeProp((xmlAttrPtr)elem);
       
  3276                 return NULL;
       
  3277             }
       
  3278         }else{
       
  3279            if (attr != (xmlAttrPtr) elem) {
       
  3280                 /* different instance, destroy it (attributes must be unique) */
       
  3281                 xmlFreeProp(attr);
       
  3282            }
       
  3283         }
       
  3284     }
       
  3285 
       
  3286     if (elem->doc != cur->doc) {
       
  3287         xmlSetTreeDoc(elem, cur->doc);
       
  3288     }
       
  3289 
       
  3290     elem->parent = cur->parent;
       
  3291     elem->prev = cur;
       
  3292     elem->next = cur->next;
       
  3293     cur->next = elem;
       
  3294 
       
  3295     if (elem->next != NULL)
       
  3296         elem->next->prev = elem;
       
  3297     if ((elem->parent != NULL)      &&
       
  3298         (elem->parent->last == cur) &&
       
  3299         (elem->type != XML_ATTRIBUTE_NODE))
       
  3300     {
       
  3301         elem->parent->last = elem;
       
  3302     }
       
  3303     return(elem);
       
  3304 }
       
  3305 
       
  3306 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED)
       
  3307 /**
       
  3308  * xmlAddPrevSibling:
       
  3309  * @param cur the child node
       
  3310  * @param elem the new node
       
  3311  *
       
  3312  * Add a new node elem as the previous sibling of cur
       
  3313  * merging adjacent TEXT nodes (elem may be freed)
       
  3314  * If the new node was already inserted in a document it is
       
  3315  * first unlinked from its existing context.
       
  3316  * If the new node is ATTRIBUTE, it is added into properties instead of children.
       
  3317  * If there is an attribute with equal name, it is first destroyed.
       
  3318  *
       
  3319  * Returns the new node or NULL in case of error.
       
  3320  */
       
  3321 XMLPUBFUNEXPORT xmlNodePtr
       
  3322 xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) {
       
  3323     if (cur == NULL) {
       
  3324 #ifdef DEBUG_TREE
       
  3325         xmlGenericError(xmlGenericErrorContext,
       
  3326         "xmlAddPrevSibling : cur == NULL\n");
       
  3327 #endif
       
  3328     return(NULL);
       
  3329     }
       
  3330     if (elem == NULL) {
       
  3331 #ifdef DEBUG_TREE
       
  3332         xmlGenericError(xmlGenericErrorContext,
       
  3333         "xmlAddPrevSibling : elem == NULL\n");
       
  3334 #endif
       
  3335     return(NULL);
       
  3336     }
       
  3337 
       
  3338     xmlUnlinkNode(elem);
       
  3339 
       
  3340     if (elem->type == XML_TEXT_NODE) {
       
  3341     if (cur->type == XML_TEXT_NODE) {
       
  3342         xmlChar *tmp;
       
  3343 
       
  3344         tmp = xmlStrdup(elem->content);
       
  3345         tmp = xmlStrcat(tmp, cur->content);
       
  3346         xmlNodeSetContent(cur, tmp);
       
  3347         xmlFree(tmp);
       
  3348         xmlFreeNode(elem);
       
  3349         return(cur);
       
  3350     }
       
  3351     if ((cur->prev != NULL) && (cur->prev->type == XML_TEXT_NODE) &&
       
  3352             (cur->name == cur->prev->name)) {
       
  3353         xmlNodeAddContent(cur->prev, elem->content);
       
  3354         xmlFreeNode(elem);
       
  3355         return(cur->prev);
       
  3356     }
       
  3357     } else if (elem->type == XML_ATTRIBUTE_NODE) {
       
  3358         /* check if an attribute with the same name exists */
       
  3359     xmlAttrPtr attr;
       
  3360 
       
  3361     if (elem->ns == NULL)
       
  3362         attr = xmlHasProp(cur->parent, elem->name);
       
  3363     else
       
  3364         attr = xmlHasNsProp(cur->parent, elem->name, elem->ns->href);
       
  3365     if ((attr != NULL) && (attr != (xmlAttrPtr) elem)) {
       
  3366         /* different instance, destroy it (attributes must be unique) */
       
  3367         xmlFreeProp(attr);
       
  3368     }
       
  3369     }
       
  3370 
       
  3371     if (elem->doc != cur->doc) {
       
  3372     xmlSetTreeDoc(elem, cur->doc);
       
  3373     }
       
  3374     elem->parent = cur->parent;
       
  3375     elem->next = cur;
       
  3376     elem->prev = cur->prev;
       
  3377     cur->prev = elem;
       
  3378     if (elem->prev != NULL)
       
  3379     elem->prev->next = elem;
       
  3380     if (elem->parent != NULL) {
       
  3381     if (elem->type == XML_ATTRIBUTE_NODE) {
       
  3382         if (elem->parent->properties == (xmlAttrPtr) cur) {
       
  3383         elem->parent->properties = (xmlAttrPtr) elem;
       
  3384         }
       
  3385     } else {
       
  3386         if (elem->parent->children == cur) {
       
  3387         elem->parent->children = elem;
       
  3388         }
       
  3389     }
       
  3390     }
       
  3391     return(elem);
       
  3392 }
       
  3393 #endif /* LIBXML_TREE_ENABLED */
       
  3394 
       
  3395 /**
       
  3396  * xmlAddSibling:
       
  3397  * @param cur the child node
       
  3398  * @param elem the new node
       
  3399  *
       
  3400  * Add a new element elem to the list of siblings of cur
       
  3401  * merging adjacent TEXT nodes (elem may be freed)
       
  3402  * If the new element was already inserted in a document it is
       
  3403  * first unlinked from its existing context.
       
  3404  *
       
  3405  * Returns the new element or NULL in case of error.
       
  3406  */
       
  3407 XMLPUBFUNEXPORT xmlNodePtr
       
  3408 xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
       
  3409     xmlNodePtr parent;
       
  3410 
       
  3411     if (cur == NULL) {
       
  3412 #ifdef DEBUG_TREE
       
  3413         xmlGenericError(xmlGenericErrorContext, "xmlAddSibling : cur == NULL\n");
       
  3414 #endif
       
  3415         return(NULL);
       
  3416     }
       
  3417 
       
  3418     if (elem == NULL) {
       
  3419 #ifdef DEBUG_TREE
       
  3420         xmlGenericError(xmlGenericErrorContext, "xmlAddSibling : elem == NULL\n");
       
  3421 #endif
       
  3422         return(NULL);
       
  3423     }
       
  3424 
       
  3425     /*
       
  3426      * Constant time is we can rely on the ->parent->last to find
       
  3427      * the last sibling.
       
  3428      */
       
  3429     
       
  3430     if ((cur->parent != NULL) &&
       
  3431         (cur->parent->children != NULL) &&
       
  3432         (cur->parent->last != NULL) &&
       
  3433         (cur->parent->last->next == NULL))
       
  3434     {
       
  3435         cur = cur->parent->last;
       
  3436     }
       
  3437     else {
       
  3438         while (cur->next != NULL)
       
  3439             cur = cur->next;
       
  3440     }
       
  3441 
       
  3442     xmlUnlinkNode(elem);
       
  3443 
       
  3444     if ((cur->type == XML_TEXT_NODE) &&
       
  3445         (elem->type == XML_TEXT_NODE) &&
       
  3446         (cur->name == elem->name))
       
  3447     {
       
  3448         xmlNodeAddContent(cur, elem->content);
       
  3449         xmlFreeNode(elem);
       
  3450         return(cur);
       
  3451     }
       
  3452 
       
  3453     if (elem->doc != cur->doc) {
       
  3454         xmlSetTreeDoc(elem, cur->doc);
       
  3455     }
       
  3456     parent = cur->parent;
       
  3457     elem->prev = cur;
       
  3458     elem->next = NULL;
       
  3459     elem->parent = parent;
       
  3460     cur->next = elem;
       
  3461 
       
  3462     if (parent != NULL)
       
  3463         parent->last = elem;
       
  3464 
       
  3465     return(elem);
       
  3466 }
       
  3467 
       
  3468 /**
       
  3469  * xmlAddChildList:
       
  3470  * @param parent the parent node
       
  3471  * @param cur the first node in the list
       
  3472  *
       
  3473  * Add a list of node at the end of the child list of the parent
       
  3474  * merging adjacent TEXT nodes (cur may be freed)
       
  3475  *
       
  3476  * Returns the last child or NULL in case of error.
       
  3477  */
       
  3478 XMLPUBFUNEXPORT xmlNodePtr
       
  3479 xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
       
  3480     xmlNodePtr prev;
       
  3481 
       
  3482     if (parent == NULL) {
       
  3483 #ifdef DEBUG_TREE
       
  3484         xmlGenericError(xmlGenericErrorContext, "xmlAddChildList : parent == NULL\n");
       
  3485 #endif
       
  3486         return(NULL);
       
  3487     }
       
  3488 
       
  3489     if (cur == NULL) {
       
  3490 #ifdef DEBUG_TREE
       
  3491         xmlGenericError(xmlGenericErrorContext, "xmlAddChildList : child == NULL\n");
       
  3492 #endif
       
  3493         return(NULL);
       
  3494     }
       
  3495 
       
  3496     if ((cur->doc != NULL) &&
       
  3497         (parent->doc != NULL) &&
       
  3498         (cur->doc != parent->doc))
       
  3499    {
       
  3500 #ifdef DEBUG_TREE
       
  3501         xmlGenericError(xmlGenericErrorContext, "Elements moved to a different document\n");
       
  3502 #endif
       
  3503     }
       
  3504 
       
  3505     /*
       
  3506      * add the first element at the end of the children list.
       
  3507      */
       
  3508 
       
  3509     if (parent->children == NULL) {
       
  3510         parent->children = cur;
       
  3511     } else {
       
  3512         /*
       
  3513          * If cur and parent->last both are TEXT nodes, then merge them.
       
  3514          */
       
  3515         if ((cur->type == XML_TEXT_NODE) &&
       
  3516             (parent->last->type == XML_TEXT_NODE) &&
       
  3517             (cur->name == parent->last->name))
       
  3518         {
       
  3519             xmlNodeAddContent(parent->last, cur->content);
       
  3520             /*
       
  3521              * if it's the only child, nothing more to be done.
       
  3522              */
       
  3523             if (cur->next == NULL) {
       
  3524                 xmlFreeNode(cur);
       
  3525                 return(parent->last);
       
  3526             }
       
  3527             prev = cur;
       
  3528             cur = cur->next;
       
  3529             xmlFreeNode(prev);
       
  3530         }
       
  3531         prev = parent->last;
       
  3532         prev->next = cur;
       
  3533         cur->prev = prev;
       
  3534     }
       
  3535     while (cur->next != NULL) {
       
  3536         cur->parent = parent;
       
  3537         if (cur->doc != parent->doc) {
       
  3538             xmlSetTreeDoc(cur, parent->doc);
       
  3539         }
       
  3540         cur = cur->next;
       
  3541     }
       
  3542     cur->parent = parent;
       
  3543     cur->doc = parent->doc; /* the parent may not be linked to a doc ! */
       
  3544     parent->last = cur;
       
  3545 
       
  3546     return(cur);
       
  3547 }
       
  3548 
       
  3549 /**
       
  3550  * xmlAddChild:
       
  3551  * @param parent the parent node
       
  3552  * @param cur the child node
       
  3553  *
       
  3554  * Add a new node to parent, at the end of the child (or property) list
       
  3555  * merging adjacent TEXT nodes (in which case cur is freed)
       
  3556  * If the new node is ATTRIBUTE, it is added into properties instead of children.
       
  3557  * If there is an attribute with equal name, it is first destroyed.
       
  3558  *
       
  3559  * Returns the child or NULL in case of error.
       
  3560  *
       
  3561  * OOM: possible --> OOM flag is set, NULL is returned
       
  3562  *      if OOM then 'cur' never freed
       
  3563  */
       
  3564 XMLPUBFUNEXPORT xmlNodePtr
       
  3565 xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
       
  3566     xmlNodePtr prev;
       
  3567     LOAD_GS_SAFE_NODE(cur)
       
  3568 
       
  3569     if (parent == NULL) {
       
  3570 #ifdef DEBUG_TREE
       
  3571         xmlGenericError(xmlGenericErrorContext, "xmlAddChild : parent == NULL\n");
       
  3572 #endif
       
  3573         return(NULL);
       
  3574     }
       
  3575 
       
  3576     if (cur == NULL) {
       
  3577 #ifdef DEBUG_TREE
       
  3578         xmlGenericError(xmlGenericErrorContext, "xmlAddChild : child == NULL\n");
       
  3579 #endif
       
  3580         return(NULL);
       
  3581     }
       
  3582 
       
  3583     /*
       
  3584      * If cur is a TEXT node, merge its content with adjacent TEXT nodes
       
  3585      * cur is then freed.
       
  3586      */
       
  3587     
       
  3588     if (cur->type == XML_TEXT_NODE) {
       
  3589         if ((parent->type == XML_TEXT_NODE) &&
       
  3590             (parent->content != NULL) &&
       
  3591             (parent->name == cur->name) &&
       
  3592             (parent != cur))
       
  3593         {
       
  3594             xmlNodeAddContent(parent, cur->content);
       
  3595             xmlFreeNode(cur);
       
  3596             //
       
  3597             if(OOM_FLAG)
       
  3598                 return NULL;
       
  3599             //
       
  3600             return(parent);
       
  3601         }
       
  3602         if ((parent->last != NULL) &&
       
  3603             (parent->last->type == XML_TEXT_NODE) &&
       
  3604             (parent->last->name == cur->name) &&
       
  3605             (parent->last != cur) &&
       
  3606             (!(TEXT_IS_DATA(cur)))) 
       
  3607         {
       
  3608             xmlNodeAddContent(parent->last, cur->content);
       
  3609             //
       
  3610             if(OOM_FLAG)
       
  3611                 return NULL;
       
  3612             //
       
  3613             xmlFreeNode(cur);
       
  3614             return(parent->last);
       
  3615         }
       
  3616        	if(TEXT_IS_DATA(cur)){
       
  3617        		xmlAppendDataList(cur, cur->doc);
       
  3618        	}
       
  3619     }
       
  3620 
       
  3621     /*
       
  3622      * add the new element at the end of the children list.
       
  3623      */
       
  3624     prev = cur->parent;
       
  3625     cur->parent = parent;
       
  3626     if (cur->doc != parent->doc)
       
  3627     {
       
  3628         xmlSetTreeDoc(cur, parent->doc);
       
  3629     }
       
  3630     /* this check prevents a loop on tree-traversions if a developer
       
  3631      * tries to add a node to its parent multiple times
       
  3632      */
       
  3633     if (prev == parent)
       
  3634         return(cur);
       
  3635 
       
  3636     /*
       
  3637      * Coalescing
       
  3638      */
       
  3639     if ((parent->type == XML_TEXT_NODE) &&
       
  3640         (parent->content != NULL) &&
       
  3641         (parent != cur))
       
  3642     {
       
  3643         xmlNodeAddContent(parent, cur->content);
       
  3644         if(OOM_FLAG)
       
  3645             return NULL;
       
  3646         //
       
  3647         xmlFreeNode(cur);
       
  3648         //
       
  3649         return(parent);
       
  3650     }
       
  3651     if (cur->type == XML_ATTRIBUTE_NODE) {
       
  3652         if (parent->properties == NULL) {
       
  3653             parent->properties = (xmlAttrPtr) cur;
       
  3654         } else {
       
  3655             /* check if an attribute with the same name exists */
       
  3656             xmlAttrPtr lastattr;
       
  3657 
       
  3658             if (cur->ns == NULL)
       
  3659                 lastattr = xmlHasProp(parent, cur->name);
       
  3660             else
       
  3661                 lastattr = xmlHasNsProp(parent, cur->name, cur->ns->href);
       
  3662             // OOM was possible --> if lastattr == NULL and xmlOOM is set
       
  3663 
       
  3664             if (lastattr != NULL){
       
  3665                 if (lastattr != (xmlAttrPtr) cur) {
       
  3666                     /* different instance, destroy it (attributes must be unique) */
       
  3667                     xmlFreeProp(lastattr);
       
  3668                 }
       
  3669             }else{
       
  3670                 // lastattr == NULL
       
  3671                 if (OOM_FLAG)
       
  3672                     return NULL;
       
  3673             }
       
  3674             /* find the end */
       
  3675             lastattr = parent->properties;
       
  3676             while (lastattr->next != NULL) {
       
  3677                 lastattr = lastattr->next;
       
  3678             }
       
  3679             lastattr->next = (xmlAttrPtr) cur;
       
  3680             ((xmlAttrPtr) cur)->prev = lastattr;
       
  3681         }
       
  3682     } else {
       
  3683         if (parent->children == NULL) {
       
  3684             parent->children = cur;
       
  3685             parent->last = cur;
       
  3686         } else {
       
  3687             prev = parent->last;
       
  3688             prev->next = cur;
       
  3689             cur->prev = prev;
       
  3690             parent->last = cur;
       
  3691         }
       
  3692     }
       
  3693     return(cur);
       
  3694 }
       
  3695 
       
  3696 /**
       
  3697  * xmlGetLastChild:
       
  3698  * @param parent the parent node
       
  3699  *
       
  3700  * Search the last child of a node.
       
  3701  * Returns the last child or NULL if none.
       
  3702  */
       
  3703 XMLPUBFUNEXPORT xmlNodePtr
       
  3704 xmlGetLastChild(xmlNodePtr parent) {
       
  3705     
       
  3706     //       Note! only there are two users: areBlanks() and xmlSAX2CDataBlock():
       
  3707     //       the former always gives argument!=NULL and the latter needs code to
       
  3708     //       check the argument itself
       
  3709     if (parent == NULL) {
       
  3710 #ifdef DEBUG_TREE
       
  3711         xmlGenericError(xmlGenericErrorContext, "xmlGetLastChild : parent == NULL\n");
       
  3712 #endif
       
  3713         return(NULL);
       
  3714     }
       
  3715     return(parent->last);
       
  3716 }
       
  3717 
       
  3718 /**
       
  3719  * xmlFreeNodeList:
       
  3720  * @param cur the first node in the list
       
  3721  *
       
  3722  * Free a node and all its siblings, this is a recursive behaviour, all
       
  3723  * the children are freed too.
       
  3724  *
       
  3725  * OOM: never
       
  3726  */
       
  3727 XMLPUBFUNEXPORT void
       
  3728 xmlFreeNodeList(xmlNodePtr cur) {
       
  3729     xmlNodePtr next;
       
  3730     xmlDictPtr dict = NULL;
       
  3731     LOAD_GS_SAFE_NODE(cur)
       
  3732 
       
  3733     if (cur == NULL) return;
       
  3734     if (cur->type == XML_NAMESPACE_DECL) {
       
  3735         xmlFreeNsList((xmlNsPtr) cur);
       
  3736         return;
       
  3737     }
       
  3738 
       
  3739     if ((cur->type == XML_DOCUMENT_NODE) ||
       
  3740         (cur->type == XML_HTML_DOCUMENT_NODE))
       
  3741     {
       
  3742         xmlFreeDoc((xmlDocPtr) cur);
       
  3743         return;
       
  3744     }
       
  3745     if (cur->doc != NULL)
       
  3746         dict = cur->doc->dict;
       
  3747     while (cur != NULL) {
       
  3748         next = cur->next;
       
  3749         if (cur->type != XML_DTD_NODE)
       
  3750         {
       
  3751             if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
       
  3752                 xmlDeregisterNodeDefaultValue(cur);
       
  3753             
       
  3754             if ((cur->children != NULL) &&
       
  3755                 (cur->type != XML_ENTITY_REF_NODE))
       
  3756             {
       
  3757                 xmlFreeNodeList(cur->children);
       
  3758             }
       
  3759             
       
  3760             //  type = cur->type; 
       
  3761             //  A = (type == XML_ELEMENT_NODE) ||
       
  3762             //      (type == XML_XINCLUDE_START) ||
       
  3763             //      (type == XML_XINCLUDE_END)
       
  3764             //  if(A){
       
  3765             //      if(cur->properties) {xmlFreePropList(cur->properties);}
       
  3766             //      if(cur->nsDef) {xmlFreeNsList(cur->nsDef);}
       
  3767             //  }else
       
  3768             //    if(type != XML_ENTITY_REF_NODE) {DICT_FREE(cur->content)}
       
  3769 
       
  3770 
       
  3771             //1.  if (A && cur->properties != NULL)
       
  3772             if (((cur->type == XML_ELEMENT_NODE) ||
       
  3773                 (cur->type == XML_XINCLUDE_START) ||
       
  3774                 (cur->type == XML_XINCLUDE_END)) &&
       
  3775                 (cur->properties != NULL))
       
  3776             {
       
  3777                 xmlFreePropList(cur->properties);
       
  3778             }
       
  3779 
       
  3780             //2.  if (!A && (cur->type != XML_ENTITY_REF_NODE))
       
  3781             if ((cur->type != XML_ELEMENT_NODE) &&
       
  3782                 (cur->type != XML_XINCLUDE_START) &&
       
  3783                 (cur->type != XML_XINCLUDE_END) &&
       
  3784                 (cur->type != XML_ENTITY_REF_NODE))
       
  3785             {
       
  3786             	if (IS_DATA_NODE(cur)){
       
  3787 					xmlRemoveFromDataList(cur, cur->doc);
       
  3788 					DICT_FREE(cur->ns)
       
  3789 					if (TEXT_IS_BINARY(cur)){
       
  3790 						DICT_FREE(cur->content)	
       
  3791 					}
       
  3792             	}
       
  3793 				else{
       
  3794 					DICT_FREE(cur->content)
       
  3795 				}
       
  3796             }
       
  3797 
       
  3798             //3.  if (A && (cur->nsDef != NULL))
       
  3799             if (((cur->type == XML_ELEMENT_NODE) ||
       
  3800                 (cur->type == XML_XINCLUDE_START) ||
       
  3801                 (cur->type == XML_XINCLUDE_END)) &&
       
  3802                 (cur->nsDef != NULL))
       
  3803             {
       
  3804                 xmlFreeNsList(cur->nsDef);
       
  3805             }
       
  3806 
       
  3807             /*
       
  3808             * When a node is a text node or a comment, it uses a global static
       
  3809             * variable for the name of the node.
       
  3810             * Otherwise the node name might come from the document's
       
  3811             * dictionnary
       
  3812             */
       
  3813             if ((cur->name) &&
       
  3814                 (cur->type != XML_TEXT_NODE) &&
       
  3815                 (cur->type != XML_COMMENT_NODE))
       
  3816             {
       
  3817                 DICT_FREE(cur->name)
       
  3818             }
       
  3819             xmlFree(cur);
       
  3820         }
       
  3821         cur = next;
       
  3822     }
       
  3823 }
       
  3824 
       
  3825 /**
       
  3826  * xmlFreeNode:
       
  3827  * @param cur the node
       
  3828  *
       
  3829  * Free a node, this is a recursive behaviour, all the children are freed too.
       
  3830  * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
       
  3831  *
       
  3832  * OOM: never
       
  3833  */
       
  3834 XMLPUBFUNEXPORT void
       
  3835 xmlFreeNode(xmlNodePtr cur) {
       
  3836 	xmlDictPtr dict = NULL;
       
  3837 	LOAD_GS_SAFE_NODE(cur)
       
  3838     
       
  3839     
       
  3840     
       
  3841     
       
  3842     if (cur == NULL) return;
       
  3843 
       
  3844     /* use xmlFreeDtd for DTD nodes */
       
  3845     if (cur->type == XML_DTD_NODE) {
       
  3846         xmlFreeDtd((xmlDtdPtr) cur);
       
  3847         return;
       
  3848     }
       
  3849     if (cur->type == XML_NAMESPACE_DECL) {
       
  3850         xmlFreeNs((xmlNsPtr) cur);
       
  3851         return;
       
  3852     }
       
  3853     if (cur->type == XML_ATTRIBUTE_NODE) {
       
  3854         xmlFreeProp((xmlAttrPtr) cur);
       
  3855         return;
       
  3856     }
       
  3857     if (cur->type == XML_DOCUMENT_NODE) {
       
  3858         xmlFreeDoc((xmlDocPtr) cur);
       
  3859         return;
       
  3860     }
       
  3861     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
       
  3862     {   
       
  3863         xmlDeregisterNodeDefaultValue(cur);
       
  3864     }
       
  3865     
       
  3866     //  KO: I think this should be done prior to freeing other node's data
       
  3867 
       
  3868     if (cur->doc != NULL) dict = cur->doc->dict;
       
  3869 
       
  3870     if ((cur->children != NULL) &&
       
  3871         (cur->type != XML_ENTITY_REF_NODE))
       
  3872         xmlFreeNodeList(cur->children);
       
  3873 
       
  3874     if (((cur->type == XML_ELEMENT_NODE) ||
       
  3875         (cur->type == XML_XINCLUDE_START) ||
       
  3876         (cur->type == XML_XINCLUDE_END)) &&
       
  3877         (cur->properties != NULL))
       
  3878     {
       
  3879         xmlFreePropList(cur->properties);
       
  3880     }
       
  3881     if ((cur->type != XML_ELEMENT_NODE) &&
       
  3882         (cur->content != NULL) &&
       
  3883         (cur->type != XML_ENTITY_REF_NODE) &&
       
  3884         (cur->type != XML_XINCLUDE_END) &&
       
  3885         (cur->type != XML_XINCLUDE_START))
       
  3886     {
       
  3887        	if (IS_DATA_NODE(cur)){
       
  3888 			xmlRemoveFromDataList(cur, cur->doc);
       
  3889 			DICT_FREE(cur->ns)
       
  3890 			if (TEXT_IS_BINARY(cur)){
       
  3891 				DICT_FREE(cur->content)	
       
  3892 			}
       
  3893        	}
       
  3894 		else{
       
  3895 			DICT_FREE(cur->content)
       
  3896 		}      
       
  3897     }
       
  3898 
       
  3899     /*
       
  3900      * When a node is a text node or a comment, it uses a global static
       
  3901      * variable for the name of the node.
       
  3902      * Otherwise the node name might come from the document's dictionnary
       
  3903      */
       
  3904     if ((cur->name != NULL) &&
       
  3905         (cur->type != XML_TEXT_NODE) &&
       
  3906         (cur->type != XML_COMMENT_NODE))
       
  3907     {
       
  3908         DICT_FREE(cur->name)
       
  3909     }
       
  3910     if (((cur->type == XML_ELEMENT_NODE) ||
       
  3911         (cur->type == XML_XINCLUDE_START) ||
       
  3912         (cur->type == XML_XINCLUDE_END)) &&
       
  3913         (cur->nsDef != NULL))
       
  3914     {
       
  3915         xmlFreeNsList(cur->nsDef);
       
  3916     }
       
  3917     xmlFree(cur);
       
  3918 }
       
  3919 
       
  3920 /**
       
  3921  * xmlUnlinkNode:
       
  3922  * @param cur the node
       
  3923  *
       
  3924  * Unlink a node from it's current context, the node is not freed
       
  3925  *
       
  3926  * OOM: never
       
  3927  */
       
  3928 XMLPUBFUNEXPORT void
       
  3929 xmlUnlinkNode(xmlNodePtr cur) {
       
  3930     if (cur == NULL) {
       
  3931 #ifdef DEBUG_TREE
       
  3932         xmlGenericError(xmlGenericErrorContext, "xmlUnlinkNode : node == NULL\n");
       
  3933 #endif
       
  3934         return;
       
  3935     }
       
  3936     if (cur->type == XML_DTD_NODE) {
       
  3937         xmlDocPtr doc;
       
  3938         doc = cur->doc;
       
  3939         if (doc != NULL) {
       
  3940             if (doc->intSubset == (xmlDtdPtr) cur)
       
  3941                 doc->intSubset = NULL;
       
  3942             if (doc->extSubset == (xmlDtdPtr) cur)
       
  3943                 doc->extSubset = NULL;
       
  3944         }
       
  3945     }
       
  3946     else if (IS_DATA_NODE(cur)){
       
  3947     	xmlRemoveFromDataList(cur, cur->doc);
       
  3948 	}    
       
  3949     if (cur->parent != NULL) {
       
  3950         xmlNodePtr parent;
       
  3951         parent = cur->parent;
       
  3952         if (cur->type == XML_ATTRIBUTE_NODE) {
       
  3953             if (parent->properties == (xmlAttrPtr) cur)
       
  3954                 parent->properties = ((xmlAttrPtr) cur)->next;
       
  3955         } else {
       
  3956             if (parent->children == cur)
       
  3957                 parent->children = cur->next;
       
  3958             if (parent->last == cur)
       
  3959                 parent->last = cur->prev;
       
  3960         }
       
  3961         cur->parent = NULL;
       
  3962     }
       
  3963     if (cur->next != NULL)
       
  3964         cur->next->prev = cur->prev;
       
  3965     if (cur->prev != NULL)
       
  3966         cur->prev->next = cur->next;
       
  3967     cur->next = cur->prev = NULL;
       
  3968 }
       
  3969 
       
  3970 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
       
  3971 /**
       
  3972  * xmlReplaceNode:
       
  3973  * @param old the old node
       
  3974  * @param cur the node
       
  3975  *
       
  3976  * Unlink the old node from its current context, prune the new one
       
  3977  * at the same place. If cur was already inserted in a document it is
       
  3978  * first unlinked from its existing context.
       
  3979  *
       
  3980  * Returns the old node
       
  3981  */
       
  3982 XMLPUBFUNEXPORT xmlNodePtr
       
  3983 xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
       
  3984     if (old == NULL) {
       
  3985 #ifdef DEBUG_TREE
       
  3986         xmlGenericError(xmlGenericErrorContext, "xmlReplaceNode : old == NULL\n");
       
  3987 #endif
       
  3988         return(NULL);
       
  3989     }
       
  3990     if (cur == NULL) {
       
  3991         xmlUnlinkNode(old);
       
  3992         return(old);
       
  3993     }
       
  3994     if (cur == old) {
       
  3995         return(old);
       
  3996     }
       
  3997     if ((old->type==XML_ATTRIBUTE_NODE) && (cur->type!=XML_ATTRIBUTE_NODE)) {
       
  3998 #ifdef DEBUG_TREE
       
  3999         xmlGenericError(xmlGenericErrorContext,
       
  4000         "xmlReplaceNode : Trying to replace attribute node with other node type\n");
       
  4001 #endif
       
  4002         return(old);
       
  4003     }
       
  4004     if ((cur->type==XML_ATTRIBUTE_NODE) && (old->type!=XML_ATTRIBUTE_NODE)) {
       
  4005 #ifdef DEBUG_TREE
       
  4006         xmlGenericError(xmlGenericErrorContext,
       
  4007         "xmlReplaceNode : Trying to replace a non-attribute node with attribute node\n");
       
  4008 #endif
       
  4009         return(old);
       
  4010     }
       
  4011     xmlUnlinkNode(cur);
       
  4012     
       
  4013 	if (IS_DATA_NODE(cur))
       
  4014 	{
       
  4015 		if(xmlReplaceInDataList(old, cur, old->doc) == -1)
       
  4016 		{
       
  4017 			xmlAppendDataList(cur,old->doc);
       
  4018 		}
       
  4019 	}
       
  4020 				
       
  4021     cur->doc = old->doc;
       
  4022     cur->parent = old->parent;
       
  4023     cur->next = old->next;
       
  4024     if (cur->next != NULL)
       
  4025         cur->next->prev = cur;
       
  4026     cur->prev = old->prev;
       
  4027     if (cur->prev != NULL)
       
  4028         cur->prev->next = cur;
       
  4029     if (cur->parent != NULL) {
       
  4030         if (cur->type == XML_ATTRIBUTE_NODE) {
       
  4031             if (cur->parent->properties == (xmlAttrPtr)old)
       
  4032                 cur->parent->properties = ((xmlAttrPtr) cur);
       
  4033         } else {
       
  4034             if (cur->parent->children == old)
       
  4035                 cur->parent->children = cur;
       
  4036             if (cur->parent->last == old)
       
  4037                 cur->parent->last = cur;
       
  4038         }
       
  4039     }
       
  4040     old->next = old->prev = NULL;
       
  4041     old->parent = NULL;
       
  4042     return(old);
       
  4043 }
       
  4044 #endif /* LIBXML_TREE_ENABLED */
       
  4045 
       
  4046 /************************************************************************
       
  4047  *                                                                      *
       
  4048  *      Copy operations                                                 *
       
  4049  *                                                                      *
       
  4050  ************************************************************************/
       
  4051 
       
  4052 /**
       
  4053  * xmlCopyNamespace:
       
  4054  * @param cur the namespace
       
  4055  *
       
  4056  * Do a copy of the namespace.
       
  4057  *
       
  4058  * Returns: a new #xmlNsPtr, or NULL in case of error.
       
  4059  *
       
  4060  * OOM: possible --> returns NULL and sets OOM
       
  4061  */
       
  4062 XMLPUBFUNEXPORT xmlNsPtr
       
  4063 xmlCopyNamespace(xmlNsPtr cur)
       
  4064 {
       
  4065     if (cur == NULL)
       
  4066         return(NULL);
       
  4067 
       
  4068     switch (cur->type) {
       
  4069     case XML_LOCAL_NAMESPACE:
       
  4070         return xmlNewNs(NULL, cur->href, cur->prefix);
       
  4071     default:
       
  4072 #ifdef DEBUG_TREE
       
  4073         xmlGenericError(xmlGenericErrorContext,
       
  4074             "xmlCopyNamespace: invalid type %d\n", cur->type);
       
  4075 #endif
       
  4076         return(NULL);
       
  4077     }
       
  4078 }
       
  4079 
       
  4080 /**
       
  4081  * xmlCopyNamespaceList:
       
  4082  * @param cur the first namespace
       
  4083  *
       
  4084  * Do a copy of an namespace list.
       
  4085  *
       
  4086  * Returns: a new #xmlNsPtr, or NULL in case of error.
       
  4087  *
       
  4088  * OOM: possible --> if returns NULL for cur!=NULL (sets OOM flag too)
       
  4089  */
       
  4090 XMLPUBFUNEXPORT xmlNsPtr
       
  4091 xmlCopyNamespaceList(xmlNsPtr cur) {
       
  4092 	LOAD_GS_DIRECT
       
  4093     xmlNsPtr ret = NULL;
       
  4094     xmlNsPtr p = NULL,q;
       
  4095 
       
  4096     while (cur != NULL) {
       
  4097         q = xmlCopyNamespace(cur);
       
  4098         if(!q && OOM_FLAG){
       
  4099             if(ret)
       
  4100                 xmlFreeNsList(ret);
       
  4101             return NULL;
       
  4102         }
       
  4103         if (p == NULL) {
       
  4104             ret = p = q;
       
  4105         } else {
       
  4106             p->next = q;
       
  4107             p = q;
       
  4108         }
       
  4109         cur = cur->next;
       
  4110     }
       
  4111     return(ret);
       
  4112 }
       
  4113 
       
  4114 //static
       
  4115 XMLPUBFUN xmlNodePtr
       
  4116 xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent);
       
  4117 /**
       
  4118  * xmlCopyProp:
       
  4119  * @param target the element where the attribute will be grafted
       
  4120  * @param cur the attribute
       
  4121  *
       
  4122  * Do a copy of the attribute.
       
  4123  *
       
  4124  * Returns: a new #xmlAttrPtr, or NULL in case of error.
       
  4125  *
       
  4126  * OOM: possible --> NULL is returned for cur!=NULL, OOM flag is set
       
  4127  */
       
  4128 XMLPUBFUNEXPORT xmlAttrPtr
       
  4129 xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur)
       
  4130 {
       
  4131     xmlAttrPtr ret;
       
  4132     xmlDocPtr target_doc; // XE: new code
       
  4133 	LOAD_GS_SAFE_ATTR(cur)
       
  4134 	
       
  4135     if (cur == NULL) return(NULL);
       
  4136 
       
  4137 /* XMLENGINE: CHANGED CODE
       
  4138     if (target != NULL)
       
  4139         ret = xmlNewDocProp(target->doc, cur->name, NULL);
       
  4140     else if (cur->parent != NULL)
       
  4141         ret = xmlNewDocProp(cur->parent->doc, cur->name, NULL);
       
  4142     else if (cur->children != NULL)
       
  4143         ret = xmlNewDocProp(cur->children->doc, cur->name, NULL);
       
  4144     else
       
  4145         ret = xmlNewDocProp(NULL, cur->name, NULL);
       
  4146 */
       
  4147 // XMLENGINE: REPLACEMENT CODE
       
  4148      // replaces target->doc  in the rest of function
       
  4149     if (target)
       
  4150         target_doc = target->doc;
       
  4151     else if (cur->parent)
       
  4152         target_doc = cur->parent->doc;
       
  4153     else if (cur->children)
       
  4154         target_doc = cur->children->doc;
       
  4155     else
       
  4156         target_doc = NULL;
       
  4157 
       
  4158     ret = xmlNewDocProp(target_doc, cur->name, NULL);
       
  4159 //   END REPLACEMENT
       
  4160     if(!ret)
       
  4161         return ret; // NULL, OOM detected
       
  4162 
       
  4163     ret->parent = target;
       
  4164 
       
  4165     if ((cur->ns != NULL) && (target != NULL))
       
  4166     {
       
  4167         xmlNsPtr ns;
       
  4168 
       
  4169         ns = xmlSearchNs(target_doc, target, cur->ns->prefix);
       
  4170         if (ns == NULL) {
       
  4171             /*
       
  4172              * Humm, we are copying an element whose namespace is defined
       
  4173              * out of the new tree scope. Search it in the original tree
       
  4174              * and add it at the top of the new tree
       
  4175              */
       
  4176             ns = xmlSearchNs(cur->doc, cur->parent, cur->ns->prefix);
       
  4177             if (ns != NULL) {
       
  4178               xmlNodePtr root = target;
       
  4179               xmlNodePtr pred = NULL;
       
  4180 
       
  4181               while (root->parent != NULL) {
       
  4182                 pred = root;
       
  4183                 root = root->parent;
       
  4184               }
       
  4185               if (root == (xmlNodePtr) target_doc) {
       
  4186                 /* correct possibly cycling above the document elt */
       
  4187                 root = pred;
       
  4188               }
       
  4189               ret->ns = xmlNewNs(root, ns->href, ns->prefix);
       
  4190             }
       
  4191           } else {
       
  4192                 /*
       
  4193                  * we have to find something appropriate here since
       
  4194                  * we cant be sure, that the namespace we found is identified
       
  4195                  * by the prefix
       
  4196                  */
       
  4197                 if (xmlStrEqual(ns->href, cur->ns->href)) {
       
  4198                   /* this is the nice case */
       
  4199                   ret->ns = ns;
       
  4200                 } else {
       
  4201                   /*
       
  4202                    * we are in trouble: we need a new reconcilied namespace.
       
  4203                    * This is expensive
       
  4204                    */
       
  4205                   ret->ns = xmlNewReconciliedNs(target_doc, target, cur->ns);
       
  4206                 }
       
  4207           }
       
  4208 
       
  4209     } else
       
  4210         ret->ns = NULL;
       
  4211     //-
       
  4212     if(OOM_FLAG)
       
  4213         goto OOM;
       
  4214     //-
       
  4215     if (cur->children != NULL) {
       
  4216         xmlNodePtr tmp;
       
  4217 
       
  4218         ret->children = xmlStaticCopyNodeList(cur->children, target_doc /* ret->doc */, (xmlNodePtr) ret);
       
  4219         //-
       
  4220         if(OOM_FLAG)
       
  4221             goto OOM;
       
  4222         //-
       
  4223         ret->last = NULL;
       
  4224         tmp = ret->children;
       
  4225         while (tmp != NULL) {
       
  4226             /* tmp->parent = (xmlNodePtr)ret; */
       
  4227             if (tmp->next == NULL)
       
  4228                 ret->last = tmp;
       
  4229             tmp = tmp->next;
       
  4230         }
       
  4231     }
       
  4232     /*
       
  4233      * Try to handle IDs
       
  4234      */
       
  4235     if (target && cur &&
       
  4236         target->doc && cur->doc &&
       
  4237         cur->doc->ids && cur->parent)
       
  4238     {
       
  4239         if (xmlIsID(cur->doc, cur->parent, cur)) {
       
  4240             xmlChar *id;
       
  4241 
       
  4242             id = xmlNodeListGetString(cur->doc, cur->children, 1);
       
  4243             if (id) {
       
  4244                 xmlAddID(NULL, target_doc, id, ret);
       
  4245                 xmlFree(id);
       
  4246             }
       
  4247             if(OOM_FLAG)
       
  4248                 goto OOM;
       
  4249         }
       
  4250     }
       
  4251     return(ret);
       
  4252 OOM:
       
  4253     xmlFreeProp(ret);
       
  4254     return NULL;
       
  4255 }
       
  4256 
       
  4257 /**
       
  4258  * xmlCopyPropList:
       
  4259  * @param target the element where the attributes will be grafted
       
  4260  * @param cur the first attribute
       
  4261  *
       
  4262  * Do a copy of an attribute list.
       
  4263  *
       
  4264  * Returns: a new #xmlAttrPtr, or NULL in case of error.
       
  4265  *
       
  4266  * OOM: possible --> returns NULL for cur!=NULL,  sets OOM flag
       
  4267  */
       
  4268 XMLPUBFUNEXPORT xmlAttrPtr
       
  4269 xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) {
       
  4270     xmlAttrPtr ret = NULL;
       
  4271     xmlAttrPtr p = NULL,q;
       
  4272 
       
  4273     while (cur != NULL) {
       
  4274         q = xmlCopyProp(target, cur);
       
  4275         if(!q){ // OOM
       
  4276             xmlFreePropList(ret);
       
  4277             return NULL;
       
  4278         }
       
  4279 
       
  4280         if (p == NULL) {
       
  4281             ret = p = q;
       
  4282         } else {
       
  4283             p->next = q;
       
  4284             q->prev = p;
       
  4285             p = q;
       
  4286         }
       
  4287         cur = cur->next;
       
  4288     }
       
  4289     return(ret);
       
  4290 }
       
  4291 
       
  4292 /*
       
  4293  * NOTE about the CopyNode operations !
       
  4294  *
       
  4295  * They are split into external and internal parts for one
       
  4296  * tricky reason: namespaces. Doing a direct copy of a node
       
  4297  * say RPM:Copyright without changing the namespace pointer to
       
  4298  * something else can produce stale links. One way to do it is
       
  4299  * to keep a reference counter but this doesn't work as soon
       
  4300  * as one move the element or the subtree out of the scope of
       
  4301  * the existing namespace. The actual solution seems to add
       
  4302  * a copy of the namespace at the top of the copied tree if
       
  4303  * not available in the subtree.
       
  4304  * Hence two functions, the public front-end call the inner ones
       
  4305  * The argument "recursive" normally indicates a recursive copy
       
  4306  * of the node with values 0 (no) and 1 (yes).  For XInclude,
       
  4307  * however, we allow a value of 2 to indicate copy properties and
       
  4308  * namespace info, but don't recurse on children.
       
  4309  *
       
  4310  * OOM: possible --> OOM flag is set when returns NULL for node!=NULL
       
  4311  */
       
  4312 //static  // NOTE: XE: Moved to exports -- declared in tree.h now
       
  4313 XMLPUBFUNEXPORT xmlNodePtr
       
  4314 xmlStaticCopyNode(const xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent, int extended)
       
  4315 {
       
  4316     xmlNodePtr ret;
       
  4317     LOAD_GS_SAFE_DOC(doc)
       
  4318 
       
  4319     if (node == NULL)
       
  4320         return(NULL);
       
  4321 
       
  4322     switch (node->type) {
       
  4323         case XML_ATTRIBUTE_NODE:
       
  4324             return((xmlNodePtr) xmlCopyProp(parent, (xmlAttrPtr) node));
       
  4325         case XML_NAMESPACE_DECL:
       
  4326             return((xmlNodePtr) xmlCopyNamespaceList((xmlNsPtr) node));
       
  4327         case XML_DOCUMENT_NODE:
       
  4328         case XML_HTML_DOCUMENT_NODE:
       
  4329 #ifdef LIBXML_DOCB_ENABLED
       
  4330         case XML_DOCB_DOCUMENT_NODE:
       
  4331 #endif
       
  4332 #ifdef LIBXML_TREE_ENABLED
       
  4333             return((xmlNodePtr) xmlCopyDoc((xmlDocPtr) node, extended));
       
  4334 #else
       
  4335             /* NOTE:  FALLTHROUGH */
       
  4336 #endif /* LIBXML_TREE_ENABLED */
       
  4337 
       
  4338         case XML_DOCUMENT_TYPE_NODE:
       
  4339         case XML_NOTATION_NODE:
       
  4340         case XML_DTD_NODE:
       
  4341         case XML_ELEMENT_DECL:
       
  4342         case XML_ATTRIBUTE_DECL:
       
  4343         case XML_ENTITY_DECL:
       
  4344             return(NULL); 
       
  4345         default:    ;
       
  4346         /* DONE: 
       
  4347         case XML_TEXT_NODE:
       
  4348         case XML_CDATA_SECTION_NODE:
       
  4349         case XML_ELEMENT_NODE:
       
  4350         case XML_DOCUMENT_FRAG_NODE:
       
  4351         case XML_ENTITY_REF_NODE:
       
  4352         case XML_ENTITY_NODE:
       
  4353         case XML_PI_NODE:
       
  4354         case XML_COMMENT_NODE:
       
  4355         case XML_XINCLUDE_START:
       
  4356         case XML_XINCLUDE_END:
       
  4357             break;
       
  4358         */
       
  4359     }
       
  4360 
       
  4361     /*
       
  4362      * Allocate a new node and fill the fields.
       
  4363      */
       
  4364     ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
       
  4365     if (ret == NULL) {
       
  4366         xmlTreeErrMemory(EMBED_ERRTXT("copying node"));
       
  4367         return(NULL);
       
  4368     }
       
  4369     memset(ret, 0, sizeof(xmlNode));
       
  4370     ret->type = node->type;
       
  4371 
       
  4372     ret->doc = doc;
       
  4373     ret->parent = parent;
       
  4374     if (node->name == xmlStringText)
       
  4375         ret->name = xmlStringText;
       
  4376     else if (node->name == xmlStringTextNoenc)
       
  4377         ret->name = xmlStringTextNoenc;
       
  4378     else if (node->name == xmlStringComment)
       
  4379         ret->name = xmlStringComment;
       
  4380     else if (node->name != NULL)
       
  4381     {
       
  4382         ret->name = xmlStrdup(node->name);
       
  4383         if(! ret->name)
       
  4384             goto OOM;
       
  4385     }
       
  4386 
       
  4387     if ((node->type != XML_ELEMENT_NODE) &&
       
  4388         (node->content != NULL) &&
       
  4389         (node->type != XML_ENTITY_REF_NODE) &&
       
  4390         (node->type != XML_XINCLUDE_END) &&
       
  4391         (node->type != XML_XINCLUDE_START))
       
  4392     {
       
  4393     	if (IS_DATA_NODE(node))
       
  4394     		{
       
  4395 		   	xmlAppendDataList(ret, ret->doc);
       
  4396 		    if(OOM_FLAG)
       
  4397 		    	goto OOM;
       
  4398 			ret->psvi = node->psvi;
       
  4399 	   		if (TEXT_IS_BINARY(node)){
       
  4400 		        ret->content = xmlStrndup(node->content, (int)node->properties);
       
  4401 		        if(! ret->content)
       
  4402 		            goto OOM;
       
  4403 	   		}
       
  4404 		   	else{
       
  4405 		   		ret->content = node->content;			
       
  4406 		   		}
       
  4407     		}
       
  4408    		else{
       
  4409 	        ret->content = xmlStrdup(node->content);
       
  4410 	        if(node->content && !ret->content)
       
  4411 	            goto OOM;   			
       
  4412    		}
       
  4413     }
       
  4414 #ifdef LIBXML_ENABLE_NODE_LINEINFO
       
  4415     else{
       
  4416       if (node->type == XML_ELEMENT_NODE)
       
  4417         ret->line = node->line;
       
  4418     }
       
  4419 #endif
       
  4420 
       
  4421     if (parent != NULL) {
       
  4422         xmlNodePtr tmp;
       
  4423 
       
  4424         /*
       
  4425          * this is a tricky part for the node register thing:
       
  4426          * in case ret does get coalesced in xmlAddChild
       
  4427          * the deregister-node callback is called; so we register ret now already
       
  4428          */
       
  4429         if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
       
  4430         {
       
  4431             
       
  4432             xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
       
  4433         }
       
  4434 
       
  4435         tmp = xmlAddChild(parent, ret);
       
  4436         if(OOM_FLAG)
       
  4437             goto OOM;
       
  4438         /* node could have coalesced */
       
  4439         if (tmp != ret)
       
  4440             return(tmp);
       
  4441     }
       
  4442 
       
  4443     if (!extended)
       
  4444         goto out;
       
  4445     if (node->nsDef != NULL){
       
  4446     	if (node->type == XML_TEXT_NODE){
       
  4447     		ret->nsDef = node->nsDef;
       
  4448     		}
       
  4449     	else{
       
  4450 	        ret->nsDef = xmlCopyNamespaceList(node->nsDef);
       
  4451 	        if(! ret->nsDef)
       
  4452 	            goto OOM;     		
       
  4453     		}
       
  4454     }
       
  4455     if (node->ns != NULL) {
       
  4456     	if (node->type == XML_TEXT_NODE){
       
  4457     		ret->ns = (xmlNs*)xmlStrdup((const unsigned char *)node->ns);
       
  4458     		}
       
  4459     	else{
       
  4460     		xmlNsPtr ns;
       
  4461 	        ns = xmlSearchNs(doc, ret, node->ns->prefix);
       
  4462 	        if (ns == NULL) {
       
  4463 	            /*
       
  4464 	             * Humm, we are copying an element whose namespace is defined
       
  4465 	             * out of the new tree scope. Search it in the original tree
       
  4466 	             * and add it at the top of the new tree
       
  4467 	             */
       
  4468 	            ns = xmlSearchNs(node->doc, node, node->ns->prefix);
       
  4469 	            if (ns != NULL) {
       
  4470 	                xmlNodePtr root = ret;
       
  4471 
       
  4472 	                while (root->parent != NULL)
       
  4473 	                    root = root->parent;
       
  4474 	                ret->ns = xmlNewNs(root, ns->href, ns->prefix);
       
  4475 	            }
       
  4476 	        } else {
       
  4477 	            /*
       
  4478 	             * reference the existing namespace definition in our own tree.
       
  4479 	             */
       
  4480 	            ret->ns = ns;
       
  4481 	        }
       
  4482 	        if(OOM_FLAG)
       
  4483 	            goto OOM;
       
  4484     	}
       
  4485     }
       
  4486     if (node->properties != NULL){
       
  4487     	if(node->type == XML_TEXT_NODE) {
       
  4488     		ret->properties = node->properties;
       
  4489     	}
       
  4490     	else {
       
  4491     		ret->properties = xmlCopyPropList(ret, node->properties);	
       
  4492     	}
       
  4493         if(! ret->properties)
       
  4494             goto OOM;
       
  4495     }
       
  4496     if (node->type == XML_ENTITY_REF_NODE) {
       
  4497         if ((doc == NULL) || (node->doc != doc)) {
       
  4498             /*
       
  4499              * The copied node will go into a separate document, so
       
  4500              * to avoid dangling references to the ENTITY_DECL node
       
  4501              * we cannot keep the reference. Try to find it in the
       
  4502              * target document.
       
  4503              */
       
  4504             ret->children = (xmlNodePtr) xmlGetDocEntity(doc, ret->name);
       
  4505         } else {
       
  4506             ret->children = node->children;
       
  4507         }
       
  4508         ret->last = ret->children;
       
  4509     } else if ((node->children != NULL) && (extended != 2)) {
       
  4510         ret->children = xmlStaticCopyNodeList(node->children, doc, ret);
       
  4511         if(! ret->children)
       
  4512             goto OOM;
       
  4513 
       
  4514         UPDATE_LAST_CHILD_AND_PARENT(ret)
       
  4515     }
       
  4516 
       
  4517 out:
       
  4518     /* if parent != NULL we already registered the node above */
       
  4519     if (parent == NULL && xmlRegisterNodeDefaultValue){
       
  4520         
       
  4521         xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
       
  4522     }
       
  4523     return(ret);
       
  4524 //-------------------------
       
  4525 OOM:
       
  4526     xmlFreeNode(ret);
       
  4527     return NULL;
       
  4528 }
       
  4529 
       
  4530 //static // NOTE: XE: Moved to exports -- declared in tree.h now
       
  4531 /**
       
  4532     Internal routine for copying nodes lists
       
  4533 
       
  4534     OOM: possible --> sets OOM flag, returns NULL for node!=NULL
       
  4535 */
       
  4536 XMLPUBFUNEXPORT xmlNodePtr
       
  4537 xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
       
  4538     xmlNodePtr ret = NULL;
       
  4539     xmlNodePtr p = NULL,q;
       
  4540 	LOAD_GS_SAFE_DOC(doc)
       
  4541 	
       
  4542     while (node != NULL) {
       
  4543 #ifdef LIBXML_TREE_ENABLED
       
  4544         if (node->type == XML_DTD_NODE ) {
       
  4545             if (doc == NULL) {
       
  4546                 node = node->next;
       
  4547                 continue;
       
  4548             }
       
  4549             if (doc->intSubset == NULL) {
       
  4550                 q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
       
  4551                 if(!q)
       
  4552                     goto OOM;
       
  4553                 q->doc = doc;
       
  4554                 q->parent = parent;
       
  4555                 doc->intSubset = (xmlDtdPtr) q;
       
  4556                 xmlAddChild(parent, q);
       
  4557                 if(OOM_FLAG)
       
  4558                     goto OOM_q;
       
  4559             } else {
       
  4560                 q = (xmlNodePtr) doc->intSubset;
       
  4561                 xmlAddChild(parent, q);
       
  4562                 if(OOM_FLAG)
       
  4563                     goto OOM;
       
  4564             }
       
  4565         } else
       
  4566 #endif /* LIBXML_TREE_ENABLED */
       
  4567         {
       
  4568             q = xmlStaticCopyNode(node, doc, parent, 1);
       
  4569             if(OOM_FLAG)
       
  4570                 goto OOM;
       
  4571         }
       
  4572         if (ret == NULL) {
       
  4573             q->prev = NULL;
       
  4574             ret = p = q;
       
  4575         } else if (p != q) {
       
  4576             /* the test is required if xmlStaticCopyNode coalesced 2 text nodes */
       
  4577             p->next = q;
       
  4578             q->prev = p;
       
  4579             p = q;
       
  4580         }
       
  4581         node = node->next;
       
  4582     }
       
  4583     return(ret);
       
  4584 OOM_q:
       
  4585     doc->intSubset = NULL; // was q
       
  4586     xmlFreeDtd((xmlDtdPtr)q);
       
  4587 OOM:
       
  4588     xmlFreeNodeList(ret);
       
  4589     return NULL;
       
  4590 }
       
  4591 
       
  4592 /**
       
  4593  * xmlCopyNode:
       
  4594  * @param node the node
       
  4595  * @param extended if 1 do a recursive copy (properties, namespaces and children
       
  4596  *          when applicable)
       
  4597  *      if 2 copy properties and namespaces (when applicable)
       
  4598  *
       
  4599  * Do a copy of the node.
       
  4600  *
       
  4601  * Returns: a new #xmlNodePtr, or NULL in case of error.
       
  4602  *
       
  4603  * OOM: possible --> OOM flag should be checked
       
  4604  */
       
  4605 XMLPUBFUNEXPORT xmlNodePtr
       
  4606 xmlCopyNode(const xmlNodePtr node, int extended) {
       
  4607     xmlNodePtr ret;
       
  4608 
       
  4609     ret = xmlStaticCopyNode(node, NULL, NULL, extended);
       
  4610     return(ret);
       
  4611 }
       
  4612 
       
  4613 /**
       
  4614  * xmlDocCopyNode:
       
  4615  * @param node the node
       
  4616  * @param doc the document
       
  4617  * @param extended if 1 - do a recursive copy (properties, namespaces and children
       
  4618  *          when applicable)
       
  4619  *      if 2 - copy properties and namespaces (when applicable)
       
  4620  *
       
  4621  * Do a copy of the node to a given document.
       
  4622  *
       
  4623  * Returns: a new #xmlNodePtr, or NULL in case of error.
       
  4624  *
       
  4625  * OOM: possible --> OOM flag should be checked
       
  4626  */
       
  4627 XMLPUBFUNEXPORT xmlNodePtr
       
  4628 xmlDocCopyNode(const xmlNodePtr node, xmlDocPtr doc, int extended) {
       
  4629     xmlNodePtr ret;
       
  4630 
       
  4631     ret = xmlStaticCopyNode(node, doc, NULL, extended);
       
  4632     return(ret);
       
  4633 }
       
  4634 
       
  4635 /**
       
  4636  * xmlCopyNodeList:
       
  4637  * @param node the first node in the list.
       
  4638  *
       
  4639  * Do a recursive copy of the node list.
       
  4640  *
       
  4641  * Returns: a new #xmlNodePtr, or NULL in case of error.
       
  4642  */
       
  4643 XMLPUBFUNEXPORT xmlNodePtr xmlCopyNodeList(const xmlNodePtr node) {
       
  4644     xmlNodePtr ret = xmlStaticCopyNodeList(node, NULL, NULL);
       
  4645     return(ret);
       
  4646 }
       
  4647 
       
  4648 
       
  4649 #if defined(LIBXML_TREE_ENABLED)
       
  4650 /**
       
  4651  * xmlCopyDtd:
       
  4652  * @param dtd the dtd
       
  4653  *
       
  4654  * Do a copy of the dtd.
       
  4655  *
       
  4656  * Returns: a new #xmlDtdPtr, or NULL in case of error.
       
  4657  *
       
  4658  * OOM: possible --> OOM flag is set when returns NULL
       
  4659  */
       
  4660 XMLPUBFUNEXPORT xmlDtdPtr
       
  4661 xmlCopyDtd(xmlDtdPtr dtd) {
       
  4662     xmlDtdPtr ret;
       
  4663     xmlNodePtr cur, p = NULL, q;
       
  4664     LOAD_GS_SAFE_DTD(dtd)
       
  4665 
       
  4666     if (dtd == NULL)
       
  4667         return(NULL);
       
  4668 
       
  4669     ret = xmlNewDtd(NULL, dtd->name, dtd->ExternalID, dtd->SystemID); // may set OOM flag
       
  4670 
       
  4671     if (ret == NULL)
       
  4672         return(NULL);
       
  4673 
       
  4674     if (dtd->entities != NULL){
       
  4675         ret->entities = (void*) xmlCopyEntitiesTable((xmlEntitiesTablePtr) dtd->entities);
       
  4676         if(OOM_FLAG) goto oom;
       
  4677     }
       
  4678     if (dtd->notations != NULL){
       
  4679         ret->notations = (void*) xmlCopyNotationTable((xmlNotationTablePtr) dtd->notations);
       
  4680         if(OOM_FLAG) goto oom;
       
  4681     }
       
  4682     if (dtd->elements != NULL){
       
  4683         ret->elements = (void*) xmlCopyElementTable((xmlElementTablePtr) dtd->elements);
       
  4684         if(OOM_FLAG) goto oom;
       
  4685     }
       
  4686     if (dtd->attributes != NULL){
       
  4687         ret->attributes = (void*) xmlCopyAttributeTable((xmlAttributeTablePtr) dtd->attributes);
       
  4688         if(OOM_FLAG) goto oom;
       
  4689     }
       
  4690     if (dtd->pentities != NULL){
       
  4691         ret->pentities = (void*) xmlCopyEntitiesTable((xmlEntitiesTablePtr) dtd->pentities);
       
  4692         if(OOM_FLAG) goto oom;
       
  4693     }
       
  4694 
       
  4695     cur = dtd->children;
       
  4696     while (cur != NULL) {
       
  4697         q = NULL;
       
  4698 
       
  4699         if (cur->type == XML_ENTITY_DECL) {
       
  4700             xmlEntityPtr tmp = (xmlEntityPtr) cur;
       
  4701             switch (tmp->etype) {
       
  4702             case XML_INTERNAL_GENERAL_ENTITY:
       
  4703             case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
       
  4704             case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
       
  4705                 q = (xmlNodePtr) xmlGetEntityFromDtd(ret, tmp->name);
       
  4706                 break;
       
  4707             case XML_INTERNAL_PARAMETER_ENTITY:
       
  4708             case XML_EXTERNAL_PARAMETER_ENTITY:
       
  4709                 q = (xmlNodePtr)
       
  4710                 xmlGetParameterEntityFromDtd(ret, tmp->name);
       
  4711                 break;
       
  4712             case XML_INTERNAL_PREDEFINED_ENTITY:
       
  4713                 break;
       
  4714             //default:
       
  4715             //    break; // SHOULD NOT HAPPEN
       
  4716             }
       
  4717         } else if (cur->type == XML_ELEMENT_DECL) {
       
  4718             xmlElementPtr tmp = (xmlElementPtr) cur;
       
  4719             q = (xmlNodePtr)
       
  4720             xmlGetDtdQElementDesc(ret, tmp->name, tmp->prefix);
       
  4721         } else if (cur->type == XML_ATTRIBUTE_DECL) {
       
  4722             xmlAttributePtr tmp = (xmlAttributePtr) cur;
       
  4723             q = (xmlNodePtr)
       
  4724             xmlGetDtdQAttrDesc(ret, tmp->elem, tmp->name, tmp->prefix);
       
  4725         } else if (cur->type == XML_COMMENT_NODE) {
       
  4726             q = xmlCopyNode(cur, 0);
       
  4727         }
       
  4728 
       
  4729         if (q == NULL) {
       
  4730             cur = cur->next;
       
  4731             continue;
       
  4732         }
       
  4733 
       
  4734         if (p == NULL)
       
  4735             ret->children = q;
       
  4736         else
       
  4737                 p->next = q;
       
  4738 
       
  4739             q->prev = p;
       
  4740             q->parent = (xmlNodePtr) ret;
       
  4741         q->next = NULL;
       
  4742         ret->last = q;
       
  4743             p = q;
       
  4744         cur = cur->next;
       
  4745     }
       
  4746 
       
  4747     return(ret);
       
  4748 // -------------------
       
  4749 oom:
       
  4750     xmlFreeDtd(ret);
       
  4751     return NULL;
       
  4752 }
       
  4753 #endif
       
  4754 
       
  4755 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
       
  4756 /**
       
  4757  * xmlCopyDoc:
       
  4758  * @param doc the document
       
  4759  * @param recursive if not zero do a recursive copy.
       
  4760  *
       
  4761  * Do a copy of the document info. If recursive, the content tree will
       
  4762  * be copied too as well as DTD, namespaces and entities.
       
  4763  *
       
  4764  * Returns: a new #xmlDocPtr, or NULL in case of error.
       
  4765  *
       
  4766  * OOM: possible --> returns NULL, OOM flag is set
       
  4767  */
       
  4768 XMLPUBFUNEXPORT xmlDocPtr
       
  4769 xmlCopyDoc(xmlDocPtr doc, int recursive) {
       
  4770     xmlDocPtr ret;
       
  4771     LOAD_GS_SAFE_DOC(doc)
       
  4772 
       
  4773     if (doc == NULL)
       
  4774         return(NULL);
       
  4775 
       
  4776     ret = xmlNewDoc(doc->version); // may set OOM flag
       
  4777 	
       
  4778     if (ret == NULL)
       
  4779         return(NULL); // OOM!
       
  4780     if (doc->name != NULL){
       
  4781         ret->name = xmlMemStrdup(doc->name); // may set OOM flag
       
  4782         if(! ret->name)
       
  4783             goto OOM;
       
  4784     }
       
  4785     if (doc->encoding != NULL){
       
  4786         ret->encoding = xmlStrdup(doc->encoding);
       
  4787         if(! ret->encoding)
       
  4788             goto OOM;
       
  4789     }
       
  4790     ret->charset = doc->charset;
       
  4791     ret->compression = doc->compression;
       
  4792     ret->standalone = doc->standalone;
       
  4793 
       
  4794     if (!recursive)
       
  4795         return(ret);
       
  4796 
       
  4797     ret->last = NULL;
       
  4798     ret->children = NULL;
       
  4799 #ifdef LIBXML_TREE_ENABLED
       
  4800     if (doc->intSubset != NULL) {
       
  4801         ret->intSubset = xmlCopyDtd(doc->intSubset);
       
  4802         if(! ret->intSubset)
       
  4803             goto OOM;
       
  4804         xmlSetTreeDoc((xmlNodePtr)ret->intSubset, ret);
       
  4805         ret->intSubset->parent = ret;
       
  4806     }
       
  4807 #endif
       
  4808     if (doc->oldNs != NULL){
       
  4809         ret->oldNs = xmlCopyNamespaceList(doc->oldNs);
       
  4810         if(OOM_FLAG)
       
  4811             goto OOM;
       
  4812     }
       
  4813     if (doc->children != NULL) {
       
  4814         xmlNodePtr tmp;
       
  4815 
       
  4816         ret->children = xmlStaticCopyNodeList(doc->children, ret, (xmlNodePtr)ret);
       
  4817         if(! ret->children)
       
  4818             goto OOM;
       
  4819 
       
  4820         ret->last = NULL;
       
  4821         tmp = ret->children;
       
  4822         while (tmp != NULL) {
       
  4823             if (tmp->next == NULL)
       
  4824                 ret->last = tmp;
       
  4825             tmp = tmp->next;
       
  4826         }
       
  4827     }   
       
  4828     return(ret);
       
  4829 OOM:
       
  4830     xmlFreeDoc(ret);
       
  4831     return NULL;
       
  4832 }
       
  4833 #endif /* LIBXML_TREE_ENABLED */
       
  4834 
       
  4835 /************************************************************************
       
  4836  *                                                                      *
       
  4837  *      Content access functions                                        *
       
  4838  *                                                                      *
       
  4839  ************************************************************************/
       
  4840 
       
  4841 #ifdef LIBXML_ENABLE_NODE_LINEINFO
       
  4842 /**
       
  4843  * xmlGetLineNo:
       
  4844  * @param node valid node
       
  4845  *
       
  4846  * Get line number of node. This requires activation of this option
       
  4847  * before invoking the parser by calling xmlLineNumbersDefault(1)
       
  4848  *
       
  4849  * Returns the line number if successful, -1 otherwise
       
  4850  */
       
  4851 long
       
  4852 xmlGetLineNo(xmlNodePtr node)
       
  4853 {
       
  4854     long result = -1;
       
  4855 
       
  4856     if (!node)
       
  4857         return result;
       
  4858     if (node->type == XML_ELEMENT_NODE)
       
  4859         result = (long) node->line;
       
  4860     else if ((node->prev != NULL) &&
       
  4861              ((node->prev->type == XML_ELEMENT_NODE) ||
       
  4862           (node->prev->type == XML_TEXT_NODE)))
       
  4863         result = xmlGetLineNo(node->prev);
       
  4864     else if ((node->parent != NULL) &&
       
  4865              ((node->parent->type == XML_ELEMENT_NODE) ||
       
  4866               (node->parent->type == XML_TEXT_NODE)))
       
  4867         result = xmlGetLineNo(node->parent);
       
  4868 
       
  4869     return result;
       
  4870 }
       
  4871 #endif  // LIBXML_ENABLE_NODE_LINEINFO
       
  4872 
       
  4873 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
       
  4874 
       
  4875 #ifndef XMLENGINE_EXCLUDE_UNUSED
       
  4876 /**
       
  4877  * xmlGetNodePath:
       
  4878  * @param node a node
       
  4879  *
       
  4880  * Build a structure based Path for the given node
       
  4881  *
       
  4882  * Returns the new path or NULL in case of error. The caller must free
       
  4883  *     the returned string
       
  4884  */
       
  4885 xmlChar *
       
  4886 xmlGetNodePath(xmlNodePtr node)
       
  4887 {
       
  4888     xmlNodePtr cur, tmp, next;
       
  4889     xmlChar *buffer = NULL, *temp;
       
  4890     size_t buf_len;
       
  4891     xmlChar *buf;
       
  4892     const char *sep;
       
  4893     const char *name;
       
  4894     char nametemp[100];
       
  4895     int occur = 0;
       
  4896 
       
  4897     if (node == NULL)
       
  4898         return (NULL);
       
  4899 
       
  4900     buf_len = 500;
       
  4901     buffer = (xmlChar *) xmlMallocAtomic(buf_len * sizeof(xmlChar));
       
  4902     if (buffer == NULL) {
       
  4903         xmlTreeErrMemory(EMBED_ERRTXT("getting node path"));
       
  4904         return (NULL);
       
  4905     }
       
  4906     buf = (xmlChar *) xmlMallocAtomic(buf_len * sizeof(xmlChar));
       
  4907     if (buf == NULL) {
       
  4908         xmlTreeErrMemory(EMBED_ERRTXT("getting node path"));
       
  4909         xmlFree(buffer);
       
  4910         return (NULL);
       
  4911     }
       
  4912 
       
  4913     buffer[0] = 0;
       
  4914     cur = node;
       
  4915     do {
       
  4916         name = "";
       
  4917         sep = "?";
       
  4918         occur = 0;
       
  4919         if ((cur->type == XML_DOCUMENT_NODE) ||
       
  4920             (cur->type == XML_HTML_DOCUMENT_NODE)) {
       
  4921             if (buffer[0] == '/')
       
  4922                 break;
       
  4923             sep = "/";
       
  4924             next = NULL;
       
  4925         } else if (cur->type == XML_ELEMENT_NODE) {
       
  4926             sep = "/";
       
  4927             name = (const char *) cur->name;
       
  4928             if (cur->ns) {
       
  4929             if (cur->ns->prefix != NULL)
       
  4930                     snprintf(nametemp, sizeof(nametemp) - 1,
       
  4931                          EMBED_ERRTXT("%s:%s"), cur->ns->prefix, cur->name);
       
  4932         else
       
  4933             snprintf(nametemp, sizeof(nametemp) - 1,
       
  4934                  EMBED_ERRTXT("%s"), cur->name);
       
  4935                 nametemp[sizeof(nametemp) - 1] = 0;
       
  4936                 name = nametemp;
       
  4937             }
       
  4938             next = cur->parent;
       
  4939 
       
  4940             /*
       
  4941              * Thumbler index computation
       
  4942              * 
       
  4943              */
       
  4944             tmp = cur->prev;
       
  4945             while (tmp != NULL) {
       
  4946                 if ((tmp->type == XML_ELEMENT_NODE) &&
       
  4947                     (xmlStrEqual(cur->name, tmp->name)))
       
  4948                     occur++;
       
  4949                 tmp = tmp->prev;
       
  4950             }
       
  4951             if (occur == 0) {
       
  4952                 tmp = cur->next;
       
  4953                 while (tmp != NULL && occur == 0) {
       
  4954                     if ((tmp->type == XML_ELEMENT_NODE) &&
       
  4955                         (xmlStrEqual(cur->name, tmp->name)))
       
  4956                         occur++;
       
  4957                     tmp = tmp->next;
       
  4958                 }
       
  4959                 if (occur != 0)
       
  4960                     occur = 1;
       
  4961             } else
       
  4962                 occur++;
       
  4963         } else if (cur->type == XML_COMMENT_NODE) {
       
  4964             sep = "/";
       
  4965             name = "comment()";
       
  4966             next = cur->parent;
       
  4967 
       
  4968             /*
       
  4969              * Thumbler index computation
       
  4970              */
       
  4971             tmp = cur->prev;
       
  4972             while (tmp != NULL) {
       
  4973                 if (tmp->type == XML_COMMENT_NODE)
       
  4974             occur++;
       
  4975                 tmp = tmp->prev;
       
  4976             }
       
  4977             if (occur == 0) {
       
  4978                 tmp = cur->next;
       
  4979                 while (tmp != NULL && occur == 0) {
       
  4980           if (tmp->type == XML_COMMENT_NODE)
       
  4981             occur++;
       
  4982                     tmp = tmp->next;
       
  4983                 }
       
  4984                 if (occur != 0)
       
  4985                     occur = 1;
       
  4986             } else
       
  4987                 occur++;
       
  4988         } else if ((cur->type == XML_TEXT_NODE) ||
       
  4989                    (cur->type == XML_CDATA_SECTION_NODE)) {
       
  4990             sep = "/";
       
  4991         name = "text()";
       
  4992             next = cur->parent;
       
  4993 
       
  4994             /*
       
  4995              * Thumbler index computation
       
  4996              */
       
  4997             tmp = cur->prev;
       
  4998             while (tmp != NULL) {
       
  4999                 if ((cur->type == XML_TEXT_NODE) ||
       
  5000             (cur->type == XML_CDATA_SECTION_NODE))
       
  5001             occur++;
       
  5002                 tmp = tmp->prev;
       
  5003             }
       
  5004             if (occur == 0) {
       
  5005                 tmp = cur->next;
       
  5006                 while (tmp != NULL && occur == 0) {
       
  5007           if ((cur->type == XML_TEXT_NODE) ||
       
  5008               (cur->type == XML_CDATA_SECTION_NODE))
       
  5009             occur++;
       
  5010                     tmp = tmp->next;
       
  5011                 }
       
  5012                 if (occur != 0)
       
  5013                     occur = 1;
       
  5014             } else
       
  5015                 occur++;
       
  5016         } else if (cur->type == XML_PI_NODE) {
       
  5017             sep = "/";
       
  5018         snprintf(nametemp, sizeof(nametemp) - 1,
       
  5019              EMBED_ERRTXT("processing-instruction('%s')"), cur->name);
       
  5020             nametemp[sizeof(nametemp) - 1] = 0;
       
  5021             name = nametemp;
       
  5022 
       
  5023         next = cur->parent;
       
  5024 
       
  5025             /*
       
  5026              * Thumbler index computation
       
  5027              */
       
  5028             tmp = cur->prev;
       
  5029             while (tmp != NULL) {
       
  5030                 if ((tmp->type == XML_PI_NODE) &&
       
  5031             (xmlStrEqual(cur->name, tmp->name)))
       
  5032                     occur++;
       
  5033                 tmp = tmp->prev;
       
  5034             }
       
  5035             if (occur == 0) {
       
  5036                 tmp = cur->next;
       
  5037                 while (tmp != NULL && occur == 0) {
       
  5038                     if ((tmp->type == XML_PI_NODE) &&
       
  5039             (xmlStrEqual(cur->name, tmp->name)))
       
  5040                         occur++;
       
  5041                     tmp = tmp->next;
       
  5042                 }
       
  5043                 if (occur != 0)
       
  5044                     occur = 1;
       
  5045             } else
       
  5046                 occur++;
       
  5047 
       
  5048         } else if (cur->type == XML_ATTRIBUTE_NODE) {
       
  5049             sep = "/@";
       
  5050             name = (const char *) (((xmlAttrPtr) cur)->name);
       
  5051             next = ((xmlAttrPtr) cur)->parent;
       
  5052         } else {
       
  5053             next = cur->parent;
       
  5054         }
       
  5055 
       
  5056         /*
       
  5057          * Make sure there is enough room
       
  5058          */
       
  5059         if (xmlStrlen(buffer) + sizeof(nametemp) + 20 > buf_len) {
       
  5060             buf_len =
       
  5061                 2 * buf_len + xmlStrlen(buffer) + sizeof(nametemp) + 20;
       
  5062             temp = (xmlChar *) xmlRealloc(buffer, buf_len);
       
  5063             if (temp == NULL) {
       
  5064         xmlTreeErrMemory(EMBED_ERRTXT("getting node path"));
       
  5065                 xmlFree(buf);
       
  5066                 xmlFree(buffer);
       
  5067                 return (NULL);
       
  5068             }
       
  5069             buffer = temp;
       
  5070             temp = (xmlChar *) xmlRealloc(buf, buf_len);
       
  5071             if (temp == NULL) {
       
  5072         xmlTreeErrMemory(EMBED_ERRTXT("getting node path"));
       
  5073                 xmlFree(buf);
       
  5074                 xmlFree(buffer);
       
  5075                 return (NULL);
       
  5076             }
       
  5077             buf = temp;
       
  5078         }
       
  5079         if (occur == 0)
       
  5080             snprintf((char *) buf, buf_len, EMBED_ERRTXT("%s%s%s"),
       
  5081                      sep, name, (char *) buffer);
       
  5082         else
       
  5083             snprintf((char *) buf, buf_len, EMBED_ERRTXT("%s%s[%d]%s"),
       
  5084                      sep, name, occur, (char *) buffer);
       
  5085         snprintf((char *) buffer, buf_len, EMBED_ERRTXT("%s"), buf);
       
  5086         cur = next;
       
  5087     } while (cur != NULL);
       
  5088     xmlFree(buf);
       
  5089     return (buffer);
       
  5090 }
       
  5091 #endif /* ifndef XMLENGINE_EXCLUDE_UNUSED */
       
  5092 
       
  5093 #endif /* LIBXML_TREE_ENABLED */
       
  5094 
       
  5095 /**
       
  5096  * xmlDocGetRootElement:
       
  5097  * @param doc the document
       
  5098  *
       
  5099  * Get the root element of the document (doc->children is a list
       
  5100  * containing possibly comments, PIs, etc ...).
       
  5101  *
       
  5102  * Returns the #xmlNodePtr for the root or NULL
       
  5103  */
       
  5104 XMLPUBFUNEXPORT xmlNodePtr
       
  5105 xmlDocGetRootElement(xmlDocPtr doc)
       
  5106 {
       
  5107     xmlNodePtr ret;
       
  5108 
       
  5109     if (doc == NULL) return(NULL);
       
  5110     ret = doc->children;
       
  5111     while (ret != NULL)
       
  5112     {
       
  5113         if (ret->type == XML_ELEMENT_NODE)
       
  5114             return(ret);
       
  5115         ret = ret->next;
       
  5116     }
       
  5117     return(ret);
       
  5118 }
       
  5119 
       
  5120 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
       
  5121 /**
       
  5122  * xmlDocSetRootElement:
       
  5123  * @param doc the document
       
  5124  * @param root the new document root element
       
  5125  *
       
  5126  * Set the root element of the document (doc->children is a list
       
  5127  * containing possibly comments, PIs, etc ...).
       
  5128  *
       
  5129  * Returns the old root element if any was found
       
  5130  */
       
  5131 XMLPUBFUNEXPORT xmlNodePtr
       
  5132 xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
       
  5133     xmlNodePtr old = NULL;
       
  5134 
       
  5135     if (doc == NULL) return(NULL);
       
  5136     if (root == NULL)return(NULL);
       
  5137 
       
  5138     xmlUnlinkNode(root);
       
  5139     root->doc = doc;
       
  5140     root->parent = (xmlNodePtr) doc;
       
  5141     old = doc->children;
       
  5142 
       
  5143     while (old != NULL) {
       
  5144         if (old->type == XML_ELEMENT_NODE)
       
  5145             break;
       
  5146         old = old->next;
       
  5147     }
       
  5148 
       
  5149     if (old == NULL) {
       
  5150         if (doc->children == NULL) {
       
  5151             doc->children = root;
       
  5152             doc->last = root;
       
  5153         } else {
       
  5154             xmlAddSibling(doc->children, root);
       
  5155         }
       
  5156     } else {
       
  5157     xmlReplaceNode(old, root);
       
  5158     }
       
  5159     return(old);
       
  5160 }
       
  5161 #endif
       
  5162 
       
  5163 #if defined(LIBXML_TREE_ENABLED)
       
  5164 /**
       
  5165  * xmlNodeSetLang:
       
  5166  * @param cur the node being changed
       
  5167  * @param lang the language description
       
  5168  *
       
  5169  * Set the language of a node, i.e. the values of the xml:lang
       
  5170  * attribute.
       
  5171  */
       
  5172 XMLPUBFUNEXPORT void
       
  5173 xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
       
  5174     xmlNsPtr ns;
       
  5175 
       
  5176     if (cur == NULL) return;
       
  5177     
       
  5178     switch(cur->type) {
       
  5179         case XML_TEXT_NODE:
       
  5180         case XML_CDATA_SECTION_NODE:
       
  5181         case XML_COMMENT_NODE:
       
  5182         case XML_DOCUMENT_NODE:
       
  5183         case XML_DOCUMENT_TYPE_NODE:
       
  5184         case XML_DOCUMENT_FRAG_NODE:
       
  5185         case XML_NOTATION_NODE:
       
  5186         case XML_HTML_DOCUMENT_NODE:
       
  5187         case XML_DTD_NODE:
       
  5188         case XML_ELEMENT_DECL:
       
  5189         case XML_ATTRIBUTE_DECL:
       
  5190         case XML_ENTITY_DECL:
       
  5191         case XML_PI_NODE:
       
  5192         case XML_ENTITY_REF_NODE:
       
  5193         case XML_ENTITY_NODE:
       
  5194         case XML_NAMESPACE_DECL:
       
  5195 #ifdef LIBXML_DOCB_ENABLED
       
  5196         case XML_DOCB_DOCUMENT_NODE:
       
  5197 #endif
       
  5198         case XML_XINCLUDE_START:
       
  5199         case XML_XINCLUDE_END:
       
  5200         return;
       
  5201         case XML_ELEMENT_NODE:
       
  5202         case XML_ATTRIBUTE_NODE:
       
  5203         break;
       
  5204     }
       
  5205     ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
       
  5206     if (ns == NULL)
       
  5207         return;
       
  5208     xmlSetNsProp(cur, ns, BAD_CAST "lang", lang);
       
  5209 }
       
  5210 #endif /* LIBXML_TREE_ENABLED */
       
  5211 
       
  5212 /**
       
  5213  * xmlNodeGetLang:
       
  5214  * @param cur the node being checked
       
  5215  *
       
  5216  * Searches the language of a node, i.e. the values of the xml:lang
       
  5217  * attribute or the one carried by the nearest ancestor.
       
  5218  *
       
  5219  * Returns a pointer to the lang value, or NULL if not found
       
  5220  *     It's up to the caller to free the memory with xmlFree().
       
  5221  */
       
  5222 XMLPUBFUNEXPORT xmlChar *
       
  5223 xmlNodeGetLang(xmlNodePtr cur) {
       
  5224     xmlChar *lang;
       
  5225 
       
  5226     while (cur != NULL) {
       
  5227         lang = xmlGetNsProp(cur, BAD_CAST "lang", XML_XML_NAMESPACE);
       
  5228         if (lang != NULL)
       
  5229             return(lang);
       
  5230         cur = cur->parent;
       
  5231     }
       
  5232     return(NULL);
       
  5233 }
       
  5234 
       
  5235 
       
  5236 #ifdef LIBXML_TREE_ENABLED
       
  5237 /**
       
  5238  * xmlNodeSetSpacePreserve:
       
  5239  * @param cur the node being changed
       
  5240  * @param val the xml:space value ("0": default, 1: "preserve")
       
  5241  *
       
  5242  * Set (or reset) the space preserving behaviour of a node, i.e. the
       
  5243  * value of the xml:space attribute.
       
  5244  */
       
  5245 XMLPUBFUNEXPORT void
       
  5246 xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) {
       
  5247     xmlNsPtr ns;
       
  5248 
       
  5249     if (cur == NULL) return;
       
  5250     switch(cur->type) {
       
  5251         case XML_TEXT_NODE:
       
  5252         case XML_CDATA_SECTION_NODE:
       
  5253         case XML_COMMENT_NODE:
       
  5254         case XML_DOCUMENT_NODE:
       
  5255         case XML_DOCUMENT_TYPE_NODE:
       
  5256         case XML_DOCUMENT_FRAG_NODE:
       
  5257         case XML_NOTATION_NODE:
       
  5258         case XML_HTML_DOCUMENT_NODE:
       
  5259         case XML_DTD_NODE:
       
  5260         case XML_ELEMENT_DECL:
       
  5261         case XML_ATTRIBUTE_DECL:
       
  5262         case XML_ENTITY_DECL:
       
  5263         case XML_PI_NODE:
       
  5264         case XML_ENTITY_REF_NODE:
       
  5265         case XML_ENTITY_NODE:
       
  5266     case XML_NAMESPACE_DECL:
       
  5267     case XML_XINCLUDE_START:
       
  5268     case XML_XINCLUDE_END:
       
  5269 #ifdef LIBXML_DOCB_ENABLED
       
  5270     case XML_DOCB_DOCUMENT_NODE:
       
  5271 #endif
       
  5272         return;
       
  5273         case XML_ELEMENT_NODE:
       
  5274         case XML_ATTRIBUTE_NODE:
       
  5275         break;
       
  5276     }
       
  5277     ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
       
  5278     if (ns == NULL)
       
  5279     return;
       
  5280     switch (val) {
       
  5281     case 0:
       
  5282     xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST "default");
       
  5283     break;
       
  5284     case 1:
       
  5285     xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST "preserve");
       
  5286     break;
       
  5287     }
       
  5288 }
       
  5289 #endif /* LIBXML_TREE_ENABLED */
       
  5290 
       
  5291 /**
       
  5292  * xmlNodeGetSpacePreserve:
       
  5293  * @param cur the node being checked
       
  5294  *
       
  5295  * Searches the space preserving behaviour of a node, i.e. the values
       
  5296  * of the xml:space attribute or the one carried by the nearest
       
  5297  * ancestor.
       
  5298  *
       
  5299  * Returns -1 if xml:space is not inherited, 0 if "default", 1 if "preserve"
       
  5300  */
       
  5301 XMLPUBFUNEXPORT int
       
  5302 xmlNodeGetSpacePreserve(xmlNodePtr cur) {
       
  5303     xmlChar *space;
       
  5304 
       
  5305     while (cur != NULL) {
       
  5306     space = xmlGetNsProp(cur, BAD_CAST "space", XML_XML_NAMESPACE);
       
  5307     if (space != NULL) {
       
  5308         if (xmlStrEqual(space, BAD_CAST "preserve")) {
       
  5309         xmlFree(space);
       
  5310         return(1);
       
  5311         }
       
  5312         if (xmlStrEqual(space, BAD_CAST "default")) {
       
  5313         xmlFree(space);
       
  5314         return(0);
       
  5315         }
       
  5316         xmlFree(space);
       
  5317     }
       
  5318     cur = cur->parent;
       
  5319     }
       
  5320     return(-1);
       
  5321 }
       
  5322 
       
  5323 #ifdef LIBXML_TREE_ENABLED
       
  5324 /**
       
  5325  * xmlNodeSetName:
       
  5326  * @param cur the node being changed
       
  5327  * @param name the new tag name
       
  5328  *
       
  5329  * Set (or reset) the name of a node.
       
  5330  */
       
  5331 XMLPUBFUNEXPORT void
       
  5332 xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
       
  5333     if (cur == NULL) return;
       
  5334     if (name == NULL) return;
       
  5335     switch(cur->type) {
       
  5336         case XML_TEXT_NODE:
       
  5337         case XML_CDATA_SECTION_NODE:
       
  5338         case XML_COMMENT_NODE:
       
  5339         case XML_DOCUMENT_TYPE_NODE:
       
  5340         case XML_DOCUMENT_FRAG_NODE:
       
  5341         case XML_NOTATION_NODE:
       
  5342         case XML_HTML_DOCUMENT_NODE:
       
  5343         case XML_NAMESPACE_DECL:
       
  5344         case XML_XINCLUDE_START:
       
  5345         case XML_XINCLUDE_END:
       
  5346 //#ifdef LIBXML_DOCB_ENABLED
       
  5347 //  case XML_DOCB_DOCUMENT_NODE:
       
  5348 //#endif
       
  5349         return;
       
  5350         case XML_ELEMENT_NODE:
       
  5351         case XML_ATTRIBUTE_NODE:
       
  5352         case XML_PI_NODE:
       
  5353         case XML_ENTITY_REF_NODE:
       
  5354         case XML_ENTITY_NODE:
       
  5355         case XML_DTD_NODE:
       
  5356         case XML_DOCUMENT_NODE:
       
  5357         case XML_ELEMENT_DECL:
       
  5358         case XML_ATTRIBUTE_DECL:
       
  5359         case XML_ENTITY_DECL:
       
  5360         break;
       
  5361     }
       
  5362     if (cur->name != NULL)
       
  5363         xmlFree((xmlChar *) cur->name);
       
  5364     cur->name = xmlStrdup(name);
       
  5365     
       
  5366 }
       
  5367 #endif
       
  5368 
       
  5369 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
       
  5370 /**
       
  5371  * xmlNodeSetBase:
       
  5372  * @param cur the node being changed
       
  5373  * @param uri the new base URI
       
  5374  *
       
  5375  * Set (or reset) the base URI of a node, i.e. the value of the
       
  5376  * xml:base attribute.
       
  5377  */
       
  5378 XMLPUBFUNEXPORT void
       
  5379 xmlNodeSetBase(xmlNodePtr cur, const xmlChar* uri) {
       
  5380     xmlNsPtr ns;
       
  5381 
       
  5382     if (cur == NULL) return;
       
  5383     
       
  5384     switch(cur->type) {
       
  5385         case XML_TEXT_NODE:
       
  5386         case XML_CDATA_SECTION_NODE:
       
  5387         case XML_COMMENT_NODE:
       
  5388         case XML_DOCUMENT_TYPE_NODE:
       
  5389         case XML_DOCUMENT_FRAG_NODE:
       
  5390         case XML_NOTATION_NODE:
       
  5391         case XML_DTD_NODE:
       
  5392         case XML_ELEMENT_DECL:
       
  5393         case XML_ATTRIBUTE_DECL:
       
  5394         case XML_ENTITY_DECL:
       
  5395         case XML_PI_NODE:
       
  5396         case XML_ENTITY_REF_NODE:
       
  5397         case XML_ENTITY_NODE:
       
  5398         case XML_NAMESPACE_DECL:
       
  5399         case XML_XINCLUDE_START:
       
  5400         case XML_XINCLUDE_END:
       
  5401             return;
       
  5402         case XML_ELEMENT_NODE:
       
  5403         case XML_ATTRIBUTE_NODE:
       
  5404             break;
       
  5405         case XML_DOCUMENT_NODE:
       
  5406 //#ifdef LIBXML_DOCB_ENABLED
       
  5407 //  case XML_DOCB_DOCUMENT_NODE:
       
  5408 //#endif
       
  5409         case XML_HTML_DOCUMENT_NODE: {
       
  5410         xmlDocPtr doc = (xmlDocPtr) cur;
       
  5411 
       
  5412         if (doc->URL != NULL)
       
  5413         xmlFree((xmlChar *) doc->URL);
       
  5414         if (uri == NULL)
       
  5415         doc->URL = NULL;
       
  5416         else
       
  5417         doc->URL = xmlStrdup(uri);
       
  5418         return;
       
  5419     }
       
  5420     }
       
  5421 
       
  5422     ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
       
  5423     if (ns == NULL)
       
  5424         return;
       
  5425     xmlSetNsProp(cur, ns, BAD_CAST "base", uri);
       
  5426 }
       
  5427 #endif /* LIBXML_TREE_ENABLED */
       
  5428 
       
  5429 /**
       
  5430  * xmlNodeGetBase:
       
  5431  * @param doc the document the node pertains to
       
  5432  * @param cur the node being checked
       
  5433  *
       
  5434  * Searches for the BASE URL. The code should work on both XML
       
  5435  * and HTML document even if base mechanisms are completely different.
       
  5436  * It returns the base as defined in RFC 2396 sections
       
  5437  * 5.1.1. Base URI within Document Content
       
  5438  * and
       
  5439  * 5.1.2. Base URI from the Encapsulating Entity
       
  5440  * However it does not return the document base (5.1.3), use
       
  5441  * xmlDocumentGetBase() for this
       
  5442  *
       
  5443  * Returns a pointer to the base URL, or NULL if not found
       
  5444  *     It's up to the caller to free the memory with xmlFree().
       
  5445  *
       
  5446  * OOM: possible --> check OOM flag // NOT REVIEWED
       
  5447  */
       
  5448 XMLPUBFUNEXPORT xmlChar *
       
  5449 xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
       
  5450     xmlChar* oldbase = NULL;
       
  5451     xmlChar* base;
       
  5452     xmlChar* newbase;
       
  5453 
       
  5454     if (!cur && !doc)
       
  5455         return(NULL);
       
  5456     if (!doc)
       
  5457         doc = cur->doc;
       
  5458 
       
  5459 #ifdef LIBXML_HTML_ENABLED
       
  5460     if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
       
  5461         cur = doc->children;
       
  5462         while ((cur != NULL) && (cur->name != NULL)) {
       
  5463             if (cur->type != XML_ELEMENT_NODE) {
       
  5464                 cur = cur->next;
       
  5465                 continue;
       
  5466             }
       
  5467             if (!xmlStrcasecmp(cur->name, BAD_CAST "html")) {
       
  5468                 cur = cur->children;
       
  5469                 continue;
       
  5470             }
       
  5471             if (!xmlStrcasecmp(cur->name, BAD_CAST "head")) {
       
  5472                 cur = cur->children;
       
  5473                 continue;
       
  5474             }
       
  5475             if (!xmlStrcasecmp(cur->name, BAD_CAST "base")) {
       
  5476                     return(xmlGetProp(cur, BAD_CAST "href"));
       
  5477             }
       
  5478             cur = cur->next;
       
  5479         }
       
  5480         return(NULL);
       
  5481     }
       
  5482 #endif /* LIBXML_HTML_ENABLED */
       
  5483 
       
  5484     while (cur) {
       
  5485         if (cur->type == XML_ENTITY_DECL) {
       
  5486             xmlEntityPtr ent = (xmlEntityPtr) cur;
       
  5487             return(xmlStrdup(ent->URI));
       
  5488         }
       
  5489         if (cur->type == XML_ELEMENT_NODE) {
       
  5490             base = xmlGetNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
       
  5491             if (base) {
       
  5492                 if (oldbase) {
       
  5493                     newbase = xmlBuildURI(oldbase, base);
       
  5494                     if (newbase) {
       
  5495                         xmlFree(oldbase);
       
  5496                         xmlFree(base);
       
  5497                         oldbase = newbase;
       
  5498                     } else {
       
  5499                         xmlFree(oldbase);
       
  5500                         xmlFree(base);
       
  5501                         return(NULL);
       
  5502                     }
       
  5503                 } else {
       
  5504                     oldbase = base;
       
  5505                 }
       
  5506                 if ((!xmlStrncmp(oldbase, BAD_CAST "http://", 7)) ||
       
  5507                     (!xmlStrncmp(oldbase, BAD_CAST "ftp://", 6)) ||
       
  5508                     (!xmlStrncmp(oldbase, BAD_CAST "urn:", 4)))
       
  5509                     return(oldbase);
       
  5510             }
       
  5511         }
       
  5512         cur = cur->parent;
       
  5513     }
       
  5514     if (doc && doc->URL) {
       
  5515         if (!oldbase)
       
  5516             return(xmlStrdup(doc->URL));
       
  5517         newbase = xmlBuildURI(oldbase, doc->URL);
       
  5518         xmlFree(oldbase);
       
  5519         return(newbase);
       
  5520     }
       
  5521     return(oldbase);
       
  5522 }
       
  5523 
       
  5524 /**
       
  5525  * xmlNodeBufGetContent:
       
  5526  * @param buffer a buffer
       
  5527  * @param cur the node being read
       
  5528  *
       
  5529  * Read the value of a node cur, this can be either the text carried
       
  5530  * directly by this node if it's a TEXT node or the aggregate string
       
  5531  * of the values carried by this node child's (TEXT and ENTITY_REF).
       
  5532  * Entity references are substituted.
       
  5533  * Fills up the buffer buffer with this value
       
  5534  *
       
  5535  * Returns 0 in case of success and -1 in case of error.
       
  5536  *
       
  5537  * OOM: possible / NOT REVIEWED
       
  5538  */
       
  5539 XMLPUBFUNEXPORT int
       
  5540 xmlNodeBufGetContent(xmlBufferPtr buffer, xmlNodePtr cur)
       
  5541 {
       
  5542     if ((cur == NULL) || (buffer == NULL)) return(-1);
       
  5543     switch (cur->type) {
       
  5544         case XML_CDATA_SECTION_NODE:
       
  5545         case XML_TEXT_NODE:
       
  5546             xmlBufferCat(buffer, cur->content);
       
  5547             break;
       
  5548         case XML_DOCUMENT_FRAG_NODE:
       
  5549         case XML_ELEMENT_NODE:{
       
  5550                 xmlNodePtr tmp = cur;
       
  5551 
       
  5552                 while (tmp != NULL) {
       
  5553                     switch (tmp->type) {
       
  5554                         case XML_CDATA_SECTION_NODE:
       
  5555                         case XML_TEXT_NODE:
       
  5556                             if (tmp->content != NULL)
       
  5557                                 xmlBufferCat(buffer, tmp->content);
       
  5558                             break;
       
  5559                         case XML_ENTITY_REF_NODE:
       
  5560                             xmlNodeBufGetContent(buffer, tmp); // was tmp->children
       
  5561                             break;
       
  5562                         default:
       
  5563                             break;
       
  5564                     }
       
  5565                     /*
       
  5566                      * Skip to next node
       
  5567                      */
       
  5568                     if (tmp->children != NULL) {
       
  5569                         if (tmp->children->type != XML_ENTITY_DECL) {
       
  5570                             tmp = tmp->children;
       
  5571                             continue;
       
  5572                         }
       
  5573                     }
       
  5574                     if (tmp == cur)
       
  5575                         break;
       
  5576 
       
  5577                     if (tmp->next != NULL) {
       
  5578                         tmp = tmp->next;
       
  5579                         continue;
       
  5580                     }
       
  5581 
       
  5582                     do {
       
  5583                         tmp = tmp->parent;
       
  5584                         if (tmp == NULL)
       
  5585                             break;
       
  5586                         if (tmp == cur) {
       
  5587                             tmp = NULL;
       
  5588                             break;
       
  5589                         }
       
  5590                         if (tmp->next != NULL) {
       
  5591                             tmp = tmp->next;
       
  5592                             break;
       
  5593                         }
       
  5594                     } while (tmp != NULL);
       
  5595                 }
       
  5596                 break;
       
  5597             }
       
  5598         case XML_ATTRIBUTE_NODE:{
       
  5599                 xmlAttrPtr attr = (xmlAttrPtr) cur;
       
  5600                 xmlNodePtr tmp = attr->children;
       
  5601 
       
  5602                 while (tmp != NULL) {
       
  5603                     if (tmp->type == XML_TEXT_NODE)
       
  5604                         xmlBufferCat(buffer, tmp->content);
       
  5605                     else
       
  5606                         xmlNodeBufGetContent(buffer, tmp);
       
  5607                     tmp = tmp->next;
       
  5608                 }
       
  5609                 break;
       
  5610             }
       
  5611         case XML_COMMENT_NODE:
       
  5612         case XML_PI_NODE:
       
  5613             xmlBufferCat(buffer, cur->content);
       
  5614             break;
       
  5615         case XML_ENTITY_REF_NODE:{
       
  5616                 xmlEntityPtr ent;
       
  5617                 xmlNodePtr tmp;
       
  5618 
       
  5619                 /* lookup entity declaration */
       
  5620                 ent = xmlGetDocEntity(cur->doc, cur->name);
       
  5621                 if (ent == NULL)
       
  5622                     return(-1);
       
  5623 
       
  5624                 /* an entity content can be any "well balanced chunk",
       
  5625                  * i.e. the result of the content [43] production:
       
  5626                  * http://www.w3.org/TR/REC-xml#NT-content
       
  5627                  * -> we iterate through child nodes and recursive call
       
  5628                  * xmlNodeGetContent() which handles all possible node types */
       
  5629                 tmp = ent->children;
       
  5630                 while (tmp) {
       
  5631                     xmlNodeBufGetContent(buffer, tmp);
       
  5632                     tmp = tmp->next;
       
  5633                 }
       
  5634                 break;
       
  5635             }
       
  5636         case XML_ENTITY_NODE:
       
  5637         case XML_DOCUMENT_TYPE_NODE:
       
  5638         case XML_NOTATION_NODE:
       
  5639         case XML_DTD_NODE:
       
  5640         case XML_XINCLUDE_START:
       
  5641         case XML_XINCLUDE_END:
       
  5642             break;
       
  5643         case XML_DOCUMENT_NODE:
       
  5644 #ifdef LIBXML_DOCB_ENABLED
       
  5645         case XML_DOCB_DOCUMENT_NODE:
       
  5646 #endif
       
  5647         case XML_HTML_DOCUMENT_NODE:
       
  5648             cur = cur->children;
       
  5649             while (cur!= NULL) {
       
  5650                 if ((cur->type == XML_ELEMENT_NODE) ||
       
  5651                     (cur->type == XML_TEXT_NODE) ||
       
  5652                     (cur->type == XML_CDATA_SECTION_NODE)) {
       
  5653                     xmlNodeBufGetContent(buffer, cur);
       
  5654                 }
       
  5655                 cur = cur->next;
       
  5656             }
       
  5657             break;
       
  5658         case XML_NAMESPACE_DECL:
       
  5659             xmlBufferCat(buffer, ((xmlNsPtr) cur)->href);
       
  5660             break;
       
  5661         case XML_ELEMENT_DECL:
       
  5662         case XML_ATTRIBUTE_DECL:
       
  5663         case XML_ENTITY_DECL:
       
  5664             break;
       
  5665     }
       
  5666     return(0);
       
  5667 }
       
  5668 /**
       
  5669  * xmlNodeGetContent:
       
  5670  * @param cur the node being read
       
  5671  *
       
  5672  * Read the value of a node, this can be either the text carried
       
  5673  * directly by this node if it's a TEXT node or the aggregate string
       
  5674  * of the values carried by this node child's (TEXT and ENTITY_REF).
       
  5675  * Entity references are substituted.
       
  5676  * Returns a new xmlChar* or NULL if no content is available.
       
  5677  *     It's up to the caller to free the memory with xmlFree().
       
  5678  *
       
  5679  * OOM: possible --> check OOM flag always // NOT REVIEWED COMPLETELY
       
  5680  */
       
  5681 XMLPUBFUNEXPORT xmlChar*
       
  5682 xmlNodeGetContent(xmlNodePtr cur)
       
  5683 {
       
  5684     if (cur == NULL)
       
  5685         return (NULL);
       
  5686     
       
  5687     switch (cur->type) {
       
  5688         case XML_DOCUMENT_FRAG_NODE:
       
  5689         case XML_ELEMENT_NODE:{
       
  5690                 xmlBufferPtr buffer;
       
  5691                 xmlChar *ret;
       
  5692 
       
  5693                 buffer = xmlBufferCreateSize(64);
       
  5694                 if (buffer == NULL)
       
  5695                     return (NULL);
       
  5696                 xmlNodeBufGetContent(buffer, cur);
       
  5697                 
       
  5698                 ret = buffer->content;
       
  5699                 buffer->content = NULL;
       
  5700                 xmlBufferFree(buffer);
       
  5701                 return (ret);
       
  5702             }
       
  5703         case XML_ATTRIBUTE_NODE:
       
  5704                 /* XMLENGINE: was replaced:
       
  5705                 {
       
  5706                 xmlAttrPtr attr = (xmlAttrPtr) cur;
       
  5707                 if (attr->parent != NULL)
       
  5708                     return (xmlNodeListGetString(attr->parent->doc, attr->children, 1));
       
  5709                 else
       
  5710                     return (xmlNodeListGetString(NULL, attr->children, 1));
       
  5711                 }
       
  5712                 */
       
  5713                 return xmlNodeListGetString(
       
  5714                             (cur->parent ? cur->parent->doc : NULL),
       
  5715                             cur->children,
       
  5716                             1);
       
  5717 
       
  5718         case XML_TEXT_NODE:
       
  5719         case XML_CDATA_SECTION_NODE:
       
  5720                 /* XMLENGINE: DONE: branches joined with Comment and PI nodes */
       
  5721         case XML_COMMENT_NODE:
       
  5722         case XML_PI_NODE:
       
  5723                 /* XMLENGINE: DONE: simplified */
       
  5724                 return cur->content ? xmlStrdup(cur->content) : cur->content /* NULL here */;
       
  5725         case XML_ENTITY_REF_NODE:{
       
  5726                 xmlEntityPtr ent;
       
  5727                 xmlBufferPtr buffer;
       
  5728                 xmlChar*     ret;
       
  5729 
       
  5730                 /* lookup entity declaration */
       
  5731                 ent = xmlGetDocEntity(cur->doc, cur->name);
       
  5732                 if (!ent)
       
  5733                     return (NULL);
       
  5734 
       
  5735                 buffer = xmlBufferCreate();
       
  5736                 if (!buffer)
       
  5737                     return (NULL); // OOM
       
  5738 
       
  5739                 xmlNodeBufGetContent(buffer, cur);
       
  5740                 
       
  5741                 ret = buffer->content;
       
  5742                 buffer->content = NULL;
       
  5743                 xmlBufferFree(buffer);
       
  5744                 return (ret);
       
  5745             }
       
  5746         /* XMLENGINE: defaulted
       
  5747         case XML_ENTITY_NODE:
       
  5748         case XML_DOCUMENT_TYPE_NODE:
       
  5749         case XML_NOTATION_NODE:
       
  5750         case XML_DTD_NODE:
       
  5751         case XML_XINCLUDE_START:
       
  5752         case XML_XINCLUDE_END:
       
  5753             return (NULL);
       
  5754         */
       
  5755         case XML_DOCUMENT_NODE:
       
  5756 #ifdef LIBXML_DOCB_ENABLED
       
  5757         case XML_DOCB_DOCUMENT_NODE:
       
  5758 #endif
       
  5759         case XML_HTML_DOCUMENT_NODE: {
       
  5760             xmlBufferPtr buffer;
       
  5761             xmlChar *ret;
       
  5762 
       
  5763             buffer = xmlBufferCreate();
       
  5764             if (!buffer)
       
  5765                 return (NULL);
       
  5766 
       
  5767             xmlNodeBufGetContent(buffer, (xmlNodePtr) cur);
       
  5768             
       
  5769             ret = buffer->content;
       
  5770             buffer->content = NULL;
       
  5771             xmlBufferFree(buffer);
       
  5772             return (ret);
       
  5773         }
       
  5774         case XML_NAMESPACE_DECL:
       
  5775             /*
       
  5776             {
       
  5777             xmlChar *tmp;
       
  5778 
       
  5779             tmp = xmlStrdup(((xmlNsPtr) cur)->href);
       
  5780             return (tmp);
       
  5781             }
       
  5782             */
       
  5783             return xmlStrdup(((xmlNsPtr) cur)->href);
       
  5784 
       
  5785         /* XMLENGINE: defaulted / not implemented by libxml2
       
  5786         case XML_ELEMENT_DECL:
       
  5787             
       
  5788             return (NULL);
       
  5789         case XML_ATTRIBUTE_DECL:
       
  5790             
       
  5791             return (NULL);
       
  5792         case XML_ENTITY_DECL:
       
  5793             
       
  5794             return (NULL);
       
  5795         */
       
  5796 
       
  5797         //-- most of node types do not have text content
       
  5798         default:
       
  5799             return (NULL);
       
  5800     }
       
  5801 }
       
  5802 
       
  5803 /**
       
  5804  * xmlNodeSetContent:
       
  5805  * @param cur the node being modified
       
  5806  * @param content the new value of the content
       
  5807  *
       
  5808  * Replace the content of a node.
       
  5809  *
       
  5810  * OOM: possible --> sets OOM flag
       
  5811  */
       
  5812 XMLPUBFUNEXPORT void
       
  5813 xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content)
       
  5814 {
       
  5815 	LOAD_GS_SAFE_NODE(cur)
       
  5816     if (!cur) {
       
  5817 #ifdef DEBUG_TREE
       
  5818         xmlGenericError(xmlGenericErrorContext, "xmlNodeSetContent : node == NULL\n");
       
  5819 #endif
       
  5820         return;
       
  5821     }
       
  5822     
       
  5823     switch (cur->type) {
       
  5824         case XML_DOCUMENT_FRAG_NODE:
       
  5825         case XML_ELEMENT_NODE:
       
  5826         case XML_ATTRIBUTE_NODE:{
       
  5827             xmlNodePtr tmpN = cur->children;
       
  5828             cur->children = xmlStringGetNodeList(cur->doc, content); // may set OOM flag
       
  5829             
       
  5830             if(OOM_FLAG)
       
  5831             {
       
  5832                 cur->children = tmpN;
       
  5833                 return;
       
  5834             }
       
  5835             if (tmpN)
       
  5836                 xmlFreeNodeList(tmpN);
       
  5837             UPDATE_LAST_CHILD_AND_PARENT(cur)
       
  5838             break;
       
  5839             }
       
  5840         case XML_TEXT_NODE:
       
  5841         case XML_CDATA_SECTION_NODE:
       
  5842         case XML_ENTITY_REF_NODE:
       
  5843         case XML_ENTITY_NODE:
       
  5844         case XML_PI_NODE:
       
  5845         case XML_COMMENT_NODE:
       
  5846             
       
  5847             if (cur->content != NULL) {
       
  5848                 if (!((cur->doc != NULL) &&
       
  5849                      (cur->doc->dict != NULL) &&
       
  5850                       xmlDictOwns(cur->doc->dict, cur->content)))
       
  5851                 {
       
  5852                     xmlFree(cur->content);
       
  5853                 }
       
  5854             }
       
  5855             if (cur->children != NULL)
       
  5856                 xmlFreeNodeList(cur->children);
       
  5857             cur->last = cur->children = NULL;
       
  5858             if (content != NULL) {
       
  5859                 cur->content = xmlStrdup(content); // may set OOM flag
       
  5860                 
       
  5861             } else
       
  5862                 cur->content = NULL;
       
  5863             break;
       
  5864         case XML_DOCUMENT_NODE:
       
  5865         case XML_HTML_DOCUMENT_NODE:
       
  5866         case XML_DOCUMENT_TYPE_NODE:
       
  5867         case XML_XINCLUDE_START:
       
  5868         case XML_XINCLUDE_END:
       
  5869 #ifdef LIBXML_DOCB_ENABLED
       
  5870         case XML_DOCB_DOCUMENT_NODE:
       
  5871 #endif
       
  5872             break;
       
  5873         case XML_NOTATION_NODE:
       
  5874             break;
       
  5875         case XML_DTD_NODE:
       
  5876             break;
       
  5877         case XML_NAMESPACE_DECL:
       
  5878         break;
       
  5879         case XML_ELEMENT_DECL:
       
  5880             
       
  5881             break;
       
  5882         case XML_ATTRIBUTE_DECL:
       
  5883             
       
  5884             break;
       
  5885         case XML_ENTITY_DECL:
       
  5886             
       
  5887             break;
       
  5888     }
       
  5889 }
       
  5890 
       
  5891 #ifdef LIBXML_TREE_ENABLED
       
  5892 /**
       
  5893  * xmlNodeSetContentLen:
       
  5894  * @param cur the node being modified
       
  5895  * @param content the new value of the content
       
  5896  * @param len the size of content
       
  5897  *
       
  5898  * Replace the content of a node.
       
  5899  */
       
  5900 XMLPUBFUNEXPORT void
       
  5901 xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len)
       
  5902 {
       
  5903     
       
  5904     if (cur == NULL) {
       
  5905 #ifdef DEBUG_TREE
       
  5906         xmlGenericError(xmlGenericErrorContext,
       
  5907         "xmlNodeSetContentLen : node == NULL\n");
       
  5908 #endif
       
  5909     return;
       
  5910     }
       
  5911     switch (cur->type) {
       
  5912         case XML_DOCUMENT_FRAG_NODE:
       
  5913         case XML_ELEMENT_NODE:
       
  5914         case XML_ATTRIBUTE_NODE:
       
  5915         if (cur->children != NULL) xmlFreeNodeList(cur->children);
       
  5916         cur->children = xmlStringLenGetNodeList(cur->doc, content, len);
       
  5917         UPDATE_LAST_CHILD_AND_PARENT(cur)
       
  5918         break;
       
  5919         case XML_TEXT_NODE:
       
  5920         case XML_CDATA_SECTION_NODE:
       
  5921         case XML_ENTITY_REF_NODE:
       
  5922         case XML_ENTITY_NODE:
       
  5923         case XML_PI_NODE:
       
  5924         case XML_COMMENT_NODE:
       
  5925         case XML_NOTATION_NODE:
       
  5926         if (cur->content != NULL) {
       
  5927         xmlFree(cur->content);
       
  5928         }
       
  5929         if (cur->children != NULL) xmlFreeNodeList(cur->children);
       
  5930         cur->children = cur->last = NULL;
       
  5931         if (content != NULL) {
       
  5932         cur->content = xmlStrndup(content, len);
       
  5933         } else
       
  5934         cur->content = NULL;
       
  5935         break;
       
  5936         case XML_DOCUMENT_NODE:
       
  5937         case XML_DTD_NODE:
       
  5938         case XML_HTML_DOCUMENT_NODE:
       
  5939         case XML_DOCUMENT_TYPE_NODE:
       
  5940     case XML_NAMESPACE_DECL:
       
  5941     case XML_XINCLUDE_START:
       
  5942     case XML_XINCLUDE_END:
       
  5943 #ifdef LIBXML_DOCB_ENABLED
       
  5944     case XML_DOCB_DOCUMENT_NODE:
       
  5945 #endif
       
  5946         break;
       
  5947         case XML_ELEMENT_DECL:
       
  5948         
       
  5949         break;
       
  5950         case XML_ATTRIBUTE_DECL:
       
  5951         
       
  5952         break;
       
  5953         case XML_ENTITY_DECL:
       
  5954         
       
  5955         break;
       
  5956     }
       
  5957 }
       
  5958 #endif /* LIBXML_TREE_ENABLED */
       
  5959 
       
  5960 /**
       
  5961  * xmlNodeAddContentLen:
       
  5962  * @param cur the node being modified
       
  5963  * @param content extra content
       
  5964  * @param len the size of content
       
  5965  *
       
  5966  * Append the extra substring to the node content.
       
  5967  *
       
  5968  * OOM: possible --> OOM flag is set
       
  5969  */
       
  5970 XMLPUBFUNEXPORT void
       
  5971 xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len)
       
  5972 {
       
  5973     
       
  5974     
       
  5975     if (!cur) {
       
  5976 #ifdef DEBUG_TREE
       
  5977         xmlGenericError(xmlGenericErrorContext, "xmlNodeAddContentLen : node == NULL\n");
       
  5978 #endif
       
  5979         return;
       
  5980     }
       
  5981     if (len <= 0)
       
  5982         return;
       
  5983     // DONE: OPTIMIZE: switch
       
  5984     switch (cur->type) {
       
  5985         case XML_ELEMENT_NODE:
       
  5986         case XML_DOCUMENT_FRAG_NODE: {
       
  5987             xmlNodePtr last, newNode, tmp;
       
  5988 
       
  5989             last = cur->last;
       
  5990             newNode = xmlNewTextLen(content, len); // may set OOM flag
       
  5991             if (newNode)
       
  5992             {
       
  5993                 tmp = xmlAddChild(cur, newNode); // may set OOM flag
       
  5994                 if (!tmp)
       
  5995                    return; // OOM has happened --> OOM flag is already set
       
  5996 
       
  5997                 if (tmp != newNode)
       
  5998                 {
       
  5999                     return; // no need to try to merge
       
  6000                 }
       
  6001                 if (last && (last->next == newNode)) {
       
  6002                     xmlTextMerge(last, newNode); // may set OOM flag
       
  6003                 }
       
  6004             }
       
  6005             break;
       
  6006         }
       
  6007         case XML_ATTRIBUTE_NODE: // = default branch, but for faster lookup, let's have it here
       
  6008             break;
       
  6009         case XML_TEXT_NODE:
       
  6010         case XML_CDATA_SECTION_NODE:
       
  6011         case XML_ENTITY_REF_NODE:
       
  6012         case XML_ENTITY_NODE:
       
  6013         case XML_PI_NODE:
       
  6014         case XML_COMMENT_NODE:
       
  6015         case XML_NOTATION_NODE:{
       
  6016             xmlChar* tmpS;
       
  6017             if (content) {
       
  6018                 if (cur->doc       &&
       
  6019                     cur->doc->dict &&
       
  6020                     xmlDictOwns(cur->doc->dict, cur->content))
       
  6021                 {
       
  6022                     tmpS = xmlStrncatNew(cur->content, content, len); // may set OOM flag
       
  6023                     if(!tmpS)
       
  6024                         return;
       
  6025                     cur->content = tmpS;
       
  6026                 }
       
  6027                 else
       
  6028                 {
       
  6029                     cur->content = xmlStrncat(cur->content, content, len); // may set OOM flag
       
  6030                 }
       
  6031             }
       
  6032             break;
       
  6033         }
       
  6034         default:
       
  6035             break;
       
  6036 /* DONE: this is in the default branch now
       
  6037         case XML_DOCUMENT_NODE:
       
  6038         case XML_DTD_NODE:
       
  6039         case XML_HTML_DOCUMENT_NODE:
       
  6040         case XML_DOCUMENT_TYPE_NODE:
       
  6041         case XML_NAMESPACE_DECL:
       
  6042         case XML_XINCLUDE_START:
       
  6043         case XML_XINCLUDE_END:
       
  6044 #ifdef LIBXML_DOCB_ENABLED
       
  6045         case XML_DOCB_DOCUMENT_NODE:
       
  6046 #endif
       
  6047             break;
       
  6048         case XML_ELEMENT_DECL:
       
  6049         case XML_ATTRIBUTE_DECL:
       
  6050         case XML_ENTITY_DECL:
       
  6051             break;
       
  6052 */
       
  6053     }
       
  6054 }
       
  6055 
       
  6056 /**
       
  6057  * xmlNodeAddContent:
       
  6058  * @param cur the node being modified
       
  6059  * @param content extra content
       
  6060  *
       
  6061  * Append the extra substring to the node content.
       
  6062  *
       
  6063  * OOM: possible --> OOM flag is set
       
  6064  */
       
  6065 XMLPUBFUNEXPORT void
       
  6066 xmlNodeAddContent(xmlNodePtr cur, const xmlChar* content)
       
  6067 {
       
  6068     int len;
       
  6069     
       
  6070     if (!cur) {
       
  6071 #ifdef DEBUG_TREE
       
  6072         xmlGenericError(xmlGenericErrorContext, "xmlNodeAddContent : node == NULL\n");
       
  6073 #endif
       
  6074         return;
       
  6075     }
       
  6076     if (!content)
       
  6077         return;
       
  6078     len = xmlStrlen(content);
       
  6079     xmlNodeAddContentLen(cur, content, len); // may set OOM flag
       
  6080 }
       
  6081 
       
  6082 /**
       
  6083  * xmlTextMerge:
       
  6084  * @param first the first text node
       
  6085  * @param second the second text node being merged
       
  6086  *
       
  6087  * Merge two text nodes into one
       
  6088  * Returns the first text node augmented
       
  6089  *
       
  6090  * OOM: possible --> OOM flag is set, returns NULL
       
  6091  */
       
  6092 XMLPUBFUNEXPORT xmlNodePtr
       
  6093 xmlTextMerge(xmlNodePtr first, xmlNodePtr second)
       
  6094 {
       
  6095 	LOAD_GS_SAFE_NODE(first)
       
  6096     if (!first)
       
  6097         return(second);
       
  6098     if (!second                       ||
       
  6099         first->type  != XML_TEXT_NODE ||
       
  6100         second->type != XML_TEXT_NODE ||
       
  6101         second->name != first->name)
       
  6102     {
       
  6103         return(first);
       
  6104     }
       
  6105     xmlNodeAddContent(first, second->content);
       
  6106     if (OOM_FLAG)
       
  6107         return NULL;
       
  6108     xmlUnlinkNode(second);
       
  6109     xmlFreeNode(second);
       
  6110     return(first);
       
  6111 }
       
  6112 
       
  6113 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED)
       
  6114 /**
       
  6115  * xmlGetNsList:
       
  6116  * @param doc the document
       
  6117  * @param node the current node
       
  6118  *
       
  6119  * Search all the namespace applying to a given element.
       
  6120  * Returns an NULL terminated array of all the #xmlNsPtr found
       
  6121  *         that need to be freed by the caller or NULL if no
       
  6122  *         namespace if defined
       
  6123  *
       
  6124  * OOM: iif returns NULL and OOM flag is set
       
  6125  */
       
  6126 XMLPUBFUNEXPORT xmlNsPtr*
       
  6127 xmlGetNsList(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node)
       
  6128 {
       
  6129     xmlNsPtr  cur;
       
  6130     xmlNsPtr* ret = NULL;
       
  6131     int       nbns = 0;
       
  6132     
       
  6133     int       maxns = 10;
       
  6134     int       i;
       
  6135 
       
  6136     while (node)
       
  6137     {
       
  6138         if (node->type == XML_ELEMENT_NODE)
       
  6139         {
       
  6140             cur = node->nsDef;
       
  6141             while (cur)
       
  6142             {
       
  6143                 if (!ret)
       
  6144                 {
       
  6145                     ret = (xmlNsPtr*) xmlMalloc((maxns + 1) * sizeof(xmlNsPtr));
       
  6146                     if (!ret) {
       
  6147                         xmlTreeErrMemory(EMBED_ERRTXT("getting namespace list"));
       
  6148                         return (NULL);
       
  6149                     }
       
  6150                     ret[nbns] = NULL;
       
  6151                 }
       
  6152                 for (i = 0; i < nbns; i++) {
       
  6153                     if (cur->prefix == ret[i]->prefix ||
       
  6154                         xmlStrEqual(cur->prefix, ret[i]->prefix))
       
  6155                         break;
       
  6156                 }
       
  6157                 if (i >= nbns)
       
  6158                 {
       
  6159                     if (nbns >= maxns)
       
  6160                     {
       
  6161                         xmlNsPtr* tmpret;
       
  6162                         maxns *= 2;
       
  6163                         tmpret = (xmlNsPtr*) xmlRealloc(ret,(maxns + 1) * sizeof(xmlNsPtr)); // may set OOM flag
       
  6164                         if (!tmpret) {
       
  6165                             xmlFree(ret);
       
  6166                             xmlTreeErrMemory(EMBED_ERRTXT("getting namespace list"));// sets OOM flag
       
  6167                             return (NULL);
       
  6168                         }
       
  6169                         ret = tmpret;
       
  6170                     }
       
  6171                     ret[nbns++] = cur;
       
  6172                     ret[nbns] = NULL;
       
  6173                 }
       
  6174                 cur = cur->next;
       
  6175             } // while (cur)
       
  6176         } // if (node->type == XML_ELEMENT_NODE)
       
  6177         node = node->parent;
       
  6178     } // while (node)
       
  6179     return (ret);
       
  6180 }
       
  6181 #endif /* LIBXML_TREE_ENABLED */
       
  6182 
       
  6183 // DONE: Rename argument nameSpace into nsPrefix
       
  6184 /**
       
  6185  * xmlSearchNs:
       
  6186  * @param doc the document
       
  6187  * @param node the current node
       
  6188  * @param nsPrefix the namespace prefix
       
  6189  *
       
  6190  * Search a Ns registered under a given name space for a document.
       
  6191  * recurse on the parents until it finds the defined namespace
       
  6192  * or return NULL otherwise.
       
  6193  * nsPrefix can be NULL, this is a search for the default namespace.
       
  6194  * We don't allow to cross entities boundaries. If you don't declare
       
  6195  * the namespace within those you will be in troubles !!! A warning
       
  6196  * is generated to cover this case.
       
  6197  *
       
  6198  * Returns the namespace pointer or NULL.
       
  6199  *
       
  6200  * OOM: possible only for "xml" prefix, when (!doc && node->type==XML_ELEMENT_NODE) || !doc->oldNs ,
       
  6201  *      NULL is returned then as if "NOT FOUND" result and OOM flag is set
       
  6202  */
       
  6203 XMLPUBFUNEXPORT xmlNsPtr
       
  6204 xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar* nsPrefix) {
       
  6205 	
       
  6206     xmlNsPtr cur;
       
  6207     xmlNodePtr orig = node;
       
  6208     LOAD_GS_SAFE_DOC(doc)
       
  6209 
       
  6210     if (!node)
       
  6211         return(NULL);
       
  6212 
       
  6213     if (nsPrefix && xmlStrEqual(nsPrefix, (const xmlChar*) "xml"))
       
  6214     {
       
  6215         if (!doc && node->type == XML_ELEMENT_NODE)
       
  6216         {
       
  6217             /*
       
  6218              * The XML-1.0 namespace is normally held on the root
       
  6219              * element. In this case exceptionally create it on the
       
  6220              * node element.
       
  6221              */
       
  6222             cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
       
  6223             if (!cur)
       
  6224                 goto OOM_exit;
       
  6225 
       
  6226             memset(cur, 0, sizeof(xmlNs));
       
  6227             cur->type = XML_LOCAL_NAMESPACE;
       
  6228             cur->href = xmlStrdup(XML_XML_NAMESPACE);
       
  6229             cur->prefix = xmlStrdup((const xmlChar *)"xml");
       
  6230 
       
  6231             if(OOM_FLAG){
       
  6232                 xmlFreeNs(cur);
       
  6233 OOM_exit:
       
  6234                 xmlTreeErrMemory(EMBED_ERRTXT("searching namespace"));
       
  6235                 return(NULL);
       
  6236             }
       
  6237 
       
  6238             cur->next = node->nsDef;
       
  6239             node->nsDef = cur;
       
  6240             return(cur);
       
  6241         }
       
  6242         
       
  6243         
       
  6244         if (!doc->oldNs) {
       
  6245             /*
       
  6246              * Allocate a new Namespace and fill the fields.
       
  6247              */
       
  6248             doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
       
  6249             if (!doc->oldNs)
       
  6250                 goto OOM_exit;
       
  6251 
       
  6252             memset(doc->oldNs, 0, sizeof(xmlNs));
       
  6253             doc->oldNs->type = XML_LOCAL_NAMESPACE;
       
  6254             doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE);        //
       
  6255             doc->oldNs->prefix = xmlStrdup((const xmlChar *)"xml"); // may set OOM flag
       
  6256             if(OOM_FLAG){
       
  6257                 xmlFreeNs(doc->oldNs);
       
  6258                 doc->oldNs = NULL;
       
  6259                 goto OOM_exit;
       
  6260             }
       
  6261         }
       
  6262         return(doc->oldNs);
       
  6263     } // if nsPrefix is "xml"
       
  6264 
       
  6265     
       
  6266     
       
  6267     while (node &&
       
  6268            node->type != XML_ENTITY_NODE     &&
       
  6269            node->type != XML_ENTITY_REF_NODE &&
       
  6270            node->type != XML_ENTITY_DECL)
       
  6271    {
       
  6272 
       
  6273         if (node->type == XML_ELEMENT_NODE)
       
  6274         {
       
  6275             
       
  6276             
       
  6277             cur = node->nsDef;
       
  6278             while (cur)
       
  6279             {
       
  6280                 if (( !cur->prefix && !nsPrefix && cur->href  )
       
  6281                         ||
       
  6282                     (  cur->prefix  &&  nsPrefix && cur->href &&
       
  6283                        xmlStrEqual(cur->prefix, nsPrefix)     ))
       
  6284                 {
       
  6285                     return(cur);
       
  6286                 }
       
  6287                 cur = cur->next;
       
  6288             }
       
  6289             if (orig != node) {
       
  6290                 cur = node->ns;
       
  6291                 if (cur
       
  6292                        &&
       
  6293                        (( !cur->prefix && !nsPrefix && cur->href  )
       
  6294                             ||
       
  6295                         (  cur->prefix &&  nsPrefix && cur->href &&
       
  6296                           xmlStrEqual(cur->prefix, nsPrefix)      ))
       
  6297                    )
       
  6298                 {
       
  6299                     return(cur);
       
  6300                 }
       
  6301             }
       
  6302         }
       
  6303         node = node->parent;
       
  6304     }
       
  6305     return(NULL);
       
  6306 }
       
  6307 
       
  6308 /**
       
  6309  * xmlNsInScope:
       
  6310  * @param doc the document
       
  6311  * @param node the current node
       
  6312  * @param ancestor the ancestor carrying the namespace
       
  6313  * @param prefix the namespace prefix
       
  6314  *
       
  6315  * Verify that the given namespace held on ancestor is still in scope
       
  6316  * on node.
       
  6317  *
       
  6318  * Returns 1 if true, 0 if false and -1 in case of error.
       
  6319  *
       
  6320  * OOM: never
       
  6321  */
       
  6322 static int
       
  6323 xmlNsInScope(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node,
       
  6324              xmlNodePtr ancestor, const xmlChar * prefix)
       
  6325 {
       
  6326     xmlNsPtr tst;
       
  6327 
       
  6328     while (node && (node != ancestor))
       
  6329     {
       
  6330         if (node->type == XML_ELEMENT_NODE)
       
  6331         {
       
  6332             tst = node->nsDef;
       
  6333             while (tst)
       
  6334             {
       
  6335                 if ( (!tst->prefix && !prefix)
       
  6336                         ||
       
  6337                      (tst->prefix  &&  prefix &&
       
  6338                       xmlStrEqual(tst->prefix, prefix)) )
       
  6339                 {
       
  6340                     return (0);
       
  6341                 }
       
  6342                 tst = tst->next;
       
  6343             }
       
  6344         }
       
  6345         else
       
  6346         if (node->type == XML_ENTITY_REF_NODE ||
       
  6347             node->type == XML_ENTITY_NODE     ||
       
  6348             node->type == XML_ENTITY_DECL)
       
  6349         {
       
  6350             return (-1);
       
  6351         }
       
  6352         node = node->parent;
       
  6353     }
       
  6354     return (node != ancestor) ? -1 : 1;
       
  6355 }
       
  6356 
       
  6357 /**
       
  6358  * xmlSearchNsByHref:
       
  6359  * @param doc the document
       
  6360  * @param node the current node
       
  6361  * @param href the namespace value
       
  6362  *
       
  6363  * Search a Ns aliasing a given URI. Recurse on the parents until it finds
       
  6364  * the defined namespace or return NULL otherwise.
       
  6365  * Returns the namespace pointer or NULL.
       
  6366  *
       
  6367  * OOM: possible iif: href is XML_XML_NAMESPACE && (!doc && node->type == XML_ELEMENT_NODE) || !(doc->oldNs))
       
  6368  *      --> then OOM flag is set when it returns NULL,
       
  6369  *      otherwise, OOM never happens
       
  6370  */
       
  6371 XMLPUBFUNEXPORT xmlNsPtr
       
  6372 xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar* href)
       
  6373 {
       
  6374     xmlNsPtr cur;
       
  6375     xmlNodePtr orig = node;
       
  6376     int is_attr;
       
  6377     LOAD_GS_SAFE_DOC(doc)
       
  6378 
       
  6379     if (!node || !href)
       
  6380         return (NULL);
       
  6381 
       
  6382     if (xmlStrEqual(href, XML_XML_NAMESPACE))
       
  6383     {
       
  6384         /*
       
  6385             Maybe in the future we will have global const XML namespace object
       
  6386             that will be reused everywhere:
       
  6387             - no need to allocate memory for it (thus no OOM may happen) - it is just
       
  6388               linked as the last NsDef in the list
       
  6389             - it is never freed (we should have special routine for deleting xmlNsPtr that
       
  6390               compares pointer with the global object's pointer)
       
  6391 
       
  6392               O.K. NRC/Helsinki
       
  6393         */
       
  6394 
       
  6395         /*
       
  6396          * Only the document can hold the XML spec namespace.
       
  6397          */
       
  6398         if (!doc && (node->type == XML_ELEMENT_NODE))
       
  6399         {
       
  6400             /*
       
  6401              * The XML-1.0 namespace is normally held on the root
       
  6402              * element. In this case exceptionally create it on the
       
  6403              * node element.
       
  6404              */
       
  6405             cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
       
  6406             if (!cur)
       
  6407                 goto OOM_exit;
       
  6408 
       
  6409             memset(cur, 0, sizeof(xmlNs));
       
  6410             cur->type = XML_LOCAL_NAMESPACE;
       
  6411             cur->href = xmlStrdup(XML_XML_NAMESPACE);
       
  6412             cur->prefix = xmlStrdup((const xmlChar *) "xml");
       
  6413 
       
  6414             if(OOM_FLAG){ // OOM!
       
  6415                 xmlFreeNs(cur);
       
  6416 OOM_exit:
       
  6417                 xmlTreeErrMemory(EMBED_ERRTXT("searching namespace"));
       
  6418                 return (NULL);
       
  6419             }
       
  6420             cur->next = node->nsDef;
       
  6421             node->nsDef = cur;
       
  6422             return (cur);
       
  6423         }
       
  6424 
       
  6425         if (!doc->oldNs)
       
  6426         {
       
  6427             /*
       
  6428              * Allocate a new Namespace and fill the fields.
       
  6429              */
       
  6430             doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
       
  6431             if (!doc->oldNs)
       
  6432                 goto OOM_exit;
       
  6433 
       
  6434             memset(doc->oldNs, 0, sizeof(xmlNs));
       
  6435             doc->oldNs->type = XML_LOCAL_NAMESPACE;
       
  6436             doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE);
       
  6437             doc->oldNs->prefix = xmlStrdup((const xmlChar*) "xml");
       
  6438             if(OOM_FLAG){
       
  6439                 xmlFreeNs(doc->oldNs);
       
  6440                 doc->oldNs = NULL;
       
  6441                 goto OOM_exit;
       
  6442             }
       
  6443         }
       
  6444         return (doc->oldNs);
       
  6445     } // end if XML namespace
       
  6446 
       
  6447     is_attr = (node->type == XML_ATTRIBUTE_NODE);
       
  6448     while (node)
       
  6449     {
       
  6450         if ((node->type == XML_ENTITY_REF_NODE) ||
       
  6451             (node->type == XML_ENTITY_NODE)     ||
       
  6452             (node->type == XML_ENTITY_DECL))
       
  6453         {
       
  6454             return (NULL);
       
  6455         }
       
  6456         if (node->type == XML_ELEMENT_NODE)
       
  6457         {
       
  6458             cur = node->nsDef;
       
  6459             while (cur)
       
  6460             {
       
  6461                 if (cur->href &&
       
  6462                     href      &&
       
  6463                     xmlStrEqual(cur->href, href))
       
  6464                 {
       
  6465                     if ((!is_attr || cur->prefix) &&
       
  6466                         (xmlNsInScope(doc, orig, node, cur->href) == 1))
       
  6467                         return (cur);
       
  6468                 }
       
  6469                 cur = cur->next;
       
  6470             }
       
  6471             if (orig != node)
       
  6472             {   
       
  6473                 cur = node->ns;
       
  6474                 if (cur                          &&
       
  6475                     cur->href                    &&
       
  6476                     href                         && // move up?
       
  6477                     xmlStrEqual(cur->href, href) &&
       
  6478                     (!is_attr || cur->prefix)    && // move up?
       
  6479                     (xmlNsInScope(doc, orig, node, cur->href) == 1))
       
  6480                 {
       
  6481                         return (cur);
       
  6482                 }
       
  6483 
       
  6484             }
       
  6485         }
       
  6486         node = node->parent;
       
  6487     }
       
  6488     return (NULL);
       
  6489 }
       
  6490 
       
  6491 /**
       
  6492  * xmlNewReconciliedNs:
       
  6493  * @param doc the document
       
  6494  * @param tree a node expected to hold the new namespace
       
  6495  * @param ns the original namespace
       
  6496  *
       
  6497  * This function tries to locate a namespace definition in a tree
       
  6498  * ancestors, or create a new namespace definition node similar to
       
  6499  * ns trying to reuse the same prefix. However if the given prefix is
       
  6500  * null (default namespace) or reused within the subtree defined by
       
  6501  * tree or on one of its ancestors then a new prefix is generated.
       
  6502  * Returns the (new) namespace definition or NULL in case of error
       
  6503  *
       
  6504  * OOM: possible --> OOM flag is set when returns NULL
       
  6505  */
       
  6506 xmlNsPtr
       
  6507 xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
       
  6508     xmlNsPtr def;
       
  6509     xmlChar prefix[50]; 
       
  6510     int counter = 1;
       
  6511     LOAD_GS_SAFE_DOC(doc)
       
  6512 
       
  6513     
       
  6514     if (!tree) {
       
  6515 #ifdef DEBUG_TREE
       
  6516         xmlGenericError(xmlGenericErrorContext,"xmlNewReconciliedNs : tree == NULL\n");
       
  6517 #endif
       
  6518         return(NULL);
       
  6519     }
       
  6520     if (!ns) {
       
  6521 #ifdef DEBUG_TREE
       
  6522         xmlGenericError(xmlGenericErrorContext,"xmlNewReconciliedNs : ns == NULL\n");
       
  6523 #endif
       
  6524         return(NULL);
       
  6525     }
       
  6526     /*
       
  6527      * Search an existing namespace definition inherited.
       
  6528      */
       
  6529     def = xmlSearchNsByHref(doc, tree, ns->href); // OOM is possible
       
  6530     if (def){
       
  6531         return(def);
       
  6532     }else{
       
  6533         if(OOM_FLAG)
       
  6534             return NULL;
       
  6535     }
       
  6536 
       
  6537     /*
       
  6538      * Find a close prefix which is not already in use.
       
  6539      * Let's strip namespace prefixes longer than 20 chars !
       
  6540      */
       
  6541     if (!ns->prefix)
       
  6542         snprintf((char*) prefix, sizeof(prefix), "default");
       
  6543     else
       
  6544         snprintf((char*) prefix, sizeof(prefix), "%.20s", ns->prefix);
       
  6545 
       
  6546     def = xmlSearchNs(doc, tree, prefix);
       
  6547     while (def && !OOM_FLAG)
       
  6548     {
       
  6549         if (counter > 1000)  
       
  6550             return(NULL); // giveup
       
  6551         if (!ns->prefix)
       
  6552             snprintf((char *) prefix, sizeof(prefix), "default%d", counter++);
       
  6553         else
       
  6554             snprintf((char *) prefix, sizeof(prefix), "%.20s%d", ns->prefix, counter++);
       
  6555         def = xmlSearchNs(doc, tree, prefix);
       
  6556     }
       
  6557     if (OOM_FLAG)
       
  6558           return NULL;
       
  6559     /*
       
  6560      * Ok, now we are ready to create a new one.
       
  6561      */
       
  6562     def = xmlNewNs(tree, ns->href, prefix); // may set OOM flag
       
  6563     return(def);
       
  6564 }
       
  6565 
       
  6566 #ifdef LIBXML_TREE_ENABLED
       
  6567 /**
       
  6568  * xmlReconciliateNs:
       
  6569  * @param doc the document
       
  6570  * @param tree a node defining the subtree to reconciliate
       
  6571  *
       
  6572  * This function checks that all the namespaces declared within the given
       
  6573  * tree are properly declared. This is needed for example after Copy or Cut
       
  6574  * and then paste operations. The subtree may still hold pointers to
       
  6575  * namespace declarations outside the subtree or invalid/masked. As much
       
  6576  * as possible the function try to reuse the existing namespaces found in
       
  6577  * the new environment. If not possible the new namespaces are redeclared
       
  6578  * on tree at the top of the given subtree.
       
  6579  * Returns the number of namespace declarations created or -1 in case of error.
       
  6580  *
       
  6581  * OOM: possible.. / NOT REVIEWED
       
  6582  */
       
  6583 
       
  6584 XMLPUBFUNEXPORT int
       
  6585 xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree)
       
  6586 {
       
  6587     xmlNsPtr*   oldNs = NULL;
       
  6588     xmlNsPtr*   newNs = NULL;
       
  6589     int         sizeCache = 0;
       
  6590     int         nbCache = 0;
       
  6591 
       
  6592     //xmlNsPtr    n; // DONE: moved into inner scope
       
  6593     xmlNodePtr  node = tree;
       
  6594     xmlAttrPtr  attr;
       
  6595     //int         ret = 0; // DONE: not needed
       
  6596     int         i;
       
  6597 
       
  6598 	if(node->type != XML_ELEMENT_NODE) {
       
  6599 		return -1;
       
  6600 	}
       
  6601     while (node)
       
  6602     {
       
  6603         /*
       
  6604          * Reconciliate the node namespace
       
  6605          */
       
  6606         if (node->ns && (node->type != XML_TEXT_NODE))
       
  6607         {
       
  6608             /*
       
  6609              * initialize the cache if needed
       
  6610              */
       
  6611             if (sizeCache == 0)
       
  6612             {
       
  6613                 
       
  6614                 sizeCache = 10;
       
  6615                 
       
  6616                 oldNs = (xmlNsPtr*) xmlMalloc(sizeCache * sizeof(xmlNsPtr));
       
  6617                 if (!oldNs)
       
  6618                     goto OOM;
       
  6619 
       
  6620                 newNs = (xmlNsPtr*) xmlMalloc(sizeCache * sizeof(xmlNsPtr));
       
  6621                 if (!newNs)
       
  6622                     goto OOM;
       
  6623             }
       
  6624             for (i = 0;i < nbCache;i++) {
       
  6625                 if (oldNs[i] == node->ns) {
       
  6626                     node->ns = newNs[i];
       
  6627                     break;
       
  6628                 }
       
  6629             }
       
  6630             if (i == nbCache) {
       
  6631                 /*
       
  6632                  * Ok, we need to recreate a new namespace definition
       
  6633                  */
       
  6634                 xmlNsPtr n = xmlNewReconciliedNs(doc, tree, node->ns);
       
  6635                 if (n) { /* :-( what if else ??? */
       
  6636                     /*
       
  6637                      * check if we need to grow the cache buffers.
       
  6638                      */
       
  6639                     if (sizeCache <= nbCache)
       
  6640                     {
       
  6641                         // DONE: Fix xmlRealloc
       
  6642                         xmlNsPtr* tmp;
       
  6643                         sizeCache *= 2;
       
  6644                         tmp = (xmlNsPtr *) xmlRealloc(oldNs, sizeCache * sizeof(xmlNsPtr));
       
  6645                         if (!tmp)
       
  6646                             goto OOM;
       
  6647                         oldNs = tmp;
       
  6648                         // DONE: Fix xmlRealloc
       
  6649                         tmp = (xmlNsPtr*) xmlRealloc(newNs, sizeCache * sizeof(xmlNsPtr));
       
  6650                         if (!tmp)
       
  6651                             goto OOM;
       
  6652                         newNs = tmp;
       
  6653                     }
       
  6654                     newNs[nbCache] = n;
       
  6655                     oldNs[nbCache++] = node->ns;
       
  6656                     node->ns = n;
       
  6657                 }
       
  6658             }
       
  6659         }
       
  6660         /*
       
  6661          * now check for namespace hold by attributes on the node.
       
  6662          */
       
  6663         if(!(IS_DATA_NODE(node))){
       
  6664 	        attr = node->properties;
       
  6665 	        while (attr)
       
  6666 	        {
       
  6667 	            if (attr->ns)
       
  6668 	            {
       
  6669 	                /*
       
  6670 	                 * initialize the cache if needed
       
  6671 	                 */
       
  6672 	                if (sizeCache == 0)
       
  6673 	                {
       
  6674 	                    sizeCache = 10;
       
  6675 	                    oldNs = (xmlNsPtr*) xmlMalloc(sizeCache * sizeof(xmlNsPtr));
       
  6676 	                    if (!oldNs)
       
  6677 	                        goto OOM;
       
  6678 
       
  6679 	                    newNs = (xmlNsPtr*) xmlMalloc(sizeCache * sizeof(xmlNsPtr));
       
  6680 	                    if (!newNs)
       
  6681 	                        goto OOM;
       
  6682 	                }
       
  6683 	                for (i = 0;i < nbCache;i++) {
       
  6684 	                    if (oldNs[i] == attr->ns) {
       
  6685 	                        attr->ns = newNs[i];
       
  6686 	                        break;
       
  6687 	                    }
       
  6688 	                }
       
  6689 	                if (i == nbCache) {
       
  6690 	                    /*
       
  6691 	                     * OK we need to recreate a new namespace definition
       
  6692 	                     */
       
  6693 	                    xmlNsPtr n = xmlNewReconciliedNs(doc, tree, attr->ns);
       
  6694 	                    if (n)
       
  6695 	                    {       /* :-( what if else ??? */
       
  6696 	                        /*
       
  6697 	                         * check if we need to grow the cache buffers.
       
  6698 	                         */
       
  6699 	                        if (sizeCache <= nbCache)
       
  6700 	                        {
       
  6701 	                            // DONE: Fix xmlRealloc
       
  6702 	                            xmlNsPtr* tmp;
       
  6703 	                            sizeCache *= 2;
       
  6704 	                            tmp = (xmlNsPtr*) xmlRealloc(oldNs, sizeCache * sizeof(xmlNsPtr));
       
  6705 	                            if (!tmp)
       
  6706 	                                goto OOM;
       
  6707 	                            oldNs = tmp;
       
  6708 	                            // DONE: Fix xmlRealloc
       
  6709 	                            tmp = (xmlNsPtr*) xmlRealloc(newNs, sizeCache * sizeof(xmlNsPtr));
       
  6710 	                            if (!tmp)
       
  6711 	                                goto OOM;
       
  6712 	                            newNs = tmp;
       
  6713 	                        }
       
  6714 	                        newNs[nbCache] = n;
       
  6715 	                        oldNs[nbCache++] = attr->ns;
       
  6716 	                        attr->ns = n;
       
  6717 	                    }
       
  6718 	                }
       
  6719 	            }
       
  6720 	            attr = attr->next;
       
  6721         	}
       
  6722         }
       
  6723 
       
  6724         /*
       
  6725          * Browse the full subtree, deep first
       
  6726          */
       
  6727     if (node->children && node->type != XML_ENTITY_REF_NODE) 
       
  6728     	{
       
  6729             /* deep first */
       
  6730             node = node->children;
       
  6731         } else if ((node != tree) && node->next) {
       
  6732             /* then siblings */
       
  6733             node = node->next;
       
  6734         } else if (node != tree) {
       
  6735             /* go up to parents->next if needed */
       
  6736             while (node != tree)
       
  6737             {
       
  6738                 if (node->parent)
       
  6739                     node = node->parent;
       
  6740                 if ((node != tree) && node->next) {
       
  6741                     node = node->next;
       
  6742                     break;
       
  6743                 }
       
  6744                 if (!node->parent) {
       
  6745                     node = NULL;
       
  6746                     break;
       
  6747                 }
       
  6748             }
       
  6749             /* exit condition */
       
  6750             if (node == tree)
       
  6751                 node = NULL;
       
  6752         } else
       
  6753             break;
       
  6754     }
       
  6755     if (oldNs)
       
  6756         xmlFree(oldNs);
       
  6757     if (newNs)
       
  6758         xmlFree(newNs);
       
  6759     return(0);
       
  6760 //------------------------
       
  6761 OOM:
       
  6762     if (oldNs)
       
  6763         xmlFree(oldNs);
       
  6764     if (newNs)
       
  6765         xmlFree(newNs);
       
  6766     xmlTreeErrMemory(EMBED_ERRTXT("fixing namespaces"));
       
  6767     return(-1);
       
  6768 }
       
  6769 #endif /* LIBXML_TREE_ENABLED */
       
  6770 
       
  6771 /**
       
  6772  * xmlHasProp:
       
  6773  * @param node the node
       
  6774  * @param name the attribute name
       
  6775  *
       
  6776  * Search an attribute associated to a node
       
  6777  * This function also looks in DTD attribute declaration for #FIXED or
       
  6778  * default declaration values unless DTD use has been turned off.
       
  6779  *
       
  6780  * Returns the attribute or the attribute declaration or NULL if
       
  6781  *         neither was found.
       
  6782  *
       
  6783  * OOM: possible --> iif returns NULL and OOM flag is set
       
  6784  */
       
  6785 XMLPUBFUNEXPORT xmlAttrPtr
       
  6786 xmlHasProp(xmlNodePtr node, const xmlChar *name) {
       
  6787     xmlAttrPtr prop;
       
  6788     xmlDocPtr doc;
       
  6789     LOAD_GS_SAFE_NODE(node)
       
  6790 
       
  6791     if (!node || !name)
       
  6792         return(NULL);
       
  6793     /*
       
  6794      * Check on the properties attached to the node
       
  6795      */
       
  6796     prop = node->properties;
       
  6797     while (prop) {
       
  6798         if (xmlStrEqual(prop->name, name))  {
       
  6799             return(prop);
       
  6800         }
       
  6801         prop = prop->next;
       
  6802     }
       
  6803     if (!xmlCheckDTD)
       
  6804         return(NULL);
       
  6805 
       
  6806     /*
       
  6807      * Check if there is a default declaration in the internal
       
  6808      * or external subsets
       
  6809      */
       
  6810     doc =  node->doc;
       
  6811     if (doc)
       
  6812     {
       
  6813         xmlAttributePtr attrDecl;
       
  6814         if (doc->intSubset)
       
  6815         {
       
  6816             attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name); // OOM is possible
       
  6817             if (!attrDecl)
       
  6818             {
       
  6819                 if(OOM_FLAG)
       
  6820                     return NULL;
       
  6821                 if(doc->extSubset)
       
  6822                 {
       
  6823                     attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
       
  6824                     if(OOM_FLAG)
       
  6825                         return NULL;
       
  6826                 }
       
  6827             }
       
  6828             if (attrDecl &&
       
  6829                 attrDecl->defaultValue)
       
  6830             {
       
  6831                 /* return attribute declaration only if a default value is given
       
  6832                 (that includes #FIXED declarations) */
       
  6833                 return((xmlAttrPtr) attrDecl);
       
  6834             }
       
  6835         }
       
  6836     }
       
  6837     return(NULL);
       
  6838 }
       
  6839 
       
  6840 /**
       
  6841  * xmlHasNsProp:
       
  6842  * @param node the node
       
  6843  * @param name the attribute name
       
  6844  * @param nameSpace the URI of the namespace
       
  6845  *
       
  6846  * Search for an attribute associated to a node
       
  6847  * This attribute has to be anchored in the namespace specified.
       
  6848  * This does the entity substitution.
       
  6849  * This function looks in DTD attribute declaration for #FIXED or
       
  6850  * default declaration values unless DTD use has been turned off.
       
  6851  *
       
  6852  * Returns the attribute or the attribute declaration or NULL
       
  6853  *     if neither was found.
       
  6854  *
       
  6855  * OOM: possible --> iif returns NULL AND OOM flag is set
       
  6856  */
       
  6857 XMLPUBFUNEXPORT xmlAttrPtr
       
  6858 xmlHasNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
       
  6859     xmlAttrPtr prop;
       
  6860 	    
       
  6861 #ifdef LIBXML_TREE_ENABLED
       
  6862     xmlDocPtr doc;
       
  6863 #endif /* LIBXML_TREE_ENABLED */
       
  6864 	LOAD_GS_SAFE_NODE(node)
       
  6865 
       
  6866     if (!node)
       
  6867         return(NULL);
       
  6868 
       
  6869     if (!nameSpace)
       
  6870         return(xmlHasProp(node, name)); // may set OOM flag when NULL
       
  6871 
       
  6872     prop = node->properties;
       
  6873     while (prop)
       
  6874     {
       
  6875         /*
       
  6876         * One need to have
       
  6877         *   - same attribute names
       
  6878         *   - and the attribute carrying that namespace
       
  6879         */
       
  6880         if (xmlStrEqual(prop->name, name) &&
       
  6881             prop->ns                      &&   
       
  6882             xmlStrEqual(prop->ns->href, nameSpace))
       
  6883         {
       
  6884             return(prop);
       
  6885         }
       
  6886         prop = prop->next;
       
  6887     }
       
  6888     if (!xmlCheckDTD)
       
  6889         return(NULL);
       
  6890 
       
  6891 #ifdef LIBXML_TREE_ENABLED
       
  6892     /*
       
  6893      * Check if there is a default declaration in the internal
       
  6894      * or external subsets
       
  6895      */
       
  6896     doc =  node->doc;
       
  6897     if (doc && doc->intSubset)
       
  6898     {
       
  6899         xmlAttributePtr attrDecl = NULL;
       
  6900         xmlNsPtr* nsList;
       
  6901         xmlNsPtr* cur;
       
  6902         xmlChar*  ename;
       
  6903 
       
  6904         nsList = xmlGetNsList(node->doc, node); //  may set OOM flag when returns NULL
       
  6905         if (!nsList)
       
  6906             return(NULL);
       
  6907 
       
  6908         if (node->ns && node->ns->prefix) {
       
  6909             // may set OOM flag, the check is later
       
  6910             ename = xmlStrdup(node->ns->prefix);
       
  6911             ename = xmlStrcat(ename, BAD_CAST ":");
       
  6912             ename = xmlStrcat(ename, node->name);
       
  6913         } else {
       
  6914             ename = xmlStrdup(node->name);
       
  6915         }
       
  6916         if (!ename || OOM_FLAG) {
       
  6917             xmlFree(nsList);
       
  6918             if (ename)
       
  6919                 xmlFree(ename); // XMLENGINE added: ename may be !=NULL if OOM_FLAG!=NULL
       
  6920             return(NULL);
       
  6921         }
       
  6922 
       
  6923         cur = nsList;
       
  6924         while (*cur) {
       
  6925             if (xmlStrEqual((*cur)->href, nameSpace))
       
  6926             {
       
  6927                 attrDecl = xmlGetDtdQAttrDesc(
       
  6928                                     doc->intSubset,
       
  6929                                     ename,
       
  6930                                     name,
       
  6931                                     (*cur)->prefix);
       
  6932                 if (!attrDecl &&
       
  6933                      doc->extSubset)
       
  6934                 {
       
  6935                     attrDecl = xmlGetDtdQAttrDesc(
       
  6936                                     doc->extSubset,
       
  6937                                     ename,
       
  6938                                     name,
       
  6939                                     (*cur)->prefix);
       
  6940                 }
       
  6941             }
       
  6942             cur++;
       
  6943         }
       
  6944         xmlFree(nsList);
       
  6945         xmlFree(ename);
       
  6946         return((xmlAttrPtr) attrDecl);
       
  6947     }
       
  6948 #endif /* LIBXML_TREE_ENABLED */
       
  6949     return(NULL);
       
  6950 }
       
  6951 
       
  6952 /**
       
  6953  * xmlGetProp:
       
  6954  * @param node the node
       
  6955  * @param name the attribute name
       
  6956  *
       
  6957  * Search and get the value of an attribute associated to a node
       
  6958  * This does the entity substitution.
       
  6959  * This function looks in DTD attribute declaration for #FIXED or
       
  6960  * default declaration values unless DTD use has been turned off.
       
  6961  * NOTE: this function acts independently of namespaces associated
       
  6962  *       to the attribute. Use xmlGetNsProp() or xmlGetNoNsProp()
       
  6963  *       for namespace aware processing.
       
  6964  *
       
  6965  * Returns the attribute value or NULL if not found.
       
  6966  *     It's up to the caller to free the memory with xmlFree().
       
  6967  */
       
  6968 XMLPUBFUNEXPORT xmlChar*
       
  6969 xmlGetProp(xmlNodePtr node, const xmlChar* name)
       
  6970 {
       
  6971     xmlAttrPtr prop;
       
  6972     xmlDocPtr doc;
       
  6973     LOAD_GS_SAFE_NODE(node)
       
  6974 
       
  6975     if (!node || !name || (node->type != XML_ELEMENT_NODE))
       
  6976         return(NULL);
       
  6977     // REPLACED: if ((node == NULL) || (name == NULL)) return(NULL);
       
  6978 
       
  6979     /*
       
  6980      * Check on the properties attached to the node
       
  6981      */
       
  6982     prop = node->properties;
       
  6983     while (prop) {
       
  6984         if (xmlStrEqual(prop->name, name))  {
       
  6985             xmlChar *ret;
       
  6986 
       
  6987             ret = xmlNodeListGetString(node->doc, prop->children, 1);
       
  6988             if (!ret)
       
  6989                 return(xmlStrdup((xmlChar *)""));
       
  6990             return(ret);
       
  6991         }
       
  6992         prop = prop->next;
       
  6993     }
       
  6994     if (!xmlCheckDTD)
       
  6995         return(NULL);
       
  6996 
       
  6997     /*
       
  6998      * Check if there is a default declaration in the internal
       
  6999      * or external subsets
       
  7000      */
       
  7001     doc =  node->doc;
       
  7002     if (doc) {
       
  7003         xmlAttributePtr attrDecl;
       
  7004         if (doc->intSubset) {
       
  7005             attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
       
  7006             if (!attrDecl && doc->extSubset)
       
  7007                 attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
       
  7008             if (attrDecl && attrDecl->defaultValue)
       
  7009             {
       
  7010                 /* return attribute declaration only if a default value is given
       
  7011                    (that includes #FIXED declarations) */
       
  7012                 return(xmlStrdup(attrDecl->defaultValue));
       
  7013             }
       
  7014         }
       
  7015     }
       
  7016     return(NULL);
       
  7017 }
       
  7018 
       
  7019 /**
       
  7020  * xmlGetNoNsProp:
       
  7021  * @param node the node
       
  7022  * @param name the attribute name
       
  7023  *
       
  7024  * Search and get the value of an attribute associated to a node
       
  7025  * This does the entity substitution.
       
  7026  * This function looks in DTD attribute declaration for #FIXED or
       
  7027  * default declaration values unless DTD use has been turned off.
       
  7028  * This function is similar to xmlGetProp except it will accept only
       
  7029  * an attribute in no namespace.
       
  7030  *
       
  7031  * Returns the attribute value or NULL if not found.
       
  7032  *     It's up to the caller to free the memory with xmlFree().
       
  7033  */
       
  7034 XMLPUBFUNEXPORT xmlChar*
       
  7035 xmlGetNoNsProp(xmlNodePtr node, const xmlChar *name)
       
  7036 {
       
  7037     xmlAttrPtr prop;
       
  7038     xmlDocPtr doc;
       
  7039     LOAD_GS_SAFE_NODE(node)
       
  7040 
       
  7041     if (!node || !name || (node->type != XML_ELEMENT_NODE))
       
  7042         return(NULL);
       
  7043 
       
  7044     /*
       
  7045      * Check on the properties attached to the node
       
  7046      */
       
  7047     prop = node->properties;
       
  7048     while (prop) {
       
  7049         if (!prop->ns && xmlStrEqual(prop->name, name))
       
  7050         {
       
  7051             xmlChar *ret;
       
  7052 
       
  7053             ret = xmlNodeListGetString(node->doc, prop->children, 1);
       
  7054             return ret ? ret : xmlStrdup((xmlChar *)"");
       
  7055         }
       
  7056         prop = prop->next;
       
  7057     }
       
  7058     if (!xmlCheckDTD)
       
  7059         return(NULL);
       
  7060 
       
  7061     /*
       
  7062      * Check if there is a default declaration in the internal
       
  7063      * or external subsets
       
  7064      */
       
  7065     doc =  node->doc;
       
  7066     if (doc) {
       
  7067         xmlAttributePtr attrDecl;
       
  7068         if (doc->intSubset) {
       
  7069             attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
       
  7070             if (!attrDecl && doc->extSubset)
       
  7071                 attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
       
  7072             if (attrDecl && attrDecl->defaultValue)
       
  7073             {
       
  7074               /* return attribute declaration only if a default value is given
       
  7075                  (that includes #FIXED declarations) */
       
  7076                 return(xmlStrdup(attrDecl->defaultValue));
       
  7077             }
       
  7078         }
       
  7079     }
       
  7080     return(NULL);
       
  7081 }
       
  7082 
       
  7083 /**
       
  7084  * xmlGetNsProp:
       
  7085  * @param node the node
       
  7086  * @param name the attribute name
       
  7087  * @param nameSpace the URI of the namespace
       
  7088  *
       
  7089  * Search and get the value of an attribute associated to a node
       
  7090  * This attribute has to be anchored in the namespace specified.
       
  7091  * This does the entity substitution.
       
  7092  * This function looks in DTD attribute declaration for #FIXED or
       
  7093  * default declaration values unless DTD use has been turned off.
       
  7094  *
       
  7095  * Returns the attribute value or NULL if not found.
       
  7096  *     It's up to the caller to free the memory with xmlFree().
       
  7097  */
       
  7098 XMLPUBFUNEXPORT xmlChar*
       
  7099 xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace)
       
  7100 {
       
  7101 	xmlAttrPtr prop;
       
  7102     xmlDocPtr doc;
       
  7103     xmlNsPtr ns;
       
  7104     LOAD_GS_SAFE_NODE(node)
       
  7105 
       
  7106     if (!node || node->type != XML_ELEMENT_NODE)
       
  7107         return(NULL);
       
  7108 
       
  7109     if (!nameSpace)
       
  7110         return(xmlGetNoNsProp(node, name));
       
  7111 
       
  7112     prop = node->properties;
       
  7113 
       
  7114     while (prop)
       
  7115     {
       
  7116         /*
       
  7117          * One need to have
       
  7118          *   - same attribute names
       
  7119          *   - and the attribute carrying that namespace
       
  7120          */
       
  7121         if (xmlStrEqual(prop->name, name)   &&
       
  7122             prop->ns                        &&  
       
  7123             xmlStrEqual(prop->ns->href, nameSpace))
       
  7124         {
       
  7125             xmlChar* ret;
       
  7126 
       
  7127             ret = xmlNodeListGetString(node->doc, prop->children, 1);
       
  7128             if (!ret)
       
  7129                 return(xmlStrdup((xmlChar*)""));
       
  7130             return(ret);
       
  7131         }
       
  7132         prop = prop->next;
       
  7133     }
       
  7134     if (!xmlCheckDTD)
       
  7135         return(NULL);
       
  7136 
       
  7137     /*
       
  7138      * Check if there is a default declaration in the internal
       
  7139      * or external subsets
       
  7140      */
       
  7141     doc =  node->doc;
       
  7142     if (doc && doc->intSubset) {
       
  7143         xmlAttributePtr attrDecl;
       
  7144 
       
  7145         attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
       
  7146         if (!attrDecl && doc->extSubset)
       
  7147             attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
       
  7148 
       
  7149         if (attrDecl && attrDecl->prefix)
       
  7150         {
       
  7151             /*
       
  7152              * The DTD declaration only allows a prefix search
       
  7153              */
       
  7154             ns = xmlSearchNs(doc, node, attrDecl->prefix);
       
  7155             if (ns && xmlStrEqual(ns->href, nameSpace))
       
  7156                 return(xmlStrdup(attrDecl->defaultValue));
       
  7157         }
       
  7158     }
       
  7159     return(NULL);
       
  7160 }
       
  7161 
       
  7162 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
       
  7163 /**
       
  7164  * xmlUnsetProp:
       
  7165  * @param node the node
       
  7166  * @param name the attribute name
       
  7167  *
       
  7168  * Remove an attribute carried by a node.
       
  7169  * Returns 0 if successful, -1 if not found
       
  7170  */
       
  7171 XMLPUBFUNEXPORT int
       
  7172 xmlUnsetProp(xmlNodePtr node, const xmlChar* name)
       
  7173 {
       
  7174     xmlAttrPtr prop, prev;
       
  7175 
       
  7176     if (!node || !name)
       
  7177         return(-1);
       
  7178 
       
  7179     prev = NULL;
       
  7180     prop = node->properties;
       
  7181     while (prop)
       
  7182     {   
       
  7183         if (!prop->ns && xmlStrEqual(prop->name, name))
       
  7184         {
       
  7185             if (prev)
       
  7186                 prev->next = prop->next;
       
  7187             else
       
  7188                 node->properties = prop->next;
       
  7189             xmlFreeProp(prop);
       
  7190             return(0);
       
  7191         }
       
  7192         prev = prop;
       
  7193         prop = prop->next;
       
  7194     }
       
  7195     return(-1);
       
  7196 }
       
  7197 
       
  7198 /**
       
  7199  * xmlUnsetNsProp:
       
  7200  * @param node the node
       
  7201  * @param ns the namespace definition
       
  7202  * @param name the attribute name
       
  7203  *
       
  7204  * Remove an attribute carried by a node.
       
  7205  * Returns 0 if successful, -1 if not found
       
  7206  */
       
  7207 XMLPUBFUNEXPORT int
       
  7208 xmlUnsetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar* name)
       
  7209 {
       
  7210     xmlAttrPtr prop;
       
  7211     xmlAttrPtr prev;
       
  7212 
       
  7213     
       
  7214     if (!ns) // Note: check it first to avoid double check of 'node' and 'name' arguments
       
  7215         return(xmlUnsetProp(node, name));
       
  7216 
       
  7217     if (!node || !name || !ns->href)
       
  7218         return(-1);
       
  7219 
       
  7220     prop = node->properties;
       
  7221     prev = NULL;
       
  7222 
       
  7223     while (prop)
       
  7224     {
       
  7225         if (prop->ns                      &&
       
  7226             xmlStrEqual(prop->name, name) &&
       
  7227             xmlStrEqual(prop->ns->href, ns->href))
       
  7228         {
       
  7229             if (!prev)
       
  7230                 node->properties = prop->next;
       
  7231             else
       
  7232                 prev->next = prop->next;
       
  7233             xmlFreeProp(prop);
       
  7234             return(0);
       
  7235         }
       
  7236         prev = prop;
       
  7237         prop = prop->next;
       
  7238     }
       
  7239     return(-1);
       
  7240 }
       
  7241 #endif
       
  7242 
       
  7243 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
       
  7244 /**
       
  7245  * xmlSetProp:
       
  7246  * @param node the node
       
  7247  * @param name the attribute name
       
  7248  * @param value the attribute value
       
  7249  *
       
  7250  * Set (or reset) an attribute carried by a node.
       
  7251  * Returns the attribute pointer.
       
  7252  */
       
  7253 XMLPUBFUNEXPORT xmlAttrPtr
       
  7254 xmlSetProp(xmlNodePtr node, const xmlChar* name, const xmlChar* value)
       
  7255 {
       
  7256     xmlAttrPtr prop;
       
  7257     xmlDocPtr doc;
       
  7258 
       
  7259     if (!node || !name || (node->type != XML_ELEMENT_NODE))
       
  7260         return(NULL);
       
  7261 
       
  7262     doc = node->doc;
       
  7263     prop = node->properties;
       
  7264     while (prop)
       
  7265     {
       
  7266         if (!prop->ns && xmlStrEqual(prop->name, name)) // ISSUE: need to check ns->href ?
       
  7267         {
       
  7268             xmlNodePtr oldprop = prop->children;
       
  7269 
       
  7270             prop->children = NULL;
       
  7271             prop->last = NULL;
       
  7272             if (value)
       
  7273             {
       
  7274                 xmlChar*   buffer;
       
  7275                 xmlNodePtr tmp;
       
  7276 
       
  7277                 buffer = xmlEncodeEntitiesReentrant(node->doc, value);
       
  7278                 prop->children = xmlStringGetNodeList(node->doc, buffer);
       
  7279                 prop->last = NULL;
       
  7280                 prop->doc = doc;
       
  7281                 tmp = prop->children;
       
  7282 
       
  7283                 while (tmp) {
       
  7284                     tmp->parent = (xmlNodePtr) prop;
       
  7285                     tmp->doc = doc;
       
  7286                     if (!tmp->next)
       
  7287                         prop->last = tmp;
       
  7288                     tmp = tmp->next;
       
  7289                 }
       
  7290                 xmlFree(buffer);
       
  7291             }
       
  7292             if (oldprop)
       
  7293                 xmlFreeNodeList(oldprop);
       
  7294 
       
  7295             return(prop);
       
  7296         }
       
  7297         prop = prop->next;
       
  7298     }
       
  7299     prop = xmlNewProp(node, name, value);
       
  7300     return(prop);
       
  7301 }
       
  7302 
       
  7303 /**
       
  7304  * xmlSetNsProp:
       
  7305  * @param node the node
       
  7306  * @param ns the namespace definition
       
  7307  * @param name the attribute name
       
  7308  * @param value the attribute value
       
  7309  *
       
  7310  * Set (or reset) an attribute carried by a node.
       
  7311  * The ns structure must be in scope, this is not checked.
       
  7312  *
       
  7313  * Returns the attribute pointer.
       
  7314  */
       
  7315 XMLPUBFUNEXPORT xmlAttrPtr
       
  7316 xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar* name, const xmlChar* value)
       
  7317 {
       
  7318     xmlAttrPtr prop;
       
  7319 
       
  7320     if (!ns) 
       
  7321         return(xmlSetProp(node, name, value));
       
  7322 
       
  7323     if (!node || !name || !ns->href || (node->type != XML_ELEMENT_NODE))
       
  7324         return(NULL);
       
  7325 
       
  7326     prop = node->properties;
       
  7327 
       
  7328     while (prop)
       
  7329     {
       
  7330         /*
       
  7331          * One need to have
       
  7332          *   - same attribute names
       
  7333          *   - and the attribute carrying that namespace
       
  7334          */
       
  7335         if (prop->ns                        &&
       
  7336             xmlStrEqual(prop->name, name)   &&
       
  7337             xmlStrEqual(prop->ns->href, ns->href))
       
  7338         {
       
  7339             if (prop->children)
       
  7340                 xmlFreeNodeList(prop->children);
       
  7341             prop->children = NULL;
       
  7342             prop->last = NULL;
       
  7343             prop->ns = ns;
       
  7344             if (value)
       
  7345             {
       
  7346                 xmlChar*   buffer;
       
  7347                 xmlNodePtr tmp;
       
  7348 
       
  7349                 buffer = xmlEncodeEntitiesReentrant(node->doc, value);
       
  7350                 prop->children = xmlStringGetNodeList(node->doc, buffer);
       
  7351                 prop->last = NULL;
       
  7352                 tmp = prop->children;
       
  7353                 while (tmp) {
       
  7354                     tmp->parent = (xmlNodePtr) prop;
       
  7355                     if (!tmp->next)
       
  7356                         prop->last = tmp;
       
  7357                     tmp = tmp->next;
       
  7358                 }
       
  7359                 xmlFree(buffer);
       
  7360             }
       
  7361             return(prop);
       
  7362         }
       
  7363         prop = prop->next;
       
  7364     }
       
  7365     prop = xmlNewNsProp(node, ns, name, value);
       
  7366     return(prop);
       
  7367 }
       
  7368 
       
  7369 #endif /* LIBXML_TREE_ENABLED */
       
  7370 
       
  7371 
       
  7372 // #define xmlNodeIsText(node) ((node) && (node)->type == XML_TEXT_NODE)
       
  7373 /**
       
  7374  * xmlNodeIsText:
       
  7375  * @param node the node
       
  7376  *
       
  7377  * Is this node a Text node ?
       
  7378  * Returns 1 yes, 0 no
       
  7379  */
       
  7380 XMLPUBFUNEXPORT int
       
  7381 xmlNodeIsText(xmlNodePtr node)
       
  7382 {
       
  7383     return (node && node->type == XML_TEXT_NODE) ? 1 : 0; // Do we need exactly 0 and 1 ?
       
  7384 }
       
  7385 
       
  7386 /**
       
  7387  * xmlIsBlankNode:
       
  7388  * @param node the node
       
  7389  *
       
  7390  * Checks whether this node is an empty or whitespace only
       
  7391  * (and possibly ignorable) text-node.
       
  7392  *
       
  7393  * Returns 1 yes, 0 no
       
  7394  */
       
  7395 XMLPUBFUNEXPORT int
       
  7396 xmlIsBlankNode(xmlNodePtr node)
       
  7397 {
       
  7398     const xmlChar* cur;
       
  7399     if (!node ||
       
  7400           (node->type != XML_TEXT_NODE &&
       
  7401            node->type != XML_CDATA_SECTION_NODE))
       
  7402         return(0);
       
  7403 
       
  7404     if (!node->content)
       
  7405         return(1);
       
  7406 
       
  7407     cur = node->content;
       
  7408     while (*cur != 0) {
       
  7409         if (!IS_BLANK_CH(*cur))
       
  7410             return(0);
       
  7411         cur++;
       
  7412     }
       
  7413 
       
  7414     return(1);
       
  7415 }
       
  7416 
       
  7417 /**
       
  7418  * xmlTextConcat:
       
  7419  * @param node the node
       
  7420  * @param content the content
       
  7421  * @param len content length
       
  7422  *
       
  7423  * Concat the given string at the end of the existing node content
       
  7424  *
       
  7425  * Returns -1 in case of error, 0 otherwise
       
  7426  */
       
  7427 
       
  7428 XMLPUBFUNEXPORT int
       
  7429 xmlTextConcat(xmlNodePtr node, const xmlChar *content, int len)
       
  7430 {
       
  7431     if (!node)
       
  7432         return(-1);
       
  7433 
       
  7434     if ((node->type != XML_TEXT_NODE) &&
       
  7435         (node->type != XML_CDATA_SECTION_NODE))
       
  7436     {
       
  7437 #ifdef DEBUG_TREE
       
  7438     xmlGenericError(xmlGenericErrorContext,
       
  7439         "xmlTextConcat: node is not text nor CDATA\n");
       
  7440 #endif
       
  7441         return(-1);
       
  7442     }
       
  7443     /* need to check if content is currently in the dictionary */
       
  7444     if (node->doc && node->doc->dict &&
       
  7445         xmlDictOwns(node->doc->dict, node->content))
       
  7446     {
       
  7447         node->content = xmlStrncatNew(node->content, content, len);
       
  7448     } else {
       
  7449         node->content = xmlStrncat(node->content, content, len);
       
  7450     }
       
  7451     if (!node->content)
       
  7452         return(-1); // OOM!
       
  7453     return(0);
       
  7454 }
       
  7455 
       
  7456 /************************************************************************
       
  7457  *                                                                      *
       
  7458  *          Output : to a FILE or in memory                             *
       
  7459  *                                                                      *
       
  7460  ************************************************************************/
       
  7461 
       
  7462 /**
       
  7463  * xmlBufferCreate:
       
  7464  *
       
  7465  * routine to create an XML buffer.
       
  7466  * returns the new structure.
       
  7467  *
       
  7468  * OOM: possible --> NULL is returned and OOM flag is set
       
  7469  */
       
  7470 XMLPUBFUNEXPORT xmlBufferPtr
       
  7471 xmlBufferCreate(void)
       
  7472 {
       
  7473 	LOAD_GS_DIRECT
       
  7474     xmlBufferPtr ret;
       
  7475 
       
  7476     ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
       
  7477     if (!ret) {
       
  7478         xmlTreeErrMemory(EMBED_ERRTXT("creating buffer"));
       
  7479         return(NULL);
       
  7480     }
       
  7481     ret->use = 0;
       
  7482     ret->size = xmlDefaultBufferSize;
       
  7483     ret->alloc = xmlBufferAllocScheme;
       
  7484     ret->content = (xmlChar*) xmlMallocAtomic(ret->size * sizeof(xmlChar));
       
  7485     if (!ret->content) {
       
  7486         xmlTreeErrMemory(EMBED_ERRTXT("creating buffer"));
       
  7487         xmlFree(ret);
       
  7488         return(NULL);
       
  7489     }
       
  7490     ret->content[0] = 0;
       
  7491     return(ret);
       
  7492 }
       
  7493 
       
  7494 /**
       
  7495  * xmlBufferCreateSize:
       
  7496  * @param size initial size of buffer
       
  7497  *
       
  7498  * routine to create an XML buffer.
       
  7499  * returns the new structure.
       
  7500  *
       
  7501  * OOM: possible --> NULL is returned && OOM flag is set
       
  7502  */
       
  7503 XMLPUBFUNEXPORT xmlBufferPtr
       
  7504 xmlBufferCreateSize(size_t size)
       
  7505 {
       
  7506 	LOAD_GS_DIRECT
       
  7507     xmlBufferPtr ret;
       
  7508     
       
  7509     ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
       
  7510     if (!ret)
       
  7511         goto OOM_exit;
       
  7512     ret->use = 0;
       
  7513     ret->alloc = xmlBufferAllocScheme;
       
  7514     ret->size = (size ? size+2 : 0);         /* +1 for ending null */
       
  7515     if (ret->size){
       
  7516         ret->content = (xmlChar*) xmlMallocAtomic(ret->size * sizeof(xmlChar));
       
  7517         if (!ret->content) {
       
  7518             xmlFree(ret);
       
  7519 OOM_exit:
       
  7520             xmlTreeErrMemory(EMBED_ERRTXT("creating buffer")); // sets OOM flag
       
  7521             return(NULL);
       
  7522         }
       
  7523         ret->content[0] = 0;
       
  7524     } else
       
  7525         ret->content = NULL;
       
  7526     return(ret);
       
  7527 }
       
  7528 
       
  7529 /**
       
  7530  * xmlBufferCreateStatic:
       
  7531  * @param mem the memory area
       
  7532  * @param size the size in byte
       
  7533  *
       
  7534  * routine to create an XML buffer from an immutable memory area.
       
  7535  * The area won't be modified nor copied, and is expected to be
       
  7536  * present until the end of the buffer lifetime.
       
  7537  *
       
  7538  * returns the new structure.
       
  7539  */
       
  7540 XMLPUBFUNEXPORT xmlBufferPtr
       
  7541 xmlBufferCreateStatic(void* mem, size_t size)
       
  7542 {
       
  7543     xmlBufferPtr ret;
       
  7544 
       
  7545     if (!mem || (size == 0))
       
  7546         return(NULL);
       
  7547 
       
  7548     ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
       
  7549     if (!ret) {
       
  7550         xmlTreeErrMemory(EMBED_ERRTXT("creating buffer"));
       
  7551         return(NULL);
       
  7552     }
       
  7553     ret->use = size;
       
  7554     ret->size = size;
       
  7555     ret->alloc = XML_BUFFER_ALLOC_IMMUTABLE;
       
  7556     ret->content = (xmlChar*) mem;
       
  7557     return(ret);
       
  7558 }
       
  7559 
       
  7560 #ifndef XMLENGINE_EXCLUDE_UNUSED
       
  7561 /**
       
  7562  * xmlBufferSetAllocationScheme:
       
  7563  * @param buf the buffer to tune
       
  7564  * @param scheme allocation scheme to use
       
  7565  *
       
  7566  * Sets the allocation scheme for this buffer
       
  7567  */
       
  7568 void
       
  7569 xmlBufferSetAllocationScheme(xmlBufferPtr buf,
       
  7570                              xmlBufferAllocationScheme scheme)
       
  7571 {
       
  7572     if (!buf) {
       
  7573 #ifdef DEBUG_BUFFER
       
  7574         xmlGenericError(xmlGenericErrorContext, "xmlBufferSetAllocationScheme: buf == NULL\n");
       
  7575 #endif
       
  7576         return;
       
  7577     }
       
  7578     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
       
  7579         return;
       
  7580 
       
  7581     buf->alloc = scheme;
       
  7582 }
       
  7583 
       
  7584 #endif /* ifndef XMLENGINE_EXCLUDE_UNUSED */
       
  7585 
       
  7586 /**
       
  7587  * xmlBufferFree:
       
  7588  * @param buf the buffer to free
       
  7589  *
       
  7590  * Frees an XML buffer. It frees both the content and the structure which
       
  7591  * encapsulate it.
       
  7592  *
       
  7593  * OOM: never
       
  7594  */
       
  7595 XMLPUBFUNEXPORT void
       
  7596 xmlBufferFree(xmlBufferPtr buf)
       
  7597 {
       
  7598     if (!buf) {
       
  7599 #ifdef DEBUG_BUFFER
       
  7600         xmlGenericError(xmlGenericErrorContext, "xmlBufferFree: buf == NULL\n");
       
  7601 #endif
       
  7602         return;
       
  7603     }
       
  7604 
       
  7605     if (buf->content &&
       
  7606         buf->alloc != XML_BUFFER_ALLOC_IMMUTABLE)
       
  7607     {
       
  7608         xmlFree(buf->content);
       
  7609     }
       
  7610     xmlFree(buf);
       
  7611 }
       
  7612 
       
  7613 #ifndef XMLENGINE_EXCLUDE_UNUSED
       
  7614 /**
       
  7615  * xmlBufferEmpty:
       
  7616  * @param buf the buffer
       
  7617  *
       
  7618  * empty a buffer.
       
  7619  */
       
  7620 void
       
  7621 xmlBufferEmpty(xmlBufferPtr buf)
       
  7622 {
       
  7623     if (!buf->content)
       
  7624         return;
       
  7625 
       
  7626     buf->use = 0;
       
  7627     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) {
       
  7628         buf->content = BAD_CAST "";
       
  7629     } else {
       
  7630         memset(buf->content, 0, buf->size);
       
  7631     }
       
  7632 }
       
  7633 
       
  7634 #endif /* ifndef XMLENGINE_EXCLUDE_UNUSED */
       
  7635 
       
  7636 /**
       
  7637  * xmlBufferShrink:
       
  7638  * @param buf the buffer to dump
       
  7639  * @param len the number of xmlChar to remove
       
  7640  *
       
  7641  * Remove the beginning of an XML buffer.
       
  7642  *
       
  7643  * Returns the number of #xmlChar removed, or -1 in case of failure.
       
  7644  *
       
  7645  * OOM: never
       
  7646  */
       
  7647 XMLPUBFUNEXPORT int
       
  7648 xmlBufferShrink(xmlBufferPtr buf, unsigned int len)
       
  7649 {
       
  7650     if (len == 0)
       
  7651         return(0);
       
  7652     if (len > buf->use)
       
  7653         return(-1);
       
  7654 
       
  7655     buf->use -= len;
       
  7656     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) {
       
  7657         buf->content += len;
       
  7658     } else {
       
  7659         memmove(buf->content, &buf->content[len], buf->use * sizeof(xmlChar));
       
  7660         buf->content[buf->use] = 0;
       
  7661     }
       
  7662     return(len);
       
  7663 }
       
  7664 
       
  7665 /**
       
  7666  * xmlBufferGrow:
       
  7667  * @param buf the buffer
       
  7668  * @param len the minimum free size to allocate
       
  7669  *
       
  7670  * Grow the available space of an XML buffer.
       
  7671  *
       
  7672  * Returns the new available space or -1 in case of error
       
  7673  *
       
  7674  * OOM: possible --> returns -1 && sets OOM flag
       
  7675  */
       
  7676 XMLPUBFUNEXPORT int
       
  7677 xmlBufferGrow(xmlBufferPtr buf, unsigned int len)
       
  7678 {
       
  7679     int      size;
       
  7680     xmlChar* newbuf;
       
  7681 
       
  7682     if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)  ||
       
  7683         (len + buf->use < buf->size))
       
  7684     {
       
  7685          return(0);
       
  7686     }
       
  7687     size = buf->use + len + 100;
       
  7688 
       
  7689     newbuf = (xmlChar*) xmlRealloc(buf->content, size);
       
  7690     if (!newbuf) {
       
  7691         xmlTreeErrMemory(EMBED_ERRTXT("growing buffer"));
       
  7692         return(-1);
       
  7693     }
       
  7694     buf->content = newbuf;
       
  7695     buf->size = size;
       
  7696     return(buf->size - buf->use);
       
  7697 }
       
  7698 
       
  7699 #ifndef XMLENGINE_EXCLUDE_FILE_FUNC
       
  7700 /**
       
  7701  * xmlBufferDump:
       
  7702  * @param file the file output
       
  7703  * @param buf the buffer to dump
       
  7704  *
       
  7705  * Dumps an XML buffer to  a FILE *.
       
  7706  * Returns the number of #xmlChar written
       
  7707  */
       
  7708 int
       
  7709 xmlBufferDump(FILE* file, xmlBufferPtr buf)
       
  7710 {
       
  7711     int ret;
       
  7712 
       
  7713     if (!buf) {
       
  7714 #ifdef DEBUG_BUFFER
       
  7715         xmlGenericError(xmlGenericErrorContext,
       
  7716                         "xmlBufferDump: buf == NULL\n");
       
  7717 #endif
       
  7718         return(0);
       
  7719     }
       
  7720     if (!buf->content) {
       
  7721 #ifdef DEBUG_BUFFER
       
  7722         xmlGenericError(xmlGenericErrorContext,
       
  7723                         "xmlBufferDump: buf->content == NULL\n");
       
  7724 #endif
       
  7725         return(0);
       
  7726     }
       
  7727     if (!file)
       
  7728         file = stdout;
       
  7729 
       
  7730     ret = fwrite(buf->content, sizeof(xmlChar), buf->use, file);
       
  7731     if(ret == EOF)
       
  7732     {
       
  7733         CHECK_ERRNO;
       
  7734     }
       
  7735     return(ret);
       
  7736 }
       
  7737 #endif
       
  7738 
       
  7739 // XMLENGINE: NOTE: replaced by macro
       
  7740 /**
       
  7741  * xmlBufferContent:
       
  7742  * @param buf the buffer
       
  7743  *
       
  7744  * Function to extract the content of a buffer
       
  7745  *
       
  7746  * Returns the internal content
       
  7747  */
       
  7748 /*
       
  7749 const xmlChar *
       
  7750 xmlBufferContent(const xmlBufferPtr buf)
       
  7751 {
       
  7752     if(!buf)
       
  7753         return NULL;
       
  7754 
       
  7755     return buf->content;
       
  7756 }
       
  7757 */
       
  7758 
       
  7759 /**
       
  7760  * xmlBufferLength:
       
  7761  * @param buf the buffer
       
  7762  *
       
  7763  * Function to get the length of a buffer
       
  7764  *
       
  7765  * Returns the length of data in the internal content
       
  7766  */
       
  7767 XMLPUBFUNEXPORT int
       
  7768 xmlBufferLength(const xmlBufferPtr buf)
       
  7769 {
       
  7770     if(!buf)
       
  7771         return 0;
       
  7772 
       
  7773     return buf->use;
       
  7774 }
       
  7775 
       
  7776 /**
       
  7777  * xmlBufferResize:
       
  7778  * @param buf the buffer to resize
       
  7779  * @param size the desired size
       
  7780  *
       
  7781  * Resize a buffer to accommodate minimum size of size.
       
  7782  *
       
  7783  * Returns  0 in case of problems, 1 otherwise
       
  7784  *
       
  7785  * OOM: possible --> OOM flag is set && returns 0
       
  7786  */
       
  7787 XMLPUBFUNEXPORT int
       
  7788 xmlBufferResize(xmlBufferPtr buf, unsigned int size)
       
  7789 {
       
  7790     unsigned int newSize;
       
  7791     xmlChar* rebuf = NULL;
       
  7792 
       
  7793 	/*
       
  7794 	 *   SYMBIAN DEF130695 FIX : Ensuring the BUFFER that needs to be re-sized is valid or not.
       
  7795 	 */
       
  7796 	if(buf == NULL)
       
  7797 		return (0);
       
  7798 		 
       
  7799 
       
  7800     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
       
  7801         return(0);
       
  7802 
       
  7803     /* Don't resize if we don't have to */
       
  7804     if (size < buf->size)
       
  7805         return 1;
       
  7806 
       
  7807     /* figure out new size */
       
  7808     switch (buf->alloc)
       
  7809     {
       
  7810     case XML_BUFFER_ALLOC_DOUBLEIT:
       
  7811     /*take care of empty case*/
       
  7812         newSize = (buf->size ? buf->size*2 : size + 10);
       
  7813         while (size > newSize)
       
  7814             newSize *= 2;
       
  7815         break;
       
  7816     // NOTE: same as default case
       
  7817     //case XML_BUFFER_ALLOC_EXACT:
       
  7818     //    newSize = size+10;
       
  7819     //    break;
       
  7820     default:
       
  7821         newSize = size+10;
       
  7822         break;
       
  7823     }
       
  7824 
       
  7825     if (!buf->content)
       
  7826     {
       
  7827         rebuf = (xmlChar*) xmlMallocAtomic(newSize * sizeof(xmlChar));
       
  7828     }
       
  7829     else if (buf->size - buf->use < 100)
       
  7830     {
       
  7831         rebuf = (xmlChar*) xmlRealloc(buf->content, newSize * sizeof(xmlChar));
       
  7832     }
       
  7833     else
       
  7834     {
       
  7835         /*
       
  7836          * if we are reallocating a buffer far from being full, it's
       
  7837          * better to make a new allocation and copy only the used range
       
  7838          * and free the old one.
       
  7839          */
       
  7840         rebuf = (xmlChar*) xmlMallocAtomic(newSize * sizeof(xmlChar));
       
  7841         if (rebuf) {
       
  7842             memcpy(rebuf, buf->content, buf->use);
       
  7843             xmlFree(buf->content);
       
  7844             rebuf[buf->use] = 0;
       
  7845         }
       
  7846     }
       
  7847     if (!rebuf) {
       
  7848         xmlTreeErrMemory(EMBED_ERRTXT("growing buffer"));
       
  7849         return 0;
       
  7850     }
       
  7851     buf->content = rebuf;
       
  7852     buf->size = newSize;
       
  7853 
       
  7854     return 1;
       
  7855 }
       
  7856 
       
  7857 /**
       
  7858  * xmlBufferAdd:
       
  7859  * @param buf the buffer to dump
       
  7860  * @param str the #xmlChar string
       
  7861  * @param len the number of #xmlChar to add
       
  7862  *
       
  7863  * Add a string range to an XML buffer. if len == -1, the length of
       
  7864  * str is recomputed.
       
  7865  *
       
  7866  * OOM: possible --> check OOM flag
       
  7867  */
       
  7868 XMLPUBFUNEXPORT void
       
  7869 xmlBufferAdd(xmlBufferPtr buf, const xmlChar* str, int len)
       
  7870 {
       
  7871     unsigned int needSize;
       
  7872 
       
  7873     if (!str) {
       
  7874 #ifdef DEBUG_BUFFER
       
  7875         xmlGenericError(xmlGenericErrorContext, "xmlBufferAdd: str == NULL\n");
       
  7876 #endif
       
  7877         return;
       
  7878     }
       
  7879     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE || len == 0)
       
  7880         return;
       
  7881 
       
  7882     if (len < -1) {
       
  7883 #ifdef DEBUG_BUFFER
       
  7884         xmlGenericError(xmlGenericErrorContext, "xmlBufferAdd: len < 0\n");
       
  7885 #endif
       
  7886         return;
       
  7887     }
       
  7888 
       
  7889     if (len < 0){
       
  7890         len = xmlStrlen(str);
       
  7891         if (len <= 0)
       
  7892             return;
       
  7893     }
       
  7894 
       
  7895     needSize = buf->use + len + 2;
       
  7896     if ( (needSize > buf->size)          &&
       
  7897          !xmlBufferResize(buf, needSize) )
       
  7898     {
       
  7899         xmlTreeErrMemory(EMBED_ERRTXT("growing buffer"));
       
  7900         return;
       
  7901     }
       
  7902 
       
  7903     memmove(&buf->content[buf->use], str, len * sizeof(xmlChar));
       
  7904     buf->use += len;
       
  7905     buf->content[buf->use] = 0;
       
  7906 }
       
  7907 
       
  7908 /**
       
  7909  * xmlBufferAddHead:
       
  7910  * @param buf the buffer
       
  7911  * @param str the #xmlChar string
       
  7912  * @param len the number of #xmlChar to add
       
  7913  *
       
  7914  * Add a string range to the beginning of an XML buffer.
       
  7915  * if len == -1, the length of str is recomputed.
       
  7916  *
       
  7917  * OOM: possible --> OOM flag is set
       
  7918  */
       
  7919 XMLPUBFUNEXPORT void
       
  7920 xmlBufferAddHead(xmlBufferPtr buf, const xmlChar* str, int len)
       
  7921 {
       
  7922     unsigned int needSize;
       
  7923     
       
  7924     if (len == 0 ||
       
  7925         buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
       
  7926     {
       
  7927         return;
       
  7928     }
       
  7929 
       
  7930     if (!str) {
       
  7931 #ifdef DEBUG_BUFFER
       
  7932         xmlGenericError(xmlGenericErrorContext, "xmlBufferAddHead: str == NULL\n");
       
  7933 #endif
       
  7934         return;
       
  7935     }
       
  7936     if (len < -1) {
       
  7937 #ifdef DEBUG_BUFFER
       
  7938         xmlGenericError(xmlGenericErrorContext, "xmlBufferAddHead: len < 0\n");
       
  7939 #endif
       
  7940         return;
       
  7941     }
       
  7942 
       
  7943     if (len < 0){  // if (len == -1)
       
  7944         len = xmlStrlen(str);
       
  7945         if (len <= 0)
       
  7946             return;
       
  7947     }
       
  7948 
       
  7949     needSize = buf->use + len + 2;
       
  7950     if ( needSize > buf->size            &&
       
  7951          !xmlBufferResize(buf, needSize) )
       
  7952     {
       
  7953         xmlTreeErrMemory(EMBED_ERRTXT("growing buffer"));
       
  7954         return;
       
  7955     }
       
  7956 
       
  7957     memmove(&buf->content[len], &buf->content[0], buf->use * sizeof(xmlChar));
       
  7958     memmove(&buf->content[0], str, len * sizeof(xmlChar));
       
  7959     buf->use += len;
       
  7960     buf->content[buf->use] = 0;
       
  7961 }
       
  7962 
       
  7963 /**
       
  7964  * xmlBufferCat:
       
  7965  * @param buf the buffer to dump
       
  7966  * @param str the #xmlChar string
       
  7967  *
       
  7968  * Append a zero terminated string to an XML buffer.
       
  7969  *
       
  7970  * OOM: possible / NOT REVIEWED
       
  7971  */
       
  7972 XMLPUBFUNEXPORT void
       
  7973 xmlBufferCat(xmlBufferPtr buf, const xmlChar* str)
       
  7974 {
       
  7975     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
       
  7976         return;
       
  7977     if (str)
       
  7978         xmlBufferAdd(buf, str, -1);
       
  7979 }
       
  7980 
       
  7981 /**
       
  7982  * xmlBufferCCat:
       
  7983  * @param buf the buffer to dump
       
  7984  * @param str the C char string
       
  7985  *
       
  7986  * Append a zero terminated C string to an XML buffer.
       
  7987  */
       
  7988 XMLPUBFUNEXPORT void
       
  7989 xmlBufferCCat(xmlBufferPtr buf, const char* str)
       
  7990 {
       
  7991     const char *cur;
       
  7992 
       
  7993     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
       
  7994         return;
       
  7995     if (!str) {
       
  7996 #ifdef DEBUG_BUFFER
       
  7997         xmlGenericError(xmlGenericErrorContext, "xmlBufferCCat: str == NULL\n");
       
  7998 #endif
       
  7999         return;
       
  8000     }
       
  8001     for (cur = str; *cur != 0; cur++) {
       
  8002         if (buf->use + 10 >= buf->size   &&
       
  8003             !xmlBufferResize(buf, buf->use+10))
       
  8004         {
       
  8005             xmlTreeErrMemory(EMBED_ERRTXT("growing buffer"));
       
  8006             return;
       
  8007         }
       
  8008         buf->content[buf->use++] = *cur;
       
  8009     }
       
  8010     buf->content[buf->use] = 0;
       
  8011 }
       
  8012 
       
  8013 
       
  8014 /**
       
  8015  * xmlBufferWriteCHAR:
       
  8016  * @param buf the XML buffer
       
  8017  * @param string the string to add
       
  8018  *
       
  8019  * routine which manages and grows an output buffer. This one adds
       
  8020  * xmlChars at the end of the buffer.
       
  8021  */
       
  8022 XMLPUBFUNEXPORT void
       
  8023 xmlBufferWriteCHAR(xmlBufferPtr buf, const xmlChar* string)
       
  8024 {
       
  8025     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
       
  8026         return;
       
  8027     xmlBufferCat(buf, string);
       
  8028 }
       
  8029 
       
  8030 /**
       
  8031  * xmlBufferWriteChar:
       
  8032  * @param buf the XML buffer output
       
  8033  * @param string the string to add
       
  8034  *
       
  8035  * routine which manage and grows an output buffer. This one add
       
  8036  * C chars at the end of the array.
       
  8037  */
       
  8038 XMLPUBFUNEXPORT void
       
  8039 xmlBufferWriteChar(xmlBufferPtr buf, const char* string)
       
  8040 {
       
  8041     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
       
  8042         return;
       
  8043     xmlBufferCCat(buf, string);
       
  8044 }
       
  8045 
       
  8046 
       
  8047 /**
       
  8048  * xmlBufferWriteQuotedString:
       
  8049  * @param buf the XML buffer output
       
  8050  * @param string the string to add
       
  8051  *
       
  8052  * routine which manage and grows an output buffer. This one writes
       
  8053  * a quoted or double quoted #xmlChar string, checking first if it holds
       
  8054  * quote or double-quotes internally
       
  8055  */
       
  8056 XMLPUBFUNEXPORT void
       
  8057 xmlBufferWriteQuotedString(xmlBufferPtr buf, const xmlChar* string)
       
  8058 {
       
  8059     const xmlChar* cur;
       
  8060     const xmlChar* base;
       
  8061 
       
  8062     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
       
  8063         return;
       
  8064     if (xmlStrchr(string, '\"')) {
       
  8065         if (xmlStrchr(string, '\'')) {
       
  8066 #ifdef DEBUG_BUFFER
       
  8067             xmlGenericError(xmlGenericErrorContext,
       
  8068  "xmlBufferWriteQuotedString: string contains quote and double-quotes !\n");
       
  8069 #endif
       
  8070             xmlBufferCCat(buf, "\"");
       
  8071             base = cur = string;
       
  8072             while(*cur != 0){
       
  8073                 if(*cur == '"'){
       
  8074                     if (base != cur)
       
  8075                         xmlBufferAdd(buf, base, cur - base);
       
  8076                     xmlBufferAdd(buf, BAD_CAST "&quot;", 6);
       
  8077                     cur++;
       
  8078                     base = cur;
       
  8079                 } else {
       
  8080                     cur++;
       
  8081                 }
       
  8082             }
       
  8083             if (base != cur)
       
  8084                 xmlBufferAdd(buf, base, cur - base);
       
  8085             xmlBufferCCat(buf, "\"");
       
  8086 
       
  8087         } else {
       
  8088             xmlBufferCCat(buf, "\'");
       
  8089             xmlBufferCat(buf, string);
       
  8090             xmlBufferCCat(buf, "\'");
       
  8091         }
       
  8092     } else {
       
  8093         xmlBufferCCat(buf, "\"");
       
  8094         xmlBufferCat(buf, string);
       
  8095         xmlBufferCCat(buf, "\"");
       
  8096     }
       
  8097 }
       
  8098 
       
  8099 /**
       
  8100  * xmlSetDocCompressMode:
       
  8101  * @param doc the document
       
  8102  * @param mode the compression ratio
       
  8103  *
       
  8104  * set the compression ratio for a document, ZLIB based
       
  8105  * Correct values: 0 (uncompressed) to 9 (max compression)
       
  8106  */
       
  8107 XMLPUBFUNEXPORT void
       
  8108 xmlSetDocCompressMode (xmlDocPtr doc, int mode)
       
  8109 {
       
  8110     if (!doc)
       
  8111         return;
       
  8112     if (mode < 0)
       
  8113         doc->compression = 0;
       
  8114     else
       
  8115         if (mode > 9)
       
  8116             doc->compression = 9;
       
  8117         else
       
  8118             doc->compression = mode;
       
  8119 }
       
  8120 
       
  8121 #ifndef XMLENGINE_EXCLUDE_UNUSED
       
  8122 /**
       
  8123  * xmlGetDocCompressMode:
       
  8124  * @param doc the document
       
  8125  *
       
  8126  * get the compression ratio for a document, ZLIB based
       
  8127  * Returns 0 (uncompressed) to 9 (max compression)
       
  8128  */
       
  8129 int
       
  8130 xmlGetDocCompressMode (xmlDocPtr doc)
       
  8131 {
       
  8132     if (!doc)
       
  8133         return(-1);
       
  8134     return(doc->compression);
       
  8135 }
       
  8136 
       
  8137 /**
       
  8138  * xmlGetCompressMode:
       
  8139  *
       
  8140  * get the default compression mode used, ZLIB based.
       
  8141  * Returns 0 (uncompressed) to 9 (max compression)
       
  8142  */
       
  8143 int
       
  8144 xmlGetCompressMode(void)
       
  8145 {
       
  8146     return (xmlCompressMode);
       
  8147 }
       
  8148 
       
  8149 /**
       
  8150  * xmlSetCompressMode:
       
  8151  * @param mode the compression ratio
       
  8152  *
       
  8153  * set the default compression mode used, ZLIB based
       
  8154  * Correct values: 0 (uncompressed) to 9 (max compression)
       
  8155  */
       
  8156 void
       
  8157 xmlSetCompressMode(int mode)
       
  8158 {
       
  8159     if (mode < 0)
       
  8160         xmlCompressMode = 0;
       
  8161     else if (mode > 9)
       
  8162         xmlCompressMode = 9;
       
  8163     else
       
  8164         xmlCompressMode = mode;
       
  8165 }
       
  8166 #endif /* ifndef XMLENGINE_EXCLUDE_UNUSED */
       
  8167 
       
  8168 /**
       
  8169  * Appends data container pointer to the list
       
  8170  *
       
  8171  */	
       
  8172 XMLPUBFUNEXPORT int 
       
  8173 xmlAppendDataList(xmlNodePtr node, xmlDocPtr doc)
       
  8174 {
       
  8175 	int max; 
       
  8176 	int i =0;
       
  8177 	int k = 0;
       
  8178 	const int factor = 2;	
       
  8179 	xmlNodePtr* tmp;
       
  8180 	
       
  8181 	if(!doc)
       
  8182 		return -1;
       
  8183 	
       
  8184 	max = doc->dataNodeMax;
       
  8185 	
       
  8186 	while( doc->dataNodeList[i] && i < max )
       
  8187 		{
       
  8188 		if(doc->dataNodeList[i] == node){
       
  8189 			return -1;
       
  8190 			}
       
  8191 		++i;		
       
  8192 		}	
       
  8193 	if( i >= max - 1) //leave out one space for NULL at the end of array
       
  8194 		{
       
  8195 		doc->dataNodeMax = max * factor;
       
  8196 		tmp = (xmlNodePtr*) xmlRealloc(doc->dataNodeList, doc->dataNodeMax * sizeof(xmlNodePtr));
       
  8197 		if(!tmp)
       
  8198 			{
       
  8199 			return -1;
       
  8200 			}
       
  8201 		doc->dataNodeList = tmp;
       
  8202 		for(k = i; k < doc->dataNodeMax; k++)
       
  8203 			{
       
  8204 			doc->dataNodeList[k] = NULL;
       
  8205 			}
       
  8206 		}
       
  8207 	doc->dataNodeList[i] = node;
       
  8208 	return 0;	
       
  8209 }
       
  8210 /**
       
  8211  * Removes data container from the list
       
  8212  *
       
  8213  */
       
  8214 int  
       
  8215 xmlRemoveFromDataList(xmlNodePtr node, xmlDocPtr doc)
       
  8216 {
       
  8217 	int i = 0;
       
  8218 	int j = 0;
       
  8219 	int size = 0;
       
  8220 	int ret = -1; //not found
       
  8221 		
       
  8222 	if(!doc)
       
  8223 		return 0;
       
  8224 	
       
  8225 	while( doc->dataNodeList[i] != NULL)
       
  8226 		{		
       
  8227 		if(doc->dataNodeList[i] == node)
       
  8228 			{
       
  8229 			j = i;
       
  8230 			while( doc->dataNodeList[j] != NULL )
       
  8231 				{
       
  8232 				doc->dataNodeList[j] = doc->dataNodeList[j + 1];
       
  8233 				++j;
       
  8234 				}
       
  8235 			ret = 0;
       
  8236 			}
       
  8237 		else
       
  8238 			{
       
  8239 			++i;	
       
  8240 			}
       
  8241 		}
       
  8242 	return ret;	
       
  8243 }
       
  8244 /**
       
  8245  * If found, replaces data container in the list with the new one
       
  8246  *
       
  8247  */
       
  8248 int  
       
  8249 xmlReplaceInDataList(xmlNodePtr old, xmlNodePtr cur, xmlDocPtr doc)
       
  8250 {
       
  8251 	int i = 0;
       
  8252 		
       
  8253 	if(!doc)
       
  8254 		return 0;
       
  8255 	
       
  8256 	while( doc->dataNodeList[i] != NULL)
       
  8257 		{		
       
  8258 		if(doc->dataNodeList[i] == old)
       
  8259 			{
       
  8260 			doc->dataNodeList[i] = cur;
       
  8261 			return 0;
       
  8262 			}
       
  8263 		++i;	
       
  8264 		}
       
  8265 	return -1;	
       
  8266 }