Annotation of XML/entities.c, revision 1.15
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.15 ! daniel 6: * $Id: entities.c,v 1.14 1998/08/07 05:15:37 daniel Exp $
1.1 httpng 7: */
8:
9: #include <stdio.h>
10: #include <malloc.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.3 httpng 33: * A buffer used for converting entities to their equivalent and back.
34: */
1.14 daniel 35: static int buffer_size = 0;
1.6 veillard 36: static CHAR *buffer = NULL;
1.3 httpng 37:
38: void growBuffer(void) {
39: buffer_size *= 2;
40: buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
41: if (buffer == NULL) {
42: perror("realloc failed");
43: exit(1);
44: }
45: }
46:
47: /*
1.2 httpng 48: * xmlFreeEntity : clean-up an entity record.
1.1 httpng 49: */
50:
1.2 httpng 51: void xmlFreeEntity(xmlEntityPtr entity) {
52: if (entity == NULL) return;
53:
1.11 daniel 54: if (entity->name != NULL)
55: free((char *) entity->name);
1.14 daniel 56: if (entity->ExternalID != NULL)
57: free((char *) entity->ExternalID);
58: if (entity->SystemID != NULL)
59: free((char *) entity->SystemID);
60: if (entity->content != NULL)
61: free((char *) entity->content);
62: memset(entity, -1, sizeof(xmlEntity));
1.2 httpng 63: }
1.1 httpng 64:
65: /*
1.2 httpng 66: * xmlAddDocEntity : register a new entity for an entities table.
1.13 daniel 67: *
68: * TODO !!! We should check here that the combination of type
69: * ExternalID and SystemID is valid.
1.1 httpng 70: */
1.13 daniel 71: static void xmlAddEntity(xmlEntitiesTablePtr table, const CHAR *name, int type,
72: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.2 httpng 73: int i;
74: xmlEntityPtr cur;
1.14 daniel 75: int len;
1.1 httpng 76:
1.2 httpng 77: for (i = 0;i < table->nb_entities;i++) {
78: cur = &table->table[i];
1.11 daniel 79: if (!xmlStrcmp(cur->name, name)) {
1.13 daniel 80: /*
81: * The entity is already defined in this Dtd, the spec says to NOT
82: * override it ... Is it worth a Warning ??? !!!
83: */
84: return;
1.7 veillard 85: }
1.2 httpng 86: }
87: if (table->nb_entities >= table->max_entities) {
88: /*
89: * need more elements.
90: */
91: table->max_entities *= 2;
92: table->table = (xmlEntityPtr)
93: realloc(table->table, table->max_entities * sizeof(xmlEntity));
94: if (table->table) {
95: perror("realloc failed");
96: exit(1);
97: }
98: }
99: cur = &table->table[table->nb_entities];
1.11 daniel 100: cur->name = xmlStrdup(name);
1.14 daniel 101: for (len = 0;name[0] != 0;name++)len++;
102: cur->len = len;
1.13 daniel 103: cur->type = type;
104: if (ExternalID != NULL)
105: cur->ExternalID = xmlStrdup(ExternalID);
1.14 daniel 106: else
107: cur->ExternalID = NULL;
1.13 daniel 108: if (SystemID != NULL)
1.14 daniel 109: cur->SystemID = xmlStrdup(SystemID);
110: else
111: cur->SystemID = NULL;
1.13 daniel 112: if (content != NULL)
113: cur->content = xmlStrdup(content);
1.14 daniel 114: else
115: cur->content = NULL;
1.2 httpng 116: table->nb_entities++;
117: }
1.1 httpng 118:
1.15 ! daniel 119: /*
! 120: * Set up xmlPredefinedEntities from xmlPredefinedEntityValues.
! 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],
! 141: XML_INTERNAL_GENERAL_ENTITY, NULL, NULL,
! 142: &value[0]);
! 143: }
! 144: }
! 145:
1.1 httpng 146:
147: /*
1.12 daniel 148: * xmlAddDtdEntity : register a new entity for this DTD.
1.1 httpng 149: */
1.13 daniel 150: void xmlAddDtdEntity(xmlDtdPtr dtd, const CHAR *name, int type,
151: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.2 httpng 152: xmlEntitiesTablePtr table;
1.1 httpng 153:
1.2 httpng 154: table = (xmlEntitiesTablePtr) dtd->entities;
155: if (table == NULL) {
156: table = xmlCreateEntitiesTable();
157: dtd->entities = table;
1.1 httpng 158: }
1.13 daniel 159: xmlAddEntity(table, name, type, ExternalID, SystemID, content);
1.1 httpng 160: }
161:
162: /*
1.2 httpng 163: * xmlAddDocEntity : register a new entity for this document.
1.1 httpng 164: */
1.13 daniel 165: void xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
166: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.12 daniel 167: if (doc->dtd == NULL) {
168: fprintf(stderr, "xmlAddDocEntity: document without DTD\n");
169: return;
1.2 httpng 170: }
1.13 daniel 171: xmlAddDtdEntity(doc->dtd, name, type, ExternalID, SystemID, content);
1.1 httpng 172: }
173:
174: /*
175: * xmlGetEntity : do an entity lookup in the hash table and
1.15 ! daniel 176: * returns the corrsponding entity, if found, NULL otherwise.
1.1 httpng 177: */
1.15 ! daniel 178: xmlEntityPtr xmlGetEntity(xmlDocPtr doc, const CHAR *name) {
1.2 httpng 179: int i;
180: xmlEntityPtr cur;
181: xmlEntitiesTablePtr table;
182:
1.15 ! daniel 183: /* Try entities defined in the document DTD if any */
! 184: if ((doc->dtd != NULL) && (doc->dtd->entities != NULL)) {
! 185: table = (xmlEntitiesTablePtr) doc->dtd->entities;
! 186: for (i = 0;i < table->nb_entities;i++) {
! 187: cur = &table->table[i];
! 188: if (!xmlStrcmp(cur->name, name)) return(cur);
! 189: }
! 190: }
! 191: /* Try predefined entities */
! 192: if (xmlPredefinedEntities == NULL)
! 193: xmlInitializePredefinedEntities();
! 194: table = xmlPredefinedEntities;
1.2 httpng 195: for (i = 0;i < table->nb_entities;i++) {
1.15 ! daniel 196: cur = &table->table[i];
! 197: if (!xmlStrcmp(cur->name, name)) return(cur);
1.2 httpng 198: }
1.15 ! daniel 199:
1.7 veillard 200: return(NULL);
1.1 httpng 201: }
202:
203: /*
1.6 veillard 204: * xmlReadEntities : read an entity.
1.12 daniel 205: * TODO !!!! Complete nonsense, rewite !!!
1.1 httpng 206: */
1.7 veillard 207: const CHAR *xmlReadEntity(xmlDocPtr doc, const CHAR **input) {
208: static CHAR *entity = NULL;
209: static int entity_size = 100;
210: const CHAR *cur = *input;
211:
212: if (entity == NULL) {
213: entity = (CHAR *) malloc(entity_size * sizeof(CHAR));
214: if (entity == NULL) {
215: fprintf(stderr, "xmlReadEntity : cannot allocate %d bytes\n",
216: entity_size * sizeof(CHAR));
217: return(NULL);
218: }
219: }
220: if (*cur == '&') {
221: cur++;
222: if (*cur == '#') {
223: /* TODO !!!!
224: fprintf(stderr, "Character reference not yet implemented\n"); */
1.3 httpng 225: } else {
1.7 veillard 226: /* TODO !!!!
227: fprintf(stderr, "Entity search not yet implemented\n"); */
1.3 httpng 228: }
229: }
1.7 veillard 230:
231: /*
232: * The few predefined entities.
233: */
234: if ((cur[0] == 'a') && (cur[1] == 'm') && (cur[2] == 'p') &&
235: (cur[3] == ';')) {
1.13 daniel 236: entity[0] = '&';
1.7 veillard 237: entity[1] = 0;
1.8 veillard 238: cur += 3;
1.7 veillard 239: *input = cur;
240: return(entity);
241: } else if ((cur[0] == 'q') && (cur[1] == 'u') && (cur[2] == 'o') &&
242: (cur[3] == 't') && (cur[4] == ';')) {
243: entity[0] = '"';
244: entity[1] = 0;
245: cur += 4;
246: *input = cur;
247: return(entity);
248: } else if ((cur[0] == 'a') && (cur[1] == 'p') && (cur[2] == 'o') &&
249: (cur[3] == 's') && (cur[4] == ';')) {
250: entity[0] = '\'';
251: entity[1] = 0;
252: cur += 4;
253: *input = cur;
254: return(entity);
255: } else if ((cur[0] == 'l') && (cur[1] == 't') && (cur[2] == ';')) {
256: entity[0] = '<';
257: entity[1] = 0;
1.8 veillard 258: cur += 2;
1.7 veillard 259: *input = cur;
260: return(entity);
261: } else if ((cur[0] == 'g') && (cur[1] == 't') && (cur[2] == ';')) {
262: entity[0] = '>';
263: entity[1] = 0;
1.8 veillard 264: cur += 2;
1.7 veillard 265: *input = cur;
266: return(entity);
1.13 daniel 267: } else {
268: entity[0] = '&';
269: entity[1] = 0;
270: return(entity);
1.7 veillard 271: }
1.13 daniel 272:
1.7 veillard 273:
274: return(NULL);
1.3 httpng 275: }
276:
277: /*
1.14 daniel 278: * xmlEntityLookup : do a lookup for an entity.
279: */
280: const CHAR *xmlEntityLookup(xmlDocPtr doc, const CHAR **input) {
281: static CHAR *entity = NULL;
282: static int entity_size = 10;
283: const CHAR *cur = *input;
284: int isParameter;
285: int i;
286: xmlEntitiesTablePtr table;
287: xmlEntityPtr ent;
288:
1.15 ! daniel 289: if (xmlPredefinedEntities == NULL)
! 290: xmlInitializePredefinedEntities();
! 291:
1.14 daniel 292: if (*cur == '&') isParameter = 0;
293: else if (*cur == '%') isParameter = 1;
294: else return(NULL);
295:
296: if (entity == NULL) {
297: entity = (CHAR *) malloc(entity_size * sizeof(CHAR));
298: if (entity == NULL) {
299: fprintf(stderr, "xmlReadEntity : cannot allocate %d bytes\n",
300: entity_size * sizeof(CHAR));
301: return(NULL);
302: }
303: }
304: /* skip the first char */
305: cur++;
306:
307: /*
308: * The few predefined entities.
309: */
310: if ((cur[0] == 'a') && (cur[1] == 'm') && (cur[2] == 'p') &&
311: (cur[3] == ';')) {
312: entity[0] = '&';
313: entity[1] = 0;
314: cur += 3;
315: *input = cur;
316: return(xmlStrdup(entity));
317: } else if ((cur[0] == 'q') && (cur[1] == 'u') && (cur[2] == 'o') &&
318: (cur[3] == 't') && (cur[4] == ';')) {
319: entity[0] = '"';
320: entity[1] = 0;
321: cur += 4;
322: *input = cur;
323: return(xmlStrdup(entity));
324: } else if ((cur[0] == 'a') && (cur[1] == 'p') && (cur[2] == 'o') &&
325: (cur[3] == 's') && (cur[4] == ';')) {
326: entity[0] = '\'';
327: entity[1] = 0;
328: cur += 4;
329: *input = cur;
330: return(xmlStrdup(entity));
331: } else if ((cur[0] == 'l') && (cur[1] == 't') && (cur[2] == ';')) {
332: entity[0] = '<';
333: entity[1] = 0;
334: cur += 2;
335: *input = cur;
336: return(xmlStrdup(entity));
337: } else if ((cur[0] == 'g') && (cur[1] == 't') && (cur[2] == ';')) {
338: entity[0] = '>';
339: entity[1] = 0;
340: cur += 2;
341: *input = cur;
342: return(xmlStrdup(entity));
343: } else {
344: if ((doc->dtd != NULL) && (doc->dtd->entities != NULL)) {
345: table = (xmlEntitiesTablePtr) doc->dtd->entities;
346: /*
347: * Browse the set of entities declared and check for the
348: * first match...
349: */
350: for (i = 0;i < table->nb_entities;i++) {
351: ent = &table->table[i];
352: if (!xmlStrncmp(ent->name, cur, ent->len)) {
353: switch (ent->type) {
354: case XML_INTERNAL_GENERAL_ENTITY:
355: case XML_INTERNAL_PARAMETER_ENTITY:
356: cur += ent->len;
357: *input = cur;
358: /* Do the substitution on existing entities */
359: return(xmlDecodeEntities(doc, ent->content,
360: ent->len));
361: break;
362: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
363: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
364: case XML_EXTERNAL_PARAMETER_ENTITY:
365: fprintf(stderr,
366: "External entities not supported\n");
367: break;
368: default:
369: fprintf(stderr,
370: "xmlDumpEntitiesTable: internal: unknown type %d\n",
371: ent->type);
372: }
373: }
374: }
375: }
376: if (isParameter)
377: entity[0] = '%';
378: else
379: entity[0] = '&';
380: entity[1] = 0;
381: return(xmlStrdup(entity));
382: }
383:
384:
385: return(NULL);
386: }
387: /*
1.7 veillard 388: * xmlDecodeEntities : do a global entities lookup on a input string
1.3 httpng 389: * and returns a duplicate after the entities substitution.
390: */
1.7 veillard 391: CHAR *xmlDecodeEntities(xmlDocPtr doc, const CHAR *input, int len) {
392: const CHAR *cur = input;
1.14 daniel 393: CHAR *out;
394: CHAR *buffer;
395: int buffer_size;
1.3 httpng 396: int i;
397:
1.14 daniel 398: buffer_size = 10000 + len * 2;
399: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
1.3 httpng 400: if (buffer == NULL) {
1.14 daniel 401: perror("malloc failed");
402: exit(1);
1.3 httpng 403: }
1.14 daniel 404: out = buffer;
1.7 veillard 405: for (i = 0;(*cur != 0) && (cur - input < len);cur++) {
1.3 httpng 406: if (*cur == '&') {
1.14 daniel 407: const CHAR *base, *entity = xmlEntityLookup(doc, &cur);
408: if (entity != NULL) {
409: base = entity;
1.3 httpng 410: while (*entity != 0) {
411: *out++ = *entity++;
412: i++;
1.6 veillard 413: if (i + 10 > buffer_size) {
414: int index = out - buffer;
415:
416: growBuffer();
417: out = &buffer[index];
418: }
1.3 httpng 419: }
1.15 ! daniel 420: free((char *) base);
1.14 daniel 421: }
1.3 httpng 422: } else if (*cur == '%') {
1.7 veillard 423: /* TODO !!!!!
424: fprintf(stderr, " \n"); */
1.3 httpng 425: } else {
1.7 veillard 426: *out++ = *cur;
1.3 httpng 427: i++;
428: }
429:
1.6 veillard 430: if (i + 10 > buffer_size) {
431: int index = out - buffer;
432:
433: growBuffer();
434: out = &buffer[index];
435: }
1.3 httpng 436: }
1.7 veillard 437: *out++ = 0;
1.3 httpng 438: return(buffer);
1.1 httpng 439: }
440:
441: /*
1.2 httpng 442: * xmlEncodeEntities : do a global encoding of a string, replacing the
1.11 daniel 443: * basic content with their entities form.
1.12 daniel 444: * TODO !!!! rewite !!!
1.1 httpng 445: */
1.2 httpng 446: CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) {
1.7 veillard 447: const CHAR *cur = input;
1.3 httpng 448: CHAR *out = buffer;
449:
450: if (buffer == NULL) {
451: buffer_size = 1000;
452: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
453: if (buffer == NULL) {
454: perror("malloc failed");
455: exit(1);
456: }
457: out = buffer;
458: }
1.6 veillard 459: while (*cur != '\0') {
460: if (out - buffer > buffer_size - 100) {
461: int index = out - buffer;
462:
463: growBuffer();
464: out = &buffer[index];
465: }
466:
467: /*
1.7 veillard 468: * By default one have to encode at least '<', '>', '"' and '&' !
469: * One could try a better encoding using the entities defined and
470: * used as a compression code !!!.
1.6 veillard 471: */
472: if (*cur == '<') {
473: *out++ = '&';
474: *out++ = 'l';
475: *out++ = 't';
476: *out++ = ';';
1.7 veillard 477: } else if (*cur == '>') {
478: *out++ = '&';
479: *out++ = 'g';
480: *out++ = 't';
481: *out++ = ';';
1.6 veillard 482: } else if (*cur == '&') {
483: *out++ = '&';
484: *out++ = 'a';
485: *out++ = 'm';
486: *out++ = 'p';
1.7 veillard 487: *out++ = ';';
488: } else if (*cur == '"') {
489: *out++ = '&';
490: *out++ = 'q';
491: *out++ = 'u';
492: *out++ = 'o';
493: *out++ = 't';
494: *out++ = ';';
495: } else if (*cur == '\'') {
496: *out++ = '&';
497: *out++ = 'a';
498: *out++ = 'p';
499: *out++ = 'o';
500: *out++ = 's';
1.6 veillard 501: *out++ = ';';
502: } else {
503: /*
504: * default case, just copy !
505: */
506: *out++ = *cur;
507: }
508: cur++;
509: }
510: *out++ = 0;
511: return(buffer);
1.2 httpng 512: }
513:
514: /*
515: * xmlCreateEntitiesTable : create and initialize an enmpty hash table
516: */
517: xmlEntitiesTablePtr xmlCreateEntitiesTable(void) {
518: xmlEntitiesTablePtr ret;
1.1 httpng 519:
1.2 httpng 520: ret = (xmlEntitiesTablePtr)
521: malloc(sizeof(xmlEntitiesTable));
1.1 httpng 522: if (ret == NULL) {
1.2 httpng 523: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
524: sizeof(xmlEntitiesTable));
525: return(NULL);
526: }
527: ret->max_entities = XML_MIN_ENTITIES_TABLE;
528: ret->nb_entities = 0;
529: ret->table = (xmlEntityPtr )
530: malloc(ret->max_entities * sizeof(xmlEntity));
531: if (ret == NULL) {
532: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
533: ret->max_entities * sizeof(xmlEntity));
534: free(ret);
1.1 httpng 535: return(NULL);
536: }
537: return(ret);
538: }
539:
540: /*
1.2 httpng 541: * xmlFreeEntitiesTable : clean up and free an entities hash table.
1.1 httpng 542: */
1.2 httpng 543: void xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
1.1 httpng 544: int i;
545:
546: if (table == NULL) return;
547:
1.2 httpng 548: for (i = 0;i < table->nb_entities;i++) {
549: xmlFreeEntity(&table->table[i]);
1.1 httpng 550: }
1.2 httpng 551: free(table->table);
1.1 httpng 552: free(table);
553: }
554:
1.13 daniel 555: /*
556: * Dump the content of an entity table to the document output.
557: */
558: void xmlDumpEntitiesTable(xmlEntitiesTablePtr table) {
1.14 daniel 559: int i;
560: xmlEntityPtr cur;
561:
562: if (table == NULL) return;
563:
564: for (i = 0;i < table->nb_entities;i++) {
565: cur = &table->table[i];
566: switch (cur->type) {
567: case XML_INTERNAL_GENERAL_ENTITY:
568: xmlBufferWriteChar("<!ENTITY ");
569: xmlBufferWriteCHAR(cur->name);
570: xmlBufferWriteChar(" \"");
571: xmlBufferWriteCHAR(cur->content);
572: xmlBufferWriteChar("\">\n");
573: break;
574: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
575: xmlBufferWriteChar("<!ENTITY ");
576: xmlBufferWriteCHAR(cur->name);
577: if (cur->ExternalID != NULL) {
578: xmlBufferWriteChar(" PUBLIC \"");
579: xmlBufferWriteCHAR(cur->ExternalID);
580: xmlBufferWriteChar("\" \"");
581: xmlBufferWriteCHAR(cur->SystemID);
582: xmlBufferWriteChar("\"");
583: } else {
584: xmlBufferWriteChar(" SYSTEM \"");
585: xmlBufferWriteCHAR(cur->SystemID);
586: xmlBufferWriteChar("\"");
587: }
588: xmlBufferWriteChar(">\n");
589: break;
590: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
591: xmlBufferWriteChar("<!ENTITY ");
592: xmlBufferWriteCHAR(cur->name);
593: if (cur->ExternalID != NULL) {
594: xmlBufferWriteChar(" PUBLIC \"");
595: xmlBufferWriteCHAR(cur->ExternalID);
596: xmlBufferWriteChar("\" \"");
597: xmlBufferWriteCHAR(cur->SystemID);
598: xmlBufferWriteChar("\"");
599: } else {
600: xmlBufferWriteChar(" SYSTEM \"");
601: xmlBufferWriteCHAR(cur->SystemID);
602: xmlBufferWriteChar("\"");
603: }
604: if (cur->content != NULL) { /* Should be true ! */
605: xmlBufferWriteChar(" NDATA ");
606: xmlBufferWriteCHAR(cur->content);
607: }
608: xmlBufferWriteChar(">\n");
609: break;
610: case XML_INTERNAL_PARAMETER_ENTITY:
611: xmlBufferWriteChar("<!ENTITY % ");
612: xmlBufferWriteCHAR(cur->name);
613: xmlBufferWriteChar(" \"");
614: xmlBufferWriteCHAR(cur->content);
615: xmlBufferWriteChar("\">\n");
616: break;
617: case XML_EXTERNAL_PARAMETER_ENTITY:
618: xmlBufferWriteChar("<!ENTITY % ");
619: xmlBufferWriteCHAR(cur->name);
620: if (cur->ExternalID != NULL) {
621: xmlBufferWriteChar(" PUBLIC \"");
622: xmlBufferWriteCHAR(cur->ExternalID);
623: xmlBufferWriteChar("\" \"");
624: xmlBufferWriteCHAR(cur->SystemID);
625: xmlBufferWriteChar("\"");
626: } else {
627: xmlBufferWriteChar(" SYSTEM \"");
628: xmlBufferWriteCHAR(cur->SystemID);
629: xmlBufferWriteChar("\"");
630: }
631: xmlBufferWriteChar(">\n");
632: break;
633: default:
634: fprintf(stderr,
635: "xmlDumpEntitiesTable: internal: unknown type %d\n",
636: cur->type);
637: }
638: }
1.13 daniel 639: }
Webmaster