Annotation of XML/valid.c, revision 1.18

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"
1.16      daniel     15: #include "parserInternals.h"
                     16: 
                     17: #define VERROR                                                 \
                     18:    if ((ctxt != NULL) && (ctxt->error != NULL)) ctxt->error
                     19: 
                     20: #define VWARNING                                               \
                     21:    if ((ctxt != NULL) && (ctxt->warning != NULL)) ctxt->warning
                     22: 
                     23: #define CHECK_DTD                                              \
                     24:    if (doc == NULL) return(0);                                 \
                     25:    else if (doc->intSubset == NULL) return(0)
1.1       daniel     26: 
1.15      daniel     27: xmlElementPtr xmlGetDtdElementDesc(xmlDtdPtr dtd, const CHAR *name);
                     28: xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const CHAR *elem);
                     29: 
1.1       daniel     30: /****************************************************************
                     31:  *                                                             *
                     32:  *     Util functions for data allocation/deallocation         *
                     33:  *                                                             *
                     34:  ****************************************************************/
                     35: 
                     36: /**
                     37:  * xmlNewElementContent:
                     38:  * @name:  the subelement name or NULL
                     39:  * @type:  the type of element content decl
                     40:  *
                     41:  * Allocate an element content structure.
                     42:  *
1.6       daniel     43:  * Returns NULL if not, othervise the new element content structure
1.1       daniel     44:  */
                     45: xmlElementContentPtr
                     46: xmlNewElementContent(CHAR *name, int type) {
1.2       daniel     47:     xmlElementContentPtr ret;
                     48: 
                     49:     switch(type) {
                     50:        case XML_ELEMENT_CONTENT_ELEMENT:
                     51:            if (name == NULL) {
                     52:                fprintf(stderr, "xmlNewElementContent : name == NULL !\n");
                     53:            }
                     54:            break;
                     55:         case XML_ELEMENT_CONTENT_PCDATA:
                     56:        case XML_ELEMENT_CONTENT_SEQ:
                     57:        case XML_ELEMENT_CONTENT_OR:
                     58:            if (name != NULL) {
                     59:                fprintf(stderr, "xmlNewElementContent : name != NULL !\n");
                     60:            }
                     61:            break;
                     62:        default:
                     63:            fprintf(stderr, "xmlNewElementContent: unknown type %d\n", type);
                     64:            exit(1);
                     65:     }
                     66:     ret = (xmlElementContentPtr) malloc(sizeof(xmlElementContent));
                     67:     if (ret == NULL) {
                     68:        fprintf(stderr, "xmlNewElementContent : out of memory!\n");
                     69:        return(NULL);
                     70:     }
                     71:     ret->type = type;
                     72:     ret->ocur = XML_ELEMENT_CONTENT_ONCE;
                     73:     if (name != NULL)
                     74:         ret->name = xmlStrdup(name);
                     75:     else
                     76:         ret->name = NULL;
1.4       daniel     77:     ret->c1 = ret->c2 = NULL;
1.2       daniel     78:     return(ret);
                     79: }
                     80: 
                     81: /**
                     82:  * xmlCopyElementContent:
                     83:  * @content:  An element content pointer.
                     84:  *
                     85:  * Build a copy of an element content description.
                     86:  * 
1.6       daniel     87:  * Returns the new xmlElementContentPtr or NULL in case of error.
1.2       daniel     88:  */
                     89: xmlElementContentPtr
1.4       daniel     90: xmlCopyElementContent(xmlElementContentPtr cur) {
                     91:     xmlElementContentPtr ret;
                     92: 
                     93:     if (cur == NULL) return(NULL);
                     94:     ret = xmlNewElementContent((CHAR *) cur->name, cur->type);
1.11      daniel     95:     if (ret == NULL) {
                     96:         fprintf(stderr, "xmlCopyElementContent : out of memory\n");
                     97:        return(NULL);
                     98:     }
                     99:     ret->ocur = cur->ocur;
                    100:     if (cur->c1 != NULL) ret->c1 = xmlCopyElementContent(cur->c1);
                    101:     if (cur->c2 != NULL) ret->c2 = xmlCopyElementContent(cur->c2);
1.4       daniel    102:     return(ret);
1.1       daniel    103: }
                    104: 
                    105: /**
1.3       daniel    106:  * xmlFreeElementContent:
                    107:  * @cur:  the element content tree to free
1.1       daniel    108:  *
                    109:  * Free an element content structure. This is a recursive call !
                    110:  */
                    111: void
                    112: xmlFreeElementContent(xmlElementContentPtr cur) {
1.4       daniel    113:     if (cur == NULL) return;
                    114:     if (cur->c1 != NULL) xmlFreeElementContent(cur->c1);
                    115:     if (cur->c2 != NULL) xmlFreeElementContent(cur->c2);
                    116:     if (cur->name != NULL) free((CHAR *) cur->name);
                    117:     memset(cur, -1, sizeof(xmlElementContent));
                    118:     free(cur);
1.1       daniel    119: }
                    120: 
1.3       daniel    121: /**
                    122:  * xmlDumpElementContent:
1.8       daniel    123:  * @buf:  An XML buffer
1.3       daniel    124:  * @content:  An element table
                    125:  * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
                    126:  *
                    127:  * This will dump the content of the element table as an XML DTD definition
                    128:  */
                    129: void
1.8       daniel    130: xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) {
1.3       daniel    131:     if (content == NULL) return;
                    132: 
1.8       daniel    133:     if (glob) xmlBufferWriteChar(buf, "(");
1.3       daniel    134:     switch (content->type) {
                    135:         case XML_ELEMENT_CONTENT_PCDATA:
1.8       daniel    136:             xmlBufferWriteChar(buf, "#PCDATA");
1.3       daniel    137:            break;
                    138:        case XML_ELEMENT_CONTENT_ELEMENT:
1.8       daniel    139:            xmlBufferWriteCHAR(buf, content->name);
1.3       daniel    140:            break;
                    141:        case XML_ELEMENT_CONTENT_SEQ:
                    142:            if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
                    143:                (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
1.8       daniel    144:                xmlDumpElementContent(buf, content->c1, 1);
1.3       daniel    145:            else
1.8       daniel    146:                xmlDumpElementContent(buf, content->c1, 0);
                    147:             xmlBufferWriteChar(buf, " , ");
1.3       daniel    148:            if (content->c2->type == XML_ELEMENT_CONTENT_OR)
1.8       daniel    149:                xmlDumpElementContent(buf, content->c2, 1);
1.3       daniel    150:            else
1.8       daniel    151:                xmlDumpElementContent(buf, content->c2, 0);
1.3       daniel    152:            break;
                    153:        case XML_ELEMENT_CONTENT_OR:
                    154:            if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
                    155:                (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
1.8       daniel    156:                xmlDumpElementContent(buf, content->c1, 1);
1.3       daniel    157:            else
1.8       daniel    158:                xmlDumpElementContent(buf, content->c1, 0);
                    159:             xmlBufferWriteChar(buf, " | ");
1.3       daniel    160:            if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)
1.8       daniel    161:                xmlDumpElementContent(buf, content->c2, 1);
1.3       daniel    162:            else
1.8       daniel    163:                xmlDumpElementContent(buf, content->c2, 0);
1.3       daniel    164:            break;
                    165:        default:
                    166:            fprintf(stderr, "xmlDumpElementContent: unknown type %d\n",
                    167:                    content->type);
                    168:     }
                    169:     if (glob)
1.8       daniel    170:         xmlBufferWriteChar(buf, ")");
1.3       daniel    171:     switch (content->ocur) {
                    172:         case XML_ELEMENT_CONTENT_ONCE:
                    173:            break;
                    174:         case XML_ELEMENT_CONTENT_OPT:
1.8       daniel    175:            xmlBufferWriteChar(buf, "?");
1.3       daniel    176:            break;
                    177:         case XML_ELEMENT_CONTENT_MULT:
1.8       daniel    178:            xmlBufferWriteChar(buf, "*");
1.3       daniel    179:            break;
                    180:         case XML_ELEMENT_CONTENT_PLUS:
1.8       daniel    181:            xmlBufferWriteChar(buf, "+");
1.3       daniel    182:            break;
                    183:     }
                    184: }
                    185: 
1.1       daniel    186: /****************************************************************
                    187:  *                                                             *
                    188:  *     Registration of DTD declarations                        *
                    189:  *                                                             *
                    190:  ****************************************************************/
                    191: 
1.2       daniel    192: /**
                    193:  * xmlCreateElementTable:
                    194:  *
                    195:  * create and initialize an empty element hash table.
                    196:  *
1.6       daniel    197:  * Returns the xmlElementTablePtr just created or NULL in case of error.
1.2       daniel    198:  */
                    199: xmlElementTablePtr
                    200: xmlCreateElementTable(void) {
                    201:     xmlElementTablePtr ret;
                    202: 
                    203:     ret = (xmlElementTablePtr) 
                    204:          malloc(sizeof(xmlElementTable));
                    205:     if (ret == NULL) {
1.12      daniel    206:         fprintf(stderr, "xmlCreateElementTable : malloc(%ld) failed\n",
                    207:                (long)sizeof(xmlElementTable));
1.2       daniel    208:         return(NULL);
                    209:     }
1.4       daniel    210:     ret->max_elements = XML_MIN_ELEMENT_TABLE;
1.2       daniel    211:     ret->nb_elements = 0;
1.15      daniel    212:     ret->table = (xmlElementPtr *) 
                    213:          malloc(ret->max_elements * sizeof(xmlElementPtr));
1.2       daniel    214:     if (ret == NULL) {
1.12      daniel    215:         fprintf(stderr, "xmlCreateElementTable : malloc(%ld) failed\n",
                    216:                ret->max_elements * (long)sizeof(xmlElement));
1.2       daniel    217:        free(ret);
                    218:         return(NULL);
                    219:     }
                    220:     return(ret);
                    221: }
                    222: 
1.1       daniel    223: 
                    224: /**
                    225:  * xmlAddElementDecl:
1.6       daniel    226:  * @dtd:  pointer to the DTD
1.1       daniel    227:  * @name:  the entity name
1.6       daniel    228:  * @type:  the element type
                    229:  * @content:  the element content tree or NULL
1.1       daniel    230:  *
                    231:  * Register a new element declaration
                    232:  *
1.6       daniel    233:  * Returns NULL if not, othervise the entity
1.1       daniel    234:  */
                    235: xmlElementPtr
1.16      daniel    236: xmlAddElementDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const CHAR *name,
                    237:                   int type, xmlElementContentPtr content) {
1.2       daniel    238:     xmlElementPtr ret, cur;
                    239:     xmlElementTablePtr table;
                    240:     int i;
1.1       daniel    241: 
                    242:     if (dtd == NULL) {
                    243:         fprintf(stderr, "xmlAddElementDecl: dtd == NULL\n");
                    244:        return(NULL);
                    245:     }
                    246:     if (name == NULL) {
                    247:         fprintf(stderr, "xmlAddElementDecl: name == NULL\n");
                    248:        return(NULL);
                    249:     }
                    250:     switch (type) {
                    251:         case XML_ELEMENT_TYPE_EMPTY:
                    252:            if (content != NULL) {
                    253:                fprintf(stderr,
                    254:                        "xmlAddElementDecl: content != NULL for EMPTY\n");
                    255:                return(NULL);
                    256:            }
                    257:            break;
                    258:        case XML_ELEMENT_TYPE_ANY:
                    259:            if (content != NULL) {
                    260:                fprintf(stderr,
                    261:                        "xmlAddElementDecl: content != NULL for ANY\n");
                    262:                return(NULL);
                    263:            }
                    264:            break;
                    265:        case XML_ELEMENT_TYPE_MIXED:
                    266:            if (content == NULL) {
                    267:                fprintf(stderr,
                    268:                        "xmlAddElementDecl: content == NULL for MIXED\n");
                    269:                return(NULL);
                    270:            }
                    271:            break;
                    272:        case XML_ELEMENT_TYPE_ELEMENT:
                    273:            if (content == NULL) {
                    274:                fprintf(stderr,
                    275:                        "xmlAddElementDecl: content == NULL for ELEMENT\n");
                    276:                return(NULL);
                    277:            }
                    278:            break;
                    279:        default:
                    280:            fprintf(stderr, "xmlAddElementDecl: unknown type %d\n", type);
                    281:            return(NULL);
                    282:     }
                    283: 
                    284:     /*
1.2       daniel    285:      * Create the Element table if needed.
                    286:      */
                    287:     table = dtd->elements;
                    288:     if (table == NULL) 
                    289:         table = dtd->elements = xmlCreateElementTable();
                    290:     if (table == NULL) {
                    291:        fprintf(stderr, "xmlAddElementDecl: Table creation failed!\n");
                    292:         return(NULL);
                    293:     }
                    294: 
                    295:     /*
1.1       daniel    296:      * Validity Check:
                    297:      * Search the DTD for previous declarations of the ELEMENT
                    298:      */
1.2       daniel    299:     for (i = 0;i < table->nb_elements;i++) {
1.15      daniel    300:         cur = table->table[i];
1.2       daniel    301:        if (!xmlStrcmp(cur->name, name)) {
                    302:            /*
                    303:             * The element is already defined in this Dtd.
                    304:             */
1.16      daniel    305:            VERROR(ctxt->userData, "Redefinition of element %s\n", name);
1.2       daniel    306:            return(NULL);
                    307:        }
                    308:     }
1.1       daniel    309: 
                    310:     /*
1.2       daniel    311:      * Grow the table, if needed.
1.1       daniel    312:      */
1.2       daniel    313:     if (table->nb_elements >= table->max_elements) {
                    314:         /*
                    315:         * need more elements.
                    316:         */
                    317:        table->max_elements *= 2;
1.15      daniel    318:        table->table = (xmlElementPtr *) 
                    319:            realloc(table->table, table->max_elements * sizeof(xmlElementPtr));
1.13      daniel    320:        if (table->table == NULL) {
1.2       daniel    321:            fprintf(stderr, "xmlAddElementDecl: out of memory\n");
                    322:            return(NULL);
                    323:        }
1.1       daniel    324:     }
1.15      daniel    325:     ret = (xmlElementPtr) malloc(sizeof(xmlElement));
                    326:     if (ret == NULL) {
                    327:        fprintf(stderr, "xmlAddElementDecl: out of memory\n");
                    328:        return(NULL);
                    329:     }
                    330:     table->table[table->nb_elements] = ret;
1.2       daniel    331: 
                    332:     /*
                    333:      * fill the structure.
                    334:      */
1.1       daniel    335:     ret->type = type;
                    336:     ret->name = xmlStrdup(name);
1.11      daniel    337:     ret->content = xmlCopyElementContent(content);
1.15      daniel    338:     ret->attributes = xmlScanAttributeDecl(dtd, name);
1.2       daniel    339:     table->nb_elements++;
                    340: 
                    341:     return(ret);
                    342: }
                    343: 
                    344: /**
                    345:  * xmlFreeElement:
                    346:  * @elem:  An element
                    347:  *
                    348:  * Deallocate the memory used by an element definition
                    349:  */
                    350: void
                    351: xmlFreeElement(xmlElementPtr elem) {
                    352:     if (elem == NULL) return;
                    353:     xmlFreeElementContent(elem->content);
                    354:     if (elem->name != NULL)
                    355:        free((CHAR *) elem->name);
                    356:     memset(elem, -1, sizeof(xmlElement));
1.15      daniel    357:     free(elem);
1.2       daniel    358: }
1.1       daniel    359: 
1.2       daniel    360: /**
                    361:  * xmlFreeElementTable:
                    362:  * @table:  An element table
                    363:  *
1.4       daniel    364:  * Deallocate the memory used by an element hash table.
1.2       daniel    365:  */
                    366: void
                    367: xmlFreeElementTable(xmlElementTablePtr table) {
                    368:     int i;
                    369: 
                    370:     if (table == NULL) return;
                    371: 
                    372:     for (i = 0;i < table->nb_elements;i++) {
1.15      daniel    373:         xmlFreeElement(table->table[i]);
1.2       daniel    374:     }
                    375:     free(table->table);
                    376:     free(table);
                    377: }
                    378: 
                    379: /**
                    380:  * xmlCopyElementTable:
                    381:  * @table:  An element table
                    382:  *
                    383:  * Build a copy of an element table.
                    384:  * 
1.6       daniel    385:  * Returns the new xmlElementTablePtr or NULL in case of error.
1.2       daniel    386:  */
                    387: xmlElementTablePtr
                    388: xmlCopyElementTable(xmlElementTablePtr table) {
                    389:     xmlElementTablePtr ret;
                    390:     xmlElementPtr cur, ent;
                    391:     int i;
1.1       daniel    392: 
1.2       daniel    393:     ret = (xmlElementTablePtr) malloc(sizeof(xmlElementTable));
                    394:     if (ret == NULL) {
                    395:         fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
                    396:        return(NULL);
                    397:     }
1.15      daniel    398:     ret->table = (xmlElementPtr *) malloc(table->max_elements *
                    399:                                          sizeof(xmlElementPtr));
1.2       daniel    400:     if (ret->table == NULL) {
                    401:         fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
                    402:        free(ret);
                    403:        return(NULL);
                    404:     }
                    405:     ret->max_elements = table->max_elements;
                    406:     ret->nb_elements = table->nb_elements;
                    407:     for (i = 0;i < ret->nb_elements;i++) {
1.15      daniel    408:        cur = (xmlElementPtr) malloc(sizeof(xmlElement));
                    409:        if (cur == NULL) {
                    410:            fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
                    411:            free(ret);
                    412:            free(ret->table);
                    413:            return(NULL);
                    414:        }
                    415:        ret->table[i] = cur;
                    416:        ent = table->table[i];
1.2       daniel    417:        cur->type = ent->type;
                    418:        if (ent->name != NULL)
                    419:            cur->name = xmlStrdup(ent->name);
                    420:        else
                    421:            cur->name = NULL;
                    422:        cur->content = xmlCopyElementContent(ent->content);
1.15      daniel    423:        cur->attributes = NULL;
1.2       daniel    424:     }
1.1       daniel    425:     return(ret);
                    426: }
                    427: 
1.2       daniel    428: /**
                    429:  * xmlDumpElementTable:
1.9       daniel    430:  * @buf:  the XML buffer output
1.2       daniel    431:  * @table:  An element table
                    432:  *
                    433:  * This will dump the content of the element table as an XML DTD definition
                    434:  */
                    435: void
1.8       daniel    436: xmlDumpElementTable(xmlBufferPtr buf, xmlElementTablePtr table) {
1.2       daniel    437:     int i;
                    438:     xmlElementPtr cur;
                    439: 
                    440:     if (table == NULL) return;
                    441: 
                    442:     for (i = 0;i < table->nb_elements;i++) {
1.15      daniel    443:         cur = table->table[i];
1.2       daniel    444:         switch (cur->type) {
                    445:            case XML_ELEMENT_TYPE_EMPTY:
1.8       daniel    446:                xmlBufferWriteChar(buf, "<!ELEMENT ");
                    447:                xmlBufferWriteCHAR(buf, cur->name);
                    448:                xmlBufferWriteChar(buf, " EMPTY>\n");
1.2       daniel    449:                break;
                    450:            case XML_ELEMENT_TYPE_ANY:
1.8       daniel    451:                xmlBufferWriteChar(buf, "<!ELEMENT ");
                    452:                xmlBufferWriteCHAR(buf, cur->name);
                    453:                xmlBufferWriteChar(buf, " ANY>\n");
1.2       daniel    454:                break;
                    455:            case XML_ELEMENT_TYPE_MIXED:
1.8       daniel    456:                xmlBufferWriteChar(buf, "<!ELEMENT ");
                    457:                xmlBufferWriteCHAR(buf, cur->name);
                    458:                xmlBufferWriteChar(buf, " ");
                    459:                xmlDumpElementContent(buf, cur->content, 1);
                    460:                xmlBufferWriteChar(buf, ">\n");
1.2       daniel    461:                break;
                    462:            case XML_ELEMENT_TYPE_ELEMENT:
1.8       daniel    463:                xmlBufferWriteChar(buf, "<!ELEMENT ");
                    464:                xmlBufferWriteCHAR(buf, cur->name);
                    465:                xmlBufferWriteChar(buf, " ");
                    466:                xmlDumpElementContent(buf, cur->content, 1);
                    467:                xmlBufferWriteChar(buf, ">\n");
1.2       daniel    468:                break;
                    469:            default:
                    470:                fprintf(stderr,
                    471:                    "xmlDumpElementTable: internal: unknown type %d\n",
                    472:                        cur->type);
                    473:        }
1.4       daniel    474:     }
                    475: }
                    476: 
                    477: /**
                    478:  * xmlCreateEnumeration:
                    479:  * @name:  the enumeration name or NULL
                    480:  *
                    481:  * create and initialize an enumeration attribute node.
                    482:  *
1.6       daniel    483:  * Returns the xmlEnumerationPtr just created or NULL in case
1.4       daniel    484:  *                of error.
                    485:  */
                    486: xmlEnumerationPtr
                    487: xmlCreateEnumeration(CHAR *name) {
                    488:     xmlEnumerationPtr ret;
                    489: 
                    490:     ret = (xmlEnumerationPtr) malloc(sizeof(xmlEnumeration));
                    491:     if (ret == NULL) {
1.12      daniel    492:         fprintf(stderr, "xmlCreateEnumeration : malloc(%ld) failed\n",
                    493:                (long)sizeof(xmlEnumeration));
1.4       daniel    494:         return(NULL);
                    495:     }
                    496: 
                    497:     if (name != NULL)
                    498:         ret->name = xmlStrdup(name);
                    499:     else
                    500:         ret->name = NULL;
                    501:     ret->next = NULL;
                    502:     return(ret);
                    503: }
                    504: 
                    505: /**
                    506:  * xmlFreeEnumeration:
                    507:  * @cur:  the tree to free.
                    508:  *
                    509:  * free an enumeration attribute node (recursive).
                    510:  */
                    511: void
                    512: xmlFreeEnumeration(xmlEnumerationPtr cur) {
                    513:     if (cur == NULL) return;
                    514: 
                    515:     if (cur->next != NULL) xmlFreeEnumeration(cur->next);
                    516: 
                    517:     if (cur->name != NULL) free((CHAR *) cur->name);
                    518:     memset(cur, -1, sizeof(xmlEnumeration));
                    519:     free(cur);
                    520: }
                    521: 
                    522: /**
                    523:  * xmlCopyEnumeration:
                    524:  * @cur:  the tree to copy.
                    525:  *
                    526:  * Copy an enumeration attribute node (recursive).
                    527:  *
1.6       daniel    528:  * Returns the xmlEnumerationPtr just created or NULL in case
1.4       daniel    529:  *                of error.
                    530:  */
                    531: xmlEnumerationPtr
                    532: xmlCopyEnumeration(xmlEnumerationPtr cur) {
                    533:     xmlEnumerationPtr ret;
                    534: 
                    535:     if (cur == NULL) return(NULL);
                    536:     ret = xmlCreateEnumeration((CHAR *) cur->name);
                    537: 
                    538:     if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
                    539:     else ret->next = NULL;
                    540: 
                    541:     return(ret);
                    542: }
                    543: 
                    544: /**
1.18    ! daniel    545:  * xmlDumpEnumeration:
        !           546:  * @buf:  the XML buffer output
        !           547:  * @enum:  An enumeration
        !           548:  *
        !           549:  * This will dump the content of the enumeration
        !           550:  */
        !           551: void
        !           552: xmlDumpEnumeration(xmlBufferPtr buf, xmlEnumerationPtr cur) {
        !           553:     if (cur == NULL)  return;
        !           554:     
        !           555:     xmlBufferWriteCHAR(buf, cur->name);
        !           556:     if (cur->next == NULL)
        !           557:        xmlBufferWriteChar(buf, ")");
        !           558:     else {
        !           559:        xmlBufferWriteChar(buf, " | ");
        !           560:        xmlDumpEnumeration(buf, cur->next);
        !           561:     }
        !           562: }
        !           563: 
        !           564: /**
1.4       daniel    565:  * xmlCreateAttributeTable:
                    566:  *
                    567:  * create and initialize an empty attribute hash table.
                    568:  *
1.6       daniel    569:  * Returns the xmlAttributeTablePtr just created or NULL in case
1.4       daniel    570:  *                of error.
                    571:  */
                    572: xmlAttributeTablePtr
                    573: xmlCreateAttributeTable(void) {
                    574:     xmlAttributeTablePtr ret;
                    575: 
                    576:     ret = (xmlAttributeTablePtr) 
                    577:          malloc(sizeof(xmlAttributeTable));
                    578:     if (ret == NULL) {
1.12      daniel    579:         fprintf(stderr, "xmlCreateAttributeTable : malloc(%ld) failed\n",
                    580:                (long)sizeof(xmlAttributeTable));
1.4       daniel    581:         return(NULL);
                    582:     }
                    583:     ret->max_attributes = XML_MIN_ATTRIBUTE_TABLE;
                    584:     ret->nb_attributes = 0;
1.15      daniel    585:     ret->table = (xmlAttributePtr *) 
                    586:          malloc(ret->max_attributes * sizeof(xmlAttributePtr));
1.4       daniel    587:     if (ret == NULL) {
1.12      daniel    588:         fprintf(stderr, "xmlCreateAttributeTable : malloc(%ld) failed\n",
1.15      daniel    589:                ret->max_attributes * (long)sizeof(xmlAttributePtr));
1.4       daniel    590:        free(ret);
                    591:         return(NULL);
                    592:     }
                    593:     return(ret);
                    594: }
                    595: 
1.15      daniel    596: /**
                    597:  * xmlScanAttributeDecl:
                    598:  * @dtd:  pointer to the DTD
                    599:  * @elem:  the element name
                    600:  *
                    601:  * When inserting a new element scan the DtD for existing attributes
                    602:  * for taht element and initialize the Attribute chain
                    603:  *
                    604:  * Returns the pointer to the first attribute decl in the chain,
                    605:  *         possibly NULL.
                    606:  */
                    607: xmlAttributePtr
                    608: xmlScanAttributeDecl(xmlDtdPtr dtd, const CHAR *elem) {
1.16      daniel    609:     xmlAttributePtr ret = NULL;
1.15      daniel    610:     xmlAttributeTablePtr table;
                    611:     int i;
                    612: 
                    613:     if (dtd == NULL) {
                    614:         fprintf(stderr, "xmlScanAttributeDecl: dtd == NULL\n");
                    615:        return(NULL);
                    616:     }
                    617:     if (elem == NULL) {
                    618:         fprintf(stderr, "xmlScanAttributeDecl: elem == NULL\n");
                    619:        return(NULL);
                    620:     }
                    621:     table = dtd->attributes;
                    622:     if (table == NULL) 
                    623:         return(NULL);
                    624: 
                    625:     for (i = 0;i < table->nb_attributes;i++) {
                    626:         if (!xmlStrcmp(table->table[i]->elem, elem)) {
1.16      daniel    627:            table->table[i]->next = ret;
                    628:            ret = table->table[i];
                    629:        }
                    630:     }
                    631:     return(ret);
                    632: }
                    633: 
                    634: /**
                    635:  * xmlScanIDAttributeDecl:
                    636:  * @ctxt:  the validation context
                    637:  * @elem:  the element name
                    638:  *
                    639:  * Veryfy that the element don't have too many ID attributes
                    640:  * declared.
                    641:  *
                    642:  * Returns the number of ID attributes found.
                    643:  */
                    644: int
                    645: xmlScanIDAttributeDecl(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
                    646:     xmlAttributePtr cur;
                    647:     int ret = 0;
                    648: 
                    649:     if (elem == NULL) return(0);
                    650:     cur = elem->attributes;
                    651:     while (cur != NULL) {
                    652:         if (cur->type == XML_ATTRIBUTE_ID) {
                    653:            ret ++;
                    654:            if (ret > 1)
                    655:                VERROR(ctxt->userData, 
                    656:               "Element %s has too may ID attributes defined : %s\n",
                    657:                       elem->name, cur->name);
1.15      daniel    658:        }
1.16      daniel    659:        cur = cur->next;
1.15      daniel    660:     }
                    661:     return(ret);
                    662: }
                    663: 
1.4       daniel    664: 
                    665: /**
                    666:  * xmlAddAttributeDecl:
1.16      daniel    667:  * @ctxt:  the validation context
1.6       daniel    668:  * @dtd:  pointer to the DTD
                    669:  * @elem:  the element name
                    670:  * @name:  the attribute name
                    671:  * @type:  the attribute type
                    672:  * @def:  the attribute default type
                    673:  * @defaultValue:  the attribute default value
                    674:  * @tree:  if it's an enumeration, the associated list
1.4       daniel    675:  *
                    676:  * Register a new attribute declaration
                    677:  *
1.6       daniel    678:  * Returns NULL if not, othervise the entity
1.4       daniel    679:  */
                    680: xmlAttributePtr
1.16      daniel    681: xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const CHAR *elem,
                    682:                     const CHAR *name, int type, int def,
                    683:                    const CHAR *defaultValue, xmlEnumerationPtr tree) {
1.4       daniel    684:     xmlAttributePtr ret, cur;
                    685:     xmlAttributeTablePtr table;
1.15      daniel    686:     xmlElementPtr elemDef;
1.4       daniel    687:     int i;
                    688: 
                    689:     if (dtd == NULL) {
                    690:         fprintf(stderr, "xmlAddAttributeDecl: dtd == NULL\n");
                    691:        return(NULL);
                    692:     }
                    693:     if (name == NULL) {
                    694:         fprintf(stderr, "xmlAddAttributeDecl: name == NULL\n");
                    695:        return(NULL);
                    696:     }
                    697:     if (elem == NULL) {
                    698:         fprintf(stderr, "xmlAddAttributeDecl: elem == NULL\n");
                    699:        return(NULL);
                    700:     }
                    701:     /* TODO: Lacks verifications !!! */
                    702:     switch (type) {
                    703:         case XML_ATTRIBUTE_CDATA:
                    704:            break;
                    705:         case XML_ATTRIBUTE_ID:
                    706:            break;
                    707:         case XML_ATTRIBUTE_IDREF:
                    708:            break;
                    709:         case XML_ATTRIBUTE_IDREFS:
                    710:            break;
                    711:         case XML_ATTRIBUTE_ENTITY:
                    712:            break;
                    713:         case XML_ATTRIBUTE_ENTITIES:
                    714:            break;
                    715:         case XML_ATTRIBUTE_NMTOKEN:
                    716:            break;
                    717:         case XML_ATTRIBUTE_NMTOKENS:
                    718:            break;
                    719:         case XML_ATTRIBUTE_ENUMERATION:
                    720:            break;
                    721:         case XML_ATTRIBUTE_NOTATION:
                    722:            break;
                    723:        default:
                    724:            fprintf(stderr, "xmlAddAttributeDecl: unknown type %d\n", type);
                    725:            return(NULL);
                    726:     }
                    727: 
                    728:     /*
                    729:      * Create the Attribute table if needed.
                    730:      */
                    731:     table = dtd->attributes;
                    732:     if (table == NULL) 
                    733:         table = dtd->attributes = xmlCreateAttributeTable();
                    734:     if (table == NULL) {
                    735:        fprintf(stderr, "xmlAddAttributeDecl: Table creation failed!\n");
                    736:         return(NULL);
                    737:     }
                    738: 
                    739:     /*
                    740:      * Validity Check:
                    741:      * Search the DTD for previous declarations of the ATTLIST
                    742:      */
                    743:     for (i = 0;i < table->nb_attributes;i++) {
1.15      daniel    744:         cur = table->table[i];
1.4       daniel    745:        if ((!xmlStrcmp(cur->name, name)) && (!xmlStrcmp(cur->elem, elem))) {
                    746:            /*
                    747:             * The attribute is already defined in this Dtd.
                    748:             */
                    749:            fprintf(stderr,
                    750:                    "xmlAddAttributeDecl: %s already defined\n", name);
                    751:        }
                    752:     }
                    753: 
                    754:     /*
                    755:      * Grow the table, if needed.
                    756:      */
                    757:     if (table->nb_attributes >= table->max_attributes) {
                    758:         /*
                    759:         * need more attributes.
                    760:         */
                    761:        table->max_attributes *= 2;
1.15      daniel    762:        table->table = (xmlAttributePtr *) 
                    763:            realloc(table->table, table->max_attributes * 
                    764:                    sizeof(xmlAttributePtr));
1.13      daniel    765:        if (table->table == NULL) {
1.4       daniel    766:            fprintf(stderr, "xmlAddAttributeDecl: out of memory\n");
                    767:            return(NULL);
                    768:        }
                    769:     }
1.15      daniel    770:     ret = (xmlAttributePtr) malloc(sizeof(xmlAttribute));
                    771:     if (ret == NULL) {
                    772:        fprintf(stderr, "xmlAddAttributeDecl: out of memory\n");
                    773:        return(NULL);
                    774:     }
                    775:     table->table[table->nb_attributes] = ret;
1.4       daniel    776: 
                    777:     /*
                    778:      * fill the structure.
                    779:      */
                    780:     ret->type = type;
                    781:     ret->name = xmlStrdup(name);
                    782:     ret->elem = xmlStrdup(elem);
                    783:     ret->def = def;
                    784:     ret->tree = tree;
                    785:     if (defaultValue != NULL)
                    786:        ret->defaultValue = xmlStrdup(defaultValue);
                    787:     else
                    788:         ret->defaultValue = NULL;
1.15      daniel    789:     elemDef = xmlGetDtdElementDesc(dtd, elem);
                    790:     if (elemDef != NULL) {
1.16      daniel    791:         if ((type == XML_ATTRIBUTE_ID) &&
                    792:            (xmlScanIDAttributeDecl(NULL, elemDef) != 0))
                    793:            VERROR(ctxt->userData, 
                    794:           "Element %s has too may ID attributes defined : %s\n",
                    795:                   elem, name);
1.15      daniel    796:         ret->next = elemDef->attributes;
                    797:         elemDef->attributes = ret;
                    798:     }
1.4       daniel    799:     table->nb_attributes++;
                    800: 
                    801:     return(ret);
                    802: }
                    803: 
                    804: /**
                    805:  * xmlFreeAttribute:
                    806:  * @elem:  An attribute
                    807:  *
                    808:  * Deallocate the memory used by an attribute definition
                    809:  */
                    810: void
                    811: xmlFreeAttribute(xmlAttributePtr attr) {
                    812:     if (attr == NULL) return;
                    813:     if (attr->tree != NULL)
                    814:         xmlFreeEnumeration(attr->tree);
                    815:     if (attr->elem != NULL)
                    816:        free((CHAR *) attr->elem);
                    817:     if (attr->name != NULL)
                    818:        free((CHAR *) attr->name);
                    819:     if (attr->defaultValue != NULL)
                    820:        free((CHAR *) attr->defaultValue);
                    821:     memset(attr, -1, sizeof(xmlAttribute));
1.15      daniel    822:     free(attr);
1.4       daniel    823: }
                    824: 
                    825: /**
                    826:  * xmlFreeAttributeTable:
                    827:  * @table:  An attribute table
                    828:  *
                    829:  * Deallocate the memory used by an entities hash table.
                    830:  */
                    831: void
                    832: xmlFreeAttributeTable(xmlAttributeTablePtr table) {
                    833:     int i;
                    834: 
                    835:     if (table == NULL) return;
                    836: 
                    837:     for (i = 0;i < table->nb_attributes;i++) {
1.15      daniel    838:         xmlFreeAttribute(table->table[i]);
1.4       daniel    839:     }
                    840:     free(table->table);
                    841:     free(table);
                    842: }
                    843: 
                    844: /**
                    845:  * xmlCopyAttributeTable:
                    846:  * @table:  An attribute table
                    847:  *
                    848:  * Build a copy of an attribute table.
                    849:  * 
1.6       daniel    850:  * Returns the new xmlAttributeTablePtr or NULL in case of error.
1.4       daniel    851:  */
                    852: xmlAttributeTablePtr
                    853: xmlCopyAttributeTable(xmlAttributeTablePtr table) {
                    854:     xmlAttributeTablePtr ret;
                    855:     xmlAttributePtr cur, attr;
                    856:     int i;
                    857: 
                    858:     ret = (xmlAttributeTablePtr) malloc(sizeof(xmlAttributeTable));
                    859:     if (ret == NULL) {
                    860:         fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
                    861:        return(NULL);
                    862:     }
1.15      daniel    863:     ret->table = (xmlAttributePtr *) malloc(table->max_attributes *
                    864:                                           sizeof(xmlAttributePtr));
1.4       daniel    865:     if (ret->table == NULL) {
                    866:         fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
                    867:        free(ret);
                    868:        return(NULL);
                    869:     }
                    870:     ret->max_attributes = table->max_attributes;
                    871:     ret->nb_attributes = table->nb_attributes;
                    872:     for (i = 0;i < ret->nb_attributes;i++) {
1.15      daniel    873:        attr = table->table[i];
                    874:        cur = (xmlAttributePtr) malloc(sizeof(xmlAttribute));
                    875:        if (cur == NULL) {
                    876:            fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
                    877:            free(ret);
                    878:            free(ret->table);
                    879:            return(NULL);
                    880:        }
                    881:        ret->table[i] = cur;
1.4       daniel    882:        cur->type = attr->type;
                    883:        cur->def = attr->def;
                    884:        cur->tree = xmlCopyEnumeration(attr->tree);
                    885:        if (attr->elem != NULL)
                    886:            cur->elem = xmlStrdup(attr->elem);
                    887:        else
                    888:            cur->elem = NULL;
                    889:        if (attr->name != NULL)
                    890:            cur->name = xmlStrdup(attr->name);
                    891:        else
                    892:            cur->name = NULL;
                    893:        if (attr->defaultValue != NULL)
                    894:            cur->defaultValue = xmlStrdup(attr->defaultValue);
                    895:        else
                    896:            cur->defaultValue = NULL;
1.15      daniel    897:        /* NEED to rebuild the next chain !!!!!! */
1.4       daniel    898:     }
                    899:     return(ret);
                    900: }
                    901: 
                    902: /**
                    903:  * xmlDumpAttributeTable:
1.9       daniel    904:  * @buf:  the XML buffer output
1.4       daniel    905:  * @table:  An attribute table
                    906:  *
                    907:  * This will dump the content of the attribute table as an XML DTD definition
                    908:  */
                    909: void
1.8       daniel    910: xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
1.4       daniel    911:     int i;
                    912:     xmlAttributePtr cur;
                    913: 
                    914:     if (table == NULL) return;
                    915: 
                    916:     for (i = 0;i < table->nb_attributes;i++) {
1.15      daniel    917:         cur = table->table[i];
1.8       daniel    918:        xmlBufferWriteChar(buf, "<!ATTLIST ");
                    919:        xmlBufferWriteCHAR(buf, cur->elem);
                    920:        xmlBufferWriteChar(buf, " ");
                    921:        xmlBufferWriteCHAR(buf, cur->name);
1.4       daniel    922:         switch (cur->type) {
                    923:             case XML_ATTRIBUTE_CDATA:
1.8       daniel    924:                xmlBufferWriteChar(buf, " CDATA");
1.4       daniel    925:                 break;
                    926:             case XML_ATTRIBUTE_ID:
1.8       daniel    927:                xmlBufferWriteChar(buf, " ID");
1.4       daniel    928:                 break;
                    929:             case XML_ATTRIBUTE_IDREF:
1.8       daniel    930:                xmlBufferWriteChar(buf, " IDREF");
1.4       daniel    931:                 break;
                    932:             case XML_ATTRIBUTE_IDREFS:
1.8       daniel    933:                xmlBufferWriteChar(buf, " IDREFS");
1.4       daniel    934:                 break;
                    935:             case XML_ATTRIBUTE_ENTITY:
1.8       daniel    936:                xmlBufferWriteChar(buf, " ENTITY");
1.4       daniel    937:                 break;
                    938:             case XML_ATTRIBUTE_ENTITIES:
1.8       daniel    939:                xmlBufferWriteChar(buf, " ENTITIES");
1.4       daniel    940:                 break;
                    941:             case XML_ATTRIBUTE_NMTOKEN:
1.8       daniel    942:                xmlBufferWriteChar(buf, " NMTOKEN");
1.4       daniel    943:                 break;
                    944:             case XML_ATTRIBUTE_NMTOKENS:
1.8       daniel    945:                xmlBufferWriteChar(buf, " NMTOKENS");
1.4       daniel    946:                 break;
                    947:             case XML_ATTRIBUTE_ENUMERATION:
1.18    ! daniel    948:                 xmlBufferWriteChar(buf, " (");
        !           949:                xmlDumpEnumeration(buf, cur->tree);
1.4       daniel    950:                 break;
                    951:             case XML_ATTRIBUTE_NOTATION:
1.18    ! daniel    952:                 xmlBufferWriteChar(buf, " NOTATION (");
        !           953:                xmlDumpEnumeration(buf, cur->tree);
1.4       daniel    954:                 break;
                    955:            default:
                    956:                fprintf(stderr,
                    957:                    "xmlDumpAttributeTable: internal: unknown type %d\n",
                    958:                        cur->type);
                    959:        }
                    960:         switch (cur->def) {
                    961:             case XML_ATTRIBUTE_NONE:
                    962:                 break;
                    963:             case XML_ATTRIBUTE_REQUIRED:
1.8       daniel    964:                xmlBufferWriteChar(buf, " #REQUIRED");
1.4       daniel    965:                 break;
                    966:             case XML_ATTRIBUTE_IMPLIED:
1.8       daniel    967:                xmlBufferWriteChar(buf, " #IMPLIED");
1.4       daniel    968:                 break;
                    969:             case XML_ATTRIBUTE_FIXED:
1.17      daniel    970:                xmlBufferWriteChar(buf, " #FIXED");
1.4       daniel    971:                 break;
                    972:            default:
                    973:                fprintf(stderr,
                    974:                    "xmlDumpAttributeTable: internal: unknown default %d\n",
                    975:                        cur->def);
                    976:         }
1.17      daniel    977:        if (cur->defaultValue != NULL) {
                    978:            xmlBufferWriteChar(buf, " ");
                    979:            xmlBufferWriteQuotedString(buf, cur->defaultValue);
                    980:        }
1.8       daniel    981:         xmlBufferWriteChar(buf, ">\n");
1.5       daniel    982:     }
                    983: }
                    984: 
                    985: /************************************************************************
                    986:  *                                                                     *
                    987:  *                             NOTATIONs                               *
                    988:  *                                                                     *
                    989:  ************************************************************************/
                    990: /**
                    991:  * xmlCreateNotationTable:
                    992:  *
                    993:  * create and initialize an empty notation hash table.
                    994:  *
1.6       daniel    995:  * Returns the xmlNotationTablePtr just created or NULL in case
1.5       daniel    996:  *                of error.
                    997:  */
                    998: xmlNotationTablePtr
                    999: xmlCreateNotationTable(void) {
                   1000:     xmlNotationTablePtr ret;
                   1001: 
                   1002:     ret = (xmlNotationTablePtr) 
                   1003:          malloc(sizeof(xmlNotationTable));
                   1004:     if (ret == NULL) {
1.12      daniel   1005:         fprintf(stderr, "xmlCreateNotationTable : malloc(%ld) failed\n",
                   1006:                (long)sizeof(xmlNotationTable));
1.5       daniel   1007:         return(NULL);
                   1008:     }
                   1009:     ret->max_notations = XML_MIN_NOTATION_TABLE;
                   1010:     ret->nb_notations = 0;
1.15      daniel   1011:     ret->table = (xmlNotationPtr *) 
                   1012:          malloc(ret->max_notations * sizeof(xmlNotationPtr));
1.5       daniel   1013:     if (ret == NULL) {
1.12      daniel   1014:         fprintf(stderr, "xmlCreateNotationTable : malloc(%ld) failed\n",
                   1015:                ret->max_notations * (long)sizeof(xmlNotation));
1.5       daniel   1016:        free(ret);
                   1017:         return(NULL);
                   1018:     }
                   1019:     return(ret);
                   1020: }
                   1021: 
                   1022: 
                   1023: /**
                   1024:  * xmlAddNotationDecl:
1.6       daniel   1025:  * @dtd:  pointer to the DTD
1.16      daniel   1026:  * @ctxt:  the validation context
1.5       daniel   1027:  * @name:  the entity name
1.6       daniel   1028:  * @PublicID:  the public identifier or NULL
                   1029:  * @SystemID:  the system identifier or NULL
1.5       daniel   1030:  *
                   1031:  * Register a new notation declaration
                   1032:  *
1.6       daniel   1033:  * Returns NULL if not, othervise the entity
1.5       daniel   1034:  */
                   1035: xmlNotationPtr
1.16      daniel   1036: xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const CHAR *name,
                   1037:                    const CHAR *PublicID, const CHAR *SystemID) {
1.5       daniel   1038:     xmlNotationPtr ret, cur;
                   1039:     xmlNotationTablePtr table;
                   1040:     int i;
                   1041: 
                   1042:     if (dtd == NULL) {
                   1043:         fprintf(stderr, "xmlAddNotationDecl: dtd == NULL\n");
                   1044:        return(NULL);
                   1045:     }
                   1046:     if (name == NULL) {
                   1047:         fprintf(stderr, "xmlAddNotationDecl: name == NULL\n");
                   1048:        return(NULL);
                   1049:     }
                   1050:     if ((PublicID == NULL) && (SystemID == NULL)) {
                   1051:         fprintf(stderr, "xmlAddNotationDecl: no PUBLIC ID nor SYSTEM ID\n");
                   1052:     }
                   1053: 
                   1054:     /*
                   1055:      * Create the Notation table if needed.
                   1056:      */
                   1057:     table = dtd->notations;
                   1058:     if (table == NULL) 
                   1059:         table = dtd->notations = xmlCreateNotationTable();
                   1060:     if (table == NULL) {
                   1061:        fprintf(stderr, "xmlAddNotationDecl: Table creation failed!\n");
                   1062:         return(NULL);
                   1063:     }
                   1064: 
                   1065:     /*
                   1066:      * Validity Check:
                   1067:      * Search the DTD for previous declarations of the ATTLIST
                   1068:      */
                   1069:     for (i = 0;i < table->nb_notations;i++) {
1.15      daniel   1070:         cur = table->table[i];
1.5       daniel   1071:        if (!xmlStrcmp(cur->name, name)) {
                   1072:            /*
                   1073:             * The notation is already defined in this Dtd.
                   1074:             */
                   1075:            fprintf(stderr,
                   1076:                    "xmlAddNotationDecl: %s already defined\n", name);
                   1077:        }
                   1078:     }
                   1079: 
                   1080:     /*
                   1081:      * Grow the table, if needed.
                   1082:      */
                   1083:     if (table->nb_notations >= table->max_notations) {
                   1084:         /*
                   1085:         * need more notations.
                   1086:         */
                   1087:        table->max_notations *= 2;
1.15      daniel   1088:        table->table = (xmlNotationPtr *) 
                   1089:            realloc(table->table, table->max_notations *
                   1090:                    sizeof(xmlNotationPtr));
1.13      daniel   1091:        if (table->table == NULL) {
1.5       daniel   1092:            fprintf(stderr, "xmlAddNotationDecl: out of memory\n");
                   1093:            return(NULL);
                   1094:        }
                   1095:     }
1.15      daniel   1096:     ret = (xmlNotationPtr) malloc(sizeof(xmlNotation));
                   1097:     if (ret == NULL) {
                   1098:        fprintf(stderr, "xmlAddNotationDecl: out of memory\n");
                   1099:        return(NULL);
                   1100:     }
                   1101:     table->table[table->nb_notations] = ret;
1.5       daniel   1102: 
                   1103:     /*
                   1104:      * fill the structure.
                   1105:      */
                   1106:     ret->name = xmlStrdup(name);
                   1107:     if (SystemID != NULL)
                   1108:         ret->SystemID = xmlStrdup(SystemID);
                   1109:     else
                   1110:         ret->SystemID = NULL;
                   1111:     if (PublicID != NULL)
                   1112:         ret->PublicID = xmlStrdup(PublicID);
                   1113:     else
                   1114:         ret->PublicID = NULL;
                   1115:     table->nb_notations++;
                   1116: 
                   1117:     return(ret);
                   1118: }
                   1119: 
                   1120: /**
                   1121:  * xmlFreeNotation:
                   1122:  * @not:  A notation
                   1123:  *
                   1124:  * Deallocate the memory used by an notation definition
                   1125:  */
                   1126: void
                   1127: xmlFreeNotation(xmlNotationPtr nota) {
                   1128:     if (nota == NULL) return;
                   1129:     if (nota->name != NULL)
                   1130:        free((CHAR *) nota->name);
                   1131:     if (nota->PublicID != NULL)
                   1132:        free((CHAR *) nota->PublicID);
                   1133:     if (nota->SystemID != NULL)
                   1134:        free((CHAR *) nota->SystemID);
                   1135:     memset(nota, -1, sizeof(xmlNotation));
1.15      daniel   1136:     free(nota);
1.5       daniel   1137: }
                   1138: 
                   1139: /**
                   1140:  * xmlFreeNotationTable:
                   1141:  * @table:  An notation table
                   1142:  *
                   1143:  * Deallocate the memory used by an entities hash table.
                   1144:  */
                   1145: void
                   1146: xmlFreeNotationTable(xmlNotationTablePtr table) {
                   1147:     int i;
                   1148: 
                   1149:     if (table == NULL) return;
                   1150: 
                   1151:     for (i = 0;i < table->nb_notations;i++) {
1.15      daniel   1152:         xmlFreeNotation(table->table[i]);
1.5       daniel   1153:     }
                   1154:     free(table->table);
                   1155:     free(table);
                   1156: }
                   1157: 
                   1158: /**
                   1159:  * xmlCopyNotationTable:
                   1160:  * @table:  A notation table
                   1161:  *
                   1162:  * Build a copy of a notation table.
                   1163:  * 
1.6       daniel   1164:  * Returns the new xmlNotationTablePtr or NULL in case of error.
1.5       daniel   1165:  */
                   1166: xmlNotationTablePtr
                   1167: xmlCopyNotationTable(xmlNotationTablePtr table) {
                   1168:     xmlNotationTablePtr ret;
                   1169:     xmlNotationPtr cur, nota;
                   1170:     int i;
                   1171: 
                   1172:     ret = (xmlNotationTablePtr) malloc(sizeof(xmlNotationTable));
                   1173:     if (ret == NULL) {
                   1174:         fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
                   1175:        return(NULL);
                   1176:     }
1.15      daniel   1177:     ret->table = (xmlNotationPtr *) malloc(table->max_notations *
                   1178:                                          sizeof(xmlNotationPtr));
1.5       daniel   1179:     if (ret->table == NULL) {
                   1180:         fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
                   1181:        free(ret);
                   1182:        return(NULL);
                   1183:     }
                   1184:     ret->max_notations = table->max_notations;
                   1185:     ret->nb_notations = table->nb_notations;
                   1186:     for (i = 0;i < ret->nb_notations;i++) {
1.15      daniel   1187:        cur = (xmlNotationPtr) malloc(sizeof(xmlNotation));
                   1188:        if (cur == NULL) {
                   1189:            fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
                   1190:            free(ret);
                   1191:            free(ret->table);
                   1192:            return(NULL);
                   1193:        }
                   1194:        ret->table[i] = cur;
                   1195:        nota = table->table[i];
1.5       daniel   1196:        if (nota->name != NULL)
                   1197:            cur->name = xmlStrdup(nota->name);
                   1198:        else
                   1199:            cur->name = NULL;
                   1200:        if (nota->PublicID != NULL)
                   1201:            cur->PublicID = xmlStrdup(nota->PublicID);
                   1202:        else
                   1203:            cur->PublicID = NULL;
                   1204:        if (nota->SystemID != NULL)
                   1205:            cur->SystemID = xmlStrdup(nota->SystemID);
                   1206:        else
                   1207:            cur->SystemID = NULL;
                   1208:     }
                   1209:     return(ret);
                   1210: }
                   1211: 
                   1212: /**
                   1213:  * xmlDumpNotationTable:
1.9       daniel   1214:  * @buf:  the XML buffer output
1.5       daniel   1215:  * @table:  A notation table
                   1216:  *
                   1217:  * This will dump the content of the notation table as an XML DTD definition
                   1218:  */
                   1219: void
1.8       daniel   1220: xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
1.5       daniel   1221:     int i;
                   1222:     xmlNotationPtr cur;
                   1223: 
                   1224:     if (table == NULL) return;
                   1225: 
                   1226:     for (i = 0;i < table->nb_notations;i++) {
1.15      daniel   1227:         cur = table->table[i];
1.8       daniel   1228:        xmlBufferWriteChar(buf, "<!NOTATION ");
                   1229:        xmlBufferWriteCHAR(buf, cur->name);
1.5       daniel   1230:        if (cur->PublicID != NULL) {
1.10      daniel   1231:            xmlBufferWriteChar(buf, " PUBLIC ");
                   1232:            xmlBufferWriteQuotedString(buf, cur->PublicID);
1.5       daniel   1233:            if (cur->SystemID != NULL) {
1.8       daniel   1234:                xmlBufferWriteChar(buf, " ");
                   1235:                xmlBufferWriteCHAR(buf, cur->SystemID);
1.5       daniel   1236:            }
                   1237:        } else {
1.8       daniel   1238:            xmlBufferWriteChar(buf, " SYSTEM ");
                   1239:            xmlBufferWriteCHAR(buf, cur->SystemID);
1.5       daniel   1240:        }
1.8       daniel   1241:         xmlBufferWriteChar(buf, " >\n");
1.2       daniel   1242:     }
                   1243: }
1.14      daniel   1244: 
                   1245: /************************************************************************
                   1246:  *                                                                     *
                   1247:  *             Routines for validity checking                          *
                   1248:  *                                                                     *
                   1249:  ************************************************************************/
                   1250: 
                   1251: /**
                   1252:  * xmlGetDtdElementDesc:
                   1253:  * @dtd:  a pointer to the DtD to search
                   1254:  * @name:  the element name
                   1255:  *
                   1256:  * Search the Dtd for the description of this element
                   1257:  *
                   1258:  * returns the xmlElementPtr if found or NULL
                   1259:  */
                   1260: 
                   1261: xmlElementPtr
                   1262: xmlGetDtdElementDesc(xmlDtdPtr dtd, const CHAR *name) {
                   1263:     xmlElementTablePtr table;
                   1264:     xmlElementPtr cur;
                   1265:     int i;
                   1266: 
                   1267:     if (dtd == NULL) return(NULL);
                   1268:     if (dtd->elements == NULL) return(NULL);
                   1269:     table = dtd->elements;
                   1270: 
                   1271:     for (i = 0;i < table->nb_elements;i++) {
1.15      daniel   1272:         cur = table->table[i];
1.14      daniel   1273:        if (!xmlStrcmp(cur->name, name))
                   1274:            return(cur);
                   1275:     }
                   1276:     return(NULL);
                   1277: }
                   1278: 
                   1279: /**
                   1280:  * xmlGetDtdAttrDesc:
                   1281:  * @dtd:  a pointer to the DtD to search
1.15      daniel   1282:  * @elem:  the element name
1.14      daniel   1283:  * @name:  the attribute name
                   1284:  *
1.15      daniel   1285:  * Search the Dtd for the description of this attribute on
                   1286:  * this element.
1.14      daniel   1287:  *
                   1288:  * returns the xmlAttributePtr if found or NULL
                   1289:  */
                   1290: 
                   1291: xmlAttributePtr
1.15      daniel   1292: xmlGetDtdAttrDesc(xmlDtdPtr dtd, const CHAR *elem, const CHAR *name) {
1.14      daniel   1293:     xmlAttributeTablePtr table;
                   1294:     xmlAttributePtr cur;
                   1295:     int i;
                   1296: 
                   1297:     if (dtd == NULL) return(NULL);
                   1298:     if (dtd->attributes == NULL) return(NULL);
                   1299:     table = dtd->attributes;
                   1300: 
                   1301:     for (i = 0;i < table->nb_attributes;i++) {
1.15      daniel   1302:         cur = table->table[i];
                   1303:        if ((!xmlStrcmp(cur->name, name)) &&
                   1304:            (!xmlStrcmp(cur->elem, elem)))
1.14      daniel   1305:            return(cur);
                   1306:     }
                   1307:     return(NULL);
                   1308: }
                   1309: 
                   1310: /**
                   1311:  * xmlGetDtdNotationDesc:
                   1312:  * @dtd:  a pointer to the DtD to search
                   1313:  * @name:  the notation name
                   1314:  *
                   1315:  * Search the Dtd for the description of this notation
                   1316:  *
                   1317:  * returns the xmlNotationPtr if found or NULL
                   1318:  */
                   1319: 
                   1320: xmlNotationPtr
                   1321: xmlGetDtdNotationDesc(xmlDtdPtr dtd, const CHAR *name) {
                   1322:     xmlNotationTablePtr table;
                   1323:     xmlNotationPtr cur;
                   1324:     int i;
                   1325: 
                   1326:     if (dtd == NULL) return(NULL);
                   1327:     if (dtd->notations == NULL) return(NULL);
                   1328:     table = dtd->notations;
                   1329: 
                   1330:     for (i = 0;i < table->nb_notations;i++) {
1.15      daniel   1331:         cur = table->table[i];
1.14      daniel   1332:        if (!xmlStrcmp(cur->name, name))
                   1333:            return(cur);
                   1334:     }
                   1335:     return(NULL);
                   1336: }
                   1337: 
                   1338: /**
1.18    ! daniel   1339:  * xmlIsMixedElement
        !          1340:  * @doc:  the document
        !          1341:  * @name:  the element name
        !          1342:  *
        !          1343:  * Search in the DtDs whether an element accept Mixed content (or ANY)
        !          1344:  * basically if it is supposed to accept text childs
        !          1345:  *
        !          1346:  * returns 0 if no, 1 if yes, and -1 if no element description is available
        !          1347:  */
        !          1348: 
        !          1349: int
        !          1350: xmlIsMixedElement(xmlDocPtr doc, const CHAR *name) {
        !          1351:     xmlElementPtr elemDecl;
        !          1352: 
        !          1353:     if ((doc == NULL) || (doc->intSubset == NULL)) return(-1);
        !          1354: 
        !          1355:     elemDecl = xmlGetDtdElementDesc(doc->intSubset, name);
        !          1356:     if ((elemDecl == NULL) && (doc->extSubset != NULL))
        !          1357:        elemDecl = xmlGetDtdElementDesc(doc->extSubset, name);
        !          1358:     if (elemDecl == NULL) return(-1);
        !          1359:     switch (elemDecl->type) {
        !          1360:        case XML_ELEMENT_TYPE_ELEMENT:
        !          1361:            return(0);
        !          1362:         case XML_ELEMENT_TYPE_EMPTY:
        !          1363:            /*
        !          1364:             * return 1 for EMPTY since we want VC error to pop up
        !          1365:             * on <empty>     </empty> for example
        !          1366:             */
        !          1367:        case XML_ELEMENT_TYPE_ANY:
        !          1368:        case XML_ELEMENT_TYPE_MIXED:
        !          1369:            return(1);
        !          1370:     }
        !          1371:     return(1);
        !          1372: }
        !          1373: 
        !          1374: /**
1.16      daniel   1375:  * xmlValidateNameValue:
                   1376:  * @value:  an Name value
                   1377:  *
                   1378:  * Validate that the given value match Name production
                   1379:  *
                   1380:  * returns 1 if valid or 0 otherwise
                   1381:  */
                   1382: 
                   1383: int
                   1384: xmlValidateNameValue(const CHAR *value) {
                   1385:     const CHAR *cur;
                   1386: 
                   1387:     if (value == NULL) return(0);
                   1388:     cur = value;
                   1389:     
                   1390:     if (!IS_LETTER(*cur) && (*cur != '_') &&
                   1391:         (*cur != ':')) {
                   1392:        return(0);
                   1393:     }
                   1394: 
                   1395:     while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
                   1396:            (*cur == '.') || (*cur == '-') ||
                   1397:           (*cur == '_') || (*cur == ':') || 
                   1398:           (IS_COMBINING(*cur)) ||
                   1399:           (IS_EXTENDER(*cur)))
                   1400:           cur++;
                   1401: 
                   1402:     if (*cur != 0) return(0);
                   1403: 
                   1404:     return(1);
                   1405: }
                   1406: 
                   1407: /**
                   1408:  * xmlValidateNamesValue:
                   1409:  * @value:  an Names value
                   1410:  *
                   1411:  * Validate that the given value match Names production
                   1412:  *
                   1413:  * returns 1 if valid or 0 otherwise
                   1414:  */
                   1415: 
                   1416: int
                   1417: xmlValidateNamesValue(const CHAR *value) {
                   1418:     const CHAR *cur;
                   1419: 
                   1420:     if (value == NULL) return(0);
                   1421:     cur = value;
                   1422:     
                   1423:     if (!IS_LETTER(*cur) && (*cur != '_') &&
                   1424:         (*cur != ':')) {
                   1425:        return(0);
                   1426:     }
                   1427: 
                   1428:     while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
                   1429:            (*cur == '.') || (*cur == '-') ||
                   1430:           (*cur == '_') || (*cur == ':') || 
                   1431:           (IS_COMBINING(*cur)) ||
                   1432:           (IS_EXTENDER(*cur)))
                   1433:           cur++;
                   1434: 
                   1435:     while (IS_BLANK(*cur)) {
                   1436:        while (IS_BLANK(*cur)) cur++;
                   1437: 
                   1438:        if (!IS_LETTER(*cur) && (*cur != '_') &&
                   1439:            (*cur != ':')) {
                   1440:            return(0);
                   1441:        }
                   1442: 
                   1443:        while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
                   1444:               (*cur == '.') || (*cur == '-') ||
                   1445:               (*cur == '_') || (*cur == ':') || 
                   1446:               (IS_COMBINING(*cur)) ||
                   1447:               (IS_EXTENDER(*cur)))
                   1448:               cur++;
                   1449:     }
                   1450: 
                   1451:     if (*cur != 0) return(0);
                   1452: 
                   1453:     return(1);
                   1454: }
                   1455: 
                   1456: /**
                   1457:  * xmlValidateNmtokenValue:
                   1458:  * @value:  an Mntoken value
                   1459:  *
                   1460:  * Validate that the given value match Nmtoken production
                   1461:  *
                   1462:  * [ VC: Name Token ]
                   1463:  * 
                   1464:  * returns 1 if valid or 0 otherwise
                   1465:  */
                   1466: 
                   1467: int
                   1468: xmlValidateNmtokenValue(const CHAR *value) {
                   1469:     const CHAR *cur;
                   1470: 
                   1471:     if (value == NULL) return(0);
                   1472:     cur = value;
                   1473:     
                   1474:     if (!IS_LETTER(*cur) && !IS_DIGIT(*cur) &&
                   1475:         (*cur != '.') && (*cur != '-') &&
                   1476:         (*cur != '_') && (*cur != ':') && 
                   1477:         (!IS_COMBINING(*cur)) &&
                   1478:         (!IS_EXTENDER(*cur)))
                   1479:        return(0);
                   1480: 
                   1481:     while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
                   1482:            (*cur == '.') || (*cur == '-') ||
                   1483:           (*cur == '_') || (*cur == ':') || 
                   1484:           (IS_COMBINING(*cur)) ||
                   1485:           (IS_EXTENDER(*cur)))
                   1486:           cur++;
                   1487: 
                   1488:     if (*cur != 0) return(0);
                   1489: 
                   1490:     return(1);
                   1491:     return(1);
                   1492: }
                   1493: 
                   1494: /**
                   1495:  * xmlValidateNmtokensValue:
                   1496:  * @value:  an Mntokens value
                   1497:  *
                   1498:  * Validate that the given value match Nmtokens production
                   1499:  *
                   1500:  * [ VC: Name Token ]
                   1501:  * 
                   1502:  * returns 1 if valid or 0 otherwise
                   1503:  */
                   1504: 
                   1505: int
                   1506: xmlValidateNmtokensValue(const CHAR *value) {
                   1507:     const CHAR *cur;
                   1508: 
                   1509:     if (value == NULL) return(0);
                   1510:     cur = value;
                   1511:     
                   1512:     if (!IS_LETTER(*cur) && !IS_DIGIT(*cur) &&
                   1513:         (*cur != '.') && (*cur != '-') &&
                   1514:         (*cur != '_') && (*cur != ':') && 
                   1515:         (!IS_COMBINING(*cur)) &&
                   1516:         (!IS_EXTENDER(*cur)))
                   1517:        return(0);
                   1518: 
                   1519:     while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
                   1520:            (*cur == '.') || (*cur == '-') ||
                   1521:           (*cur == '_') || (*cur == ':') || 
                   1522:           (IS_COMBINING(*cur)) ||
                   1523:           (IS_EXTENDER(*cur)))
                   1524:           cur++;
                   1525: 
                   1526:     while (IS_BLANK(*cur)) {
                   1527:        while (IS_BLANK(*cur)) cur++;
                   1528: 
                   1529:        if (!IS_LETTER(*cur) && !IS_DIGIT(*cur) &&
                   1530:            (*cur != '.') && (*cur != '-') &&
                   1531:            (*cur != '_') && (*cur != ':') && 
                   1532:            (!IS_COMBINING(*cur)) &&
                   1533:            (!IS_EXTENDER(*cur)))
                   1534:            return(0);
                   1535: 
                   1536:        while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
                   1537:               (*cur == '.') || (*cur == '-') ||
                   1538:               (*cur == '_') || (*cur == ':') || 
                   1539:               (IS_COMBINING(*cur)) ||
                   1540:               (IS_EXTENDER(*cur)))
                   1541:               cur++;
                   1542:     }
                   1543: 
                   1544:     if (*cur != 0) return(0);
                   1545: 
                   1546:     return(1);
                   1547: }
                   1548: 
                   1549: /**
                   1550:  * xmlValidateNotationDecl:
                   1551:  * @doc:  a document instance
                   1552:  * @nota:  a notation definition
                   1553:  *
                   1554:  * Try to validate a single notation definition
                   1555:  * basically it does the following checks as described by the
                   1556:  * XML-1.0 recommendation:
1.18    ! daniel   1557:  *  - it seems that no validity constraing exist on notation declarations
        !          1558:  * But this function get called anyway ...
1.16      daniel   1559:  *
                   1560:  * returns 1 if valid or 0 otherwise
                   1561:  */
                   1562: 
                   1563: int
                   1564: xmlValidateNotationDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                   1565:                          xmlNotationPtr nota) {
                   1566:     int ret = 1;
                   1567: 
                   1568:     return(ret);
                   1569: }
                   1570: 
                   1571: /**
                   1572:  * xmlValidateAttributeValue:
                   1573:  * @type:  an attribute type
                   1574:  * @value:  an attribute value
                   1575:  *
                   1576:  * Validate that the given attribute value match  the proper production
                   1577:  *
                   1578:  * [ VC: ID ]
                   1579:  * Values of type ID must match the Name production....
                   1580:  *
                   1581:  * [ VC: IDREF ]
                   1582:  * Values of type IDREF must match the Name production, and values
                   1583:  * of type IDREFS must match Names ...
                   1584:  *
                   1585:  * [ VC: Entity Name ]
                   1586:  * Values of type ENTITY must match the Name production, values
                   1587:  * of type ENTITIES must match Names ...
                   1588:  *
                   1589:  * [ VC: Name Token ]
                   1590:  * Values of type NMTOKEN must match the Nmtoken production; values
                   1591:  * of type NMTOKENS must match Nmtokens. 
                   1592:  *
                   1593:  * returns 1 if valid or 0 otherwise
                   1594:  */
                   1595: 
                   1596: int
                   1597: xmlValidateAttributeValue(xmlAttributeType type, const CHAR *value) {
                   1598:     switch (type) {
                   1599:        case XML_ATTRIBUTE_IDREFS:
                   1600:        case XML_ATTRIBUTE_ENTITIES:
                   1601:            return(xmlValidateNamesValue(value));
                   1602:        case XML_ATTRIBUTE_IDREF:
                   1603:        case XML_ATTRIBUTE_ID:
                   1604:        case XML_ATTRIBUTE_ENTITY:
                   1605:        case XML_ATTRIBUTE_NOTATION:
                   1606:            return(xmlValidateNameValue(value));
                   1607:        case XML_ATTRIBUTE_NMTOKENS:
                   1608:        case XML_ATTRIBUTE_ENUMERATION:
                   1609:            return(xmlValidateNmtokensValue(value));
                   1610:        case XML_ATTRIBUTE_NMTOKEN:
                   1611:            return(xmlValidateNmtokenValue(value));
                   1612:         case XML_ATTRIBUTE_CDATA:
                   1613:            break;
                   1614:     }
                   1615:     return(1);
                   1616: }
                   1617: 
                   1618: /**
1.14      daniel   1619:  * xmlValidateAttributeDecl:
                   1620:  * @doc:  a document instance
                   1621:  * @attr:  an attribute definition
                   1622:  *
                   1623:  * Try to validate a single attribute definition
                   1624:  * basically it does the following checks as described by the
                   1625:  * XML-1.0 recommendation:
                   1626:  *  - [ VC: Attribute Default Legal ]
                   1627:  *  - [ VC: Enumeration ]
                   1628:  *  - [ VC: ID Attribute Default ]
                   1629:  *
                   1630:  * The ID/IDREF uniqueness and matching are done separately
                   1631:  *
                   1632:  * returns 1 if valid or 0 otherwise
                   1633:  */
                   1634: 
                   1635: int
                   1636: xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                   1637:                          xmlAttributePtr attr) {
1.16      daniel   1638:     int ret = 1;
                   1639:     int val;
1.14      daniel   1640:     CHECK_DTD;
1.16      daniel   1641:     if(attr == NULL) return(1);
                   1642:     
                   1643:     /* Attribute Default Legal */
                   1644:     /* Enumeration */
                   1645:     if (attr->defaultValue != NULL) {
                   1646:        val = xmlValidateAttributeValue(attr->type, attr->defaultValue);
                   1647:        if (val == 0) {
                   1648:            VERROR(ctxt->userData, 
                   1649:               "Syntax of default value for attribute %s on %s is not valid\n",
                   1650:                   attr->name, attr->elem);
                   1651:        }
                   1652:         ret &= val;
                   1653:     }
                   1654: 
                   1655:     /* ID Attribute Default */
                   1656:     if ((attr->type == XML_ATTRIBUTE_ID)&&
                   1657:         (attr->def != XML_ATTRIBUTE_IMPLIED) &&
                   1658:        (attr->def != XML_ATTRIBUTE_REQUIRED)) {
                   1659:        VERROR(ctxt->userData, 
                   1660:           "ID attribute %s on %s is not valid must be #IMPLIED or #REQUIRED\n",
                   1661:               attr->name, attr->elem);
                   1662:        ret = 0;
                   1663:     }
                   1664: 
                   1665:     /* max ID per element */
                   1666:     if ((attr->type == XML_ATTRIBUTE_ID) && (doc->extSubset != NULL)) {
                   1667:         int nbId = 0;
                   1668: 
                   1669:        /* the trick is taht we parse DtD as their own internal subset */
                   1670:         xmlElementPtr elem = xmlGetDtdElementDesc(doc->extSubset,
                   1671:                                                  attr->elem);
                   1672:        if (elem != NULL) {
                   1673:            nbId = xmlScanIDAttributeDecl(NULL, elem);
                   1674:        }
                   1675:        if (nbId >= 1)
                   1676:            VERROR(ctxt->userData, 
                   1677:           "Element %s has ID attribute defined in the external subset : %s\n",
                   1678:                   attr->elem, attr->name);
                   1679:     }
1.14      daniel   1680: 
1.16      daniel   1681:     return(ret);
1.14      daniel   1682: }
                   1683: 
                   1684: /**
                   1685:  * xmlValidateElementDecl:
                   1686:  * @ctxt:  the validation context
                   1687:  * @doc:  a document instance
                   1688:  * @elem:  an element definition
                   1689:  *
                   1690:  * Try to validate a single element definition
                   1691:  * basically it does the following checks as described by the
                   1692:  * XML-1.0 recommendation:
                   1693:  *  - [ VC: One ID per Element Type ]
                   1694:  *  - [ VC: No Duplicate Types ]
                   1695:  *  - [ VC: Unique Element Type Declaration ]
                   1696:  *
                   1697:  * returns 1 if valid or 0 otherwise
                   1698:  */
                   1699: 
                   1700: int
1.16      daniel   1701: xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                   1702:                        xmlElementPtr elem) {
                   1703:     int ret = 1;
                   1704:     xmlElementPtr tst;
                   1705: 
1.14      daniel   1706:     CHECK_DTD;
1.16      daniel   1707:     
                   1708:     if (elem == NULL) return(1);
1.14      daniel   1709: 
1.16      daniel   1710:     /* No Duplicate Types */
                   1711:     if (elem->type == XML_ELEMENT_TYPE_MIXED) {
                   1712:        xmlElementContentPtr cur, next;
                   1713:         const CHAR *name;
                   1714: 
                   1715:        cur = elem->content;
                   1716:        while (cur != NULL) {
                   1717:            if (cur->type != XML_ELEMENT_CONTENT_OR) break;
                   1718:            if (cur->c1 == NULL) break;
                   1719:            if (cur->c1->type == XML_ELEMENT_CONTENT_ELEMENT) {
                   1720:                name = cur->c1->name;
                   1721:                next = cur->c2;
                   1722:                while (next != NULL) {
                   1723:                    if (next->type == XML_ELEMENT_CONTENT_ELEMENT) {
                   1724:                        if (!xmlStrcmp(next->name, name)) {
                   1725:                            VERROR(ctxt->userData, 
                   1726:                   "Definition of %s has duplicate references of %s\n",
                   1727:                                   elem->name, name);
                   1728:                            ret = 0;
                   1729:                        }
                   1730:                        break;
                   1731:                    }
                   1732:                    if (next->c1 == NULL) break;
                   1733:                    if (next->c1->type != XML_ELEMENT_CONTENT_ELEMENT) break;
                   1734:                    if (!xmlStrcmp(next->c1->name, name)) {
                   1735:                        VERROR(ctxt->userData, 
                   1736:               "Definition of %s has duplicate references of %s\n",
                   1737:                               elem->name, name);
                   1738:                        ret = 0;
                   1739:                    }
                   1740:                    next = next->c2;
                   1741:                }
                   1742:            }
                   1743:            cur = cur->c2;
                   1744:        }
                   1745:     }
                   1746: 
                   1747:     /* VC: Unique Element Type Declaration */
                   1748:     tst = xmlGetDtdElementDesc(doc->intSubset, elem->name);
                   1749:     if ((tst != NULL ) && (tst != elem)) {
                   1750:        VERROR(ctxt->userData, "Redefinition of element %s\n",
                   1751:               elem->name);
                   1752:        ret = 0;
                   1753:     }
                   1754:     tst = xmlGetDtdElementDesc(doc->extSubset, elem->name);
                   1755:     if ((tst != NULL ) && (tst != elem)) {
                   1756:        VERROR(ctxt->userData, "Redefinition of element %s\n",
                   1757:               elem->name);
                   1758:        ret = 0;
                   1759:     }
                   1760: 
                   1761:     /* One ID per Element Type */
                   1762:     if (xmlScanIDAttributeDecl(ctxt, elem) > 1) {
                   1763:        ret = 0;
                   1764:     }
                   1765:     return(ret);
1.14      daniel   1766: }
                   1767: 
                   1768: /**
                   1769:  * xmlValidateOneAttribute:
                   1770:  * @ctxt:  the validation context
                   1771:  * @doc:  a document instance
                   1772:  * @elem:  an element instance
                   1773:  * @attr:  an attribute instance
                   1774:  *
                   1775:  * Try to validate a single attribute for an element
                   1776:  * basically it * does the following checks as described by the
                   1777:  * XML-1.0 recommendation:
1.18    ! daniel   1778:  *  - [ VC: Attribute Value Type ]
        !          1779:  *  - [ VC: Fixed Attribute Default ]
1.14      daniel   1780:  *  - [ VC: Entity Name ]
                   1781:  *  - [ VC: Name Token ]
                   1782:  *  - [ VC: ID ]
                   1783:  *  - [ VC: IDREF ]
                   1784:  *  - [ VC: Entity Name ]
1.16      daniel   1785:  *  - [ VC: Notation Attributes ]
1.14      daniel   1786:  *
                   1787:  * The ID/IDREF uniqueness and matching are done separately
                   1788:  *
                   1789:  * returns 1 if valid or 0 otherwise
                   1790:  */
                   1791: 
                   1792: int
1.16      daniel   1793: xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
1.18    ! daniel   1794:                         xmlNodePtr elem, xmlAttrPtr attr, const CHAR *value) {
        !          1795:     xmlElementPtr elemDecl;
        !          1796:     xmlAttributePtr attrDecl;
        !          1797:     int val;
        !          1798:     int ret = 1;
        !          1799: 
1.14      daniel   1800:     CHECK_DTD;
1.18    ! daniel   1801:     if ((elem == NULL) || (elem->name == NULL)) return(0);
        !          1802:     if ((attr == NULL) || (attr->name == NULL)) return(0);
        !          1803: 
        !          1804:     attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attr->name);
        !          1805:     if ((attrDecl == NULL) && (doc->extSubset != NULL))
        !          1806:        attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, attr->name);
        !          1807: 
1.14      daniel   1808: 
1.18    ! daniel   1809:     /* Validity Constraint: Attribute Value Type */
        !          1810:     if (attrDecl == NULL) {
        !          1811:        VERROR(ctxt->userData,
        !          1812:               "No declaration for attribute %s on element %s\n",
        !          1813:               attr->name, elem->name);
        !          1814:        return(0);
        !          1815:     }
        !          1816:     val = xmlValidateAttributeValue(attrDecl->type, value);
        !          1817:     if (val == 0) {
        !          1818:        VERROR(ctxt->userData, 
        !          1819:           "Syntax of value for attribute %s on %s is not valid\n",
        !          1820:               attr->name, elem->name);
        !          1821:         ret = 0;
        !          1822:     }
        !          1823: 
        !          1824:     /* Validity Constraint: Notation Attributes */
        !          1825:     if (attrDecl->type == XML_ATTRIBUTE_NOTATION) {
        !          1826:         xmlEnumerationPtr tree = attrDecl->tree;
        !          1827:         xmlNotationPtr nota;
        !          1828: 
        !          1829:         /* First check that the given NOTATION was declared */
        !          1830:        nota = xmlGetDtdNotationDesc(doc->intSubset, value);
        !          1831:        if (nota == NULL)
        !          1832:            nota = xmlGetDtdNotationDesc(doc->extSubset, value);
        !          1833:        
        !          1834:        if (nota == NULL) {
        !          1835:            VERROR(ctxt->userData, 
        !          1836:        "Value \"%s\" for attribute %s on %s is not a declared Notation\n",
        !          1837:                   value, attr->name, elem->name);
        !          1838:            ret = 0;
        !          1839:         }
        !          1840: 
        !          1841:        /* Second, verify that it's among the list */
        !          1842:        while (tree != NULL) {
        !          1843:            if (!xmlStrcmp(tree->name, value)) break;
        !          1844:            tree = tree->next;
        !          1845:        }
        !          1846:        if (tree == NULL) {
        !          1847:            VERROR(ctxt->userData, 
        !          1848:    "Value \"%s\" for attribute %s on %s is among the enumerated notations\n",
        !          1849:                   value, attr->name, elem->name);
        !          1850:            ret = 0;
        !          1851:        }
        !          1852:     }
        !          1853: 
        !          1854:     /* Validity Constraint: Enumeration */
        !          1855:     if (attrDecl->type == XML_ATTRIBUTE_ENUMERATION) {
        !          1856:         xmlEnumerationPtr tree = attrDecl->tree;
        !          1857:        while (tree != NULL) {
        !          1858:            if (!xmlStrcmp(tree->name, value)) break;
        !          1859:            tree = tree->next;
        !          1860:        }
        !          1861:        if (tree == NULL) {
        !          1862:            VERROR(ctxt->userData, 
        !          1863:        "Value \"%s\" for attribute %s on %s is among the enumerated set\n",
        !          1864:                   value, attr->name, elem->name);
        !          1865:            ret = 0;
        !          1866:        }
        !          1867:     }
        !          1868: 
        !          1869:     /* Fixed Attribute Default */
        !          1870:     if ((attrDecl->def == XML_ATTRIBUTE_FIXED) &&
        !          1871:         (xmlStrcmp(attrDecl->defaultValue, value))) {
        !          1872:        VERROR(ctxt->userData, 
        !          1873:           "Value for attribute %s on %s must be \"%s\"\n",
        !          1874:               attr->name, elem->name, attrDecl->defaultValue);
        !          1875:         ret = 0;
        !          1876:     }
        !          1877: 
        !          1878:     elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name);
        !          1879:     if ((elemDecl == NULL) && (doc->extSubset != NULL))
        !          1880:        elemDecl = xmlGetDtdElementDesc(doc->extSubset, elem->name);
        !          1881:     if (elemDecl == NULL) {
        !          1882:        /* the error has or will be reported soon in xmlValidateOneElement */
        !          1883:        return(0);
        !          1884:     }
        !          1885:     return(ret);
        !          1886: }
        !          1887: 
        !          1888: int xmlValidateElementTypeElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
        !          1889:                                  xmlElementContentPtr cont);
        !          1890: 
        !          1891: /**
        !          1892:  * xmlValidateElementTypeExpr:
        !          1893:  * @ctxt:  the validation context
        !          1894:  * @child:  pointer to the child list
        !          1895:  * @cont:  pointer to the content declaration
        !          1896:  *
        !          1897:  * Try to validate the content of an element of type element
        !          1898:  * but don't handle the occurence factor
        !          1899:  *
        !          1900:  * returns 1 if valid or 0 and -1 if PCDATA stuff is found,
        !          1901:  *         also update child value in-situ.
        !          1902:  */
        !          1903: 
        !          1904: int
        !          1905: xmlValidateElementTypeExpr(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
        !          1906:                           xmlElementContentPtr cont) {
        !          1907:     xmlNodePtr cur;
        !          1908:     int ret = 1;
        !          1909: 
        !          1910:     if (cont == NULL) return(-1);
        !          1911:     if (*child == NULL) return(0);
        !          1912:     while (*child != NULL) {
        !          1913:         if ((*child)->type == XML_PI_NODE) {
        !          1914:            *child = (*child)->next;
        !          1915:            continue;
        !          1916:        }
        !          1917:         if ((*child)->type == XML_COMMENT_NODE) {
        !          1918:            *child = (*child)->next;
        !          1919:            continue;
        !          1920:        }
        !          1921:        else if ((*child)->type != XML_ELEMENT_NODE) {
        !          1922:            return(-1);
        !          1923:        }
        !          1924:        break;
        !          1925:     }
        !          1926:     if (*child == NULL) return(0);
        !          1927:     switch (cont->type) {
        !          1928:        case XML_ELEMENT_CONTENT_PCDATA:
        !          1929:            /* Internal error !!! */
        !          1930:            fprintf(stderr, "Internal: MIXED struct bad\n");
        !          1931:            return(-1);
        !          1932:        case XML_ELEMENT_CONTENT_ELEMENT:
        !          1933:            ret = (!xmlStrcmp((*child)->name, cont->name));
        !          1934:            if (ret == 1)
        !          1935:                *child = (*child)->next;
        !          1936:            return(ret);
        !          1937:        case XML_ELEMENT_CONTENT_OR:
        !          1938:            cur = *child;
        !          1939:            ret = xmlValidateElementTypeElement(ctxt, child, cont->c1);
        !          1940:            if (ret == -1) return(-1);
        !          1941:            if (ret == 1) {
        !          1942:                 return(1);
        !          1943:            }
        !          1944:            /* rollback and retry the other path */
        !          1945:            *child = cur;
        !          1946:            ret = xmlValidateElementTypeElement(ctxt, child, cont->c2);
        !          1947:            if (ret == -1) return(-1);
        !          1948:            if (ret == 0) {
        !          1949:                *child = cur;
        !          1950:                return(0);
        !          1951:            }
        !          1952:            return(1);
        !          1953:        case XML_ELEMENT_CONTENT_SEQ:
        !          1954:            cur = *child;
        !          1955:            ret = xmlValidateElementTypeElement(ctxt, child, cont->c1);
        !          1956:            if (ret == -1) return(-1);
        !          1957:            if (ret == 0) {
        !          1958:                *child = cur;
        !          1959:                return(0);
        !          1960:            }
        !          1961:            ret = xmlValidateElementTypeElement(ctxt, child, cont->c2);
        !          1962:            if (ret == -1) return(-1);
        !          1963:            if (ret == 0) {
        !          1964:                *child = cur;
        !          1965:                return(0);
        !          1966:            }
        !          1967:            return(1);
        !          1968:     }
        !          1969:     return(ret);
        !          1970: }
        !          1971: 
        !          1972: /**
        !          1973:  * xmlValidateElementTypeElement:
        !          1974:  * @ctxt:  the validation context
        !          1975:  * @child:  pointer to the child list
        !          1976:  * @cont:  pointer to the content declaration
        !          1977:  *
        !          1978:  * Try to validate the content of an element of type element
        !          1979:  * yeah, Yet Another Regexp Implementation, and recursive
        !          1980:  *
        !          1981:  * returns 1 if valid or 0 and -1 if PCDATA stuff is found,
        !          1982:  *         also update child and content values in-situ.
        !          1983:  */
        !          1984: 
        !          1985: int
        !          1986: xmlValidateElementTypeElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
        !          1987:                              xmlElementContentPtr cont) {
        !          1988:     xmlNodePtr cur;
        !          1989:     int ret = 1;
        !          1990: 
        !          1991:     if (cont == NULL) return(-1);
        !          1992:     while (*child != NULL) {
        !          1993:         if ((*child)->type == XML_PI_NODE) {
        !          1994:            *child = (*child)->next;
        !          1995:            continue;
        !          1996:        }
        !          1997:         if ((*child)->type == XML_COMMENT_NODE) {
        !          1998:            *child = (*child)->next;
        !          1999:            continue;
        !          2000:        }
        !          2001:        else if ((*child)->type != XML_ELEMENT_NODE) {
        !          2002:            return(-1);
        !          2003:        }
        !          2004:        break;
        !          2005:     }
        !          2006:     if (*child == NULL) {
        !          2007:         if ((cont->ocur == XML_ELEMENT_CONTENT_OPT) ||
        !          2008:            (cont->ocur == XML_ELEMENT_CONTENT_MULT))
        !          2009:            return(1);
        !          2010:         return(0);
        !          2011:     }
        !          2012:     cur = *child;
        !          2013:     ret = xmlValidateElementTypeExpr(ctxt, child, cont);
        !          2014:     if (ret == -1) return(-1);
        !          2015:     switch (cont->ocur) {
        !          2016:        case XML_ELEMENT_CONTENT_ONCE:
        !          2017:            if (ret == 1) {
        !          2018:                return(1);
        !          2019:            }
        !          2020:            *child = cur;
        !          2021:            return(0);
        !          2022:        case XML_ELEMENT_CONTENT_OPT:
        !          2023:            if (ret == 0) {
        !          2024:                *child = cur;
        !          2025:                return(1);
        !          2026:            }
        !          2027:            return(1);
        !          2028:        case XML_ELEMENT_CONTENT_MULT:
        !          2029:            if (ret == 0) {
        !          2030:                *child = cur;
        !          2031:                return(1);
        !          2032:            }
        !          2033:            /* no break on purpose */
        !          2034:        case XML_ELEMENT_CONTENT_PLUS:
        !          2035:            if (ret == 0) {
        !          2036:                *child = cur;
        !          2037:                return(0);
        !          2038:            }
        !          2039:            do {
        !          2040:                cur = *child;
        !          2041:                ret = xmlValidateElementTypeExpr(ctxt, child, cont);
        !          2042:            } while (ret == 1);
        !          2043:            if (ret == -1) return(-1);
        !          2044:            *child = cur;
        !          2045:            return(1);
        !          2046:     }
        !          2047:     return(ret);
1.14      daniel   2048: }
                   2049: 
                   2050: /**
                   2051:  * xmlValidateOneElement:
                   2052:  * @ctxt:  the validation context
                   2053:  * @doc:  a document instance
                   2054:  * @elem:  an element instance
                   2055:  *
                   2056:  * Try to validate a single element and it's attributes,
                   2057:  * basically it does the following checks as described by the
                   2058:  * XML-1.0 recommendation:
                   2059:  *  - [ VC: Element Valid ]
                   2060:  *  - [ VC: Required Attribute ]
                   2061:  * Then call xmlValidateOneAttribute() for each attribute present.
                   2062:  *
                   2063:  * The ID/IDREF checkings are done separately
                   2064:  *
                   2065:  * returns 1 if valid or 0 otherwise
                   2066:  */
                   2067: 
                   2068: int
1.16      daniel   2069: xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
1.18    ! daniel   2070:                       xmlNodePtr elem) {
        !          2071:     xmlElementPtr elemDecl;
        !          2072:     xmlElementContentPtr cont;
        !          2073:     xmlNodePtr child;
        !          2074:     int ret = 1;
        !          2075:     const CHAR *name;
        !          2076: 
1.14      daniel   2077:     CHECK_DTD;
                   2078: 
1.18    ! daniel   2079:     if ((elem == NULL) || (elem->name == NULL)) return(0);
        !          2080: 
        !          2081:     elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name);
        !          2082:     if ((elemDecl == NULL) && (doc->extSubset != NULL))
        !          2083:        elemDecl = xmlGetDtdElementDesc(doc->extSubset, elem->name);
        !          2084:     if (elemDecl == NULL) {
        !          2085:        VERROR(ctxt->userData, "No declaration for element %s\n",
        !          2086:               elem->name);
        !          2087:        return(0);
        !          2088:     }
        !          2089: 
        !          2090:     /* Check taht the element content matches the definition */
        !          2091:     switch (elemDecl->type) {
        !          2092:         case XML_ELEMENT_TYPE_EMPTY:
        !          2093:            if (elem->childs != NULL) {
        !          2094:                VERROR(ctxt->userData,
        !          2095:               "Element %s was declared EMPTY this one has content\n",
        !          2096:                       elem->name);
        !          2097:                ret = 0;
        !          2098:            }
        !          2099:            break;
        !          2100:         case XML_ELEMENT_TYPE_ANY:
        !          2101:            /* I don't think anything is required then */
        !          2102:            break;
        !          2103:         case XML_ELEMENT_TYPE_MIXED:
        !          2104:            /* Hum, this start to get messy */
        !          2105:            child = elem->childs;
        !          2106:            while (child != NULL) {
        !          2107:                if (child->type == XML_ELEMENT_NODE) {
        !          2108:                    name = child->name;
        !          2109:                    cont = elemDecl->content;
        !          2110:                    while (cont != NULL) {
        !          2111:                        if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
        !          2112:                            if (!xmlStrcmp(cont->name, name)) break;
        !          2113:                        } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
        !          2114:                           (cont->c1 != NULL) &&
        !          2115:                           (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)) {
        !          2116:                            if (!xmlStrcmp(cont->c1->name, name)) break;
        !          2117:                        } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
        !          2118:                            (cont->c1 == NULL) ||
        !          2119:                            (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)) {
        !          2120:                            /* Internal error !!! */
        !          2121:                            fprintf(stderr, "Internal: MIXED struct bad\n");
        !          2122:                            break;
        !          2123:                        }
        !          2124:                        cont = cont->c2;
        !          2125:                    }
        !          2126:                    if (cont == NULL) {
        !          2127:                        VERROR(ctxt->userData,
        !          2128:               "Element %s is not declared in %s list of possible childs\n",
        !          2129:                               name, elem->name);
        !          2130:                        ret = 0;
        !          2131:                    }
        !          2132:                }
        !          2133:                child = child->next;
        !          2134:            }
        !          2135:            break;
        !          2136:         case XML_ELEMENT_TYPE_ELEMENT:
        !          2137:            child = elem->childs;
        !          2138:            cont = elemDecl->content;
        !          2139:            ret = xmlValidateElementTypeElement(ctxt, &child, cont);
        !          2140:            if (ret == 0) {
        !          2141:                VERROR(ctxt->userData,
        !          2142:               "Element %s content doesn't follow the Dtd\n", elem->name);
        !          2143:                ret = 0;
        !          2144:            } else if (child != NULL) {
        !          2145:                VERROR(ctxt->userData,
        !          2146:               "Element %s content doesn't follow the Dtd, extra elements\n",
        !          2147:                       elem->name);
        !          2148:                ret = 0;
        !          2149:            }
        !          2150:            break;
        !          2151:     }
        !          2152: 
        !          2153:     return(ret);
1.14      daniel   2154: }
                   2155: 
                   2156: /**
                   2157:  * xmlValidateRoot:
                   2158:  * @ctxt:  the validation context
                   2159:  * @doc:  a document instance
                   2160:  *
                   2161:  * Try to validate a the root element
                   2162:  * basically it does the following check as described by the
                   2163:  * XML-1.0 recommendation:
                   2164:  *  - [ VC: Root Element Type ]
                   2165:  * it doesn't try to recurse or apply other check to the element
                   2166:  *
                   2167:  * returns 1 if valid or 0 otherwise
                   2168:  */
                   2169: 
                   2170: int
                   2171: xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
                   2172:     if (doc == NULL) return(0);
                   2173: 
                   2174:     if ((doc->intSubset == NULL) ||
                   2175:        (doc->intSubset->name == NULL)) {
                   2176:        VERROR(ctxt->userData, "Not valid: no DtD found\n");
                   2177:         return(0);
                   2178:     }
                   2179:     if ((doc->root == NULL) || (doc->root->name == NULL)) {
                   2180:        VERROR(ctxt->userData, "Not valid: no root element\n");
                   2181:         return(0);
                   2182:     }
                   2183:     if (xmlStrcmp(doc->intSubset->name, doc->root->name)) {
                   2184:        VERROR(ctxt->userData,
                   2185:               "Not valid: root and DtD name do not match %s and %s\n",
                   2186:               doc->root->name, doc->intSubset->name);
                   2187:        return(0);
                   2188:     }
                   2189:     return(1);
                   2190: }
                   2191: 
                   2192: 
                   2193: /**
                   2194:  * xmlValidateElement:
                   2195:  * @ctxt:  the validation context
                   2196:  * @doc:  a document instance
                   2197:  * @elem:  an element instance
                   2198:  *
                   2199:  * Try to validate the subtree under an element 
                   2200:  *
                   2201:  * returns 1 if valid or 0 otherwise
                   2202:  */
                   2203: 
                   2204: int
1.18    ! daniel   2205: xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
1.14      daniel   2206:     CHECK_DTD;
                   2207: 
                   2208:     return(1);
                   2209: }
                   2210: 
                   2211: /**
                   2212:  * xmlValidateDtd:
                   2213:  * @ctxt:  the validation context
                   2214:  * @doc:  a document instance
                   2215:  * @dtd:  a dtd instance
                   2216:  *
                   2217:  * Try to validate the dtd instance
                   2218:  *
                   2219:  * basically it does check all the definitions in the DtD.
                   2220:  *
                   2221:  * returns 1 if valid or 0 otherwise
                   2222:  */
                   2223: 
                   2224: int
                   2225: xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
                   2226:     return(1);
                   2227: }
                   2228: 
                   2229: /**
                   2230:  * xmlValidateDocument:
                   2231:  * @ctxt:  the validation context
                   2232:  * @doc:  a document instance
                   2233:  *
                   2234:  * Try to validate the document instance
                   2235:  *
                   2236:  * basically it does the all the checks described by the
                   2237:  * i.e. validates the internal and external subset (if present)
                   2238:  * and validate the document tree.
                   2239:  *
                   2240:  * returns 1 if valid or 0 otherwise
                   2241:  */
                   2242: 
                   2243: int
                   2244: xmlValidateDocument(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
                   2245:     if (!xmlValidateRoot(ctxt, doc)) return(0);
                   2246: 
                   2247:     return(1);
                   2248: }
                   2249: 

Webmaster