blob: ef6aa7922a6db338c474130cb887d0a113731a72 [file] [log] [blame]
Daniel Veillard260a68f1998-08-13 03:39:55 +00001/*
2 * entities.c : implementation for the XML entities handking
3 *
4 * See Copyright for the status of this software.
5 *
Daniel Veillard39a1f9a1999-01-17 19:11:59 +00006 * Daniel.Veillard@w3.org
Daniel Veillard260a68f1998-08-13 03:39:55 +00007 */
8
9#include <stdio.h>
Seth Alvese7f12e61998-10-01 20:51:15 +000010#include <stdlib.h>
Daniel Veillard260a68f1998-08-13 03:39:55 +000011#include <string.h>
12#include "entities.h"
13
14/*
15 * The XML predefined entities.
16 */
17
18struct xmlPredefinedEntityValue {
19 const char *name;
20 const char *value;
21};
22struct xmlPredefinedEntityValue xmlPredefinedEntityValues[] = {
23 { "lt", "<" },
24 { "gt", ">" },
25 { "apos", "'" },
26 { "quot", "\"" },
27 { "amp", "&" }
28};
29
30xmlEntitiesTablePtr xmlPredefinedEntities = NULL;
31
32/*
33 * A buffer used for converting entities to their equivalent and back.
Daniel Veillardbe36afe1998-11-27 06:39:50 +000034 *
35 * TODO: remove this, this helps performances but forbid reentrancy in a
36 * stupid way.
Daniel Veillard260a68f1998-08-13 03:39:55 +000037 */
38static int buffer_size = 0;
39static CHAR *buffer = NULL;
40
41void growBuffer(void) {
42 buffer_size *= 2;
43 buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
44 if (buffer == NULL) {
45 perror("realloc failed");
46 exit(1);
47 }
48}
49
50/*
51 * xmlFreeEntity : clean-up an entity record.
52 */
Daniel Veillard260a68f1998-08-13 03:39:55 +000053void xmlFreeEntity(xmlEntityPtr entity) {
54 if (entity == NULL) return;
55
56 if (entity->name != NULL)
57 free((char *) entity->name);
58 if (entity->ExternalID != NULL)
59 free((char *) entity->ExternalID);
60 if (entity->SystemID != NULL)
61 free((char *) entity->SystemID);
62 if (entity->content != NULL)
63 free((char *) entity->content);
64 memset(entity, -1, sizeof(xmlEntity));
65}
66
67/*
Daniel Veillardbe36afe1998-11-27 06:39:50 +000068 * xmlAddEntity : register a new entity for an entities table.
Daniel Veillard260a68f1998-08-13 03:39:55 +000069 *
70 * TODO !!! We should check here that the combination of type
71 * ExternalID and SystemID is valid.
72 */
Daniel Veillardbe36afe1998-11-27 06:39:50 +000073static void
74xmlAddEntity(xmlEntitiesTablePtr table, const CHAR *name, int type,
Daniel Veillard260a68f1998-08-13 03:39:55 +000075 const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
76 int i;
77 xmlEntityPtr cur;
78 int len;
79
80 for (i = 0;i < table->nb_entities;i++) {
81 cur = &table->table[i];
82 if (!xmlStrcmp(cur->name, name)) {
83 /*
84 * The entity is already defined in this Dtd, the spec says to NOT
85 * override it ... Is it worth a Warning ??? !!!
86 */
87 return;
88 }
89 }
90 if (table->nb_entities >= table->max_entities) {
91 /*
92 * need more elements.
93 */
94 table->max_entities *= 2;
95 table->table = (xmlEntityPtr)
96 realloc(table->table, table->max_entities * sizeof(xmlEntity));
97 if (table->table) {
98 perror("realloc failed");
99 exit(1);
100 }
101 }
102 cur = &table->table[table->nb_entities];
103 cur->name = xmlStrdup(name);
104 for (len = 0;name[0] != 0;name++)len++;
105 cur->len = len;
106 cur->type = type;
107 if (ExternalID != NULL)
108 cur->ExternalID = xmlStrdup(ExternalID);
109 else
110 cur->ExternalID = NULL;
111 if (SystemID != NULL)
112 cur->SystemID = xmlStrdup(SystemID);
113 else
114 cur->SystemID = NULL;
115 if (content != NULL)
116 cur->content = xmlStrdup(content);
117 else
118 cur->content = NULL;
119 table->nb_entities++;
120}
121
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000122/**
123 * xmlInitializePredefinedEntities:
124 *
125 * Set up the predefined entities.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000126 */
127void xmlInitializePredefinedEntities(void) {
128 int i;
129 CHAR name[50];
130 CHAR value[50];
131 const char *in;
132 CHAR *out;
133
134 if (xmlPredefinedEntities != NULL) return;
135
136 xmlPredefinedEntities = xmlCreateEntitiesTable();
137 for (i = 0;i < sizeof(xmlPredefinedEntityValues) /
138 sizeof(xmlPredefinedEntityValues[0]);i++) {
139 in = xmlPredefinedEntityValues[i].name;
140 out = &name[0];
141 for (;(*out++ = (CHAR) *in);)in++;
142 in = xmlPredefinedEntityValues[i].value;
143 out = &value[0];
144 for (;(*out++ = (CHAR) *in);)in++;
145 xmlAddEntity(xmlPredefinedEntities, (const CHAR *) &name[0],
Daniel Veillard25940b71998-10-29 05:51:30 +0000146 XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL,
Daniel Veillard260a68f1998-08-13 03:39:55 +0000147 &value[0]);
148 }
149}
150
Daniel Veillardccb09631998-10-27 06:21:04 +0000151/**
152 * xmlGetPredefinedEntity:
153 * @name: the entity name
154 *
155 * Check whether this name is an predefined entity.
156 *
157 * return values: NULL if not, othervise the entity
158 */
159xmlEntityPtr
160xmlGetPredefinedEntity(const CHAR *name) {
161 int i;
162 xmlEntityPtr cur;
163
164 if (xmlPredefinedEntities == NULL)
165 xmlInitializePredefinedEntities();
166 for (i = 0;i < xmlPredefinedEntities->nb_entities;i++) {
167 cur = &xmlPredefinedEntities->table[i];
168 if (!xmlStrcmp(cur->name, name)) return(cur);
169 }
170 return(NULL);
171}
172
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000173/**
174 * xmlAddDtdEntity:
175 * @doc: the document
176 * @name: the entity name
177 * @type: the entity type XML_xxx_yyy_ENTITY
178 * @ExternalID: the entity external ID if available
179 * @SystemID: the entity system ID if available
180 * @content: the entity content
181 *
182 * Register a new entity for this document DTD.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000183 */
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000184void
185xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
Daniel Veillard260a68f1998-08-13 03:39:55 +0000186 const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
187 xmlEntitiesTablePtr table;
188
Daniel Veillard39a1f9a1999-01-17 19:11:59 +0000189 if (doc->extSubset == NULL) {
190 fprintf(stderr,
191 "xmlAddDtdEntity: document without external subset !\n");
Daniel Veillard260a68f1998-08-13 03:39:55 +0000192 return;
193 }
Daniel Veillard39a1f9a1999-01-17 19:11:59 +0000194 table = (xmlEntitiesTablePtr) doc->extSubset->entities;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000195 if (table == NULL) {
196 table = xmlCreateEntitiesTable();
Daniel Veillard39a1f9a1999-01-17 19:11:59 +0000197 doc->extSubset->entities = table;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000198 }
199 xmlAddEntity(table, name, type, ExternalID, SystemID, content);
200}
201
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000202/**
203 * xmlAddDocEntity:
204 * @doc: the document
205 * @name: the entity name
206 * @type: the entity type XML_xxx_yyy_ENTITY
207 * @ExternalID: the entity external ID if available
208 * @SystemID: the entity system ID if available
209 * @content: the entity content
210 *
211 * Register a new entity for this document.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000212 */
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000213void
214xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
Daniel Veillard260a68f1998-08-13 03:39:55 +0000215 const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
216 xmlEntitiesTablePtr table;
217
Daniel Veillard39a1f9a1999-01-17 19:11:59 +0000218 if (doc == NULL) {
219 fprintf(stderr,
220 "xmlAddDocEntity: document is NULL !\n");
221 return;
222 }
223 if (doc->intSubset == NULL) {
224 fprintf(stderr,
225 "xmlAddDtdEntity: document without internal subset !\n");
226 return;
227 }
228 table = (xmlEntitiesTablePtr) doc->intSubset->entities;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000229 if (table == NULL) {
230 table = xmlCreateEntitiesTable();
Daniel Veillard39a1f9a1999-01-17 19:11:59 +0000231 doc->intSubset->entities = table;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000232 }
Daniel Veillard39a1f9a1999-01-17 19:11:59 +0000233 xmlAddEntity(table, name, type, ExternalID, SystemID, content);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000234}
235
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000236/**
237 * xmlGetDtdEntity:
238 * @doc: the document referencing the entity
239 * @name: the entity name
240 *
241 * Do an entity lookup in the Dtd entity hash table and
242 * returns the corresponding entity, if found.
243 *
244 * return values: A pointer to the entity structure or NULL if not found.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000245 */
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000246xmlEntityPtr
247xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name) {
Daniel Veillard260a68f1998-08-13 03:39:55 +0000248 int i;
249 xmlEntityPtr cur;
250 xmlEntitiesTablePtr table;
251
Daniel Veillard39a1f9a1999-01-17 19:11:59 +0000252 if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
253 table = (xmlEntitiesTablePtr) doc->extSubset->entities;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000254 for (i = 0;i < table->nb_entities;i++) {
255 cur = &table->table[i];
256 if (!xmlStrcmp(cur->name, name)) return(cur);
257 }
258 }
259 return(NULL);
260}
261
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000262/**
263 * xmlGetDocEntity:
264 * @doc: the document referencing the entity
265 * @name: the entity name
266 *
267 * Do an entity lookup in the document entity hash table and
268 * returns the corrsponding entity, otherwise a lookup is done
269 * in the predefined entities too.
270 *
271 * return values: A pointer to the entity structure or NULL if not found.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000272 */
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000273xmlEntityPtr
274xmlGetDocEntity(xmlDocPtr doc, const CHAR *name) {
Daniel Veillard260a68f1998-08-13 03:39:55 +0000275 int i;
276 xmlEntityPtr cur;
277 xmlEntitiesTablePtr table;
278
Daniel Veillard39a1f9a1999-01-17 19:11:59 +0000279 if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
280 table = (xmlEntitiesTablePtr) doc->intSubset->entities;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000281 for (i = 0;i < table->nb_entities;i++) {
282 cur = &table->table[i];
283 if (!xmlStrcmp(cur->name, name)) return(cur);
284 }
285 }
286 if (xmlPredefinedEntities == NULL)
287 xmlInitializePredefinedEntities();
288 table = xmlPredefinedEntities;
289 for (i = 0;i < table->nb_entities;i++) {
290 cur = &table->table[i];
291 if (!xmlStrcmp(cur->name, name)) return(cur);
292 }
293
294 return(NULL);
295}
296
297/*
Daniel Veillard8cc0d1f1998-11-16 01:04:26 +0000298 * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
299 * | [#x10000-#x10FFFF]
300 * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
301 */
302#define IS_CHAR(c) \
303 (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || \
304 (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
305
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000306/**
307 * xmlEncodeEntities:
308 * @doc: the document containing the string
309 * @input: A string to convert to XML.
310 *
311 * Do a global encoding of a string, replacing the predefined entities
312 * and non ASCII values with their entities and CharRef counterparts.
313 *
Daniel Veillard0ba4d531998-11-01 19:34:31 +0000314 * TODO !!!! Once moved to UTF-8 internal encoding, the encoding of non-ascii
315 * get erroneous.
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000316 *
317 * TODO This routine is not reentrant and this will be changed, the interface
318 * should not be modified though.
319 *
320 * return values: A newly allocated string with the substitution done.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000321 */
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000322CHAR *
323xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) {
Daniel Veillard260a68f1998-08-13 03:39:55 +0000324 const CHAR *cur = input;
325 CHAR *out = buffer;
326
Daniel Veillard242590e1998-11-13 18:04:35 +0000327 if (input == NULL) return(NULL);
Daniel Veillard260a68f1998-08-13 03:39:55 +0000328 if (buffer == NULL) {
329 buffer_size = 1000;
330 buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
331 if (buffer == NULL) {
332 perror("malloc failed");
333 exit(1);
334 }
335 out = buffer;
336 }
337 while (*cur != '\0') {
338 if (out - buffer > buffer_size - 100) {
339 int index = out - buffer;
340
341 growBuffer();
342 out = &buffer[index];
343 }
344
345 /*
346 * By default one have to encode at least '<', '>', '"' and '&' !
Daniel Veillard260a68f1998-08-13 03:39:55 +0000347 */
348 if (*cur == '<') {
349 *out++ = '&';
350 *out++ = 'l';
351 *out++ = 't';
352 *out++ = ';';
353 } else if (*cur == '>') {
354 *out++ = '&';
355 *out++ = 'g';
356 *out++ = 't';
357 *out++ = ';';
358 } else if (*cur == '&') {
359 *out++ = '&';
360 *out++ = 'a';
361 *out++ = 'm';
362 *out++ = 'p';
363 *out++ = ';';
364 } else if (*cur == '"') {
365 *out++ = '&';
366 *out++ = 'q';
367 *out++ = 'u';
368 *out++ = 'o';
369 *out++ = 't';
370 *out++ = ';';
371 } else if (*cur == '\'') {
372 *out++ = '&';
373 *out++ = 'a';
374 *out++ = 'p';
375 *out++ = 'o';
376 *out++ = 's';
377 *out++ = ';';
Daniel Veillard8cc0d1f1998-11-16 01:04:26 +0000378 } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
379 (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
380 /*
381 * default case, just copy !
382 */
383 *out++ = *cur;
Daniel Veillard0ba4d531998-11-01 19:34:31 +0000384#ifndef USE_UTF_8
385 } else if ((sizeof(CHAR) == 1) && (*cur >= 0x80)) {
386 char buf[10], *ptr;
Daniel Veillardda4d3c41998-11-04 20:07:05 +0000387#ifdef HAVE_SNPRINTF
388 snprintf(buf, 9, "&#%d;", *cur);
389#else
390 sprintf(buf, "&#%d;", *cur);
391#endif
Daniel Veillard0ba4d531998-11-01 19:34:31 +0000392 ptr = buf;
393 while (*ptr != 0) *out++ = *ptr++;
394#endif
Daniel Veillard8cc0d1f1998-11-16 01:04:26 +0000395 } else if (IS_CHAR(*cur)) {
396 char buf[10], *ptr;
397
398#ifdef HAVE_SNPRINTF
399 snprintf(buf, 9, "&#%d;", *cur);
400#else
401 sprintf(buf, "&#%d;", *cur);
402#endif
403 ptr = buf;
404 while (*ptr != 0) *out++ = *ptr++;
Daniel Veillard260a68f1998-08-13 03:39:55 +0000405 }
Daniel Veillard8cc0d1f1998-11-16 01:04:26 +0000406#if 0
407 else {
408 /*
409 * default case, this is not a valid char !
410 * Skip it...
411 */
412 fprintf(stderr, "xmlEncodeEntities: invalid char %d\n", (int) *cur);
413 }
414#endif
Daniel Veillard260a68f1998-08-13 03:39:55 +0000415 cur++;
416 }
417 *out++ = 0;
418 return(buffer);
419}
420
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000421/**
422 * xmlCreateEntitiesTable:
423 *
424 * create and initialize an empty entities hash table.
425 *
426 * return values: the xmlEntitiesTablePtr just created or NULL in case of error.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000427 */
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000428xmlEntitiesTablePtr
429xmlCreateEntitiesTable(void) {
Daniel Veillard260a68f1998-08-13 03:39:55 +0000430 xmlEntitiesTablePtr ret;
431
432 ret = (xmlEntitiesTablePtr)
433 malloc(sizeof(xmlEntitiesTable));
434 if (ret == NULL) {
435 fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
436 sizeof(xmlEntitiesTable));
437 return(NULL);
438 }
439 ret->max_entities = XML_MIN_ENTITIES_TABLE;
440 ret->nb_entities = 0;
441 ret->table = (xmlEntityPtr )
442 malloc(ret->max_entities * sizeof(xmlEntity));
443 if (ret == NULL) {
444 fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
445 ret->max_entities * sizeof(xmlEntity));
446 free(ret);
447 return(NULL);
448 }
449 return(ret);
450}
451
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000452/**
453 * xmlFreeEntitiesTable:
454 * @table: An entity table
455 *
456 * Deallocate the memory used by an entities hash table.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000457 */
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000458void
459xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
Daniel Veillard260a68f1998-08-13 03:39:55 +0000460 int i;
461
462 if (table == NULL) return;
463
464 for (i = 0;i < table->nb_entities;i++) {
465 xmlFreeEntity(&table->table[i]);
466 }
467 free(table->table);
468 free(table);
469}
470
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000471/**
472 * xmlCopyEntitiesTable:
473 * @table: An entity table
474 *
475 * Build a copy of an entity table.
476 *
477 * return values: the new xmlEntitiesTablePtr or NULL in case of error.
Daniel Veillard260a68f1998-08-13 03:39:55 +0000478 */
Daniel Veillardbe36afe1998-11-27 06:39:50 +0000479xmlEntitiesTablePtr
480xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
481 xmlEntitiesTablePtr ret;
482 xmlEntityPtr cur, ent;
483 int i;
484
485 ret = (xmlEntitiesTablePtr) malloc(sizeof(xmlEntitiesTable));
486 if (ret == NULL) {
487 fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
488 return(NULL);
489 }
490 ret->table = (xmlEntityPtr) malloc(table->max_entities *
491 sizeof(xmlEntity));
492 if (ret->table == NULL) {
493 fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
494 free(ret);
495 return(NULL);
496 }
497 ret->max_entities = table->max_entities;
498 ret->nb_entities = table->nb_entities;
499 for (i = 0;i < ret->nb_entities;i++) {
500 cur = &ret->table[i];
501 ent = &table->table[i];
502 cur->len = ent->len;
503 cur->type = ent->type;
504 if (ent->name != NULL)
505 cur->name = xmlStrdup(ent->name);
506 else
507 cur->name = NULL;
508 if (ent->ExternalID != NULL)
509 cur->ExternalID = xmlStrdup(ent->ExternalID);
510 else
511 cur->ExternalID = NULL;
512 if (ent->SystemID != NULL)
513 cur->SystemID = xmlStrdup(ent->SystemID);
514 else
515 cur->SystemID = NULL;
516 if (ent->content != NULL)
517 cur->content = xmlStrdup(ent->content);
518 else
519 cur->content = NULL;
520 }
521 return(ret);
522}
523
524/**
525 * xmlDumpEntitiesTable:
526 * @table: An entity table
527 *
528 * This will dump the content of the entity table as an XML DTD definition
529 *
530 * NOTE: TODO an extra parameter allowing a reentant implementation will
531 * be added.
532 */
533void
534xmlDumpEntitiesTable(xmlEntitiesTablePtr table) {
Daniel Veillard260a68f1998-08-13 03:39:55 +0000535 int i;
536 xmlEntityPtr cur;
537
538 if (table == NULL) return;
539
540 for (i = 0;i < table->nb_entities;i++) {
541 cur = &table->table[i];
542 switch (cur->type) {
543 case XML_INTERNAL_GENERAL_ENTITY:
544 xmlBufferWriteChar("<!ENTITY ");
545 xmlBufferWriteCHAR(cur->name);
546 xmlBufferWriteChar(" \"");
547 xmlBufferWriteCHAR(cur->content);
548 xmlBufferWriteChar("\">\n");
549 break;
550 case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
551 xmlBufferWriteChar("<!ENTITY ");
552 xmlBufferWriteCHAR(cur->name);
553 if (cur->ExternalID != NULL) {
554 xmlBufferWriteChar(" PUBLIC \"");
555 xmlBufferWriteCHAR(cur->ExternalID);
556 xmlBufferWriteChar("\" \"");
557 xmlBufferWriteCHAR(cur->SystemID);
558 xmlBufferWriteChar("\"");
559 } else {
560 xmlBufferWriteChar(" SYSTEM \"");
561 xmlBufferWriteCHAR(cur->SystemID);
562 xmlBufferWriteChar("\"");
563 }
564 xmlBufferWriteChar(">\n");
565 break;
566 case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
567 xmlBufferWriteChar("<!ENTITY ");
568 xmlBufferWriteCHAR(cur->name);
569 if (cur->ExternalID != NULL) {
570 xmlBufferWriteChar(" PUBLIC \"");
571 xmlBufferWriteCHAR(cur->ExternalID);
572 xmlBufferWriteChar("\" \"");
573 xmlBufferWriteCHAR(cur->SystemID);
574 xmlBufferWriteChar("\"");
575 } else {
576 xmlBufferWriteChar(" SYSTEM \"");
577 xmlBufferWriteCHAR(cur->SystemID);
578 xmlBufferWriteChar("\"");
579 }
580 if (cur->content != NULL) { /* Should be true ! */
581 xmlBufferWriteChar(" NDATA ");
582 xmlBufferWriteCHAR(cur->content);
583 }
584 xmlBufferWriteChar(">\n");
585 break;
586 case XML_INTERNAL_PARAMETER_ENTITY:
587 xmlBufferWriteChar("<!ENTITY % ");
588 xmlBufferWriteCHAR(cur->name);
589 xmlBufferWriteChar(" \"");
590 xmlBufferWriteCHAR(cur->content);
591 xmlBufferWriteChar("\">\n");
592 break;
593 case XML_EXTERNAL_PARAMETER_ENTITY:
594 xmlBufferWriteChar("<!ENTITY % ");
595 xmlBufferWriteCHAR(cur->name);
596 if (cur->ExternalID != NULL) {
597 xmlBufferWriteChar(" PUBLIC \"");
598 xmlBufferWriteCHAR(cur->ExternalID);
599 xmlBufferWriteChar("\" \"");
600 xmlBufferWriteCHAR(cur->SystemID);
601 xmlBufferWriteChar("\"");
602 } else {
603 xmlBufferWriteChar(" SYSTEM \"");
604 xmlBufferWriteCHAR(cur->SystemID);
605 xmlBufferWriteChar("\"");
606 }
607 xmlBufferWriteChar(">\n");
608 break;
609 default:
610 fprintf(stderr,
611 "xmlDumpEntitiesTable: internal: unknown type %d\n",
612 cur->type);
613 }
614 }
615}