Annotation of XML/valid.c, revision 1.5
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: *
29: * return values: NULL if not, othervise the new element content structure
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: *
73: * return values: the new xmlElementContentPtr or NULL in case of error.
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: *
180: * return values: the xmlElementTablePtr just created or NULL in case of error.
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:
209: * @name: the entity name
210: *
211: * Register a new element declaration
212: *
213: * return values: NULL if not, othervise the entity
214: */
215: xmlElementPtr
1.4 daniel 216: xmlAddElementDecl(xmlDtdPtr dtd, CHAR *name, int type,
1.1 daniel 217: xmlElementContentPtr content) {
1.2 daniel 218: xmlElementPtr ret, cur;
219: xmlElementTablePtr table;
220: int i;
1.1 daniel 221:
222: if (dtd == NULL) {
223: fprintf(stderr, "xmlAddElementDecl: dtd == NULL\n");
224: return(NULL);
225: }
226: if (name == NULL) {
227: fprintf(stderr, "xmlAddElementDecl: name == NULL\n");
228: return(NULL);
229: }
230: switch (type) {
231: case XML_ELEMENT_TYPE_EMPTY:
232: if (content != NULL) {
233: fprintf(stderr,
234: "xmlAddElementDecl: content != NULL for EMPTY\n");
235: return(NULL);
236: }
237: break;
238: case XML_ELEMENT_TYPE_ANY:
239: if (content != NULL) {
240: fprintf(stderr,
241: "xmlAddElementDecl: content != NULL for ANY\n");
242: return(NULL);
243: }
244: break;
245: case XML_ELEMENT_TYPE_MIXED:
246: if (content == NULL) {
247: fprintf(stderr,
248: "xmlAddElementDecl: content == NULL for MIXED\n");
249: return(NULL);
250: }
251: break;
252: case XML_ELEMENT_TYPE_ELEMENT:
253: if (content == NULL) {
254: fprintf(stderr,
255: "xmlAddElementDecl: content == NULL for ELEMENT\n");
256: return(NULL);
257: }
258: break;
259: default:
260: fprintf(stderr, "xmlAddElementDecl: unknown type %d\n", type);
261: return(NULL);
262: }
263:
264: /*
1.2 daniel 265: * Create the Element table if needed.
266: */
267: table = dtd->elements;
268: if (table == NULL)
269: table = dtd->elements = xmlCreateElementTable();
270: if (table == NULL) {
271: fprintf(stderr, "xmlAddElementDecl: Table creation failed!\n");
272: return(NULL);
273: }
274:
275: /*
1.1 daniel 276: * Validity Check:
277: * Search the DTD for previous declarations of the ELEMENT
278: */
1.2 daniel 279: for (i = 0;i < table->nb_elements;i++) {
280: cur = &table->table[i];
281: if (!xmlStrcmp(cur->name, name)) {
282: /*
283: * The element is already defined in this Dtd.
284: */
285: fprintf(stderr,
286: "xmlAddElementDecl: %s already defined\n", name);
287: return(NULL);
288: }
289: }
1.1 daniel 290:
291: /*
1.2 daniel 292: * Grow the table, if needed.
1.1 daniel 293: */
1.2 daniel 294: if (table->nb_elements >= table->max_elements) {
295: /*
296: * need more elements.
297: */
298: table->max_elements *= 2;
299: table->table = (xmlElementPtr)
300: realloc(table->table, table->max_elements * sizeof(xmlElement));
301: if (table->table) {
302: fprintf(stderr, "xmlAddElementDecl: out of memory\n");
303: return(NULL);
304: }
1.1 daniel 305: }
1.2 daniel 306: ret = &table->table[table->nb_elements];
307:
308: /*
309: * fill the structure.
310: */
1.1 daniel 311: ret->type = type;
312: ret->name = xmlStrdup(name);
313: ret->content = content;
1.2 daniel 314: table->nb_elements++;
315:
316: return(ret);
317: }
318:
319: /**
320: * xmlFreeElement:
321: * @elem: An element
322: *
323: * Deallocate the memory used by an element definition
324: */
325: void
326: xmlFreeElement(xmlElementPtr elem) {
327: if (elem == NULL) return;
328: xmlFreeElementContent(elem->content);
329: if (elem->name != NULL)
330: free((CHAR *) elem->name);
331: memset(elem, -1, sizeof(xmlElement));
332: }
1.1 daniel 333:
1.2 daniel 334: /**
335: * xmlFreeElementTable:
336: * @table: An element table
337: *
1.4 daniel 338: * Deallocate the memory used by an element hash table.
1.2 daniel 339: */
340: void
341: xmlFreeElementTable(xmlElementTablePtr table) {
342: int i;
343:
344: if (table == NULL) return;
345:
346: for (i = 0;i < table->nb_elements;i++) {
347: xmlFreeElement(&table->table[i]);
348: }
349: free(table->table);
350: free(table);
351: }
352:
353: /**
354: * xmlCopyElementTable:
355: * @table: An element table
356: *
357: * Build a copy of an element table.
358: *
359: * return values: the new xmlElementTablePtr or NULL in case of error.
360: */
361: xmlElementTablePtr
362: xmlCopyElementTable(xmlElementTablePtr table) {
363: xmlElementTablePtr ret;
364: xmlElementPtr cur, ent;
365: int i;
1.1 daniel 366:
1.2 daniel 367: ret = (xmlElementTablePtr) malloc(sizeof(xmlElementTable));
368: if (ret == NULL) {
369: fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
370: return(NULL);
371: }
372: ret->table = (xmlElementPtr) malloc(table->max_elements *
373: sizeof(xmlElement));
374: if (ret->table == NULL) {
375: fprintf(stderr, "xmlCopyElementTable: out of memory !\n");
376: free(ret);
377: return(NULL);
378: }
379: ret->max_elements = table->max_elements;
380: ret->nb_elements = table->nb_elements;
381: for (i = 0;i < ret->nb_elements;i++) {
382: cur = &ret->table[i];
383: ent = &table->table[i];
384: cur->type = ent->type;
385: if (ent->name != NULL)
386: cur->name = xmlStrdup(ent->name);
387: else
388: cur->name = NULL;
389: cur->content = xmlCopyElementContent(ent->content);
390: }
1.1 daniel 391: return(ret);
392: }
393:
1.2 daniel 394: /**
395: * xmlDumpElementTable:
396: * @table: An element table
397: *
398: * This will dump the content of the element table as an XML DTD definition
399: *
400: * NOTE: TODO an extra parameter allowing a reentant implementation will
401: * be added.
402: */
403: void
404: xmlDumpElementTable(xmlElementTablePtr table) {
405: int i;
406: xmlElementPtr cur;
407:
408: if (table == NULL) return;
409:
410: for (i = 0;i < table->nb_elements;i++) {
411: cur = &table->table[i];
412: switch (cur->type) {
413: case XML_ELEMENT_TYPE_EMPTY:
414: xmlBufferWriteChar("<!ELEMENT ");
415: xmlBufferWriteCHAR(cur->name);
1.3 daniel 416: xmlBufferWriteChar(" EMPTY>\n");
1.2 daniel 417: break;
418: case XML_ELEMENT_TYPE_ANY:
419: xmlBufferWriteChar("<!ELEMENT ");
420: xmlBufferWriteCHAR(cur->name);
1.3 daniel 421: xmlBufferWriteChar(" ANY>\n");
1.2 daniel 422: break;
423: case XML_ELEMENT_TYPE_MIXED:
1.3 daniel 424: xmlBufferWriteChar("<!ELEMENT ");
425: xmlBufferWriteCHAR(cur->name);
426: xmlBufferWriteChar(" ");
427: xmlDumpElementContent(cur->content, 1);
428: xmlBufferWriteChar(">\n");
1.2 daniel 429: break;
430: case XML_ELEMENT_TYPE_ELEMENT:
1.3 daniel 431: xmlBufferWriteChar("<!ELEMENT ");
432: xmlBufferWriteCHAR(cur->name);
433: xmlBufferWriteChar(" ");
434: xmlDumpElementContent(cur->content, 1);
435: xmlBufferWriteChar(">\n");
1.2 daniel 436: break;
437: default:
438: fprintf(stderr,
439: "xmlDumpElementTable: internal: unknown type %d\n",
440: cur->type);
441: }
1.4 daniel 442: }
443: }
444:
445: /**
446: * xmlCreateEnumeration:
447: * @name: the enumeration name or NULL
448: *
449: * create and initialize an enumeration attribute node.
450: *
451: * return values: the xmlEnumerationPtr just created or NULL in case
452: * of error.
453: */
454: xmlEnumerationPtr
455: xmlCreateEnumeration(CHAR *name) {
456: xmlEnumerationPtr ret;
457:
458: ret = (xmlEnumerationPtr) malloc(sizeof(xmlEnumeration));
459: if (ret == NULL) {
460: fprintf(stderr, "xmlCreateEnumeration : malloc(%d) failed\n",
461: sizeof(xmlEnumeration));
462: return(NULL);
463: }
464:
465: if (name != NULL)
466: ret->name = xmlStrdup(name);
467: else
468: ret->name = NULL;
469: ret->next = NULL;
470: return(ret);
471: }
472:
473: /**
474: * xmlFreeEnumeration:
475: * @cur: the tree to free.
476: *
477: * free an enumeration attribute node (recursive).
478: */
479: void
480: xmlFreeEnumeration(xmlEnumerationPtr cur) {
481: if (cur == NULL) return;
482:
483: if (cur->next != NULL) xmlFreeEnumeration(cur->next);
484:
485: if (cur->name != NULL) free((CHAR *) cur->name);
486: memset(cur, -1, sizeof(xmlEnumeration));
487: free(cur);
488: }
489:
490: /**
491: * xmlCopyEnumeration:
492: * @cur: the tree to copy.
493: *
494: * Copy an enumeration attribute node (recursive).
495: *
496: * return values: the xmlEnumerationPtr just created or NULL in case
497: * of error.
498: */
499: xmlEnumerationPtr
500: xmlCopyEnumeration(xmlEnumerationPtr cur) {
501: xmlEnumerationPtr ret;
502:
503: if (cur == NULL) return(NULL);
504: ret = xmlCreateEnumeration((CHAR *) cur->name);
505:
506: if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
507: else ret->next = NULL;
508:
509: return(ret);
510: }
511:
512: /**
513: * xmlCreateAttributeTable:
514: *
515: * create and initialize an empty attribute hash table.
516: *
517: * return values: the xmlAttributeTablePtr just created or NULL in case
518: * of error.
519: */
520: xmlAttributeTablePtr
521: xmlCreateAttributeTable(void) {
522: xmlAttributeTablePtr ret;
523:
524: ret = (xmlAttributeTablePtr)
525: malloc(sizeof(xmlAttributeTable));
526: if (ret == NULL) {
527: fprintf(stderr, "xmlCreateAttributeTable : malloc(%d) failed\n",
528: sizeof(xmlAttributeTable));
529: return(NULL);
530: }
531: ret->max_attributes = XML_MIN_ATTRIBUTE_TABLE;
532: ret->nb_attributes = 0;
533: ret->table = (xmlAttributePtr )
534: malloc(ret->max_attributes * sizeof(xmlAttribute));
535: if (ret == NULL) {
536: fprintf(stderr, "xmlCreateAttributeTable : malloc(%d) failed\n",
537: ret->max_attributes * sizeof(xmlAttribute));
538: free(ret);
539: return(NULL);
540: }
541: return(ret);
542: }
543:
544:
545: /**
546: * xmlAddAttributeDecl:
547: * @name: the entity name
548: *
549: * Register a new attribute declaration
550: *
551: * return values: NULL if not, othervise the entity
552: */
553: xmlAttributePtr
554: xmlAddAttributeDecl(xmlDtdPtr dtd, CHAR *elem, CHAR *name, int type, int def,
555: CHAR *defaultValue, xmlEnumerationPtr tree) {
556: xmlAttributePtr ret, cur;
557: xmlAttributeTablePtr table;
558: int i;
559:
560: if (dtd == NULL) {
561: fprintf(stderr, "xmlAddAttributeDecl: dtd == NULL\n");
562: return(NULL);
563: }
564: if (name == NULL) {
565: fprintf(stderr, "xmlAddAttributeDecl: name == NULL\n");
566: return(NULL);
567: }
568: if (elem == NULL) {
569: fprintf(stderr, "xmlAddAttributeDecl: elem == NULL\n");
570: return(NULL);
571: }
572: /* TODO: Lacks verifications !!! */
573: switch (type) {
574: case XML_ATTRIBUTE_CDATA:
575: break;
576: case XML_ATTRIBUTE_ID:
577: break;
578: case XML_ATTRIBUTE_IDREF:
579: break;
580: case XML_ATTRIBUTE_IDREFS:
581: break;
582: case XML_ATTRIBUTE_ENTITY:
583: break;
584: case XML_ATTRIBUTE_ENTITIES:
585: break;
586: case XML_ATTRIBUTE_NMTOKEN:
587: break;
588: case XML_ATTRIBUTE_NMTOKENS:
589: break;
590: case XML_ATTRIBUTE_ENUMERATION:
591: break;
592: case XML_ATTRIBUTE_NOTATION:
593: break;
594: default:
595: fprintf(stderr, "xmlAddAttributeDecl: unknown type %d\n", type);
596: return(NULL);
597: }
598:
599: /*
600: * Create the Attribute table if needed.
601: */
602: table = dtd->attributes;
603: if (table == NULL)
604: table = dtd->attributes = xmlCreateAttributeTable();
605: if (table == NULL) {
606: fprintf(stderr, "xmlAddAttributeDecl: Table creation failed!\n");
607: return(NULL);
608: }
609:
610: /*
611: * Validity Check:
612: * Search the DTD for previous declarations of the ATTLIST
613: */
614: for (i = 0;i < table->nb_attributes;i++) {
615: cur = &table->table[i];
616: if ((!xmlStrcmp(cur->name, name)) && (!xmlStrcmp(cur->elem, elem))) {
617: /*
618: * The attribute is already defined in this Dtd.
619: */
620: fprintf(stderr,
621: "xmlAddAttributeDecl: %s already defined\n", name);
622: }
623: }
624:
625: /*
626: * Grow the table, if needed.
627: */
628: if (table->nb_attributes >= table->max_attributes) {
629: /*
630: * need more attributes.
631: */
632: table->max_attributes *= 2;
633: table->table = (xmlAttributePtr)
634: realloc(table->table, table->max_attributes * sizeof(xmlAttribute));
635: if (table->table) {
636: fprintf(stderr, "xmlAddAttributeDecl: out of memory\n");
637: return(NULL);
638: }
639: }
640: ret = &table->table[table->nb_attributes];
641:
642: /*
643: * fill the structure.
644: */
645: ret->type = type;
646: ret->name = xmlStrdup(name);
647: ret->elem = xmlStrdup(elem);
648: ret->def = def;
649: ret->tree = tree;
650: if (defaultValue != NULL)
651: ret->defaultValue = xmlStrdup(defaultValue);
652: else
653: ret->defaultValue = NULL;
654: table->nb_attributes++;
655:
656: return(ret);
657: }
658:
659: /**
660: * xmlFreeAttribute:
661: * @elem: An attribute
662: *
663: * Deallocate the memory used by an attribute definition
664: */
665: void
666: xmlFreeAttribute(xmlAttributePtr attr) {
667: if (attr == NULL) return;
668: if (attr->tree != NULL)
669: xmlFreeEnumeration(attr->tree);
670: if (attr->elem != NULL)
671: free((CHAR *) attr->elem);
672: if (attr->name != NULL)
673: free((CHAR *) attr->name);
674: if (attr->defaultValue != NULL)
675: free((CHAR *) attr->defaultValue);
676: memset(attr, -1, sizeof(xmlAttribute));
677: }
678:
679: /**
680: * xmlFreeAttributeTable:
681: * @table: An attribute table
682: *
683: * Deallocate the memory used by an entities hash table.
684: */
685: void
686: xmlFreeAttributeTable(xmlAttributeTablePtr table) {
687: int i;
688:
689: if (table == NULL) return;
690:
691: for (i = 0;i < table->nb_attributes;i++) {
692: xmlFreeAttribute(&table->table[i]);
693: }
694: free(table->table);
695: free(table);
696: }
697:
698: /**
699: * xmlCopyAttributeTable:
700: * @table: An attribute table
701: *
702: * Build a copy of an attribute table.
703: *
704: * return values: the new xmlAttributeTablePtr or NULL in case of error.
705: */
706: xmlAttributeTablePtr
707: xmlCopyAttributeTable(xmlAttributeTablePtr table) {
708: xmlAttributeTablePtr ret;
709: xmlAttributePtr cur, attr;
710: int i;
711:
712: ret = (xmlAttributeTablePtr) malloc(sizeof(xmlAttributeTable));
713: if (ret == NULL) {
714: fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
715: return(NULL);
716: }
717: ret->table = (xmlAttributePtr) malloc(table->max_attributes *
718: sizeof(xmlAttribute));
719: if (ret->table == NULL) {
720: fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n");
721: free(ret);
722: return(NULL);
723: }
724: ret->max_attributes = table->max_attributes;
725: ret->nb_attributes = table->nb_attributes;
726: for (i = 0;i < ret->nb_attributes;i++) {
727: cur = &ret->table[i];
728: attr = &table->table[i];
729: cur->type = attr->type;
730: cur->def = attr->def;
731: cur->tree = xmlCopyEnumeration(attr->tree);
732: if (attr->elem != NULL)
733: cur->elem = xmlStrdup(attr->elem);
734: else
735: cur->elem = NULL;
736: if (attr->name != NULL)
737: cur->name = xmlStrdup(attr->name);
738: else
739: cur->name = NULL;
740: if (attr->defaultValue != NULL)
741: cur->defaultValue = xmlStrdup(attr->defaultValue);
742: else
743: cur->defaultValue = NULL;
744: }
745: return(ret);
746: }
747:
748: /**
749: * xmlDumpAttributeTable:
750: * @table: An attribute table
751: *
752: * This will dump the content of the attribute table as an XML DTD definition
753: *
754: * NOTE: TODO an extra parameter allowing a reentant implementation will
755: * be added.
756: */
757: void
758: xmlDumpAttributeTable(xmlAttributeTablePtr table) {
759: int i;
760: xmlAttributePtr cur;
761:
762: if (table == NULL) return;
763:
764: for (i = 0;i < table->nb_attributes;i++) {
765: cur = &table->table[i];
766: xmlBufferWriteChar("<!ATTLIST ");
767: xmlBufferWriteCHAR(cur->elem);
768: xmlBufferWriteChar(" ");
769: xmlBufferWriteCHAR(cur->name);
770: switch (cur->type) {
771: case XML_ATTRIBUTE_CDATA:
772: xmlBufferWriteChar(" CDATA");
773: break;
774: case XML_ATTRIBUTE_ID:
775: xmlBufferWriteChar(" ID");
776: break;
777: case XML_ATTRIBUTE_IDREF:
778: xmlBufferWriteChar(" IDREF");
779: break;
780: case XML_ATTRIBUTE_IDREFS:
781: xmlBufferWriteChar(" IDREFS");
782: break;
783: case XML_ATTRIBUTE_ENTITY:
784: xmlBufferWriteChar(" ENTITY");
785: break;
786: case XML_ATTRIBUTE_ENTITIES:
787: xmlBufferWriteChar(" ENTITIES");
788: break;
789: case XML_ATTRIBUTE_NMTOKEN:
790: xmlBufferWriteChar(" NMTOKEN");
791: break;
792: case XML_ATTRIBUTE_NMTOKENS:
793: xmlBufferWriteChar(" NMTOKENS");
794: break;
795: case XML_ATTRIBUTE_ENUMERATION:
796: xmlBufferWriteChar(" (pbm)");
797: break;
798: case XML_ATTRIBUTE_NOTATION:
799: xmlBufferWriteChar(" NOTATION (pbm)");
800: break;
801: default:
802: fprintf(stderr,
803: "xmlDumpAttributeTable: internal: unknown type %d\n",
804: cur->type);
805: }
806: switch (cur->def) {
807: case XML_ATTRIBUTE_NONE:
808: break;
809: case XML_ATTRIBUTE_REQUIRED:
810: xmlBufferWriteChar(" #REQUIRED");
811: break;
812: case XML_ATTRIBUTE_IMPLIED:
813: xmlBufferWriteChar(" #IMPLIED");
814: break;
815: case XML_ATTRIBUTE_FIXED:
816: xmlBufferWriteChar(" #FIXED \"");
817: xmlBufferWriteCHAR(cur->defaultValue);
818: xmlBufferWriteChar("\"");
819: break;
820: default:
821: fprintf(stderr,
822: "xmlDumpAttributeTable: internal: unknown default %d\n",
823: cur->def);
824: }
825: xmlBufferWriteChar(">\n");
1.5 ! daniel 826: }
! 827: }
! 828:
! 829: /************************************************************************
! 830: * *
! 831: * NOTATIONs *
! 832: * *
! 833: ************************************************************************/
! 834: /**
! 835: * xmlCreateNotationTable:
! 836: *
! 837: * create and initialize an empty notation hash table.
! 838: *
! 839: * return values: the xmlNotationTablePtr just created or NULL in case
! 840: * of error.
! 841: */
! 842: xmlNotationTablePtr
! 843: xmlCreateNotationTable(void) {
! 844: xmlNotationTablePtr ret;
! 845:
! 846: ret = (xmlNotationTablePtr)
! 847: malloc(sizeof(xmlNotationTable));
! 848: if (ret == NULL) {
! 849: fprintf(stderr, "xmlCreateNotationTable : malloc(%d) failed\n",
! 850: sizeof(xmlNotationTable));
! 851: return(NULL);
! 852: }
! 853: ret->max_notations = XML_MIN_NOTATION_TABLE;
! 854: ret->nb_notations = 0;
! 855: ret->table = (xmlNotationPtr )
! 856: malloc(ret->max_notations * sizeof(xmlNotation));
! 857: if (ret == NULL) {
! 858: fprintf(stderr, "xmlCreateNotationTable : malloc(%d) failed\n",
! 859: ret->max_notations * sizeof(xmlNotation));
! 860: free(ret);
! 861: return(NULL);
! 862: }
! 863: return(ret);
! 864: }
! 865:
! 866:
! 867: /**
! 868: * xmlAddNotationDecl:
! 869: * @name: the entity name
! 870: *
! 871: * Register a new notation declaration
! 872: *
! 873: * return values: NULL if not, othervise the entity
! 874: */
! 875: xmlNotationPtr
! 876: xmlAddNotationDecl(xmlDtdPtr dtd, CHAR *name, CHAR *PublicID, CHAR *SystemID) {
! 877: xmlNotationPtr ret, cur;
! 878: xmlNotationTablePtr table;
! 879: int i;
! 880:
! 881: if (dtd == NULL) {
! 882: fprintf(stderr, "xmlAddNotationDecl: dtd == NULL\n");
! 883: return(NULL);
! 884: }
! 885: if (name == NULL) {
! 886: fprintf(stderr, "xmlAddNotationDecl: name == NULL\n");
! 887: return(NULL);
! 888: }
! 889: if ((PublicID == NULL) && (SystemID == NULL)) {
! 890: fprintf(stderr, "xmlAddNotationDecl: no PUBLIC ID nor SYSTEM ID\n");
! 891: }
! 892:
! 893: /*
! 894: * Create the Notation table if needed.
! 895: */
! 896: table = dtd->notations;
! 897: if (table == NULL)
! 898: table = dtd->notations = xmlCreateNotationTable();
! 899: if (table == NULL) {
! 900: fprintf(stderr, "xmlAddNotationDecl: Table creation failed!\n");
! 901: return(NULL);
! 902: }
! 903:
! 904: /*
! 905: * Validity Check:
! 906: * Search the DTD for previous declarations of the ATTLIST
! 907: */
! 908: for (i = 0;i < table->nb_notations;i++) {
! 909: cur = &table->table[i];
! 910: if (!xmlStrcmp(cur->name, name)) {
! 911: /*
! 912: * The notation is already defined in this Dtd.
! 913: */
! 914: fprintf(stderr,
! 915: "xmlAddNotationDecl: %s already defined\n", name);
! 916: }
! 917: }
! 918:
! 919: /*
! 920: * Grow the table, if needed.
! 921: */
! 922: if (table->nb_notations >= table->max_notations) {
! 923: /*
! 924: * need more notations.
! 925: */
! 926: table->max_notations *= 2;
! 927: table->table = (xmlNotationPtr)
! 928: realloc(table->table, table->max_notations * sizeof(xmlNotation));
! 929: if (table->table) {
! 930: fprintf(stderr, "xmlAddNotationDecl: out of memory\n");
! 931: return(NULL);
! 932: }
! 933: }
! 934: ret = &table->table[table->nb_notations];
! 935:
! 936: /*
! 937: * fill the structure.
! 938: */
! 939: ret->name = xmlStrdup(name);
! 940: if (SystemID != NULL)
! 941: ret->SystemID = xmlStrdup(SystemID);
! 942: else
! 943: ret->SystemID = NULL;
! 944: if (PublicID != NULL)
! 945: ret->PublicID = xmlStrdup(PublicID);
! 946: else
! 947: ret->PublicID = NULL;
! 948: table->nb_notations++;
! 949:
! 950: return(ret);
! 951: }
! 952:
! 953: /**
! 954: * xmlFreeNotation:
! 955: * @not: A notation
! 956: *
! 957: * Deallocate the memory used by an notation definition
! 958: */
! 959: void
! 960: xmlFreeNotation(xmlNotationPtr nota) {
! 961: if (nota == NULL) return;
! 962: if (nota->name != NULL)
! 963: free((CHAR *) nota->name);
! 964: if (nota->PublicID != NULL)
! 965: free((CHAR *) nota->PublicID);
! 966: if (nota->SystemID != NULL)
! 967: free((CHAR *) nota->SystemID);
! 968: memset(nota, -1, sizeof(xmlNotation));
! 969: }
! 970:
! 971: /**
! 972: * xmlFreeNotationTable:
! 973: * @table: An notation table
! 974: *
! 975: * Deallocate the memory used by an entities hash table.
! 976: */
! 977: void
! 978: xmlFreeNotationTable(xmlNotationTablePtr table) {
! 979: int i;
! 980:
! 981: if (table == NULL) return;
! 982:
! 983: for (i = 0;i < table->nb_notations;i++) {
! 984: xmlFreeNotation(&table->table[i]);
! 985: }
! 986: free(table->table);
! 987: free(table);
! 988: }
! 989:
! 990: /**
! 991: * xmlCopyNotationTable:
! 992: * @table: A notation table
! 993: *
! 994: * Build a copy of a notation table.
! 995: *
! 996: * return values: the new xmlNotationTablePtr or NULL in case of error.
! 997: */
! 998: xmlNotationTablePtr
! 999: xmlCopyNotationTable(xmlNotationTablePtr table) {
! 1000: xmlNotationTablePtr ret;
! 1001: xmlNotationPtr cur, nota;
! 1002: int i;
! 1003:
! 1004: ret = (xmlNotationTablePtr) malloc(sizeof(xmlNotationTable));
! 1005: if (ret == NULL) {
! 1006: fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
! 1007: return(NULL);
! 1008: }
! 1009: ret->table = (xmlNotationPtr) malloc(table->max_notations *
! 1010: sizeof(xmlNotation));
! 1011: if (ret->table == NULL) {
! 1012: fprintf(stderr, "xmlCopyNotationTable: out of memory !\n");
! 1013: free(ret);
! 1014: return(NULL);
! 1015: }
! 1016: ret->max_notations = table->max_notations;
! 1017: ret->nb_notations = table->nb_notations;
! 1018: for (i = 0;i < ret->nb_notations;i++) {
! 1019: cur = &ret->table[i];
! 1020: nota = &table->table[i];
! 1021: if (nota->name != NULL)
! 1022: cur->name = xmlStrdup(nota->name);
! 1023: else
! 1024: cur->name = NULL;
! 1025: if (nota->PublicID != NULL)
! 1026: cur->PublicID = xmlStrdup(nota->PublicID);
! 1027: else
! 1028: cur->PublicID = NULL;
! 1029: if (nota->SystemID != NULL)
! 1030: cur->SystemID = xmlStrdup(nota->SystemID);
! 1031: else
! 1032: cur->SystemID = NULL;
! 1033: }
! 1034: return(ret);
! 1035: }
! 1036:
! 1037: /**
! 1038: * xmlDumpNotationTable:
! 1039: * @table: A notation table
! 1040: *
! 1041: * This will dump the content of the notation table as an XML DTD definition
! 1042: *
! 1043: * NOTE: TODO an extra parameter allowing a reentant implementation will
! 1044: * be added.
! 1045: */
! 1046: void
! 1047: xmlDumpNotationTable(xmlNotationTablePtr table) {
! 1048: int i;
! 1049: xmlNotationPtr cur;
! 1050:
! 1051: if (table == NULL) return;
! 1052:
! 1053: for (i = 0;i < table->nb_notations;i++) {
! 1054: cur = &table->table[i];
! 1055: xmlBufferWriteChar("<!NOTATION ");
! 1056: xmlBufferWriteCHAR(cur->name);
! 1057: if (cur->PublicID != NULL) {
! 1058: xmlBufferWriteChar(" PUBLIC \"");
! 1059: xmlBufferWriteCHAR(cur->PublicID);
! 1060: xmlBufferWriteChar("\"");
! 1061: if (cur->SystemID != NULL) {
! 1062: xmlBufferWriteChar(" ");
! 1063: xmlBufferWriteCHAR(cur->SystemID);
! 1064: }
! 1065: } else {
! 1066: xmlBufferWriteChar(" SYSTEM ");
! 1067: xmlBufferWriteCHAR(cur->SystemID);
! 1068: }
! 1069: xmlBufferWriteChar(" >\n");
1.2 daniel 1070: }
1071: }
Webmaster