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