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