2 * entities.c : implementation for the XML entities handling
4 * See Copyright for the status of this software.
16 #include <libxml/xmlmemory.h>
17 #include <libxml/hash.h>
18 #include <libxml/entities.h>
19 #include <libxml/parser.h>
20 #include <libxml/xmlerror.h>
21 #include <libxml/globals.h>
24 * The XML predefined entities.
27 struct xmlPredefinedEntityValue {
31 static struct xmlPredefinedEntityValue xmlPredefinedEntityValues[] = {
40 * TODO: This is GROSS, allocation of a 256 entry hash for
41 * a fixed number of 4 elements !
43 static xmlHashTablePtr xmlPredefinedEntities = NULL;
46 * xmlFreeEntity : clean-up an entity record.
48 static void xmlFreeEntity(xmlEntityPtr entity) {
49 if (entity == NULL) return;
51 if ((entity->children) && (entity->owner == 1) &&
52 (entity == (xmlEntityPtr) entity->children->parent))
53 xmlFreeNodeList(entity->children);
54 if (entity->name != NULL)
55 xmlFree((char *) entity->name);
56 if (entity->ExternalID != NULL)
57 xmlFree((char *) entity->ExternalID);
58 if (entity->SystemID != NULL)
59 xmlFree((char *) entity->SystemID);
60 if (entity->URI != NULL)
61 xmlFree((char *) entity->URI);
62 if (entity->content != NULL)
63 xmlFree((char *) entity->content);
64 if (entity->orig != NULL)
65 xmlFree((char *) entity->orig);
70 * xmlAddEntity : register a new entity for an entities table.
73 xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type,
74 const xmlChar *ExternalID, const xmlChar *SystemID,
75 const xmlChar *content) {
76 xmlEntitiesTablePtr table = NULL;
82 case XML_INTERNAL_GENERAL_ENTITY:
83 case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
84 case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
85 if (dtd->entities == NULL)
86 dtd->entities = xmlHashCreate(0);
87 table = dtd->entities;
89 case XML_INTERNAL_PARAMETER_ENTITY:
90 case XML_EXTERNAL_PARAMETER_ENTITY:
91 if (dtd->pentities == NULL)
92 dtd->pentities = xmlHashCreate(0);
93 table = dtd->pentities;
95 case XML_INTERNAL_PREDEFINED_ENTITY:
96 if (xmlPredefinedEntities == NULL)
97 xmlPredefinedEntities = xmlHashCreate(8);
98 table = xmlPredefinedEntities;
102 ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
104 xmlGenericError(xmlGenericErrorContext,
105 "xmlAddEntity: out of memory\n");
108 memset(ret, 0, sizeof(xmlEntity));
109 ret->type = XML_ENTITY_DECL;
112 * fill the structure.
114 ret->name = xmlStrdup(name);
115 ret->etype = (xmlEntityType) type;
116 if (ExternalID != NULL)
117 ret->ExternalID = xmlStrdup(ExternalID);
118 if (SystemID != NULL)
119 ret->SystemID = xmlStrdup(SystemID);
120 if (content != NULL) {
121 ret->length = xmlStrlen(content);
122 ret->content = xmlStrndup(content, ret->length);
127 ret->URI = NULL; /* to be computed by the layer knowing
128 the defining entity */
132 if (xmlHashAddEntry(table, name, ret)) {
134 * entity was already defined at another level.
143 * xmlInitializePredefinedEntities:
145 * Set up the predefined entities.
147 void xmlInitializePredefinedEntities(void) {
154 if (xmlPredefinedEntities != NULL) return;
156 xmlPredefinedEntities = xmlCreateEntitiesTable();
157 for (i = 0;i < sizeof(xmlPredefinedEntityValues) /
158 sizeof(xmlPredefinedEntityValues[0]);i++) {
159 in = xmlPredefinedEntityValues[i].name;
161 for (;(*out++ = (xmlChar) *in);)in++;
162 in = xmlPredefinedEntityValues[i].value;
164 for (;(*out++ = (xmlChar) *in);)in++;
166 xmlAddEntity(NULL, (const xmlChar *) &name[0],
167 XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL,
173 * xmlCleanupPredefinedEntities:
175 * Cleanup up the predefined entities table.
177 void xmlCleanupPredefinedEntities(void) {
178 if (xmlPredefinedEntities == NULL) return;
180 xmlFreeEntitiesTable(xmlPredefinedEntities);
181 xmlPredefinedEntities = NULL;
185 * xmlGetPredefinedEntity:
186 * @name: the entity name
188 * Check whether this name is an predefined entity.
190 * Returns NULL if not, otherwise the entity
193 xmlGetPredefinedEntity(const xmlChar *name) {
194 if (xmlPredefinedEntities == NULL)
195 xmlInitializePredefinedEntities();
196 return((xmlEntityPtr) xmlHashLookup(xmlPredefinedEntities, name));
202 * @name: the entity name
203 * @type: the entity type XML_xxx_yyy_ENTITY
204 * @ExternalID: the entity external ID if available
205 * @SystemID: the entity system ID if available
206 * @content: the entity content
208 * Register a new entity for this document DTD external subset.
210 * Returns a pointer to the entity or NULL in case of error
213 xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type,
214 const xmlChar *ExternalID, const xmlChar *SystemID,
215 const xmlChar *content) {
220 xmlGenericError(xmlGenericErrorContext,
221 "xmlAddDtdEntity: doc == NULL !\n");
224 if (doc->extSubset == NULL) {
225 xmlGenericError(xmlGenericErrorContext,
226 "xmlAddDtdEntity: document without external subset !\n");
229 dtd = doc->extSubset;
230 ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
231 if (ret == NULL) return(NULL);
238 if (dtd->last == NULL) {
239 dtd->children = dtd->last = (xmlNodePtr) ret;
241 dtd->last->next = (xmlNodePtr) ret;
242 ret->prev = dtd->last;
243 dtd->last = (xmlNodePtr) ret;
251 * @name: the entity name
252 * @type: the entity type XML_xxx_yyy_ENTITY
253 * @ExternalID: the entity external ID if available
254 * @SystemID: the entity system ID if available
255 * @content: the entity content
257 * Register a new entity for this document.
259 * Returns a pointer to the entity or NULL in case of error
262 xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type,
263 const xmlChar *ExternalID, const xmlChar *SystemID,
264 const xmlChar *content) {
269 xmlGenericError(xmlGenericErrorContext,
270 "xmlAddDocEntity: document is NULL !\n");
273 if (doc->intSubset == NULL) {
274 xmlGenericError(xmlGenericErrorContext,
275 "xmlAddDocEntity: document without internal subset !\n");
278 dtd = doc->intSubset;
279 ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
280 if (ret == NULL) return(NULL);
287 if (dtd->last == NULL) {
288 dtd->children = dtd->last = (xmlNodePtr) ret;
290 dtd->last->next = (xmlNodePtr) ret;
291 ret->prev = dtd->last;
292 dtd->last = (xmlNodePtr) ret;
298 * xmlGetEntityFromTable:
299 * @table: an entity table
300 * @name: the entity name
301 * @parameter: look for parameter entities
303 * Do an entity lookup in the table.
304 * returns the corresponding parameter entity, if found.
306 * Returns A pointer to the entity structure or NULL if not found.
309 xmlGetEntityFromTable(xmlEntitiesTablePtr table, const xmlChar *name) {
310 return((xmlEntityPtr) xmlHashLookup(table, name));
314 * xmlGetParameterEntity:
315 * @doc: the document referencing the entity
316 * @name: the entity name
318 * Do an entity lookup in the internal and external subsets and
319 * returns the corresponding parameter entity, if found.
321 * Returns A pointer to the entity structure or NULL if not found.
324 xmlGetParameterEntity(xmlDocPtr doc, const xmlChar *name) {
325 xmlEntitiesTablePtr table;
330 if ((doc->intSubset != NULL) && (doc->intSubset->pentities != NULL)) {
331 table = (xmlEntitiesTablePtr) doc->intSubset->pentities;
332 ret = xmlGetEntityFromTable(table, name);
336 if ((doc->extSubset != NULL) && (doc->extSubset->pentities != NULL)) {
337 table = (xmlEntitiesTablePtr) doc->extSubset->pentities;
338 return(xmlGetEntityFromTable(table, name));
345 * @doc: the document referencing the entity
346 * @name: the entity name
348 * Do an entity lookup in the DTD entity hash table and
349 * returns the corresponding entity, if found.
350 * Note: the first argument is the document node, not the DTD node.
352 * Returns A pointer to the entity structure or NULL if not found.
355 xmlGetDtdEntity(xmlDocPtr doc, const xmlChar *name) {
356 xmlEntitiesTablePtr table;
360 if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
361 table = (xmlEntitiesTablePtr) doc->extSubset->entities;
362 return(xmlGetEntityFromTable(table, name));
369 * @doc: the document referencing the entity
370 * @name: the entity name
372 * Do an entity lookup in the document entity hash table and
373 * returns the corresponding entity, otherwise a lookup is done
374 * in the predefined entities too.
376 * Returns A pointer to the entity structure or NULL if not found.
379 xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) {
381 xmlEntitiesTablePtr table;
384 if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
385 table = (xmlEntitiesTablePtr) doc->intSubset->entities;
386 cur = xmlGetEntityFromTable(table, name);
390 if (doc->standalone != 1) {
391 if ((doc->extSubset != NULL) &&
392 (doc->extSubset->entities != NULL)) {
393 table = (xmlEntitiesTablePtr) doc->extSubset->entities;
394 cur = xmlGetEntityFromTable(table, name);
400 if (xmlPredefinedEntities == NULL)
401 xmlInitializePredefinedEntities();
402 table = xmlPredefinedEntities;
403 return(xmlGetEntityFromTable(table, name));
407 * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
408 * | [#x10000-#x10FFFF]
409 * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
412 (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || \
413 (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
416 * A buffer used for converting entities to their equivalent and back.
418 static int static_buffer_size = 0;
419 static xmlChar *static_buffer = NULL;
421 static int growBuffer(void) {
422 static_buffer_size *= 2;
423 static_buffer = (xmlChar *) xmlRealloc(static_buffer,
424 static_buffer_size * sizeof(xmlChar));
425 if (static_buffer == NULL) {
426 xmlGenericError(xmlGenericErrorContext, "malloc failed\n");
435 * @doc: the document containing the string
436 * @input: A string to convert to XML.
438 * Do a global encoding of a string, replacing the predefined entities
439 * and non ASCII values with their entities and CharRef counterparts.
441 * TODO: remove xmlEncodeEntities, once we are not afraid of breaking binary
444 * People must migrate their code to xmlEncodeEntitiesReentrant !
445 * This routine will issue a warning when encountered.
447 * Returns A newly allocated string with the substitution done.
450 xmlEncodeEntities(xmlDocPtr doc, const xmlChar *input) {
451 const xmlChar *cur = input;
452 xmlChar *out = static_buffer;
453 static int warning = 1;
458 xmlGenericError(xmlGenericErrorContext,
459 "Deprecated API xmlEncodeEntities() used\n");
460 xmlGenericError(xmlGenericErrorContext,
461 " change code to use xmlEncodeEntitiesReentrant()\n");
465 if (input == NULL) return(NULL);
467 html = (doc->type == XML_HTML_DOCUMENT_NODE);
469 if (static_buffer == NULL) {
470 static_buffer_size = 1000;
471 static_buffer = (xmlChar *)
472 xmlMalloc(static_buffer_size * sizeof(xmlChar));
473 if (static_buffer == NULL) {
474 xmlGenericError(xmlGenericErrorContext, "malloc failed\n");
479 while (*cur != '\0') {
480 if (out - static_buffer > static_buffer_size - 100) {
481 int indx = out - static_buffer;
484 out = &static_buffer[indx];
488 * By default one have to encode at least '<', '>', '"' and '&' !
495 } else if (*cur == '>') {
500 } else if (*cur == '&') {
506 } else if (*cur == '"') {
513 } else if ((*cur == '\'') && (!html)) {
520 } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
521 (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
523 * default case, just copy !
527 } else if ((sizeof(xmlChar) == 1) && (*cur >= 0x80)) {
530 snprintf(buf, sizeof(buf), "&#%d;", *cur);
531 buf[sizeof(buf) - 1] = 0;
533 while (*ptr != 0) *out++ = *ptr++;
535 } else if (IS_CHAR((unsigned int) *cur)) {
538 snprintf(buf, sizeof(buf), "&#%d;", *cur);
539 buf[sizeof(buf) - 1] = 0;
541 while (*ptr != 0) *out++ = *ptr++;
546 * default case, this is not a valid char !
549 xmlGenericError(xmlGenericErrorContext,
550 "xmlEncodeEntities: invalid char %d\n", (int) *cur);
556 return(static_buffer);
560 * Macro used to grow the current buffer.
562 #define growBufferReentrant() { \
564 buffer = (xmlChar *) \
565 xmlRealloc(buffer, buffer_size * sizeof(xmlChar)); \
566 if (buffer == NULL) { \
567 xmlGenericError(xmlGenericErrorContext, "realloc failed\n"); \
574 * xmlEncodeEntitiesReentrant:
575 * @doc: the document containing the string
576 * @input: A string to convert to XML.
578 * Do a global encoding of a string, replacing the predefined entities
579 * and non ASCII values with their entities and CharRef counterparts.
580 * Contrary to xmlEncodeEntities, this routine is reentrant, and result
581 * must be deallocated.
583 * Returns A newly allocated string with the substitution done.
586 xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
587 const xmlChar *cur = input;
588 xmlChar *buffer = NULL;
593 if (input == NULL) return(NULL);
595 html = (doc->type == XML_HTML_DOCUMENT_NODE);
598 * allocate an translation buffer.
601 buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
602 if (buffer == NULL) {
603 xmlGenericError(xmlGenericErrorContext, "malloc failed\n");
608 while (*cur != '\0') {
609 if (out - buffer > buffer_size - 100) {
610 int indx = out - buffer;
612 growBufferReentrant();
617 * By default one have to encode at least '<', '>', '"' and '&' !
624 } else if (*cur == '>') {
629 } else if (*cur == '&') {
636 } else if (*cur == '"') {
643 } else if ((*cur == '\'') && (!html)) {
651 } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
652 (*cur == '\n') || (*cur == '\t') || ((html) && (*cur == '\r'))) {
654 * default case, just copy !
657 } else if (*cur >= 0x80) {
658 if (((doc != NULL) && (doc->encoding != NULL)) || (html)) {
660 * Bjørn Reese <br@sseusa.com> provided the patch
662 xc = (*cur & 0x3F) << 6;
664 xc += *(++cur) & 0x3F;
671 * We assume we have UTF-8 input.
677 xmlGenericError(xmlGenericErrorContext,
678 "xmlEncodeEntitiesReentrant : input not UTF-8\n");
680 doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
681 snprintf(buf, sizeof(buf), "&#%d;", *cur);
682 buf[sizeof(buf) - 1] = 0;
684 while (*ptr != 0) *out++ = *ptr++;
687 } else if (*cur < 0xE0) {
688 val = (cur[0]) & 0x1F;
690 val |= (cur[1]) & 0x3F;
692 } else if (*cur < 0xF0) {
693 val = (cur[0]) & 0x0F;
695 val |= (cur[1]) & 0x3F;
697 val |= (cur[2]) & 0x3F;
699 } else if (*cur < 0xF8) {
700 val = (cur[0]) & 0x07;
702 val |= (cur[1]) & 0x3F;
704 val |= (cur[2]) & 0x3F;
706 val |= (cur[3]) & 0x3F;
709 if ((l == 1) || (!IS_CHAR(val))) {
710 xmlGenericError(xmlGenericErrorContext,
711 "xmlEncodeEntitiesReentrant : char out of range\n");
713 doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
714 snprintf(buf, sizeof(buf), "&#%d;", *cur);
715 buf[sizeof(buf) - 1] = 0;
717 while (*ptr != 0) *out++ = *ptr++;
722 * We could do multiple things here. Just save as a char ref
725 snprintf(buf, sizeof(buf), "&#%d;", val);
727 snprintf(buf, sizeof(buf), "&#x%X;", val);
728 buf[sizeof(buf) - 1] = 0;
730 while (*ptr != 0) *out++ = *ptr++;
734 } else if (IS_CHAR((unsigned int) *cur)) {
737 snprintf(buf, sizeof(buf), "&#%d;", *cur);
738 buf[sizeof(buf) - 1] = 0;
740 while (*ptr != 0) *out++ = *ptr++;
745 * default case, this is not a valid char !
748 xmlGenericError(xmlGenericErrorContext,
749 "xmlEncodeEntities: invalid char %d\n", (int) *cur);
759 * xmlEncodeSpecialChars:
760 * @doc: the document containing the string
761 * @input: A string to convert to XML.
763 * Do a global encoding of a string, replacing the predefined entities
764 * this routine is reentrant, and result must be deallocated.
766 * Returns A newly allocated string with the substitution done.
769 xmlEncodeSpecialChars(xmlDocPtr doc, const xmlChar *input) {
770 const xmlChar *cur = input;
771 xmlChar *buffer = NULL;
776 if (input == NULL) return(NULL);
778 html = (doc->type == XML_HTML_DOCUMENT_NODE);
781 * allocate an translation buffer.
784 buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
785 if (buffer == NULL) {
786 xmlGenericError(xmlGenericErrorContext, "malloc failed\n");
791 while (*cur != '\0') {
792 if (out - buffer > buffer_size - 10) {
793 int indx = out - buffer;
795 growBufferReentrant();
800 * By default one have to encode at least '<', '>', '"' and '&' !
807 } else if (*cur == '>') {
812 } else if (*cur == '&') {
818 } else if (*cur == '"') {
825 } else if (*cur == '\r') {
833 * Works because on UTF-8, all extended sequences cannot
834 * result in bytes in the ASCII range.
845 * xmlCreateEntitiesTable:
847 * create and initialize an empty entities hash table.
849 * Returns the xmlEntitiesTablePtr just created or NULL in case of error.
852 xmlCreateEntitiesTable(void) {
853 return((xmlEntitiesTablePtr) xmlHashCreate(0));
857 * xmlFreeEntityWrapper:
861 * Deallocate the memory used by an entities in the hash table.
864 xmlFreeEntityWrapper(xmlEntityPtr entity,
865 const xmlChar *name ATTRIBUTE_UNUSED) {
867 xmlFreeEntity(entity);
871 * xmlFreeEntitiesTable:
872 * @table: An entity table
874 * Deallocate the memory used by an entities hash table.
877 xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
878 xmlHashFree(table, (xmlHashDeallocator) xmlFreeEntityWrapper);
885 * Build a copy of an entity
887 * Returns the new xmlEntitiesPtr or NULL in case of error.
890 xmlCopyEntity(xmlEntityPtr ent) {
893 cur = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
895 xmlGenericError(xmlGenericErrorContext,
896 "xmlCopyEntity: out of memory !\n");
899 memset(cur, 0, sizeof(xmlEntity));
900 cur->type = XML_ENTITY_DECL;
902 cur->etype = ent->etype;
903 if (ent->name != NULL)
904 cur->name = xmlStrdup(ent->name);
905 if (ent->ExternalID != NULL)
906 cur->ExternalID = xmlStrdup(ent->ExternalID);
907 if (ent->SystemID != NULL)
908 cur->SystemID = xmlStrdup(ent->SystemID);
909 if (ent->content != NULL)
910 cur->content = xmlStrdup(ent->content);
911 if (ent->orig != NULL)
912 cur->orig = xmlStrdup(ent->orig);
913 if (ent->URI != NULL)
914 cur->URI = xmlStrdup(ent->URI);
919 * xmlCopyEntitiesTable:
920 * @table: An entity table
922 * Build a copy of an entity table.
924 * Returns the new xmlEntitiesTablePtr or NULL in case of error.
927 xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
928 return(xmlHashCopy(table, (xmlHashCopier) xmlCopyEntity));
933 * @buf: An XML buffer.
934 * @ent: An entity table
936 * This will dump the content of the entity table as an XML DTD definition
939 xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) {
940 switch (ent->etype) {
941 case XML_INTERNAL_GENERAL_ENTITY:
942 xmlBufferWriteChar(buf, "<!ENTITY ");
943 xmlBufferWriteCHAR(buf, ent->name);
944 xmlBufferWriteChar(buf, " ");
945 if (ent->orig != NULL)
946 xmlBufferWriteQuotedString(buf, ent->orig);
948 xmlBufferWriteQuotedString(buf, ent->content);
949 xmlBufferWriteChar(buf, ">\n");
951 case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
952 xmlBufferWriteChar(buf, "<!ENTITY ");
953 xmlBufferWriteCHAR(buf, ent->name);
954 if (ent->ExternalID != NULL) {
955 xmlBufferWriteChar(buf, " PUBLIC ");
956 xmlBufferWriteQuotedString(buf, ent->ExternalID);
957 xmlBufferWriteChar(buf, " ");
958 xmlBufferWriteQuotedString(buf, ent->SystemID);
960 xmlBufferWriteChar(buf, " SYSTEM ");
961 xmlBufferWriteQuotedString(buf, ent->SystemID);
963 xmlBufferWriteChar(buf, ">\n");
965 case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
966 xmlBufferWriteChar(buf, "<!ENTITY ");
967 xmlBufferWriteCHAR(buf, ent->name);
968 if (ent->ExternalID != NULL) {
969 xmlBufferWriteChar(buf, " PUBLIC ");
970 xmlBufferWriteQuotedString(buf, ent->ExternalID);
971 xmlBufferWriteChar(buf, " ");
972 xmlBufferWriteQuotedString(buf, ent->SystemID);
974 xmlBufferWriteChar(buf, " SYSTEM ");
975 xmlBufferWriteQuotedString(buf, ent->SystemID);
977 if (ent->content != NULL) { /* Should be true ! */
978 xmlBufferWriteChar(buf, " NDATA ");
979 if (ent->orig != NULL)
980 xmlBufferWriteCHAR(buf, ent->orig);
982 xmlBufferWriteCHAR(buf, ent->content);
984 xmlBufferWriteChar(buf, ">\n");
986 case XML_INTERNAL_PARAMETER_ENTITY:
987 xmlBufferWriteChar(buf, "<!ENTITY % ");
988 xmlBufferWriteCHAR(buf, ent->name);
989 xmlBufferWriteChar(buf, " ");
990 if (ent->orig == NULL)
991 xmlBufferWriteQuotedString(buf, ent->content);
993 xmlBufferWriteQuotedString(buf, ent->orig);
994 xmlBufferWriteChar(buf, ">\n");
996 case XML_EXTERNAL_PARAMETER_ENTITY:
997 xmlBufferWriteChar(buf, "<!ENTITY % ");
998 xmlBufferWriteCHAR(buf, ent->name);
999 if (ent->ExternalID != NULL) {
1000 xmlBufferWriteChar(buf, " PUBLIC ");
1001 xmlBufferWriteQuotedString(buf, ent->ExternalID);
1002 xmlBufferWriteChar(buf, " ");
1003 xmlBufferWriteQuotedString(buf, ent->SystemID);
1005 xmlBufferWriteChar(buf, " SYSTEM ");
1006 xmlBufferWriteQuotedString(buf, ent->SystemID);
1008 xmlBufferWriteChar(buf, ">\n");
1011 xmlGenericError(xmlGenericErrorContext,
1012 "xmlDumpEntitiesDecl: internal: unknown type %d\n",
1018 * xmlDumpEntitiesTable:
1019 * @buf: An XML buffer.
1020 * @table: An entity table
1022 * This will dump the content of the entity table as an XML DTD definition
1025 xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
1026 xmlHashScan(table, (xmlHashScanner)xmlDumpEntityDecl, buf);