Annotation of XML/entities.c, revision 1.54

1.1       httpng      1: /*
                      2:  * entities.c : implementation for the XML entities handking
1.9       veillard    3:  *
                      4:  * See Copyright for the status of this software.
                      5:  *
1.23      daniel      6:  * Daniel.Veillard@w3.org
1.1       httpng      7:  */
                      8: 
1.42      daniel      9: #ifdef WIN32
                     10: #include "win32config.h"
                     11: #else
1.37      daniel     12: #include "config.h"
                     13: #endif
                     14: 
1.1       httpng     15: #include <stdio.h>
1.37      daniel     16: #include <string.h>
                     17: #ifdef HAVE_STDLIB_H
1.17      daniel     18: #include <stdlib.h>
1.37      daniel     19: #endif
1.36      daniel     20: #include "xmlmemory.h"
1.1       httpng     21: #include "entities.h"
1.41      daniel     22: #include "parser.h"
1.1       httpng     23: 
1.54    ! daniel     24: #define DEBUG_ENT_REF /* debugging of cross entities dependancies */
        !            25: 
1.1       httpng     26: /*
1.15      daniel     27:  * The XML predefined entities.
                     28:  */
                     29: 
                     30: struct xmlPredefinedEntityValue {
                     31:     const char *name;
                     32:     const char *value;
                     33: };
                     34: struct xmlPredefinedEntityValue xmlPredefinedEntityValues[] = {
                     35:     { "lt", "<" },
                     36:     { "gt", ">" },
                     37:     { "apos", "'" },
                     38:     { "quot", "\"" },
                     39:     { "amp", "&" }
                     40: };
                     41: 
                     42: xmlEntitiesTablePtr xmlPredefinedEntities = NULL;
                     43: 
                     44: /*
1.2       httpng     45:  * xmlFreeEntity : clean-up an entity record.
1.1       httpng     46:  */
1.2       httpng     47: void xmlFreeEntity(xmlEntityPtr entity) {
                     48:     if (entity == NULL) return;
                     49: 
1.52      daniel     50:     if (entity->children)
                     51:        xmlFreeNodeList(entity->children);
1.11      daniel     52:     if (entity->name != NULL)
1.36      daniel     53:        xmlFree((char *) entity->name);
1.14      daniel     54:     if (entity->ExternalID != NULL)
1.36      daniel     55:         xmlFree((char *) entity->ExternalID);
1.14      daniel     56:     if (entity->SystemID != NULL)
1.36      daniel     57:         xmlFree((char *) entity->SystemID);
1.14      daniel     58:     if (entity->content != NULL)
1.36      daniel     59:         xmlFree((char *) entity->content);
1.27      daniel     60:     if (entity->orig != NULL)
1.36      daniel     61:         xmlFree((char *) entity->orig);
1.54    ! daniel     62:     if (entity->entTab != NULL) {
        !            63:        int i;
        !            64: 
        !            65:        for (i = 0; i < entity->entNr; i++)
        !            66:            xmlFree(entity->entTab[i]);
        !            67:        xmlFree(entity->entTab);
        !            68:     }
1.14      daniel     69:     memset(entity, -1, sizeof(xmlEntity));
1.51      daniel     70:     xmlFree(entity);
1.2       httpng     71: }
1.1       httpng     72: 
                     73: /*
1.22      daniel     74:  * xmlAddEntity : register a new entity for an entities table.
1.1       httpng     75:  */
1.51      daniel     76: static xmlEntityPtr
1.38      daniel     77: xmlAddEntity(xmlEntitiesTablePtr table, const xmlChar *name, int type,
                     78:          const xmlChar *ExternalID, const xmlChar *SystemID, const xmlChar *content) {
1.2       httpng     79:     int i;
1.51      daniel     80:     xmlEntityPtr ret;
1.1       httpng     81: 
1.2       httpng     82:     for (i = 0;i < table->nb_entities;i++) {
1.51      daniel     83:         ret = table->table[i];
                     84:        if (!xmlStrcmp(ret->name, name)) {
1.13      daniel     85:            /*
                     86:             * The entity is already defined in this Dtd, the spec says to NOT
                     87:             * override it ... Is it worth a Warning ??? !!!
1.33      daniel     88:             * Not having a cprinting context this seems hard ...
1.13      daniel     89:             */
1.30      daniel     90:            if (((type == XML_INTERNAL_PARAMETER_ENTITY) ||
                     91:                 (type == XML_EXTERNAL_PARAMETER_ENTITY)) &&
1.51      daniel     92:                ((ret->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
                     93:                 (ret->etype == XML_EXTERNAL_PARAMETER_ENTITY)))
                     94:                return(NULL);
1.30      daniel     95:            else
                     96:            if (((type != XML_INTERNAL_PARAMETER_ENTITY) &&
                     97:                 (type != XML_EXTERNAL_PARAMETER_ENTITY)) &&
1.51      daniel     98:                ((ret->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
                     99:                 (ret->etype != XML_EXTERNAL_PARAMETER_ENTITY)))
                    100:                return(NULL);
1.7       veillard  101:        }
1.2       httpng    102:     }
                    103:     if (table->nb_entities >= table->max_entities) {
                    104:         /*
                    105:         * need more elements.
                    106:         */
                    107:        table->max_entities *= 2;
1.51      daniel    108:        table->table = (xmlEntityPtr *) 
                    109:            xmlRealloc(table->table,
                    110:                       table->max_entities * sizeof(xmlEntityPtr));
1.29      daniel    111:        if (table->table == NULL) {
1.2       httpng    112:            perror("realloc failed");
1.51      daniel    113:            return(NULL);
1.2       httpng    114:        }
                    115:     }
1.51      daniel    116:     ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
                    117:     if (ret == NULL) {
                    118:        fprintf(stderr, "xmlAddEntity: out of memory\n");
                    119:        return(NULL);
                    120:     }
                    121:     memset(ret, 0, sizeof(xmlEntity));
                    122:     ret->type = XML_ENTITY_DECL;
                    123:     table->table[table->nb_entities] = ret;
                    124: 
                    125:     /*
                    126:      * fill the structure.
                    127:      */
                    128:     ret->name = xmlStrdup(name);
                    129:     ret->etype = type;
1.13      daniel    130:     if (ExternalID != NULL)
1.51      daniel    131:        ret->ExternalID = xmlStrdup(ExternalID);
1.13      daniel    132:     if (SystemID != NULL)
1.51      daniel    133:        ret->SystemID = xmlStrdup(SystemID);
1.43      daniel    134:     if (content != NULL) {
1.51      daniel    135:         ret->length = xmlStrlen(content);
                    136:        ret->content = xmlStrndup(content, ret->length);
1.43      daniel    137:      } else {
1.51      daniel    138:         ret->length = 0;
                    139:         ret->content = NULL;
1.43      daniel    140:     }
1.51      daniel    141:     ret->orig = NULL;
1.2       httpng    142:     table->nb_entities++;
1.51      daniel    143: 
                    144:     return(ret);
1.2       httpng    145: }
1.1       httpng    146: 
1.22      daniel    147: /**
                    148:  * xmlInitializePredefinedEntities:
                    149:  *
                    150:  * Set up the predefined entities.
1.15      daniel    151:  */
                    152: void xmlInitializePredefinedEntities(void) {
                    153:     int i;
1.38      daniel    154:     xmlChar name[50];
                    155:     xmlChar value[50];
1.15      daniel    156:     const char *in;
1.38      daniel    157:     xmlChar *out;
1.15      daniel    158: 
                    159:     if (xmlPredefinedEntities != NULL) return;
                    160: 
                    161:     xmlPredefinedEntities = xmlCreateEntitiesTable();
                    162:     for (i = 0;i < sizeof(xmlPredefinedEntityValues) / 
                    163:                    sizeof(xmlPredefinedEntityValues[0]);i++) {
                    164:         in = xmlPredefinedEntityValues[i].name;
                    165:        out = &name[0];
1.38      daniel    166:        for (;(*out++ = (xmlChar) *in);)in++;
1.15      daniel    167:         in = xmlPredefinedEntityValues[i].value;
                    168:        out = &value[0];
1.38      daniel    169:        for (;(*out++ = (xmlChar) *in);)in++;
                    170:         xmlAddEntity(xmlPredefinedEntities, (const xmlChar *) &name[0],
1.18      daniel    171:                     XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL,
1.15      daniel    172:                     &value[0]);
                    173:     }
                    174: }
1.17      daniel    175: 
                    176: /**
1.40      daniel    177:  * xmlCleanupPredefinedEntities:
                    178:  *
                    179:  * Cleanup up the predefined entities table.
                    180:  */
                    181: void xmlCleanupPredefinedEntities(void) {
                    182:     if (xmlPredefinedEntities == NULL) return;
                    183: 
                    184:     xmlFreeEntitiesTable(xmlPredefinedEntities);
                    185:     xmlPredefinedEntities = NULL;
                    186: }
                    187: 
                    188: /**
1.17      daniel    189:  * xmlGetPredefinedEntity:
                    190:  * @name:  the entity name
                    191:  *
                    192:  * Check whether this name is an predefined entity.
                    193:  *
1.24      daniel    194:  * Returns NULL if not, othervise the entity
1.17      daniel    195:  */
                    196: xmlEntityPtr
1.38      daniel    197: xmlGetPredefinedEntity(const xmlChar *name) {
1.17      daniel    198:     int i;
                    199:     xmlEntityPtr cur;
                    200: 
                    201:     if (xmlPredefinedEntities == NULL)
                    202:         xmlInitializePredefinedEntities();
                    203:     for (i = 0;i < xmlPredefinedEntities->nb_entities;i++) {
1.51      daniel    204:        cur = xmlPredefinedEntities->table[i];
1.17      daniel    205:        if (!xmlStrcmp(cur->name, name)) return(cur);
                    206:     }
                    207:     return(NULL);
                    208: }
                    209: 
1.22      daniel    210: /**
                    211:  * xmlAddDtdEntity:
                    212:  * @doc:  the document
                    213:  * @name:  the entity name
                    214:  * @type:  the entity type XML_xxx_yyy_ENTITY
                    215:  * @ExternalID:  the entity external ID if available
                    216:  * @SystemID:  the entity system ID if available
                    217:  * @content:  the entity content
                    218:  *
1.51      daniel    219:  * Register a new entity for this document DTD external subset.
                    220:  *
                    221:  * Returns a pointer to the entity or NULL in case of error
1.1       httpng    222:  */
1.51      daniel    223: xmlEntityPtr
1.38      daniel    224: xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type,
1.51      daniel    225:                const xmlChar *ExternalID, const xmlChar *SystemID,
                    226:                const xmlChar *content) {
1.2       httpng    227:     xmlEntitiesTablePtr table;
1.51      daniel    228:     xmlEntityPtr ret;
                    229:     xmlDtdPtr dtd;
1.1       httpng    230: 
1.51      daniel    231:     if (doc == NULL) {
                    232:         fprintf(stderr,
                    233:                "xmlAddDtdEntity: doc == NULL !\n");
                    234:        return(NULL);
                    235:     }
1.22      daniel    236:     if (doc->extSubset == NULL) {
                    237:         fprintf(stderr,
                    238:                "xmlAddDtdEntity: document without external subset !\n");
1.51      daniel    239:        return(NULL);
1.16      daniel    240:     }
1.51      daniel    241:     dtd = doc->extSubset;
                    242:     table = (xmlEntitiesTablePtr) dtd->entities;
1.2       httpng    243:     if (table == NULL) {
                    244:         table = xmlCreateEntitiesTable();
1.51      daniel    245:        dtd->entities = table;
1.1       httpng    246:     }
1.51      daniel    247:     ret = xmlAddEntity(table, name, type, ExternalID, SystemID, content);
                    248:     if (ret == NULL) return(NULL);
                    249: 
                    250:     /*
                    251:      * Link it to the Dtd
                    252:      */
                    253:     ret->parent = dtd;
                    254:     ret->doc = dtd->doc;
                    255:     if (dtd->last == NULL) {
                    256:        dtd->children = dtd->last = (xmlNodePtr) ret;
                    257:     } else {
                    258:         dtd->last->next = (xmlNodePtr) ret;
                    259:        ret->prev = dtd->last;
                    260:        dtd->last = (xmlNodePtr) ret;
                    261:     }
                    262:     return(ret);
1.1       httpng    263: }
                    264: 
1.22      daniel    265: /**
                    266:  * xmlAddDocEntity:
                    267:  * @doc:  the document
                    268:  * @name:  the entity name
                    269:  * @type:  the entity type XML_xxx_yyy_ENTITY
                    270:  * @ExternalID:  the entity external ID if available
                    271:  * @SystemID:  the entity system ID if available
                    272:  * @content:  the entity content
                    273:  *
                    274:  * Register a new entity for this document.
1.51      daniel    275:  *
                    276:  * Returns a pointer to the entity or NULL in case of error
1.1       httpng    277:  */
1.51      daniel    278: xmlEntityPtr
1.38      daniel    279: xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type,
1.51      daniel    280:                const xmlChar *ExternalID, const xmlChar *SystemID,
                    281:                const xmlChar *content) {
1.16      daniel    282:     xmlEntitiesTablePtr table;
1.51      daniel    283:     xmlEntityPtr ret;
                    284:     xmlDtdPtr dtd;
1.16      daniel    285: 
1.22      daniel    286:     if (doc == NULL) {
                    287:         fprintf(stderr,
                    288:                "xmlAddDocEntity: document is NULL !\n");
1.51      daniel    289:        return(NULL);
1.22      daniel    290:     }
                    291:     if (doc->intSubset == NULL) {
                    292:         fprintf(stderr,
                    293:                "xmlAddDtdEntity: document without internal subset !\n");
1.51      daniel    294:        return(NULL);
1.22      daniel    295:     }
1.51      daniel    296:     dtd = doc->intSubset;
1.22      daniel    297:     table = (xmlEntitiesTablePtr) doc->intSubset->entities;
1.16      daniel    298:     if (table == NULL) {
                    299:         table = xmlCreateEntitiesTable();
1.22      daniel    300:        doc->intSubset->entities = table;
1.2       httpng    301:     }
1.51      daniel    302:     ret = xmlAddEntity(table, name, type, ExternalID, SystemID, content);
                    303:     if (ret == NULL) return(NULL);
                    304: 
                    305:     /*
                    306:      * Link it to the Dtd
                    307:      */
                    308:     ret->parent = dtd;
                    309:     ret->doc = dtd->doc;
                    310:     if (dtd->last == NULL) {
                    311:        dtd->children = dtd->last = (xmlNodePtr) ret;
                    312:     } else {
                    313:        dtd->last->next = (xmlNodePtr) ret;
                    314:        ret->prev = dtd->last;
                    315:        dtd->last = (xmlNodePtr) ret;
                    316:     }
                    317:     return(ret);
1.54    ! daniel    318: }
        !           319: 
        !           320: /**
        !           321:  * xmlEntityCheckReference:
        !           322:  * @ent:  an existing entity
        !           323:  * @to:  the entity name it's referencing
        !           324:  *
        !           325:  * Function to keep track of references and detect cycles (well formedness 
        !           326:  * errors !).
        !           327:  *
        !           328:  * Returns: 0 if Okay, -1 in case of general error, 1 in case of loop 
        !           329:  *      detection.
        !           330:  */
        !           331: int
        !           332: xmlEntityCheckReference(xmlEntityPtr ent, const xmlChar *to) {
        !           333:     int i;
        !           334:     xmlDocPtr doc;
        !           335: 
        !           336:     if (ent == NULL) return(-1);
        !           337:     if (to == NULL) return(-1);
        !           338: 
        !           339:     doc = ent->doc;
        !           340:     if (doc == NULL) return(-1);
        !           341: 
        !           342: #ifdef DEBUG_ENT_REF
        !           343:     printf("xmlEntityCheckReference(%s to %s)\n", ent->name, to);
        !           344: #endif
        !           345: 
        !           346: 
        !           347:     /*
        !           348:      * Do a recursive checking
        !           349:      */
        !           350:     for (i = 0;i < ent->entNr;i++) {
        !           351:        xmlEntityPtr indir = NULL;
        !           352: 
        !           353:        if (!xmlStrcmp(to, ent->entTab[i]))
        !           354:            return(1);
        !           355: 
        !           356:        switch (ent->etype) {
        !           357:             case XML_INTERNAL_GENERAL_ENTITY:
        !           358:             case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
        !           359:                indir = xmlGetDocEntity(doc, ent->entTab[i]);
        !           360:                break;
        !           361:             case XML_INTERNAL_PARAMETER_ENTITY:
        !           362:             case XML_EXTERNAL_PARAMETER_ENTITY:
        !           363:                indir = xmlGetDtdEntity(doc, ent->entTab[i]);
        !           364:                break;
        !           365:             case XML_INTERNAL_PREDEFINED_ENTITY:
        !           366:             case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
        !           367:                break;
        !           368:        }
        !           369:        if (xmlEntityCheckReference(indir, to) == 1)
        !           370:            return(1);
        !           371:     }
        !           372:     return(0);
        !           373: }
        !           374: 
        !           375: /**
        !           376:  * xmlEntityAddReference:
        !           377:  * @ent:  an existing entity
        !           378:  * @to:  the entity name it's referencing
        !           379:  *
        !           380:  * Function to register reuse of an existing entity from a (new) one
        !           381:  * Used to keep track of references and detect cycles (well formedness 
        !           382:  * errors !).
        !           383:  *
        !           384:  * Returns: 0 if Okay, -1 in case of general error, 1 in case of loop 
        !           385:  *      detection.
        !           386:  */
        !           387: int
        !           388: xmlEntityAddReference(xmlEntityPtr ent, const xmlChar *to) {
        !           389:     int i;
        !           390:     xmlDocPtr doc;
        !           391:     xmlEntityPtr indir = NULL;
        !           392: 
        !           393:     if (ent == NULL) return(-1);
        !           394:     if (to == NULL) return(-1);
        !           395: 
        !           396:     doc = ent->doc;
        !           397:     if (doc == NULL) return(-1);
        !           398: 
        !           399: #ifdef DEBUG_ENT_REF
        !           400:     printf("xmlEntityAddReference(%s to %s)\n", ent->name, to);
        !           401: #endif
        !           402:     if (ent->entTab == NULL) {
        !           403:        ent->entNr = 0;
        !           404:        ent->entMax = 5;
        !           405:        ent->entTab = (xmlChar **) xmlMalloc(ent->entMax * sizeof(xmlChar *));
        !           406:        if (ent->entTab == NULL) {
        !           407:            fprintf(stderr, "xmlEntityAddReference: out of memory !\n");
        !           408:            return(-1);
        !           409:        }
        !           410:     }
        !           411: 
        !           412:     for (i = 0;i < ent->entNr;i++) {
        !           413:        if (!xmlStrcmp(to, ent->entTab[i]))
        !           414:            return(0);
        !           415:     }
        !           416: 
        !           417:     /*
        !           418:      * Do a recursive checking
        !           419:      */
        !           420: 
        !           421:     switch (ent->etype) {
        !           422:        case XML_INTERNAL_GENERAL_ENTITY:
        !           423:        case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
        !           424:            indir = xmlGetDocEntity(doc, to);
        !           425:            break;
        !           426:        case XML_INTERNAL_PARAMETER_ENTITY:
        !           427:        case XML_EXTERNAL_PARAMETER_ENTITY:
        !           428:            indir = xmlGetDtdEntity(doc, to);
        !           429:            break;
        !           430:        case XML_INTERNAL_PREDEFINED_ENTITY:
        !           431:        case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
        !           432:            break;
        !           433:     }
        !           434:     if ((indir != NULL) &&
        !           435:        (xmlEntityCheckReference(indir, ent->name) == 1))
        !           436:        return(1);
        !           437: 
        !           438:     /*
        !           439:      * Add this to the list
        !           440:      */
        !           441:     if (ent->entMax <= ent->entNr) {
        !           442:        ent->entMax *= 2;
        !           443:        ent->entTab = (xmlChar **) xmlRealloc(ent->entTab,
        !           444:                                              ent->entMax * sizeof(xmlChar *));
        !           445:        if (ent->entTab == NULL) {
        !           446:            fprintf(stderr, "xmlEntityAddReference: out of memory !\n");
        !           447:            return(-1);
        !           448:        }
        !           449:     }
        !           450:     ent->entTab[ent->entNr++] = xmlStrdup(to);
        !           451:     return(0);
1.1       httpng    452: }
                    453: 
1.22      daniel    454: /**
1.30      daniel    455:  * xmlGetParameterEntity:
                    456:  * @doc:  the document referencing the entity
                    457:  * @name:  the entity name
                    458:  *
                    459:  * Do an entity lookup in the internal and external subsets and
                    460:  * returns the corresponding parameter entity, if found.
                    461:  * 
                    462:  * Returns A pointer to the entity structure or NULL if not found.
                    463:  */
                    464: xmlEntityPtr
1.38      daniel    465: xmlGetParameterEntity(xmlDocPtr doc, const xmlChar *name) {
1.30      daniel    466:     int i;
                    467:     xmlEntityPtr cur;
                    468:     xmlEntitiesTablePtr table;
                    469: 
                    470:     if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
                    471:        table = (xmlEntitiesTablePtr) doc->intSubset->entities;
                    472:        for (i = 0;i < table->nb_entities;i++) {
1.51      daniel    473:            cur = table->table[i];
1.49      daniel    474:            if (((cur->etype ==  XML_INTERNAL_PARAMETER_ENTITY) ||
                    475:                 (cur->etype ==  XML_EXTERNAL_PARAMETER_ENTITY)) &&
1.30      daniel    476:                (!xmlStrcmp(cur->name, name))) return(cur);
                    477:        }
                    478:     }
                    479:     if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
                    480:        table = (xmlEntitiesTablePtr) doc->extSubset->entities;
                    481:        for (i = 0;i < table->nb_entities;i++) {
1.51      daniel    482:            cur = table->table[i];
1.49      daniel    483:            if (((cur->etype ==  XML_INTERNAL_PARAMETER_ENTITY) ||
                    484:                 (cur->etype ==  XML_EXTERNAL_PARAMETER_ENTITY)) &&
1.30      daniel    485:                (!xmlStrcmp(cur->name, name))) return(cur);
                    486:        }
                    487:     }
1.35      daniel    488:     if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
                    489:        table = (xmlEntitiesTablePtr) doc->extSubset->entities;
                    490:        for (i = 0;i < table->nb_entities;i++) {
1.51      daniel    491:            cur = table->table[i];
1.49      daniel    492:            if (((cur->etype ==  XML_INTERNAL_PARAMETER_ENTITY) ||
                    493:                 (cur->etype ==  XML_EXTERNAL_PARAMETER_ENTITY)) &&
1.35      daniel    494:                (!xmlStrcmp(cur->name, name))) return(cur);
                    495:        }
                    496:     }
1.30      daniel    497:     return(NULL);
                    498: }
                    499: 
                    500: /**
1.22      daniel    501:  * xmlGetDtdEntity:
                    502:  * @doc:  the document referencing the entity
                    503:  * @name:  the entity name
                    504:  *
                    505:  * Do an entity lookup in the Dtd entity hash table and
                    506:  * returns the corresponding entity, if found.
                    507:  * 
1.24      daniel    508:  * Returns A pointer to the entity structure or NULL if not found.
1.1       httpng    509:  */
1.22      daniel    510: xmlEntityPtr
1.38      daniel    511: xmlGetDtdEntity(xmlDocPtr doc, const xmlChar *name) {
1.2       httpng    512:     int i;
                    513:     xmlEntityPtr cur;
                    514:     xmlEntitiesTablePtr table;
                    515: 
1.22      daniel    516:     if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
                    517:        table = (xmlEntitiesTablePtr) doc->extSubset->entities;
1.15      daniel    518:        for (i = 0;i < table->nb_entities;i++) {
1.51      daniel    519:            cur = table->table[i];
1.49      daniel    520:            if ((cur->etype !=  XML_INTERNAL_PARAMETER_ENTITY) &&
                    521:                (cur->etype !=  XML_EXTERNAL_PARAMETER_ENTITY) &&
1.30      daniel    522:                (!xmlStrcmp(cur->name, name))) return(cur);
1.15      daniel    523:        }
                    524:     }
1.7       veillard  525:     return(NULL);
1.3       httpng    526: }
                    527: 
1.22      daniel    528: /**
                    529:  * xmlGetDocEntity:
                    530:  * @doc:  the document referencing the entity
                    531:  * @name:  the entity name
                    532:  *
                    533:  * Do an entity lookup in the document entity hash table and
                    534:  * returns the corrsponding entity, otherwise a lookup is done
                    535:  * in the predefined entities too.
                    536:  * 
1.24      daniel    537:  * Returns A pointer to the entity structure or NULL if not found.
1.14      daniel    538:  */
1.22      daniel    539: xmlEntityPtr
1.38      daniel    540: xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) {
1.14      daniel    541:     int i;
1.16      daniel    542:     xmlEntityPtr cur;
1.14      daniel    543:     xmlEntitiesTablePtr table;
                    544: 
1.22      daniel    545:     if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
                    546:        table = (xmlEntitiesTablePtr) doc->intSubset->entities;
1.16      daniel    547:        for (i = 0;i < table->nb_entities;i++) {
1.51      daniel    548:            cur = table->table[i];
1.49      daniel    549:            if ((cur->etype !=  XML_INTERNAL_PARAMETER_ENTITY) &&
                    550:                (cur->etype !=  XML_EXTERNAL_PARAMETER_ENTITY) &&
1.30      daniel    551:                (!xmlStrcmp(cur->name, name))) return(cur);
1.16      daniel    552:        }
                    553:     }
1.34      daniel    554:     if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
                    555:        table = (xmlEntitiesTablePtr) doc->extSubset->entities;
                    556:        for (i = 0;i < table->nb_entities;i++) {
1.51      daniel    557:            cur = table->table[i];
1.49      daniel    558:            if ((cur->etype !=  XML_INTERNAL_PARAMETER_ENTITY) &&
                    559:                (cur->etype !=  XML_EXTERNAL_PARAMETER_ENTITY) &&
1.34      daniel    560:                (!xmlStrcmp(cur->name, name))) return(cur);
                    561:        }
                    562:     }
1.15      daniel    563:     if (xmlPredefinedEntities == NULL)
                    564:         xmlInitializePredefinedEntities();
1.16      daniel    565:     table = xmlPredefinedEntities;
                    566:     for (i = 0;i < table->nb_entities;i++) {
1.51      daniel    567:        cur = table->table[i];
1.49      daniel    568:        if ((cur->etype !=  XML_INTERNAL_PARAMETER_ENTITY) &&
                    569:            (cur->etype !=  XML_EXTERNAL_PARAMETER_ENTITY) &&
1.30      daniel    570:            (!xmlStrcmp(cur->name, name))) return(cur);
1.14      daniel    571:     }
                    572: 
                    573:     return(NULL);
1.1       httpng    574: }
                    575: 
                    576: /*
1.21      daniel    577:  * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
                    578:  *                  | [#x10000-#x10FFFF]
                    579:  * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
                    580:  */
                    581: #define IS_CHAR(c)                                                     \
                    582:     (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) ||                        \
                    583:      (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
                    584: 
1.28      daniel    585: /*
                    586:  * A buffer used for converting entities to their equivalent and back.
                    587:  */
                    588: static int buffer_size = 0;
1.38      daniel    589: static xmlChar *buffer = NULL;
1.28      daniel    590: 
1.44      daniel    591: int growBuffer(void) {
1.28      daniel    592:     buffer_size *= 2;
1.38      daniel    593:     buffer = (xmlChar *) xmlRealloc(buffer, buffer_size * sizeof(xmlChar));
1.28      daniel    594:     if (buffer == NULL) {
                    595:         perror("realloc failed");
1.44      daniel    596:        return(-1);
1.28      daniel    597:     }
1.44      daniel    598:     return(0);
1.28      daniel    599: }
                    600: 
                    601: 
1.22      daniel    602: /**
                    603:  * xmlEncodeEntities:
                    604:  * @doc:  the document containing the string
                    605:  * @input:  A string to convert to XML.
                    606:  *
                    607:  * Do a global encoding of a string, replacing the predefined entities
                    608:  * and non ASCII values with their entities and CharRef counterparts.
                    609:  *
1.33      daniel    610:  * TODO: remove xmlEncodeEntities, once we are not afraid of breaking binary
                    611:  *       compatibility
1.28      daniel    612:  *
                    613:  * People must migrate their code to xmlEncodeEntitiesReentrant !
1.31      daniel    614:  * This routine will issue a warning when encountered.
1.28      daniel    615:  * 
                    616:  * Returns A newly allocated string with the substitution done.
                    617:  */
1.38      daniel    618: const xmlChar *
                    619: xmlEncodeEntities(xmlDocPtr doc, const xmlChar *input) {
                    620:     const xmlChar *cur = input;
                    621:     xmlChar *out = buffer;
1.31      daniel    622:     static int warning = 1;
1.39      daniel    623:     int html = 0;
                    624: 
1.31      daniel    625: 
                    626:     if (warning) {
                    627:     fprintf(stderr, "Deprecated API xmlEncodeEntities() used\n");
                    628:     fprintf(stderr, "   change code to use xmlEncodeEntitiesReentrant()\n");
                    629:     warning = 0;
                    630:     }
1.28      daniel    631: 
                    632:     if (input == NULL) return(NULL);
1.39      daniel    633:     if (doc != NULL)
                    634:         html = (doc->type == XML_HTML_DOCUMENT_NODE);
                    635: 
1.28      daniel    636:     if (buffer == NULL) {
                    637:         buffer_size = 1000;
1.38      daniel    638:         buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
1.28      daniel    639:        if (buffer == NULL) {
                    640:            perror("malloc failed");
1.44      daniel    641:             return(NULL);
1.28      daniel    642:        }
                    643:        out = buffer;
                    644:     }
                    645:     while (*cur != '\0') {
                    646:         if (out - buffer > buffer_size - 100) {
                    647:            int index = out - buffer;
                    648: 
                    649:            growBuffer();
                    650:            out = &buffer[index];
                    651:        }
                    652: 
                    653:        /*
                    654:         * By default one have to encode at least '<', '>', '"' and '&' !
                    655:         */
                    656:        if (*cur == '<') {
                    657:            *out++ = '&';
                    658:            *out++ = 'l';
                    659:            *out++ = 't';
                    660:            *out++ = ';';
                    661:        } else if (*cur == '>') {
                    662:            *out++ = '&';
                    663:            *out++ = 'g';
                    664:            *out++ = 't';
                    665:            *out++ = ';';
                    666:        } else if (*cur == '&') {
                    667:            *out++ = '&';
                    668:            *out++ = 'a';
                    669:            *out++ = 'm';
                    670:            *out++ = 'p';
                    671:            *out++ = ';';
                    672:        } else if (*cur == '"') {
                    673:            *out++ = '&';
                    674:            *out++ = 'q';
                    675:            *out++ = 'u';
                    676:            *out++ = 'o';
                    677:            *out++ = 't';
                    678:            *out++ = ';';
1.39      daniel    679:        } else if ((*cur == '\'') && (!html)) {
1.28      daniel    680:            *out++ = '&';
                    681:            *out++ = 'a';
                    682:            *out++ = 'p';
                    683:            *out++ = 'o';
                    684:            *out++ = 's';
                    685:            *out++ = ';';
                    686:        } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
                    687:            (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
                    688:            /*
                    689:             * default case, just copy !
                    690:             */
                    691:            *out++ = *cur;
                    692: #ifndef USE_UTF_8
1.38      daniel    693:        } else if ((sizeof(xmlChar) == 1) && (*cur >= 0x80)) {
1.28      daniel    694:            char buf[10], *ptr;
                    695: #ifdef HAVE_SNPRINTF
                    696:            snprintf(buf, 9, "&#%d;", *cur);
                    697: #else
                    698:            sprintf(buf, "&#%d;", *cur);
                    699: #endif
                    700:             ptr = buf;
                    701:            while (*ptr != 0) *out++ = *ptr++;
                    702: #endif
                    703:        } else if (IS_CHAR(*cur)) {
                    704:            char buf[10], *ptr;
                    705: 
                    706: #ifdef HAVE_SNPRINTF
                    707:            snprintf(buf, 9, "&#%d;", *cur);
                    708: #else
                    709:            sprintf(buf, "&#%d;", *cur);
                    710: #endif
                    711:             ptr = buf;
                    712:            while (*ptr != 0) *out++ = *ptr++;
                    713:        }
                    714: #if 0
                    715:        else {
                    716:            /*
                    717:             * default case, this is not a valid char !
                    718:             * Skip it...
                    719:             */
                    720:            fprintf(stderr, "xmlEncodeEntities: invalid char %d\n", (int) *cur);
                    721:        }
                    722: #endif
                    723:        cur++;
                    724:     }
                    725:     *out++ = 0;
                    726:     return(buffer);
                    727: }
                    728: 
                    729: /*
                    730:  * Macro used to grow the current buffer.
                    731:  */
                    732: #define growBufferReentrant() {                                                \
                    733:     buffer_size *= 2;                                                  \
1.44      daniel    734:     buffer = (xmlChar *)                                               \
                    735:                xmlRealloc(buffer, buffer_size * sizeof(xmlChar));      \
1.28      daniel    736:     if (buffer == NULL) {                                              \
                    737:        perror("realloc failed");                                       \
1.44      daniel    738:        return(NULL);                                                   \
1.28      daniel    739:     }                                                                  \
                    740: }
                    741: 
                    742: 
                    743: /**
                    744:  * xmlEncodeEntitiesReentrant:
                    745:  * @doc:  the document containing the string
                    746:  * @input:  A string to convert to XML.
                    747:  *
                    748:  * Do a global encoding of a string, replacing the predefined entities
                    749:  * and non ASCII values with their entities and CharRef counterparts.
                    750:  * Contrary to xmlEncodeEntities, this routine is reentrant, and result
                    751:  * must be deallocated.
                    752:  *
                    753:  * TODO !!!! Once moved to UTF-8 internal encoding, the encoding of non-ascii
                    754:  *           get erroneous.
                    755:  *
1.24      daniel    756:  * Returns A newly allocated string with the substitution done.
1.1       httpng    757:  */
1.38      daniel    758: xmlChar *
                    759: xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
                    760:     const xmlChar *cur = input;
                    761:     xmlChar *buffer = NULL;
                    762:     xmlChar *out = NULL;
1.26      daniel    763:     int buffer_size = 0;
1.39      daniel    764:     int html = 0;
1.3       httpng    765: 
1.19      daniel    766:     if (input == NULL) return(NULL);
1.39      daniel    767:     if (doc != NULL)
                    768:         html = (doc->type == XML_HTML_DOCUMENT_NODE);
1.26      daniel    769: 
                    770:     /*
                    771:      * allocate an translation buffer.
                    772:      */
                    773:     buffer_size = 1000;
1.38      daniel    774:     buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
1.3       httpng    775:     if (buffer == NULL) {
1.26      daniel    776:        perror("malloc failed");
1.44      daniel    777:        return(NULL);
1.3       httpng    778:     }
1.26      daniel    779:     out = buffer;
                    780: 
1.6       veillard  781:     while (*cur != '\0') {
                    782:         if (out - buffer > buffer_size - 100) {
                    783:            int index = out - buffer;
                    784: 
1.28      daniel    785:            growBufferReentrant();
1.6       veillard  786:            out = &buffer[index];
                    787:        }
                    788: 
                    789:        /*
1.7       veillard  790:         * By default one have to encode at least '<', '>', '"' and '&' !
1.6       veillard  791:         */
                    792:        if (*cur == '<') {
                    793:            *out++ = '&';
                    794:            *out++ = 'l';
                    795:            *out++ = 't';
                    796:            *out++ = ';';
1.7       veillard  797:        } else if (*cur == '>') {
                    798:            *out++ = '&';
                    799:            *out++ = 'g';
                    800:            *out++ = 't';
                    801:            *out++ = ';';
1.6       veillard  802:        } else if (*cur == '&') {
                    803:            *out++ = '&';
                    804:            *out++ = 'a';
                    805:            *out++ = 'm';
                    806:            *out++ = 'p';
1.7       veillard  807:            *out++ = ';';
                    808:        } else if (*cur == '"') {
                    809:            *out++ = '&';
                    810:            *out++ = 'q';
                    811:            *out++ = 'u';
                    812:            *out++ = 'o';
                    813:            *out++ = 't';
                    814:            *out++ = ';';
1.53      daniel    815: #if 0
1.39      daniel    816:        } else if ((*cur == '\'') && (!html)) {
1.7       veillard  817:            *out++ = '&';
                    818:            *out++ = 'a';
                    819:            *out++ = 'p';
                    820:            *out++ = 'o';
                    821:            *out++ = 's';
1.6       veillard  822:            *out++ = ';';
1.53      daniel    823: #endif
1.21      daniel    824:        } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
                    825:            (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
                    826:            /*
                    827:             * default case, just copy !
                    828:             */
                    829:            *out++ = *cur;
1.46      daniel    830:        } else if (*cur >= 0x80) {
                    831:            if (html) {
1.50      daniel    832:                char buf[15], *ptr;
1.46      daniel    833: 
                    834:                /*
                    835:                 * TODO: improve by searching in html40EntitiesTable
                    836:                 */
1.19      daniel    837: #ifdef HAVE_SNPRINTF
1.45      daniel    838:                snprintf(buf, 9, "&#%d;", *cur);
1.19      daniel    839: #else
1.45      daniel    840:                sprintf(buf, "&#%d;", *cur);
1.19      daniel    841: #endif
1.45      daniel    842:                ptr = buf;
                    843:                while (*ptr != 0) *out++ = *ptr++;
1.46      daniel    844:            } else if (doc->encoding != NULL) {
                    845:                /*
                    846:                 * TODO !!!
                    847:                 */
                    848:                *out++ = *cur;
                    849:            } else {
                    850:                /*
                    851:                 * We assume we have UTF-8 input.
                    852:                 */
                    853:                char buf[10], *ptr;
1.48      daniel    854:                int val = 0, l = 1;
1.46      daniel    855: 
                    856:                if (*cur < 0xC0) {
                    857:                    fprintf(stderr,
                    858:                            "xmlEncodeEntitiesReentrant : input not UTF-8\n");
                    859:                    doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
                    860: #ifdef HAVE_SNPRINTF
                    861:                    snprintf(buf, 9, "&#%d;", *cur);
                    862: #else
                    863:                    sprintf(buf, "&#%d;", *cur);
                    864: #endif
                    865:                    ptr = buf;
                    866:                    while (*ptr != 0) *out++ = *ptr++;
                    867:                    continue;
                    868:                } else if (*cur < 0xE0) {
                    869:                     val = (cur[0]) & 0x1F;
                    870:                    val <<= 6;
                    871:                    val |= (cur[1]) & 0x3F;
                    872:                    l = 2;
                    873:                } else if (*cur < 0xF0) {
                    874:                     val = (cur[0]) & 0x0F;
                    875:                    val <<= 6;
                    876:                    val |= (cur[1]) & 0x3F;
                    877:                    val <<= 6;
                    878:                    val |= (cur[2]) & 0x3F;
                    879:                    l = 3;
                    880:                } else if (*cur < 0xF8) {
                    881:                     val = (cur[0]) & 0x07;
                    882:                    val <<= 6;
                    883:                    val |= (cur[1]) & 0x3F;
                    884:                    val <<= 6;
                    885:                    val |= (cur[2]) & 0x3F;
                    886:                    val <<= 6;
                    887:                    val |= (cur[3]) & 0x3F;
                    888:                    l = 4;
                    889:                }
                    890:                if ((l == 1) || (!IS_CHAR(val))) {
                    891:                    fprintf(stderr,
                    892:                        "xmlEncodeEntitiesReentrant : char out of range\n");
                    893:                    doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
                    894: #ifdef HAVE_SNPRINTF
                    895:                    snprintf(buf, 9, "&#%d;", *cur);
                    896: #else
                    897:                    sprintf(buf, "&#%d;", *cur);
                    898: #endif
                    899:                    ptr = buf;
                    900:                    while (*ptr != 0) *out++ = *ptr++;
                    901:                    cur++;
                    902:                    continue;
                    903:                }
                    904:                /*
                    905:                 * We could do multiple things here. Just save as a char ref
                    906:                 */
                    907: #ifdef HAVE_SNPRINTF
1.50      daniel    908:                snprintf(buf, 14, "&#x%X;", val);
1.46      daniel    909: #else
1.50      daniel    910:                sprintf(buf, "&#x%X;", val);
1.46      daniel    911: #endif
1.50      daniel    912:                buf[14] = 0;
1.47      daniel    913:                ptr = buf;
                    914:                while (*ptr != 0) *out++ = *ptr++;
                    915:                cur += l;
                    916:                continue;
1.45      daniel    917:            }
1.21      daniel    918:        } else if (IS_CHAR(*cur)) {
1.20      daniel    919:            char buf[10], *ptr;
                    920: 
                    921: #ifdef HAVE_SNPRINTF
                    922:            snprintf(buf, 9, "&#%d;", *cur);
                    923: #else
                    924:            sprintf(buf, "&#%d;", *cur);
                    925: #endif
                    926:             ptr = buf;
                    927:            while (*ptr != 0) *out++ = *ptr++;
1.21      daniel    928:        }
                    929: #if 0
                    930:        else {
1.6       veillard  931:            /*
1.21      daniel    932:             * default case, this is not a valid char !
                    933:             * Skip it...
1.6       veillard  934:             */
1.21      daniel    935:            fprintf(stderr, "xmlEncodeEntities: invalid char %d\n", (int) *cur);
1.6       veillard  936:        }
1.21      daniel    937: #endif
1.6       veillard  938:        cur++;
                    939:     }
                    940:     *out++ = 0;
                    941:     return(buffer);
1.2       httpng    942: }
                    943: 
1.22      daniel    944: /**
                    945:  * xmlCreateEntitiesTable:
                    946:  *
                    947:  * create and initialize an empty entities hash table.
                    948:  *
1.24      daniel    949:  * Returns the xmlEntitiesTablePtr just created or NULL in case of error.
1.2       httpng    950:  */
1.22      daniel    951: xmlEntitiesTablePtr
                    952: xmlCreateEntitiesTable(void) {
1.2       httpng    953:     xmlEntitiesTablePtr ret;
1.1       httpng    954: 
1.2       httpng    955:     ret = (xmlEntitiesTablePtr) 
1.36      daniel    956:          xmlMalloc(sizeof(xmlEntitiesTable));
1.1       httpng    957:     if (ret == NULL) {
1.36      daniel    958:         fprintf(stderr, "xmlCreateEntitiesTable : xmlMalloc(%ld) failed\n",
1.28      daniel    959:                (long)sizeof(xmlEntitiesTable));
1.2       httpng    960:         return(NULL);
                    961:     }
                    962:     ret->max_entities = XML_MIN_ENTITIES_TABLE;
                    963:     ret->nb_entities = 0;
1.51      daniel    964:     ret->table = (xmlEntityPtr *) 
                    965:          xmlMalloc(ret->max_entities * sizeof(xmlEntityPtr));
1.2       httpng    966:     if (ret == NULL) {
1.36      daniel    967:         fprintf(stderr, "xmlCreateEntitiesTable : xmlMalloc(%ld) failed\n",
1.51      daniel    968:                ret->max_entities * (long)sizeof(xmlEntityPtr));
1.36      daniel    969:        xmlFree(ret);
1.1       httpng    970:         return(NULL);
                    971:     }
                    972:     return(ret);
                    973: }
                    974: 
1.22      daniel    975: /**
                    976:  * xmlFreeEntitiesTable:
                    977:  * @table:  An entity table
                    978:  *
                    979:  * Deallocate the memory used by an entities hash table.
1.1       httpng    980:  */
1.22      daniel    981: void
                    982: xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
1.1       httpng    983:     int i;
                    984: 
                    985:     if (table == NULL) return;
                    986: 
1.2       httpng    987:     for (i = 0;i < table->nb_entities;i++) {
1.51      daniel    988:         xmlFreeEntity(table->table[i]);
1.1       httpng    989:     }
1.36      daniel    990:     xmlFree(table->table);
                    991:     xmlFree(table);
1.1       httpng    992: }
                    993: 
1.22      daniel    994: /**
                    995:  * xmlCopyEntitiesTable:
                    996:  * @table:  An entity table
                    997:  *
                    998:  * Build a copy of an entity table.
                    999:  * 
1.24      daniel   1000:  * Returns the new xmlEntitiesTablePtr or NULL in case of error.
1.22      daniel   1001:  */
                   1002: xmlEntitiesTablePtr
                   1003: xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
                   1004:     xmlEntitiesTablePtr ret;
                   1005:     xmlEntityPtr cur, ent;
                   1006:     int i;
                   1007: 
1.36      daniel   1008:     ret = (xmlEntitiesTablePtr) xmlMalloc(sizeof(xmlEntitiesTable));
1.22      daniel   1009:     if (ret == NULL) {
                   1010:         fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
                   1011:        return(NULL);
                   1012:     }
1.51      daniel   1013:     ret->table = (xmlEntityPtr *) xmlMalloc(table->max_entities *
                   1014:                                             sizeof(xmlEntityPtr));
1.22      daniel   1015:     if (ret->table == NULL) {
                   1016:         fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
1.36      daniel   1017:        xmlFree(ret);
1.22      daniel   1018:        return(NULL);
                   1019:     }
                   1020:     ret->max_entities = table->max_entities;
                   1021:     ret->nb_entities = table->nb_entities;
                   1022:     for (i = 0;i < ret->nb_entities;i++) {
1.51      daniel   1023:        cur = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
                   1024:        if (cur == NULL) {
                   1025:            fprintf(stderr, "xmlCopyEntityTable: out of memory !\n");
                   1026:            xmlFree(ret);
                   1027:            xmlFree(ret->table);
                   1028:            return(NULL);
                   1029:        }
                   1030:        memset(cur, 0, sizeof(xmlEntity));
                   1031:        cur->type = XML_ELEMENT_DECL;
                   1032:        ret->table[i] = cur;
                   1033:        ent = table->table[i];
                   1034: 
1.49      daniel   1035:        cur->etype = ent->etype;
1.22      daniel   1036:        if (ent->name != NULL)
                   1037:            cur->name = xmlStrdup(ent->name);
                   1038:        if (ent->ExternalID != NULL)
                   1039:            cur->ExternalID = xmlStrdup(ent->ExternalID);
                   1040:        if (ent->SystemID != NULL)
                   1041:            cur->SystemID = xmlStrdup(ent->SystemID);
                   1042:        if (ent->content != NULL)
                   1043:            cur->content = xmlStrdup(ent->content);
1.27      daniel   1044:        if (ent->orig != NULL)
                   1045:            cur->orig = xmlStrdup(ent->orig);
1.22      daniel   1046:     }
                   1047:     return(ret);
                   1048: }
                   1049: 
                   1050: /**
1.53      daniel   1051:  * xmlDumpEntityDecl:
                   1052:  * @buf:  An XML buffer.
                   1053:  * @ent:  An entity table
                   1054:  *
                   1055:  * This will dump the content of the entity table as an XML DTD definition
                   1056:  */
                   1057: void
                   1058: xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) {
                   1059:     switch (ent->etype) {
                   1060:        case XML_INTERNAL_GENERAL_ENTITY:
                   1061:            xmlBufferWriteChar(buf, "<!ENTITY ");
                   1062:            xmlBufferWriteCHAR(buf, ent->name);
                   1063:            xmlBufferWriteChar(buf, " ");
                   1064:            if (ent->orig != NULL)
                   1065:                xmlBufferWriteQuotedString(buf, ent->orig);
                   1066:            else
                   1067:                xmlBufferWriteQuotedString(buf, ent->content);
                   1068:            xmlBufferWriteChar(buf, ">\n");
                   1069:            break;
                   1070:        case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
                   1071:            xmlBufferWriteChar(buf, "<!ENTITY ");
                   1072:            xmlBufferWriteCHAR(buf, ent->name);
                   1073:            if (ent->ExternalID != NULL) {
                   1074:                 xmlBufferWriteChar(buf, " PUBLIC ");
                   1075:                 xmlBufferWriteQuotedString(buf, ent->ExternalID);
                   1076:                 xmlBufferWriteChar(buf, " ");
                   1077:                 xmlBufferWriteQuotedString(buf, ent->SystemID);
                   1078:            } else {
                   1079:                 xmlBufferWriteChar(buf, " SYSTEM ");
                   1080:                 xmlBufferWriteQuotedString(buf, ent->SystemID);
                   1081:            }
                   1082:            xmlBufferWriteChar(buf, ">\n");
                   1083:            break;
                   1084:        case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
                   1085:            xmlBufferWriteChar(buf, "<!ENTITY ");
                   1086:            xmlBufferWriteCHAR(buf, ent->name);
                   1087:            if (ent->ExternalID != NULL) {
                   1088:                 xmlBufferWriteChar(buf, " PUBLIC ");
                   1089:                 xmlBufferWriteQuotedString(buf, ent->ExternalID);
                   1090:                 xmlBufferWriteChar(buf, " ");
                   1091:                 xmlBufferWriteQuotedString(buf, ent->SystemID);
                   1092:            } else {
                   1093:                 xmlBufferWriteChar(buf, " SYSTEM ");
                   1094:                 xmlBufferWriteQuotedString(buf, ent->SystemID);
                   1095:            }
                   1096:            if (ent->content != NULL) { /* Should be true ! */
                   1097:                xmlBufferWriteChar(buf, " NDATA ");
                   1098:                if (ent->orig != NULL)
                   1099:                    xmlBufferWriteCHAR(buf, ent->orig);
                   1100:                else
                   1101:                    xmlBufferWriteCHAR(buf, ent->content);
                   1102:            }
                   1103:            xmlBufferWriteChar(buf, ">\n");
                   1104:            break;
                   1105:        case XML_INTERNAL_PARAMETER_ENTITY:
                   1106:            xmlBufferWriteChar(buf, "<!ENTITY % ");
                   1107:            xmlBufferWriteCHAR(buf, ent->name);
                   1108:            xmlBufferWriteChar(buf, " ");
                   1109:            if (ent->orig == NULL)
                   1110:                xmlBufferWriteQuotedString(buf, ent->content);
                   1111:            else
                   1112:                xmlBufferWriteQuotedString(buf, ent->orig);
                   1113:            xmlBufferWriteChar(buf, ">\n");
                   1114:            break;
                   1115:        case XML_EXTERNAL_PARAMETER_ENTITY:
                   1116:            xmlBufferWriteChar(buf, "<!ENTITY % ");
                   1117:            xmlBufferWriteCHAR(buf, ent->name);
                   1118:            if (ent->ExternalID != NULL) {
                   1119:                 xmlBufferWriteChar(buf, " PUBLIC ");
                   1120:                 xmlBufferWriteQuotedString(buf, ent->ExternalID);
                   1121:                 xmlBufferWriteChar(buf, " ");
                   1122:                 xmlBufferWriteQuotedString(buf, ent->SystemID);
                   1123:            } else {
                   1124:                 xmlBufferWriteChar(buf, " SYSTEM ");
                   1125:                 xmlBufferWriteQuotedString(buf, ent->SystemID);
                   1126:            }
                   1127:            xmlBufferWriteChar(buf, ">\n");
                   1128:            break;
                   1129:        default:
                   1130:            fprintf(stderr,
                   1131:                "xmlDumpEntitiesTable: internal: unknown type %d\n",
                   1132:                    ent->etype);
                   1133:     }
                   1134: }
                   1135: 
                   1136: /**
1.22      daniel   1137:  * xmlDumpEntitiesTable:
1.25      daniel   1138:  * @buf:  An XML buffer.
1.22      daniel   1139:  * @table:  An entity table
                   1140:  *
                   1141:  * This will dump the content of the entity table as an XML DTD definition
1.13      daniel   1142:  */
1.22      daniel   1143: void
1.25      daniel   1144: xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
1.14      daniel   1145:     int i;
                   1146:     xmlEntityPtr cur;
                   1147: 
                   1148:     if (table == NULL) return;
                   1149: 
                   1150:     for (i = 0;i < table->nb_entities;i++) {
1.51      daniel   1151:         cur = table->table[i];
1.53      daniel   1152:        xmlDumpEntityDecl(buf, cur);
1.14      daniel   1153:     }
1.13      daniel   1154: }

Webmaster