Annotation of XML/valid.c, revision 1.8
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:
1.8 ! daniel 104: * @buf: An XML buffer
1.3 daniel 105: * @content: An element table
106: * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
107: *
108: * This will dump the content of the element table as an XML DTD definition
109: */
110: void
1.8 ! daniel 111: xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) {
1.3 daniel 112: if (content == NULL) return;
113:
1.8 ! daniel 114: if (glob) xmlBufferWriteChar(buf, "(");
1.3 daniel 115: switch (content->type) {
116: case XML_ELEMENT_CONTENT_PCDATA:
1.8 ! daniel 117: xmlBufferWriteChar(buf, "#PCDATA");
1.3 daniel 118: break;
119: case XML_ELEMENT_CONTENT_ELEMENT:
1.8 ! daniel 120: xmlBufferWriteCHAR(buf, content->name);
1.3 daniel 121: break;
122: case XML_ELEMENT_CONTENT_SEQ:
123: if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
124: (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
1.8 ! daniel 125: xmlDumpElementContent(buf, content->c1, 1);
1.3 daniel 126: else
1.8 ! daniel 127: xmlDumpElementContent(buf, content->c1, 0);
! 128: xmlBufferWriteChar(buf, " , ");
1.3 daniel 129: if (content->c2->type == XML_ELEMENT_CONTENT_OR)
1.8 ! daniel 130: xmlDumpElementContent(buf, content->c2, 1);
1.3 daniel 131: else
1.8 ! daniel 132: xmlDumpElementContent(buf, content->c2, 0);
1.3 daniel 133: break;
134: case XML_ELEMENT_CONTENT_OR:
135: if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
136: (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
1.8 ! daniel 137: xmlDumpElementContent(buf, content->c1, 1);
1.3 daniel 138: else
1.8 ! daniel 139: xmlDumpElementContent(buf, content->c1, 0);
! 140: xmlBufferWriteChar(buf, " | ");
1.3 daniel 141: if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)
1.8 ! daniel 142: xmlDumpElementContent(buf, content->c2, 1);
1.3 daniel 143: else
1.8 ! daniel 144: xmlDumpElementContent(buf, content->c2, 0);
1.3 daniel 145: break;
146: default:
147: fprintf(stderr, "xmlDumpElementContent: unknown type %d\n",
148: content->type);
149: }
150: if (glob)
1.8 ! daniel 151: xmlBufferWriteChar(buf, ")");
1.3 daniel 152: switch (content->ocur) {
153: case XML_ELEMENT_CONTENT_ONCE:
154: break;
155: case XML_ELEMENT_CONTENT_OPT:
1.8 ! daniel 156: xmlBufferWriteChar(buf, "?");
1.3 daniel 157: break;
158: case XML_ELEMENT_CONTENT_MULT:
1.8 ! daniel 159: xmlBufferWriteChar(buf, "*");
1.3 daniel 160: break;
161: case XML_ELEMENT_CONTENT_PLUS:
1.8 ! daniel 162: xmlBufferWriteChar(buf, "+");
1.3 daniel 163: break;
164: }
165: }
166:
1.1 daniel 167: /****************************************************************
168: * *
169: * Registration of DTD declarations *
170: * *
171: ****************************************************************/
172:
1.2 daniel 173: /**
174: * xmlCreateElementTable:
175: *
176: * create and initialize an empty element hash table.
177: *
1.6 daniel 178: * Returns the xmlElementTablePtr just created or NULL in case of error.
1.2 daniel 179: */
180: xmlElementTablePtr
181: xmlCreateElementTable(void) {
182: xmlElementTablePtr ret;
183:
184: ret = (xmlElementTablePtr)
185: malloc(sizeof(xmlElementTable));
186: if (ret == NULL) {
187: fprintf(stderr, "xmlCreateElementTable : malloc(%d) failed\n",
188: sizeof(xmlElementTable));
189: return(NULL);
190: }
1.4 daniel 191: ret->max_elements = XML_MIN_ELEMENT_TABLE;
1.2 daniel 192: ret->nb_elements = 0;
193: ret->table = (xmlElementPtr )
194: malloc(ret->max_elements * sizeof(xmlElement));
195: if (ret == NULL) {
196: fprintf(stderr, "xmlCreateElementTable : malloc(%d) failed\n",
197: ret->max_elements * sizeof(xmlElement));
198: free(ret);
199: return(NULL);
200: }
201: return(ret);
202: }
203:
1.1 daniel 204:
205: /**
206: * xmlAddElementDecl:
1.6 daniel 207: * @dtd: pointer to the DTD
1.1 daniel 208: * @name: the entity name
1.6 daniel 209: * @type: the element type
210: * @content: the element content tree or NULL
1.1 daniel 211: *
212: * Register a new element declaration
213: *
1.6 daniel 214: * Returns NULL if not, othervise the entity
1.1 daniel 215: */
216: xmlElementPtr
1.7 daniel 217: xmlAddElementDecl(xmlDtdPtr dtd, const CHAR *name, int type,
1.1 daniel 218: xmlElementContentPtr content) {
1.2 daniel 219: xmlElementPtr ret, cur;
220: xmlElementTablePtr table;
221: int i;
1.1 daniel 222:
223: if (dtd == NULL) {
224: fprintf(stderr, "xmlAddElementDecl: dtd == NULL\n");
225: return(NULL);
226: }
227: if (name == NULL) {
228: fprintf(stderr, "xmlAddElementDecl: name == NULL\n");
229: return(NULL);
230: }
231: switch (type) {
232: case XML_ELEMENT_TYPE_EMPTY:
233: if (content != NULL) {
234: fprintf(stderr,
235: "xmlAddElementDecl: content != NULL for EMPTY\n");
236: return(NULL);
237: }
238: break;
239: case XML_ELEMENT_TYPE_ANY:
240: if (content != NULL) {
241: fprintf(stderr,
242: "xmlAddElementDecl: content != NULL for ANY\n");
243: return(NULL);
244: }
245: break;
246: case XML_ELEMENT_TYPE_MIXED:
247: if (content == NULL) {
248: fprintf(stderr,
249: "xmlAddElementDecl: content == NULL for MIXED\n");
250: return(NULL);
251: }
252: break;
253: case XML_ELEMENT_TYPE_ELEMENT:
254: if (content == NULL) {
255: fprintf(stderr,
256: "xmlAddElementDecl: content == NULL for ELEMENT\n");
257: return(NULL);
258: }
259: break;
260: default:
261: fprintf(stderr, "xmlAddElementDecl: unknown type %d\n", type);
262: return(NULL);
263: }
264:
265: /*
1.2 daniel 266: * Create the Element table if needed.
267: */
268: table = dtd->elements;
269: if (table == NULL)
270: table = dtd->elements = xmlCreateElementTable();
271: if (table == NULL) {
272: fprintf(stderr, "xmlAddElementDecl: Table creation failed!\n");
273: return(NULL);
274: }
275:
276: /*
1.1 daniel 277: * Validity Check:
278: * Search the DTD for previous declarations of the ELEMENT
279: */
1.2 daniel 280: for (i = 0;i < table->nb_elements;i++) {
281: cur = &table->table[i];
282: if (!xmlStrcmp(cur->name, name)) {
283: /*
284: * The element is already defined in this Dtd.
285: */
286: fprintf(stderr,
287: "xmlAddElementDecl: %s already defined\n", name);
288: return(NULL);
289: }
290: }
1.1 daniel 291:
292: /*
1.2 daniel 293: * Grow the table, if needed.
1.1 daniel 294: */
1.2 daniel 295: if (table->nb_elements >= table->max_elements) {
296: /*
297: * need more elements.
298: */
299: table->max_elements *= 2;
300: table->table = (xmlElementPtr)
301: realloc(table->table, table->max_elements * sizeof(xmlElement));
302: if (table->table) {
303: fprintf(stderr, "xmlAddElementDecl: out of memory\n");
304: return(NULL);
305: }
1.1 daniel 306: }
1.2 daniel 307: ret = &table->table[table->nb_elements];
308:
309: /*
310: * fill the structure.
311: */
1.1 daniel 312: ret->type = type;
313: ret->name = xmlStrdup(name);
314: ret->content = content;
1.2 daniel 315: table->nb_elements++;
316:
317: return(ret);
318: }
319:
320: /**
321: * xmlFreeElement:
322: * @elem: An element
323: *
324: * Deallocate the memory used by an element definition
325: */
326: void
327: xmlFreeElement(xmlElementPtr elem) {
328: if (elem == NULL) return;
329: xmlFreeElementContent(elem->content);
330: if (elem->name != NULL)
331: free((CHAR *) elem->name);
332: memset(elem, -1, sizeof(xmlElement));
333: }
1.1 daniel 334:
1.2 daniel 335: /**
336: * xmlFreeElementTable:
337: * @table: An element table
338: *
1.4 daniel 339: * Deallocate the memory used by an element hash table.
1.2 daniel 340: */
341: void
342: xmlFreeElementTable(xmlElementTablePtr table) {
343: int i;
344:
345: if (table == NULL) return;
346:
347: for (i = 0;i < table->nb_elements;i++) {
348: xmlFreeElement(&table->table[i]);
349: }
350: free(table->table);
351: free(table);
352: }
353:
354: /**
355: * xmlCopyElementTable:
356: * @table: An element table
357: *
358: * Build a copy of an element table.
359: *
1.6 daniel 360: * Returns the new xmlElementTablePtr or NULL in case of error.
1.2 daniel 361: */
362: xmlElementTablePtr
363: xmlCopyElementTable(xmlElementTablePtr table) {
364: xmlElementTablePtr ret;
365: xmlElementPtr cur, ent;
366: int i;
1.1 daniel 367:
1.2 daniel 368: ret = (xmlElementTablePtr) malloc(sizeof(xmlElementTable));
369: if (ret == NULL) {
370: fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
371: return(NULL);
372: }
373: ret->table = (xmlElementPtr) malloc(table->max_elements *
374: sizeof(xmlElement));
375: if (ret->table == NULL) {
376: fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
377: free(ret);
378: return(NULL);
379: }
380: ret->max_elements = table->max_elements;
381: ret->nb_elements = table->nb_elements;
382: for (i = 0;i < ret->nb_elements;i++) {
383: cur = &ret->table[i];
384: ent = &table->table[i];
385: cur->type = ent->type;
386: if (ent->name != NULL)
387: cur->name = xmlStrdup(ent->name);
388: else
389: cur->name = NULL;
390: cur->content = xmlCopyElementContent(ent->content);
391: }
1.1 daniel 392: return(ret);
393: }
394:
1.2 daniel 395: /**
396: * xmlDumpElementTable:
397: * @table: An element table
398: *
399: * This will dump the content of the element table as an XML DTD definition
400: *
401: * NOTE: TODO an extra parameter allowing a reentant implementation will
402: * be added.
403: */
404: void
1.8 ! daniel 405: xmlDumpElementTable(xmlBufferPtr buf, xmlElementTablePtr table) {
1.2 daniel 406: int i;
407: xmlElementPtr cur;
408:
409: if (table == NULL) return;
410:
411: for (i = 0;i < table->nb_elements;i++) {
412: cur = &table->table[i];
413: switch (cur->type) {
414: case XML_ELEMENT_TYPE_EMPTY:
1.8 ! daniel 415: xmlBufferWriteChar(buf, "<!ELEMENT ");
! 416: xmlBufferWriteCHAR(buf, cur->name);
! 417: xmlBufferWriteChar(buf, " EMPTY>\n");
1.2 daniel 418: break;
419: case XML_ELEMENT_TYPE_ANY:
1.8 ! daniel 420: xmlBufferWriteChar(buf, "<!ELEMENT ");
! 421: xmlBufferWriteCHAR(buf, cur->name);
! 422: xmlBufferWriteChar(buf, " ANY>\n");
1.2 daniel 423: break;
424: case XML_ELEMENT_TYPE_MIXED:
1.8 ! daniel 425: xmlBufferWriteChar(buf, "<!ELEMENT ");
! 426: xmlBufferWriteCHAR(buf, cur->name);
! 427: xmlBufferWriteChar(buf, " ");
! 428: xmlDumpElementContent(buf, cur->content, 1);
! 429: xmlBufferWriteChar(buf, ">\n");
1.2 daniel 430: break;
431: case XML_ELEMENT_TYPE_ELEMENT:
1.8 ! daniel 432: xmlBufferWriteChar(buf, "<!ELEMENT ");
! 433: xmlBufferWriteCHAR(buf, cur->name);
! 434: xmlBufferWriteChar(buf, " ");
! 435: xmlDumpElementContent(buf, cur->content, 1);
! 436: xmlBufferWriteChar(buf, ">\n");
1.2 daniel 437: break;
438: default:
439: fprintf(stderr,
440: "xmlDumpElementTable: internal: unknown type %d\n",
441: cur->type);
442: }
1.4 daniel 443: }
444: }
445:
446: /**
447: * xmlCreateEnumeration:
448: * @name: the enumeration name or NULL
449: *
450: * create and initialize an enumeration attribute node.
451: *
1.6 daniel 452: * Returns the xmlEnumerationPtr just created or NULL in case
1.4 daniel 453: * of error.
454: */
455: xmlEnumerationPtr
456: xmlCreateEnumeration(CHAR *name) {
457: xmlEnumerationPtr ret;
458:
459: ret = (xmlEnumerationPtr) malloc(sizeof(xmlEnumeration));
460: if (ret == NULL) {
461: fprintf(stderr, "xmlCreateEnumeration : malloc(%d) failed\n",
462: sizeof(xmlEnumeration));
463: return(NULL);
464: }
465:
466: if (name != NULL)
467: ret->name = xmlStrdup(name);
468: else
469: ret->name = NULL;
470: ret->next = NULL;
471: return(ret);
472: }
473:
474: /**
475: * xmlFreeEnumeration:
476: * @cur: the tree to free.
477: *
478: * free an enumeration attribute node (recursive).
479: */
480: void
481: xmlFreeEnumeration(xmlEnumerationPtr cur) {
482: if (cur == NULL) return;
483:
484: if (cur->next != NULL) xmlFreeEnumeration(cur->next);
485:
486: if (cur->name != NULL) free((CHAR *) cur->name);
487: memset(cur, -1, sizeof(xmlEnumeration));
488: free(cur);
489: }
490:
491: /**
492: * xmlCopyEnumeration:
493: * @cur: the tree to copy.
494: *
495: * Copy an enumeration attribute node (recursive).
496: *
1.6 daniel 497: * Returns the xmlEnumerationPtr just created or NULL in case
1.4 daniel 498: * of error.
499: */
500: xmlEnumerationPtr
501: xmlCopyEnumeration(xmlEnumerationPtr cur) {
502: xmlEnumerationPtr ret;
503:
504: if (cur == NULL) return(NULL);
505: ret = xmlCreateEnumeration((CHAR *) cur->name);
506:
507: if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
508: else ret->next = NULL;
509:
510: return(ret);
511: }
512:
513: /**
514: * xmlCreateAttributeTable:
515: *
516: * create and initialize an empty attribute hash table.
517: *
1.6 daniel 518: * Returns the xmlAttributeTablePtr just created or NULL in case
1.4 daniel 519: * of error.
520: */
521: xmlAttributeTablePtr
522: xmlCreateAttributeTable(void) {
523: xmlAttributeTablePtr ret;
524:
525: ret = (xmlAttributeTablePtr)
526: malloc(sizeof(xmlAttributeTable));
527: if (ret == NULL) {
528: fprintf(stderr, "xmlCreateAttributeTable : malloc(%d) failed\n",
529: sizeof(xmlAttributeTable));
530: return(NULL);
531: }
532: ret->max_attributes = XML_MIN_ATTRIBUTE_TABLE;
533: ret->nb_attributes = 0;
534: ret->table = (xmlAttributePtr )
535: malloc(ret->max_attributes * sizeof(xmlAttribute));
536: if (ret == NULL) {
537: fprintf(stderr, "xmlCreateAttributeTable : malloc(%d) failed\n",
538: ret->max_attributes * sizeof(xmlAttribute));
539: free(ret);
540: return(NULL);
541: }
542: return(ret);
543: }
544:
545:
546: /**
547: * xmlAddAttributeDecl:
1.6 daniel 548: * @dtd: pointer to the DTD
549: * @elem: the element name
550: * @name: the attribute name
551: * @type: the attribute type
552: * @def: the attribute default type
553: * @defaultValue: the attribute default value
554: * @tree: if it's an enumeration, the associated list
1.4 daniel 555: *
556: * Register a new attribute declaration
557: *
1.6 daniel 558: * Returns NULL if not, othervise the entity
1.4 daniel 559: */
560: xmlAttributePtr
1.7 daniel 561: xmlAddAttributeDecl(xmlDtdPtr dtd, const CHAR *elem, const CHAR *name,
562: int type, int def, const CHAR *defaultValue,
563: xmlEnumerationPtr tree) {
1.4 daniel 564: xmlAttributePtr ret, cur;
565: xmlAttributeTablePtr table;
566: int i;
567:
568: if (dtd == NULL) {
569: fprintf(stderr, "xmlAddAttributeDecl: dtd == NULL\n");
570: return(NULL);
571: }
572: if (name == NULL) {
573: fprintf(stderr, "xmlAddAttributeDecl: name == NULL\n");
574: return(NULL);
575: }
576: if (elem == NULL) {
577: fprintf(stderr, "xmlAddAttributeDecl: elem == NULL\n");
578: return(NULL);
579: }
580: /* TODO: Lacks verifications !!! */
581: switch (type) {
582: case XML_ATTRIBUTE_CDATA:
583: break;
584: case XML_ATTRIBUTE_ID:
585: break;
586: case XML_ATTRIBUTE_IDREF:
587: break;
588: case XML_ATTRIBUTE_IDREFS:
589: break;
590: case XML_ATTRIBUTE_ENTITY:
591: break;
592: case XML_ATTRIBUTE_ENTITIES:
593: break;
594: case XML_ATTRIBUTE_NMTOKEN:
595: break;
596: case XML_ATTRIBUTE_NMTOKENS:
597: break;
598: case XML_ATTRIBUTE_ENUMERATION:
599: break;
600: case XML_ATTRIBUTE_NOTATION:
601: break;
602: default:
603: fprintf(stderr, "xmlAddAttributeDecl: unknown type %d\n", type);
604: return(NULL);
605: }
606:
607: /*
608: * Create the Attribute table if needed.
609: */
610: table = dtd->attributes;
611: if (table == NULL)
612: table = dtd->attributes = xmlCreateAttributeTable();
613: if (table == NULL) {
614: fprintf(stderr, "xmlAddAttributeDecl: Table creation failed!\n");
615: return(NULL);
616: }
617:
618: /*
619: * Validity Check:
620: * Search the DTD for previous declarations of the ATTLIST
621: */
622: for (i = 0;i < table->nb_attributes;i++) {
623: cur = &table->table[i];
624: if ((!xmlStrcmp(cur->name, name)) && (!xmlStrcmp(cur->elem, elem))) {
625: /*
626: * The attribute is already defined in this Dtd.
627: */
628: fprintf(stderr,
629: "xmlAddAttributeDecl: %s already defined\n", name);
630: }
631: }
632:
633: /*
634: * Grow the table, if needed.
635: */
636: if (table->nb_attributes >= table->max_attributes) {
637: /*
638: * need more attributes.
639: */
640: table->max_attributes *= 2;
641: table->table = (xmlAttributePtr)
642: realloc(table->table, table->max_attributes * sizeof(xmlAttribute));
643: if (table->table) {
644: fprintf(stderr, "xmlAddAttributeDecl: out of memory\n");
645: return(NULL);
646: }
647: }
648: ret = &table->table[table->nb_attributes];
649:
650: /*
651: * fill the structure.
652: */
653: ret->type = type;
654: ret->name = xmlStrdup(name);
655: ret->elem = xmlStrdup(elem);
656: ret->def = def;
657: ret->tree = tree;
658: if (defaultValue != NULL)
659: ret->defaultValue = xmlStrdup(defaultValue);
660: else
661: ret->defaultValue = NULL;
662: table->nb_attributes++;
663:
664: return(ret);
665: }
666:
667: /**
668: * xmlFreeAttribute:
669: * @elem: An attribute
670: *
671: * Deallocate the memory used by an attribute definition
672: */
673: void
674: xmlFreeAttribute(xmlAttributePtr attr) {
675: if (attr == NULL) return;
676: if (attr->tree != NULL)
677: xmlFreeEnumeration(attr->tree);
678: if (attr->elem != NULL)
679: free((CHAR *) attr->elem);
680: if (attr->name != NULL)
681: free((CHAR *) attr->name);
682: if (attr->defaultValue != NULL)
683: free((CHAR *) attr->defaultValue);
684: memset(attr, -1, sizeof(xmlAttribute));
685: }
686:
687: /**
688: * xmlFreeAttributeTable:
689: * @table: An attribute table
690: *
691: * Deallocate the memory used by an entities hash table.
692: */
693: void
694: xmlFreeAttributeTable(xmlAttributeTablePtr table) {
695: int i;
696:
697: if (table == NULL) return;
698:
699: for (i = 0;i < table->nb_attributes;i++) {
700: xmlFreeAttribute(&table->table[i]);
701: }
702: free(table->table);
703: free(table);
704: }
705:
706: /**
707: * xmlCopyAttributeTable:
708: * @table: An attribute table
709: *
710: * Build a copy of an attribute table.
711: *
1.6 daniel 712: * Returns the new xmlAttributeTablePtr or NULL in case of error.
1.4 daniel 713: */
714: xmlAttributeTablePtr
715: xmlCopyAttributeTable(xmlAttributeTablePtr table) {
716: xmlAttributeTablePtr ret;
717: xmlAttributePtr cur, attr;
718: int i;
719:
720: ret = (xmlAttributeTablePtr) malloc(sizeof(xmlAttributeTable));
721: if (ret == NULL) {
722: fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
723: return(NULL);
724: }
725: ret->table = (xmlAttributePtr) malloc(table->max_attributes *
726: sizeof(xmlAttribute));
727: if (ret->table == NULL) {
728: fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
729: free(ret);
730: return(NULL);
731: }
732: ret->max_attributes = table->max_attributes;
733: ret->nb_attributes = table->nb_attributes;
734: for (i = 0;i < ret->nb_attributes;i++) {
735: cur = &ret->table[i];
736: attr = &table->table[i];
737: cur->type = attr->type;
738: cur->def = attr->def;
739: cur->tree = xmlCopyEnumeration(attr->tree);
740: if (attr->elem != NULL)
741: cur->elem = xmlStrdup(attr->elem);
742: else
743: cur->elem = NULL;
744: if (attr->name != NULL)
745: cur->name = xmlStrdup(attr->name);
746: else
747: cur->name = NULL;
748: if (attr->defaultValue != NULL)
749: cur->defaultValue = xmlStrdup(attr->defaultValue);
750: else
751: cur->defaultValue = NULL;
752: }
753: return(ret);
754: }
755:
756: /**
757: * xmlDumpAttributeTable:
758: * @table: An attribute table
759: *
760: * This will dump the content of the attribute table as an XML DTD definition
761: *
762: * NOTE: TODO an extra parameter allowing a reentant implementation will
763: * be added.
764: */
765: void
1.8 ! daniel 766: xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
1.4 daniel 767: int i;
768: xmlAttributePtr cur;
769:
770: if (table == NULL) return;
771:
772: for (i = 0;i < table->nb_attributes;i++) {
773: cur = &table->table[i];
1.8 ! daniel 774: xmlBufferWriteChar(buf, "<!ATTLIST ");
! 775: xmlBufferWriteCHAR(buf, cur->elem);
! 776: xmlBufferWriteChar(buf, " ");
! 777: xmlBufferWriteCHAR(buf, cur->name);
1.4 daniel 778: switch (cur->type) {
779: case XML_ATTRIBUTE_CDATA:
1.8 ! daniel 780: xmlBufferWriteChar(buf, " CDATA");
1.4 daniel 781: break;
782: case XML_ATTRIBUTE_ID:
1.8 ! daniel 783: xmlBufferWriteChar(buf, " ID");
1.4 daniel 784: break;
785: case XML_ATTRIBUTE_IDREF:
1.8 ! daniel 786: xmlBufferWriteChar(buf, " IDREF");
1.4 daniel 787: break;
788: case XML_ATTRIBUTE_IDREFS:
1.8 ! daniel 789: xmlBufferWriteChar(buf, " IDREFS");
1.4 daniel 790: break;
791: case XML_ATTRIBUTE_ENTITY:
1.8 ! daniel 792: xmlBufferWriteChar(buf, " ENTITY");
1.4 daniel 793: break;
794: case XML_ATTRIBUTE_ENTITIES:
1.8 ! daniel 795: xmlBufferWriteChar(buf, " ENTITIES");
1.4 daniel 796: break;
797: case XML_ATTRIBUTE_NMTOKEN:
1.8 ! daniel 798: xmlBufferWriteChar(buf, " NMTOKEN");
1.4 daniel 799: break;
800: case XML_ATTRIBUTE_NMTOKENS:
1.8 ! daniel 801: xmlBufferWriteChar(buf, " NMTOKENS");
1.4 daniel 802: break;
803: case XML_ATTRIBUTE_ENUMERATION:
1.8 ! daniel 804: xmlBufferWriteChar(buf, " (pbm)");
1.4 daniel 805: break;
806: case XML_ATTRIBUTE_NOTATION:
1.8 ! daniel 807: xmlBufferWriteChar(buf, " NOTATION (pbm)");
1.4 daniel 808: break;
809: default:
810: fprintf(stderr,
811: "xmlDumpAttributeTable: internal: unknown type %d\n",
812: cur->type);
813: }
814: switch (cur->def) {
815: case XML_ATTRIBUTE_NONE:
816: break;
817: case XML_ATTRIBUTE_REQUIRED:
1.8 ! daniel 818: xmlBufferWriteChar(buf, " #REQUIRED");
1.4 daniel 819: break;
820: case XML_ATTRIBUTE_IMPLIED:
1.8 ! daniel 821: xmlBufferWriteChar(buf, " #IMPLIED");
1.6 daniel 822: if (cur->defaultValue != NULL) {
1.8 ! daniel 823: xmlBufferWriteChar(buf, " \"");
! 824: xmlBufferWriteCHAR(buf, cur->defaultValue);
! 825: xmlBufferWriteChar(buf, "\"");
1.6 daniel 826: }
1.4 daniel 827: break;
828: case XML_ATTRIBUTE_FIXED:
1.8 ! daniel 829: xmlBufferWriteChar(buf, " #FIXED \"");
! 830: xmlBufferWriteCHAR(buf, cur->defaultValue);
! 831: xmlBufferWriteChar(buf, "\"");
1.4 daniel 832: break;
833: default:
834: fprintf(stderr,
835: "xmlDumpAttributeTable: internal: unknown default %d\n",
836: cur->def);
837: }
1.8 ! daniel 838: xmlBufferWriteChar(buf, ">\n");
1.5 daniel 839: }
840: }
841:
842: /************************************************************************
843: * *
844: * NOTATIONs *
845: * *
846: ************************************************************************/
847: /**
848: * xmlCreateNotationTable:
849: *
850: * create and initialize an empty notation hash table.
851: *
1.6 daniel 852: * Returns the xmlNotationTablePtr just created or NULL in case
1.5 daniel 853: * of error.
854: */
855: xmlNotationTablePtr
856: xmlCreateNotationTable(void) {
857: xmlNotationTablePtr ret;
858:
859: ret = (xmlNotationTablePtr)
860: malloc(sizeof(xmlNotationTable));
861: if (ret == NULL) {
862: fprintf(stderr, "xmlCreateNotationTable : malloc(%d) failed\n",
863: sizeof(xmlNotationTable));
864: return(NULL);
865: }
866: ret->max_notations = XML_MIN_NOTATION_TABLE;
867: ret->nb_notations = 0;
868: ret->table = (xmlNotationPtr )
869: malloc(ret->max_notations * sizeof(xmlNotation));
870: if (ret == NULL) {
871: fprintf(stderr, "xmlCreateNotationTable : malloc(%d) failed\n",
872: ret->max_notations * sizeof(xmlNotation));
873: free(ret);
874: return(NULL);
875: }
876: return(ret);
877: }
878:
879:
880: /**
881: * xmlAddNotationDecl:
1.6 daniel 882: * @dtd: pointer to the DTD
1.5 daniel 883: * @name: the entity name
1.6 daniel 884: * @PublicID: the public identifier or NULL
885: * @SystemID: the system identifier or NULL
1.5 daniel 886: *
887: * Register a new notation declaration
888: *
1.6 daniel 889: * Returns NULL if not, othervise the entity
1.5 daniel 890: */
891: xmlNotationPtr
1.7 daniel 892: xmlAddNotationDecl(xmlDtdPtr dtd, const CHAR *name, const CHAR *PublicID,
893: const CHAR *SystemID) {
1.5 daniel 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
1.8 ! daniel 1064: xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
1.5 daniel 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];
1.8 ! daniel 1072: xmlBufferWriteChar(buf, "<!NOTATION ");
! 1073: xmlBufferWriteCHAR(buf, cur->name);
1.5 daniel 1074: if (cur->PublicID != NULL) {
1.8 ! daniel 1075: xmlBufferWriteChar(buf, " PUBLIC \"");
! 1076: xmlBufferWriteCHAR(buf, cur->PublicID);
! 1077: xmlBufferWriteChar(buf, "\"");
1.5 daniel 1078: if (cur->SystemID != NULL) {
1.8 ! daniel 1079: xmlBufferWriteChar(buf, " ");
! 1080: xmlBufferWriteCHAR(buf, cur->SystemID);
1.5 daniel 1081: }
1082: } else {
1.8 ! daniel 1083: xmlBufferWriteChar(buf, " SYSTEM ");
! 1084: xmlBufferWriteCHAR(buf, cur->SystemID);
1.5 daniel 1085: }
1.8 ! daniel 1086: xmlBufferWriteChar(buf, " >\n");
1.2 daniel 1087: }
1088: }
Webmaster