Annotation of XML/valid.c, revision 1.15

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: 
1.15    ! daniel     16: xmlElementPtr xmlGetDtdElementDesc(xmlDtdPtr dtd, const CHAR *name);
        !            17: xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const CHAR *elem);
        !            18: 
1.1       daniel     19: /****************************************************************
                     20:  *                                                             *
                     21:  *     Util functions for data allocation/deallocation         *
                     22:  *                                                             *
                     23:  ****************************************************************/
                     24: 
                     25: /**
                     26:  * xmlNewElementContent:
                     27:  * @name:  the subelement name or NULL
                     28:  * @type:  the type of element content decl
                     29:  *
                     30:  * Allocate an element content structure.
                     31:  *
1.6       daniel     32:  * Returns NULL if not, othervise the new element content structure
1.1       daniel     33:  */
                     34: xmlElementContentPtr
                     35: xmlNewElementContent(CHAR *name, int type) {
1.2       daniel     36:     xmlElementContentPtr ret;
                     37: 
                     38:     switch(type) {
                     39:        case XML_ELEMENT_CONTENT_ELEMENT:
                     40:            if (name == NULL) {
                     41:                fprintf(stderr, "xmlNewElementContent : name == NULL !\n");
                     42:            }
                     43:            break;
                     44:         case XML_ELEMENT_CONTENT_PCDATA:
                     45:        case XML_ELEMENT_CONTENT_SEQ:
                     46:        case XML_ELEMENT_CONTENT_OR:
                     47:            if (name != NULL) {
                     48:                fprintf(stderr, "xmlNewElementContent : name != NULL !\n");
                     49:            }
                     50:            break;
                     51:        default:
                     52:            fprintf(stderr, "xmlNewElementContent: unknown type %d\n", type);
                     53:            exit(1);
                     54:     }
                     55:     ret = (xmlElementContentPtr) malloc(sizeof(xmlElementContent));
                     56:     if (ret == NULL) {
                     57:        fprintf(stderr, "xmlNewElementContent : out of memory!\n");
                     58:        return(NULL);
                     59:     }
                     60:     ret->type = type;
                     61:     ret->ocur = XML_ELEMENT_CONTENT_ONCE;
                     62:     if (name != NULL)
                     63:         ret->name = xmlStrdup(name);
                     64:     else
                     65:         ret->name = NULL;
1.4       daniel     66:     ret->c1 = ret->c2 = NULL;
1.2       daniel     67:     return(ret);
                     68: }
                     69: 
                     70: /**
                     71:  * xmlCopyElementContent:
                     72:  * @content:  An element content pointer.
                     73:  *
                     74:  * Build a copy of an element content description.
                     75:  * 
1.6       daniel     76:  * Returns the new xmlElementContentPtr or NULL in case of error.
1.2       daniel     77:  */
                     78: xmlElementContentPtr
1.4       daniel     79: xmlCopyElementContent(xmlElementContentPtr cur) {
                     80:     xmlElementContentPtr ret;
                     81: 
                     82:     if (cur == NULL) return(NULL);
                     83:     ret = xmlNewElementContent((CHAR *) cur->name, cur->type);
1.11      daniel     84:     if (ret == NULL) {
                     85:         fprintf(stderr, "xmlCopyElementContent : out of memory\n");
                     86:        return(NULL);
                     87:     }
                     88:     ret->ocur = cur->ocur;
                     89:     if (cur->c1 != NULL) ret->c1 = xmlCopyElementContent(cur->c1);
                     90:     if (cur->c2 != NULL) ret->c2 = xmlCopyElementContent(cur->c2);
1.4       daniel     91:     return(ret);
1.1       daniel     92: }
                     93: 
                     94: /**
1.3       daniel     95:  * xmlFreeElementContent:
                     96:  * @cur:  the element content tree to free
1.1       daniel     97:  *
                     98:  * Free an element content structure. This is a recursive call !
                     99:  */
                    100: void
                    101: xmlFreeElementContent(xmlElementContentPtr cur) {
1.4       daniel    102:     if (cur == NULL) return;
                    103:     if (cur->c1 != NULL) xmlFreeElementContent(cur->c1);
                    104:     if (cur->c2 != NULL) xmlFreeElementContent(cur->c2);
                    105:     if (cur->name != NULL) free((CHAR *) cur->name);
                    106:     memset(cur, -1, sizeof(xmlElementContent));
                    107:     free(cur);
1.1       daniel    108: }
                    109: 
1.3       daniel    110: /**
                    111:  * xmlDumpElementContent:
1.8       daniel    112:  * @buf:  An XML buffer
1.3       daniel    113:  * @content:  An element table
                    114:  * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
                    115:  *
                    116:  * This will dump the content of the element table as an XML DTD definition
                    117:  */
                    118: void
1.8       daniel    119: xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) {
1.3       daniel    120:     if (content == NULL) return;
                    121: 
1.8       daniel    122:     if (glob) xmlBufferWriteChar(buf, "(");
1.3       daniel    123:     switch (content->type) {
                    124:         case XML_ELEMENT_CONTENT_PCDATA:
1.8       daniel    125:             xmlBufferWriteChar(buf, "#PCDATA");
1.3       daniel    126:            break;
                    127:        case XML_ELEMENT_CONTENT_ELEMENT:
1.8       daniel    128:            xmlBufferWriteCHAR(buf, content->name);
1.3       daniel    129:            break;
                    130:        case XML_ELEMENT_CONTENT_SEQ:
                    131:            if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
                    132:                (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
1.8       daniel    133:                xmlDumpElementContent(buf, content->c1, 1);
1.3       daniel    134:            else
1.8       daniel    135:                xmlDumpElementContent(buf, content->c1, 0);
                    136:             xmlBufferWriteChar(buf, " , ");
1.3       daniel    137:            if (content->c2->type == XML_ELEMENT_CONTENT_OR)
1.8       daniel    138:                xmlDumpElementContent(buf, content->c2, 1);
1.3       daniel    139:            else
1.8       daniel    140:                xmlDumpElementContent(buf, content->c2, 0);
1.3       daniel    141:            break;
                    142:        case XML_ELEMENT_CONTENT_OR:
                    143:            if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
                    144:                (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
1.8       daniel    145:                xmlDumpElementContent(buf, content->c1, 1);
1.3       daniel    146:            else
1.8       daniel    147:                xmlDumpElementContent(buf, content->c1, 0);
                    148:             xmlBufferWriteChar(buf, " | ");
1.3       daniel    149:            if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)
1.8       daniel    150:                xmlDumpElementContent(buf, content->c2, 1);
1.3       daniel    151:            else
1.8       daniel    152:                xmlDumpElementContent(buf, content->c2, 0);
1.3       daniel    153:            break;
                    154:        default:
                    155:            fprintf(stderr, "xmlDumpElementContent: unknown type %d\n",
                    156:                    content->type);
                    157:     }
                    158:     if (glob)
1.8       daniel    159:         xmlBufferWriteChar(buf, ")");
1.3       daniel    160:     switch (content->ocur) {
                    161:         case XML_ELEMENT_CONTENT_ONCE:
                    162:            break;
                    163:         case XML_ELEMENT_CONTENT_OPT:
1.8       daniel    164:            xmlBufferWriteChar(buf, "?");
1.3       daniel    165:            break;
                    166:         case XML_ELEMENT_CONTENT_MULT:
1.8       daniel    167:            xmlBufferWriteChar(buf, "*");
1.3       daniel    168:            break;
                    169:         case XML_ELEMENT_CONTENT_PLUS:
1.8       daniel    170:            xmlBufferWriteChar(buf, "+");
1.3       daniel    171:            break;
                    172:     }
                    173: }
                    174: 
1.1       daniel    175: /****************************************************************
                    176:  *                                                             *
                    177:  *     Registration of DTD declarations                        *
                    178:  *                                                             *
                    179:  ****************************************************************/
                    180: 
1.2       daniel    181: /**
                    182:  * xmlCreateElementTable:
                    183:  *
                    184:  * create and initialize an empty element hash table.
                    185:  *
1.6       daniel    186:  * Returns the xmlElementTablePtr just created or NULL in case of error.
1.2       daniel    187:  */
                    188: xmlElementTablePtr
                    189: xmlCreateElementTable(void) {
                    190:     xmlElementTablePtr ret;
                    191: 
                    192:     ret = (xmlElementTablePtr) 
                    193:          malloc(sizeof(xmlElementTable));
                    194:     if (ret == NULL) {
1.12      daniel    195:         fprintf(stderr, "xmlCreateElementTable : malloc(%ld) failed\n",
                    196:                (long)sizeof(xmlElementTable));
1.2       daniel    197:         return(NULL);
                    198:     }
1.4       daniel    199:     ret->max_elements = XML_MIN_ELEMENT_TABLE;
1.2       daniel    200:     ret->nb_elements = 0;
1.15    ! daniel    201:     ret->table = (xmlElementPtr *) 
        !           202:          malloc(ret->max_elements * sizeof(xmlElementPtr));
1.2       daniel    203:     if (ret == NULL) {
1.12      daniel    204:         fprintf(stderr, "xmlCreateElementTable : malloc(%ld) failed\n",
                    205:                ret->max_elements * (long)sizeof(xmlElement));
1.2       daniel    206:        free(ret);
                    207:         return(NULL);
                    208:     }
                    209:     return(ret);
                    210: }
                    211: 
1.1       daniel    212: 
                    213: /**
                    214:  * xmlAddElementDecl:
1.6       daniel    215:  * @dtd:  pointer to the DTD
1.1       daniel    216:  * @name:  the entity name
1.6       daniel    217:  * @type:  the element type
                    218:  * @content:  the element content tree or NULL
1.1       daniel    219:  *
                    220:  * Register a new element declaration
                    221:  *
1.6       daniel    222:  * Returns NULL if not, othervise the entity
1.1       daniel    223:  */
                    224: xmlElementPtr
1.7       daniel    225: xmlAddElementDecl(xmlDtdPtr dtd, const CHAR *name, int type, 
1.1       daniel    226:                   xmlElementContentPtr content) {
1.2       daniel    227:     xmlElementPtr ret, cur;
                    228:     xmlElementTablePtr table;
                    229:     int i;
1.1       daniel    230: 
                    231:     if (dtd == NULL) {
                    232:         fprintf(stderr, "xmlAddElementDecl: dtd == NULL\n");
                    233:        return(NULL);
                    234:     }
                    235:     if (name == NULL) {
                    236:         fprintf(stderr, "xmlAddElementDecl: name == NULL\n");
                    237:        return(NULL);
                    238:     }
                    239:     switch (type) {
                    240:         case XML_ELEMENT_TYPE_EMPTY:
                    241:            if (content != NULL) {
                    242:                fprintf(stderr,
                    243:                        "xmlAddElementDecl: content != NULL for EMPTY\n");
                    244:                return(NULL);
                    245:            }
                    246:            break;
                    247:        case XML_ELEMENT_TYPE_ANY:
                    248:            if (content != NULL) {
                    249:                fprintf(stderr,
                    250:                        "xmlAddElementDecl: content != NULL for ANY\n");
                    251:                return(NULL);
                    252:            }
                    253:            break;
                    254:        case XML_ELEMENT_TYPE_MIXED:
                    255:            if (content == NULL) {
                    256:                fprintf(stderr,
                    257:                        "xmlAddElementDecl: content == NULL for MIXED\n");
                    258:                return(NULL);
                    259:            }
                    260:            break;
                    261:        case XML_ELEMENT_TYPE_ELEMENT:
                    262:            if (content == NULL) {
                    263:                fprintf(stderr,
                    264:                        "xmlAddElementDecl: content == NULL for ELEMENT\n");
                    265:                return(NULL);
                    266:            }
                    267:            break;
                    268:        default:
                    269:            fprintf(stderr, "xmlAddElementDecl: unknown type %d\n", type);
                    270:            return(NULL);
                    271:     }
                    272: 
                    273:     /*
1.2       daniel    274:      * Create the Element table if needed.
                    275:      */
                    276:     table = dtd->elements;
                    277:     if (table == NULL) 
                    278:         table = dtd->elements = xmlCreateElementTable();
                    279:     if (table == NULL) {
                    280:        fprintf(stderr, "xmlAddElementDecl: Table creation failed!\n");
                    281:         return(NULL);
                    282:     }
                    283: 
                    284:     /*
1.1       daniel    285:      * Validity Check:
                    286:      * Search the DTD for previous declarations of the ELEMENT
                    287:      */
1.2       daniel    288:     for (i = 0;i < table->nb_elements;i++) {
1.15    ! daniel    289:         cur = table->table[i];
1.2       daniel    290:        if (!xmlStrcmp(cur->name, name)) {
                    291:            /*
                    292:             * The element is already defined in this Dtd.
                    293:             */
                    294:            fprintf(stderr,
                    295:                    "xmlAddElementDecl: %s already defined\n", name);
                    296:            return(NULL);
                    297:        }
                    298:     }
1.1       daniel    299: 
                    300:     /*
1.2       daniel    301:      * Grow the table, if needed.
1.1       daniel    302:      */
1.2       daniel    303:     if (table->nb_elements >= table->max_elements) {
                    304:         /*
                    305:         * need more elements.
                    306:         */
                    307:        table->max_elements *= 2;
1.15    ! daniel    308:        table->table = (xmlElementPtr *) 
        !           309:            realloc(table->table, table->max_elements * sizeof(xmlElementPtr));
1.13      daniel    310:        if (table->table == NULL) {
1.2       daniel    311:            fprintf(stderr, "xmlAddElementDecl: out of memory\n");
                    312:            return(NULL);
                    313:        }
1.1       daniel    314:     }
1.15    ! daniel    315:     ret = (xmlElementPtr) malloc(sizeof(xmlElement));
        !           316:     if (ret == NULL) {
        !           317:        fprintf(stderr, "xmlAddElementDecl: out of memory\n");
        !           318:        return(NULL);
        !           319:     }
        !           320:     table->table[table->nb_elements] = ret;
1.2       daniel    321: 
                    322:     /*
                    323:      * fill the structure.
                    324:      */
1.1       daniel    325:     ret->type = type;
                    326:     ret->name = xmlStrdup(name);
1.11      daniel    327:     ret->content = xmlCopyElementContent(content);
1.15    ! daniel    328:     ret->attributes = xmlScanAttributeDecl(dtd, name);
1.2       daniel    329:     table->nb_elements++;
                    330: 
                    331:     return(ret);
                    332: }
                    333: 
                    334: /**
                    335:  * xmlFreeElement:
                    336:  * @elem:  An element
                    337:  *
                    338:  * Deallocate the memory used by an element definition
                    339:  */
                    340: void
                    341: xmlFreeElement(xmlElementPtr elem) {
                    342:     if (elem == NULL) return;
                    343:     xmlFreeElementContent(elem->content);
                    344:     if (elem->name != NULL)
                    345:        free((CHAR *) elem->name);
                    346:     memset(elem, -1, sizeof(xmlElement));
1.15    ! daniel    347:     free(elem);
1.2       daniel    348: }
1.1       daniel    349: 
1.2       daniel    350: /**
                    351:  * xmlFreeElementTable:
                    352:  * @table:  An element table
                    353:  *
1.4       daniel    354:  * Deallocate the memory used by an element hash table.
1.2       daniel    355:  */
                    356: void
                    357: xmlFreeElementTable(xmlElementTablePtr table) {
                    358:     int i;
                    359: 
                    360:     if (table == NULL) return;
                    361: 
                    362:     for (i = 0;i < table->nb_elements;i++) {
1.15    ! daniel    363:         xmlFreeElement(table->table[i]);
1.2       daniel    364:     }
                    365:     free(table->table);
                    366:     free(table);
                    367: }
                    368: 
                    369: /**
                    370:  * xmlCopyElementTable:
                    371:  * @table:  An element table
                    372:  *
                    373:  * Build a copy of an element table.
                    374:  * 
1.6       daniel    375:  * Returns the new xmlElementTablePtr or NULL in case of error.
1.2       daniel    376:  */
                    377: xmlElementTablePtr
                    378: xmlCopyElementTable(xmlElementTablePtr table) {
                    379:     xmlElementTablePtr ret;
                    380:     xmlElementPtr cur, ent;
                    381:     int i;
1.1       daniel    382: 
1.2       daniel    383:     ret = (xmlElementTablePtr) malloc(sizeof(xmlElementTable));
                    384:     if (ret == NULL) {
                    385:         fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
                    386:        return(NULL);
                    387:     }
1.15    ! daniel    388:     ret->table = (xmlElementPtr *) malloc(table->max_elements *
        !           389:                                          sizeof(xmlElementPtr));
1.2       daniel    390:     if (ret->table == NULL) {
                    391:         fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
                    392:        free(ret);
                    393:        return(NULL);
                    394:     }
                    395:     ret->max_elements = table->max_elements;
                    396:     ret->nb_elements = table->nb_elements;
                    397:     for (i = 0;i < ret->nb_elements;i++) {
1.15    ! daniel    398:        cur = (xmlElementPtr) malloc(sizeof(xmlElement));
        !           399:        if (cur == NULL) {
        !           400:            fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
        !           401:            free(ret);
        !           402:            free(ret->table);
        !           403:            return(NULL);
        !           404:        }
        !           405:        ret->table[i] = cur;
        !           406:        ent = table->table[i];
1.2       daniel    407:        cur->type = ent->type;
                    408:        if (ent->name != NULL)
                    409:            cur->name = xmlStrdup(ent->name);
                    410:        else
                    411:            cur->name = NULL;
                    412:        cur->content = xmlCopyElementContent(ent->content);
1.15    ! daniel    413:        cur->attributes = NULL;
1.2       daniel    414:     }
1.1       daniel    415:     return(ret);
                    416: }
                    417: 
1.2       daniel    418: /**
                    419:  * xmlDumpElementTable:
1.9       daniel    420:  * @buf:  the XML buffer output
1.2       daniel    421:  * @table:  An element table
                    422:  *
                    423:  * This will dump the content of the element table as an XML DTD definition
                    424:  */
                    425: void
1.8       daniel    426: xmlDumpElementTable(xmlBufferPtr buf, xmlElementTablePtr table) {
1.2       daniel    427:     int i;
                    428:     xmlElementPtr cur;
                    429: 
                    430:     if (table == NULL) return;
                    431: 
                    432:     for (i = 0;i < table->nb_elements;i++) {
1.15    ! daniel    433:         cur = table->table[i];
1.2       daniel    434:         switch (cur->type) {
                    435:            case XML_ELEMENT_TYPE_EMPTY:
1.8       daniel    436:                xmlBufferWriteChar(buf, "<!ELEMENT ");
                    437:                xmlBufferWriteCHAR(buf, cur->name);
                    438:                xmlBufferWriteChar(buf, " EMPTY>\n");
1.2       daniel    439:                break;
                    440:            case XML_ELEMENT_TYPE_ANY:
1.8       daniel    441:                xmlBufferWriteChar(buf, "<!ELEMENT ");
                    442:                xmlBufferWriteCHAR(buf, cur->name);
                    443:                xmlBufferWriteChar(buf, " ANY>\n");
1.2       daniel    444:                break;
                    445:            case XML_ELEMENT_TYPE_MIXED:
1.8       daniel    446:                xmlBufferWriteChar(buf, "<!ELEMENT ");
                    447:                xmlBufferWriteCHAR(buf, cur->name);
                    448:                xmlBufferWriteChar(buf, " ");
                    449:                xmlDumpElementContent(buf, cur->content, 1);
                    450:                xmlBufferWriteChar(buf, ">\n");
1.2       daniel    451:                break;
                    452:            case XML_ELEMENT_TYPE_ELEMENT:
1.8       daniel    453:                xmlBufferWriteChar(buf, "<!ELEMENT ");
                    454:                xmlBufferWriteCHAR(buf, cur->name);
                    455:                xmlBufferWriteChar(buf, " ");
                    456:                xmlDumpElementContent(buf, cur->content, 1);
                    457:                xmlBufferWriteChar(buf, ">\n");
1.2       daniel    458:                break;
                    459:            default:
                    460:                fprintf(stderr,
                    461:                    "xmlDumpElementTable: internal: unknown type %d\n",
                    462:                        cur->type);
                    463:        }
1.4       daniel    464:     }
                    465: }
                    466: 
                    467: /**
                    468:  * xmlCreateEnumeration:
                    469:  * @name:  the enumeration name or NULL
                    470:  *
                    471:  * create and initialize an enumeration attribute node.
                    472:  *
1.6       daniel    473:  * Returns the xmlEnumerationPtr just created or NULL in case
1.4       daniel    474:  *                of error.
                    475:  */
                    476: xmlEnumerationPtr
                    477: xmlCreateEnumeration(CHAR *name) {
                    478:     xmlEnumerationPtr ret;
                    479: 
                    480:     ret = (xmlEnumerationPtr) malloc(sizeof(xmlEnumeration));
                    481:     if (ret == NULL) {
1.12      daniel    482:         fprintf(stderr, "xmlCreateEnumeration : malloc(%ld) failed\n",
                    483:                (long)sizeof(xmlEnumeration));
1.4       daniel    484:         return(NULL);
                    485:     }
                    486: 
                    487:     if (name != NULL)
                    488:         ret->name = xmlStrdup(name);
                    489:     else
                    490:         ret->name = NULL;
                    491:     ret->next = NULL;
                    492:     return(ret);
                    493: }
                    494: 
                    495: /**
                    496:  * xmlFreeEnumeration:
                    497:  * @cur:  the tree to free.
                    498:  *
                    499:  * free an enumeration attribute node (recursive).
                    500:  */
                    501: void
                    502: xmlFreeEnumeration(xmlEnumerationPtr cur) {
                    503:     if (cur == NULL) return;
                    504: 
                    505:     if (cur->next != NULL) xmlFreeEnumeration(cur->next);
                    506: 
                    507:     if (cur->name != NULL) free((CHAR *) cur->name);
                    508:     memset(cur, -1, sizeof(xmlEnumeration));
                    509:     free(cur);
                    510: }
                    511: 
                    512: /**
                    513:  * xmlCopyEnumeration:
                    514:  * @cur:  the tree to copy.
                    515:  *
                    516:  * Copy an enumeration attribute node (recursive).
                    517:  *
1.6       daniel    518:  * Returns the xmlEnumerationPtr just created or NULL in case
1.4       daniel    519:  *                of error.
                    520:  */
                    521: xmlEnumerationPtr
                    522: xmlCopyEnumeration(xmlEnumerationPtr cur) {
                    523:     xmlEnumerationPtr ret;
                    524: 
                    525:     if (cur == NULL) return(NULL);
                    526:     ret = xmlCreateEnumeration((CHAR *) cur->name);
                    527: 
                    528:     if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
                    529:     else ret->next = NULL;
                    530: 
                    531:     return(ret);
                    532: }
                    533: 
                    534: /**
                    535:  * xmlCreateAttributeTable:
                    536:  *
                    537:  * create and initialize an empty attribute hash table.
                    538:  *
1.6       daniel    539:  * Returns the xmlAttributeTablePtr just created or NULL in case
1.4       daniel    540:  *                of error.
                    541:  */
                    542: xmlAttributeTablePtr
                    543: xmlCreateAttributeTable(void) {
                    544:     xmlAttributeTablePtr ret;
                    545: 
                    546:     ret = (xmlAttributeTablePtr) 
                    547:          malloc(sizeof(xmlAttributeTable));
                    548:     if (ret == NULL) {
1.12      daniel    549:         fprintf(stderr, "xmlCreateAttributeTable : malloc(%ld) failed\n",
                    550:                (long)sizeof(xmlAttributeTable));
1.4       daniel    551:         return(NULL);
                    552:     }
                    553:     ret->max_attributes = XML_MIN_ATTRIBUTE_TABLE;
                    554:     ret->nb_attributes = 0;
1.15    ! daniel    555:     ret->table = (xmlAttributePtr *) 
        !           556:          malloc(ret->max_attributes * sizeof(xmlAttributePtr));
1.4       daniel    557:     if (ret == NULL) {
1.12      daniel    558:         fprintf(stderr, "xmlCreateAttributeTable : malloc(%ld) failed\n",
1.15    ! daniel    559:                ret->max_attributes * (long)sizeof(xmlAttributePtr));
1.4       daniel    560:        free(ret);
                    561:         return(NULL);
                    562:     }
                    563:     return(ret);
                    564: }
                    565: 
1.15    ! daniel    566: /**
        !           567:  * xmlScanAttributeDecl:
        !           568:  * @dtd:  pointer to the DTD
        !           569:  * @elem:  the element name
        !           570:  *
        !           571:  * When inserting a new element scan the DtD for existing attributes
        !           572:  * for taht element and initialize the Attribute chain
        !           573:  *
        !           574:  * Returns the pointer to the first attribute decl in the chain,
        !           575:  *         possibly NULL.
        !           576:  */
        !           577: xmlAttributePtr
        !           578: xmlScanAttributeDecl(xmlDtdPtr dtd, const CHAR *elem) {
        !           579:     xmlAttributePtr ret = NULL, cur = NULL;
        !           580:     xmlAttributeTablePtr table;
        !           581:     int i;
        !           582: 
        !           583:     if (dtd == NULL) {
        !           584:         fprintf(stderr, "xmlScanAttributeDecl: dtd == NULL\n");
        !           585:        return(NULL);
        !           586:     }
        !           587:     if (elem == NULL) {
        !           588:         fprintf(stderr, "xmlScanAttributeDecl: elem == NULL\n");
        !           589:        return(NULL);
        !           590:     }
        !           591:     table = dtd->attributes;
        !           592:     if (table == NULL) 
        !           593:         return(NULL);
        !           594: 
        !           595:     for (i = 0;i < table->nb_attributes;i++) {
        !           596:         if (!xmlStrcmp(table->table[i]->elem, elem)) {
        !           597:            table->table[i]->next = cur;
        !           598:            cur = table->table[i];
        !           599:            if (ret == NULL) ret = cur;
        !           600:        }
        !           601:     }
        !           602:     return(ret);
        !           603: }
        !           604: 
1.4       daniel    605: 
                    606: /**
                    607:  * xmlAddAttributeDecl:
1.6       daniel    608:  * @dtd:  pointer to the DTD
                    609:  * @elem:  the element name
                    610:  * @name:  the attribute name
                    611:  * @type:  the attribute type
                    612:  * @def:  the attribute default type
                    613:  * @defaultValue:  the attribute default value
                    614:  * @tree:  if it's an enumeration, the associated list
1.4       daniel    615:  *
                    616:  * Register a new attribute declaration
                    617:  *
1.6       daniel    618:  * Returns NULL if not, othervise the entity
1.4       daniel    619:  */
                    620: xmlAttributePtr
1.7       daniel    621: xmlAddAttributeDecl(xmlDtdPtr dtd, const CHAR *elem, const CHAR *name,
                    622:                     int type, int def, const CHAR *defaultValue,
                    623:                    xmlEnumerationPtr tree) {
1.4       daniel    624:     xmlAttributePtr ret, cur;
                    625:     xmlAttributeTablePtr table;
1.15    ! daniel    626:     xmlElementPtr elemDef;
1.4       daniel    627:     int i;
                    628: 
                    629:     if (dtd == NULL) {
                    630:         fprintf(stderr, "xmlAddAttributeDecl: dtd == NULL\n");
                    631:        return(NULL);
                    632:     }
                    633:     if (name == NULL) {
                    634:         fprintf(stderr, "xmlAddAttributeDecl: name == NULL\n");
                    635:        return(NULL);
                    636:     }
                    637:     if (elem == NULL) {
                    638:         fprintf(stderr, "xmlAddAttributeDecl: elem == NULL\n");
                    639:        return(NULL);
                    640:     }
                    641:     /* TODO: Lacks verifications !!! */
                    642:     switch (type) {
                    643:         case XML_ATTRIBUTE_CDATA:
                    644:            break;
                    645:         case XML_ATTRIBUTE_ID:
                    646:            break;
                    647:         case XML_ATTRIBUTE_IDREF:
                    648:            break;
                    649:         case XML_ATTRIBUTE_IDREFS:
                    650:            break;
                    651:         case XML_ATTRIBUTE_ENTITY:
                    652:            break;
                    653:         case XML_ATTRIBUTE_ENTITIES:
                    654:            break;
                    655:         case XML_ATTRIBUTE_NMTOKEN:
                    656:            break;
                    657:         case XML_ATTRIBUTE_NMTOKENS:
                    658:            break;
                    659:         case XML_ATTRIBUTE_ENUMERATION:
                    660:            break;
                    661:         case XML_ATTRIBUTE_NOTATION:
                    662:            break;
                    663:        default:
                    664:            fprintf(stderr, "xmlAddAttributeDecl: unknown type %d\n", type);
                    665:            return(NULL);
                    666:     }
                    667: 
                    668:     /*
                    669:      * Create the Attribute table if needed.
                    670:      */
                    671:     table = dtd->attributes;
                    672:     if (table == NULL) 
                    673:         table = dtd->attributes = xmlCreateAttributeTable();
                    674:     if (table == NULL) {
                    675:        fprintf(stderr, "xmlAddAttributeDecl: Table creation failed!\n");
                    676:         return(NULL);
                    677:     }
                    678: 
                    679:     /*
                    680:      * Validity Check:
                    681:      * Search the DTD for previous declarations of the ATTLIST
                    682:      */
                    683:     for (i = 0;i < table->nb_attributes;i++) {
1.15    ! daniel    684:         cur = table->table[i];
1.4       daniel    685:        if ((!xmlStrcmp(cur->name, name)) && (!xmlStrcmp(cur->elem, elem))) {
                    686:            /*
                    687:             * The attribute is already defined in this Dtd.
                    688:             */
                    689:            fprintf(stderr,
                    690:                    "xmlAddAttributeDecl: %s already defined\n", name);
                    691:        }
                    692:     }
                    693: 
                    694:     /*
                    695:      * Grow the table, if needed.
                    696:      */
                    697:     if (table->nb_attributes >= table->max_attributes) {
                    698:         /*
                    699:         * need more attributes.
                    700:         */
                    701:        table->max_attributes *= 2;
1.15    ! daniel    702:        table->table = (xmlAttributePtr *) 
        !           703:            realloc(table->table, table->max_attributes * 
        !           704:                    sizeof(xmlAttributePtr));
1.13      daniel    705:        if (table->table == NULL) {
1.4       daniel    706:            fprintf(stderr, "xmlAddAttributeDecl: out of memory\n");
                    707:            return(NULL);
                    708:        }
                    709:     }
1.15    ! daniel    710:     ret = (xmlAttributePtr) malloc(sizeof(xmlAttribute));
        !           711:     if (ret == NULL) {
        !           712:        fprintf(stderr, "xmlAddAttributeDecl: out of memory\n");
        !           713:        return(NULL);
        !           714:     }
        !           715:     table->table[table->nb_attributes] = ret;
1.4       daniel    716: 
                    717:     /*
                    718:      * fill the structure.
                    719:      */
                    720:     ret->type = type;
                    721:     ret->name = xmlStrdup(name);
                    722:     ret->elem = xmlStrdup(elem);
                    723:     ret->def = def;
                    724:     ret->tree = tree;
                    725:     if (defaultValue != NULL)
                    726:        ret->defaultValue = xmlStrdup(defaultValue);
                    727:     else
                    728:         ret->defaultValue = NULL;
1.15    ! daniel    729:     elemDef = xmlGetDtdElementDesc(dtd, elem);
        !           730:     if (elemDef != NULL) {
        !           731:         ret->next = elemDef->attributes;
        !           732:         elemDef->attributes = ret;
        !           733:     }
1.4       daniel    734:     table->nb_attributes++;
                    735: 
                    736:     return(ret);
                    737: }
                    738: 
                    739: /**
                    740:  * xmlFreeAttribute:
                    741:  * @elem:  An attribute
                    742:  *
                    743:  * Deallocate the memory used by an attribute definition
                    744:  */
                    745: void
                    746: xmlFreeAttribute(xmlAttributePtr attr) {
                    747:     if (attr == NULL) return;
                    748:     if (attr->tree != NULL)
                    749:         xmlFreeEnumeration(attr->tree);
                    750:     if (attr->elem != NULL)
                    751:        free((CHAR *) attr->elem);
                    752:     if (attr->name != NULL)
                    753:        free((CHAR *) attr->name);
                    754:     if (attr->defaultValue != NULL)
                    755:        free((CHAR *) attr->defaultValue);
                    756:     memset(attr, -1, sizeof(xmlAttribute));
1.15    ! daniel    757:     free(attr);
1.4       daniel    758: }
                    759: 
                    760: /**
                    761:  * xmlFreeAttributeTable:
                    762:  * @table:  An attribute table
                    763:  *
                    764:  * Deallocate the memory used by an entities hash table.
                    765:  */
                    766: void
                    767: xmlFreeAttributeTable(xmlAttributeTablePtr table) {
                    768:     int i;
                    769: 
                    770:     if (table == NULL) return;
                    771: 
                    772:     for (i = 0;i < table->nb_attributes;i++) {
1.15    ! daniel    773:         xmlFreeAttribute(table->table[i]);
1.4       daniel    774:     }
                    775:     free(table->table);
                    776:     free(table);
                    777: }
                    778: 
                    779: /**
                    780:  * xmlCopyAttributeTable:
                    781:  * @table:  An attribute table
                    782:  *
                    783:  * Build a copy of an attribute table.
                    784:  * 
1.6       daniel    785:  * Returns the new xmlAttributeTablePtr or NULL in case of error.
1.4       daniel    786:  */
                    787: xmlAttributeTablePtr
                    788: xmlCopyAttributeTable(xmlAttributeTablePtr table) {
                    789:     xmlAttributeTablePtr ret;
                    790:     xmlAttributePtr cur, attr;
                    791:     int i;
                    792: 
                    793:     ret = (xmlAttributeTablePtr) malloc(sizeof(xmlAttributeTable));
                    794:     if (ret == NULL) {
                    795:         fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
                    796:        return(NULL);
                    797:     }
1.15    ! daniel    798:     ret->table = (xmlAttributePtr *) malloc(table->max_attributes *
        !           799:                                           sizeof(xmlAttributePtr));
1.4       daniel    800:     if (ret->table == NULL) {
                    801:         fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
                    802:        free(ret);
                    803:        return(NULL);
                    804:     }
                    805:     ret->max_attributes = table->max_attributes;
                    806:     ret->nb_attributes = table->nb_attributes;
                    807:     for (i = 0;i < ret->nb_attributes;i++) {
1.15    ! daniel    808:        attr = table->table[i];
        !           809:        cur = (xmlAttributePtr) malloc(sizeof(xmlAttribute));
        !           810:        if (cur == NULL) {
        !           811:            fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
        !           812:            free(ret);
        !           813:            free(ret->table);
        !           814:            return(NULL);
        !           815:        }
        !           816:        ret->table[i] = cur;
1.4       daniel    817:        cur->type = attr->type;
                    818:        cur->def = attr->def;
                    819:        cur->tree = xmlCopyEnumeration(attr->tree);
                    820:        if (attr->elem != NULL)
                    821:            cur->elem = xmlStrdup(attr->elem);
                    822:        else
                    823:            cur->elem = NULL;
                    824:        if (attr->name != NULL)
                    825:            cur->name = xmlStrdup(attr->name);
                    826:        else
                    827:            cur->name = NULL;
                    828:        if (attr->defaultValue != NULL)
                    829:            cur->defaultValue = xmlStrdup(attr->defaultValue);
                    830:        else
                    831:            cur->defaultValue = NULL;
1.15    ! daniel    832:        /* NEED to rebuild the next chain !!!!!! */
1.4       daniel    833:     }
                    834:     return(ret);
                    835: }
                    836: 
                    837: /**
                    838:  * xmlDumpAttributeTable:
1.9       daniel    839:  * @buf:  the XML buffer output
1.4       daniel    840:  * @table:  An attribute table
                    841:  *
                    842:  * This will dump the content of the attribute table as an XML DTD definition
                    843:  */
                    844: void
1.8       daniel    845: xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
1.4       daniel    846:     int i;
                    847:     xmlAttributePtr cur;
                    848: 
                    849:     if (table == NULL) return;
                    850: 
                    851:     for (i = 0;i < table->nb_attributes;i++) {
1.15    ! daniel    852:         cur = table->table[i];
1.8       daniel    853:        xmlBufferWriteChar(buf, "<!ATTLIST ");
                    854:        xmlBufferWriteCHAR(buf, cur->elem);
                    855:        xmlBufferWriteChar(buf, " ");
                    856:        xmlBufferWriteCHAR(buf, cur->name);
1.4       daniel    857:         switch (cur->type) {
                    858:             case XML_ATTRIBUTE_CDATA:
1.8       daniel    859:                xmlBufferWriteChar(buf, " CDATA");
1.4       daniel    860:                 break;
                    861:             case XML_ATTRIBUTE_ID:
1.8       daniel    862:                xmlBufferWriteChar(buf, " ID");
1.4       daniel    863:                 break;
                    864:             case XML_ATTRIBUTE_IDREF:
1.8       daniel    865:                xmlBufferWriteChar(buf, " IDREF");
1.4       daniel    866:                 break;
                    867:             case XML_ATTRIBUTE_IDREFS:
1.8       daniel    868:                xmlBufferWriteChar(buf, " IDREFS");
1.4       daniel    869:                 break;
                    870:             case XML_ATTRIBUTE_ENTITY:
1.8       daniel    871:                xmlBufferWriteChar(buf, " ENTITY");
1.4       daniel    872:                 break;
                    873:             case XML_ATTRIBUTE_ENTITIES:
1.8       daniel    874:                xmlBufferWriteChar(buf, " ENTITIES");
1.4       daniel    875:                 break;
                    876:             case XML_ATTRIBUTE_NMTOKEN:
1.8       daniel    877:                xmlBufferWriteChar(buf, " NMTOKEN");
1.4       daniel    878:                 break;
                    879:             case XML_ATTRIBUTE_NMTOKENS:
1.8       daniel    880:                xmlBufferWriteChar(buf, " NMTOKENS");
1.4       daniel    881:                 break;
                    882:             case XML_ATTRIBUTE_ENUMERATION:
1.8       daniel    883:                 xmlBufferWriteChar(buf, " (pbm)");
1.4       daniel    884:                 break;
                    885:             case XML_ATTRIBUTE_NOTATION:
1.8       daniel    886:                 xmlBufferWriteChar(buf, " NOTATION (pbm)");
1.4       daniel    887:                 break;
                    888:            default:
                    889:                fprintf(stderr,
                    890:                    "xmlDumpAttributeTable: internal: unknown type %d\n",
                    891:                        cur->type);
                    892:        }
                    893:         switch (cur->def) {
                    894:             case XML_ATTRIBUTE_NONE:
                    895:                 break;
                    896:             case XML_ATTRIBUTE_REQUIRED:
1.8       daniel    897:                xmlBufferWriteChar(buf, " #REQUIRED");
1.4       daniel    898:                 break;
                    899:             case XML_ATTRIBUTE_IMPLIED:
1.8       daniel    900:                xmlBufferWriteChar(buf, " #IMPLIED");
1.6       daniel    901:                if (cur->defaultValue != NULL) {
1.10      daniel    902:                    xmlBufferWriteChar(buf, " ");
                    903:                    xmlBufferWriteQuotedString(buf, cur->defaultValue);
1.6       daniel    904:                }
1.4       daniel    905:                 break;
                    906:             case XML_ATTRIBUTE_FIXED:
1.10      daniel    907:                xmlBufferWriteChar(buf, " #FIXED ");
                    908:                xmlBufferWriteQuotedString(buf, cur->defaultValue);
1.4       daniel    909:                 break;
                    910:            default:
                    911:                fprintf(stderr,
                    912:                    "xmlDumpAttributeTable: internal: unknown default %d\n",
                    913:                        cur->def);
                    914:         }
1.8       daniel    915:         xmlBufferWriteChar(buf, ">\n");
1.5       daniel    916:     }
                    917: }
                    918: 
                    919: /************************************************************************
                    920:  *                                                                     *
                    921:  *                             NOTATIONs                               *
                    922:  *                                                                     *
                    923:  ************************************************************************/
                    924: /**
                    925:  * xmlCreateNotationTable:
                    926:  *
                    927:  * create and initialize an empty notation hash table.
                    928:  *
1.6       daniel    929:  * Returns the xmlNotationTablePtr just created or NULL in case
1.5       daniel    930:  *                of error.
                    931:  */
                    932: xmlNotationTablePtr
                    933: xmlCreateNotationTable(void) {
                    934:     xmlNotationTablePtr ret;
                    935: 
                    936:     ret = (xmlNotationTablePtr) 
                    937:          malloc(sizeof(xmlNotationTable));
                    938:     if (ret == NULL) {
1.12      daniel    939:         fprintf(stderr, "xmlCreateNotationTable : malloc(%ld) failed\n",
                    940:                (long)sizeof(xmlNotationTable));
1.5       daniel    941:         return(NULL);
                    942:     }
                    943:     ret->max_notations = XML_MIN_NOTATION_TABLE;
                    944:     ret->nb_notations = 0;
1.15    ! daniel    945:     ret->table = (xmlNotationPtr *) 
        !           946:          malloc(ret->max_notations * sizeof(xmlNotationPtr));
1.5       daniel    947:     if (ret == NULL) {
1.12      daniel    948:         fprintf(stderr, "xmlCreateNotationTable : malloc(%ld) failed\n",
                    949:                ret->max_notations * (long)sizeof(xmlNotation));
1.5       daniel    950:        free(ret);
                    951:         return(NULL);
                    952:     }
                    953:     return(ret);
                    954: }
                    955: 
                    956: 
                    957: /**
                    958:  * xmlAddNotationDecl:
1.6       daniel    959:  * @dtd:  pointer to the DTD
1.5       daniel    960:  * @name:  the entity name
1.6       daniel    961:  * @PublicID:  the public identifier or NULL
                    962:  * @SystemID:  the system identifier or NULL
1.5       daniel    963:  *
                    964:  * Register a new notation declaration
                    965:  *
1.6       daniel    966:  * Returns NULL if not, othervise the entity
1.5       daniel    967:  */
                    968: xmlNotationPtr
1.7       daniel    969: xmlAddNotationDecl(xmlDtdPtr dtd, const CHAR *name, const CHAR *PublicID,
                    970:                    const CHAR *SystemID) {
1.5       daniel    971:     xmlNotationPtr ret, cur;
                    972:     xmlNotationTablePtr table;
                    973:     int i;
                    974: 
                    975:     if (dtd == NULL) {
                    976:         fprintf(stderr, "xmlAddNotationDecl: dtd == NULL\n");
                    977:        return(NULL);
                    978:     }
                    979:     if (name == NULL) {
                    980:         fprintf(stderr, "xmlAddNotationDecl: name == NULL\n");
                    981:        return(NULL);
                    982:     }
                    983:     if ((PublicID == NULL) && (SystemID == NULL)) {
                    984:         fprintf(stderr, "xmlAddNotationDecl: no PUBLIC ID nor SYSTEM ID\n");
                    985:     }
                    986: 
                    987:     /*
                    988:      * Create the Notation table if needed.
                    989:      */
                    990:     table = dtd->notations;
                    991:     if (table == NULL) 
                    992:         table = dtd->notations = xmlCreateNotationTable();
                    993:     if (table == NULL) {
                    994:        fprintf(stderr, "xmlAddNotationDecl: Table creation failed!\n");
                    995:         return(NULL);
                    996:     }
                    997: 
                    998:     /*
                    999:      * Validity Check:
                   1000:      * Search the DTD for previous declarations of the ATTLIST
                   1001:      */
                   1002:     for (i = 0;i < table->nb_notations;i++) {
1.15    ! daniel   1003:         cur = table->table[i];
1.5       daniel   1004:        if (!xmlStrcmp(cur->name, name)) {
                   1005:            /*
                   1006:             * The notation is already defined in this Dtd.
                   1007:             */
                   1008:            fprintf(stderr,
                   1009:                    "xmlAddNotationDecl: %s already defined\n", name);
                   1010:        }
                   1011:     }
                   1012: 
                   1013:     /*
                   1014:      * Grow the table, if needed.
                   1015:      */
                   1016:     if (table->nb_notations >= table->max_notations) {
                   1017:         /*
                   1018:         * need more notations.
                   1019:         */
                   1020:        table->max_notations *= 2;
1.15    ! daniel   1021:        table->table = (xmlNotationPtr *) 
        !          1022:            realloc(table->table, table->max_notations *
        !          1023:                    sizeof(xmlNotationPtr));
1.13      daniel   1024:        if (table->table == NULL) {
1.5       daniel   1025:            fprintf(stderr, "xmlAddNotationDecl: out of memory\n");
                   1026:            return(NULL);
                   1027:        }
                   1028:     }
1.15    ! daniel   1029:     ret = (xmlNotationPtr) malloc(sizeof(xmlNotation));
        !          1030:     if (ret == NULL) {
        !          1031:        fprintf(stderr, "xmlAddNotationDecl: out of memory\n");
        !          1032:        return(NULL);
        !          1033:     }
        !          1034:     table->table[table->nb_notations] = ret;
1.5       daniel   1035: 
                   1036:     /*
                   1037:      * fill the structure.
                   1038:      */
                   1039:     ret->name = xmlStrdup(name);
                   1040:     if (SystemID != NULL)
                   1041:         ret->SystemID = xmlStrdup(SystemID);
                   1042:     else
                   1043:         ret->SystemID = NULL;
                   1044:     if (PublicID != NULL)
                   1045:         ret->PublicID = xmlStrdup(PublicID);
                   1046:     else
                   1047:         ret->PublicID = NULL;
                   1048:     table->nb_notations++;
                   1049: 
                   1050:     return(ret);
                   1051: }
                   1052: 
                   1053: /**
                   1054:  * xmlFreeNotation:
                   1055:  * @not:  A notation
                   1056:  *
                   1057:  * Deallocate the memory used by an notation definition
                   1058:  */
                   1059: void
                   1060: xmlFreeNotation(xmlNotationPtr nota) {
                   1061:     if (nota == NULL) return;
                   1062:     if (nota->name != NULL)
                   1063:        free((CHAR *) nota->name);
                   1064:     if (nota->PublicID != NULL)
                   1065:        free((CHAR *) nota->PublicID);
                   1066:     if (nota->SystemID != NULL)
                   1067:        free((CHAR *) nota->SystemID);
                   1068:     memset(nota, -1, sizeof(xmlNotation));
1.15    ! daniel   1069:     free(nota);
1.5       daniel   1070: }
                   1071: 
                   1072: /**
                   1073:  * xmlFreeNotationTable:
                   1074:  * @table:  An notation table
                   1075:  *
                   1076:  * Deallocate the memory used by an entities hash table.
                   1077:  */
                   1078: void
                   1079: xmlFreeNotationTable(xmlNotationTablePtr table) {
                   1080:     int i;
                   1081: 
                   1082:     if (table == NULL) return;
                   1083: 
                   1084:     for (i = 0;i < table->nb_notations;i++) {
1.15    ! daniel   1085:         xmlFreeNotation(table->table[i]);
1.5       daniel   1086:     }
                   1087:     free(table->table);
                   1088:     free(table);
                   1089: }
                   1090: 
                   1091: /**
                   1092:  * xmlCopyNotationTable:
                   1093:  * @table:  A notation table
                   1094:  *
                   1095:  * Build a copy of a notation table.
                   1096:  * 
1.6       daniel   1097:  * Returns the new xmlNotationTablePtr or NULL in case of error.
1.5       daniel   1098:  */
                   1099: xmlNotationTablePtr
                   1100: xmlCopyNotationTable(xmlNotationTablePtr table) {
                   1101:     xmlNotationTablePtr ret;
                   1102:     xmlNotationPtr cur, nota;
                   1103:     int i;
                   1104: 
                   1105:     ret = (xmlNotationTablePtr) malloc(sizeof(xmlNotationTable));
                   1106:     if (ret == NULL) {
                   1107:         fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
                   1108:        return(NULL);
                   1109:     }
1.15    ! daniel   1110:     ret->table = (xmlNotationPtr *) malloc(table->max_notations *
        !          1111:                                          sizeof(xmlNotationPtr));
1.5       daniel   1112:     if (ret->table == NULL) {
                   1113:         fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
                   1114:        free(ret);
                   1115:        return(NULL);
                   1116:     }
                   1117:     ret->max_notations = table->max_notations;
                   1118:     ret->nb_notations = table->nb_notations;
                   1119:     for (i = 0;i < ret->nb_notations;i++) {
1.15    ! daniel   1120:        cur = (xmlNotationPtr) malloc(sizeof(xmlNotation));
        !          1121:        if (cur == NULL) {
        !          1122:            fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
        !          1123:            free(ret);
        !          1124:            free(ret->table);
        !          1125:            return(NULL);
        !          1126:        }
        !          1127:        ret->table[i] = cur;
        !          1128:        nota = table->table[i];
1.5       daniel   1129:        if (nota->name != NULL)
                   1130:            cur->name = xmlStrdup(nota->name);
                   1131:        else
                   1132:            cur->name = NULL;
                   1133:        if (nota->PublicID != NULL)
                   1134:            cur->PublicID = xmlStrdup(nota->PublicID);
                   1135:        else
                   1136:            cur->PublicID = NULL;
                   1137:        if (nota->SystemID != NULL)
                   1138:            cur->SystemID = xmlStrdup(nota->SystemID);
                   1139:        else
                   1140:            cur->SystemID = NULL;
                   1141:     }
                   1142:     return(ret);
                   1143: }
                   1144: 
                   1145: /**
                   1146:  * xmlDumpNotationTable:
1.9       daniel   1147:  * @buf:  the XML buffer output
1.5       daniel   1148:  * @table:  A notation table
                   1149:  *
                   1150:  * This will dump the content of the notation table as an XML DTD definition
                   1151:  */
                   1152: void
1.8       daniel   1153: xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
1.5       daniel   1154:     int i;
                   1155:     xmlNotationPtr cur;
                   1156: 
                   1157:     if (table == NULL) return;
                   1158: 
                   1159:     for (i = 0;i < table->nb_notations;i++) {
1.15    ! daniel   1160:         cur = table->table[i];
1.8       daniel   1161:        xmlBufferWriteChar(buf, "<!NOTATION ");
                   1162:        xmlBufferWriteCHAR(buf, cur->name);
1.5       daniel   1163:        if (cur->PublicID != NULL) {
1.10      daniel   1164:            xmlBufferWriteChar(buf, " PUBLIC ");
                   1165:            xmlBufferWriteQuotedString(buf, cur->PublicID);
1.5       daniel   1166:            if (cur->SystemID != NULL) {
1.8       daniel   1167:                xmlBufferWriteChar(buf, " ");
                   1168:                xmlBufferWriteCHAR(buf, cur->SystemID);
1.5       daniel   1169:            }
                   1170:        } else {
1.8       daniel   1171:            xmlBufferWriteChar(buf, " SYSTEM ");
                   1172:            xmlBufferWriteCHAR(buf, cur->SystemID);
1.5       daniel   1173:        }
1.8       daniel   1174:         xmlBufferWriteChar(buf, " >\n");
1.2       daniel   1175:     }
                   1176: }
1.14      daniel   1177: 
                   1178: /************************************************************************
                   1179:  *                                                                     *
                   1180:  *             Routines for validity checking                          *
                   1181:  *                                                                     *
                   1182:  ************************************************************************/
                   1183: 
                   1184: #define VERROR                                                 \
                   1185:    if ((ctxt != NULL) && (ctxt->error != NULL)) ctxt->error
                   1186: 
                   1187: #define VWARNING                                               \
                   1188:    if ((ctxt != NULL) && (ctxt->warning != NULL)) ctxt->warning
                   1189: 
                   1190: #define CHECK_DTD                                              \
                   1191:    if (doc == NULL) return(0);                                 \
                   1192:    else if (doc->intSubset == NULL) return(0)
                   1193: 
                   1194: /**
                   1195:  * xmlGetDtdElementDesc:
                   1196:  * @dtd:  a pointer to the DtD to search
                   1197:  * @name:  the element name
                   1198:  *
                   1199:  * Search the Dtd for the description of this element
                   1200:  *
                   1201:  * returns the xmlElementPtr if found or NULL
                   1202:  */
                   1203: 
                   1204: xmlElementPtr
                   1205: xmlGetDtdElementDesc(xmlDtdPtr dtd, const CHAR *name) {
                   1206:     xmlElementTablePtr table;
                   1207:     xmlElementPtr cur;
                   1208:     int i;
                   1209: 
                   1210:     if (dtd == NULL) return(NULL);
                   1211:     if (dtd->elements == NULL) return(NULL);
                   1212:     table = dtd->elements;
                   1213: 
                   1214:     for (i = 0;i < table->nb_elements;i++) {
1.15    ! daniel   1215:         cur = table->table[i];
1.14      daniel   1216:        if (!xmlStrcmp(cur->name, name))
                   1217:            return(cur);
                   1218:     }
                   1219:     return(NULL);
                   1220: }
                   1221: 
                   1222: /**
                   1223:  * xmlGetDtdAttrDesc:
                   1224:  * @dtd:  a pointer to the DtD to search
1.15    ! daniel   1225:  * @elem:  the element name
1.14      daniel   1226:  * @name:  the attribute name
                   1227:  *
1.15    ! daniel   1228:  * Search the Dtd for the description of this attribute on
        !          1229:  * this element.
1.14      daniel   1230:  *
                   1231:  * returns the xmlAttributePtr if found or NULL
                   1232:  */
                   1233: 
                   1234: xmlAttributePtr
1.15    ! daniel   1235: xmlGetDtdAttrDesc(xmlDtdPtr dtd, const CHAR *elem, const CHAR *name) {
1.14      daniel   1236:     xmlAttributeTablePtr table;
                   1237:     xmlAttributePtr cur;
                   1238:     int i;
                   1239: 
                   1240:     if (dtd == NULL) return(NULL);
                   1241:     if (dtd->attributes == NULL) return(NULL);
                   1242:     table = dtd->attributes;
                   1243: 
                   1244:     for (i = 0;i < table->nb_attributes;i++) {
1.15    ! daniel   1245:         cur = table->table[i];
        !          1246:        if ((!xmlStrcmp(cur->name, name)) &&
        !          1247:            (!xmlStrcmp(cur->elem, elem)))
1.14      daniel   1248:            return(cur);
                   1249:     }
                   1250:     return(NULL);
                   1251: }
                   1252: 
                   1253: /**
                   1254:  * xmlGetDtdNotationDesc:
                   1255:  * @dtd:  a pointer to the DtD to search
                   1256:  * @name:  the notation name
                   1257:  *
                   1258:  * Search the Dtd for the description of this notation
                   1259:  *
                   1260:  * returns the xmlNotationPtr if found or NULL
                   1261:  */
                   1262: 
                   1263: xmlNotationPtr
                   1264: xmlGetDtdNotationDesc(xmlDtdPtr dtd, const CHAR *name) {
                   1265:     xmlNotationTablePtr table;
                   1266:     xmlNotationPtr cur;
                   1267:     int i;
                   1268: 
                   1269:     if (dtd == NULL) return(NULL);
                   1270:     if (dtd->notations == NULL) return(NULL);
                   1271:     table = dtd->notations;
                   1272: 
                   1273:     for (i = 0;i < table->nb_notations;i++) {
1.15    ! daniel   1274:         cur = table->table[i];
1.14      daniel   1275:        if (!xmlStrcmp(cur->name, name))
                   1276:            return(cur);
                   1277:     }
                   1278:     return(NULL);
                   1279: }
                   1280: 
                   1281: /**
                   1282:  * xmlValidateAttributeDecl:
                   1283:  * @doc:  a document instance
                   1284:  * @attr:  an attribute definition
                   1285:  *
                   1286:  * Try to validate a single attribute definition
                   1287:  * basically it does the following checks as described by the
                   1288:  * XML-1.0 recommendation:
                   1289:  *  - [ VC: Attribute Default Legal ]
                   1290:  *  - [ VC: Notation Declared ]
                   1291:  *  - [ VC: Notation Attributes ]
                   1292:  *  - [ VC: Enumeration ]
                   1293:  *  - [ VC: ID Attribute Default ]
                   1294:  *
                   1295:  * The ID/IDREF uniqueness and matching are done separately
                   1296:  *
                   1297:  * returns 1 if valid or 0 otherwise
                   1298:  */
                   1299: 
                   1300: int
                   1301: xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                   1302:                          xmlAttributePtr attr) {
                   1303:     CHECK_DTD;
                   1304: 
                   1305:     return(1);
                   1306: }
                   1307: 
                   1308: /**
                   1309:  * xmlValidateElementDecl:
                   1310:  * @ctxt:  the validation context
                   1311:  * @doc:  a document instance
                   1312:  * @elem:  an element definition
                   1313:  *
                   1314:  * Try to validate a single element definition
                   1315:  * basically it does the following checks as described by the
                   1316:  * XML-1.0 recommendation:
                   1317:  *  - [ VC: One ID per Element Type ]
                   1318:  *  - [ VC: No Duplicate Types ]
                   1319:  *  - [ VC: Unique Element Type Declaration ]
                   1320:  *
                   1321:  * returns 1 if valid or 0 otherwise
                   1322:  */
                   1323: 
                   1324: int
                   1325: xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlElementPtr elem) {
                   1326:     CHECK_DTD;
                   1327: 
                   1328:     return(1);
                   1329: }
                   1330: 
                   1331: /**
                   1332:  * xmlValidateOneAttribute:
                   1333:  * @ctxt:  the validation context
                   1334:  * @doc:  a document instance
                   1335:  * @elem:  an element instance
                   1336:  * @attr:  an attribute instance
                   1337:  *
                   1338:  * Try to validate a single attribute for an element
                   1339:  * basically it * does the following checks as described by the
                   1340:  * XML-1.0 recommendation:
                   1341:  *  - [ VC: Entity Name ]
                   1342:  *  - [ VC: Name Token ]
                   1343:  *  - [ VC: Fixed Attribute Default ]
                   1344:  *  - [ VC: ID ]
                   1345:  *  - [ VC: IDREF ]
                   1346:  *  - [ VC: Entity Name ]
                   1347:  *
                   1348:  * The ID/IDREF uniqueness and matching are done separately
                   1349:  *
                   1350:  * returns 1 if valid or 0 otherwise
                   1351:  */
                   1352: 
                   1353: int
                   1354: xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlElementPtr elem,
                   1355:                         xmlAttributePtr attr) {
                   1356:     CHECK_DTD;
                   1357: 
                   1358:     return(1);
                   1359: }
                   1360: 
                   1361: /**
                   1362:  * xmlValidateOneElement:
                   1363:  * @ctxt:  the validation context
                   1364:  * @doc:  a document instance
                   1365:  * @elem:  an element instance
                   1366:  *
                   1367:  * Try to validate a single element and it's attributes,
                   1368:  * basically it does the following checks as described by the
                   1369:  * XML-1.0 recommendation:
                   1370:  *  - [ VC: Element Valid ]
                   1371:  *  - [ VC: Required Attribute ]
                   1372:  * Then call xmlValidateOneAttribute() for each attribute present.
                   1373:  *
                   1374:  * The ID/IDREF checkings are done separately
                   1375:  *
                   1376:  * returns 1 if valid or 0 otherwise
                   1377:  */
                   1378: 
                   1379: int
                   1380: xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlElementPtr elem) {
                   1381:     CHECK_DTD;
                   1382: 
                   1383:     return(1);
                   1384: }
                   1385: 
                   1386: /**
                   1387:  * xmlValidateRoot:
                   1388:  * @ctxt:  the validation context
                   1389:  * @doc:  a document instance
                   1390:  *
                   1391:  * Try to validate a the root element
                   1392:  * basically it does the following check as described by the
                   1393:  * XML-1.0 recommendation:
                   1394:  *  - [ VC: Root Element Type ]
                   1395:  * it doesn't try to recurse or apply other check to the element
                   1396:  *
                   1397:  * returns 1 if valid or 0 otherwise
                   1398:  */
                   1399: 
                   1400: int
                   1401: xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
                   1402:     if (doc == NULL) return(0);
                   1403: 
                   1404:     if ((doc->intSubset == NULL) ||
                   1405:        (doc->intSubset->name == NULL)) {
                   1406:        VERROR(ctxt->userData, "Not valid: no DtD found\n");
                   1407:         return(0);
                   1408:     }
                   1409:     if ((doc->root == NULL) || (doc->root->name == NULL)) {
                   1410:        VERROR(ctxt->userData, "Not valid: no root element\n");
                   1411:         return(0);
                   1412:     }
                   1413:     if (xmlStrcmp(doc->intSubset->name, doc->root->name)) {
                   1414:        VERROR(ctxt->userData,
                   1415:               "Not valid: root and DtD name do not match %s and %s\n",
                   1416:               doc->root->name, doc->intSubset->name);
                   1417:        return(0);
                   1418:     }
                   1419:     return(1);
                   1420: }
                   1421: 
                   1422: 
                   1423: /**
                   1424:  * xmlValidateElement:
                   1425:  * @ctxt:  the validation context
                   1426:  * @doc:  a document instance
                   1427:  * @elem:  an element instance
                   1428:  *
                   1429:  * Try to validate the subtree under an element 
                   1430:  *
                   1431:  * returns 1 if valid or 0 otherwise
                   1432:  */
                   1433: 
                   1434: int
                   1435: xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlElementPtr elem) {
                   1436:     CHECK_DTD;
                   1437: 
                   1438:     return(1);
                   1439: }
                   1440: 
                   1441: /**
                   1442:  * xmlValidateDtd:
                   1443:  * @ctxt:  the validation context
                   1444:  * @doc:  a document instance
                   1445:  * @dtd:  a dtd instance
                   1446:  *
                   1447:  * Try to validate the dtd instance
                   1448:  *
                   1449:  * basically it does check all the definitions in the DtD.
                   1450:  *
                   1451:  * returns 1 if valid or 0 otherwise
                   1452:  */
                   1453: 
                   1454: int
                   1455: xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
                   1456:     return(1);
                   1457: }
                   1458: 
                   1459: /**
                   1460:  * xmlValidateDocument:
                   1461:  * @ctxt:  the validation context
                   1462:  * @doc:  a document instance
                   1463:  *
                   1464:  * Try to validate the document instance
                   1465:  *
                   1466:  * basically it does the all the checks described by the
                   1467:  * i.e. validates the internal and external subset (if present)
                   1468:  * and validate the document tree.
                   1469:  *
                   1470:  * returns 1 if valid or 0 otherwise
                   1471:  */
                   1472: 
                   1473: int
                   1474: xmlValidateDocument(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
                   1475:     if (!xmlValidateRoot(ctxt, doc)) return(0);
                   1476: 
                   1477:     return(1);
                   1478: }
                   1479: 

Webmaster