Annotation of XML/valid.c, revision 1.13

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

Webmaster