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