Annotation of XML/entities.c, revision 1.26
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.26 ! daniel 33: * Macro used to grow the current buffer.
1.3 httpng 34: */
1.26 ! daniel 35: #define growBuffer() { \
! 36: buffer_size *= 2; \
! 37: buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR)); \
! 38: if (buffer == NULL) { \
! 39: perror("realloc failed"); \
! 40: exit(1); \
! 41: } \
! 42: }
1.3 httpng 43:
44:
45: /*
1.2 httpng 46: * xmlFreeEntity : clean-up an entity record.
1.1 httpng 47: */
1.2 httpng 48: void xmlFreeEntity(xmlEntityPtr entity) {
49: if (entity == NULL) return;
50:
1.11 daniel 51: if (entity->name != NULL)
52: free((char *) entity->name);
1.14 daniel 53: if (entity->ExternalID != NULL)
54: free((char *) entity->ExternalID);
55: if (entity->SystemID != NULL)
56: free((char *) entity->SystemID);
57: if (entity->content != NULL)
58: free((char *) entity->content);
59: memset(entity, -1, sizeof(xmlEntity));
1.2 httpng 60: }
1.1 httpng 61:
62: /*
1.22 daniel 63: * xmlAddEntity : register a new entity for an entities table.
1.13 daniel 64: *
65: * TODO !!! We should check here that the combination of type
66: * ExternalID and SystemID is valid.
1.1 httpng 67: */
1.22 daniel 68: static void
69: xmlAddEntity(xmlEntitiesTablePtr table, const CHAR *name, int type,
1.13 daniel 70: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.2 httpng 71: int i;
72: xmlEntityPtr cur;
1.14 daniel 73: int len;
1.1 httpng 74:
1.2 httpng 75: for (i = 0;i < table->nb_entities;i++) {
76: cur = &table->table[i];
1.11 daniel 77: if (!xmlStrcmp(cur->name, name)) {
1.13 daniel 78: /*
79: * The entity is already defined in this Dtd, the spec says to NOT
80: * override it ... Is it worth a Warning ??? !!!
81: */
82: return;
1.7 veillard 83: }
1.2 httpng 84: }
85: if (table->nb_entities >= table->max_entities) {
86: /*
87: * need more elements.
88: */
89: table->max_entities *= 2;
90: table->table = (xmlEntityPtr)
91: realloc(table->table, table->max_entities * sizeof(xmlEntity));
92: if (table->table) {
93: perror("realloc failed");
94: exit(1);
95: }
96: }
97: cur = &table->table[table->nb_entities];
1.11 daniel 98: cur->name = xmlStrdup(name);
1.14 daniel 99: for (len = 0;name[0] != 0;name++)len++;
100: cur->len = len;
1.13 daniel 101: cur->type = type;
102: if (ExternalID != NULL)
103: cur->ExternalID = xmlStrdup(ExternalID);
1.14 daniel 104: else
105: cur->ExternalID = NULL;
1.13 daniel 106: if (SystemID != NULL)
1.14 daniel 107: cur->SystemID = xmlStrdup(SystemID);
108: else
109: cur->SystemID = NULL;
1.13 daniel 110: if (content != NULL)
111: cur->content = xmlStrdup(content);
1.14 daniel 112: else
113: cur->content = NULL;
1.2 httpng 114: table->nb_entities++;
115: }
1.1 httpng 116:
1.22 daniel 117: /**
118: * xmlInitializePredefinedEntities:
119: *
120: * Set up the predefined entities.
1.15 daniel 121: */
122: void xmlInitializePredefinedEntities(void) {
123: int i;
124: CHAR name[50];
125: CHAR value[50];
126: const char *in;
127: CHAR *out;
128:
129: if (xmlPredefinedEntities != NULL) return;
130:
131: xmlPredefinedEntities = xmlCreateEntitiesTable();
132: for (i = 0;i < sizeof(xmlPredefinedEntityValues) /
133: sizeof(xmlPredefinedEntityValues[0]);i++) {
134: in = xmlPredefinedEntityValues[i].name;
135: out = &name[0];
136: for (;(*out++ = (CHAR) *in);)in++;
137: in = xmlPredefinedEntityValues[i].value;
138: out = &value[0];
139: for (;(*out++ = (CHAR) *in);)in++;
140: xmlAddEntity(xmlPredefinedEntities, (const CHAR *) &name[0],
1.18 daniel 141: XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL,
1.15 daniel 142: &value[0]);
143: }
144: }
1.17 daniel 145:
146: /**
147: * xmlGetPredefinedEntity:
148: * @name: the entity name
149: *
150: * Check whether this name is an predefined entity.
151: *
1.24 daniel 152: * Returns NULL if not, othervise the entity
1.17 daniel 153: */
154: xmlEntityPtr
155: xmlGetPredefinedEntity(const CHAR *name) {
156: int i;
157: xmlEntityPtr cur;
158:
159: if (xmlPredefinedEntities == NULL)
160: xmlInitializePredefinedEntities();
161: for (i = 0;i < xmlPredefinedEntities->nb_entities;i++) {
162: cur = &xmlPredefinedEntities->table[i];
163: if (!xmlStrcmp(cur->name, name)) return(cur);
164: }
165: return(NULL);
166: }
167:
1.22 daniel 168: /**
169: * xmlAddDtdEntity:
170: * @doc: the document
171: * @name: the entity name
172: * @type: the entity type XML_xxx_yyy_ENTITY
173: * @ExternalID: the entity external ID if available
174: * @SystemID: the entity system ID if available
175: * @content: the entity content
176: *
177: * Register a new entity for this document DTD.
1.1 httpng 178: */
1.22 daniel 179: void
180: xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
1.13 daniel 181: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.2 httpng 182: xmlEntitiesTablePtr table;
1.1 httpng 183:
1.22 daniel 184: if (doc->extSubset == NULL) {
185: fprintf(stderr,
186: "xmlAddDtdEntity: document without external subset !\n");
1.16 daniel 187: return;
188: }
1.22 daniel 189: table = (xmlEntitiesTablePtr) doc->extSubset->entities;
1.2 httpng 190: if (table == NULL) {
191: table = xmlCreateEntitiesTable();
1.22 daniel 192: doc->extSubset->entities = table;
1.1 httpng 193: }
1.13 daniel 194: xmlAddEntity(table, name, type, ExternalID, SystemID, content);
1.1 httpng 195: }
196:
1.22 daniel 197: /**
198: * xmlAddDocEntity:
199: * @doc: the document
200: * @name: the entity name
201: * @type: the entity type XML_xxx_yyy_ENTITY
202: * @ExternalID: the entity external ID if available
203: * @SystemID: the entity system ID if available
204: * @content: the entity content
205: *
206: * Register a new entity for this document.
1.1 httpng 207: */
1.22 daniel 208: void
209: xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
1.13 daniel 210: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.16 daniel 211: xmlEntitiesTablePtr table;
212:
1.22 daniel 213: if (doc == NULL) {
214: fprintf(stderr,
215: "xmlAddDocEntity: document is NULL !\n");
216: return;
217: }
218: if (doc->intSubset == NULL) {
219: fprintf(stderr,
220: "xmlAddDtdEntity: document without internal subset !\n");
221: return;
222: }
223: table = (xmlEntitiesTablePtr) doc->intSubset->entities;
1.16 daniel 224: if (table == NULL) {
225: table = xmlCreateEntitiesTable();
1.22 daniel 226: doc->intSubset->entities = table;
1.2 httpng 227: }
1.22 daniel 228: xmlAddEntity(table, name, type, ExternalID, SystemID, content);
1.1 httpng 229: }
230:
1.22 daniel 231: /**
232: * xmlGetDtdEntity:
233: * @doc: the document referencing the entity
234: * @name: the entity name
235: *
236: * Do an entity lookup in the Dtd entity hash table and
237: * returns the corresponding entity, if found.
238: *
1.24 daniel 239: * Returns A pointer to the entity structure or NULL if not found.
1.1 httpng 240: */
1.22 daniel 241: xmlEntityPtr
242: xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name) {
1.2 httpng 243: int i;
244: xmlEntityPtr cur;
245: xmlEntitiesTablePtr table;
246:
1.22 daniel 247: if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
248: table = (xmlEntitiesTablePtr) doc->extSubset->entities;
1.15 daniel 249: for (i = 0;i < table->nb_entities;i++) {
250: cur = &table->table[i];
251: if (!xmlStrcmp(cur->name, name)) return(cur);
252: }
253: }
1.7 veillard 254: return(NULL);
1.3 httpng 255: }
256:
1.22 daniel 257: /**
258: * xmlGetDocEntity:
259: * @doc: the document referencing the entity
260: * @name: the entity name
261: *
262: * Do an entity lookup in the document entity hash table and
263: * returns the corrsponding entity, otherwise a lookup is done
264: * in the predefined entities too.
265: *
1.24 daniel 266: * Returns A pointer to the entity structure or NULL if not found.
1.14 daniel 267: */
1.22 daniel 268: xmlEntityPtr
269: xmlGetDocEntity(xmlDocPtr doc, const CHAR *name) {
1.14 daniel 270: int i;
1.16 daniel 271: xmlEntityPtr cur;
1.14 daniel 272: xmlEntitiesTablePtr table;
273:
1.22 daniel 274: if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
275: table = (xmlEntitiesTablePtr) doc->intSubset->entities;
1.16 daniel 276: for (i = 0;i < table->nb_entities;i++) {
277: cur = &table->table[i];
278: if (!xmlStrcmp(cur->name, name)) return(cur);
279: }
280: }
1.15 daniel 281: if (xmlPredefinedEntities == NULL)
282: xmlInitializePredefinedEntities();
1.16 daniel 283: table = xmlPredefinedEntities;
284: for (i = 0;i < table->nb_entities;i++) {
285: cur = &table->table[i];
286: if (!xmlStrcmp(cur->name, name)) return(cur);
1.14 daniel 287: }
288:
289: return(NULL);
1.1 httpng 290: }
291:
292: /*
1.21 daniel 293: * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
294: * | [#x10000-#x10FFFF]
295: * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
296: */
297: #define IS_CHAR(c) \
298: (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || \
299: (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
300:
1.22 daniel 301: /**
302: * xmlEncodeEntities:
303: * @doc: the document containing the string
304: * @input: A string to convert to XML.
305: *
306: * Do a global encoding of a string, replacing the predefined entities
307: * and non ASCII values with their entities and CharRef counterparts.
308: *
1.19 daniel 309: * TODO !!!! Once moved to UTF-8 internal encoding, the encoding of non-ascii
310: * get erroneous.
1.22 daniel 311: *
1.24 daniel 312: * Returns A newly allocated string with the substitution done.
1.1 httpng 313: */
1.22 daniel 314: CHAR *
315: xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) {
1.7 veillard 316: const CHAR *cur = input;
1.26 ! daniel 317: CHAR *buffer = NULL;
! 318: CHAR *out = NULL;
! 319: int buffer_size = 0;
1.3 httpng 320:
1.19 daniel 321: if (input == NULL) return(NULL);
1.26 ! daniel 322:
! 323: /*
! 324: * allocate an translation buffer.
! 325: */
! 326: buffer_size = 1000;
! 327: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
1.3 httpng 328: if (buffer == NULL) {
1.26 ! daniel 329: perror("malloc failed");
! 330: exit(1);
1.3 httpng 331: }
1.26 ! daniel 332: out = buffer;
! 333:
1.6 veillard 334: while (*cur != '\0') {
335: if (out - buffer > buffer_size - 100) {
336: int index = out - buffer;
337:
338: growBuffer();
339: out = &buffer[index];
340: }
341:
342: /*
1.7 veillard 343: * By default one have to encode at least '<', '>', '"' and '&' !
1.6 veillard 344: */
345: if (*cur == '<') {
346: *out++ = '&';
347: *out++ = 'l';
348: *out++ = 't';
349: *out++ = ';';
1.7 veillard 350: } else if (*cur == '>') {
351: *out++ = '&';
352: *out++ = 'g';
353: *out++ = 't';
354: *out++ = ';';
1.6 veillard 355: } else if (*cur == '&') {
356: *out++ = '&';
357: *out++ = 'a';
358: *out++ = 'm';
359: *out++ = 'p';
1.7 veillard 360: *out++ = ';';
361: } else if (*cur == '"') {
362: *out++ = '&';
363: *out++ = 'q';
364: *out++ = 'u';
365: *out++ = 'o';
366: *out++ = 't';
367: *out++ = ';';
368: } else if (*cur == '\'') {
369: *out++ = '&';
370: *out++ = 'a';
371: *out++ = 'p';
372: *out++ = 'o';
373: *out++ = 's';
1.6 veillard 374: *out++ = ';';
1.21 daniel 375: } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
376: (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
377: /*
378: * default case, just copy !
379: */
380: *out++ = *cur;
1.19 daniel 381: #ifndef USE_UTF_8
382: } else if ((sizeof(CHAR) == 1) && (*cur >= 0x80)) {
383: char buf[10], *ptr;
384: #ifdef HAVE_SNPRINTF
385: snprintf(buf, 9, "&#%d;", *cur);
386: #else
387: sprintf(buf, "&#%d;", *cur);
388: #endif
389: ptr = buf;
390: while (*ptr != 0) *out++ = *ptr++;
391: #endif
1.21 daniel 392: } else if (IS_CHAR(*cur)) {
1.20 daniel 393: char buf[10], *ptr;
394:
395: #ifdef HAVE_SNPRINTF
396: snprintf(buf, 9, "&#%d;", *cur);
397: #else
398: sprintf(buf, "&#%d;", *cur);
399: #endif
400: ptr = buf;
401: while (*ptr != 0) *out++ = *ptr++;
1.21 daniel 402: }
403: #if 0
404: else {
1.6 veillard 405: /*
1.21 daniel 406: * default case, this is not a valid char !
407: * Skip it...
1.6 veillard 408: */
1.21 daniel 409: fprintf(stderr, "xmlEncodeEntities: invalid char %d\n", (int) *cur);
1.6 veillard 410: }
1.21 daniel 411: #endif
1.6 veillard 412: cur++;
413: }
414: *out++ = 0;
415: return(buffer);
1.2 httpng 416: }
417:
1.22 daniel 418: /**
419: * xmlCreateEntitiesTable:
420: *
421: * create and initialize an empty entities hash table.
422: *
1.24 daniel 423: * Returns the xmlEntitiesTablePtr just created or NULL in case of error.
1.2 httpng 424: */
1.22 daniel 425: xmlEntitiesTablePtr
426: xmlCreateEntitiesTable(void) {
1.2 httpng 427: xmlEntitiesTablePtr ret;
1.1 httpng 428:
1.2 httpng 429: ret = (xmlEntitiesTablePtr)
430: malloc(sizeof(xmlEntitiesTable));
1.1 httpng 431: if (ret == NULL) {
1.2 httpng 432: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
433: sizeof(xmlEntitiesTable));
434: return(NULL);
435: }
436: ret->max_entities = XML_MIN_ENTITIES_TABLE;
437: ret->nb_entities = 0;
438: ret->table = (xmlEntityPtr )
439: malloc(ret->max_entities * sizeof(xmlEntity));
440: if (ret == NULL) {
441: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
442: ret->max_entities * sizeof(xmlEntity));
443: free(ret);
1.1 httpng 444: return(NULL);
445: }
446: return(ret);
447: }
448:
1.22 daniel 449: /**
450: * xmlFreeEntitiesTable:
451: * @table: An entity table
452: *
453: * Deallocate the memory used by an entities hash table.
1.1 httpng 454: */
1.22 daniel 455: void
456: xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
1.1 httpng 457: int i;
458:
459: if (table == NULL) return;
460:
1.2 httpng 461: for (i = 0;i < table->nb_entities;i++) {
462: xmlFreeEntity(&table->table[i]);
1.1 httpng 463: }
1.2 httpng 464: free(table->table);
1.1 httpng 465: free(table);
466: }
467:
1.22 daniel 468: /**
469: * xmlCopyEntitiesTable:
470: * @table: An entity table
471: *
472: * Build a copy of an entity table.
473: *
1.24 daniel 474: * Returns the new xmlEntitiesTablePtr or NULL in case of error.
1.22 daniel 475: */
476: xmlEntitiesTablePtr
477: xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
478: xmlEntitiesTablePtr ret;
479: xmlEntityPtr cur, ent;
480: int i;
481:
482: ret = (xmlEntitiesTablePtr) malloc(sizeof(xmlEntitiesTable));
483: if (ret == NULL) {
484: fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
485: return(NULL);
486: }
487: ret->table = (xmlEntityPtr) malloc(table->max_entities *
488: sizeof(xmlEntity));
489: if (ret->table == NULL) {
490: fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
491: free(ret);
492: return(NULL);
493: }
494: ret->max_entities = table->max_entities;
495: ret->nb_entities = table->nb_entities;
496: for (i = 0;i < ret->nb_entities;i++) {
497: cur = &ret->table[i];
498: ent = &table->table[i];
499: cur->len = ent->len;
500: cur->type = ent->type;
501: if (ent->name != NULL)
502: cur->name = xmlStrdup(ent->name);
503: else
504: cur->name = NULL;
505: if (ent->ExternalID != NULL)
506: cur->ExternalID = xmlStrdup(ent->ExternalID);
507: else
508: cur->ExternalID = NULL;
509: if (ent->SystemID != NULL)
510: cur->SystemID = xmlStrdup(ent->SystemID);
511: else
512: cur->SystemID = NULL;
513: if (ent->content != NULL)
514: cur->content = xmlStrdup(ent->content);
515: else
516: cur->content = NULL;
517: }
518: return(ret);
519: }
520:
521: /**
522: * xmlDumpEntitiesTable:
1.25 daniel 523: * @buf: An XML buffer.
1.22 daniel 524: * @table: An entity table
525: *
526: * This will dump the content of the entity table as an XML DTD definition
1.13 daniel 527: */
1.22 daniel 528: void
1.25 daniel 529: xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
1.14 daniel 530: int i;
531: xmlEntityPtr cur;
532:
533: if (table == NULL) return;
534:
535: for (i = 0;i < table->nb_entities;i++) {
536: cur = &table->table[i];
537: switch (cur->type) {
538: case XML_INTERNAL_GENERAL_ENTITY:
1.25 daniel 539: xmlBufferWriteChar(buf, "<!ENTITY ");
540: xmlBufferWriteCHAR(buf, cur->name);
541: xmlBufferWriteChar(buf, " \"");
542: xmlBufferWriteCHAR(buf, cur->content);
543: xmlBufferWriteChar(buf, "\">\n");
1.14 daniel 544: break;
545: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
1.25 daniel 546: xmlBufferWriteChar(buf, "<!ENTITY ");
547: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 548: if (cur->ExternalID != NULL) {
1.25 daniel 549: xmlBufferWriteChar(buf, " PUBLIC \"");
550: xmlBufferWriteCHAR(buf, cur->ExternalID);
551: xmlBufferWriteChar(buf, "\" \"");
552: xmlBufferWriteCHAR(buf, cur->SystemID);
553: xmlBufferWriteChar(buf, "\"");
1.14 daniel 554: } else {
1.25 daniel 555: xmlBufferWriteChar(buf, " SYSTEM \"");
556: xmlBufferWriteCHAR(buf, cur->SystemID);
557: xmlBufferWriteChar(buf, "\"");
1.14 daniel 558: }
1.25 daniel 559: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 560: break;
561: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
1.25 daniel 562: xmlBufferWriteChar(buf, "<!ENTITY ");
563: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 564: if (cur->ExternalID != NULL) {
1.25 daniel 565: xmlBufferWriteChar(buf, " PUBLIC \"");
566: xmlBufferWriteCHAR(buf, cur->ExternalID);
567: xmlBufferWriteChar(buf, "\" \"");
568: xmlBufferWriteCHAR(buf, cur->SystemID);
569: xmlBufferWriteChar(buf, "\"");
1.14 daniel 570: } else {
1.25 daniel 571: xmlBufferWriteChar(buf, " SYSTEM \"");
572: xmlBufferWriteCHAR(buf, cur->SystemID);
573: xmlBufferWriteChar(buf, "\"");
1.14 daniel 574: }
575: if (cur->content != NULL) { /* Should be true ! */
1.25 daniel 576: xmlBufferWriteChar(buf, " NDATA ");
577: xmlBufferWriteCHAR(buf, cur->content);
1.14 daniel 578: }
1.25 daniel 579: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 580: break;
581: case XML_INTERNAL_PARAMETER_ENTITY:
1.25 daniel 582: xmlBufferWriteChar(buf, "<!ENTITY % ");
583: xmlBufferWriteCHAR(buf, cur->name);
584: xmlBufferWriteChar(buf, " \"");
585: xmlBufferWriteCHAR(buf, cur->content);
586: xmlBufferWriteChar(buf, "\">\n");
1.14 daniel 587: break;
588: case XML_EXTERNAL_PARAMETER_ENTITY:
1.25 daniel 589: xmlBufferWriteChar(buf, "<!ENTITY % ");
590: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 591: if (cur->ExternalID != NULL) {
1.25 daniel 592: xmlBufferWriteChar(buf, " PUBLIC \"");
593: xmlBufferWriteCHAR(buf, cur->ExternalID);
594: xmlBufferWriteChar(buf, "\" \"");
595: xmlBufferWriteCHAR(buf, cur->SystemID);
596: xmlBufferWriteChar(buf, "\"");
1.14 daniel 597: } else {
1.25 daniel 598: xmlBufferWriteChar(buf, " SYSTEM \"");
599: xmlBufferWriteCHAR(buf, cur->SystemID);
600: xmlBufferWriteChar(buf, "\"");
1.14 daniel 601: }
1.25 daniel 602: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 603: break;
604: default:
605: fprintf(stderr,
606: "xmlDumpEntitiesTable: internal: unknown type %d\n",
607: cur->type);
608: }
609: }
1.13 daniel 610: }
Webmaster