Annotation of XML/valid.c, revision 1.5

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:  *
                     29:  * return values: NULL if not, othervise the new element content structure
                     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:  * 
                     73:  * return values: the new xmlElementContentPtr or NULL in case of error.
                     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:  *
                    180:  * return values: the xmlElementTablePtr just created or NULL in case of error.
                    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:
                    209:  * @name:  the entity name
                    210:  *
                    211:  * Register a new element declaration
                    212:  *
                    213:  * return values: NULL if not, othervise the entity
                    214:  */
                    215: xmlElementPtr
1.4       daniel    216: xmlAddElementDecl(xmlDtdPtr dtd, CHAR *name, int type, 
1.1       daniel    217:                   xmlElementContentPtr content) {
1.2       daniel    218:     xmlElementPtr ret, cur;
                    219:     xmlElementTablePtr table;
                    220:     int i;
1.1       daniel    221: 
                    222:     if (dtd == NULL) {
                    223:         fprintf(stderr, "xmlAddElementDecl: dtd == NULL\n");
                    224:        return(NULL);
                    225:     }
                    226:     if (name == NULL) {
                    227:         fprintf(stderr, "xmlAddElementDecl: name == NULL\n");
                    228:        return(NULL);
                    229:     }
                    230:     switch (type) {
                    231:         case XML_ELEMENT_TYPE_EMPTY:
                    232:            if (content != NULL) {
                    233:                fprintf(stderr,
                    234:                        "xmlAddElementDecl: content != NULL for EMPTY\n");
                    235:                return(NULL);
                    236:            }
                    237:            break;
                    238:        case XML_ELEMENT_TYPE_ANY:
                    239:            if (content != NULL) {
                    240:                fprintf(stderr,
                    241:                        "xmlAddElementDecl: content != NULL for ANY\n");
                    242:                return(NULL);
                    243:            }
                    244:            break;
                    245:        case XML_ELEMENT_TYPE_MIXED:
                    246:            if (content == NULL) {
                    247:                fprintf(stderr,
                    248:                        "xmlAddElementDecl: content == NULL for MIXED\n");
                    249:                return(NULL);
                    250:            }
                    251:            break;
                    252:        case XML_ELEMENT_TYPE_ELEMENT:
                    253:            if (content == NULL) {
                    254:                fprintf(stderr,
                    255:                        "xmlAddElementDecl: content == NULL for ELEMENT\n");
                    256:                return(NULL);
                    257:            }
                    258:            break;
                    259:        default:
                    260:            fprintf(stderr, "xmlAddElementDecl: unknown type %d\n", type);
                    261:            return(NULL);
                    262:     }
                    263: 
                    264:     /*
1.2       daniel    265:      * Create the Element table if needed.
                    266:      */
                    267:     table = dtd->elements;
                    268:     if (table == NULL) 
                    269:         table = dtd->elements = xmlCreateElementTable();
                    270:     if (table == NULL) {
                    271:        fprintf(stderr, "xmlAddElementDecl: Table creation failed!\n");
                    272:         return(NULL);
                    273:     }
                    274: 
                    275:     /*
1.1       daniel    276:      * Validity Check:
                    277:      * Search the DTD for previous declarations of the ELEMENT
                    278:      */
1.2       daniel    279:     for (i = 0;i < table->nb_elements;i++) {
                    280:         cur = &table->table[i];
                    281:        if (!xmlStrcmp(cur->name, name)) {
                    282:            /*
                    283:             * The element is already defined in this Dtd.
                    284:             */
                    285:            fprintf(stderr,
                    286:                    "xmlAddElementDecl: %s already defined\n", name);
                    287:            return(NULL);
                    288:        }
                    289:     }
1.1       daniel    290: 
                    291:     /*
1.2       daniel    292:      * Grow the table, if needed.
1.1       daniel    293:      */
1.2       daniel    294:     if (table->nb_elements >= table->max_elements) {
                    295:         /*
                    296:         * need more elements.
                    297:         */
                    298:        table->max_elements *= 2;
                    299:        table->table = (xmlElementPtr) 
                    300:            realloc(table->table, table->max_elements * sizeof(xmlElement));
                    301:        if (table->table) {
                    302:            fprintf(stderr, "xmlAddElementDecl: out of memory\n");
                    303:            return(NULL);
                    304:        }
1.1       daniel    305:     }
1.2       daniel    306:     ret = &table->table[table->nb_elements];
                    307: 
                    308:     /*
                    309:      * fill the structure.
                    310:      */
1.1       daniel    311:     ret->type = type;
                    312:     ret->name = xmlStrdup(name);
                    313:     ret->content = content;
1.2       daniel    314:     table->nb_elements++;
                    315: 
                    316:     return(ret);
                    317: }
                    318: 
                    319: /**
                    320:  * xmlFreeElement:
                    321:  * @elem:  An element
                    322:  *
                    323:  * Deallocate the memory used by an element definition
                    324:  */
                    325: void
                    326: xmlFreeElement(xmlElementPtr elem) {
                    327:     if (elem == NULL) return;
                    328:     xmlFreeElementContent(elem->content);
                    329:     if (elem->name != NULL)
                    330:        free((CHAR *) elem->name);
                    331:     memset(elem, -1, sizeof(xmlElement));
                    332: }
1.1       daniel    333: 
1.2       daniel    334: /**
                    335:  * xmlFreeElementTable:
                    336:  * @table:  An element table
                    337:  *
1.4       daniel    338:  * Deallocate the memory used by an element hash table.
1.2       daniel    339:  */
                    340: void
                    341: xmlFreeElementTable(xmlElementTablePtr table) {
                    342:     int i;
                    343: 
                    344:     if (table == NULL) return;
                    345: 
                    346:     for (i = 0;i < table->nb_elements;i++) {
                    347:         xmlFreeElement(&table->table[i]);
                    348:     }
                    349:     free(table->table);
                    350:     free(table);
                    351: }
                    352: 
                    353: /**
                    354:  * xmlCopyElementTable:
                    355:  * @table:  An element table
                    356:  *
                    357:  * Build a copy of an element table.
                    358:  * 
                    359:  * return values: the new xmlElementTablePtr or NULL in case of error.
                    360:  */
                    361: xmlElementTablePtr
                    362: xmlCopyElementTable(xmlElementTablePtr table) {
                    363:     xmlElementTablePtr ret;
                    364:     xmlElementPtr cur, ent;
                    365:     int i;
1.1       daniel    366: 
1.2       daniel    367:     ret = (xmlElementTablePtr) malloc(sizeof(xmlElementTable));
                    368:     if (ret == NULL) {
                    369:         fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
                    370:        return(NULL);
                    371:     }
                    372:     ret->table = (xmlElementPtr) malloc(table->max_elements *
                    373:                                          sizeof(xmlElement));
                    374:     if (ret->table == NULL) {
                    375:         fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
                    376:        free(ret);
                    377:        return(NULL);
                    378:     }
                    379:     ret->max_elements = table->max_elements;
                    380:     ret->nb_elements = table->nb_elements;
                    381:     for (i = 0;i < ret->nb_elements;i++) {
                    382:        cur = &ret->table[i];
                    383:        ent = &table->table[i];
                    384:        cur->type = ent->type;
                    385:        if (ent->name != NULL)
                    386:            cur->name = xmlStrdup(ent->name);
                    387:        else
                    388:            cur->name = NULL;
                    389:        cur->content = xmlCopyElementContent(ent->content);
                    390:     }
1.1       daniel    391:     return(ret);
                    392: }
                    393: 
1.2       daniel    394: /**
                    395:  * xmlDumpElementTable:
                    396:  * @table:  An element table
                    397:  *
                    398:  * This will dump the content of the element table as an XML DTD definition
                    399:  *
                    400:  * NOTE: TODO an extra parameter allowing a reentant implementation will
                    401:  *       be added.
                    402:  */
                    403: void
                    404: xmlDumpElementTable(xmlElementTablePtr table) {
                    405:     int i;
                    406:     xmlElementPtr cur;
                    407: 
                    408:     if (table == NULL) return;
                    409: 
                    410:     for (i = 0;i < table->nb_elements;i++) {
                    411:         cur = &table->table[i];
                    412:         switch (cur->type) {
                    413:            case XML_ELEMENT_TYPE_EMPTY:
                    414:                xmlBufferWriteChar("<!ELEMENT ");
                    415:                xmlBufferWriteCHAR(cur->name);
1.3       daniel    416:                xmlBufferWriteChar(" EMPTY>\n");
1.2       daniel    417:                break;
                    418:            case XML_ELEMENT_TYPE_ANY:
                    419:                xmlBufferWriteChar("<!ELEMENT ");
                    420:                xmlBufferWriteCHAR(cur->name);
1.3       daniel    421:                xmlBufferWriteChar(" ANY>\n");
1.2       daniel    422:                break;
                    423:            case XML_ELEMENT_TYPE_MIXED:
1.3       daniel    424:                xmlBufferWriteChar("<!ELEMENT ");
                    425:                xmlBufferWriteCHAR(cur->name);
                    426:                xmlBufferWriteChar(" ");
                    427:                xmlDumpElementContent(cur->content, 1);
                    428:                xmlBufferWriteChar(">\n");
1.2       daniel    429:                break;
                    430:            case XML_ELEMENT_TYPE_ELEMENT:
1.3       daniel    431:                xmlBufferWriteChar("<!ELEMENT ");
                    432:                xmlBufferWriteCHAR(cur->name);
                    433:                xmlBufferWriteChar(" ");
                    434:                xmlDumpElementContent(cur->content, 1);
                    435:                xmlBufferWriteChar(">\n");
1.2       daniel    436:                break;
                    437:            default:
                    438:                fprintf(stderr,
                    439:                    "xmlDumpElementTable: internal: unknown type %d\n",
                    440:                        cur->type);
                    441:        }
1.4       daniel    442:     }
                    443: }
                    444: 
                    445: /**
                    446:  * xmlCreateEnumeration:
                    447:  * @name:  the enumeration name or NULL
                    448:  *
                    449:  * create and initialize an enumeration attribute node.
                    450:  *
                    451:  * return values: the xmlEnumerationPtr just created or NULL in case
                    452:  *                of error.
                    453:  */
                    454: xmlEnumerationPtr
                    455: xmlCreateEnumeration(CHAR *name) {
                    456:     xmlEnumerationPtr ret;
                    457: 
                    458:     ret = (xmlEnumerationPtr) malloc(sizeof(xmlEnumeration));
                    459:     if (ret == NULL) {
                    460:         fprintf(stderr, "xmlCreateEnumeration : malloc(%d) failed\n",
                    461:                sizeof(xmlEnumeration));
                    462:         return(NULL);
                    463:     }
                    464: 
                    465:     if (name != NULL)
                    466:         ret->name = xmlStrdup(name);
                    467:     else
                    468:         ret->name = NULL;
                    469:     ret->next = NULL;
                    470:     return(ret);
                    471: }
                    472: 
                    473: /**
                    474:  * xmlFreeEnumeration:
                    475:  * @cur:  the tree to free.
                    476:  *
                    477:  * free an enumeration attribute node (recursive).
                    478:  */
                    479: void
                    480: xmlFreeEnumeration(xmlEnumerationPtr cur) {
                    481:     if (cur == NULL) return;
                    482: 
                    483:     if (cur->next != NULL) xmlFreeEnumeration(cur->next);
                    484: 
                    485:     if (cur->name != NULL) free((CHAR *) cur->name);
                    486:     memset(cur, -1, sizeof(xmlEnumeration));
                    487:     free(cur);
                    488: }
                    489: 
                    490: /**
                    491:  * xmlCopyEnumeration:
                    492:  * @cur:  the tree to copy.
                    493:  *
                    494:  * Copy an enumeration attribute node (recursive).
                    495:  *
                    496:  * return values: the xmlEnumerationPtr just created or NULL in case
                    497:  *                of error.
                    498:  */
                    499: xmlEnumerationPtr
                    500: xmlCopyEnumeration(xmlEnumerationPtr cur) {
                    501:     xmlEnumerationPtr ret;
                    502: 
                    503:     if (cur == NULL) return(NULL);
                    504:     ret = xmlCreateEnumeration((CHAR *) cur->name);
                    505: 
                    506:     if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
                    507:     else ret->next = NULL;
                    508: 
                    509:     return(ret);
                    510: }
                    511: 
                    512: /**
                    513:  * xmlCreateAttributeTable:
                    514:  *
                    515:  * create and initialize an empty attribute hash table.
                    516:  *
                    517:  * return values: the xmlAttributeTablePtr just created or NULL in case
                    518:  *                of error.
                    519:  */
                    520: xmlAttributeTablePtr
                    521: xmlCreateAttributeTable(void) {
                    522:     xmlAttributeTablePtr ret;
                    523: 
                    524:     ret = (xmlAttributeTablePtr) 
                    525:          malloc(sizeof(xmlAttributeTable));
                    526:     if (ret == NULL) {
                    527:         fprintf(stderr, "xmlCreateAttributeTable : malloc(%d) failed\n",
                    528:                sizeof(xmlAttributeTable));
                    529:         return(NULL);
                    530:     }
                    531:     ret->max_attributes = XML_MIN_ATTRIBUTE_TABLE;
                    532:     ret->nb_attributes = 0;
                    533:     ret->table = (xmlAttributePtr ) 
                    534:          malloc(ret->max_attributes * sizeof(xmlAttribute));
                    535:     if (ret == NULL) {
                    536:         fprintf(stderr, "xmlCreateAttributeTable : malloc(%d) failed\n",
                    537:                ret->max_attributes * sizeof(xmlAttribute));
                    538:        free(ret);
                    539:         return(NULL);
                    540:     }
                    541:     return(ret);
                    542: }
                    543: 
                    544: 
                    545: /**
                    546:  * xmlAddAttributeDecl:
                    547:  * @name:  the entity name
                    548:  *
                    549:  * Register a new attribute declaration
                    550:  *
                    551:  * return values: NULL if not, othervise the entity
                    552:  */
                    553: xmlAttributePtr
                    554: xmlAddAttributeDecl(xmlDtdPtr dtd, CHAR *elem, CHAR *name, int type, int def,
                    555:                     CHAR *defaultValue, xmlEnumerationPtr tree) {
                    556:     xmlAttributePtr ret, cur;
                    557:     xmlAttributeTablePtr table;
                    558:     int i;
                    559: 
                    560:     if (dtd == NULL) {
                    561:         fprintf(stderr, "xmlAddAttributeDecl: dtd == NULL\n");
                    562:        return(NULL);
                    563:     }
                    564:     if (name == NULL) {
                    565:         fprintf(stderr, "xmlAddAttributeDecl: name == NULL\n");
                    566:        return(NULL);
                    567:     }
                    568:     if (elem == NULL) {
                    569:         fprintf(stderr, "xmlAddAttributeDecl: elem == NULL\n");
                    570:        return(NULL);
                    571:     }
                    572:     /* TODO: Lacks verifications !!! */
                    573:     switch (type) {
                    574:         case XML_ATTRIBUTE_CDATA:
                    575:            break;
                    576:         case XML_ATTRIBUTE_ID:
                    577:            break;
                    578:         case XML_ATTRIBUTE_IDREF:
                    579:            break;
                    580:         case XML_ATTRIBUTE_IDREFS:
                    581:            break;
                    582:         case XML_ATTRIBUTE_ENTITY:
                    583:            break;
                    584:         case XML_ATTRIBUTE_ENTITIES:
                    585:            break;
                    586:         case XML_ATTRIBUTE_NMTOKEN:
                    587:            break;
                    588:         case XML_ATTRIBUTE_NMTOKENS:
                    589:            break;
                    590:         case XML_ATTRIBUTE_ENUMERATION:
                    591:            break;
                    592:         case XML_ATTRIBUTE_NOTATION:
                    593:            break;
                    594:        default:
                    595:            fprintf(stderr, "xmlAddAttributeDecl: unknown type %d\n", type);
                    596:            return(NULL);
                    597:     }
                    598: 
                    599:     /*
                    600:      * Create the Attribute table if needed.
                    601:      */
                    602:     table = dtd->attributes;
                    603:     if (table == NULL) 
                    604:         table = dtd->attributes = xmlCreateAttributeTable();
                    605:     if (table == NULL) {
                    606:        fprintf(stderr, "xmlAddAttributeDecl: Table creation failed!\n");
                    607:         return(NULL);
                    608:     }
                    609: 
                    610:     /*
                    611:      * Validity Check:
                    612:      * Search the DTD for previous declarations of the ATTLIST
                    613:      */
                    614:     for (i = 0;i < table->nb_attributes;i++) {
                    615:         cur = &table->table[i];
                    616:        if ((!xmlStrcmp(cur->name, name)) && (!xmlStrcmp(cur->elem, elem))) {
                    617:            /*
                    618:             * The attribute is already defined in this Dtd.
                    619:             */
                    620:            fprintf(stderr,
                    621:                    "xmlAddAttributeDecl: %s already defined\n", name);
                    622:        }
                    623:     }
                    624: 
                    625:     /*
                    626:      * Grow the table, if needed.
                    627:      */
                    628:     if (table->nb_attributes >= table->max_attributes) {
                    629:         /*
                    630:         * need more attributes.
                    631:         */
                    632:        table->max_attributes *= 2;
                    633:        table->table = (xmlAttributePtr) 
                    634:            realloc(table->table, table->max_attributes * sizeof(xmlAttribute));
                    635:        if (table->table) {
                    636:            fprintf(stderr, "xmlAddAttributeDecl: out of memory\n");
                    637:            return(NULL);
                    638:        }
                    639:     }
                    640:     ret = &table->table[table->nb_attributes];
                    641: 
                    642:     /*
                    643:      * fill the structure.
                    644:      */
                    645:     ret->type = type;
                    646:     ret->name = xmlStrdup(name);
                    647:     ret->elem = xmlStrdup(elem);
                    648:     ret->def = def;
                    649:     ret->tree = tree;
                    650:     if (defaultValue != NULL)
                    651:        ret->defaultValue = xmlStrdup(defaultValue);
                    652:     else
                    653:         ret->defaultValue = NULL;
                    654:     table->nb_attributes++;
                    655: 
                    656:     return(ret);
                    657: }
                    658: 
                    659: /**
                    660:  * xmlFreeAttribute:
                    661:  * @elem:  An attribute
                    662:  *
                    663:  * Deallocate the memory used by an attribute definition
                    664:  */
                    665: void
                    666: xmlFreeAttribute(xmlAttributePtr attr) {
                    667:     if (attr == NULL) return;
                    668:     if (attr->tree != NULL)
                    669:         xmlFreeEnumeration(attr->tree);
                    670:     if (attr->elem != NULL)
                    671:        free((CHAR *) attr->elem);
                    672:     if (attr->name != NULL)
                    673:        free((CHAR *) attr->name);
                    674:     if (attr->defaultValue != NULL)
                    675:        free((CHAR *) attr->defaultValue);
                    676:     memset(attr, -1, sizeof(xmlAttribute));
                    677: }
                    678: 
                    679: /**
                    680:  * xmlFreeAttributeTable:
                    681:  * @table:  An attribute table
                    682:  *
                    683:  * Deallocate the memory used by an entities hash table.
                    684:  */
                    685: void
                    686: xmlFreeAttributeTable(xmlAttributeTablePtr table) {
                    687:     int i;
                    688: 
                    689:     if (table == NULL) return;
                    690: 
                    691:     for (i = 0;i < table->nb_attributes;i++) {
                    692:         xmlFreeAttribute(&table->table[i]);
                    693:     }
                    694:     free(table->table);
                    695:     free(table);
                    696: }
                    697: 
                    698: /**
                    699:  * xmlCopyAttributeTable:
                    700:  * @table:  An attribute table
                    701:  *
                    702:  * Build a copy of an attribute table.
                    703:  * 
                    704:  * return values: the new xmlAttributeTablePtr or NULL in case of error.
                    705:  */
                    706: xmlAttributeTablePtr
                    707: xmlCopyAttributeTable(xmlAttributeTablePtr table) {
                    708:     xmlAttributeTablePtr ret;
                    709:     xmlAttributePtr cur, attr;
                    710:     int i;
                    711: 
                    712:     ret = (xmlAttributeTablePtr) malloc(sizeof(xmlAttributeTable));
                    713:     if (ret == NULL) {
                    714:         fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
                    715:        return(NULL);
                    716:     }
                    717:     ret->table = (xmlAttributePtr) malloc(table->max_attributes *
                    718:                                          sizeof(xmlAttribute));
                    719:     if (ret->table == NULL) {
                    720:         fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
                    721:        free(ret);
                    722:        return(NULL);
                    723:     }
                    724:     ret->max_attributes = table->max_attributes;
                    725:     ret->nb_attributes = table->nb_attributes;
                    726:     for (i = 0;i < ret->nb_attributes;i++) {
                    727:        cur = &ret->table[i];
                    728:        attr = &table->table[i];
                    729:        cur->type = attr->type;
                    730:        cur->def = attr->def;
                    731:        cur->tree = xmlCopyEnumeration(attr->tree);
                    732:        if (attr->elem != NULL)
                    733:            cur->elem = xmlStrdup(attr->elem);
                    734:        else
                    735:            cur->elem = NULL;
                    736:        if (attr->name != NULL)
                    737:            cur->name = xmlStrdup(attr->name);
                    738:        else
                    739:            cur->name = NULL;
                    740:        if (attr->defaultValue != NULL)
                    741:            cur->defaultValue = xmlStrdup(attr->defaultValue);
                    742:        else
                    743:            cur->defaultValue = NULL;
                    744:     }
                    745:     return(ret);
                    746: }
                    747: 
                    748: /**
                    749:  * xmlDumpAttributeTable:
                    750:  * @table:  An attribute table
                    751:  *
                    752:  * This will dump the content of the attribute table as an XML DTD definition
                    753:  *
                    754:  * NOTE: TODO an extra parameter allowing a reentant implementation will
                    755:  *       be added.
                    756:  */
                    757: void
                    758: xmlDumpAttributeTable(xmlAttributeTablePtr table) {
                    759:     int i;
                    760:     xmlAttributePtr cur;
                    761: 
                    762:     if (table == NULL) return;
                    763: 
                    764:     for (i = 0;i < table->nb_attributes;i++) {
                    765:         cur = &table->table[i];
                    766:        xmlBufferWriteChar("<!ATTLIST ");
                    767:        xmlBufferWriteCHAR(cur->elem);
                    768:        xmlBufferWriteChar(" ");
                    769:        xmlBufferWriteCHAR(cur->name);
                    770:         switch (cur->type) {
                    771:             case XML_ATTRIBUTE_CDATA:
                    772:                xmlBufferWriteChar(" CDATA");
                    773:                 break;
                    774:             case XML_ATTRIBUTE_ID:
                    775:                xmlBufferWriteChar(" ID");
                    776:                 break;
                    777:             case XML_ATTRIBUTE_IDREF:
                    778:                xmlBufferWriteChar(" IDREF");
                    779:                 break;
                    780:             case XML_ATTRIBUTE_IDREFS:
                    781:                xmlBufferWriteChar(" IDREFS");
                    782:                 break;
                    783:             case XML_ATTRIBUTE_ENTITY:
                    784:                xmlBufferWriteChar(" ENTITY");
                    785:                 break;
                    786:             case XML_ATTRIBUTE_ENTITIES:
                    787:                xmlBufferWriteChar(" ENTITIES");
                    788:                 break;
                    789:             case XML_ATTRIBUTE_NMTOKEN:
                    790:                xmlBufferWriteChar(" NMTOKEN");
                    791:                 break;
                    792:             case XML_ATTRIBUTE_NMTOKENS:
                    793:                xmlBufferWriteChar(" NMTOKENS");
                    794:                 break;
                    795:             case XML_ATTRIBUTE_ENUMERATION:
                    796:                 xmlBufferWriteChar(" (pbm)");
                    797:                 break;
                    798:             case XML_ATTRIBUTE_NOTATION:
                    799:                 xmlBufferWriteChar(" NOTATION (pbm)");
                    800:                 break;
                    801:            default:
                    802:                fprintf(stderr,
                    803:                    "xmlDumpAttributeTable: internal: unknown type %d\n",
                    804:                        cur->type);
                    805:        }
                    806:         switch (cur->def) {
                    807:             case XML_ATTRIBUTE_NONE:
                    808:                 break;
                    809:             case XML_ATTRIBUTE_REQUIRED:
                    810:                xmlBufferWriteChar(" #REQUIRED");
                    811:                 break;
                    812:             case XML_ATTRIBUTE_IMPLIED:
                    813:                xmlBufferWriteChar(" #IMPLIED");
                    814:                 break;
                    815:             case XML_ATTRIBUTE_FIXED:
                    816:                xmlBufferWriteChar(" #FIXED \"");
                    817:                xmlBufferWriteCHAR(cur->defaultValue);
                    818:                xmlBufferWriteChar("\"");
                    819:                 break;
                    820:            default:
                    821:                fprintf(stderr,
                    822:                    "xmlDumpAttributeTable: internal: unknown default %d\n",
                    823:                        cur->def);
                    824:         }
                    825:         xmlBufferWriteChar(">\n");
1.5     ! daniel    826:     }
        !           827: }
        !           828: 
        !           829: /************************************************************************
        !           830:  *                                                                     *
        !           831:  *                             NOTATIONs                               *
        !           832:  *                                                                     *
        !           833:  ************************************************************************/
        !           834: /**
        !           835:  * xmlCreateNotationTable:
        !           836:  *
        !           837:  * create and initialize an empty notation hash table.
        !           838:  *
        !           839:  * return values: the xmlNotationTablePtr just created or NULL in case
        !           840:  *                of error.
        !           841:  */
        !           842: xmlNotationTablePtr
        !           843: xmlCreateNotationTable(void) {
        !           844:     xmlNotationTablePtr ret;
        !           845: 
        !           846:     ret = (xmlNotationTablePtr) 
        !           847:          malloc(sizeof(xmlNotationTable));
        !           848:     if (ret == NULL) {
        !           849:         fprintf(stderr, "xmlCreateNotationTable : malloc(%d) failed\n",
        !           850:                sizeof(xmlNotationTable));
        !           851:         return(NULL);
        !           852:     }
        !           853:     ret->max_notations = XML_MIN_NOTATION_TABLE;
        !           854:     ret->nb_notations = 0;
        !           855:     ret->table = (xmlNotationPtr ) 
        !           856:          malloc(ret->max_notations * sizeof(xmlNotation));
        !           857:     if (ret == NULL) {
        !           858:         fprintf(stderr, "xmlCreateNotationTable : malloc(%d) failed\n",
        !           859:                ret->max_notations * sizeof(xmlNotation));
        !           860:        free(ret);
        !           861:         return(NULL);
        !           862:     }
        !           863:     return(ret);
        !           864: }
        !           865: 
        !           866: 
        !           867: /**
        !           868:  * xmlAddNotationDecl:
        !           869:  * @name:  the entity name
        !           870:  *
        !           871:  * Register a new notation declaration
        !           872:  *
        !           873:  * return values: NULL if not, othervise the entity
        !           874:  */
        !           875: xmlNotationPtr
        !           876: xmlAddNotationDecl(xmlDtdPtr dtd, CHAR *name, CHAR *PublicID, CHAR *SystemID) {
        !           877:     xmlNotationPtr ret, cur;
        !           878:     xmlNotationTablePtr table;
        !           879:     int i;
        !           880: 
        !           881:     if (dtd == NULL) {
        !           882:         fprintf(stderr, "xmlAddNotationDecl: dtd == NULL\n");
        !           883:        return(NULL);
        !           884:     }
        !           885:     if (name == NULL) {
        !           886:         fprintf(stderr, "xmlAddNotationDecl: name == NULL\n");
        !           887:        return(NULL);
        !           888:     }
        !           889:     if ((PublicID == NULL) && (SystemID == NULL)) {
        !           890:         fprintf(stderr, "xmlAddNotationDecl: no PUBLIC ID nor SYSTEM ID\n");
        !           891:     }
        !           892: 
        !           893:     /*
        !           894:      * Create the Notation table if needed.
        !           895:      */
        !           896:     table = dtd->notations;
        !           897:     if (table == NULL) 
        !           898:         table = dtd->notations = xmlCreateNotationTable();
        !           899:     if (table == NULL) {
        !           900:        fprintf(stderr, "xmlAddNotationDecl: Table creation failed!\n");
        !           901:         return(NULL);
        !           902:     }
        !           903: 
        !           904:     /*
        !           905:      * Validity Check:
        !           906:      * Search the DTD for previous declarations of the ATTLIST
        !           907:      */
        !           908:     for (i = 0;i < table->nb_notations;i++) {
        !           909:         cur = &table->table[i];
        !           910:        if (!xmlStrcmp(cur->name, name)) {
        !           911:            /*
        !           912:             * The notation is already defined in this Dtd.
        !           913:             */
        !           914:            fprintf(stderr,
        !           915:                    "xmlAddNotationDecl: %s already defined\n", name);
        !           916:        }
        !           917:     }
        !           918: 
        !           919:     /*
        !           920:      * Grow the table, if needed.
        !           921:      */
        !           922:     if (table->nb_notations >= table->max_notations) {
        !           923:         /*
        !           924:         * need more notations.
        !           925:         */
        !           926:        table->max_notations *= 2;
        !           927:        table->table = (xmlNotationPtr) 
        !           928:            realloc(table->table, table->max_notations * sizeof(xmlNotation));
        !           929:        if (table->table) {
        !           930:            fprintf(stderr, "xmlAddNotationDecl: out of memory\n");
        !           931:            return(NULL);
        !           932:        }
        !           933:     }
        !           934:     ret = &table->table[table->nb_notations];
        !           935: 
        !           936:     /*
        !           937:      * fill the structure.
        !           938:      */
        !           939:     ret->name = xmlStrdup(name);
        !           940:     if (SystemID != NULL)
        !           941:         ret->SystemID = xmlStrdup(SystemID);
        !           942:     else
        !           943:         ret->SystemID = NULL;
        !           944:     if (PublicID != NULL)
        !           945:         ret->PublicID = xmlStrdup(PublicID);
        !           946:     else
        !           947:         ret->PublicID = NULL;
        !           948:     table->nb_notations++;
        !           949: 
        !           950:     return(ret);
        !           951: }
        !           952: 
        !           953: /**
        !           954:  * xmlFreeNotation:
        !           955:  * @not:  A notation
        !           956:  *
        !           957:  * Deallocate the memory used by an notation definition
        !           958:  */
        !           959: void
        !           960: xmlFreeNotation(xmlNotationPtr nota) {
        !           961:     if (nota == NULL) return;
        !           962:     if (nota->name != NULL)
        !           963:        free((CHAR *) nota->name);
        !           964:     if (nota->PublicID != NULL)
        !           965:        free((CHAR *) nota->PublicID);
        !           966:     if (nota->SystemID != NULL)
        !           967:        free((CHAR *) nota->SystemID);
        !           968:     memset(nota, -1, sizeof(xmlNotation));
        !           969: }
        !           970: 
        !           971: /**
        !           972:  * xmlFreeNotationTable:
        !           973:  * @table:  An notation table
        !           974:  *
        !           975:  * Deallocate the memory used by an entities hash table.
        !           976:  */
        !           977: void
        !           978: xmlFreeNotationTable(xmlNotationTablePtr table) {
        !           979:     int i;
        !           980: 
        !           981:     if (table == NULL) return;
        !           982: 
        !           983:     for (i = 0;i < table->nb_notations;i++) {
        !           984:         xmlFreeNotation(&table->table[i]);
        !           985:     }
        !           986:     free(table->table);
        !           987:     free(table);
        !           988: }
        !           989: 
        !           990: /**
        !           991:  * xmlCopyNotationTable:
        !           992:  * @table:  A notation table
        !           993:  *
        !           994:  * Build a copy of a notation table.
        !           995:  * 
        !           996:  * return values: the new xmlNotationTablePtr or NULL in case of error.
        !           997:  */
        !           998: xmlNotationTablePtr
        !           999: xmlCopyNotationTable(xmlNotationTablePtr table) {
        !          1000:     xmlNotationTablePtr ret;
        !          1001:     xmlNotationPtr cur, nota;
        !          1002:     int i;
        !          1003: 
        !          1004:     ret = (xmlNotationTablePtr) malloc(sizeof(xmlNotationTable));
        !          1005:     if (ret == NULL) {
        !          1006:         fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
        !          1007:        return(NULL);
        !          1008:     }
        !          1009:     ret->table = (xmlNotationPtr) malloc(table->max_notations *
        !          1010:                                          sizeof(xmlNotation));
        !          1011:     if (ret->table == NULL) {
        !          1012:         fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
        !          1013:        free(ret);
        !          1014:        return(NULL);
        !          1015:     }
        !          1016:     ret->max_notations = table->max_notations;
        !          1017:     ret->nb_notations = table->nb_notations;
        !          1018:     for (i = 0;i < ret->nb_notations;i++) {
        !          1019:        cur = &ret->table[i];
        !          1020:        nota = &table->table[i];
        !          1021:        if (nota->name != NULL)
        !          1022:            cur->name = xmlStrdup(nota->name);
        !          1023:        else
        !          1024:            cur->name = NULL;
        !          1025:        if (nota->PublicID != NULL)
        !          1026:            cur->PublicID = xmlStrdup(nota->PublicID);
        !          1027:        else
        !          1028:            cur->PublicID = NULL;
        !          1029:        if (nota->SystemID != NULL)
        !          1030:            cur->SystemID = xmlStrdup(nota->SystemID);
        !          1031:        else
        !          1032:            cur->SystemID = NULL;
        !          1033:     }
        !          1034:     return(ret);
        !          1035: }
        !          1036: 
        !          1037: /**
        !          1038:  * xmlDumpNotationTable:
        !          1039:  * @table:  A notation table
        !          1040:  *
        !          1041:  * This will dump the content of the notation table as an XML DTD definition
        !          1042:  *
        !          1043:  * NOTE: TODO an extra parameter allowing a reentant implementation will
        !          1044:  *       be added.
        !          1045:  */
        !          1046: void
        !          1047: xmlDumpNotationTable(xmlNotationTablePtr table) {
        !          1048:     int i;
        !          1049:     xmlNotationPtr cur;
        !          1050: 
        !          1051:     if (table == NULL) return;
        !          1052: 
        !          1053:     for (i = 0;i < table->nb_notations;i++) {
        !          1054:         cur = &table->table[i];
        !          1055:        xmlBufferWriteChar("<!NOTATION ");
        !          1056:        xmlBufferWriteCHAR(cur->name);
        !          1057:        if (cur->PublicID != NULL) {
        !          1058:            xmlBufferWriteChar(" PUBLIC \"");
        !          1059:            xmlBufferWriteCHAR(cur->PublicID);
        !          1060:            xmlBufferWriteChar("\"");
        !          1061:            if (cur->SystemID != NULL) {
        !          1062:                xmlBufferWriteChar(" ");
        !          1063:                xmlBufferWriteCHAR(cur->SystemID);
        !          1064:            }
        !          1065:        } else {
        !          1066:            xmlBufferWriteChar(" SYSTEM ");
        !          1067:            xmlBufferWriteCHAR(cur->SystemID);
        !          1068:        }
        !          1069:         xmlBufferWriteChar(" >\n");
1.2       daniel   1070:     }
                   1071: }

Webmaster