ReactOS  0.4.15-dev-3303-g1ade494
HTMLtree.c
Go to the documentation of this file.
1 /*
2  * HTMLtree.c : implementation of access function for an HTML tree.
3  *
4  * See Copyright for the status of this software.
5  *
6  * daniel@veillard.com
7  */
8 
9 
10 #define IN_LIBXML
11 #include "libxml.h"
12 #ifdef LIBXML_HTML_ENABLED
13 
14 #include <string.h> /* for memset() only ! */
15 
16 #ifdef HAVE_CTYPE_H
17 #include <ctype.h>
18 #endif
19 #ifdef HAVE_STDLIB_H
20 #include <stdlib.h>
21 #endif
22 
23 #include <libxml/xmlmemory.h>
24 #include <libxml/HTMLparser.h>
25 #include <libxml/HTMLtree.h>
26 #include <libxml/entities.h>
27 #include <libxml/valid.h>
28 #include <libxml/xmlerror.h>
29 #include <libxml/parserInternals.h>
30 #include <libxml/globals.h>
31 #include <libxml/uri.h>
32 
33 #include "buf.h"
34 
35 /************************************************************************
36  * *
37  * Getting/Setting encoding meta tags *
38  * *
39  ************************************************************************/
40 
49 const xmlChar *
50 htmlGetMetaEncoding(htmlDocPtr doc) {
51  htmlNodePtr cur;
52  const xmlChar *content;
53  const xmlChar *encoding;
54 
55  if (doc == NULL)
56  return(NULL);
57  cur = doc->children;
58 
59  /*
60  * Search the html
61  */
62  while (cur != NULL) {
63  if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
64  if (xmlStrEqual(cur->name, BAD_CAST"html"))
65  break;
66  if (xmlStrEqual(cur->name, BAD_CAST"head"))
67  goto found_head;
68  if (xmlStrEqual(cur->name, BAD_CAST"meta"))
69  goto found_meta;
70  }
71  cur = cur->next;
72  }
73  if (cur == NULL)
74  return(NULL);
75  cur = cur->children;
76 
77  /*
78  * Search the head
79  */
80  while (cur != NULL) {
81  if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
82  if (xmlStrEqual(cur->name, BAD_CAST"head"))
83  break;
84  if (xmlStrEqual(cur->name, BAD_CAST"meta"))
85  goto found_meta;
86  }
87  cur = cur->next;
88  }
89  if (cur == NULL)
90  return(NULL);
91 found_head:
92  cur = cur->children;
93 
94  /*
95  * Search the meta elements
96  */
97 found_meta:
98  while (cur != NULL) {
99  if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
100  if (xmlStrEqual(cur->name, BAD_CAST"meta")) {
101  xmlAttrPtr attr = cur->properties;
102  int http;
103  const xmlChar *value;
104 
105  content = NULL;
106  http = 0;
107  while (attr != NULL) {
108  if ((attr->children != NULL) &&
109  (attr->children->type == XML_TEXT_NODE) &&
110  (attr->children->next == NULL)) {
111  value = attr->children->content;
112  if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
113  && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
114  http = 1;
115  else if ((value != NULL)
116  && (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
117  content = value;
118  if ((http != 0) && (content != NULL))
119  goto found_content;
120  }
121  attr = attr->next;
122  }
123  }
124  }
125  cur = cur->next;
126  }
127  return(NULL);
128 
129 found_content:
130  encoding = xmlStrstr(content, BAD_CAST"charset=");
131  if (encoding == NULL)
132  encoding = xmlStrstr(content, BAD_CAST"Charset=");
133  if (encoding == NULL)
134  encoding = xmlStrstr(content, BAD_CAST"CHARSET=");
135  if (encoding != NULL) {
136  encoding += 8;
137  } else {
138  encoding = xmlStrstr(content, BAD_CAST"charset =");
139  if (encoding == NULL)
140  encoding = xmlStrstr(content, BAD_CAST"Charset =");
141  if (encoding == NULL)
142  encoding = xmlStrstr(content, BAD_CAST"CHARSET =");
143  if (encoding != NULL)
144  encoding += 9;
145  }
146  if (encoding != NULL) {
147  while ((*encoding == ' ') || (*encoding == '\t')) encoding++;
148  }
149  return(encoding);
150 }
151 
163 int
164 htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) {
165  htmlNodePtr cur, meta = NULL, head = NULL;
166  const xmlChar *content = NULL;
167  char newcontent[100];
168 
169  newcontent[0] = 0;
170 
171  if (doc == NULL)
172  return(-1);
173 
174  /* html isn't a real encoding it's just libxml2 way to get entities */
175  if (!xmlStrcasecmp(encoding, BAD_CAST "html"))
176  return(-1);
177 
178  if (encoding != NULL) {
179  snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s",
180  (char *)encoding);
181  newcontent[sizeof(newcontent) - 1] = 0;
182  }
183 
184  cur = doc->children;
185 
186  /*
187  * Search the html
188  */
189  while (cur != NULL) {
190  if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
191  if (xmlStrcasecmp(cur->name, BAD_CAST"html") == 0)
192  break;
193  if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
194  goto found_head;
195  if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0)
196  goto found_meta;
197  }
198  cur = cur->next;
199  }
200  if (cur == NULL)
201  return(-1);
202  cur = cur->children;
203 
204  /*
205  * Search the head
206  */
207  while (cur != NULL) {
208  if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
209  if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
210  break;
211  if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) {
212  head = cur->parent;
213  goto found_meta;
214  }
215  }
216  cur = cur->next;
217  }
218  if (cur == NULL)
219  return(-1);
220 found_head:
221  head = cur;
222  if (cur->children == NULL)
223  goto create;
224  cur = cur->children;
225 
226 found_meta:
227  /*
228  * Search and update all the remaining the meta elements carrying
229  * encoding information
230  */
231  while (cur != NULL) {
232  if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
233  if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) {
234  xmlAttrPtr attr = cur->properties;
235  int http;
236  const xmlChar *value;
237 
238  content = NULL;
239  http = 0;
240  while (attr != NULL) {
241  if ((attr->children != NULL) &&
242  (attr->children->type == XML_TEXT_NODE) &&
243  (attr->children->next == NULL)) {
244  value = attr->children->content;
245  if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
246  && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
247  http = 1;
248  else
249  {
250  if ((value != NULL) &&
251  (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
252  content = value;
253  }
254  if ((http != 0) && (content != NULL))
255  break;
256  }
257  attr = attr->next;
258  }
259  if ((http != 0) && (content != NULL)) {
260  meta = cur;
261  break;
262  }
263 
264  }
265  }
266  cur = cur->next;
267  }
268 create:
269  if (meta == NULL) {
270  if ((encoding != NULL) && (head != NULL)) {
271  /*
272  * Create a new Meta element with the right attributes
273  */
274 
275  meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
276  if (head->children == NULL)
277  xmlAddChild(head, meta);
278  else
279  xmlAddPrevSibling(head->children, meta);
280  xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
281  xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
282  }
283  } else {
284  /* remove the meta tag if NULL is passed */
285  if (encoding == NULL) {
286  xmlUnlinkNode(meta);
287  xmlFreeNode(meta);
288  }
289  /* change the document only if there is a real encoding change */
290  else if (xmlStrcasestr(content, encoding) == NULL) {
291  xmlSetProp(meta, BAD_CAST"content", BAD_CAST newcontent);
292  }
293  }
294 
295 
296  return(0);
297 }
298 
307 static const char* htmlBooleanAttrs[] = {
308  "checked", "compact", "declare", "defer", "disabled", "ismap",
309  "multiple", "nohref", "noresize", "noshade", "nowrap", "readonly",
310  "selected", NULL
311 };
312 
313 
322 int
323 htmlIsBooleanAttr(const xmlChar *name)
324 {
325  int i = 0;
326 
327  while (htmlBooleanAttrs[i] != NULL) {
328  if (xmlStrcasecmp((const xmlChar *)htmlBooleanAttrs[i], name) == 0)
329  return 1;
330  i++;
331  }
332  return 0;
333 }
334 
335 #ifdef LIBXML_OUTPUT_ENABLED
336 /*
337  * private routine exported from xmlIO.c
338  */
340 xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
341 /************************************************************************
342  * *
343  * Output error handlers *
344  * *
345  ************************************************************************/
352 static void
353 htmlSaveErrMemory(const char *extra)
354 {
355  __xmlSimpleError(XML_FROM_OUTPUT, XML_ERR_NO_MEMORY, NULL, NULL, extra);
356 }
357 
366 static void
367 htmlSaveErr(int code, xmlNodePtr node, const char *extra)
368 {
369  const char *msg = NULL;
370 
371  switch(code) {
372  case XML_SAVE_NOT_UTF8:
373  msg = "string is not in UTF-8\n";
374  break;
376  msg = "invalid character value\n";
377  break;
379  msg = "unknown encoding %s\n";
380  break;
381  case XML_SAVE_NO_DOCTYPE:
382  msg = "HTML has no DOCTYPE\n";
383  break;
384  default:
385  msg = "unexpected error number\n";
386  }
387  __xmlSimpleError(XML_FROM_OUTPUT, code, node, msg, extra);
388 }
389 
390 /************************************************************************
391  * *
392  * Dumping HTML tree content to a simple buffer *
393  * *
394  ************************************************************************/
395 
407 static size_t
408 htmlBufNodeDumpFormat(xmlBufPtr buf, xmlDocPtr doc, xmlNodePtr cur,
409  int format) {
410  size_t use;
411  int ret;
412  xmlOutputBufferPtr outbuf;
413 
414  if (cur == NULL) {
415  return (-1);
416  }
417  if (buf == NULL) {
418  return (-1);
419  }
420  outbuf = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
421  if (outbuf == NULL) {
422  htmlSaveErrMemory("allocating HTML output buffer");
423  return (-1);
424  }
425  memset(outbuf, 0, (size_t) sizeof(xmlOutputBuffer));
426  outbuf->buffer = buf;
427  outbuf->encoder = NULL;
428  outbuf->writecallback = NULL;
429  outbuf->closecallback = NULL;
430  outbuf->context = NULL;
431  outbuf->written = 0;
432 
433  use = xmlBufUse(buf);
434  htmlNodeDumpFormatOutput(outbuf, doc, cur, NULL, format);
435  xmlFree(outbuf);
436  ret = xmlBufUse(buf) - use;
437  return (ret);
438 }
439 
451 int
452 htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
454  size_t ret;
455 
456  if ((buf == NULL) || (cur == NULL))
457  return(-1);
458 
459  xmlInitParser();
461  if (buffer == NULL)
462  return(-1);
463 
464  ret = htmlBufNodeDumpFormat(buffer, doc, cur, 1);
465 
467 
468  if (ret > INT_MAX)
469  return(-1);
470  return((int) ret);
471 }
472 
487 int
488 htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc,
489  xmlNodePtr cur, const char *encoding, int format) {
492  int ret;
493 
494  xmlInitParser();
495 
496  if (encoding != NULL) {
497  xmlCharEncoding enc;
498 
500  if (enc != XML_CHAR_ENCODING_UTF8) {
502  if (handler == NULL)
503  htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
504  }
505  } else {
506  /*
507  * Fallback to HTML or ASCII when the encoding is unspecified
508  */
509  if (handler == NULL)
511  if (handler == NULL)
513  }
514 
515  /*
516  * save the content to a temp buffer.
517  */
518  buf = xmlOutputBufferCreateFile(out, handler);
519  if (buf == NULL) return(0);
520 
521  htmlNodeDumpFormatOutput(buf, doc, cur, NULL, format);
522 
523  ret = xmlOutputBufferClose(buf);
524  return(ret);
525 }
526 
536 void
537 htmlNodeDumpFile(FILE *out, xmlDocPtr doc, xmlNodePtr cur) {
538  htmlNodeDumpFileFormat(out, doc, cur, NULL, 1);
539 }
540 
551 void
552 htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
555  const char *encoding;
556 
557  xmlInitParser();
558 
559  if ((mem == NULL) || (size == NULL))
560  return;
561  if (cur == NULL) {
562  *mem = NULL;
563  *size = 0;
564  return;
565  }
566 
567  encoding = (const char *) htmlGetMetaEncoding(cur);
568 
569  if (encoding != NULL) {
570  xmlCharEncoding enc;
571 
573  if (enc != XML_CHAR_ENCODING_UTF8) {
575  if (handler == NULL)
576  htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
577 
578  }
579  } else {
580  /*
581  * Fallback to HTML or ASCII when the encoding is unspecified
582  */
583  if (handler == NULL)
585  if (handler == NULL)
587  }
588 
589  buf = xmlAllocOutputBufferInternal(handler);
590  if (buf == NULL) {
591  *mem = NULL;
592  *size = 0;
593  return;
594  }
595 
596  htmlDocContentDumpFormatOutput(buf, cur, NULL, format);
597 
598  xmlOutputBufferFlush(buf);
599  if (buf->conv != NULL) {
600  *size = xmlBufUse(buf->conv);
601  *mem = xmlStrndup(xmlBufContent(buf->conv), *size);
602  } else {
603  *size = xmlBufUse(buf->buffer);
604  *mem = xmlStrndup(xmlBufContent(buf->buffer), *size);
605  }
606  (void)xmlOutputBufferClose(buf);
607 }
608 
618 void
619 htmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
620  htmlDocDumpMemoryFormat(cur, mem, size, 1);
621 }
622 
623 
624 /************************************************************************
625  * *
626  * Dumping HTML tree content to an I/O output buffer *
627  * *
628  ************************************************************************/
629 
630 void xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur);
631 
642 static void
643 htmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
644  const char *encoding ATTRIBUTE_UNUSED) {
645  xmlDtdPtr cur = doc->intSubset;
646 
647  if (cur == NULL) {
648  htmlSaveErr(XML_SAVE_NO_DOCTYPE, (xmlNodePtr) doc, NULL);
649  return;
650  }
651  xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
652  xmlOutputBufferWriteString(buf, (const char *)cur->name);
653  if (cur->ExternalID != NULL) {
654  xmlOutputBufferWriteString(buf, " PUBLIC ");
655  xmlBufWriteQuotedString(buf->buffer, cur->ExternalID);
656  if (cur->SystemID != NULL) {
657  xmlOutputBufferWriteString(buf, " ");
658  xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
659  }
660  } else if (cur->SystemID != NULL &&
661  xmlStrcmp(cur->SystemID, BAD_CAST "about:legacy-compat")) {
662  xmlOutputBufferWriteString(buf, " SYSTEM ");
663  xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
664  }
665  xmlOutputBufferWriteString(buf, ">\n");
666 }
667 
676 static void
677 htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
678  xmlChar *value;
679 
680  /*
681  * The html output method should not escape a & character
682  * occurring in an attribute value immediately followed by
683  * a { character (see Section B.7.1 of the HTML 4.0 Recommendation).
684  * This is implemented in xmlEncodeEntitiesReentrant
685  */
686 
687  if (cur == NULL) {
688  return;
689  }
690  xmlOutputBufferWriteString(buf, " ");
691  if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
692  xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
693  xmlOutputBufferWriteString(buf, ":");
694  }
695  xmlOutputBufferWriteString(buf, (const char *)cur->name);
696  if ((cur->children != NULL) && (!htmlIsBooleanAttr(cur->name))) {
697  value = xmlNodeListGetString(doc, cur->children, 0);
698  if (value) {
699  xmlOutputBufferWriteString(buf, "=");
700  if ((cur->ns == NULL) && (cur->parent != NULL) &&
701  (cur->parent->ns == NULL) &&
702  ((!xmlStrcasecmp(cur->name, BAD_CAST "href")) ||
703  (!xmlStrcasecmp(cur->name, BAD_CAST "action")) ||
704  (!xmlStrcasecmp(cur->name, BAD_CAST "src")) ||
705  ((!xmlStrcasecmp(cur->name, BAD_CAST "name")) &&
706  (!xmlStrcasecmp(cur->parent->name, BAD_CAST "a"))))) {
707  xmlChar *escaped;
708  xmlChar *tmp = value;
709 
710  while (IS_BLANK_CH(*tmp)) tmp++;
711 
712  /*
713  * the < and > have already been escaped at the entity level
714  * And doing so here breaks server side includes
715  */
716  escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+<>");
717  if (escaped != NULL) {
718  xmlBufWriteQuotedString(buf->buffer, escaped);
719  xmlFree(escaped);
720  } else {
722  }
723  } else {
725  }
726  xmlFree(value);
727  } else {
728  xmlOutputBufferWriteString(buf, "=\"\"");
729  }
730  }
731 }
732 
743 void
744 htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
746  int format) {
749  const htmlElemDesc * info;
750 
751  xmlInitParser();
752 
753  if ((cur == NULL) || (buf == NULL)) {
754  return;
755  }
756 
757  root = cur;
758  while (1) {
759  switch (cur->type) {
761  case XML_DOCUMENT_NODE:
762  if (((xmlDocPtr) cur)->intSubset != NULL) {
763  htmlDtdDumpOutput(buf, (xmlDocPtr) cur, NULL);
764  }
765  if (cur->children != NULL) {
766  cur = cur->children;
767  continue;
768  }
769  break;
770 
771  case XML_ELEMENT_NODE:
772  /*
773  * Get specific HTML info for that node.
774  */
775  if (cur->ns == NULL)
776  info = htmlTagLookup(cur->name);
777  else
778  info = NULL;
779 
780  xmlOutputBufferWriteString(buf, "<");
781  if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
782  xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
783  xmlOutputBufferWriteString(buf, ":");
784  }
785  xmlOutputBufferWriteString(buf, (const char *)cur->name);
786  if (cur->nsDef)
787  xmlNsListDumpOutput(buf, cur->nsDef);
788  attr = cur->properties;
789  while (attr != NULL) {
790  htmlAttrDumpOutput(buf, doc, attr);
791  attr = attr->next;
792  }
793 
794  if ((info != NULL) && (info->empty)) {
795  xmlOutputBufferWriteString(buf, ">");
796  } else if (cur->children == NULL) {
797  if ((info != NULL) && (info->saveEndTag != 0) &&
798  (xmlStrcmp(BAD_CAST info->name, BAD_CAST "html")) &&
799  (xmlStrcmp(BAD_CAST info->name, BAD_CAST "body"))) {
800  xmlOutputBufferWriteString(buf, ">");
801  } else {
802  xmlOutputBufferWriteString(buf, "></");
803  if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
804  xmlOutputBufferWriteString(buf,
805  (const char *)cur->ns->prefix);
806  xmlOutputBufferWriteString(buf, ":");
807  }
808  xmlOutputBufferWriteString(buf, (const char *)cur->name);
809  xmlOutputBufferWriteString(buf, ">");
810  }
811  } else {
812  xmlOutputBufferWriteString(buf, ">");
813  if ((format) && (info != NULL) && (!info->isinline) &&
814  (cur->children->type != HTML_TEXT_NODE) &&
815  (cur->children->type != HTML_ENTITY_REF_NODE) &&
816  (cur->children != cur->last) &&
817  (cur->name != NULL) &&
818  (cur->name[0] != 'p')) /* p, pre, param */
819  xmlOutputBufferWriteString(buf, "\n");
820  cur = cur->children;
821  continue;
822  }
823 
824  if ((format) && (cur->next != NULL) &&
825  (info != NULL) && (!info->isinline)) {
826  if ((cur->next->type != HTML_TEXT_NODE) &&
827  (cur->next->type != HTML_ENTITY_REF_NODE) &&
828  (cur->parent != NULL) &&
829  (cur->parent->name != NULL) &&
830  (cur->parent->name[0] != 'p')) /* p, pre, param */
831  xmlOutputBufferWriteString(buf, "\n");
832  }
833 
834  break;
835 
836  case XML_ATTRIBUTE_NODE:
837  htmlAttrDumpOutput(buf, doc, (xmlAttrPtr) cur);
838  break;
839 
840  case HTML_TEXT_NODE:
841  if (cur->content == NULL)
842  break;
843  if (((cur->name == (const xmlChar *)xmlStringText) ||
844  (cur->name != (const xmlChar *)xmlStringTextNoenc)) &&
845  ((cur->parent == NULL) ||
846  ((xmlStrcasecmp(cur->parent->name, BAD_CAST "script")) &&
847  (xmlStrcasecmp(cur->parent->name, BAD_CAST "style"))))) {
848  xmlChar *buffer;
849 
850  buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
851  if (buffer != NULL) {
852  xmlOutputBufferWriteString(buf, (const char *)buffer);
853  xmlFree(buffer);
854  }
855  } else {
856  xmlOutputBufferWriteString(buf, (const char *)cur->content);
857  }
858  break;
859 
860  case HTML_COMMENT_NODE:
861  if (cur->content != NULL) {
862  xmlOutputBufferWriteString(buf, "<!--");
863  xmlOutputBufferWriteString(buf, (const char *)cur->content);
864  xmlOutputBufferWriteString(buf, "-->");
865  }
866  break;
867 
868  case HTML_PI_NODE:
869  if (cur->name != NULL) {
870  xmlOutputBufferWriteString(buf, "<?");
871  xmlOutputBufferWriteString(buf, (const char *)cur->name);
872  if (cur->content != NULL) {
873  xmlOutputBufferWriteString(buf, " ");
874  xmlOutputBufferWriteString(buf,
875  (const char *)cur->content);
876  }
877  xmlOutputBufferWriteString(buf, ">");
878  }
879  break;
880 
881  case HTML_ENTITY_REF_NODE:
882  xmlOutputBufferWriteString(buf, "&");
883  xmlOutputBufferWriteString(buf, (const char *)cur->name);
884  xmlOutputBufferWriteString(buf, ";");
885  break;
886 
887  case HTML_PRESERVE_NODE:
888  if (cur->content != NULL) {
889  xmlOutputBufferWriteString(buf, (const char *)cur->content);
890  }
891  break;
892 
893  default:
894  break;
895  }
896 
897  while (1) {
898  if (cur == root)
899  return;
900  if (cur->next != NULL) {
901  cur = cur->next;
902  break;
903  }
904 
905  /*
906  * The parent should never be NULL here but we want to handle
907  * corrupted documents gracefully.
908  */
909  if (cur->parent == NULL)
910  return;
911  cur = cur->parent;
912 
913  if ((cur->type == XML_HTML_DOCUMENT_NODE) ||
914  (cur->type == XML_DOCUMENT_NODE)) {
915  xmlOutputBufferWriteString(buf, "\n");
916  } else {
917  if ((format) && (cur->ns == NULL))
918  info = htmlTagLookup(cur->name);
919  else
920  info = NULL;
921 
922  if ((format) && (info != NULL) && (!info->isinline) &&
923  (cur->last->type != HTML_TEXT_NODE) &&
924  (cur->last->type != HTML_ENTITY_REF_NODE) &&
925  (cur->children != cur->last) &&
926  (cur->name != NULL) &&
927  (cur->name[0] != 'p')) /* p, pre, param */
928  xmlOutputBufferWriteString(buf, "\n");
929 
930  xmlOutputBufferWriteString(buf, "</");
931  if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
932  xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
933  xmlOutputBufferWriteString(buf, ":");
934  }
935  xmlOutputBufferWriteString(buf, (const char *)cur->name);
936  xmlOutputBufferWriteString(buf, ">");
937 
938  if ((format) && (info != NULL) && (!info->isinline) &&
939  (cur->next != NULL)) {
940  if ((cur->next->type != HTML_TEXT_NODE) &&
941  (cur->next->type != HTML_ENTITY_REF_NODE) &&
942  (cur->parent != NULL) &&
943  (cur->parent->name != NULL) &&
944  (cur->parent->name[0] != 'p')) /* p, pre, param */
945  xmlOutputBufferWriteString(buf, "\n");
946  }
947  }
948  }
949  }
950 }
951 
962 void
963 htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
964  xmlNodePtr cur, const char *encoding ATTRIBUTE_UNUSED) {
965  htmlNodeDumpFormatOutput(buf, doc, cur, NULL, 1);
966 }
967 
977 void
978 htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
979  const char *encoding ATTRIBUTE_UNUSED,
980  int format) {
981  htmlNodeDumpFormatOutput(buf, cur, (xmlNodePtr) cur, NULL, format);
982 }
983 
992 void
993 htmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
994  const char *encoding ATTRIBUTE_UNUSED) {
995  htmlNodeDumpFormatOutput(buf, cur, (xmlNodePtr) cur, NULL, 1);
996 }
997 
998 /************************************************************************
999  * *
1000  * Saving functions front-ends *
1001  * *
1002  ************************************************************************/
1003 
1013 int
1014 htmlDocDump(FILE *f, xmlDocPtr cur) {
1017  const char *encoding;
1018  int ret;
1019 
1020  xmlInitParser();
1021 
1022  if ((cur == NULL) || (f == NULL)) {
1023  return(-1);
1024  }
1025 
1026  encoding = (const char *) htmlGetMetaEncoding(cur);
1027 
1028  if (encoding != NULL) {
1029  xmlCharEncoding enc;
1030 
1032  if (enc != XML_CHAR_ENCODING_UTF8) {
1034  if (handler == NULL)
1035  htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
1036  }
1037  } else {
1038  /*
1039  * Fallback to HTML or ASCII when the encoding is unspecified
1040  */
1041  if (handler == NULL)
1043  if (handler == NULL)
1045  }
1046 
1047  buf = xmlOutputBufferCreateFile(f, handler);
1048  if (buf == NULL) return(-1);
1049  htmlDocContentDumpOutput(buf, cur, NULL);
1050 
1051  ret = xmlOutputBufferClose(buf);
1052  return(ret);
1053 }
1054 
1064 int
1065 htmlSaveFile(const char *filename, xmlDocPtr cur) {
1068  const char *encoding;
1069  int ret;
1070 
1071  if ((cur == NULL) || (filename == NULL))
1072  return(-1);
1073 
1074  xmlInitParser();
1075 
1076  encoding = (const char *) htmlGetMetaEncoding(cur);
1077 
1078  if (encoding != NULL) {
1079  xmlCharEncoding enc;
1080 
1082  if (enc != XML_CHAR_ENCODING_UTF8) {
1084  if (handler == NULL)
1085  htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
1086  }
1087  } else {
1088  /*
1089  * Fallback to HTML or ASCII when the encoding is unspecified
1090  */
1091  if (handler == NULL)
1093  if (handler == NULL)
1095  }
1096 
1097  /*
1098  * save the content to a temp buffer.
1099  */
1100  buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
1101  if (buf == NULL) return(0);
1102 
1103  htmlDocContentDumpOutput(buf, cur, NULL);
1104 
1105  ret = xmlOutputBufferClose(buf);
1106  return(ret);
1107 }
1108 
1120 int
1121 htmlSaveFileFormat(const char *filename, xmlDocPtr cur,
1122  const char *encoding, int format) {
1125  int ret;
1126 
1127  if ((cur == NULL) || (filename == NULL))
1128  return(-1);
1129 
1130  xmlInitParser();
1131 
1132  if (encoding != NULL) {
1133  xmlCharEncoding enc;
1134 
1136  if (enc != XML_CHAR_ENCODING_UTF8) {
1138  if (handler == NULL)
1139  htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
1140  }
1141  htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
1142  } else {
1143  htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
1144 
1145  /*
1146  * Fallback to HTML or ASCII when the encoding is unspecified
1147  */
1148  if (handler == NULL)
1150  if (handler == NULL)
1152  }
1153 
1154  /*
1155  * save the content to a temp buffer.
1156  */
1157  buf = xmlOutputBufferCreateFilename(filename, handler, 0);
1158  if (buf == NULL) return(0);
1159 
1160  htmlDocContentDumpFormatOutput(buf, cur, encoding, format);
1161 
1162  ret = xmlOutputBufferClose(buf);
1163  return(ret);
1164 }
1165 
1177 int
1178 htmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
1179  return(htmlSaveFileFormat(filename, cur, encoding, 1));
1180 }
1181 
1182 #endif /* LIBXML_OUTPUT_ENABLED */
1183 
1184 #define bottom_HTMLtree
1185 #include "elfgcchack.h"
1186 #endif /* LIBXML_HTML_ENABLED */
Definition: pdh_main.c:93
XMLPUBFUN const xmlChar *XMLCALL xmlStrstr(const xmlChar *str, const xmlChar *val)
Definition: xmlstring.c:344
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
XMLPUBFUN xmlCharEncoding XMLCALL xmlParseCharEncoding(const char *name)
Definition: encoding.c:1160
XMLPUBFUN xmlChar *XMLCALL xmlBufContent(const xmlBuf *buf)
Definition: buf.c:582
#define INT_MAX
Definition: limits.h:40
struct _xmlDtd * intSubset
Definition: tree.h:570
struct outqueuenode * head
Definition: adnsresfilter.c:66
Definition: tree.h:389
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:41
XMLPUBFUN void XMLCALL xmlInitParser(void)
Definition: parser.c:14670
struct _root root
XMLPUBFUN xmlChar *XMLCALL xmlURIEscapeStr(const xmlChar *str, const xmlChar *list)
Definition: uri.c:1678
xmlBufPtr xmlBufFromBuffer(xmlBufferPtr buffer)
Definition: buf.c:1167
#define snprintf
Definition: wintirpc.h:48
GLuint buffer
Definition: glext.h:5915
xmlCharEncoding
Definition: encoding.h:58
XMLPUBFUN xmlChar *XMLCALL xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input)
const char * filename
Definition: ioapi.h:135
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
Definition: tree.h:406
struct _xmlOutputBuffer xmlOutputBuffer
Definition: tree.h:31
Definition: buf.c:43
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
xmlOutputBuffer * xmlOutputBufferPtr
Definition: tree.h:32
#define IS_BLANK_CH(c)
content
Definition: atl_ax.c:993
XMLPUBVAR const xmlChar xmlStringText[]
#define BAD_CAST
Definition: xmlstring.h:35
GLfloat f
Definition: glext.h:7540
GLsizeiptr size
Definition: glext.h:5919
XMLPUBFUN xmlNodePtr XMLCALL xmlAddChild(xmlNodePtr parent, xmlNodePtr cur)
Definition: id3.c:95
XMLPUBFUN void XMLCALL xmlUnlinkNode(xmlNodePtr cur)
static FILE * out
Definition: regtests2xml.c:44
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:250
Definition: cookie.c:201
struct _test_info info[]
Definition: SetCursorPos.c:19
Definition: tree.h:489
XMLPUBFUN xmlChar *XMLCALL xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
int ret
xmlBufferPtr xmlBufBackToBuffer(xmlBufPtr buf)
Definition: buf.c:1204
__u8 attr
Definition: mkdosfs.c:359
XMLPUBFUN xmlCharEncodingHandlerPtr XMLCALL xmlFindCharEncodingHandler(const char *name)
Definition: encoding.c:1660
unsigned char xmlChar
Definition: xmlstring.h:28
GLsizei const GLfloat * value
Definition: glext.h:6069
Definition: inflate.c:139
ed encoding
Definition: write.c:2825
FxCollectionEntry * cur
static WCHAR http[]
Definition: url.c:30
XMLPUBFUN const xmlChar *XMLCALL xmlStrcasestr(const xmlChar *str, const xmlChar *val)
Definition: xmlstring.c:372
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ATTRIBUTE_UNUSED
Definition: win32config.h:132
XMLPUBVAR const xmlChar xmlStringTextNoenc[]
#define NULL
Definition: types.h:112
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns, const xmlChar *name, const xmlChar *content)
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:247
Definition: tree.h:551
XMLPUBFUN void XMLCALL xmlFreeNode(xmlNodePtr cur)
#define msg(x)
Definition: auth_time.c:54
Definition: mem.c:156
Definition: tree.h:434
Definition: name.c:38
WCHAR * name
Definition: cookie.c:203
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7786
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:159
#define memset(x, y, z)
Definition: compat.h:39
static const struct access_res create[16]
Definition: package.c:7720
int xmlBufWriteQuotedString(xmlBufPtr buf, const xmlChar *string)
Definition: buf.c:1111
XMLPUBFUN int XMLCALL xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:274
XMLPUBFUN size_t XMLCALL xmlBufUse(const xmlBufPtr buf)
Definition: buf.c:687
Definition: dlist.c:348
XMLPUBFUN int XMLCALL xmlStrcmp(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:132