iconv: Bail out of the loop when an illegal sequence of bytes occurs.
[elinks/elinks-j605.git] / src / dom / sgml / dump.c
blob3bac87e818de498159562b2894d60bafe0e776b0
1 /* SGML generics */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include <stdlib.h>
8 #include <string.h>
10 #include "elinks.h"
12 #include "dom/node.h"
13 #include "dom/sgml/dump.h"
14 #include "dom/stack.h"
15 #include "dom/string.h"
18 static enum dom_code
19 sgml_file_dumper_element_push(struct dom_stack *stack, struct dom_node *node, void *data)
21 FILE *file = stack->current->data;
22 struct dom_string *string = &node->string;
24 fprintf(file, "<%.*s", string->length, string->string);
25 if (!node->data.element.map
26 || node->data.element.map->size == 0)
27 fprintf(file, ">");
29 return DOM_CODE_OK;
32 static enum dom_code
33 sgml_file_dumper_element_pop(struct dom_stack *stack, struct dom_node *node, void *data)
35 FILE *file = stack->current->data;
36 struct dom_string *string = &node->string;
38 fprintf(file, "</%.*s>", string->length, string->string);
40 return DOM_CODE_OK;
43 static enum dom_code
44 sgml_file_dumper_attribute_push(struct dom_stack *stack, struct dom_node *node, void *data)
46 FILE *file = stack->current->data;
47 struct dom_string *name = &node->string;
48 struct dom_string *value = &node->data.attribute.value;
50 if (node->parent->type == DOM_NODE_PROCESSING_INSTRUCTION)
51 return DOM_CODE_OK;
53 fprintf(file, " %.*s", name->length, name->string);
55 if (value->string) {
56 if (node->data.attribute.quoted)
57 fprintf(file, "=%c%.*s%c",
58 node->data.attribute.quoted,
59 value->length, value->string,
60 node->data.attribute.quoted);
61 else
62 /* FIXME: 'encode' if the value contains '"'s? */
63 fprintf(file, "=\"%.*s\"", value->length, value->string);
66 if (!get_dom_node_next(node))
67 fprintf(file, ">");
69 return DOM_CODE_OK;
72 static enum dom_code
73 sgml_file_dumper_proc_instruction_push(struct dom_stack *stack, struct dom_node *node, void *data)
75 FILE *file = stack->current->data;
76 struct dom_string *target = &node->string;
77 struct dom_string *instruction = &node->data.proc_instruction.instruction;
79 fprintf(file, "<?%.*s %.*s?>",
80 target->length, target->string,
81 instruction->length, instruction->string);
83 return DOM_CODE_OK;
86 static enum dom_code
87 sgml_file_dumper_text_push(struct dom_stack *stack, struct dom_node *node, void *data)
89 FILE *file = stack->current->data;
90 struct dom_string *string = &node->string;
92 fprintf(file, "%.*s", string->length, string->string);
94 return DOM_CODE_OK;
97 static enum dom_code
98 sgml_file_dumper_cdata_section_push(struct dom_stack *stack, struct dom_node *node, void *data)
100 FILE *file = stack->current->data;
101 struct dom_string *string = &node->string;
103 fprintf(file, "<![CDATA[%.*s]]>", string->length, string->string);
105 return DOM_CODE_OK;
108 static enum dom_code
109 sgml_file_dumper_comment_push(struct dom_stack *stack, struct dom_node *node, void *data)
111 FILE *file = stack->current->data;
112 struct dom_string *string = &node->string;
114 fprintf(file, "<!--%.*s-->", string->length, string->string);
116 return DOM_CODE_OK;
119 static enum dom_code
120 sgml_file_dumper_entity_ref_push(struct dom_stack *stack, struct dom_node *node, void *data)
122 FILE *file = stack->current->data;
123 struct dom_string *string = &node->string;
125 fprintf(file, "&%.*s;", string->length, string->string);
127 return DOM_CODE_OK;
130 struct dom_stack_context_info sgml_file_dumper = {
131 /* Object size: */ 0,
132 /* Push: */
134 /* */ NULL,
135 /* DOM_NODE_ELEMENT */ sgml_file_dumper_element_push,
136 /* DOM_NODE_ATTRIBUTE */ sgml_file_dumper_attribute_push,
137 /* DOM_NODE_TEXT */ sgml_file_dumper_text_push,
138 /* DOM_NODE_CDATA_SECTION */ sgml_file_dumper_cdata_section_push,
139 /* DOM_NODE_ENTITY_REFERENCE */ sgml_file_dumper_entity_ref_push,
140 /* DOM_NODE_ENTITY */ NULL,
141 /* DOM_NODE_PROC_INSTRUCTION */ sgml_file_dumper_proc_instruction_push,
142 /* DOM_NODE_COMMENT */ sgml_file_dumper_comment_push,
143 /* DOM_NODE_DOCUMENT */ NULL,
144 /* DOM_NODE_DOCUMENT_TYPE */ NULL,
145 /* DOM_NODE_DOCUMENT_FRAGMENT */ NULL,
146 /* DOM_NODE_NOTATION */ NULL,
148 /* Pop: */
150 /* */ NULL,
151 /* DOM_NODE_ELEMENT */ sgml_file_dumper_element_pop,
152 /* DOM_NODE_ATTRIBUTE */ NULL,
153 /* DOM_NODE_TEXT */ NULL,
154 /* DOM_NODE_CDATA_SECTION */ NULL,
155 /* DOM_NODE_ENTITY_REFERENCE */ NULL,
156 /* DOM_NODE_ENTITY */ NULL,
157 /* DOM_NODE_PROC_INSTRUCTION */ NULL,
158 /* DOM_NODE_COMMENT */ NULL,
159 /* DOM_NODE_DOCUMENT */ NULL,
160 /* DOM_NODE_DOCUMENT_TYPE */ NULL,
161 /* DOM_NODE_DOCUMENT_FRAGMENT */ NULL,
162 /* DOM_NODE_NOTATION */ NULL,
166 struct dom_stack_context *
167 add_sgml_file_dumper(struct dom_stack *stack, FILE *file)
169 return add_dom_stack_context(stack, file, &sgml_file_dumper);