Annotation of XML/valid.c, revision 1.8

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:
1.8     ! daniel    104:  * @buf:  An XML buffer
1.3       daniel    105:  * @content:  An element table
                    106:  * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
                    107:  *
                    108:  * This will dump the content of the element table as an XML DTD definition
                    109:  */
                    110: void
1.8     ! daniel    111: xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) {
1.3       daniel    112:     if (content == NULL) return;
                    113: 
1.8     ! daniel    114:     if (glob) xmlBufferWriteChar(buf, "(");
1.3       daniel    115:     switch (content->type) {
                    116:         case XML_ELEMENT_CONTENT_PCDATA:
1.8     ! daniel    117:             xmlBufferWriteChar(buf, "#PCDATA");
1.3       daniel    118:            break;
                    119:        case XML_ELEMENT_CONTENT_ELEMENT:
1.8     ! daniel    120:            xmlBufferWriteCHAR(buf, content->name);
1.3       daniel    121:            break;
                    122:        case XML_ELEMENT_CONTENT_SEQ:
                    123:            if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
                    124:                (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
1.8     ! daniel    125:                xmlDumpElementContent(buf, content->c1, 1);
1.3       daniel    126:            else
1.8     ! daniel    127:                xmlDumpElementContent(buf, content->c1, 0);
        !           128:             xmlBufferWriteChar(buf, " , ");
1.3       daniel    129:            if (content->c2->type == XML_ELEMENT_CONTENT_OR)
1.8     ! daniel    130:                xmlDumpElementContent(buf, content->c2, 1);
1.3       daniel    131:            else
1.8     ! daniel    132:                xmlDumpElementContent(buf, content->c2, 0);
1.3       daniel    133:            break;
                    134:        case XML_ELEMENT_CONTENT_OR:
                    135:            if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
                    136:                (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
1.8     ! daniel    137:                xmlDumpElementContent(buf, content->c1, 1);
1.3       daniel    138:            else
1.8     ! daniel    139:                xmlDumpElementContent(buf, content->c1, 0);
        !           140:             xmlBufferWriteChar(buf, " | ");
1.3       daniel    141:            if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)
1.8     ! daniel    142:                xmlDumpElementContent(buf, content->c2, 1);
1.3       daniel    143:            else
1.8     ! daniel    144:                xmlDumpElementContent(buf, content->c2, 0);
1.3       daniel    145:            break;
                    146:        default:
                    147:            fprintf(stderr, "xmlDumpElementContent: unknown type %d\n",
                    148:                    content->type);
                    149:     }
                    150:     if (glob)
1.8     ! daniel    151:         xmlBufferWriteChar(buf, ")");
1.3       daniel    152:     switch (content->ocur) {
                    153:         case XML_ELEMENT_CONTENT_ONCE:
                    154:            break;
                    155:         case XML_ELEMENT_CONTENT_OPT:
1.8     ! daniel    156:            xmlBufferWriteChar(buf, "?");
1.3       daniel    157:            break;
                    158:         case XML_ELEMENT_CONTENT_MULT:
1.8     ! daniel    159:            xmlBufferWriteChar(buf, "*");
1.3       daniel    160:            break;
                    161:         case XML_ELEMENT_CONTENT_PLUS:
1.8     ! daniel    162:            xmlBufferWriteChar(buf, "+");
1.3       daniel    163:            break;
                    164:     }
                    165: }
                    166: 
1.1       daniel    167: /****************************************************************
                    168:  *                                                             *
                    169:  *     Registration of DTD declarations                        *
                    170:  *                                                             *
                    171:  ****************************************************************/
                    172: 
1.2       daniel    173: /**
                    174:  * xmlCreateElementTable:
                    175:  *
                    176:  * create and initialize an empty element hash table.
                    177:  *
1.6       daniel    178:  * Returns the xmlElementTablePtr just created or NULL in case of error.
1.2       daniel    179:  */
                    180: xmlElementTablePtr
                    181: xmlCreateElementTable(void) {
                    182:     xmlElementTablePtr ret;
                    183: 
                    184:     ret = (xmlElementTablePtr) 
                    185:          malloc(sizeof(xmlElementTable));
                    186:     if (ret == NULL) {
                    187:         fprintf(stderr, "xmlCreateElementTable : malloc(%d) failed\n",
                    188:                sizeof(xmlElementTable));
                    189:         return(NULL);
                    190:     }
1.4       daniel    191:     ret->max_elements = XML_MIN_ELEMENT_TABLE;
1.2       daniel    192:     ret->nb_elements = 0;
                    193:     ret->table = (xmlElementPtr ) 
                    194:          malloc(ret->max_elements * sizeof(xmlElement));
                    195:     if (ret == NULL) {
                    196:         fprintf(stderr, "xmlCreateElementTable : malloc(%d) failed\n",
                    197:                ret->max_elements * sizeof(xmlElement));
                    198:        free(ret);
                    199:         return(NULL);
                    200:     }
                    201:     return(ret);
                    202: }
                    203: 
1.1       daniel    204: 
                    205: /**
                    206:  * xmlAddElementDecl:
1.6       daniel    207:  * @dtd:  pointer to the DTD
1.1       daniel    208:  * @name:  the entity name
1.6       daniel    209:  * @type:  the element type
                    210:  * @content:  the element content tree or NULL
1.1       daniel    211:  *
                    212:  * Register a new element declaration
                    213:  *
1.6       daniel    214:  * Returns NULL if not, othervise the entity
1.1       daniel    215:  */
                    216: xmlElementPtr
1.7       daniel    217: xmlAddElementDecl(xmlDtdPtr dtd, const CHAR *name, int type, 
1.1       daniel    218:                   xmlElementContentPtr content) {
1.2       daniel    219:     xmlElementPtr ret, cur;
                    220:     xmlElementTablePtr table;
                    221:     int i;
1.1       daniel    222: 
                    223:     if (dtd == NULL) {
                    224:         fprintf(stderr, "xmlAddElementDecl: dtd == NULL\n");
                    225:        return(NULL);
                    226:     }
                    227:     if (name == NULL) {
                    228:         fprintf(stderr, "xmlAddElementDecl: name == NULL\n");
                    229:        return(NULL);
                    230:     }
                    231:     switch (type) {
                    232:         case XML_ELEMENT_TYPE_EMPTY:
                    233:            if (content != NULL) {
                    234:                fprintf(stderr,
                    235:                        "xmlAddElementDecl: content != NULL for EMPTY\n");
                    236:                return(NULL);
                    237:            }
                    238:            break;
                    239:        case XML_ELEMENT_TYPE_ANY:
                    240:            if (content != NULL) {
                    241:                fprintf(stderr,
                    242:                        "xmlAddElementDecl: content != NULL for ANY\n");
                    243:                return(NULL);
                    244:            }
                    245:            break;
                    246:        case XML_ELEMENT_TYPE_MIXED:
                    247:            if (content == NULL) {
                    248:                fprintf(stderr,
                    249:                        "xmlAddElementDecl: content == NULL for MIXED\n");
                    250:                return(NULL);
                    251:            }
                    252:            break;
                    253:        case XML_ELEMENT_TYPE_ELEMENT:
                    254:            if (content == NULL) {
                    255:                fprintf(stderr,
                    256:                        "xmlAddElementDecl: content == NULL for ELEMENT\n");
                    257:                return(NULL);
                    258:            }
                    259:            break;
                    260:        default:
                    261:            fprintf(stderr, "xmlAddElementDecl: unknown type %d\n", type);
                    262:            return(NULL);
                    263:     }
                    264: 
                    265:     /*
1.2       daniel    266:      * Create the Element table if needed.
                    267:      */
                    268:     table = dtd->elements;
                    269:     if (table == NULL) 
                    270:         table = dtd->elements = xmlCreateElementTable();
                    271:     if (table == NULL) {
                    272:        fprintf(stderr, "xmlAddElementDecl: Table creation failed!\n");
                    273:         return(NULL);
                    274:     }
                    275: 
                    276:     /*
1.1       daniel    277:      * Validity Check:
                    278:      * Search the DTD for previous declarations of the ELEMENT
                    279:      */
1.2       daniel    280:     for (i = 0;i < table->nb_elements;i++) {
                    281:         cur = &table->table[i];
                    282:        if (!xmlStrcmp(cur->name, name)) {
                    283:            /*
                    284:             * The element is already defined in this Dtd.
                    285:             */
                    286:            fprintf(stderr,
                    287:                    "xmlAddElementDecl: %s already defined\n", name);
                    288:            return(NULL);
                    289:        }
                    290:     }
1.1       daniel    291: 
                    292:     /*
1.2       daniel    293:      * Grow the table, if needed.
1.1       daniel    294:      */
1.2       daniel    295:     if (table->nb_elements >= table->max_elements) {
                    296:         /*
                    297:         * need more elements.
                    298:         */
                    299:        table->max_elements *= 2;
                    300:        table->table = (xmlElementPtr) 
                    301:            realloc(table->table, table->max_elements * sizeof(xmlElement));
                    302:        if (table->table) {
                    303:            fprintf(stderr, "xmlAddElementDecl: out of memory\n");
                    304:            return(NULL);
                    305:        }
1.1       daniel    306:     }
1.2       daniel    307:     ret = &table->table[table->nb_elements];
                    308: 
                    309:     /*
                    310:      * fill the structure.
                    311:      */
1.1       daniel    312:     ret->type = type;
                    313:     ret->name = xmlStrdup(name);
                    314:     ret->content = content;
1.2       daniel    315:     table->nb_elements++;
                    316: 
                    317:     return(ret);
                    318: }
                    319: 
                    320: /**
                    321:  * xmlFreeElement:
                    322:  * @elem:  An element
                    323:  *
                    324:  * Deallocate the memory used by an element definition
                    325:  */
                    326: void
                    327: xmlFreeElement(xmlElementPtr elem) {
                    328:     if (elem == NULL) return;
                    329:     xmlFreeElementContent(elem->content);
                    330:     if (elem->name != NULL)
                    331:        free((CHAR *) elem->name);
                    332:     memset(elem, -1, sizeof(xmlElement));
                    333: }
1.1       daniel    334: 
1.2       daniel    335: /**
                    336:  * xmlFreeElementTable:
                    337:  * @table:  An element table
                    338:  *
1.4       daniel    339:  * Deallocate the memory used by an element hash table.
1.2       daniel    340:  */
                    341: void
                    342: xmlFreeElementTable(xmlElementTablePtr table) {
                    343:     int i;
                    344: 
                    345:     if (table == NULL) return;
                    346: 
                    347:     for (i = 0;i < table->nb_elements;i++) {
                    348:         xmlFreeElement(&table->table[i]);
                    349:     }
                    350:     free(table->table);
                    351:     free(table);
                    352: }
                    353: 
                    354: /**
                    355:  * xmlCopyElementTable:
                    356:  * @table:  An element table
                    357:  *
                    358:  * Build a copy of an element table.
                    359:  * 
1.6       daniel    360:  * Returns the new xmlElementTablePtr or NULL in case of error.
1.2       daniel    361:  */
                    362: xmlElementTablePtr
                    363: xmlCopyElementTable(xmlElementTablePtr table) {
                    364:     xmlElementTablePtr ret;
                    365:     xmlElementPtr cur, ent;
                    366:     int i;
1.1       daniel    367: 
1.2       daniel    368:     ret = (xmlElementTablePtr) malloc(sizeof(xmlElementTable));
                    369:     if (ret == NULL) {
                    370:         fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
                    371:        return(NULL);
                    372:     }
                    373:     ret->table = (xmlElementPtr) malloc(table->max_elements *
                    374:                                          sizeof(xmlElement));
                    375:     if (ret->table == NULL) {
                    376:         fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
                    377:        free(ret);
                    378:        return(NULL);
                    379:     }
                    380:     ret->max_elements = table->max_elements;
                    381:     ret->nb_elements = table->nb_elements;
                    382:     for (i = 0;i < ret->nb_elements;i++) {
                    383:        cur = &ret->table[i];
                    384:        ent = &table->table[i];
                    385:        cur->type = ent->type;
                    386:        if (ent->name != NULL)
                    387:            cur->name = xmlStrdup(ent->name);
                    388:        else
                    389:            cur->name = NULL;
                    390:        cur->content = xmlCopyElementContent(ent->content);
                    391:     }
1.1       daniel    392:     return(ret);
                    393: }
                    394: 
1.2       daniel    395: /**
                    396:  * xmlDumpElementTable:
                    397:  * @table:  An element table
                    398:  *
                    399:  * This will dump the content of the element table as an XML DTD definition
                    400:  *
                    401:  * NOTE: TODO an extra parameter allowing a reentant implementation will
                    402:  *       be added.
                    403:  */
                    404: void
1.8     ! daniel    405: xmlDumpElementTable(xmlBufferPtr buf, xmlElementTablePtr table) {
1.2       daniel    406:     int i;
                    407:     xmlElementPtr cur;
                    408: 
                    409:     if (table == NULL) return;
                    410: 
                    411:     for (i = 0;i < table->nb_elements;i++) {
                    412:         cur = &table->table[i];
                    413:         switch (cur->type) {
                    414:            case XML_ELEMENT_TYPE_EMPTY:
1.8     ! daniel    415:                xmlBufferWriteChar(buf, "<!ELEMENT ");
        !           416:                xmlBufferWriteCHAR(buf, cur->name);
        !           417:                xmlBufferWriteChar(buf, " EMPTY>\n");
1.2       daniel    418:                break;
                    419:            case XML_ELEMENT_TYPE_ANY:
1.8     ! daniel    420:                xmlBufferWriteChar(buf, "<!ELEMENT ");
        !           421:                xmlBufferWriteCHAR(buf, cur->name);
        !           422:                xmlBufferWriteChar(buf, " ANY>\n");
1.2       daniel    423:                break;
                    424:            case XML_ELEMENT_TYPE_MIXED:
1.8     ! daniel    425:                xmlBufferWriteChar(buf, "<!ELEMENT ");
        !           426:                xmlBufferWriteCHAR(buf, cur->name);
        !           427:                xmlBufferWriteChar(buf, " ");
        !           428:                xmlDumpElementContent(buf, cur->content, 1);
        !           429:                xmlBufferWriteChar(buf, ">\n");
1.2       daniel    430:                break;
                    431:            case XML_ELEMENT_TYPE_ELEMENT:
1.8     ! daniel    432:                xmlBufferWriteChar(buf, "<!ELEMENT ");
        !           433:                xmlBufferWriteCHAR(buf, cur->name);
        !           434:                xmlBufferWriteChar(buf, " ");
        !           435:                xmlDumpElementContent(buf, cur->content, 1);
        !           436:                xmlBufferWriteChar(buf, ">\n");
1.2       daniel    437:                break;
                    438:            default:
                    439:                fprintf(stderr,
                    440:                    "xmlDumpElementTable: internal: unknown type %d\n",
                    441:                        cur->type);
                    442:        }
1.4       daniel    443:     }
                    444: }
                    445: 
                    446: /**
                    447:  * xmlCreateEnumeration:
                    448:  * @name:  the enumeration name or NULL
                    449:  *
                    450:  * create and initialize an enumeration attribute node.
                    451:  *
1.6       daniel    452:  * Returns the xmlEnumerationPtr just created or NULL in case
1.4       daniel    453:  *                of error.
                    454:  */
                    455: xmlEnumerationPtr
                    456: xmlCreateEnumeration(CHAR *name) {
                    457:     xmlEnumerationPtr ret;
                    458: 
                    459:     ret = (xmlEnumerationPtr) malloc(sizeof(xmlEnumeration));
                    460:     if (ret == NULL) {
                    461:         fprintf(stderr, "xmlCreateEnumeration : malloc(%d) failed\n",
                    462:                sizeof(xmlEnumeration));
                    463:         return(NULL);
                    464:     }
                    465: 
                    466:     if (name != NULL)
                    467:         ret->name = xmlStrdup(name);
                    468:     else
                    469:         ret->name = NULL;
                    470:     ret->next = NULL;
                    471:     return(ret);
                    472: }
                    473: 
                    474: /**
                    475:  * xmlFreeEnumeration:
                    476:  * @cur:  the tree to free.
                    477:  *
                    478:  * free an enumeration attribute node (recursive).
                    479:  */
                    480: void
                    481: xmlFreeEnumeration(xmlEnumerationPtr cur) {
                    482:     if (cur == NULL) return;
                    483: 
                    484:     if (cur->next != NULL) xmlFreeEnumeration(cur->next);
                    485: 
                    486:     if (cur->name != NULL) free((CHAR *) cur->name);
                    487:     memset(cur, -1, sizeof(xmlEnumeration));
                    488:     free(cur);
                    489: }
                    490: 
                    491: /**
                    492:  * xmlCopyEnumeration:
                    493:  * @cur:  the tree to copy.
                    494:  *
                    495:  * Copy an enumeration attribute node (recursive).
                    496:  *
1.6       daniel    497:  * Returns the xmlEnumerationPtr just created or NULL in case
1.4       daniel    498:  *                of error.
                    499:  */
                    500: xmlEnumerationPtr
                    501: xmlCopyEnumeration(xmlEnumerationPtr cur) {
                    502:     xmlEnumerationPtr ret;
                    503: 
                    504:     if (cur == NULL) return(NULL);
                    505:     ret = xmlCreateEnumeration((CHAR *) cur->name);
                    506: 
                    507:     if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
                    508:     else ret->next = NULL;
                    509: 
                    510:     return(ret);
                    511: }
                    512: 
                    513: /**
                    514:  * xmlCreateAttributeTable:
                    515:  *
                    516:  * create and initialize an empty attribute hash table.
                    517:  *
1.6       daniel    518:  * Returns the xmlAttributeTablePtr just created or NULL in case
1.4       daniel    519:  *                of error.
                    520:  */
                    521: xmlAttributeTablePtr
                    522: xmlCreateAttributeTable(void) {
                    523:     xmlAttributeTablePtr ret;
                    524: 
                    525:     ret = (xmlAttributeTablePtr) 
                    526:          malloc(sizeof(xmlAttributeTable));
                    527:     if (ret == NULL) {
                    528:         fprintf(stderr, "xmlCreateAttributeTable : malloc(%d) failed\n",
                    529:                sizeof(xmlAttributeTable));
                    530:         return(NULL);
                    531:     }
                    532:     ret->max_attributes = XML_MIN_ATTRIBUTE_TABLE;
                    533:     ret->nb_attributes = 0;
                    534:     ret->table = (xmlAttributePtr ) 
                    535:          malloc(ret->max_attributes * sizeof(xmlAttribute));
                    536:     if (ret == NULL) {
                    537:         fprintf(stderr, "xmlCreateAttributeTable : malloc(%d) failed\n",
                    538:                ret->max_attributes * sizeof(xmlAttribute));
                    539:        free(ret);
                    540:         return(NULL);
                    541:     }
                    542:     return(ret);
                    543: }
                    544: 
                    545: 
                    546: /**
                    547:  * xmlAddAttributeDecl:
1.6       daniel    548:  * @dtd:  pointer to the DTD
                    549:  * @elem:  the element name
                    550:  * @name:  the attribute name
                    551:  * @type:  the attribute type
                    552:  * @def:  the attribute default type
                    553:  * @defaultValue:  the attribute default value
                    554:  * @tree:  if it's an enumeration, the associated list
1.4       daniel    555:  *
                    556:  * Register a new attribute declaration
                    557:  *
1.6       daniel    558:  * Returns NULL if not, othervise the entity
1.4       daniel    559:  */
                    560: xmlAttributePtr
1.7       daniel    561: xmlAddAttributeDecl(xmlDtdPtr dtd, const CHAR *elem, const CHAR *name,
                    562:                     int type, int def, const CHAR *defaultValue,
                    563:                    xmlEnumerationPtr tree) {
1.4       daniel    564:     xmlAttributePtr ret, cur;
                    565:     xmlAttributeTablePtr table;
                    566:     int i;
                    567: 
                    568:     if (dtd == NULL) {
                    569:         fprintf(stderr, "xmlAddAttributeDecl: dtd == NULL\n");
                    570:        return(NULL);
                    571:     }
                    572:     if (name == NULL) {
                    573:         fprintf(stderr, "xmlAddAttributeDecl: name == NULL\n");
                    574:        return(NULL);
                    575:     }
                    576:     if (elem == NULL) {
                    577:         fprintf(stderr, "xmlAddAttributeDecl: elem == NULL\n");
                    578:        return(NULL);
                    579:     }
                    580:     /* TODO: Lacks verifications !!! */
                    581:     switch (type) {
                    582:         case XML_ATTRIBUTE_CDATA:
                    583:            break;
                    584:         case XML_ATTRIBUTE_ID:
                    585:            break;
                    586:         case XML_ATTRIBUTE_IDREF:
                    587:            break;
                    588:         case XML_ATTRIBUTE_IDREFS:
                    589:            break;
                    590:         case XML_ATTRIBUTE_ENTITY:
                    591:            break;
                    592:         case XML_ATTRIBUTE_ENTITIES:
                    593:            break;
                    594:         case XML_ATTRIBUTE_NMTOKEN:
                    595:            break;
                    596:         case XML_ATTRIBUTE_NMTOKENS:
                    597:            break;
                    598:         case XML_ATTRIBUTE_ENUMERATION:
                    599:            break;
                    600:         case XML_ATTRIBUTE_NOTATION:
                    601:            break;
                    602:        default:
                    603:            fprintf(stderr, "xmlAddAttributeDecl: unknown type %d\n", type);
                    604:            return(NULL);
                    605:     }
                    606: 
                    607:     /*
                    608:      * Create the Attribute table if needed.
                    609:      */
                    610:     table = dtd->attributes;
                    611:     if (table == NULL) 
                    612:         table = dtd->attributes = xmlCreateAttributeTable();
                    613:     if (table == NULL) {
                    614:        fprintf(stderr, "xmlAddAttributeDecl: Table creation failed!\n");
                    615:         return(NULL);
                    616:     }
                    617: 
                    618:     /*
                    619:      * Validity Check:
                    620:      * Search the DTD for previous declarations of the ATTLIST
                    621:      */
                    622:     for (i = 0;i < table->nb_attributes;i++) {
                    623:         cur = &table->table[i];
                    624:        if ((!xmlStrcmp(cur->name, name)) && (!xmlStrcmp(cur->elem, elem))) {
                    625:            /*
                    626:             * The attribute is already defined in this Dtd.
                    627:             */
                    628:            fprintf(stderr,
                    629:                    "xmlAddAttributeDecl: %s already defined\n", name);
                    630:        }
                    631:     }
                    632: 
                    633:     /*
                    634:      * Grow the table, if needed.
                    635:      */
                    636:     if (table->nb_attributes >= table->max_attributes) {
                    637:         /*
                    638:         * need more attributes.
                    639:         */
                    640:        table->max_attributes *= 2;
                    641:        table->table = (xmlAttributePtr) 
                    642:            realloc(table->table, table->max_attributes * sizeof(xmlAttribute));
                    643:        if (table->table) {
                    644:            fprintf(stderr, "xmlAddAttributeDecl: out of memory\n");
                    645:            return(NULL);
                    646:        }
                    647:     }
                    648:     ret = &table->table[table->nb_attributes];
                    649: 
                    650:     /*
                    651:      * fill the structure.
                    652:      */
                    653:     ret->type = type;
                    654:     ret->name = xmlStrdup(name);
                    655:     ret->elem = xmlStrdup(elem);
                    656:     ret->def = def;
                    657:     ret->tree = tree;
                    658:     if (defaultValue != NULL)
                    659:        ret->defaultValue = xmlStrdup(defaultValue);
                    660:     else
                    661:         ret->defaultValue = NULL;
                    662:     table->nb_attributes++;
                    663: 
                    664:     return(ret);
                    665: }
                    666: 
                    667: /**
                    668:  * xmlFreeAttribute:
                    669:  * @elem:  An attribute
                    670:  *
                    671:  * Deallocate the memory used by an attribute definition
                    672:  */
                    673: void
                    674: xmlFreeAttribute(xmlAttributePtr attr) {
                    675:     if (attr == NULL) return;
                    676:     if (attr->tree != NULL)
                    677:         xmlFreeEnumeration(attr->tree);
                    678:     if (attr->elem != NULL)
                    679:        free((CHAR *) attr->elem);
                    680:     if (attr->name != NULL)
                    681:        free((CHAR *) attr->name);
                    682:     if (attr->defaultValue != NULL)
                    683:        free((CHAR *) attr->defaultValue);
                    684:     memset(attr, -1, sizeof(xmlAttribute));
                    685: }
                    686: 
                    687: /**
                    688:  * xmlFreeAttributeTable:
                    689:  * @table:  An attribute table
                    690:  *
                    691:  * Deallocate the memory used by an entities hash table.
                    692:  */
                    693: void
                    694: xmlFreeAttributeTable(xmlAttributeTablePtr table) {
                    695:     int i;
                    696: 
                    697:     if (table == NULL) return;
                    698: 
                    699:     for (i = 0;i < table->nb_attributes;i++) {
                    700:         xmlFreeAttribute(&table->table[i]);
                    701:     }
                    702:     free(table->table);
                    703:     free(table);
                    704: }
                    705: 
                    706: /**
                    707:  * xmlCopyAttributeTable:
                    708:  * @table:  An attribute table
                    709:  *
                    710:  * Build a copy of an attribute table.
                    711:  * 
1.6       daniel    712:  * Returns the new xmlAttributeTablePtr or NULL in case of error.
1.4       daniel    713:  */
                    714: xmlAttributeTablePtr
                    715: xmlCopyAttributeTable(xmlAttributeTablePtr table) {
                    716:     xmlAttributeTablePtr ret;
                    717:     xmlAttributePtr cur, attr;
                    718:     int i;
                    719: 
                    720:     ret = (xmlAttributeTablePtr) malloc(sizeof(xmlAttributeTable));
                    721:     if (ret == NULL) {
                    722:         fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
                    723:        return(NULL);
                    724:     }
                    725:     ret->table = (xmlAttributePtr) malloc(table->max_attributes *
                    726:                                          sizeof(xmlAttribute));
                    727:     if (ret->table == NULL) {
                    728:         fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
                    729:        free(ret);
                    730:        return(NULL);
                    731:     }
                    732:     ret->max_attributes = table->max_attributes;
                    733:     ret->nb_attributes = table->nb_attributes;
                    734:     for (i = 0;i < ret->nb_attributes;i++) {
                    735:        cur = &ret->table[i];
                    736:        attr = &table->table[i];
                    737:        cur->type = attr->type;
                    738:        cur->def = attr->def;
                    739:        cur->tree = xmlCopyEnumeration(attr->tree);
                    740:        if (attr->elem != NULL)
                    741:            cur->elem = xmlStrdup(attr->elem);
                    742:        else
                    743:            cur->elem = NULL;
                    744:        if (attr->name != NULL)
                    745:            cur->name = xmlStrdup(attr->name);
                    746:        else
                    747:            cur->name = NULL;
                    748:        if (attr->defaultValue != NULL)
                    749:            cur->defaultValue = xmlStrdup(attr->defaultValue);
                    750:        else
                    751:            cur->defaultValue = NULL;
                    752:     }
                    753:     return(ret);
                    754: }
                    755: 
                    756: /**
                    757:  * xmlDumpAttributeTable:
                    758:  * @table:  An attribute table
                    759:  *
                    760:  * This will dump the content of the attribute table as an XML DTD definition
                    761:  *
                    762:  * NOTE: TODO an extra parameter allowing a reentant implementation will
                    763:  *       be added.
                    764:  */
                    765: void
1.8     ! daniel    766: xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
1.4       daniel    767:     int i;
                    768:     xmlAttributePtr cur;
                    769: 
                    770:     if (table == NULL) return;
                    771: 
                    772:     for (i = 0;i < table->nb_attributes;i++) {
                    773:         cur = &table->table[i];
1.8     ! daniel    774:        xmlBufferWriteChar(buf, "<!ATTLIST ");
        !           775:        xmlBufferWriteCHAR(buf, cur->elem);
        !           776:        xmlBufferWriteChar(buf, " ");
        !           777:        xmlBufferWriteCHAR(buf, cur->name);
1.4       daniel    778:         switch (cur->type) {
                    779:             case XML_ATTRIBUTE_CDATA:
1.8     ! daniel    780:                xmlBufferWriteChar(buf, " CDATA");
1.4       daniel    781:                 break;
                    782:             case XML_ATTRIBUTE_ID:
1.8     ! daniel    783:                xmlBufferWriteChar(buf, " ID");
1.4       daniel    784:                 break;
                    785:             case XML_ATTRIBUTE_IDREF:
1.8     ! daniel    786:                xmlBufferWriteChar(buf, " IDREF");
1.4       daniel    787:                 break;
                    788:             case XML_ATTRIBUTE_IDREFS:
1.8     ! daniel    789:                xmlBufferWriteChar(buf, " IDREFS");
1.4       daniel    790:                 break;
                    791:             case XML_ATTRIBUTE_ENTITY:
1.8     ! daniel    792:                xmlBufferWriteChar(buf, " ENTITY");
1.4       daniel    793:                 break;
                    794:             case XML_ATTRIBUTE_ENTITIES:
1.8     ! daniel    795:                xmlBufferWriteChar(buf, " ENTITIES");
1.4       daniel    796:                 break;
                    797:             case XML_ATTRIBUTE_NMTOKEN:
1.8     ! daniel    798:                xmlBufferWriteChar(buf, " NMTOKEN");
1.4       daniel    799:                 break;
                    800:             case XML_ATTRIBUTE_NMTOKENS:
1.8     ! daniel    801:                xmlBufferWriteChar(buf, " NMTOKENS");
1.4       daniel    802:                 break;
                    803:             case XML_ATTRIBUTE_ENUMERATION:
1.8     ! daniel    804:                 xmlBufferWriteChar(buf, " (pbm)");
1.4       daniel    805:                 break;
                    806:             case XML_ATTRIBUTE_NOTATION:
1.8     ! daniel    807:                 xmlBufferWriteChar(buf, " NOTATION (pbm)");
1.4       daniel    808:                 break;
                    809:            default:
                    810:                fprintf(stderr,
                    811:                    "xmlDumpAttributeTable: internal: unknown type %d\n",
                    812:                        cur->type);
                    813:        }
                    814:         switch (cur->def) {
                    815:             case XML_ATTRIBUTE_NONE:
                    816:                 break;
                    817:             case XML_ATTRIBUTE_REQUIRED:
1.8     ! daniel    818:                xmlBufferWriteChar(buf, " #REQUIRED");
1.4       daniel    819:                 break;
                    820:             case XML_ATTRIBUTE_IMPLIED:
1.8     ! daniel    821:                xmlBufferWriteChar(buf, " #IMPLIED");
1.6       daniel    822:                if (cur->defaultValue != NULL) {
1.8     ! daniel    823:                    xmlBufferWriteChar(buf, " \"");
        !           824:                    xmlBufferWriteCHAR(buf, cur->defaultValue);
        !           825:                    xmlBufferWriteChar(buf, "\"");
1.6       daniel    826:                }
1.4       daniel    827:                 break;
                    828:             case XML_ATTRIBUTE_FIXED:
1.8     ! daniel    829:                xmlBufferWriteChar(buf, " #FIXED \"");
        !           830:                xmlBufferWriteCHAR(buf, cur->defaultValue);
        !           831:                xmlBufferWriteChar(buf, "\"");
1.4       daniel    832:                 break;
                    833:            default:
                    834:                fprintf(stderr,
                    835:                    "xmlDumpAttributeTable: internal: unknown default %d\n",
                    836:                        cur->def);
                    837:         }
1.8     ! daniel    838:         xmlBufferWriteChar(buf, ">\n");
1.5       daniel    839:     }
                    840: }
                    841: 
                    842: /************************************************************************
                    843:  *                                                                     *
                    844:  *                             NOTATIONs                               *
                    845:  *                                                                     *
                    846:  ************************************************************************/
                    847: /**
                    848:  * xmlCreateNotationTable:
                    849:  *
                    850:  * create and initialize an empty notation hash table.
                    851:  *
1.6       daniel    852:  * Returns the xmlNotationTablePtr just created or NULL in case
1.5       daniel    853:  *                of error.
                    854:  */
                    855: xmlNotationTablePtr
                    856: xmlCreateNotationTable(void) {
                    857:     xmlNotationTablePtr ret;
                    858: 
                    859:     ret = (xmlNotationTablePtr) 
                    860:          malloc(sizeof(xmlNotationTable));
                    861:     if (ret == NULL) {
                    862:         fprintf(stderr, "xmlCreateNotationTable : malloc(%d) failed\n",
                    863:                sizeof(xmlNotationTable));
                    864:         return(NULL);
                    865:     }
                    866:     ret->max_notations = XML_MIN_NOTATION_TABLE;
                    867:     ret->nb_notations = 0;
                    868:     ret->table = (xmlNotationPtr ) 
                    869:          malloc(ret->max_notations * sizeof(xmlNotation));
                    870:     if (ret == NULL) {
                    871:         fprintf(stderr, "xmlCreateNotationTable : malloc(%d) failed\n",
                    872:                ret->max_notations * sizeof(xmlNotation));
                    873:        free(ret);
                    874:         return(NULL);
                    875:     }
                    876:     return(ret);
                    877: }
                    878: 
                    879: 
                    880: /**
                    881:  * xmlAddNotationDecl:
1.6       daniel    882:  * @dtd:  pointer to the DTD
1.5       daniel    883:  * @name:  the entity name
1.6       daniel    884:  * @PublicID:  the public identifier or NULL
                    885:  * @SystemID:  the system identifier or NULL
1.5       daniel    886:  *
                    887:  * Register a new notation declaration
                    888:  *
1.6       daniel    889:  * Returns NULL if not, othervise the entity
1.5       daniel    890:  */
                    891: xmlNotationPtr
1.7       daniel    892: xmlAddNotationDecl(xmlDtdPtr dtd, const CHAR *name, const CHAR *PublicID,
                    893:                    const CHAR *SystemID) {
1.5       daniel    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
1.8     ! daniel   1064: xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
1.5       daniel   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];
1.8     ! daniel   1072:        xmlBufferWriteChar(buf, "<!NOTATION ");
        !          1073:        xmlBufferWriteCHAR(buf, cur->name);
1.5       daniel   1074:        if (cur->PublicID != NULL) {
1.8     ! daniel   1075:            xmlBufferWriteChar(buf, " PUBLIC \"");
        !          1076:            xmlBufferWriteCHAR(buf, cur->PublicID);
        !          1077:            xmlBufferWriteChar(buf, "\"");
1.5       daniel   1078:            if (cur->SystemID != NULL) {
1.8     ! daniel   1079:                xmlBufferWriteChar(buf, " ");
        !          1080:                xmlBufferWriteCHAR(buf, cur->SystemID);
1.5       daniel   1081:            }
                   1082:        } else {
1.8     ! daniel   1083:            xmlBufferWriteChar(buf, " SYSTEM ");
        !          1084:            xmlBufferWriteCHAR(buf, cur->SystemID);
1.5       daniel   1085:        }
1.8     ! daniel   1086:         xmlBufferWriteChar(buf, " >\n");
1.2       daniel   1087:     }
                   1088: }

Webmaster