Bug Summary

File:xmlsave.c
Location:line 979, column 6
Description:Value stored to 'switched_encoding' is never read

Annotated Source Code

1/*
2 * xmlsave.c: Implemetation of the document serializer
3 *
4 * See Copyright for the status of this software.
5 *
6 * daniel@veillard.com
7 */
8
9#define IN_LIBXML
10#include "libxml.h"
11
12#include <string.h>
13#include <libxml/xmlmemory.h>
14#include <libxml/parserInternals.h>
15#include <libxml/tree.h>
16#include <libxml/xmlsave.h>
17
18#define MAX_INDENT60 60
19
20#include <libxml/HTMLtree.h>
21
22/************************************************************************
23 * *
24 * XHTML detection *
25 * *
26 ************************************************************************/
27#define XHTML_STRICT_PUBLIC_ID(xmlChar *) "-//W3C//DTD XHTML 1.0 Strict//EN" BAD_CAST(xmlChar *) \
28 "-//W3C//DTD XHTML 1.0 Strict//EN"
29#define XHTML_STRICT_SYSTEM_ID(xmlChar *) "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" BAD_CAST(xmlChar *) \
30 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
31#define XHTML_FRAME_PUBLIC_ID(xmlChar *) "-//W3C//DTD XHTML 1.0 Frameset//EN" BAD_CAST(xmlChar *) \
32 "-//W3C//DTD XHTML 1.0 Frameset//EN"
33#define XHTML_FRAME_SYSTEM_ID(xmlChar *) "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd" BAD_CAST(xmlChar *) \
34 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"
35#define XHTML_TRANS_PUBLIC_ID(xmlChar *) "-//W3C//DTD XHTML 1.0 Transitional//EN" BAD_CAST(xmlChar *) \
36 "-//W3C//DTD XHTML 1.0 Transitional//EN"
37#define XHTML_TRANS_SYSTEM_ID(xmlChar *) "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" BAD_CAST(xmlChar *) \
38 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
39
40#define XHTML_NS_NAME(xmlChar *) "http://www.w3.org/1999/xhtml" BAD_CAST(xmlChar *) "http://www.w3.org/1999/xhtml"
41/**
42 * xmlIsXHTML:
43 * @systemID: the system identifier
44 * @publicID: the public identifier
45 *
46 * Try to find if the document correspond to an XHTML DTD
47 *
48 * Returns 1 if true, 0 if not and -1 in case of error
49 */
50int
51xmlIsXHTML(const xmlChar *systemID, const xmlChar *publicID) {
52 if ((systemID == NULL((void*)0)) && (publicID == NULL((void*)0)))
53 return(-1);
54 if (publicID != NULL((void*)0)) {
55 if (xmlStrEqualxmlStrEqual__internal_alias(publicID, XHTML_STRICT_PUBLIC_ID(xmlChar *) "-//W3C//DTD XHTML 1.0 Strict//EN")) return(1);
56 if (xmlStrEqualxmlStrEqual__internal_alias(publicID, XHTML_FRAME_PUBLIC_ID(xmlChar *) "-//W3C//DTD XHTML 1.0 Frameset//EN")) return(1);
57 if (xmlStrEqualxmlStrEqual__internal_alias(publicID, XHTML_TRANS_PUBLIC_ID(xmlChar *) "-//W3C//DTD XHTML 1.0 Transitional//EN")) return(1);
58 }
59 if (systemID != NULL((void*)0)) {
60 if (xmlStrEqualxmlStrEqual__internal_alias(systemID, XHTML_STRICT_SYSTEM_ID(xmlChar *) "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd")) return(1);
61 if (xmlStrEqualxmlStrEqual__internal_alias(systemID, XHTML_FRAME_SYSTEM_ID(xmlChar *) "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd")) return(1);
62 if (xmlStrEqualxmlStrEqual__internal_alias(systemID, XHTML_TRANS_SYSTEM_ID(xmlChar *) "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd")) return(1);
63 }
64 return(0);
65}
66
67#ifdef LIBXML_OUTPUT_ENABLED
68
69#define TODO(*(__xmlGenericError__internal_alias()))((*(__xmlGenericErrorContext__internal_alias
())), "Unimplemented block at %s:%d\n", "xmlsave.c", 69);
\
70 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())), \
71 "Unimplemented block at %s:%d\n", \
72 __FILE__"xmlsave.c", __LINE__72);
73
74struct _xmlSaveCtxt {
75 void *_private;
76 int type;
77 int fd;
78 const xmlChar *filename;
79 const xmlChar *encoding;
80 xmlCharEncodingHandlerPtr handler;
81 xmlOutputBufferPtr buf;
82 xmlDocPtr doc;
83 int options;
84 int level;
85 int format;
86 char indent[MAX_INDENT60 + 1]; /* array for indenting output */
87 int indent_nr;
88 int indent_size;
89 xmlCharEncodingOutputFunc escape; /* used for element content */
90 xmlCharEncodingOutputFunc escapeAttr;/* used for attribute content */
91};
92
93/************************************************************************
94 * *
95 * Output error handlers *
96 * *
97 ************************************************************************/
98/**
99 * xmlSaveErrMemory:
100 * @extra: extra informations
101 *
102 * Handle an out of memory condition
103 */
104static void
105xmlSaveErrMemory(const char *extra)
106{
107 __xmlSimpleError(XML_FROM_OUTPUT, XML_ERR_NO_MEMORY, NULL((void*)0), NULL((void*)0), extra);
108}
109
110/**
111 * xmlSaveErr:
112 * @code: the error number
113 * @node: the location of the error.
114 * @extra: extra informations
115 *
116 * Handle an out of memory condition
117 */
118static void
119xmlSaveErr(int code, xmlNodePtr node, const char *extra)
120{
121 const char *msg = NULL((void*)0);
122
123 switch(code) {
124 case XML_SAVE_NOT_UTF8:
125 msg = "string is not in UTF-8\n";
126 break;
127 case XML_SAVE_CHAR_INVALID:
128 msg = "invalid character value\n";
129 break;
130 case XML_SAVE_UNKNOWN_ENCODING:
131 msg = "unknown encoding %s\n";
132 break;
133 case XML_SAVE_NO_DOCTYPE:
134 msg = "document has no DOCTYPE\n";
135 break;
136 default:
137 msg = "unexpected error number\n";
138 }
139 __xmlSimpleError(XML_FROM_OUTPUT, code, node, msg, extra);
140}
141
142/************************************************************************
143 * *
144 * Special escaping routines *
145 * *
146 ************************************************************************/
147static unsigned char *
148xmlSerializeHexCharRef(unsigned char *out, int val) {
149 unsigned char *ptr;
150
151 *out++ = '&';
152 *out++ = '#';
153 *out++ = 'x';
154 if (val < 0x10) ptr = out;
155 else if (val < 0x100) ptr = out + 1;
156 else if (val < 0x1000) ptr = out + 2;
157 else if (val < 0x10000) ptr = out + 3;
158 else if (val < 0x100000) ptr = out + 4;
159 else ptr = out + 5;
160 out = ptr + 1;
161 while (val > 0) {
162 switch (val & 0xF) {
163 case 0: *ptr-- = '0'; break;
164 case 1: *ptr-- = '1'; break;
165 case 2: *ptr-- = '2'; break;
166 case 3: *ptr-- = '3'; break;
167 case 4: *ptr-- = '4'; break;
168 case 5: *ptr-- = '5'; break;
169 case 6: *ptr-- = '6'; break;
170 case 7: *ptr-- = '7'; break;
171 case 8: *ptr-- = '8'; break;
172 case 9: *ptr-- = '9'; break;
173 case 0xA: *ptr-- = 'A'; break;
174 case 0xB: *ptr-- = 'B'; break;
175 case 0xC: *ptr-- = 'C'; break;
176 case 0xD: *ptr-- = 'D'; break;
177 case 0xE: *ptr-- = 'E'; break;
178 case 0xF: *ptr-- = 'F'; break;
179 default: *ptr-- = '0'; break;
180 }
181 val >>= 4;
182 }
183 *out++ = ';';
184 *out = 0;
185 return(out);
186}
187
188/**
189 * xmlEscapeEntities:
190 * @out: a pointer to an array of bytes to store the result
191 * @outlen: the length of @out
192 * @in: a pointer to an array of unescaped UTF-8 bytes
193 * @inlen: the length of @in
194 *
195 * Take a block of UTF-8 chars in and escape them. Used when there is no
196 * encoding specified.
197 *
198 * Returns 0 if success, or -1 otherwise
199 * The value of @inlen after return is the number of octets consumed
200 * if the return value is positive, else unpredictable.
201 * The value of @outlen after return is the number of octets consumed.
202 */
203static int
204xmlEscapeEntities(unsigned char* out, int *outlen,
205 const xmlChar* in, int *inlen) {
206 unsigned char* outstart = out;
207 const unsigned char* base = in;
208 unsigned char* outend = out + *outlen;
209 const unsigned char* inend;
210 int val;
211
212 inend = in + (*inlen);
213
214 while ((in < inend) && (out < outend)) {
215 if (*in == '<') {
216 if (outend - out < 4) break;
217 *out++ = '&';
218 *out++ = 'l';
219 *out++ = 't';
220 *out++ = ';';
221 in++;
222 continue;
223 } else if (*in == '>') {
224 if (outend - out < 4) break;
225 *out++ = '&';
226 *out++ = 'g';
227 *out++ = 't';
228 *out++ = ';';
229 in++;
230 continue;
231 } else if (*in == '&') {
232 if (outend - out < 5) break;
233 *out++ = '&';
234 *out++ = 'a';
235 *out++ = 'm';
236 *out++ = 'p';
237 *out++ = ';';
238 in++;
239 continue;
240 } else if (((*in >= 0x20) && (*in < 0x80)) ||
241 (*in == '\n') || (*in == '\t')) {
242 /*
243 * default case, just copy !
244 */
245 *out++ = *in++;
246 continue;
247 } else if (*in >= 0x80) {
248 /*
249 * We assume we have UTF-8 input.
250 */
251 if (outend - out < 10) break;
252
253 if (*in < 0xC0) {
254 xmlSaveErr(XML_SAVE_NOT_UTF8, NULL((void*)0), NULL((void*)0));
255 in++;
256 goto error;
257 } else if (*in < 0xE0) {
258 if (inend - in < 2) break;
259 val = (in[0]) & 0x1F;
260 val <<= 6;
261 val |= (in[1]) & 0x3F;
262 in += 2;
263 } else if (*in < 0xF0) {
264 if (inend - in < 3) break;
265 val = (in[0]) & 0x0F;
266 val <<= 6;
267 val |= (in[1]) & 0x3F;
268 val <<= 6;
269 val |= (in[2]) & 0x3F;
270 in += 3;
271 } else if (*in < 0xF8) {
272 if (inend - in < 4) break;
273 val = (in[0]) & 0x07;
274 val <<= 6;
275 val |= (in[1]) & 0x3F;
276 val <<= 6;
277 val |= (in[2]) & 0x3F;
278 val <<= 6;
279 val |= (in[3]) & 0x3F;
280 in += 4;
281 } else {
282 xmlSaveErr(XML_SAVE_CHAR_INVALID, NULL((void*)0), NULL((void*)0));
283 in++;
284 goto error;
285 }
286 if (!IS_CHAR(val)(((val) < 0x100) ? (((0x9 <= ((val))) && (((val
)) <= 0xa)) || (((val)) == 0xd) || (0x20 <= ((val)))) :
(((0x100 <= (val)) && ((val) <= 0xd7ff)) || ((
0xe000 <= (val)) && ((val) <= 0xfffd)) || ((0x10000
<= (val)) && ((val) <= 0x10ffff))))
) {
287 xmlSaveErr(XML_SAVE_CHAR_INVALID, NULL((void*)0), NULL((void*)0));
288 in++;
289 goto error;
290 }
291
292 /*
293 * We could do multiple things here. Just save as a char ref
294 */
295 out = xmlSerializeHexCharRef(out, val);
296 } else if (IS_BYTE_CHAR(*in)(((0x9 <= (*in)) && ((*in) <= 0xa)) || ((*in) ==
0xd) || (0x20 <= (*in)))
) {
297 if (outend - out < 6) break;
298 out = xmlSerializeHexCharRef(out, *in++);
299 } else {
300 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
301 "xmlEscapeEntities : char out of range\n");
302 in++;
303 goto error;
304 }
305 }
306 *outlen = out - outstart;
307 *inlen = in - base;
308 return(0);
309error:
310 *outlen = out - outstart;
311 *inlen = in - base;
312 return(-1);
313}
314
315/************************************************************************
316 * *
317 * Allocation and deallocation *
318 * *
319 ************************************************************************/
320/**
321 * xmlSaveCtxtInit:
322 * @ctxt: the saving context
323 *
324 * Initialize a saving context
325 */
326static void
327xmlSaveCtxtInit(xmlSaveCtxtPtr ctxt)
328{
329 int i;
330 int len;
331
332 if (ctxt == NULL((void*)0)) return;
333 if ((ctxt->encoding == NULL((void*)0)) && (ctxt->escape == NULL((void*)0)))
334 ctxt->escape = xmlEscapeEntities;
335 len = xmlStrlenxmlStrlen__internal_alias((xmlChar *)xmlTreeIndentString(*(__xmlTreeIndentString())));
336 if ((xmlTreeIndentString(*(__xmlTreeIndentString())) == NULL((void*)0)) || (len == 0)) {
337 memset(&ctxt->indent[0], 0, MAX_INDENT60 + 1);
338 } else {
339 ctxt->indent_size = len;
340 ctxt->indent_nr = MAX_INDENT60 / ctxt->indent_size;
341 for (i = 0;i < ctxt->indent_nr;i++)
342 memcpy(&ctxt->indent[i * ctxt->indent_size], xmlTreeIndentString(*(__xmlTreeIndentString())),
343 ctxt->indent_size);
344 ctxt->indent[ctxt->indent_nr * ctxt->indent_size] = 0;
345 }
346
347 if (xmlSaveNoEmptyTags(*(__xmlSaveNoEmptyTags()))) {
348 ctxt->options |= XML_SAVE_NO_EMPTY;
349 }
350}
351
352/**
353 * xmlFreeSaveCtxt:
354 *
355 * Free a saving context, destroying the ouptut in any remaining buffer
356 */
357static void
358xmlFreeSaveCtxt(xmlSaveCtxtPtr ctxt)
359{
360 if (ctxt == NULL((void*)0)) return;
361 if (ctxt->encoding != NULL((void*)0))
362 xmlFree((char *) ctxt->encoding);
363 if (ctxt->buf != NULL((void*)0))
364 xmlOutputBufferClosexmlOutputBufferClose__internal_alias(ctxt->buf);
365 xmlFree(ctxt);
366}
367
368/**
369 * xmlNewSaveCtxt:
370 *
371 * Create a new saving context
372 *
373 * Returns the new structure or NULL in case of error
374 */
375static xmlSaveCtxtPtr
376xmlNewSaveCtxt(const char *encoding, int options)
377{
378 xmlSaveCtxtPtr ret;
379
380 ret = (xmlSaveCtxtPtr) xmlMalloc(sizeof(xmlSaveCtxt));
381 if (ret == NULL((void*)0)) {
382 xmlSaveErrMemory("creating saving context");
383 return ( NULL((void*)0) );
384 }
385 memset(ret, 0, sizeof(xmlSaveCtxt));
386
387 if (encoding != NULL((void*)0)) {
388 ret->handler = xmlFindCharEncodingHandlerxmlFindCharEncodingHandler__internal_alias(encoding);
389 if (ret->handler == NULL((void*)0)) {
390 xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL((void*)0), encoding);
391 xmlFreeSaveCtxt(ret);
392 return(NULL((void*)0));
393 }
394 ret->encoding = xmlStrdupxmlStrdup__internal_alias((const xmlChar *)encoding);
395 ret->escape = NULL((void*)0);
396 }
397 xmlSaveCtxtInit(ret);
398
399 /*
400 * Use the options
401 */
402
403 /* Re-check this option as it may already have been set */
404 if ((ret->options & XML_SAVE_NO_EMPTY) && ! (options & XML_SAVE_NO_EMPTY)) {
405 options |= XML_SAVE_NO_EMPTY;
406 }
407
408 ret->options = options;
409 if (options & XML_SAVE_FORMAT)
410 ret->format = 1;
411
412 return(ret);
413}
414
415/************************************************************************
416 * *
417 * Dumping XML tree content to a simple buffer *
418 * *
419 ************************************************************************/
420/**
421 * xmlAttrSerializeContent:
422 * @buf: the XML buffer output
423 * @doc: the document
424 * @attr: the attribute pointer
425 *
426 * Serialize the attribute in the buffer
427 */
428static void
429xmlAttrSerializeContent(xmlOutputBufferPtr buf, xmlAttrPtr attr)
430{
431 xmlNodePtr children;
432
433 children = attr->children;
434 while (children != NULL((void*)0)) {
435 switch (children->type) {
436 case XML_TEXT_NODE:
437 xmlAttrSerializeTxtContent(buf->buffer, attr->doc,
438 attr, children->content);
439 break;
440 case XML_ENTITY_REF_NODE:
441 xmlBufferAddxmlBufferAdd__internal_alias(buf->buffer, BAD_CAST(xmlChar *) "&", 1);
442 xmlBufferAddxmlBufferAdd__internal_alias(buf->buffer, children->name,
443 xmlStrlenxmlStrlen__internal_alias(children->name));
444 xmlBufferAddxmlBufferAdd__internal_alias(buf->buffer, BAD_CAST(xmlChar *) ";", 1);
445 break;
446 default:
447 /* should not happen unless we have a badly built tree */
448 break;
449 }
450 children = children->next;
451 }
452}
453
454/************************************************************************
455 * *
456 * Dumping XML tree content to an I/O output buffer *
457 * *
458 ************************************************************************/
459
460static int xmlSaveSwitchEncoding(xmlSaveCtxtPtr ctxt, const char *encoding) {
461 xmlOutputBufferPtr buf = ctxt->buf;
462
463 if ((encoding != NULL((void*)0)) && (buf->encoder == NULL((void*)0)) && (buf->conv == NULL((void*)0))) {
464 buf->encoder = xmlFindCharEncodingHandlerxmlFindCharEncodingHandler__internal_alias((const char *)encoding);
465 if (buf->encoder == NULL((void*)0)) {
466 xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL((void*)0),
467 (const char *)encoding);
468 return(-1);
469 }
470 buf->conv = xmlBufferCreatexmlBufferCreate__internal_alias();
471 if (buf->conv == NULL((void*)0)) {
472 xmlCharEncCloseFuncxmlCharEncCloseFunc__internal_alias(buf->encoder);
473 xmlSaveErrMemory("creating encoding buffer");
474 return(-1);
475 }
476 /*
477 * initialize the state, e.g. if outputting a BOM
478 */
479 xmlCharEncOutFuncxmlCharEncOutFunc__internal_alias(buf->encoder, buf->conv, NULL((void*)0));
480 }
481 return(0);
482}
483
484static int xmlSaveClearEncoding(xmlSaveCtxtPtr ctxt) {
485 xmlOutputBufferPtr buf = ctxt->buf;
486 xmlOutputBufferFlushxmlOutputBufferFlush__internal_alias(buf);
487 xmlCharEncCloseFuncxmlCharEncCloseFunc__internal_alias(buf->encoder);
488 xmlBufferFreexmlBufferFree__internal_alias(buf->conv);
489 buf->encoder = NULL((void*)0);
490 buf->conv = NULL((void*)0);
491 return(0);
492}
493
494#ifdef LIBXML_HTML_ENABLED
495static void
496xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
497#endif
498static void xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
499static void xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
500void xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur);
501static int xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur);
502
503/**
504 * xmlNsDumpOutput:
505 * @buf: the XML buffer output
506 * @cur: a namespace
507 *
508 * Dump a local Namespace definition.
509 * Should be called in the context of attributes dumps.
510 */
511static void
512xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
513 if ((cur == NULL((void*)0)) || (buf == NULL((void*)0))) return;
514 if ((cur->type == XML_LOCAL_NAMESPACEXML_NAMESPACE_DECL) && (cur->href != NULL((void*)0))) {
515 if (xmlStrEqualxmlStrEqual__internal_alias(cur->prefix, BAD_CAST(xmlChar *) "xml"))
516 return;
517
518 /* Within the context of an element attributes */
519 if (cur->prefix != NULL((void*)0)) {
520 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 7, " xmlns:");
521 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->prefix);
522 } else
523 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 6, " xmlns");
524 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "=");
525 xmlBufferWriteQuotedStringxmlBufferWriteQuotedString__internal_alias(buf->buffer, cur->href);
526 }
527}
528
529/**
530 * xmlNsListDumpOutput:
531 * @buf: the XML buffer output
532 * @cur: the first namespace
533 *
534 * Dump a list of local Namespace definitions.
535 * Should be called in the context of attributes dumps.
536 */
537void
538xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
539 while (cur != NULL((void*)0)) {
540 xmlNsDumpOutput(buf, cur);
541 cur = cur->next;
542 }
543}
544
545/**
546 * xmlDtdDumpOutput:
547 * @buf: the XML buffer output
548 * @dtd: the pointer to the DTD
549 *
550 * Dump the XML document DTD, if any.
551 */
552static void
553xmlDtdDumpOutput(xmlSaveCtxtPtr ctxt, xmlDtdPtr dtd) {
554 xmlOutputBufferPtr buf;
555 int format, level;
556 xmlDocPtr doc;
557
558 if (dtd == NULL((void*)0)) return;
559 if ((ctxt == NULL((void*)0)) || (ctxt->buf == NULL((void*)0)))
560 return;
561 buf = ctxt->buf;
562 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 10, "<!DOCTYPE ");
563 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)dtd->name);
564 if (dtd->ExternalID != NULL((void*)0)) {
565 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 8, " PUBLIC ");
566 xmlBufferWriteQuotedStringxmlBufferWriteQuotedString__internal_alias(buf->buffer, dtd->ExternalID);
567 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, " ");
568 xmlBufferWriteQuotedStringxmlBufferWriteQuotedString__internal_alias(buf->buffer, dtd->SystemID);
569 } else if (dtd->SystemID != NULL((void*)0)) {
570 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 8, " SYSTEM ");
571 xmlBufferWriteQuotedStringxmlBufferWriteQuotedString__internal_alias(buf->buffer, dtd->SystemID);
572 }
573 if ((dtd->entities == NULL((void*)0)) && (dtd->elements == NULL((void*)0)) &&
574 (dtd->attributes == NULL((void*)0)) && (dtd->notations == NULL((void*)0)) &&
575 (dtd->pentities == NULL((void*)0))) {
576 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ">");
577 return;
578 }
579 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 3, " [\n");
580 /*
581 * Dump the notations first they are not in the DTD children list
582 * Do this only on a standalone DTD or on the internal subset though.
583 */
584 if ((dtd->notations != NULL((void*)0)) && ((dtd->doc == NULL((void*)0)) ||
585 (dtd->doc->intSubset == dtd))) {
586 xmlDumpNotationTablexmlDumpNotationTable__internal_alias(buf->buffer, (xmlNotationTablePtr) dtd->notations);
587 }
588 format = ctxt->format;
589 level = ctxt->level;
590 doc = ctxt->doc;
591 ctxt->format = 0;
592 ctxt->level = -1;
593 ctxt->doc = dtd->doc;
594 xmlNodeListDumpOutput(ctxt, dtd->children);
595 ctxt->format = format;
596 ctxt->level = level;
597 ctxt->doc = doc;
598 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "]>");
599}
600
601/**
602 * xmlAttrDumpOutput:
603 * @buf: the XML buffer output
604 * @cur: the attribute pointer
605 *
606 * Dump an XML attribute
607 */
608static void
609xmlAttrDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
610 xmlOutputBufferPtr buf;
611
612 if (cur == NULL((void*)0)) return;
613 buf = ctxt->buf;
614 if (buf == NULL((void*)0)) return;
615 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, " ");
616 if ((cur->ns != NULL((void*)0)) && (cur->ns->prefix != NULL((void*)0))) {
617 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->ns->prefix);
618 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ":");
619 }
620 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
621 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "=\"");
622 xmlAttrSerializeContent(buf, cur);
623 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\"");
624}
625
626/**
627 * xmlAttrListDumpOutput:
628 * @buf: the XML buffer output
629 * @doc: the document
630 * @cur: the first attribute pointer
631 * @encoding: an optional encoding string
632 *
633 * Dump a list of XML attributes
634 */
635static void
636xmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
637 if (cur == NULL((void*)0)) return;
638 while (cur != NULL((void*)0)) {
639 xmlAttrDumpOutput(ctxt, cur);
640 cur = cur->next;
641 }
642}
643
644
645
646/**
647 * xmlNodeListDumpOutput:
648 * @cur: the first node
649 *
650 * Dump an XML node list, recursive behaviour, children are printed too.
651 */
652static void
653xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
654 xmlOutputBufferPtr buf;
655
656 if (cur == NULL((void*)0)) return;
657 buf = ctxt->buf;
658 while (cur != NULL((void*)0)) {
659 if ((ctxt->format) && (xmlIndentTreeOutput(*(__xmlIndentTreeOutput()))) &&
660 ((cur->type == XML_ELEMENT_NODE) ||
661 (cur->type == XML_COMMENT_NODE) ||
662 (cur->type == XML_PI_NODE)))
663 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, ctxt->indent_size *
664 (ctxt->level > ctxt->indent_nr ?
665 ctxt->indent_nr : ctxt->level),
666 ctxt->indent);
667 xmlNodeDumpOutputInternal(ctxt, cur);
668 if (ctxt->format) {
669 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\n");
670 }
671 cur = cur->next;
672 }
673}
674
675#ifdef LIBXML_HTML_ENABLED
676/**
677 * xmlNodeDumpOutputInternal:
678 * @cur: the current node
679 *
680 * Dump an HTML node, recursive behaviour, children are printed too.
681 */
682static int
683htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
684 const xmlChar *oldenc = NULL((void*)0);
685 const xmlChar *oldctxtenc = ctxt->encoding;
686 const xmlChar *encoding = ctxt->encoding;
687 xmlOutputBufferPtr buf = ctxt->buf;
688 int switched_encoding = 0;
689 xmlDocPtr doc;
690
691 xmlInitParserxmlInitParser__internal_alias();
692
693 doc = cur->doc; {
694 if (doc != NULL((void*)0))
695 oldenc = doc->encoding;
696 if (ctxt->encoding != NULL((void*)0)) {
697 doc->encoding = BAD_CAST(xmlChar *) ctxt->encoding;
698 } else if (doc->encoding != NULL((void*)0)) {
699 encoding = doc->encoding;
700 }
701 }
702
703 if ((encoding != NULL((void*)0)) && (doc != NULL((void*)0)))
704 htmlSetMetaEncodinghtmlSetMetaEncoding__internal_alias(doc, (const xmlChar *) encoding);
705 if ((encoding == NULL((void*)0)) && (doc != NULL((void*)0)))
706 encoding = htmlGetMetaEncodinghtmlGetMetaEncoding__internal_alias(doc);
707 if (encoding == NULL((void*)0))
708 encoding = BAD_CAST(xmlChar *) "HTML";
709 if ((encoding != NULL((void*)0)) && (oldctxtenc == NULL((void*)0)) &&
710 (buf->encoder == NULL((void*)0)) && (buf->conv == NULL((void*)0))) {
711 if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
712 doc->encoding = oldenc;
713 return(-1);
714 }
715 switched_encoding = 1;
716 }
717 if (ctxt->options & XML_SAVE_FORMAT)
718 htmlNodeDumpFormatOutputhtmlNodeDumpFormatOutput__internal_alias(buf, doc, cur,
719 (const char *)encoding, 1);
720 else
721 htmlNodeDumpFormatOutputhtmlNodeDumpFormatOutput__internal_alias(buf, doc, cur,
722 (const char *)encoding, 0);
723 /*
724 * Restore the state of the saving context at the end of the document
725 */
726 if ((switched_encoding) && (oldctxtenc == NULL((void*)0))) {
727 xmlSaveClearEncoding(ctxt);
728 }
729 if (doc != NULL((void*)0))
730 doc->encoding = oldenc;
731 return(0);
732}
733#endif
734
735/**
736 * xmlNodeDumpOutputInternal:
737 * @cur: the current node
738 *
739 * Dump an XML node, recursive behaviour, children are printed too.
740 */
741static void
742xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
743 int format;
744 xmlNodePtr tmp;
745 xmlChar *start, *end;
746 xmlOutputBufferPtr buf;
747
748 if (cur == NULL((void*)0)) return;
749 buf = ctxt->buf;
750 if (cur->type == XML_XINCLUDE_START)
751 return;
752 if (cur->type == XML_XINCLUDE_END)
753 return;
754 if ((cur->type == XML_DOCUMENT_NODE) ||
755 (cur->type == XML_HTML_DOCUMENT_NODE)) {
756 xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
757 return;
758 }
759#ifdef LIBXML_HTML_ENABLED
760 if (ctxt->options & XML_SAVE_XHTML) {
761 xhtmlNodeDumpOutput(ctxt, cur);
762 return;
763 }
764 if (((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL((void*)0)) &&
765 (cur->doc->type == XML_HTML_DOCUMENT_NODE) &&
766 ((ctxt->options & XML_SAVE_AS_XML) == 0)) ||
767 (ctxt->options & XML_SAVE_AS_HTML)) {
768 htmlNodeDumpOutputInternal(ctxt, cur);
769 return;
770 }
771#endif
772 if (cur->type == XML_DTD_NODE) {
773 xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
774 return;
775 }
776 if (cur->type == XML_DOCUMENT_FRAG_NODE) {
777 xmlNodeListDumpOutput(ctxt, cur->children);
778 return;
779 }
780 if (cur->type == XML_ELEMENT_DECL) {
781 xmlDumpElementDeclxmlDumpElementDecl__internal_alias(buf->buffer, (xmlElementPtr) cur);
782 return;
783 }
784 if (cur->type == XML_ATTRIBUTE_DECL) {
785 xmlDumpAttributeDeclxmlDumpAttributeDecl__internal_alias(buf->buffer, (xmlAttributePtr) cur);
786 return;
787 }
788 if (cur->type == XML_ENTITY_DECL) {
789 xmlDumpEntityDeclxmlDumpEntityDecl__internal_alias(buf->buffer, (xmlEntityPtr) cur);
790 return;
791 }
792 if (cur->type == XML_TEXT_NODE) {
793 if (cur->content != NULL((void*)0)) {
794 if (cur->name != xmlStringTextNoenc) {
795 xmlOutputBufferWriteEscapexmlOutputBufferWriteEscape__internal_alias(buf, cur->content, ctxt->escape);
796 } else {
797 /*
798 * Disable escaping, needed for XSLT
799 */
800 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *) cur->content);
801 }
802 }
803
804 return;
805 }
806 if (cur->type == XML_PI_NODE) {
807 if (cur->content != NULL((void*)0)) {
808 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "<?");
809 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
810 if (cur->content != NULL((void*)0)) {
811 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, " ");
812 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->content);
813 }
814 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "?>");
815 } else {
816 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "<?");
817 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
818 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "?>");
819 }
820 return;
821 }
822 if (cur->type == XML_COMMENT_NODE) {
823 if (cur->content != NULL((void*)0)) {
824 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 4, "<!--");
825 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->content);
826 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 3, "-->");
827 }
828 return;
829 }
830 if (cur->type == XML_ENTITY_REF_NODE) {
831 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "&");
832 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
833 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ";");
834 return;
835 }
836 if (cur->type == XML_CDATA_SECTION_NODE) {
837 if (cur->content == NULL((void*)0) || *cur->content == '\0') {
838 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 12, "<![CDATA[]]>");
839 } else {
840 start = end = cur->content;
841 while (*end != '\0') {
842 if ((*end == ']') && (*(end + 1) == ']') &&
843 (*(end + 2) == '>')) {
844 end = end + 2;
845 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 9, "<![CDATA[");
846 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, end - start, (const char *)start);
847 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 3, "]]>");
848 start = end;
849 }
850 end++;
851 }
852 if (start != end) {
853 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 9, "<![CDATA[");
854 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)start);
855 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 3, "]]>");
856 }
857 }
858 return;
859 }
860 if (cur->type == XML_ATTRIBUTE_NODE) {
861 xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
862 return;
863 }
864 if (cur->type == XML_NAMESPACE_DECL) {
865 xmlNsDumpOutput(buf, (xmlNsPtr) cur);
866 return;
867 }
868
869 format = ctxt->format;
870 if (format == 1) {
871 tmp = cur->children;
872 while (tmp != NULL((void*)0)) {
873 if ((tmp->type == XML_TEXT_NODE) ||
874 (tmp->type == XML_CDATA_SECTION_NODE) ||
875 (tmp->type == XML_ENTITY_REF_NODE)) {
876 ctxt->format = 0;
877 break;
878 }
879 tmp = tmp->next;
880 }
881 }
882 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "<");
883 if ((cur->ns != NULL((void*)0)) && (cur->ns->prefix != NULL((void*)0))) {
884 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->ns->prefix);
885 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ":");
886 }
887
888 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
889 if (cur->nsDef)
890 xmlNsListDumpOutput(buf, cur->nsDef);
891 if (cur->properties != NULL((void*)0))
892 xmlAttrListDumpOutput(ctxt, cur->properties);
893
894 if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL((void*)0))) &&
895 (cur->children == NULL((void*)0)) && ((ctxt->options & XML_SAVE_NO_EMPTY) == 0)) {
896 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "/>");
897 ctxt->format = format;
898 return;
899 }
900 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ">");
901 if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL((void*)0))) {
902 xmlOutputBufferWriteEscapexmlOutputBufferWriteEscape__internal_alias(buf, cur->content, ctxt->escape);
903 }
904 if (cur->children != NULL((void*)0)) {
905 if (ctxt->format) xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\n");
906 if (ctxt->level >= 0) ctxt->level++;
907 xmlNodeListDumpOutput(ctxt, cur->children);
908 if (ctxt->level > 0) ctxt->level--;
909 if ((xmlIndentTreeOutput(*(__xmlIndentTreeOutput()))) && (ctxt->format))
910 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, ctxt->indent_size *
911 (ctxt->level > ctxt->indent_nr ?
912 ctxt->indent_nr : ctxt->level),
913 ctxt->indent);
914 }
915 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "</");
916 if ((cur->ns != NULL((void*)0)) && (cur->ns->prefix != NULL((void*)0))) {
917 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->ns->prefix);
918 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ":");
919 }
920
921 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
922 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ">");
923 ctxt->format = format;
924}
925
926/**
927 * xmlDocContentDumpOutput:
928 * @cur: the document
929 *
930 * Dump an XML document.
931 */
932static int
933xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) {
934#ifdef LIBXML_HTML_ENABLED
935 xmlDtdPtr dtd;
936 int is_xhtml = 0;
937#endif
938 const xmlChar *oldenc = cur->encoding;
939 const xmlChar *oldctxtenc = ctxt->encoding;
940 const xmlChar *encoding = ctxt->encoding;
941 xmlCharEncodingOutputFunc oldescape = ctxt->escape;
942 xmlCharEncodingOutputFunc oldescapeAttr = ctxt->escapeAttr;
943 xmlOutputBufferPtr buf = ctxt->buf;
944 xmlCharEncoding enc;
945 int switched_encoding = 0;
946
947 xmlInitParserxmlInitParser__internal_alias();
948
949 if ((cur->type != XML_HTML_DOCUMENT_NODE) &&
950 (cur->type != XML_DOCUMENT_NODE))
951 return(-1);
952
953 if (ctxt->encoding != NULL((void*)0)) {
954 cur->encoding = BAD_CAST(xmlChar *) ctxt->encoding;
955 } else if (cur->encoding != NULL((void*)0)) {
956 encoding = cur->encoding;
957 } else if (cur->charset != XML_CHAR_ENCODING_UTF8) {
958 encoding = (const xmlChar *)
959 xmlGetCharEncodingNamexmlGetCharEncodingName__internal_alias((xmlCharEncoding) cur->charset);
960 }
961
962 if (((cur->type == XML_HTML_DOCUMENT_NODE) &&
963 ((ctxt->options & XML_SAVE_AS_XML) == 0) &&
964 ((ctxt->options & XML_SAVE_XHTML) == 0)) ||
965 (ctxt->options & XML_SAVE_AS_HTML)) {
966#ifdef LIBXML_HTML_ENABLED
967 if (encoding != NULL((void*)0))
968 htmlSetMetaEncodinghtmlSetMetaEncoding__internal_alias(cur, (const xmlChar *) encoding);
969 if (encoding == NULL((void*)0))
970 encoding = htmlGetMetaEncodinghtmlGetMetaEncoding__internal_alias(cur);
971 if (encoding == NULL((void*)0))
972 encoding = BAD_CAST(xmlChar *) "HTML";
973 if ((encoding != NULL((void*)0)) && (oldctxtenc == NULL((void*)0)) &&
974 (buf->encoder == NULL((void*)0)) && (buf->conv == NULL((void*)0))) {
975 if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
976 cur->encoding = oldenc;
977 return(-1);
978 }
979 switched_encoding = 1;
Value stored to 'switched_encoding' is never read
980 }
981 if (ctxt->options & XML_SAVE_FORMAT)
982 htmlDocContentDumpFormatOutputhtmlDocContentDumpFormatOutput__internal_alias(buf, cur,
983 (const char *)encoding, 1);
984 else
985 htmlDocContentDumpFormatOutputhtmlDocContentDumpFormatOutput__internal_alias(buf, cur,
986 (const char *)encoding, 0);
987 if (ctxt->encoding != NULL((void*)0))
988 cur->encoding = oldenc;
989 return(0);
990#else
991 return(-1);
992#endif
993 } else if ((cur->type == XML_DOCUMENT_NODE) ||
994 (ctxt->options & XML_SAVE_AS_XML) ||
995 (ctxt->options & XML_SAVE_XHTML)) {
996 enc = xmlParseCharEncodingxmlParseCharEncoding__internal_alias((const char*) encoding);
997 if ((encoding != NULL((void*)0)) && (oldctxtenc == NULL((void*)0)) &&
998 (buf->encoder == NULL((void*)0)) && (buf->conv == NULL((void*)0)) &&
999 ((ctxt->options & XML_SAVE_NO_DECL) == 0)) {
1000 if ((enc != XML_CHAR_ENCODING_UTF8) &&
1001 (enc != XML_CHAR_ENCODING_NONE) &&
1002 (enc != XML_CHAR_ENCODING_ASCII)) {
1003 /*
1004 * we need to switch to this encoding but just for this
1005 * document since we output the XMLDecl the conversion
1006 * must be done to not generate not well formed documents.
1007 */
1008 if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
1009 cur->encoding = oldenc;
1010 return(-1);
1011 }
1012 switched_encoding = 1;
1013 }
1014 if (ctxt->escape == xmlEscapeEntities)
1015 ctxt->escape = NULL((void*)0);
1016 if (ctxt->escapeAttr == xmlEscapeEntities)
1017 ctxt->escapeAttr = NULL((void*)0);
1018 }
1019
1020
1021 /*
1022 * Save the XML declaration
1023 */
1024 if ((ctxt->options & XML_SAVE_NO_DECL) == 0) {
1025 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 14, "<?xml version=");
1026 if (cur->version != NULL((void*)0))
1027 xmlBufferWriteQuotedStringxmlBufferWriteQuotedString__internal_alias(buf->buffer, cur->version);
1028 else
1029 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 5, "\"1.0\"");
1030 if (encoding != NULL((void*)0)) {
1031 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 10, " encoding=");
1032 xmlBufferWriteQuotedStringxmlBufferWriteQuotedString__internal_alias(buf->buffer, (xmlChar *) encoding);
1033 }
1034 switch (cur->standalone) {
1035 case 0:
1036 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 16, " standalone=\"no\"");
1037 break;
1038 case 1:
1039 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 17, " standalone=\"yes\"");
1040 break;
1041 }
1042 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 3, "?>\n");
1043 }
1044
1045#ifdef LIBXML_HTML_ENABLED
1046 if (ctxt->options & XML_SAVE_XHTML)
1047 is_xhtml = 1;
1048 if ((ctxt->options & XML_SAVE_NO_XHTML) == 0) {
1049 dtd = xmlGetIntSubsetxmlGetIntSubset__internal_alias(cur);
1050 if (dtd != NULL((void*)0)) {
1051 is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
1052 if (is_xhtml < 0) is_xhtml = 0;
1053 }
1054 }
1055#endif
1056 if (cur->children != NULL((void*)0)) {
1057 xmlNodePtr child = cur->children;
1058
1059 while (child != NULL((void*)0)) {
1060 ctxt->level = 0;
1061#ifdef LIBXML_HTML_ENABLED
1062 if (is_xhtml)
1063 xhtmlNodeDumpOutput(ctxt, child);
1064 else
1065#endif
1066 xmlNodeDumpOutputInternal(ctxt, child);
1067 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\n");
1068 child = child->next;
1069 }
1070 }
1071 }
1072
1073 /*
1074 * Restore the state of the saving context at the end of the document
1075 */
1076 if ((switched_encoding) && (oldctxtenc == NULL((void*)0))) {
1077 xmlSaveClearEncoding(ctxt);
1078 ctxt->escape = oldescape;
1079 ctxt->escapeAttr = oldescapeAttr;
1080 }
1081 cur->encoding = oldenc;
1082 return(0);
1083}
1084
1085#ifdef LIBXML_HTML_ENABLED
1086/************************************************************************
1087 * *
1088 * Functions specific to XHTML serialization *
1089 * *
1090 ************************************************************************/
1091
1092/**
1093 * xhtmlIsEmpty:
1094 * @node: the node
1095 *
1096 * Check if a node is an empty xhtml node
1097 *
1098 * Returns 1 if the node is an empty node, 0 if not and -1 in case of error
1099 */
1100static int
1101xhtmlIsEmpty(xmlNodePtr node) {
1102 if (node == NULL((void*)0))
1103 return(-1);
1104 if (node->type != XML_ELEMENT_NODE)
1105 return(0);
1106 if ((node->ns != NULL((void*)0)) && (!xmlStrEqualxmlStrEqual__internal_alias(node->ns->href, XHTML_NS_NAME(xmlChar *) "http://www.w3.org/1999/xhtml")))
1107 return(0);
1108 if (node->children != NULL((void*)0))
1109 return(0);
1110 switch (node->name[0]) {
1111 case 'a':
1112 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "area"))
1113 return(1);
1114 return(0);
1115 case 'b':
1116 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "br"))
1117 return(1);
1118 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "base"))
1119 return(1);
1120 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "basefont"))
1121 return(1);
1122 return(0);
1123 case 'c':
1124 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "col"))
1125 return(1);
1126 return(0);
1127 case 'f':
1128 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "frame"))
1129 return(1);
1130 return(0);
1131 case 'h':
1132 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "hr"))
1133 return(1);
1134 return(0);
1135 case 'i':
1136 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "img"))
1137 return(1);
1138 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "input"))
1139 return(1);
1140 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "isindex"))
1141 return(1);
1142 return(0);
1143 case 'l':
1144 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "link"))
1145 return(1);
1146 return(0);
1147 case 'm':
1148 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "meta"))
1149 return(1);
1150 return(0);
1151 case 'p':
1152 if (xmlStrEqualxmlStrEqual__internal_alias(node->name, BAD_CAST(xmlChar *) "param"))
1153 return(1);
1154 return(0);
1155 }
1156 return(0);
1157}
1158
1159/**
1160 * xhtmlAttrListDumpOutput:
1161 * @cur: the first attribute pointer
1162 *
1163 * Dump a list of XML attributes
1164 */
1165static void
1166xhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
1167 xmlAttrPtr xml_lang = NULL((void*)0);
1168 xmlAttrPtr lang = NULL((void*)0);
1169 xmlAttrPtr name = NULL((void*)0);
1170 xmlAttrPtr id = NULL((void*)0);
1171 xmlNodePtr parent;
1172 xmlOutputBufferPtr buf;
1173
1174 if (cur == NULL((void*)0)) return;
1175 buf = ctxt->buf;
1176 parent = cur->parent;
1177 while (cur != NULL((void*)0)) {
1178 if ((cur->ns == NULL((void*)0)) && (xmlStrEqualxmlStrEqual__internal_alias(cur->name, BAD_CAST(xmlChar *) "id")))
1179 id = cur;
1180 else
1181 if ((cur->ns == NULL((void*)0)) && (xmlStrEqualxmlStrEqual__internal_alias(cur->name, BAD_CAST(xmlChar *) "name")))
1182 name = cur;
1183 else
1184 if ((cur->ns == NULL((void*)0)) && (xmlStrEqualxmlStrEqual__internal_alias(cur->name, BAD_CAST(xmlChar *) "lang")))
1185 lang = cur;
1186 else
1187 if ((cur->ns != NULL((void*)0)) && (xmlStrEqualxmlStrEqual__internal_alias(cur->name, BAD_CAST(xmlChar *) "lang")) &&
1188 (xmlStrEqualxmlStrEqual__internal_alias(cur->ns->prefix, BAD_CAST(xmlChar *) "xml")))
1189 xml_lang = cur;
1190 else if ((cur->ns == NULL((void*)0)) &&
1191 ((cur->children == NULL((void*)0)) ||
1192 (cur->children->content == NULL((void*)0)) ||
1193 (cur->children->content[0] == 0)) &&
1194 (htmlIsBooleanAttrhtmlIsBooleanAttr__internal_alias(cur->name))) {
1195 if (cur->children != NULL((void*)0))
1196 xmlFreeNodexmlFreeNode__internal_alias(cur->children);
1197 cur->children = xmlNewTextxmlNewText__internal_alias(cur->name);
1198 if (cur->children != NULL((void*)0))
1199 cur->children->parent = (xmlNodePtr) cur;
1200 }
1201 xmlAttrDumpOutput(ctxt, cur);
1202 cur = cur->next;
1203 }
1204 /*
1205 * C.8
1206 */
1207 if ((name != NULL((void*)0)) && (id == NULL((void*)0))) {
1208 if ((parent != NULL((void*)0)) && (parent->name != NULL((void*)0)) &&
1209 ((xmlStrEqualxmlStrEqual__internal_alias(parent->name, BAD_CAST(xmlChar *) "a")) ||
1210 (xmlStrEqualxmlStrEqual__internal_alias(parent->name, BAD_CAST(xmlChar *) "p")) ||
1211 (xmlStrEqualxmlStrEqual__internal_alias(parent->name, BAD_CAST(xmlChar *) "div")) ||
1212 (xmlStrEqualxmlStrEqual__internal_alias(parent->name, BAD_CAST(xmlChar *) "img")) ||
1213 (xmlStrEqualxmlStrEqual__internal_alias(parent->name, BAD_CAST(xmlChar *) "map")) ||
1214 (xmlStrEqualxmlStrEqual__internal_alias(parent->name, BAD_CAST(xmlChar *) "applet")) ||
1215 (xmlStrEqualxmlStrEqual__internal_alias(parent->name, BAD_CAST(xmlChar *) "form")) ||
1216 (xmlStrEqualxmlStrEqual__internal_alias(parent->name, BAD_CAST(xmlChar *) "frame")) ||
1217 (xmlStrEqualxmlStrEqual__internal_alias(parent->name, BAD_CAST(xmlChar *) "iframe")))) {
1218 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 5, " id=\"");
1219 xmlAttrSerializeContent(buf, name);
1220 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\"");
1221 }
1222 }
1223 /*
1224 * C.7.
1225 */
1226 if ((lang != NULL((void*)0)) && (xml_lang == NULL((void*)0))) {
1227 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 11, " xml:lang=\"");
1228 xmlAttrSerializeContent(buf, lang);
1229 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\"");
1230 } else
1231 if ((xml_lang != NULL((void*)0)) && (lang == NULL((void*)0))) {
1232 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 7, " lang=\"");
1233 xmlAttrSerializeContent(buf, xml_lang);
1234 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\"");
1235 }
1236}
1237
1238/**
1239 * xhtmlNodeListDumpOutput:
1240 * @buf: the XML buffer output
1241 * @doc: the XHTML document
1242 * @cur: the first node
1243 * @level: the imbrication level for indenting
1244 * @format: is formatting allowed
1245 * @encoding: an optional encoding string
1246 *
1247 * Dump an XML node list, recursive behaviour, children are printed too.
1248 * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
1249 * or xmlKeepBlanksDefault(0) was called
1250 */
1251static void
1252xhtmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
1253 xmlOutputBufferPtr buf;
1254
1255 if (cur == NULL((void*)0)) return;
1256 buf = ctxt->buf;
1257 while (cur != NULL((void*)0)) {
1258 if ((ctxt->format) && (xmlIndentTreeOutput(*(__xmlIndentTreeOutput()))) &&
1259 (cur->type == XML_ELEMENT_NODE))
1260 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, ctxt->indent_size *
1261 (ctxt->level > ctxt->indent_nr ?
1262 ctxt->indent_nr : ctxt->level),
1263 ctxt->indent);
1264 xhtmlNodeDumpOutput(ctxt, cur);
1265 if (ctxt->format) {
1266 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\n");
1267 }
1268 cur = cur->next;
1269 }
1270}
1271
1272/**
1273 * xhtmlNodeDumpOutput:
1274 * @buf: the XML buffer output
1275 * @doc: the XHTML document
1276 * @cur: the current node
1277 * @level: the imbrication level for indenting
1278 * @format: is formatting allowed
1279 * @encoding: an optional encoding string
1280 *
1281 * Dump an XHTML node, recursive behaviour, children are printed too.
1282 */
1283static void
1284xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
1285 int format, addmeta = 0;
1286 xmlNodePtr tmp;
1287 xmlChar *start, *end;
1288 xmlOutputBufferPtr buf;
1289
1290 if (cur == NULL((void*)0)) return;
1291 if ((cur->type == XML_DOCUMENT_NODE) ||
1292 (cur->type == XML_HTML_DOCUMENT_NODE)) {
1293 xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
1294 return;
1295 }
1296 if (cur->type == XML_XINCLUDE_START)
1297 return;
1298 if (cur->type == XML_XINCLUDE_END)
1299 return;
1300 if (cur->type == XML_DTD_NODE) {
1301 xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
1302 return;
1303 }
1304 if (cur->type == XML_DOCUMENT_FRAG_NODE) {
1305 xhtmlNodeListDumpOutput(ctxt, cur->children);
1306 return;
1307 }
1308 buf = ctxt->buf;
1309 if (cur->type == XML_ELEMENT_DECL) {
1310 xmlDumpElementDeclxmlDumpElementDecl__internal_alias(buf->buffer, (xmlElementPtr) cur);
1311 return;
1312 }
1313 if (cur->type == XML_ATTRIBUTE_DECL) {
1314 xmlDumpAttributeDeclxmlDumpAttributeDecl__internal_alias(buf->buffer, (xmlAttributePtr) cur);
1315 return;
1316 }
1317 if (cur->type == XML_ENTITY_DECL) {
1318 xmlDumpEntityDeclxmlDumpEntityDecl__internal_alias(buf->buffer, (xmlEntityPtr) cur);
1319 return;
1320 }
1321 if (cur->type == XML_TEXT_NODE) {
1322 if (cur->content != NULL((void*)0)) {
1323 if ((cur->name == xmlStringText) ||
1324 (cur->name != xmlStringTextNoenc)) {
1325 xmlOutputBufferWriteEscapexmlOutputBufferWriteEscape__internal_alias(buf, cur->content, ctxt->escape);
1326 } else {
1327 /*
1328 * Disable escaping, needed for XSLT
1329 */
1330 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *) cur->content);
1331 }
1332 }
1333
1334 return;
1335 }
1336 if (cur->type == XML_PI_NODE) {
1337 if (cur->content != NULL((void*)0)) {
1338 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "<?");
1339 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
1340 if (cur->content != NULL((void*)0)) {
1341 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, " ");
1342 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->content);
1343 }
1344 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "?>");
1345 } else {
1346 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "<?");
1347 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
1348 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "?>");
1349 }
1350 return;
1351 }
1352 if (cur->type == XML_COMMENT_NODE) {
1353 if (cur->content != NULL((void*)0)) {
1354 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 4, "<!--");
1355 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->content);
1356 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 3, "-->");
1357 }
1358 return;
1359 }
1360 if (cur->type == XML_ENTITY_REF_NODE) {
1361 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "&");
1362 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
1363 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ";");
1364 return;
1365 }
1366 if (cur->type == XML_CDATA_SECTION_NODE) {
1367 if (cur->content == NULL((void*)0) || *cur->content == '\0') {
1368 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 12, "<![CDATA[]]>");
1369 } else {
1370 start = end = cur->content;
1371 while (*end != '\0') {
1372 if (*end == ']' && *(end + 1) == ']' && *(end + 2) == '>') {
1373 end = end + 2;
1374 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 9, "<![CDATA[");
1375 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, end - start, (const char *)start);
1376 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 3, "]]>");
1377 start = end;
1378 }
1379 end++;
1380 }
1381 if (start != end) {
1382 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 9, "<![CDATA[");
1383 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)start);
1384 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 3, "]]>");
1385 }
1386 }
1387 return;
1388 }
1389 if (cur->type == XML_ATTRIBUTE_NODE) {
1390 xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
1391 return;
1392 }
1393
1394 format = ctxt->format;
1395 if (format == 1) {
1396 tmp = cur->children;
1397 while (tmp != NULL((void*)0)) {
1398 if ((tmp->type == XML_TEXT_NODE) ||
1399 (tmp->type == XML_ENTITY_REF_NODE)) {
1400 format = 0;
1401 break;
1402 }
1403 tmp = tmp->next;
1404 }
1405 }
1406 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "<");
1407 if ((cur->ns != NULL((void*)0)) && (cur->ns->prefix != NULL((void*)0))) {
1408 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->ns->prefix);
1409 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ":");
1410 }
1411
1412 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
1413 if (cur->nsDef)
1414 xmlNsListDumpOutput(buf, cur->nsDef);
1415 if ((xmlStrEqualxmlStrEqual__internal_alias(cur->name, BAD_CAST(xmlChar *) "html") &&
1416 (cur->ns == NULL((void*)0)) && (cur->nsDef == NULL((void*)0)))) {
1417 /*
1418 * 3.1.1. Strictly Conforming Documents A.3.1.1 3/
1419 */
1420 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf,
1421 " xmlns=\"http://www.w3.org/1999/xhtml\"");
1422 }
1423 if (cur->properties != NULL((void*)0))
1424 xhtmlAttrListDumpOutput(ctxt, cur->properties);
1425
1426 if ((cur->type == XML_ELEMENT_NODE) &&
1427 (cur->parent != NULL((void*)0)) &&
1428 (cur->parent->parent == (xmlNodePtr) cur->doc) &&
1429 xmlStrEqualxmlStrEqual__internal_alias(cur->name, BAD_CAST(xmlChar *)"head") &&
1430 xmlStrEqualxmlStrEqual__internal_alias(cur->parent->name, BAD_CAST(xmlChar *)"html")) {
1431
1432 tmp = cur->children;
1433 while (tmp != NULL((void*)0)) {
1434 if (xmlStrEqualxmlStrEqual__internal_alias(tmp->name, BAD_CAST(xmlChar *)"meta")) {
1435 xmlChar *httpequiv;
1436
1437 httpequiv = xmlGetPropxmlGetProp__internal_alias(tmp, BAD_CAST(xmlChar *)"http-equiv");
1438 if (httpequiv != NULL((void*)0)) {
1439 if (xmlStrcasecmpxmlStrcasecmp__internal_alias(httpequiv, BAD_CAST(xmlChar *)"Content-Type") == 0) {
1440 xmlFree(httpequiv);
1441 break;
1442 }
1443 xmlFree(httpequiv);
1444 }
1445 }
1446 tmp = tmp->next;
1447 }
1448 if (tmp == NULL((void*)0))
1449 addmeta = 1;
1450 }
1451
1452 if ((cur->type == XML_ELEMENT_NODE) && (cur->children == NULL((void*)0))) {
1453 if (((cur->ns == NULL((void*)0)) || (cur->ns->prefix == NULL((void*)0))) &&
1454 ((xhtmlIsEmpty(cur) == 1) && (addmeta == 0))) {
1455 /*
1456 * C.2. Empty Elements
1457 */
1458 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 3, " />");
1459 } else {
1460 if (addmeta == 1) {
1461 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ">");
1462 if (ctxt->format) {
1463 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\n");
1464 if (xmlIndentTreeOutput(*(__xmlIndentTreeOutput())))
1465 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, ctxt->indent_size *
1466 (ctxt->level + 1 > ctxt->indent_nr ?
1467 ctxt->indent_nr : ctxt->level + 1), ctxt->indent);
1468 }
1469 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf,
1470 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
1471 if (ctxt->encoding) {
1472 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)ctxt->encoding);
1473 } else {
1474 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 5, "UTF-8");
1475 }
1476 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 4, "\" />");
1477 if (ctxt->format)
1478 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\n");
1479 } else {
1480 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ">");
1481 }
1482 /*
1483 * C.3. Element Minimization and Empty Element Content
1484 */
1485 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "</");
1486 if ((cur->ns != NULL((void*)0)) && (cur->ns->prefix != NULL((void*)0))) {
1487 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->ns->prefix);
1488 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ":");
1489 }
1490 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
1491 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ">");
1492 }
1493 return;
1494 }
1495 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ">");
1496 if (addmeta == 1) {
1497 if (ctxt->format) {
1498 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\n");
1499 if (xmlIndentTreeOutput(*(__xmlIndentTreeOutput())))
1500 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, ctxt->indent_size *
1501 (ctxt->level + 1 > ctxt->indent_nr ?
1502 ctxt->indent_nr : ctxt->level + 1), ctxt->indent);
1503 }
1504 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf,
1505 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
1506 if (ctxt->encoding) {
1507 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)ctxt->encoding);
1508 } else {
1509 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 5, "UTF-8");
1510 }
1511 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 4, "\" />");
1512 }
1513 if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL((void*)0))) {
1514 xmlOutputBufferWriteEscapexmlOutputBufferWriteEscape__internal_alias(buf, cur->content, ctxt->escape);
1515 }
1516
1517#if 0
1518 /*
1519 * This was removed due to problems with HTML processors.
1520 * See bug #345147.
1521 */
1522 /*
1523 * 4.8. Script and Style elements
1524 */
1525 if ((cur->type == XML_ELEMENT_NODE) &&
1526 ((xmlStrEqualxmlStrEqual__internal_alias(cur->name, BAD_CAST(xmlChar *) "script")) ||
1527 (xmlStrEqualxmlStrEqual__internal_alias(cur->name, BAD_CAST(xmlChar *) "style"))) &&
1528 ((cur->ns == NULL((void*)0)) ||
1529 (xmlStrEqualxmlStrEqual__internal_alias(cur->ns->href, XHTML_NS_NAME(xmlChar *) "http://www.w3.org/1999/xhtml")))) {
1530 xmlNodePtr child = cur->children;
1531
1532 while (child != NULL((void*)0)) {
1533 if (child->type == XML_TEXT_NODE) {
1534 if ((xmlStrchrxmlStrchr__internal_alias(child->content, '<') == NULL((void*)0)) &&
1535 (xmlStrchrxmlStrchr__internal_alias(child->content, '&') == NULL((void*)0)) &&
1536 (xmlStrstrxmlStrstr__internal_alias(child->content, BAD_CAST(xmlChar *) "]]>") == NULL((void*)0))) {
1537 /* Nothing to escape, so just output as is... */
1538 /* FIXME: Should we do something about "--" also? */
1539 int level = ctxt->level;
1540 int indent = ctxt->format;
1541
1542 ctxt->level = 0;
1543 ctxt->format = 0;
1544 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *) child->content);
1545 /* (We cannot use xhtmlNodeDumpOutput() here because
1546 * we wish to leave '>' unescaped!) */
1547 ctxt->level = level;
1548 ctxt->format = indent;
1549 } else {
1550 /* We must use a CDATA section. Unfortunately,
1551 * this will break CSS and JavaScript when read by
1552 * a browser in HTML4-compliant mode. :-( */
1553 start = end = child->content;
1554 while (*end != '\0') {
1555 if (*end == ']' &&
1556 *(end + 1) == ']' &&
1557 *(end + 2) == '>') {
1558 end = end + 2;
1559 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 9, "<![CDATA[");
1560 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, end - start,
1561 (const char *)start);
1562 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 3, "]]>");
1563 start = end;
1564 }
1565 end++;
1566 }
1567 if (start != end) {
1568 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 9, "<![CDATA[");
1569 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, end - start,
1570 (const char *)start);
1571 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 3, "]]>");
1572 }
1573 }
1574 } else {
1575 int level = ctxt->level;
1576 int indent = ctxt->format;
1577
1578 ctxt->level = 0;
1579 ctxt->format = 0;
1580 xhtmlNodeDumpOutput(ctxt, child);
1581 ctxt->level = level;
1582 ctxt->format = indent;
1583 }
1584 child = child->next;
1585 }
1586 }
1587#endif
1588
1589 if (cur->children != NULL((void*)0)) {
1590 int indent = ctxt->format;
1591
1592 if (format) xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, "\n");
1593 if (ctxt->level >= 0) ctxt->level++;
1594 ctxt->format = format;
1595 xhtmlNodeListDumpOutput(ctxt, cur->children);
1596 if (ctxt->level > 0) ctxt->level--;
1597 ctxt->format = indent;
1598 if ((xmlIndentTreeOutput(*(__xmlIndentTreeOutput()))) && (format))
1599 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, ctxt->indent_size *
1600 (ctxt->level > ctxt->indent_nr ?
1601 ctxt->indent_nr : ctxt->level),
1602 ctxt->indent);
1603 }
1604 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 2, "</");
1605 if ((cur->ns != NULL((void*)0)) && (cur->ns->prefix != NULL((void*)0))) {
1606 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->ns->prefix);
1607 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ":");
1608 }
1609
1610 xmlOutputBufferWriteStringxmlOutputBufferWriteString__internal_alias(buf, (const char *)cur->name);
1611 xmlOutputBufferWritexmlOutputBufferWrite__internal_alias(buf, 1, ">");
1612}
1613#endif
1614
1615/************************************************************************
1616 * *
1617 * Public entry points *
1618 * *
1619 ************************************************************************/
1620
1621/**
1622 * xmlSaveToFd:
1623 * @fd: a file descriptor number
1624 * @encoding: the encoding name to use or NULL
1625 * @options: a set of xmlSaveOptions
1626 *
1627 * Create a document saving context serializing to a file descriptor
1628 * with the encoding and the options given.
1629 *
1630 * Returns a new serialization context or NULL in case of error.
1631 */
1632xmlSaveCtxtPtr
1633xmlSaveToFd(int fd, const char *encoding, int options)
1634{
1635 xmlSaveCtxtPtr ret;
1636
1637 ret = xmlNewSaveCtxt(encoding, options);
1638 if (ret == NULL((void*)0)) return(NULL((void*)0));
1639 ret->buf = xmlOutputBufferCreateFdxmlOutputBufferCreateFd__internal_alias(fd, ret->handler);
1640 if (ret->buf == NULL((void*)0)) {
1641 xmlFreeSaveCtxt(ret);
1642 return(NULL((void*)0));
1643 }
1644 return(ret);
1645}
1646
1647/**
1648 * xmlSaveToFilename:
1649 * @filename: a file name or an URL
1650 * @encoding: the encoding name to use or NULL
1651 * @options: a set of xmlSaveOptions
1652 *
1653 * Create a document saving context serializing to a filename or possibly
1654 * to an URL (but this is less reliable) with the encoding and the options
1655 * given.
1656 *
1657 * Returns a new serialization context or NULL in case of error.
1658 */
1659xmlSaveCtxtPtr
1660xmlSaveToFilename(const char *filename, const char *encoding, int options)
1661{
1662 xmlSaveCtxtPtr ret;
1663 int compression = 0; /* TODO handle compression option */
1664
1665 ret = xmlNewSaveCtxt(encoding, options);
1666 if (ret == NULL((void*)0)) return(NULL((void*)0));
1667 ret->buf = xmlOutputBufferCreateFilenamexmlOutputBufferCreateFilename__internal_alias(filename, ret->handler,
1668 compression);
1669 if (ret->buf == NULL((void*)0)) {
1670 xmlFreeSaveCtxt(ret);
1671 return(NULL((void*)0));
1672 }
1673 return(ret);
1674}
1675
1676/**
1677 * xmlSaveToBuffer:
1678 * @buffer: a buffer
1679 * @encoding: the encoding name to use or NULL
1680 * @options: a set of xmlSaveOptions
1681 *
1682 * Create a document saving context serializing to a buffer
1683 * with the encoding and the options given
1684 *
1685 * Returns a new serialization context or NULL in case of error.
1686 */
1687
1688xmlSaveCtxtPtr
1689xmlSaveToBuffer(xmlBufferPtr buffer, const char *encoding, int options)
1690{
1691 xmlSaveCtxtPtr ret;
1692 xmlOutputBufferPtr out_buff;
1693 xmlCharEncodingHandlerPtr handler;
1694
1695 ret = xmlNewSaveCtxt(encoding, options);
1696 if (ret == NULL((void*)0)) return(NULL((void*)0));
1697
1698 if (encoding != NULL((void*)0)) {
1699 handler = xmlFindCharEncodingHandlerxmlFindCharEncodingHandler__internal_alias(encoding);
1700 if (handler == NULL((void*)0)) {
1701 xmlFree(ret);
1702 return(NULL((void*)0));
1703 }
1704 } else
1705 handler = NULL((void*)0);
1706 out_buff = xmlOutputBufferCreateBufferxmlOutputBufferCreateBuffer__internal_alias(buffer, handler);
1707 if (out_buff == NULL((void*)0)) {
1708 xmlFree(ret);
1709 if (handler) xmlCharEncCloseFuncxmlCharEncCloseFunc__internal_alias(handler);
1710 return(NULL((void*)0));
1711 }
1712
1713 ret->buf = out_buff;
1714 return(ret);
1715}
1716
1717/**
1718 * xmlSaveToIO:
1719 * @iowrite: an I/O write function
1720 * @ioclose: an I/O close function
1721 * @ioctx: an I/O handler
1722 * @encoding: the encoding name to use or NULL
1723 * @options: a set of xmlSaveOptions
1724 *
1725 * Create a document saving context serializing to a file descriptor
1726 * with the encoding and the options given
1727 *
1728 * Returns a new serialization context or NULL in case of error.
1729 */
1730xmlSaveCtxtPtr
1731xmlSaveToIO(xmlOutputWriteCallback iowrite,
1732 xmlOutputCloseCallback ioclose,
1733 void *ioctx, const char *encoding, int options)
1734{
1735 xmlSaveCtxtPtr ret;
1736
1737 ret = xmlNewSaveCtxt(encoding, options);
1738 if (ret == NULL((void*)0)) return(NULL((void*)0));
1739 ret->buf = xmlOutputBufferCreateIOxmlOutputBufferCreateIO__internal_alias(iowrite, ioclose, ioctx, ret->handler);
1740 if (ret->buf == NULL((void*)0)) {
1741 xmlFreeSaveCtxt(ret);
1742 return(NULL((void*)0));
1743 }
1744 return(ret);
1745}
1746
1747/**
1748 * xmlSaveDoc:
1749 * @ctxt: a document saving context
1750 * @doc: a document
1751 *
1752 * Save a full document to a saving context
1753 * TODO: The function is not fully implemented yet as it does not return the
1754 * byte count but 0 instead
1755 *
1756 * Returns the number of byte written or -1 in case of error
1757 */
1758long
1759xmlSaveDoc(xmlSaveCtxtPtr ctxt, xmlDocPtr doc)
1760{
1761 long ret = 0;
1762
1763 if ((ctxt == NULL((void*)0)) || (doc == NULL((void*)0))) return(-1);
1764 if (xmlDocContentDumpOutput(ctxt, doc) < 0)
1765 return(-1);
1766 return(ret);
1767}
1768
1769/**
1770 * xmlSaveTree:
1771 * @ctxt: a document saving context
1772 * @node: the top node of the subtree to save
1773 *
1774 * Save a subtree starting at the node parameter to a saving context
1775 * TODO: The function is not fully implemented yet as it does not return the
1776 * byte count but 0 instead
1777 *
1778 * Returns the number of byte written or -1 in case of error
1779 */
1780long
1781xmlSaveTree(xmlSaveCtxtPtr ctxt, xmlNodePtr node)
1782{
1783 long ret = 0;
1784
1785 if ((ctxt == NULL((void*)0)) || (node == NULL((void*)0))) return(-1);
1786 xmlNodeDumpOutputInternal(ctxt, node);
1787 return(ret);
1788}
1789
1790/**
1791 * xmlSaveFlush:
1792 * @ctxt: a document saving context
1793 *
1794 * Flush a document saving context, i.e. make sure that all bytes have
1795 * been output.
1796 *
1797 * Returns the number of byte written or -1 in case of error.
1798 */
1799int
1800xmlSaveFlush(xmlSaveCtxtPtr ctxt)
1801{
1802 if (ctxt == NULL((void*)0)) return(-1);
1803 if (ctxt->buf == NULL((void*)0)) return(-1);
1804 return(xmlOutputBufferFlushxmlOutputBufferFlush__internal_alias(ctxt->buf));
1805}
1806
1807/**
1808 * xmlSaveClose:
1809 * @ctxt: a document saving context
1810 *
1811 * Close a document saving context, i.e. make sure that all bytes have
1812 * been output and free the associated data.
1813 *
1814 * Returns the number of byte written or -1 in case of error.
1815 */
1816int
1817xmlSaveClose(xmlSaveCtxtPtr ctxt)
1818{
1819 int ret;
1820
1821 if (ctxt == NULL((void*)0)) return(-1);
1822 ret = xmlSaveFlush(ctxt);
1823 xmlFreeSaveCtxt(ctxt);
1824 return(ret);
1825}
1826
1827/**
1828 * xmlSaveSetEscape:
1829 * @ctxt: a document saving context
1830 * @escape: the escaping function
1831 *
1832 * Set a custom escaping function to be used for text in element content
1833 *
1834 * Returns 0 if successful or -1 in case of error.
1835 */
1836int
1837xmlSaveSetEscape(xmlSaveCtxtPtr ctxt, xmlCharEncodingOutputFunc escape)
1838{
1839 if (ctxt == NULL((void*)0)) return(-1);
1840 ctxt->escape = escape;
1841 return(0);
1842}
1843
1844/**
1845 * xmlSaveSetAttrEscape:
1846 * @ctxt: a document saving context
1847 * @escape: the escaping function
1848 *
1849 * Set a custom escaping function to be used for text in attribute content
1850 *
1851 * Returns 0 if successful or -1 in case of error.
1852 */
1853int
1854xmlSaveSetAttrEscape(xmlSaveCtxtPtr ctxt, xmlCharEncodingOutputFunc escape)
1855{
1856 if (ctxt == NULL((void*)0)) return(-1);
1857 ctxt->escapeAttr = escape;
1858 return(0);
1859}
1860
1861/************************************************************************
1862 * *
1863 * Public entry points based on buffers *
1864 * *
1865 ************************************************************************/
1866/**
1867 * xmlAttrSerializeTxtContent:
1868 * @buf: the XML buffer output
1869 * @doc: the document
1870 * @attr: the attribute node
1871 * @string: the text content
1872 *
1873 * Serialize text attribute values to an xml simple buffer
1874 */
1875void
1876xmlAttrSerializeTxtContent(xmlBufferPtr buf, xmlDocPtr doc,
1877 xmlAttrPtr attr, const xmlChar * string)
1878{
1879 xmlChar *base, *cur;
1880
1881 if (string == NULL((void*)0))
1882 return;
1883 base = cur = (xmlChar *) string;
1884 while (*cur != 0) {
1885 if (*cur == '\n') {
1886 if (base != cur)
1887 xmlBufferAddxmlBufferAdd__internal_alias(buf, base, cur - base);
1888 xmlBufferAddxmlBufferAdd__internal_alias(buf, BAD_CAST(xmlChar *) "&#10;", 5);
1889 cur++;
1890 base = cur;
1891 } else if (*cur == '\r') {
1892 if (base != cur)
1893 xmlBufferAddxmlBufferAdd__internal_alias(buf, base, cur - base);
1894 xmlBufferAddxmlBufferAdd__internal_alias(buf, BAD_CAST(xmlChar *) "&#13;", 5);
1895 cur++;
1896 base = cur;
1897 } else if (*cur == '\t') {
1898 if (base != cur)
1899 xmlBufferAddxmlBufferAdd__internal_alias(buf, base, cur - base);
1900 xmlBufferAddxmlBufferAdd__internal_alias(buf, BAD_CAST(xmlChar *) "&#9;", 4);
1901 cur++;
1902 base = cur;
1903 } else if (*cur == '"') {
1904 if (base != cur)
1905 xmlBufferAddxmlBufferAdd__internal_alias(buf, base, cur - base);
1906 xmlBufferAddxmlBufferAdd__internal_alias(buf, BAD_CAST(xmlChar *) "&quot;", 6);
1907 cur++;
1908 base = cur;
1909 } else if (*cur == '<') {
1910 if (base != cur)
1911 xmlBufferAddxmlBufferAdd__internal_alias(buf, base, cur - base);
1912 xmlBufferAddxmlBufferAdd__internal_alias(buf, BAD_CAST(xmlChar *) "&lt;", 4);
1913 cur++;
1914 base = cur;
1915 } else if (*cur == '>') {
1916 if (base != cur)
1917 xmlBufferAddxmlBufferAdd__internal_alias(buf, base, cur - base);
1918 xmlBufferAddxmlBufferAdd__internal_alias(buf, BAD_CAST(xmlChar *) "&gt;", 4);
1919 cur++;
1920 base = cur;
1921 } else if (*cur == '&') {
1922 if (base != cur)
1923 xmlBufferAddxmlBufferAdd__internal_alias(buf, base, cur - base);
1924 xmlBufferAddxmlBufferAdd__internal_alias(buf, BAD_CAST(xmlChar *) "&amp;", 5);
1925 cur++;
1926 base = cur;
1927 } else if ((*cur >= 0x80) && ((doc == NULL((void*)0)) ||
1928 (doc->encoding == NULL((void*)0)))) {
1929 /*
1930 * We assume we have UTF-8 content.
1931 */
1932 unsigned char tmp[10];
1933 int val = 0, l = 1;
1934
1935 if (base != cur)
1936 xmlBufferAddxmlBufferAdd__internal_alias(buf, base, cur - base);
1937 if (*cur < 0xC0) {
1938 xmlSaveErr(XML_SAVE_NOT_UTF8, (xmlNodePtr) attr, NULL((void*)0));
1939 if (doc != NULL((void*)0))
1940 doc->encoding = xmlStrdupxmlStrdup__internal_alias(BAD_CAST(xmlChar *) "ISO-8859-1");
1941 xmlSerializeHexCharRef(tmp, *cur);
1942 xmlBufferAddxmlBufferAdd__internal_alias(buf, (xmlChar *) tmp, -1);
1943 cur++;
1944 base = cur;
1945 continue;
1946 } else if (*cur < 0xE0) {
1947 val = (cur[0]) & 0x1F;
1948 val <<= 6;
1949 val |= (cur[1]) & 0x3F;
1950 l = 2;
1951 } else if (*cur < 0xF0) {
1952 val = (cur[0]) & 0x0F;
1953 val <<= 6;
1954 val |= (cur[1]) & 0x3F;
1955 val <<= 6;
1956 val |= (cur[2]) & 0x3F;
1957 l = 3;
1958 } else if (*cur < 0xF8) {
1959 val = (cur[0]) & 0x07;
1960 val <<= 6;
1961 val |= (cur[1]) & 0x3F;
1962 val <<= 6;
1963 val |= (cur[2]) & 0x3F;
1964 val <<= 6;
1965 val |= (cur[3]) & 0x3F;
1966 l = 4;
1967 }
1968 if ((l == 1) || (!IS_CHAR(val)(((val) < 0x100) ? (((0x9 <= ((val))) && (((val
)) <= 0xa)) || (((val)) == 0xd) || (0x20 <= ((val)))) :
(((0x100 <= (val)) && ((val) <= 0xd7ff)) || ((
0xe000 <= (val)) && ((val) <= 0xfffd)) || ((0x10000
<= (val)) && ((val) <= 0x10ffff))))
)) {
1969 xmlSaveErr(XML_SAVE_CHAR_INVALID, (xmlNodePtr) attr, NULL((void*)0));
1970 if (doc != NULL((void*)0))
1971 doc->encoding = xmlStrdupxmlStrdup__internal_alias(BAD_CAST(xmlChar *) "ISO-8859-1");
1972
1973 xmlSerializeHexCharRef(tmp, *cur);
1974 xmlBufferAddxmlBufferAdd__internal_alias(buf, (xmlChar *) tmp, -1);
1975 cur++;
1976 base = cur;
1977 continue;
1978 }
1979 /*
1980 * We could do multiple things here. Just save
1981 * as a char ref
1982 */
1983 xmlSerializeHexCharRef(tmp, val);
1984 xmlBufferAddxmlBufferAdd__internal_alias(buf, (xmlChar *) tmp, -1);
1985 cur += l;
1986 base = cur;
1987 } else {
1988 cur++;
1989 }
1990 }
1991 if (base != cur)
1992 xmlBufferAddxmlBufferAdd__internal_alias(buf, base, cur - base);
1993}
1994
1995/**
1996 * xmlNodeDump:
1997 * @buf: the XML buffer output
1998 * @doc: the document
1999 * @cur: the current node
2000 * @level: the imbrication level for indenting
2001 * @format: is formatting allowed
2002 *
2003 * Dump an XML node, recursive behaviour,children are printed too.
2004 * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2005 * or xmlKeepBlanksDefault(0) was called
2006 *
2007 * Returns the number of bytes written to the buffer or -1 in case of error
2008 */
2009int
2010xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
2011 int format)
2012{
2013 unsigned int use;
2014 int ret;
2015 xmlOutputBufferPtr outbuf;
2016
2017 xmlInitParserxmlInitParser__internal_alias();
2018
2019 if (cur == NULL((void*)0)) {
2020#ifdef DEBUG_TREE
2021 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2022 "xmlNodeDump : node == NULL\n");
2023#endif
2024 return (-1);
2025 }
2026 if (buf == NULL((void*)0)) {
2027#ifdef DEBUG_TREE
2028 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2029 "xmlNodeDump : buf == NULL\n");
2030#endif
2031 return (-1);
2032 }
2033 outbuf = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
2034 if (outbuf == NULL((void*)0)) {
2035 xmlSaveErrMemory("creating buffer");
2036 return (-1);
2037 }
2038 memset(outbuf, 0, (size_t) sizeof(xmlOutputBuffer));
2039 outbuf->buffer = buf;
2040 outbuf->encoder = NULL((void*)0);
2041 outbuf->writecallback = NULL((void*)0);
2042 outbuf->closecallback = NULL((void*)0);
2043 outbuf->context = NULL((void*)0);
2044 outbuf->written = 0;
2045
2046 use = buf->use;
2047 xmlNodeDumpOutput(outbuf, doc, cur, level, format, NULL((void*)0));
2048 xmlFree(outbuf);
2049 ret = buf->use - use;
2050 return (ret);
2051}
2052
2053/**
2054 * xmlElemDump:
2055 * @f: the FILE * for the output
2056 * @doc: the document
2057 * @cur: the current node
2058 *
2059 * Dump an XML/HTML node, recursive behaviour, children are printed too.
2060 */
2061void
2062xmlElemDump(FILE * f, xmlDocPtr doc, xmlNodePtr cur)
2063{
2064 xmlOutputBufferPtr outbuf;
2065
2066 xmlInitParserxmlInitParser__internal_alias();
2067
2068 if (cur == NULL((void*)0)) {
2069#ifdef DEBUG_TREE
2070 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2071 "xmlElemDump : cur == NULL\n");
2072#endif
2073 return;
2074 }
2075#ifdef DEBUG_TREE
2076 if (doc == NULL((void*)0)) {
2077 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2078 "xmlElemDump : doc == NULL\n");
2079 }
2080#endif
2081
2082 outbuf = xmlOutputBufferCreateFilexmlOutputBufferCreateFile__internal_alias(f, NULL((void*)0));
2083 if (outbuf == NULL((void*)0))
2084 return;
2085 if ((doc != NULL((void*)0)) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
2086#ifdef LIBXML_HTML_ENABLED
2087 htmlNodeDumpOutputhtmlNodeDumpOutput__internal_alias(outbuf, doc, cur, NULL((void*)0));
2088#else
2089 xmlSaveErr(XML_ERR_INTERNAL_ERROR, cur, "HTML support not compiled in\n");
2090#endif /* LIBXML_HTML_ENABLED */
2091 } else
2092 xmlNodeDumpOutput(outbuf, doc, cur, 0, 1, NULL((void*)0));
2093 xmlOutputBufferClosexmlOutputBufferClose__internal_alias(outbuf);
2094}
2095
2096/************************************************************************
2097 * *
2098 * Saving functions front-ends *
2099 * *
2100 ************************************************************************/
2101
2102/**
2103 * xmlNodeDumpOutput:
2104 * @buf: the XML buffer output
2105 * @doc: the document
2106 * @cur: the current node
2107 * @level: the imbrication level for indenting
2108 * @format: is formatting allowed
2109 * @encoding: an optional encoding string
2110 *
2111 * Dump an XML node, recursive behaviour, children are printed too.
2112 * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2113 * or xmlKeepBlanksDefault(0) was called
2114 */
2115void
2116xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
2117 int level, int format, const char *encoding)
2118{
2119 xmlSaveCtxt ctxt;
2120#ifdef LIBXML_HTML_ENABLED
2121 xmlDtdPtr dtd;
2122 int is_xhtml = 0;
2123#endif
2124
2125 xmlInitParserxmlInitParser__internal_alias();
2126
2127 if ((buf == NULL((void*)0)) || (cur == NULL((void*)0))) return;
2128
2129 if (encoding == NULL((void*)0))
2130 encoding = "UTF-8";
2131
2132 memset(&ctxt, 0, sizeof(ctxt));
2133 ctxt.doc = doc;
2134 ctxt.buf = buf;
2135 ctxt.level = level;
2136 ctxt.format = format;
2137 ctxt.encoding = (const xmlChar *) encoding;
2138 xmlSaveCtxtInit(&ctxt);
2139 ctxt.options |= XML_SAVE_AS_XML;
2140
2141#ifdef LIBXML_HTML_ENABLED
2142 dtd = xmlGetIntSubsetxmlGetIntSubset__internal_alias(doc);
2143 if (dtd != NULL((void*)0)) {
2144 is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
2145 if (is_xhtml < 0)
2146 is_xhtml = 0;
2147 }
2148
2149 if (is_xhtml)
2150 xhtmlNodeDumpOutput(&ctxt, cur);
2151 else
2152#endif
2153 xmlNodeDumpOutputInternal(&ctxt, cur);
2154}
2155
2156/**
2157 * xmlDocDumpFormatMemoryEnc:
2158 * @out_doc: Document to generate XML text from
2159 * @doc_txt_ptr: Memory pointer for allocated XML text
2160 * @doc_txt_len: Length of the generated XML text
2161 * @txt_encoding: Character encoding to use when generating XML text
2162 * @format: should formatting spaces been added
2163 *
2164 * Dump the current DOM tree into memory using the character encoding specified
2165 * by the caller. Note it is up to the caller of this function to free the
2166 * allocated memory with xmlFree().
2167 * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2168 * or xmlKeepBlanksDefault(0) was called
2169 */
2170
2171void
2172xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
2173 int * doc_txt_len, const char * txt_encoding,
2174 int format) {
2175 xmlSaveCtxt ctxt;
2176 int dummy = 0;
2177 xmlOutputBufferPtr out_buff = NULL((void*)0);
2178 xmlCharEncodingHandlerPtr conv_hdlr = NULL((void*)0);
2179
2180 if (doc_txt_len == NULL((void*)0)) {
2181 doc_txt_len = &dummy; /* Continue, caller just won't get length */
2182 }
2183
2184 if (doc_txt_ptr == NULL((void*)0)) {
2185 *doc_txt_len = 0;
2186 return;
2187 }
2188
2189 *doc_txt_ptr = NULL((void*)0);
2190 *doc_txt_len = 0;
2191
2192 if (out_doc == NULL((void*)0)) {
2193 /* No document, no output */
2194 return;
2195 }
2196
2197 /*
2198 * Validate the encoding value, if provided.
2199 * This logic is copied from xmlSaveFileEnc.
2200 */
2201
2202 if (txt_encoding == NULL((void*)0))
2203 txt_encoding = (const char *) out_doc->encoding;
2204 if (txt_encoding != NULL((void*)0)) {
2205 conv_hdlr = xmlFindCharEncodingHandlerxmlFindCharEncodingHandler__internal_alias(txt_encoding);
2206 if ( conv_hdlr == NULL((void*)0) ) {
2207 xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, (xmlNodePtr) out_doc,
2208 txt_encoding);
2209 return;
2210 }
2211 }
2212
2213 if ((out_buff = xmlAllocOutputBufferxmlAllocOutputBuffer__internal_alias(conv_hdlr)) == NULL((void*)0) ) {
2214 xmlSaveErrMemory("creating buffer");
2215 return;
2216 }
2217
2218 memset(&ctxt, 0, sizeof(ctxt));
2219 ctxt.doc = out_doc;
2220 ctxt.buf = out_buff;
2221 ctxt.level = 0;
2222 ctxt.format = format;
2223 ctxt.encoding = (const xmlChar *) txt_encoding;
2224 xmlSaveCtxtInit(&ctxt);
2225 ctxt.options |= XML_SAVE_AS_XML;
2226 xmlDocContentDumpOutput(&ctxt, out_doc);
2227 xmlOutputBufferFlushxmlOutputBufferFlush__internal_alias(out_buff);
2228 if (out_buff->conv != NULL((void*)0)) {
2229 *doc_txt_len = out_buff->conv->use;
2230 *doc_txt_ptr = xmlStrndupxmlStrndup__internal_alias(out_buff->conv->content, *doc_txt_len);
2231 } else {
2232 *doc_txt_len = out_buff->buffer->use;
2233 *doc_txt_ptr = xmlStrndupxmlStrndup__internal_alias(out_buff->buffer->content, *doc_txt_len);
2234 }
2235 (void)xmlOutputBufferClosexmlOutputBufferClose__internal_alias(out_buff);
2236
2237 if ((*doc_txt_ptr == NULL((void*)0)) && (*doc_txt_len > 0)) {
2238 *doc_txt_len = 0;
2239 xmlSaveErrMemory("creating output");
2240 }
2241
2242 return;
2243}
2244
2245/**
2246 * xmlDocDumpMemory:
2247 * @cur: the document
2248 * @mem: OUT: the memory pointer
2249 * @size: OUT: the memory length
2250 *
2251 * Dump an XML document in memory and return the #xmlChar * and it's size
2252 * in bytes. It's up to the caller to free the memory with xmlFree().
2253 * The resulting byte array is zero terminated, though the last 0 is not
2254 * included in the returned size.
2255 */
2256void
2257xmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
2258 xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL((void*)0), 0);
2259}
2260
2261/**
2262 * xmlDocDumpFormatMemory:
2263 * @cur: the document
2264 * @mem: OUT: the memory pointer
2265 * @size: OUT: the memory length
2266 * @format: should formatting spaces been added
2267 *
2268 *
2269 * Dump an XML document in memory and return the #xmlChar * and it's size.
2270 * It's up to the caller to free the memory with xmlFree().
2271 * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2272 * or xmlKeepBlanksDefault(0) was called
2273 */
2274void
2275xmlDocDumpFormatMemory(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
2276 xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL((void*)0), format);
2277}
2278
2279/**
2280 * xmlDocDumpMemoryEnc:
2281 * @out_doc: Document to generate XML text from
2282 * @doc_txt_ptr: Memory pointer for allocated XML text
2283 * @doc_txt_len: Length of the generated XML text
2284 * @txt_encoding: Character encoding to use when generating XML text
2285 *
2286 * Dump the current DOM tree into memory using the character encoding specified
2287 * by the caller. Note it is up to the caller of this function to free the
2288 * allocated memory with xmlFree().
2289 */
2290
2291void
2292xmlDocDumpMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
2293 int * doc_txt_len, const char * txt_encoding) {
2294 xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len,
2295 txt_encoding, 0);
2296}
2297
2298/**
2299 * xmlDocFormatDump:
2300 * @f: the FILE*
2301 * @cur: the document
2302 * @format: should formatting spaces been added
2303 *
2304 * Dump an XML document to an open FILE.
2305 *
2306 * returns: the number of bytes written or -1 in case of failure.
2307 * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2308 * or xmlKeepBlanksDefault(0) was called
2309 */
2310int
2311xmlDocFormatDump(FILE *f, xmlDocPtr cur, int format) {
2312 xmlSaveCtxt ctxt;
2313 xmlOutputBufferPtr buf;
2314 const char * encoding;
2315 xmlCharEncodingHandlerPtr handler = NULL((void*)0);
2316 int ret;
2317
2318 if (cur == NULL((void*)0)) {
2319#ifdef DEBUG_TREE
2320 xmlGenericError(*(__xmlGenericError__internal_alias()))(xmlGenericErrorContext(*(__xmlGenericErrorContext__internal_alias())),
2321 "xmlDocDump : document == NULL\n");
2322#endif
2323 return(-1);
2324 }
2325 encoding = (const char *) cur->encoding;
2326
2327 if (encoding != NULL((void*)0)) {
2328 handler = xmlFindCharEncodingHandlerxmlFindCharEncodingHandler__internal_alias(encoding);
2329 if (handler == NULL((void*)0)) {
2330 xmlFree((char *) cur->encoding);
2331 cur->encoding = NULL((void*)0);
2332 encoding = NULL((void*)0);
2333 }
2334 }
2335 buf = xmlOutputBufferCreateFilexmlOutputBufferCreateFile__internal_alias(f, handler);
2336 if (buf == NULL((void*)0)) return(-1);
2337 memset(&ctxt, 0, sizeof(ctxt));
2338 ctxt.doc = cur;
2339 ctxt.buf = buf;
2340 ctxt.level = 0;
2341 ctxt.format = format;
2342 ctxt.encoding = (const xmlChar *) encoding;
2343 xmlSaveCtxtInit(&ctxt);
2344 ctxt.options |= XML_SAVE_AS_XML;
2345 xmlDocContentDumpOutput(&ctxt, cur);
2346
2347 ret = xmlOutputBufferClosexmlOutputBufferClose__internal_alias(buf);
2348 return(ret);
2349}
2350
2351/**
2352 * xmlDocDump:
2353 * @f: the FILE*
2354 * @cur: the document
2355 *
2356 * Dump an XML document to an open FILE.
2357 *
2358 * returns: the number of bytes written or -1 in case of failure.
2359 */
2360int
2361xmlDocDump(FILE *f, xmlDocPtr cur) {
2362 return(xmlDocFormatDump (f, cur, 0));
2363}
2364
2365/**
2366 * xmlSaveFileTo:
2367 * @buf: an output I/O buffer
2368 * @cur: the document
2369 * @encoding: the encoding if any assuming the I/O layer handles the trancoding
2370 *
2371 * Dump an XML document to an I/O buffer.
2372 * Warning ! This call xmlOutputBufferClose() on buf which is not available
2373 * after this call.
2374 *
2375 * returns: the number of bytes written or -1 in case of failure.
2376 */
2377int
2378xmlSaveFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur, const char *encoding) {
2379 xmlSaveCtxt ctxt;
2380 int ret;
2381
2382 if (buf == NULL((void*)0)) return(-1);
2383 if (cur == NULL((void*)0)) {
2384 xmlOutputBufferClosexmlOutputBufferClose__internal_alias(buf);
2385 return(-1);
2386 }
2387 memset(&ctxt, 0, sizeof(ctxt));
2388 ctxt.doc = cur;
2389 ctxt.buf = buf;
2390 ctxt.level = 0;
2391 ctxt.format = 0;
2392 ctxt.encoding = (const xmlChar *) encoding;
2393 xmlSaveCtxtInit(&ctxt);
2394 ctxt.options |= XML_SAVE_AS_XML;
2395 xmlDocContentDumpOutput(&ctxt, cur);
2396 ret = xmlOutputBufferClosexmlOutputBufferClose__internal_alias(buf);
2397 return(ret);
2398}
2399
2400/**
2401 * xmlSaveFormatFileTo:
2402 * @buf: an output I/O buffer
2403 * @cur: the document
2404 * @encoding: the encoding if any assuming the I/O layer handles the trancoding
2405 * @format: should formatting spaces been added
2406 *
2407 * Dump an XML document to an I/O buffer.
2408 * Warning ! This call xmlOutputBufferClose() on buf which is not available
2409 * after this call.
2410 *
2411 * returns: the number of bytes written or -1 in case of failure.
2412 */
2413int
2414xmlSaveFormatFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur,
2415 const char *encoding, int format)
2416{
2417 xmlSaveCtxt ctxt;
2418 int ret;
2419
2420 if (buf == NULL((void*)0)) return(-1);
2421 if ((cur == NULL((void*)0)) ||
2422 ((cur->type != XML_DOCUMENT_NODE) &&
2423 (cur->type != XML_HTML_DOCUMENT_NODE))) {
2424 xmlOutputBufferClosexmlOutputBufferClose__internal_alias(buf);
2425 return(-1);
2426 }
2427 memset(&ctxt, 0, sizeof(ctxt));
2428 ctxt.doc = cur;
2429 ctxt.buf = buf;
2430 ctxt.level = 0;
2431 ctxt.format = format;
2432 ctxt.encoding = (const xmlChar *) encoding;
2433 xmlSaveCtxtInit(&ctxt);
2434 ctxt.options |= XML_SAVE_AS_XML;
2435 xmlDocContentDumpOutput(&ctxt, cur);
2436 ret = xmlOutputBufferClosexmlOutputBufferClose__internal_alias(buf);
2437 return (ret);
2438}
2439
2440/**
2441 * xmlSaveFormatFileEnc:
2442 * @filename: the filename or URL to output
2443 * @cur: the document being saved
2444 * @encoding: the name of the encoding to use or NULL.
2445 * @format: should formatting spaces be added.
2446 *
2447 * Dump an XML document to a file or an URL.
2448 *
2449 * Returns the number of bytes written or -1 in case of error.
2450 * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2451 * or xmlKeepBlanksDefault(0) was called
2452 */
2453int
2454xmlSaveFormatFileEnc( const char * filename, xmlDocPtr cur,
2455 const char * encoding, int format ) {
2456 xmlSaveCtxt ctxt;
2457 xmlOutputBufferPtr buf;
2458 xmlCharEncodingHandlerPtr handler = NULL((void*)0);
2459 int ret;
2460
2461 if (cur == NULL((void*)0))
2462 return(-1);
2463
2464 if (encoding == NULL((void*)0))
2465 encoding = (const char *) cur->encoding;
2466
2467 if (encoding != NULL((void*)0)) {
2468
2469 handler = xmlFindCharEncodingHandlerxmlFindCharEncodingHandler__internal_alias(encoding);
2470 if (handler == NULL((void*)0))
2471 return(-1);
2472 }
2473
2474#ifdef HAVE_ZLIB_H1
2475 if (cur->compression < 0) cur->compression = xmlGetCompressModexmlGetCompressMode__internal_alias();
2476#endif
2477 /*
2478 * save the content to a temp buffer.
2479 */
2480 buf = xmlOutputBufferCreateFilenamexmlOutputBufferCreateFilename__internal_alias(filename, handler, cur->compression);
2481 if (buf == NULL((void*)0)) return(-1);
2482 memset(&ctxt, 0, sizeof(ctxt));
2483 ctxt.doc = cur;
2484 ctxt.buf = buf;
2485 ctxt.level = 0;
2486 ctxt.format = format;
2487 ctxt.encoding = (const xmlChar *) encoding;
2488 xmlSaveCtxtInit(&ctxt);
2489 ctxt.options |= XML_SAVE_AS_XML;
2490
2491 xmlDocContentDumpOutput(&ctxt, cur);
2492
2493 ret = xmlOutputBufferClosexmlOutputBufferClose__internal_alias(buf);
2494 return(ret);
2495}
2496
2497
2498/**
2499 * xmlSaveFileEnc:
2500 * @filename: the filename (or URL)
2501 * @cur: the document
2502 * @encoding: the name of an encoding (or NULL)
2503 *
2504 * Dump an XML document, converting it to the given encoding
2505 *
2506 * returns: the number of bytes written or -1 in case of failure.
2507 */
2508int
2509xmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
2510 return ( xmlSaveFormatFileEnc( filename, cur, encoding, 0 ) );
2511}
2512
2513/**
2514 * xmlSaveFormatFile:
2515 * @filename: the filename (or URL)
2516 * @cur: the document
2517 * @format: should formatting spaces been added
2518 *
2519 * Dump an XML document to a file. Will use compression if
2520 * compiled in and enabled. If @filename is "-" the stdout file is
2521 * used. If @format is set then the document will be indented on output.
2522 * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2523 * or xmlKeepBlanksDefault(0) was called
2524 *
2525 * returns: the number of bytes written or -1 in case of failure.
2526 */
2527int
2528xmlSaveFormatFile(const char *filename, xmlDocPtr cur, int format) {
2529 return ( xmlSaveFormatFileEnc( filename, cur, NULL((void*)0), format ) );
2530}
2531
2532/**
2533 * xmlSaveFile:
2534 * @filename: the filename (or URL)
2535 * @cur: the document
2536 *
2537 * Dump an XML document to a file. Will use compression if
2538 * compiled in and enabled. If @filename is "-" the stdout file is
2539 * used.
2540 * returns: the number of bytes written or -1 in case of failure.
2541 */
2542int
2543xmlSaveFile(const char *filename, xmlDocPtr cur) {
2544 return(xmlSaveFormatFileEnc(filename, cur, NULL((void*)0), 0));
2545}
2546
2547#endif /* LIBXML_OUTPUT_ENABLED */
2548
2549#define bottom_xmlsave
2550#include "elfgcchack.h"