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