Annotation of XML/valid.c, revision 1.6

1.1       daniel      1: /*
                      2:  * valid.c : part of the code use to do the DTD handling and the validity
                      3:  *           checking
                      4:  *
                      5:  * See Copyright for the status of this software.
                      6:  *
                      7:  * Daniel.Veillard@w3.org
                      8:  */
                      9: 
                     10: #include <stdio.h>
                     11: #include <stdlib.h>
                     12: #include <string.h>
                     13: #include "valid.h"
                     14: #include "parser.h"
                     15: 
                     16: /****************************************************************
                     17:  *                                                             *
                     18:  *     Util functions for data allocation/deallocation         *
                     19:  *                                                             *
                     20:  ****************************************************************/
                     21: 
                     22: /**
                     23:  * xmlNewElementContent:
                     24:  * @name:  the subelement name or NULL
                     25:  * @type:  the type of element content decl
                     26:  *
                     27:  * Allocate an element content structure.
                     28:  *
1.6     ! daniel     29:  * Returns NULL if not, othervise the new element content structure
1.1       daniel     30:  */
                     31: xmlElementContentPtr
                     32: xmlNewElementContent(CHAR *name, int type) {
1.2       daniel     33:     xmlElementContentPtr ret;
                     34: 
                     35:     switch(type) {
                     36:        case XML_ELEMENT_CONTENT_ELEMENT:
                     37:            if (name == NULL) {
                     38:                fprintf(stderr, "xmlNewElementContent : name == NULL !\n");
                     39:            }
                     40:            break;
                     41:         case XML_ELEMENT_CONTENT_PCDATA:
                     42:        case XML_ELEMENT_CONTENT_SEQ:
                     43:        case XML_ELEMENT_CONTENT_OR:
                     44:            if (name != NULL) {
                     45:                fprintf(stderr, "xmlNewElementContent : name != NULL !\n");
                     46:            }
                     47:            break;
                     48:        default:
                     49:            fprintf(stderr, "xmlNewElementContent: unknown type %d\n", type);
                     50:            exit(1);
                     51:     }
                     52:     ret = (xmlElementContentPtr) malloc(sizeof(xmlElementContent));
                     53:     if (ret == NULL) {
                     54:        fprintf(stderr, "xmlNewElementContent : out of memory!\n");
                     55:        return(NULL);
                     56:     }
                     57:     ret->type = type;
                     58:     ret->ocur = XML_ELEMENT_CONTENT_ONCE;
                     59:     if (name != NULL)
                     60:         ret->name = xmlStrdup(name);
                     61:     else
                     62:         ret->name = NULL;
1.4       daniel     63:     ret->c1 = ret->c2 = NULL;
1.2       daniel     64:     return(ret);
                     65: }
                     66: 
                     67: /**
                     68:  * xmlCopyElementContent:
                     69:  * @content:  An element content pointer.
                     70:  *
                     71:  * Build a copy of an element content description.
                     72:  * 
1.6     ! daniel     73:  * Returns the new xmlElementContentPtr or NULL in case of error.
1.2       daniel     74:  */
                     75: xmlElementContentPtr
1.4       daniel     76: xmlCopyElementContent(xmlElementContentPtr cur) {
                     77:     xmlElementContentPtr ret;
                     78: 
                     79:     if (cur == NULL) return(NULL);
                     80:     ret = xmlNewElementContent((CHAR *) cur->name, cur->type);
                     81:     if (cur->c1 != NULL) cur->c1 = xmlCopyElementContent(cur->c1);
                     82:     if (cur->c2 != NULL) cur->c2 = xmlCopyElementContent(cur->c2);
                     83:     return(ret);
1.1       daniel     84: }
                     85: 
                     86: /**
1.3       daniel     87:  * xmlFreeElementContent:
                     88:  * @cur:  the element content tree to free
1.1       daniel     89:  *
                     90:  * Free an element content structure. This is a recursive call !
                     91:  */
                     92: void
                     93: xmlFreeElementContent(xmlElementContentPtr cur) {
1.4       daniel     94:     if (cur == NULL) return;
                     95:     if (cur->c1 != NULL) xmlFreeElementContent(cur->c1);
                     96:     if (cur->c2 != NULL) xmlFreeElementContent(cur->c2);
                     97:     if (cur->name != NULL) free((CHAR *) cur->name);
                     98:     memset(cur, -1, sizeof(xmlElementContent));
                     99:     free(cur);
1.1       daniel    100: }
                    101: 
1.3       daniel    102: /**
                    103:  * xmlDumpElementContent:
                    104:  * @content:  An element table
                    105:  * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
                    106:  *
                    107:  * This will dump the content of the element table as an XML DTD definition
                    108:  *
                    109:  * NOTE: TODO an extra parameter allowing a reentant implementation will
                    110:  *       be added.
                    111:  */
                    112: void
                    113: xmlDumpElementContent(xmlElementContentPtr content, int glob) {
                    114:     if (content == NULL) return;
                    115: 
                    116:     if (glob) xmlBufferWriteChar("(");
                    117:     switch (content->type) {
                    118:         case XML_ELEMENT_CONTENT_PCDATA:
                    119:             xmlBufferWriteChar("#PCDATA");
                    120:            break;
                    121:        case XML_ELEMENT_CONTENT_ELEMENT:
                    122:            xmlBufferWriteCHAR(content->name);
                    123:            break;
                    124:        case XML_ELEMENT_CONTENT_SEQ:
                    125:            if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
                    126:                (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
                    127:                xmlDumpElementContent(content->c1, 1);
                    128:            else
                    129:                xmlDumpElementContent(content->c1, 0);
                    130:             xmlBufferWriteChar(" , ");
                    131:            if (content->c2->type == XML_ELEMENT_CONTENT_OR)
                    132:                xmlDumpElementContent(content->c2, 1);
                    133:            else
                    134:                xmlDumpElementContent(content->c2, 0);
                    135:            break;
                    136:        case XML_ELEMENT_CONTENT_OR:
                    137:            if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
                    138:                (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
                    139:                xmlDumpElementContent(content->c1, 1);
                    140:            else
                    141:                xmlDumpElementContent(content->c1, 0);
                    142:             xmlBufferWriteChar(" | ");
                    143:            if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)
                    144:                xmlDumpElementContent(content->c2, 1);
                    145:            else
                    146:                xmlDumpElementContent(content->c2, 0);
                    147:            break;
                    148:        default:
                    149:            fprintf(stderr, "xmlDumpElementContent: unknown type %d\n",
                    150:                    content->type);
                    151:     }
                    152:     if (glob)
                    153:         xmlBufferWriteChar(")");
                    154:     switch (content->ocur) {
                    155:         case XML_ELEMENT_CONTENT_ONCE:
                    156:            break;
                    157:         case XML_ELEMENT_CONTENT_OPT:
                    158:            xmlBufferWriteChar("?");
                    159:            break;
                    160:         case XML_ELEMENT_CONTENT_MULT:
                    161:            xmlBufferWriteChar("*");
                    162:            break;
                    163:         case XML_ELEMENT_CONTENT_PLUS:
                    164:            xmlBufferWriteChar("+");
                    165:            break;
                    166:     }
                    167: }
                    168: 
1.1       daniel    169: /****************************************************************
                    170:  *                                                             *
                    171:  *     Registration of DTD declarations                        *
                    172:  *                                                             *
                    173:  ****************************************************************/
                    174: 
1.2       daniel    175: /**
                    176:  * xmlCreateElementTable:
                    177:  *
                    178:  * create and initialize an empty element hash table.
                    179:  *
1.6     ! daniel    180:  * Returns the xmlElementTablePtr just created or NULL in case of error.
1.2       daniel    181:  */
                    182: xmlElementTablePtr
                    183: xmlCreateElementTable(void) {
                    184:     xmlElementTablePtr ret;
                    185: 
                    186:     ret = (xmlElementTablePtr) 
                    187:          malloc(sizeof(xmlElementTable));
                    188:     if (ret == NULL) {
                    189:         fprintf(stderr, "xmlCreateElementTable : malloc(%d) failed\n",
                    190:                sizeof(xmlElementTable));
                    191:         return(NULL);
                    192:     }
1.4       daniel    193:     ret->max_elements = XML_MIN_ELEMENT_TABLE;
1.2       daniel    194:     ret->nb_elements = 0;
                    195:     ret->table = (xmlElementPtr ) 
                    196:          malloc(ret->max_elements * sizeof(xmlElement));
                    197:     if (ret == NULL) {
                    198:         fprintf(stderr, "xmlCreateElementTable : malloc(%d) failed\n",
                    199:                ret->max_elements * sizeof(xmlElement));
                    200:        free(ret);
                    201:         return(NULL);
                    202:     }
                    203:     return(ret);
                    204: }
                    205: 
1.1       daniel    206: 
                    207: /**
                    208:  * xmlAddElementDecl:
1.6     ! daniel    209:  * @dtd:  pointer to the DTD
1.1       daniel    210:  * @name:  the entity name
1.6     ! daniel    211:  * @type:  the element type
        !           212:  * @content:  the element content tree or NULL
1.1       daniel    213:  *
                    214:  * Register a new element declaration
                    215:  *
1.6     ! daniel    216:  * Returns NULL if not, othervise the entity
1.1       daniel    217:  */
                    218: xmlElementPtr
1.4       daniel    219: xmlAddElementDecl(xmlDtdPtr dtd, CHAR *name, int type, 
1.1       daniel    220:                   xmlElementContentPtr content) {
1.2       daniel    221:     xmlElementPtr ret, cur;
                    222:     xmlElementTablePtr table;
                    223:     int i;
1.1       daniel    224: 
                    225:     if (dtd == NULL) {
                    226:         fprintf(stderr, "xmlAddElementDecl: dtd == NULL\n");
                    227:        return(NULL);
                    228:     }
                    229:     if (name == NULL) {
                    230:         fprintf(stderr, "xmlAddElementDecl: name == NULL\n");
                    231:        return(NULL);
                    232:     }
                    233:     switch (type) {
                    234:         case XML_ELEMENT_TYPE_EMPTY:
                    235:            if (content != NULL) {
                    236:                fprintf(stderr,
                    237:                        "xmlAddElementDecl: content != NULL for EMPTY\n");
                    238:                return(NULL);
                    239:            }
                    240:            break;
                    241:        case XML_ELEMENT_TYPE_ANY:
                    242:            if (content != NULL) {
                    243:                fprintf(stderr,
                    244:                        "xmlAddElementDecl: content != NULL for ANY\n");
                    245:                return(NULL);
                    246:            }
                    247:            break;
                    248:        case XML_ELEMENT_TYPE_MIXED:
                    249:            if (content == NULL) {
                    250:                fprintf(stderr,
                    251:                        "xmlAddElementDecl: content == NULL for MIXED\n");
                    252:                return(NULL);
                    253:            }
                    254:            break;
                    255:        case XML_ELEMENT_TYPE_ELEMENT:
                    256:            if (content == NULL) {
                    257:                fprintf(stderr,
                    258:                        "xmlAddElementDecl: content == NULL for ELEMENT\n");
                    259:                return(NULL);
                    260:            }
                    261:            break;
                    262:        default:
                    263:            fprintf(stderr, "xmlAddElementDecl: unknown type %d\n", type);
                    264:            return(NULL);
                    265:     }
                    266: 
                    267:     /*
1.2       daniel    268:      * Create the Element table if needed.
                    269:      */
                    270:     table = dtd->elements;
                    271:     if (table == NULL) 
                    272:         table = dtd->elements = xmlCreateElementTable();
                    273:     if (table == NULL) {
                    274:        fprintf(stderr, "xmlAddElementDecl: Table creation failed!\n");
                    275:         return(NULL);
                    276:     }
                    277: 
                    278:     /*
1.1       daniel    279:      * Validity Check:
                    280:      * Search the DTD for previous declarations of the ELEMENT
                    281:      */
1.2       daniel    282:     for (i = 0;i < table->nb_elements;i++) {
                    283:         cur = &table->table[i];
                    284:        if (!xmlStrcmp(cur->name, name)) {
                    285:            /*
                    286:             * The element is already defined in this Dtd.
                    287:             */
                    288:            fprintf(stderr,
                    289:                    "xmlAddElementDecl: %s already defined\n", name);
                    290:            return(NULL);
                    291:        }
                    292:     }
1.1       daniel    293: 
                    294:     /*
1.2       daniel    295:      * Grow the table, if needed.
1.1       daniel    296:      */
1.2       daniel    297:     if (table->nb_elements >= table->max_elements) {
                    298:         /*
                    299:         * need more elements.
                    300:         */
                    301:        table->max_elements *= 2;
                    302:        table->table = (xmlElementPtr) 
                    303:            realloc(table->table, table->max_elements * sizeof(xmlElement));
                    304:        if (table->table) {
                    305:            fprintf(stderr, "xmlAddElementDecl: out of memory\n");
                    306:            return(NULL);
                    307:        }
1.1       daniel    308:     }
1.2       daniel    309:     ret = &table->table[table->nb_elements];
                    310: 
                    311:     /*
                    312:      * fill the structure.
                    313:      */
1.1       daniel    314:     ret->type = type;
                    315:     ret->name = xmlStrdup(name);
                    316:     ret->content = content;
1.2       daniel    317:     table->nb_elements++;
                    318: 
                    319:     return(ret);
                    320: }
                    321: 
                    322: /**
                    323:  * xmlFreeElement:
                    324:  * @elem:  An element
                    325:  *
                    326:  * Deallocate the memory used by an element definition
                    327:  */
                    328: void
                    329: xmlFreeElement(xmlElementPtr elem) {
                    330:     if (elem == NULL) return;
                    331:     xmlFreeElementContent(elem->content);
                    332:     if (elem->name != NULL)
                    333:        free((CHAR *) elem->name);
                    334:     memset(elem, -1, sizeof(xmlElement));
                    335: }
1.1       daniel    336: 
1.2       daniel    337: /**
                    338:  * xmlFreeElementTable:
                    339:  * @table:  An element table
                    340:  *
1.4       daniel    341:  * Deallocate the memory used by an element hash table.
1.2       daniel    342:  */
                    343: void
                    344: xmlFreeElementTable(xmlElementTablePtr table) {
                    345:     int i;
                    346: 
                    347:     if (table == NULL) return;
                    348: 
                    349:     for (i = 0;i < table->nb_elements;i++) {
                    350:         xmlFreeElement(&table->table[i]);
                    351:     }
                    352:     free(table->table);
                    353:     free(table);
                    354: }
                    355: 
                    356: /**
                    357:  * xmlCopyElementTable:
                    358:  * @table:  An element table
                    359:  *
                    360:  * Build a copy of an element table.
                    361:  * 
1.6     ! daniel    362:  * Returns the new xmlElementTablePtr or NULL in case of error.
1.2       daniel    363:  */
                    364: xmlElementTablePtr
                    365: xmlCopyElementTable(xmlElementTablePtr table) {
                    366:     xmlElementTablePtr ret;
                    367:     xmlElementPtr cur, ent;
                    368:     int i;
1.1       daniel    369: 
1.2       daniel    370:     ret = (xmlElementTablePtr) malloc(sizeof(xmlElementTable));
                    371:     if (ret == NULL) {
                    372:         fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
                    373:        return(NULL);
                    374:     }
                    375:     ret->table = (xmlElementPtr) malloc(table->max_elements *
                    376:                                          sizeof(xmlElement));
                    377:     if (ret->table == NULL) {
                    378:         fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
                    379:        free(ret);
                    380:        return(NULL);
                    381:     }
                    382:     ret->max_elements = table->max_elements;
                    383:     ret->nb_elements = table->nb_elements;
                    384:     for (i = 0;i < ret->nb_elements;i++) {
                    385:        cur = &ret->table[i];
                    386:        ent = &table->table[i];
                    387:        cur->type = ent->type;
                    388:        if (ent->name != NULL)
                    389:            cur->name = xmlStrdup(ent->name);
                    390:        else
                    391:            cur->name = NULL;
                    392:        cur->content = xmlCopyElementContent(ent->content);
                    393:     }
1.1       daniel    394:     return(ret);
                    395: }
                    396: 
1.2       daniel    397: /**
                    398:  * xmlDumpElementTable:
                    399:  * @table:  An element table
                    400:  *
                    401:  * This will dump the content of the element table as an XML DTD definition
                    402:  *
                    403:  * NOTE: TODO an extra parameter allowing a reentant implementation will
                    404:  *       be added.
                    405:  */
                    406: void
                    407: xmlDumpElementTable(xmlElementTablePtr table) {
                    408:     int i;
                    409:     xmlElementPtr cur;
                    410: 
                    411:     if (table == NULL) return;
                    412: 
                    413:     for (i = 0;i < table->nb_elements;i++) {
                    414:         cur = &table->table[i];
                    415:         switch (cur->type) {
                    416:            case XML_ELEMENT_TYPE_EMPTY:
                    417:                xmlBufferWriteChar("<!ELEMENT ");
                    418:                xmlBufferWriteCHAR(cur->name);
1.3       daniel    419:                xmlBufferWriteChar(" EMPTY>\n");
1.2       daniel    420:                break;
                    421:            case XML_ELEMENT_TYPE_ANY:
                    422:                xmlBufferWriteChar("<!ELEMENT ");
                    423:                xmlBufferWriteCHAR(cur->name);
1.3       daniel    424:                xmlBufferWriteChar(" ANY>\n");
1.2       daniel    425:                break;
                    426:            case XML_ELEMENT_TYPE_MIXED:
1.3       daniel    427:                xmlBufferWriteChar("<!ELEMENT ");
                    428:                xmlBufferWriteCHAR(cur->name);
                    429:                xmlBufferWriteChar(" ");
                    430:                xmlDumpElementContent(cur->content, 1);
                    431:                xmlBufferWriteChar(">\n");
1.2       daniel    432:                break;
                    433:            case XML_ELEMENT_TYPE_ELEMENT:
1.3       daniel    434:                xmlBufferWriteChar("<!ELEMENT ");
                    435:                xmlBufferWriteCHAR(cur->name);
                    436:                xmlBufferWriteChar(" ");
                    437:                xmlDumpElementContent(cur->content, 1);
                    438:                xmlBufferWriteChar(">\n");
1.2       daniel    439:                break;
                    440:            default:
                    441:                fprintf(stderr,
                    442:                    "xmlDumpElementTable: internal: unknown type %d\n",
                    443:                        cur->type);
                    444:        }
1.4       daniel    445:     }
                    446: }
                    447: 
                    448: /**
                    449:  * xmlCreateEnumeration:
                    450:  * @name:  the enumeration name or NULL
                    451:  *
                    452:  * create and initialize an enumeration attribute node.
                    453:  *
1.6     ! daniel    454:  * Returns the xmlEnumerationPtr just created or NULL in case
1.4       daniel    455:  *                of error.
                    456:  */
                    457: xmlEnumerationPtr
                    458: xmlCreateEnumeration(CHAR *name) {
                    459:     xmlEnumerationPtr ret;
                    460: 
                    461:     ret = (xmlEnumerationPtr) malloc(sizeof(xmlEnumeration));
                    462:     if (ret == NULL) {
                    463:         fprintf(stderr, "xmlCreateEnumeration : malloc(%d) failed\n",
                    464:                sizeof(xmlEnumeration));
                    465:         return(NULL);
                    466:     }
                    467: 
                    468:     if (name != NULL)
                    469:         ret->name = xmlStrdup(name);
                    470:     else
                    471:         ret->name = NULL;
                    472:     ret->next = NULL;
                    473:     return(ret);
                    474: }
                    475: 
                    476: /**
                    477:  * xmlFreeEnumeration:
                    478:  * @cur:  the tree to free.
                    479:  *
                    480:  * free an enumeration attribute node (recursive).
                    481:  */
                    482: void
                    483: xmlFreeEnumeration(xmlEnumerationPtr cur) {
                    484:     if (cur == NULL) return;
                    485: 
                    486:     if (cur->next != NULL) xmlFreeEnumeration(cur->next);
                    487: 
                    488:     if (cur->name != NULL) free((CHAR *) cur->name);
                    489:     memset(cur, -1, sizeof(xmlEnumeration));
                    490:     free(cur);
                    491: }
                    492: 
                    493: /**
                    494:  * xmlCopyEnumeration:
                    495:  * @cur:  the tree to copy.
                    496:  *
                    497:  * Copy an enumeration attribute node (recursive).
                    498:  *
1.6     ! daniel    499:  * Returns the xmlEnumerationPtr just created or NULL in case
1.4       daniel    500:  *                of error.
                    501:  */
                    502: xmlEnumerationPtr
                    503: xmlCopyEnumeration(xmlEnumerationPtr cur) {
                    504:     xmlEnumerationPtr ret;
                    505: 
                    506:     if (cur == NULL) return(NULL);
                    507:     ret = xmlCreateEnumeration((CHAR *) cur->name);
                    508: 
                    509:     if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
                    510:     else ret->next = NULL;
                    511: 
                    512:     return(ret);
                    513: }
                    514: 
                    515: /**
                    516:  * xmlCreateAttributeTable:
                    517:  *
                    518:  * create and initialize an empty attribute hash table.
                    519:  *
1.6     ! daniel    520:  * Returns the xmlAttributeTablePtr just created or NULL in case
1.4       daniel    521:  *                of error.
                    522:  */
                    523: xmlAttributeTablePtr
                    524: xmlCreateAttributeTable(void) {
                    525:     xmlAttributeTablePtr ret;
                    526: 
                    527:     ret = (xmlAttributeTablePtr) 
                    528:          malloc(sizeof(xmlAttributeTable));
                    529:     if (ret == NULL) {
                    530:         fprintf(stderr, "xmlCreateAttributeTable : malloc(%d) failed\n",
                    531:                sizeof(xmlAttributeTable));
                    532:         return(NULL);
                    533:     }
                    534:     ret->max_attributes = XML_MIN_ATTRIBUTE_TABLE;
                    535:     ret->nb_attributes = 0;
                    536:     ret->table = (xmlAttributePtr ) 
                    537:          malloc(ret->max_attributes * sizeof(xmlAttribute));
                    538:     if (ret == NULL) {
                    539:         fprintf(stderr, "xmlCreateAttributeTable : malloc(%d) failed\n",
                    540:                ret->max_attributes * sizeof(xmlAttribute));
                    541:        free(ret);
                    542:         return(NULL);
                    543:     }
                    544:     return(ret);
                    545: }
                    546: 
                    547: 
                    548: /**
                    549:  * xmlAddAttributeDecl:
1.6     ! daniel    550:  * @dtd:  pointer to the DTD
        !           551:  * @elem:  the element name
        !           552:  * @name:  the attribute name
        !           553:  * @type:  the attribute type
        !           554:  * @def:  the attribute default type
        !           555:  * @defaultValue:  the attribute default value
        !           556:  * @tree:  if it's an enumeration, the associated list
1.4       daniel    557:  *
                    558:  * Register a new attribute declaration
                    559:  *
1.6     ! daniel    560:  * Returns NULL if not, othervise the entity
1.4       daniel    561:  */
                    562: xmlAttributePtr
                    563: xmlAddAttributeDecl(xmlDtdPtr dtd, CHAR *elem, CHAR *name, int type, int def,
                    564:                     CHAR *defaultValue, xmlEnumerationPtr tree) {
                    565:     xmlAttributePtr ret, cur;
                    566:     xmlAttributeTablePtr table;
                    567:     int i;
                    568: 
                    569:     if (dtd == NULL) {
                    570:         fprintf(stderr, "xmlAddAttributeDecl: dtd == NULL\n");
                    571:        return(NULL);
                    572:     }
                    573:     if (name == NULL) {
                    574:         fprintf(stderr, "xmlAddAttributeDecl: name == NULL\n");
                    575:        return(NULL);
                    576:     }
                    577:     if (elem == NULL) {
                    578:         fprintf(stderr, "xmlAddAttributeDecl: elem == NULL\n");
                    579:        return(NULL);
                    580:     }
                    581:     /* TODO: Lacks verifications !!! */
                    582:     switch (type) {
                    583:         case XML_ATTRIBUTE_CDATA:
                    584:            break;
                    585:         case XML_ATTRIBUTE_ID:
                    586:            break;
                    587:         case XML_ATTRIBUTE_IDREF:
                    588:            break;
                    589:         case XML_ATTRIBUTE_IDREFS:
                    590:            break;
                    591:         case XML_ATTRIBUTE_ENTITY:
                    592:            break;
                    593:         case XML_ATTRIBUTE_ENTITIES:
                    594:            break;
                    595:         case XML_ATTRIBUTE_NMTOKEN:
                    596:            break;
                    597:         case XML_ATTRIBUTE_NMTOKENS:
                    598:            break;
                    599:         case XML_ATTRIBUTE_ENUMERATION:
                    600:            break;
                    601:         case XML_ATTRIBUTE_NOTATION:
                    602:            break;
                    603:        default:
                    604:            fprintf(stderr, "xmlAddAttributeDecl: unknown type %d\n", type);
                    605:            return(NULL);
                    606:     }
                    607: 
                    608:     /*
                    609:      * Create the Attribute table if needed.
                    610:      */
                    611:     table = dtd->attributes;
                    612:     if (table == NULL) 
                    613:         table = dtd->attributes = xmlCreateAttributeTable();
                    614:     if (table == NULL) {
                    615:        fprintf(stderr, "xmlAddAttributeDecl: Table creation failed!\n");
                    616:         return(NULL);
                    617:     }
                    618: 
                    619:     /*
                    620:      * Validity Check:
                    621:      * Search the DTD for previous declarations of the ATTLIST
                    622:      */
                    623:     for (i = 0;i < table->nb_attributes;i++) {
                    624:         cur = &table->table[i];
                    625:        if ((!xmlStrcmp(cur->name, name)) && (!xmlStrcmp(cur->elem, elem))) {
                    626:            /*
                    627:             * The attribute is already defined in this Dtd.
                    628:             */
                    629:            fprintf(stderr,
                    630:                    "xmlAddAttributeDecl: %s already defined\n", name);
                    631:        }
                    632:     }
                    633: 
                    634:     /*
                    635:      * Grow the table, if needed.
                    636:      */
                    637:     if (table->nb_attributes >= table->max_attributes) {
                    638:         /*
                    639:         * need more attributes.
                    640:         */
                    641:        table->max_attributes *= 2;
                    642:        table->table = (xmlAttributePtr) 
                    643:            realloc(table->table, table->max_attributes * sizeof(xmlAttribute));
                    644:        if (table->table) {
                    645:            fprintf(stderr, "xmlAddAttributeDecl: out of memory\n");
                    646:            return(NULL);
                    647:        }
                    648:     }
                    649:     ret = &table->table[table->nb_attributes];
                    650: 
                    651:     /*
                    652:      * fill the structure.
                    653:      */
                    654:     ret->type = type;
                    655:     ret->name = xmlStrdup(name);
                    656:     ret->elem = xmlStrdup(elem);
                    657:     ret->def = def;
                    658:     ret->tree = tree;
                    659:     if (defaultValue != NULL)
                    660:        ret->defaultValue = xmlStrdup(defaultValue);
                    661:     else
                    662:         ret->defaultValue = NULL;
                    663:     table->nb_attributes++;
                    664: 
                    665:     return(ret);
                    666: }
                    667: 
                    668: /**
                    669:  * xmlFreeAttribute:
                    670:  * @elem:  An attribute
                    671:  *
                    672:  * Deallocate the memory used by an attribute definition
                    673:  */
                    674: void
                    675: xmlFreeAttribute(xmlAttributePtr attr) {
                    676:     if (attr == NULL) return;
                    677:     if (attr->tree != NULL)
                    678:         xmlFreeEnumeration(attr->tree);
                    679:     if (attr->elem != NULL)
                    680:        free((CHAR *) attr->elem);
                    681:     if (attr->name != NULL)
                    682:        free((CHAR *) attr->name);
                    683:     if (attr->defaultValue != NULL)
                    684:        free((CHAR *) attr->defaultValue);
                    685:     memset(attr, -1, sizeof(xmlAttribute));
                    686: }
                    687: 
                    688: /**
                    689:  * xmlFreeAttributeTable:
                    690:  * @table:  An attribute table
                    691:  *
                    692:  * Deallocate the memory used by an entities hash table.
                    693:  */
                    694: void
                    695: xmlFreeAttributeTable(xmlAttributeTablePtr table) {
                    696:     int i;
                    697: 
                    698:     if (table == NULL) return;
                    699: 
                    700:     for (i = 0;i < table->nb_attributes;i++) {
                    701:         xmlFreeAttribute(&table->table[i]);
                    702:     }
                    703:     free(table->table);
                    704:     free(table);
                    705: }
                    706: 
                    707: /**
                    708:  * xmlCopyAttributeTable:
                    709:  * @table:  An attribute table
                    710:  *
                    711:  * Build a copy of an attribute table.
                    712:  * 
1.6     ! daniel    713:  * Returns the new xmlAttributeTablePtr or NULL in case of error.
1.4       daniel    714:  */
                    715: xmlAttributeTablePtr
                    716: xmlCopyAttributeTable(xmlAttributeTablePtr table) {
                    717:     xmlAttributeTablePtr ret;
                    718:     xmlAttributePtr cur, attr;
                    719:     int i;
                    720: 
                    721:     ret = (xmlAttributeTablePtr) malloc(sizeof(xmlAttributeTable));
                    722:     if (ret == NULL) {
                    723:         fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
                    724:        return(NULL);
                    725:     }
                    726:     ret->table = (xmlAttributePtr) malloc(table->max_attributes *
                    727:                                          sizeof(xmlAttribute));
                    728:     if (ret->table == NULL) {
                    729:         fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
                    730:        free(ret);
                    731:        return(NULL);
                    732:     }
                    733:     ret->max_attributes = table->max_attributes;
                    734:     ret->nb_attributes = table->nb_attributes;
                    735:     for (i = 0;i < ret->nb_attributes;i++) {
                    736:        cur = &ret->table[i];
                    737:        attr = &table->table[i];
                    738:        cur->type = attr->type;
                    739:        cur->def = attr->def;
                    740:        cur->tree = xmlCopyEnumeration(attr->tree);
                    741:        if (attr->elem != NULL)
                    742:            cur->elem = xmlStrdup(attr->elem);
                    743:        else
                    744:            cur->elem = NULL;
                    745:        if (attr->name != NULL)
                    746:            cur->name = xmlStrdup(attr->name);
                    747:        else
                    748:            cur->name = NULL;
                    749:        if (attr->defaultValue != NULL)
                    750:            cur->defaultValue = xmlStrdup(attr->defaultValue);
                    751:        else
                    752:            cur->defaultValue = NULL;
                    753:     }
                    754:     return(ret);
                    755: }
                    756: 
                    757: /**
                    758:  * xmlDumpAttributeTable:
                    759:  * @table:  An attribute table
                    760:  *
                    761:  * This will dump the content of the attribute table as an XML DTD definition
                    762:  *
                    763:  * NOTE: TODO an extra parameter allowing a reentant implementation will
                    764:  *       be added.
                    765:  */
                    766: void
                    767: xmlDumpAttributeTable(xmlAttributeTablePtr table) {
                    768:     int i;
                    769:     xmlAttributePtr cur;
                    770: 
                    771:     if (table == NULL) return;
                    772: 
                    773:     for (i = 0;i < table->nb_attributes;i++) {
                    774:         cur = &table->table[i];
                    775:        xmlBufferWriteChar("<!ATTLIST ");
                    776:        xmlBufferWriteCHAR(cur->elem);
                    777:        xmlBufferWriteChar(" ");
                    778:        xmlBufferWriteCHAR(cur->name);
                    779:         switch (cur->type) {
                    780:             case XML_ATTRIBUTE_CDATA:
                    781:                xmlBufferWriteChar(" CDATA");
                    782:                 break;
                    783:             case XML_ATTRIBUTE_ID:
                    784:                xmlBufferWriteChar(" ID");
                    785:                 break;
                    786:             case XML_ATTRIBUTE_IDREF:
                    787:                xmlBufferWriteChar(" IDREF");
                    788:                 break;
                    789:             case XML_ATTRIBUTE_IDREFS:
                    790:                xmlBufferWriteChar(" IDREFS");
                    791:                 break;
                    792:             case XML_ATTRIBUTE_ENTITY:
                    793:                xmlBufferWriteChar(" ENTITY");
                    794:                 break;
                    795:             case XML_ATTRIBUTE_ENTITIES:
                    796:                xmlBufferWriteChar(" ENTITIES");
                    797:                 break;
                    798:             case XML_ATTRIBUTE_NMTOKEN:
                    799:                xmlBufferWriteChar(" NMTOKEN");
                    800:                 break;
                    801:             case XML_ATTRIBUTE_NMTOKENS:
                    802:                xmlBufferWriteChar(" NMTOKENS");
                    803:                 break;
                    804:             case XML_ATTRIBUTE_ENUMERATION:
                    805:                 xmlBufferWriteChar(" (pbm)");
                    806:                 break;
                    807:             case XML_ATTRIBUTE_NOTATION:
                    808:                 xmlBufferWriteChar(" NOTATION (pbm)");
                    809:                 break;
                    810:            default:
                    811:                fprintf(stderr,
                    812:                    "xmlDumpAttributeTable: internal: unknown type %d\n",
                    813:                        cur->type);
                    814:        }
                    815:         switch (cur->def) {
                    816:             case XML_ATTRIBUTE_NONE:
                    817:                 break;
                    818:             case XML_ATTRIBUTE_REQUIRED:
                    819:                xmlBufferWriteChar(" #REQUIRED");
                    820:                 break;
                    821:             case XML_ATTRIBUTE_IMPLIED:
                    822:                xmlBufferWriteChar(" #IMPLIED");
1.6     ! daniel    823:                if (cur->defaultValue != NULL) {
        !           824:                    xmlBufferWriteChar(" \"");
        !           825:                    xmlBufferWriteCHAR(cur->defaultValue);
        !           826:                    xmlBufferWriteChar("\"");
        !           827:                }
1.4       daniel    828:                 break;
                    829:             case XML_ATTRIBUTE_FIXED:
                    830:                xmlBufferWriteChar(" #FIXED \"");
                    831:                xmlBufferWriteCHAR(cur->defaultValue);
                    832:                xmlBufferWriteChar("\"");
                    833:                 break;
                    834:            default:
                    835:                fprintf(stderr,
                    836:                    "xmlDumpAttributeTable: internal: unknown default %d\n",
                    837:                        cur->def);
                    838:         }
                    839:         xmlBufferWriteChar(">\n");
1.5       daniel    840:     }
                    841: }
                    842: 
                    843: /************************************************************************
                    844:  *                                                                     *
                    845:  *                             NOTATIONs                               *
                    846:  *                                                                     *
                    847:  ************************************************************************/
                    848: /**
                    849:  * xmlCreateNotationTable:
                    850:  *
                    851:  * create and initialize an empty notation hash table.
                    852:  *
1.6     ! daniel    853:  * Returns the xmlNotationTablePtr just created or NULL in case
1.5       daniel    854:  *                of error.
                    855:  */
                    856: xmlNotationTablePtr
                    857: xmlCreateNotationTable(void) {
                    858:     xmlNotationTablePtr ret;
                    859: 
                    860:     ret = (xmlNotationTablePtr) 
                    861:          malloc(sizeof(xmlNotationTable));
                    862:     if (ret == NULL) {
                    863:         fprintf(stderr, "xmlCreateNotationTable : malloc(%d) failed\n",
                    864:                sizeof(xmlNotationTable));
                    865:         return(NULL);
                    866:     }
                    867:     ret->max_notations = XML_MIN_NOTATION_TABLE;
                    868:     ret->nb_notations = 0;
                    869:     ret->table = (xmlNotationPtr ) 
                    870:          malloc(ret->max_notations * sizeof(xmlNotation));
                    871:     if (ret == NULL) {
                    872:         fprintf(stderr, "xmlCreateNotationTable : malloc(%d) failed\n",
                    873:                ret->max_notations * sizeof(xmlNotation));
                    874:        free(ret);
                    875:         return(NULL);
                    876:     }
                    877:     return(ret);
                    878: }
                    879: 
                    880: 
                    881: /**
                    882:  * xmlAddNotationDecl:
1.6     ! daniel    883:  * @dtd:  pointer to the DTD
1.5       daniel    884:  * @name:  the entity name
1.6     ! daniel    885:  * @PublicID:  the public identifier or NULL
        !           886:  * @SystemID:  the system identifier or NULL
1.5       daniel    887:  *
                    888:  * Register a new notation declaration
                    889:  *
1.6     ! daniel    890:  * Returns NULL if not, othervise the entity
1.5       daniel    891:  */
                    892: xmlNotationPtr
                    893: xmlAddNotationDecl(xmlDtdPtr dtd, CHAR *name, CHAR *PublicID, CHAR *SystemID) {
                    894:     xmlNotationPtr ret, cur;
                    895:     xmlNotationTablePtr table;
                    896:     int i;
                    897: 
                    898:     if (dtd == NULL) {
                    899:         fprintf(stderr, "xmlAddNotationDecl: dtd == NULL\n");
                    900:        return(NULL);
                    901:     }
                    902:     if (name == NULL) {
                    903:         fprintf(stderr, "xmlAddNotationDecl: name == NULL\n");
                    904:        return(NULL);
                    905:     }
                    906:     if ((PublicID == NULL) && (SystemID == NULL)) {
                    907:         fprintf(stderr, "xmlAddNotationDecl: no PUBLIC ID nor SYSTEM ID\n");
                    908:     }
                    909: 
                    910:     /*
                    911:      * Create the Notation table if needed.
                    912:      */
                    913:     table = dtd->notations;
                    914:     if (table == NULL) 
                    915:         table = dtd->notations = xmlCreateNotationTable();
                    916:     if (table == NULL) {
                    917:        fprintf(stderr, "xmlAddNotationDecl: Table creation failed!\n");
                    918:         return(NULL);
                    919:     }
                    920: 
                    921:     /*
                    922:      * Validity Check:
                    923:      * Search the DTD for previous declarations of the ATTLIST
                    924:      */
                    925:     for (i = 0;i < table->nb_notations;i++) {
                    926:         cur = &table->table[i];
                    927:        if (!xmlStrcmp(cur->name, name)) {
                    928:            /*
                    929:             * The notation is already defined in this Dtd.
                    930:             */
                    931:            fprintf(stderr,
                    932:                    "xmlAddNotationDecl: %s already defined\n", name);
                    933:        }
                    934:     }
                    935: 
                    936:     /*
                    937:      * Grow the table, if needed.
                    938:      */
                    939:     if (table->nb_notations >= table->max_notations) {
                    940:         /*
                    941:         * need more notations.
                    942:         */
                    943:        table->max_notations *= 2;
                    944:        table->table = (xmlNotationPtr) 
                    945:            realloc(table->table, table->max_notations * sizeof(xmlNotation));
                    946:        if (table->table) {
                    947:            fprintf(stderr, "xmlAddNotationDecl: out of memory\n");
                    948:            return(NULL);
                    949:        }
                    950:     }
                    951:     ret = &table->table[table->nb_notations];
                    952: 
                    953:     /*
                    954:      * fill the structure.
                    955:      */
                    956:     ret->name = xmlStrdup(name);
                    957:     if (SystemID != NULL)
                    958:         ret->SystemID = xmlStrdup(SystemID);
                    959:     else
                    960:         ret->SystemID = NULL;
                    961:     if (PublicID != NULL)
                    962:         ret->PublicID = xmlStrdup(PublicID);
                    963:     else
                    964:         ret->PublicID = NULL;
                    965:     table->nb_notations++;
                    966: 
                    967:     return(ret);
                    968: }
                    969: 
                    970: /**
                    971:  * xmlFreeNotation:
                    972:  * @not:  A notation
                    973:  *
                    974:  * Deallocate the memory used by an notation definition
                    975:  */
                    976: void
                    977: xmlFreeNotation(xmlNotationPtr nota) {
                    978:     if (nota == NULL) return;
                    979:     if (nota->name != NULL)
                    980:        free((CHAR *) nota->name);
                    981:     if (nota->PublicID != NULL)
                    982:        free((CHAR *) nota->PublicID);
                    983:     if (nota->SystemID != NULL)
                    984:        free((CHAR *) nota->SystemID);
                    985:     memset(nota, -1, sizeof(xmlNotation));
                    986: }
                    987: 
                    988: /**
                    989:  * xmlFreeNotationTable:
                    990:  * @table:  An notation table
                    991:  *
                    992:  * Deallocate the memory used by an entities hash table.
                    993:  */
                    994: void
                    995: xmlFreeNotationTable(xmlNotationTablePtr table) {
                    996:     int i;
                    997: 
                    998:     if (table == NULL) return;
                    999: 
                   1000:     for (i = 0;i < table->nb_notations;i++) {
                   1001:         xmlFreeNotation(&table->table[i]);
                   1002:     }
                   1003:     free(table->table);
                   1004:     free(table);
                   1005: }
                   1006: 
                   1007: /**
                   1008:  * xmlCopyNotationTable:
                   1009:  * @table:  A notation table
                   1010:  *
                   1011:  * Build a copy of a notation table.
                   1012:  * 
1.6     ! daniel   1013:  * Returns the new xmlNotationTablePtr or NULL in case of error.
1.5       daniel   1014:  */
                   1015: xmlNotationTablePtr
                   1016: xmlCopyNotationTable(xmlNotationTablePtr table) {
                   1017:     xmlNotationTablePtr ret;
                   1018:     xmlNotationPtr cur, nota;
                   1019:     int i;
                   1020: 
                   1021:     ret = (xmlNotationTablePtr) malloc(sizeof(xmlNotationTable));
                   1022:     if (ret == NULL) {
                   1023:         fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
                   1024:        return(NULL);
                   1025:     }
                   1026:     ret->table = (xmlNotationPtr) malloc(table->max_notations *
                   1027:                                          sizeof(xmlNotation));
                   1028:     if (ret->table == NULL) {
                   1029:         fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
                   1030:        free(ret);
                   1031:        return(NULL);
                   1032:     }
                   1033:     ret->max_notations = table->max_notations;
                   1034:     ret->nb_notations = table->nb_notations;
                   1035:     for (i = 0;i < ret->nb_notations;i++) {
                   1036:        cur = &ret->table[i];
                   1037:        nota = &table->table[i];
                   1038:        if (nota->name != NULL)
                   1039:            cur->name = xmlStrdup(nota->name);
                   1040:        else
                   1041:            cur->name = NULL;
                   1042:        if (nota->PublicID != NULL)
                   1043:            cur->PublicID = xmlStrdup(nota->PublicID);
                   1044:        else
                   1045:            cur->PublicID = NULL;
                   1046:        if (nota->SystemID != NULL)
                   1047:            cur->SystemID = xmlStrdup(nota->SystemID);
                   1048:        else
                   1049:            cur->SystemID = NULL;
                   1050:     }
                   1051:     return(ret);
                   1052: }
                   1053: 
                   1054: /**
                   1055:  * xmlDumpNotationTable:
                   1056:  * @table:  A notation table
                   1057:  *
                   1058:  * This will dump the content of the notation table as an XML DTD definition
                   1059:  *
                   1060:  * NOTE: TODO an extra parameter allowing a reentant implementation will
                   1061:  *       be added.
                   1062:  */
                   1063: void
                   1064: xmlDumpNotationTable(xmlNotationTablePtr table) {
                   1065:     int i;
                   1066:     xmlNotationPtr cur;
                   1067: 
                   1068:     if (table == NULL) return;
                   1069: 
                   1070:     for (i = 0;i < table->nb_notations;i++) {
                   1071:         cur = &table->table[i];
                   1072:        xmlBufferWriteChar("<!NOTATION ");
                   1073:        xmlBufferWriteCHAR(cur->name);
                   1074:        if (cur->PublicID != NULL) {
                   1075:            xmlBufferWriteChar(" PUBLIC \"");
                   1076:            xmlBufferWriteCHAR(cur->PublicID);
                   1077:            xmlBufferWriteChar("\"");
                   1078:            if (cur->SystemID != NULL) {
                   1079:                xmlBufferWriteChar(" ");
                   1080:                xmlBufferWriteCHAR(cur->SystemID);
                   1081:            }
                   1082:        } else {
                   1083:            xmlBufferWriteChar(" SYSTEM ");
                   1084:            xmlBufferWriteCHAR(cur->SystemID);
                   1085:        }
                   1086:         xmlBufferWriteChar(" >\n");
1.2       daniel   1087:     }
                   1088: }

Webmaster