Annotation of XML/entities.c, revision 1.29
1.1 httpng 1: /*
2: * entities.c : implementation for the XML entities handking
1.9 veillard 3: *
4: * See Copyright for the status of this software.
5: *
1.23 daniel 6: * Daniel.Veillard@w3.org
1.1 httpng 7: */
8:
9: #include <stdio.h>
1.17 daniel 10: #include <stdlib.h>
1.10 daniel 11: #include <string.h>
1.1 httpng 12: #include "entities.h"
13:
14: /*
1.15 daniel 15: * The XML predefined entities.
16: */
17:
18: struct xmlPredefinedEntityValue {
19: const char *name;
20: const char *value;
21: };
22: struct xmlPredefinedEntityValue xmlPredefinedEntityValues[] = {
23: { "lt", "<" },
24: { "gt", ">" },
25: { "apos", "'" },
26: { "quot", "\"" },
27: { "amp", "&" }
28: };
29:
30: xmlEntitiesTablePtr xmlPredefinedEntities = NULL;
31:
32: /*
1.2 httpng 33: * xmlFreeEntity : clean-up an entity record.
1.1 httpng 34: */
1.2 httpng 35: void xmlFreeEntity(xmlEntityPtr entity) {
36: if (entity == NULL) return;
37:
1.11 daniel 38: if (entity->name != NULL)
39: free((char *) entity->name);
1.14 daniel 40: if (entity->ExternalID != NULL)
41: free((char *) entity->ExternalID);
42: if (entity->SystemID != NULL)
43: free((char *) entity->SystemID);
44: if (entity->content != NULL)
45: free((char *) entity->content);
1.27 daniel 46: if (entity->orig != NULL)
47: free((char *) entity->orig);
1.14 daniel 48: memset(entity, -1, sizeof(xmlEntity));
1.2 httpng 49: }
1.1 httpng 50:
51: /*
1.22 daniel 52: * xmlAddEntity : register a new entity for an entities table.
1.13 daniel 53: *
54: * TODO !!! We should check here that the combination of type
55: * ExternalID and SystemID is valid.
1.1 httpng 56: */
1.22 daniel 57: static void
58: xmlAddEntity(xmlEntitiesTablePtr table, const CHAR *name, int type,
1.13 daniel 59: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.2 httpng 60: int i;
61: xmlEntityPtr cur;
1.14 daniel 62: int len;
1.1 httpng 63:
1.2 httpng 64: for (i = 0;i < table->nb_entities;i++) {
65: cur = &table->table[i];
1.11 daniel 66: if (!xmlStrcmp(cur->name, name)) {
1.13 daniel 67: /*
68: * The entity is already defined in this Dtd, the spec says to NOT
69: * override it ... Is it worth a Warning ??? !!!
70: */
71: return;
1.7 veillard 72: }
1.2 httpng 73: }
74: if (table->nb_entities >= table->max_entities) {
75: /*
76: * need more elements.
77: */
78: table->max_entities *= 2;
79: table->table = (xmlEntityPtr)
80: realloc(table->table, table->max_entities * sizeof(xmlEntity));
1.29 ! daniel 81: if (table->table == NULL) {
1.2 httpng 82: perror("realloc failed");
1.29 ! daniel 83: return;
1.2 httpng 84: }
85: }
86: cur = &table->table[table->nb_entities];
1.11 daniel 87: cur->name = xmlStrdup(name);
1.14 daniel 88: for (len = 0;name[0] != 0;name++)len++;
89: cur->len = len;
1.13 daniel 90: cur->type = type;
91: if (ExternalID != NULL)
92: cur->ExternalID = xmlStrdup(ExternalID);
1.14 daniel 93: else
94: cur->ExternalID = NULL;
1.13 daniel 95: if (SystemID != NULL)
1.14 daniel 96: cur->SystemID = xmlStrdup(SystemID);
97: else
98: cur->SystemID = NULL;
1.13 daniel 99: if (content != NULL)
100: cur->content = xmlStrdup(content);
1.14 daniel 101: else
102: cur->content = NULL;
1.27 daniel 103: cur->orig = NULL;
1.2 httpng 104: table->nb_entities++;
105: }
1.1 httpng 106:
1.22 daniel 107: /**
108: * xmlInitializePredefinedEntities:
109: *
110: * Set up the predefined entities.
1.15 daniel 111: */
112: void xmlInitializePredefinedEntities(void) {
113: int i;
114: CHAR name[50];
115: CHAR value[50];
116: const char *in;
117: CHAR *out;
118:
119: if (xmlPredefinedEntities != NULL) return;
120:
121: xmlPredefinedEntities = xmlCreateEntitiesTable();
122: for (i = 0;i < sizeof(xmlPredefinedEntityValues) /
123: sizeof(xmlPredefinedEntityValues[0]);i++) {
124: in = xmlPredefinedEntityValues[i].name;
125: out = &name[0];
126: for (;(*out++ = (CHAR) *in);)in++;
127: in = xmlPredefinedEntityValues[i].value;
128: out = &value[0];
129: for (;(*out++ = (CHAR) *in);)in++;
130: xmlAddEntity(xmlPredefinedEntities, (const CHAR *) &name[0],
1.18 daniel 131: XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL,
1.15 daniel 132: &value[0]);
133: }
134: }
1.17 daniel 135:
136: /**
137: * xmlGetPredefinedEntity:
138: * @name: the entity name
139: *
140: * Check whether this name is an predefined entity.
141: *
1.24 daniel 142: * Returns NULL if not, othervise the entity
1.17 daniel 143: */
144: xmlEntityPtr
145: xmlGetPredefinedEntity(const CHAR *name) {
146: int i;
147: xmlEntityPtr cur;
148:
149: if (xmlPredefinedEntities == NULL)
150: xmlInitializePredefinedEntities();
151: for (i = 0;i < xmlPredefinedEntities->nb_entities;i++) {
152: cur = &xmlPredefinedEntities->table[i];
153: if (!xmlStrcmp(cur->name, name)) return(cur);
154: }
155: return(NULL);
156: }
157:
1.22 daniel 158: /**
159: * xmlAddDtdEntity:
160: * @doc: the document
161: * @name: the entity name
162: * @type: the entity type XML_xxx_yyy_ENTITY
163: * @ExternalID: the entity external ID if available
164: * @SystemID: the entity system ID if available
165: * @content: the entity content
166: *
167: * Register a new entity for this document DTD.
1.1 httpng 168: */
1.22 daniel 169: void
170: xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
1.13 daniel 171: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.2 httpng 172: xmlEntitiesTablePtr table;
1.1 httpng 173:
1.22 daniel 174: if (doc->extSubset == NULL) {
175: fprintf(stderr,
176: "xmlAddDtdEntity: document without external subset !\n");
1.16 daniel 177: return;
178: }
1.22 daniel 179: table = (xmlEntitiesTablePtr) doc->extSubset->entities;
1.2 httpng 180: if (table == NULL) {
181: table = xmlCreateEntitiesTable();
1.22 daniel 182: doc->extSubset->entities = table;
1.1 httpng 183: }
1.13 daniel 184: xmlAddEntity(table, name, type, ExternalID, SystemID, content);
1.1 httpng 185: }
186:
1.22 daniel 187: /**
188: * xmlAddDocEntity:
189: * @doc: the document
190: * @name: the entity name
191: * @type: the entity type XML_xxx_yyy_ENTITY
192: * @ExternalID: the entity external ID if available
193: * @SystemID: the entity system ID if available
194: * @content: the entity content
195: *
196: * Register a new entity for this document.
1.1 httpng 197: */
1.22 daniel 198: void
199: xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
1.13 daniel 200: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.16 daniel 201: xmlEntitiesTablePtr table;
202:
1.22 daniel 203: if (doc == NULL) {
204: fprintf(stderr,
205: "xmlAddDocEntity: document is NULL !\n");
206: return;
207: }
208: if (doc->intSubset == NULL) {
209: fprintf(stderr,
210: "xmlAddDtdEntity: document without internal subset !\n");
211: return;
212: }
213: table = (xmlEntitiesTablePtr) doc->intSubset->entities;
1.16 daniel 214: if (table == NULL) {
215: table = xmlCreateEntitiesTable();
1.22 daniel 216: doc->intSubset->entities = table;
1.2 httpng 217: }
1.22 daniel 218: xmlAddEntity(table, name, type, ExternalID, SystemID, content);
1.1 httpng 219: }
220:
1.22 daniel 221: /**
222: * xmlGetDtdEntity:
223: * @doc: the document referencing the entity
224: * @name: the entity name
225: *
226: * Do an entity lookup in the Dtd entity hash table and
227: * returns the corresponding entity, if found.
228: *
1.24 daniel 229: * Returns A pointer to the entity structure or NULL if not found.
1.1 httpng 230: */
1.22 daniel 231: xmlEntityPtr
232: xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name) {
1.2 httpng 233: int i;
234: xmlEntityPtr cur;
235: xmlEntitiesTablePtr table;
236:
1.22 daniel 237: if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
238: table = (xmlEntitiesTablePtr) doc->extSubset->entities;
1.15 daniel 239: for (i = 0;i < table->nb_entities;i++) {
240: cur = &table->table[i];
241: if (!xmlStrcmp(cur->name, name)) return(cur);
242: }
243: }
1.7 veillard 244: return(NULL);
1.3 httpng 245: }
246:
1.22 daniel 247: /**
248: * xmlGetDocEntity:
249: * @doc: the document referencing the entity
250: * @name: the entity name
251: *
252: * Do an entity lookup in the document entity hash table and
253: * returns the corrsponding entity, otherwise a lookup is done
254: * in the predefined entities too.
255: *
1.24 daniel 256: * Returns A pointer to the entity structure or NULL if not found.
1.14 daniel 257: */
1.22 daniel 258: xmlEntityPtr
259: xmlGetDocEntity(xmlDocPtr doc, const CHAR *name) {
1.14 daniel 260: int i;
1.16 daniel 261: xmlEntityPtr cur;
1.14 daniel 262: xmlEntitiesTablePtr table;
263:
1.22 daniel 264: if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
265: table = (xmlEntitiesTablePtr) doc->intSubset->entities;
1.16 daniel 266: for (i = 0;i < table->nb_entities;i++) {
267: cur = &table->table[i];
268: if (!xmlStrcmp(cur->name, name)) return(cur);
269: }
270: }
1.15 daniel 271: if (xmlPredefinedEntities == NULL)
272: xmlInitializePredefinedEntities();
1.16 daniel 273: table = xmlPredefinedEntities;
274: for (i = 0;i < table->nb_entities;i++) {
275: cur = &table->table[i];
276: if (!xmlStrcmp(cur->name, name)) return(cur);
1.14 daniel 277: }
278:
279: return(NULL);
1.1 httpng 280: }
281:
282: /*
1.21 daniel 283: * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
284: * | [#x10000-#x10FFFF]
285: * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
286: */
287: #define IS_CHAR(c) \
288: (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || \
289: (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
290:
1.28 daniel 291: /*
292: * A buffer used for converting entities to their equivalent and back.
293: *
294: * TODO: remove this, this helps performances but forbid reentrancy in a
295: * stupid way.
296: */
297: static int buffer_size = 0;
298: static CHAR *buffer = NULL;
299:
300: void growBuffer(void) {
301: buffer_size *= 2;
302: buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
303: if (buffer == NULL) {
304: perror("realloc failed");
305: exit(1);
306: }
307: }
308:
309:
1.22 daniel 310: /**
311: * xmlEncodeEntities:
312: * @doc: the document containing the string
313: * @input: A string to convert to XML.
314: *
315: * Do a global encoding of a string, replacing the predefined entities
316: * and non ASCII values with their entities and CharRef counterparts.
317: *
1.19 daniel 318: * TODO !!!! Once moved to UTF-8 internal encoding, the encoding of non-ascii
319: * get erroneous.
1.22 daniel 320: *
1.28 daniel 321: * TODO This routine is not reentrant, the interface
322: * should not be modified though.
323: *
324: * People must migrate their code to xmlEncodeEntitiesReentrant !
325: *
326: * Returns A newly allocated string with the substitution done.
327: */
328: const CHAR *
329: xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) {
330: const CHAR *cur = input;
331: CHAR *out = buffer;
332:
333: if (input == NULL) return(NULL);
334: if (buffer == NULL) {
335: buffer_size = 1000;
336: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
337: if (buffer == NULL) {
338: perror("malloc failed");
339: exit(1);
340: }
341: out = buffer;
342: }
343: while (*cur != '\0') {
344: if (out - buffer > buffer_size - 100) {
345: int index = out - buffer;
346:
347: growBuffer();
348: out = &buffer[index];
349: }
350:
351: /*
352: * By default one have to encode at least '<', '>', '"' and '&' !
353: */
354: if (*cur == '<') {
355: *out++ = '&';
356: *out++ = 'l';
357: *out++ = 't';
358: *out++ = ';';
359: } else if (*cur == '>') {
360: *out++ = '&';
361: *out++ = 'g';
362: *out++ = 't';
363: *out++ = ';';
364: } else if (*cur == '&') {
365: *out++ = '&';
366: *out++ = 'a';
367: *out++ = 'm';
368: *out++ = 'p';
369: *out++ = ';';
370: } else if (*cur == '"') {
371: *out++ = '&';
372: *out++ = 'q';
373: *out++ = 'u';
374: *out++ = 'o';
375: *out++ = 't';
376: *out++ = ';';
377: } else if (*cur == '\'') {
378: *out++ = '&';
379: *out++ = 'a';
380: *out++ = 'p';
381: *out++ = 'o';
382: *out++ = 's';
383: *out++ = ';';
384: } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
385: (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
386: /*
387: * default case, just copy !
388: */
389: *out++ = *cur;
390: #ifndef USE_UTF_8
391: } else if ((sizeof(CHAR) == 1) && (*cur >= 0x80)) {
392: char buf[10], *ptr;
393: #ifdef HAVE_SNPRINTF
394: snprintf(buf, 9, "&#%d;", *cur);
395: #else
396: sprintf(buf, "&#%d;", *cur);
397: #endif
398: ptr = buf;
399: while (*ptr != 0) *out++ = *ptr++;
400: #endif
401: } else if (IS_CHAR(*cur)) {
402: char buf[10], *ptr;
403:
404: #ifdef HAVE_SNPRINTF
405: snprintf(buf, 9, "&#%d;", *cur);
406: #else
407: sprintf(buf, "&#%d;", *cur);
408: #endif
409: ptr = buf;
410: while (*ptr != 0) *out++ = *ptr++;
411: }
412: #if 0
413: else {
414: /*
415: * default case, this is not a valid char !
416: * Skip it...
417: */
418: fprintf(stderr, "xmlEncodeEntities: invalid char %d\n", (int) *cur);
419: }
420: #endif
421: cur++;
422: }
423: *out++ = 0;
424: return(buffer);
425: }
426:
427: /*
428: * Macro used to grow the current buffer.
429: */
430: #define growBufferReentrant() { \
431: buffer_size *= 2; \
432: buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR)); \
433: if (buffer == NULL) { \
434: perror("realloc failed"); \
435: exit(1); \
436: } \
437: }
438:
439:
440: /**
441: * xmlEncodeEntitiesReentrant:
442: * @doc: the document containing the string
443: * @input: A string to convert to XML.
444: *
445: * Do a global encoding of a string, replacing the predefined entities
446: * and non ASCII values with their entities and CharRef counterparts.
447: * Contrary to xmlEncodeEntities, this routine is reentrant, and result
448: * must be deallocated.
449: *
450: * TODO !!!! Once moved to UTF-8 internal encoding, the encoding of non-ascii
451: * get erroneous.
452: *
1.24 daniel 453: * Returns A newly allocated string with the substitution done.
1.1 httpng 454: */
1.22 daniel 455: CHAR *
1.28 daniel 456: xmlEncodeEntitiesReentrant(xmlDocPtr doc, const CHAR *input) {
1.7 veillard 457: const CHAR *cur = input;
1.26 daniel 458: CHAR *buffer = NULL;
459: CHAR *out = NULL;
460: int buffer_size = 0;
1.3 httpng 461:
1.19 daniel 462: if (input == NULL) return(NULL);
1.26 daniel 463:
464: /*
465: * allocate an translation buffer.
466: */
467: buffer_size = 1000;
468: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
1.3 httpng 469: if (buffer == NULL) {
1.26 daniel 470: perror("malloc failed");
471: exit(1);
1.3 httpng 472: }
1.26 daniel 473: out = buffer;
474:
1.6 veillard 475: while (*cur != '\0') {
476: if (out - buffer > buffer_size - 100) {
477: int index = out - buffer;
478:
1.28 daniel 479: growBufferReentrant();
1.6 veillard 480: out = &buffer[index];
481: }
482:
483: /*
1.7 veillard 484: * By default one have to encode at least '<', '>', '"' and '&' !
1.6 veillard 485: */
486: if (*cur == '<') {
487: *out++ = '&';
488: *out++ = 'l';
489: *out++ = 't';
490: *out++ = ';';
1.7 veillard 491: } else if (*cur == '>') {
492: *out++ = '&';
493: *out++ = 'g';
494: *out++ = 't';
495: *out++ = ';';
1.6 veillard 496: } else if (*cur == '&') {
497: *out++ = '&';
498: *out++ = 'a';
499: *out++ = 'm';
500: *out++ = 'p';
1.7 veillard 501: *out++ = ';';
502: } else if (*cur == '"') {
503: *out++ = '&';
504: *out++ = 'q';
505: *out++ = 'u';
506: *out++ = 'o';
507: *out++ = 't';
508: *out++ = ';';
509: } else if (*cur == '\'') {
510: *out++ = '&';
511: *out++ = 'a';
512: *out++ = 'p';
513: *out++ = 'o';
514: *out++ = 's';
1.6 veillard 515: *out++ = ';';
1.21 daniel 516: } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
517: (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
518: /*
519: * default case, just copy !
520: */
521: *out++ = *cur;
1.19 daniel 522: #ifndef USE_UTF_8
523: } else if ((sizeof(CHAR) == 1) && (*cur >= 0x80)) {
524: char buf[10], *ptr;
525: #ifdef HAVE_SNPRINTF
526: snprintf(buf, 9, "&#%d;", *cur);
527: #else
528: sprintf(buf, "&#%d;", *cur);
529: #endif
530: ptr = buf;
531: while (*ptr != 0) *out++ = *ptr++;
532: #endif
1.21 daniel 533: } else if (IS_CHAR(*cur)) {
1.20 daniel 534: char buf[10], *ptr;
535:
536: #ifdef HAVE_SNPRINTF
537: snprintf(buf, 9, "&#%d;", *cur);
538: #else
539: sprintf(buf, "&#%d;", *cur);
540: #endif
541: ptr = buf;
542: while (*ptr != 0) *out++ = *ptr++;
1.21 daniel 543: }
544: #if 0
545: else {
1.6 veillard 546: /*
1.21 daniel 547: * default case, this is not a valid char !
548: * Skip it...
1.6 veillard 549: */
1.21 daniel 550: fprintf(stderr, "xmlEncodeEntities: invalid char %d\n", (int) *cur);
1.6 veillard 551: }
1.21 daniel 552: #endif
1.6 veillard 553: cur++;
554: }
555: *out++ = 0;
556: return(buffer);
1.2 httpng 557: }
558:
1.22 daniel 559: /**
560: * xmlCreateEntitiesTable:
561: *
562: * create and initialize an empty entities hash table.
563: *
1.24 daniel 564: * Returns the xmlEntitiesTablePtr just created or NULL in case of error.
1.2 httpng 565: */
1.22 daniel 566: xmlEntitiesTablePtr
567: xmlCreateEntitiesTable(void) {
1.2 httpng 568: xmlEntitiesTablePtr ret;
1.1 httpng 569:
1.2 httpng 570: ret = (xmlEntitiesTablePtr)
571: malloc(sizeof(xmlEntitiesTable));
1.1 httpng 572: if (ret == NULL) {
1.28 daniel 573: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%ld) failed\n",
574: (long)sizeof(xmlEntitiesTable));
1.2 httpng 575: return(NULL);
576: }
577: ret->max_entities = XML_MIN_ENTITIES_TABLE;
578: ret->nb_entities = 0;
579: ret->table = (xmlEntityPtr )
580: malloc(ret->max_entities * sizeof(xmlEntity));
581: if (ret == NULL) {
1.28 daniel 582: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%ld) failed\n",
583: ret->max_entities * (long)sizeof(xmlEntity));
1.2 httpng 584: free(ret);
1.1 httpng 585: return(NULL);
586: }
587: return(ret);
588: }
589:
1.22 daniel 590: /**
591: * xmlFreeEntitiesTable:
592: * @table: An entity table
593: *
594: * Deallocate the memory used by an entities hash table.
1.1 httpng 595: */
1.22 daniel 596: void
597: xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
1.1 httpng 598: int i;
599:
600: if (table == NULL) return;
601:
1.2 httpng 602: for (i = 0;i < table->nb_entities;i++) {
603: xmlFreeEntity(&table->table[i]);
1.1 httpng 604: }
1.2 httpng 605: free(table->table);
1.1 httpng 606: free(table);
607: }
608:
1.22 daniel 609: /**
610: * xmlCopyEntitiesTable:
611: * @table: An entity table
612: *
613: * Build a copy of an entity table.
614: *
1.24 daniel 615: * Returns the new xmlEntitiesTablePtr or NULL in case of error.
1.22 daniel 616: */
617: xmlEntitiesTablePtr
618: xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
619: xmlEntitiesTablePtr ret;
620: xmlEntityPtr cur, ent;
621: int i;
622:
623: ret = (xmlEntitiesTablePtr) malloc(sizeof(xmlEntitiesTable));
624: if (ret == NULL) {
625: fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
626: return(NULL);
627: }
628: ret->table = (xmlEntityPtr) malloc(table->max_entities *
629: sizeof(xmlEntity));
630: if (ret->table == NULL) {
631: fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
632: free(ret);
633: return(NULL);
634: }
635: ret->max_entities = table->max_entities;
636: ret->nb_entities = table->nb_entities;
637: for (i = 0;i < ret->nb_entities;i++) {
638: cur = &ret->table[i];
639: ent = &table->table[i];
640: cur->len = ent->len;
641: cur->type = ent->type;
642: if (ent->name != NULL)
643: cur->name = xmlStrdup(ent->name);
644: else
645: cur->name = NULL;
646: if (ent->ExternalID != NULL)
647: cur->ExternalID = xmlStrdup(ent->ExternalID);
648: else
649: cur->ExternalID = NULL;
650: if (ent->SystemID != NULL)
651: cur->SystemID = xmlStrdup(ent->SystemID);
652: else
653: cur->SystemID = NULL;
654: if (ent->content != NULL)
655: cur->content = xmlStrdup(ent->content);
656: else
657: cur->content = NULL;
1.27 daniel 658: if (ent->orig != NULL)
659: cur->orig = xmlStrdup(ent->orig);
660: else
661: cur->orig = NULL;
1.22 daniel 662: }
663: return(ret);
664: }
665:
666: /**
667: * xmlDumpEntitiesTable:
1.25 daniel 668: * @buf: An XML buffer.
1.22 daniel 669: * @table: An entity table
670: *
671: * This will dump the content of the entity table as an XML DTD definition
1.13 daniel 672: */
1.22 daniel 673: void
1.25 daniel 674: xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
1.14 daniel 675: int i;
676: xmlEntityPtr cur;
677:
678: if (table == NULL) return;
679:
680: for (i = 0;i < table->nb_entities;i++) {
681: cur = &table->table[i];
682: switch (cur->type) {
683: case XML_INTERNAL_GENERAL_ENTITY:
1.25 daniel 684: xmlBufferWriteChar(buf, "<!ENTITY ");
685: xmlBufferWriteCHAR(buf, cur->name);
1.27 daniel 686: xmlBufferWriteChar(buf, " ");
687: if (cur->orig != NULL)
688: xmlBufferWriteQuotedString(buf, cur->orig);
689: else
690: xmlBufferWriteQuotedString(buf, cur->content);
691: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 692: break;
693: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
1.25 daniel 694: xmlBufferWriteChar(buf, "<!ENTITY ");
695: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 696: if (cur->ExternalID != NULL) {
1.27 daniel 697: xmlBufferWriteChar(buf, " PUBLIC ");
698: xmlBufferWriteQuotedString(buf, cur->ExternalID);
699: xmlBufferWriteChar(buf, " ");
700: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 701: } else {
1.27 daniel 702: xmlBufferWriteChar(buf, " SYSTEM ");
703: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 704: }
1.25 daniel 705: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 706: break;
707: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
1.25 daniel 708: xmlBufferWriteChar(buf, "<!ENTITY ");
709: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 710: if (cur->ExternalID != NULL) {
1.27 daniel 711: xmlBufferWriteChar(buf, " PUBLIC ");
712: xmlBufferWriteQuotedString(buf, cur->ExternalID);
713: xmlBufferWriteChar(buf, " ");
714: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 715: } else {
1.27 daniel 716: xmlBufferWriteChar(buf, " SYSTEM ");
717: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 718: }
719: if (cur->content != NULL) { /* Should be true ! */
1.25 daniel 720: xmlBufferWriteChar(buf, " NDATA ");
1.27 daniel 721: if (cur->orig != NULL)
722: xmlBufferWriteCHAR(buf, cur->orig);
723: else
724: xmlBufferWriteCHAR(buf, cur->content);
1.14 daniel 725: }
1.25 daniel 726: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 727: break;
728: case XML_INTERNAL_PARAMETER_ENTITY:
1.25 daniel 729: xmlBufferWriteChar(buf, "<!ENTITY % ");
730: xmlBufferWriteCHAR(buf, cur->name);
1.27 daniel 731: xmlBufferWriteChar(buf, " ");
732: if (cur->orig == NULL)
733: xmlBufferWriteQuotedString(buf, cur->content);
734: else
735: xmlBufferWriteQuotedString(buf, cur->orig);
736: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 737: break;
738: case XML_EXTERNAL_PARAMETER_ENTITY:
1.25 daniel 739: xmlBufferWriteChar(buf, "<!ENTITY % ");
740: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 741: if (cur->ExternalID != NULL) {
1.27 daniel 742: xmlBufferWriteChar(buf, " PUBLIC ");
743: xmlBufferWriteQuotedString(buf, cur->ExternalID);
744: xmlBufferWriteChar(buf, " ");
745: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 746: } else {
1.27 daniel 747: xmlBufferWriteChar(buf, " SYSTEM ");
748: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 749: }
1.25 daniel 750: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 751: break;
752: default:
753: fprintf(stderr,
754: "xmlDumpEntitiesTable: internal: unknown type %d\n",
755: cur->type);
756: }
757: }
1.13 daniel 758: }
Webmaster