| OLD | NEW |
| 1 /* | 1 /* |
| 2 * HTMLtree.c : implementation of access function for an HTML tree. | 2 * HTMLtree.c : implementation of access function for an HTML tree. |
| 3 * | 3 * |
| 4 * See Copyright for the status of this software. | 4 * See Copyright for the status of this software. |
| 5 * | 5 * |
| 6 * daniel@veillard.com | 6 * daniel@veillard.com |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #define IN_LIBXML | 10 #define IN_LIBXML |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 * @encoding: the encoding string | 153 * @encoding: the encoding string |
| 154 * | 154 * |
| 155 * Sets the current encoding in the Meta tags | 155 * Sets the current encoding in the Meta tags |
| 156 * NOTE: this will not change the document content encoding, just | 156 * NOTE: this will not change the document content encoding, just |
| 157 * the META flag associated. | 157 * the META flag associated. |
| 158 * | 158 * |
| 159 * Returns 0 in case of success and -1 in case of error | 159 * Returns 0 in case of success and -1 in case of error |
| 160 */ | 160 */ |
| 161 int | 161 int |
| 162 htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) { | 162 htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) { |
| 163 htmlNodePtr cur, meta; | 163 htmlNodePtr cur, meta = NULL, head = NULL; |
| 164 const xmlChar *content; | 164 const xmlChar *content = NULL; |
| 165 char newcontent[100]; | 165 char newcontent[100]; |
| 166 | 166 |
| 167 | 167 |
| 168 if (doc == NULL) | 168 if (doc == NULL) |
| 169 return(-1); | 169 return(-1); |
| 170 | 170 |
| 171 /* html isn't a real encoding it's just libxml2 way to get entities */ |
| 172 if (!xmlStrcasecmp(encoding, BAD_CAST "html")) |
| 173 return(-1); |
| 174 |
| 171 if (encoding != NULL) { | 175 if (encoding != NULL) { |
| 172 snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s", | 176 snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s", |
| 173 (char *)encoding); | 177 (char *)encoding); |
| 174 newcontent[sizeof(newcontent) - 1] = 0; | 178 newcontent[sizeof(newcontent) - 1] = 0; |
| 175 } | 179 } |
| 176 | 180 |
| 177 cur = doc->children; | 181 cur = doc->children; |
| 178 | 182 |
| 179 /* | 183 /* |
| 180 * Search the html | 184 * Search the html |
| (...skipping 13 matching lines...) Expand all Loading... |
| 194 return(-1); | 198 return(-1); |
| 195 cur = cur->children; | 199 cur = cur->children; |
| 196 | 200 |
| 197 /* | 201 /* |
| 198 * Search the head | 202 * Search the head |
| 199 */ | 203 */ |
| 200 while (cur != NULL) { | 204 while (cur != NULL) { |
| 201 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) { | 205 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) { |
| 202 if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0) | 206 if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0) |
| 203 break; | 207 break; |
| 204 » if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) | 208 » if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) { |
| 209 head = cur->parent; |
| 205 goto found_meta; | 210 goto found_meta; |
| 211 } |
| 206 } | 212 } |
| 207 cur = cur->next; | 213 cur = cur->next; |
| 208 } | 214 } |
| 209 if (cur == NULL) | 215 if (cur == NULL) |
| 210 return(-1); | 216 return(-1); |
| 211 found_head: | 217 found_head: |
| 212 if (cur->children == NULL) { | 218 head = cur; |
| 213 » if (encoding == NULL) | 219 if (cur->children == NULL) |
| 214 » return(0); | 220 goto create; |
| 215 » meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL); | |
| 216 » xmlAddChild(cur, meta); | |
| 217 » xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type"); | |
| 218 » xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent); | |
| 219 » return(0); | |
| 220 } | |
| 221 cur = cur->children; | 221 cur = cur->children; |
| 222 | 222 |
| 223 found_meta: | 223 found_meta: |
| 224 if (encoding != NULL) { | |
| 225 /* | |
| 226 * Create a new Meta element with the right attributes | |
| 227 */ | |
| 228 | |
| 229 meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL); | |
| 230 xmlAddPrevSibling(cur, meta); | |
| 231 xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type"); | |
| 232 xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent); | |
| 233 } | |
| 234 | |
| 235 /* | 224 /* |
| 236 * Search and destroy all the remaining the meta elements carrying | 225 * Search and update all the remaining the meta elements carrying |
| 237 * encoding informations | 226 * encoding informations |
| 238 */ | 227 */ |
| 239 while (cur != NULL) { | 228 while (cur != NULL) { |
| 240 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) { | 229 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) { |
| 241 if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) { | 230 if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) { |
| 242 xmlAttrPtr attr = cur->properties; | 231 xmlAttrPtr attr = cur->properties; |
| 243 int http; | 232 int http; |
| 244 const xmlChar *value; | 233 const xmlChar *value; |
| 245 | 234 |
| 246 content = NULL; | 235 content = NULL; |
| 247 http = 0; | 236 http = 0; |
| 248 while (attr != NULL) { | 237 while (attr != NULL) { |
| 249 if ((attr->children != NULL) && | 238 if ((attr->children != NULL) && |
| 250 (attr->children->type == XML_TEXT_NODE) && | 239 (attr->children->type == XML_TEXT_NODE) && |
| 251 (attr->children->next == NULL)) { | 240 (attr->children->next == NULL)) { |
| 252 value = attr->children->content; | 241 value = attr->children->content; |
| 253 if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv")) | 242 if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv")) |
| 254 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type"))) | 243 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type"))) |
| 255 http = 1; | 244 http = 1; |
| 256 » » » else | 245 » » » else |
| 257 { | 246 { |
| 258 if ((value != NULL) && | 247 if ((value != NULL) && |
| 259 » » » » (!xmlStrcasecmp(attr->name, BAD_CAST"content"))) | 248 (!xmlStrcasecmp(attr->name, BAD_CAST"content"))) |
| 260 » » » content = value; | 249 » » » content = value; |
| 261 } | 250 } |
| 262 if ((http != 0) && (content != NULL)) | 251 if ((http != 0) && (content != NULL)) |
| 263 break; | 252 break; |
| 264 } | 253 } |
| 265 attr = attr->next; | 254 attr = attr->next; |
| 266 } | 255 } |
| 267 if ((http != 0) && (content != NULL)) { | 256 if ((http != 0) && (content != NULL)) { |
| 268 meta = cur; | 257 meta = cur; |
| 269 » » cur = cur->next; | 258 » » break; |
| 270 » » xmlUnlinkNode(meta); | |
| 271 xmlFreeNode(meta); | |
| 272 » » continue; | |
| 273 } | 259 } |
| 274 | 260 |
| 275 } | 261 } |
| 276 } | 262 } |
| 277 cur = cur->next; | 263 cur = cur->next; |
| 278 } | 264 } |
| 265 create: |
| 266 if (meta == NULL) { |
| 267 if ((encoding != NULL) && (head != NULL)) { |
| 268 /* |
| 269 * Create a new Meta element with the right attributes |
| 270 */ |
| 271 |
| 272 meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL); |
| 273 if (head->children == NULL) |
| 274 xmlAddChild(head, meta); |
| 275 else |
| 276 xmlAddPrevSibling(head->children, meta); |
| 277 xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type"); |
| 278 xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent); |
| 279 } |
| 280 } else { |
| 281 /* change the document only if there is a real encoding change */ |
| 282 if (xmlStrcasestr(content, encoding) == NULL) { |
| 283 xmlSetProp(meta, BAD_CAST"content", BAD_CAST newcontent); |
| 284 } |
| 285 } |
| 286 |
| 287 |
| 279 return(0); | 288 return(0); |
| 280 } | 289 } |
| 281 | 290 |
| 282 /** | 291 /** |
| 283 * booleanHTMLAttrs: | 292 * booleanHTMLAttrs: |
| 284 * | 293 * |
| 285 * These are the HTML attributes which will be output | 294 * These are the HTML attributes which will be output |
| 286 * in minimized form, i.e. <option selected="selected"> will be | 295 * in minimized form, i.e. <option selected="selected"> will be |
| 287 * output as <option selected>, as per XSLT 1.0 16.2 "HTML Output Method" | 296 * output as <option selected>, as per XSLT 1.0 16.2 "HTML Output Method" |
| 288 * | 297 * |
| (...skipping 20 matching lines...) Expand all Loading... |
| 309 | 318 |
| 310 while (htmlBooleanAttrs[i] != NULL) { | 319 while (htmlBooleanAttrs[i] != NULL) { |
| 311 if (xmlStrcasecmp((const xmlChar *)htmlBooleanAttrs[i], name) == 0) | 320 if (xmlStrcasecmp((const xmlChar *)htmlBooleanAttrs[i], name) == 0) |
| 312 return 1; | 321 return 1; |
| 313 i++; | 322 i++; |
| 314 } | 323 } |
| 315 return 0; | 324 return 0; |
| 316 } | 325 } |
| 317 | 326 |
| 318 #ifdef LIBXML_OUTPUT_ENABLED | 327 #ifdef LIBXML_OUTPUT_ENABLED |
| 328 /* |
| 329 * private routine exported from xmlIO.c |
| 330 */ |
| 331 xmlOutputBufferPtr |
| 332 xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder); |
| 319 /************************************************************************ | 333 /************************************************************************ |
| 320 * * | 334 * * |
| 321 * Output error handlers * | 335 * Output error handlers * |
| 322 * * | 336 * * |
| 323 ************************************************************************/ | 337 ************************************************************************/ |
| 324 /** | 338 /** |
| 325 * htmlSaveErrMemory: | 339 * htmlSaveErrMemory: |
| 326 * @extra: extra informations | 340 * @extra: extra informations |
| 327 * | 341 * |
| 328 * Handle an out of memory condition | 342 * Handle an out of memory condition |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 } | 573 } |
| 560 | 574 |
| 561 /* | 575 /* |
| 562 * Fallback to HTML or ASCII when the encoding is unspecified | 576 * Fallback to HTML or ASCII when the encoding is unspecified |
| 563 */ | 577 */ |
| 564 if (handler == NULL) | 578 if (handler == NULL) |
| 565 handler = xmlFindCharEncodingHandler("HTML"); | 579 handler = xmlFindCharEncodingHandler("HTML"); |
| 566 if (handler == NULL) | 580 if (handler == NULL) |
| 567 handler = xmlFindCharEncodingHandler("ascii"); | 581 handler = xmlFindCharEncodingHandler("ascii"); |
| 568 | 582 |
| 569 buf = xmlAllocOutputBuffer(handler); | 583 buf = xmlAllocOutputBufferInternal(handler); |
| 570 if (buf == NULL) { | 584 if (buf == NULL) { |
| 571 *mem = NULL; | 585 *mem = NULL; |
| 572 *size = 0; | 586 *size = 0; |
| 573 return; | 587 return; |
| 574 } | 588 } |
| 575 | 589 |
| 576 htmlDocContentDumpFormatOutput(buf, cur, NULL, format); | 590 htmlDocContentDumpFormatOutput(buf, cur, NULL, format); |
| 577 | 591 |
| 578 xmlOutputBufferFlush(buf); | 592 xmlOutputBufferFlush(buf); |
| 579 if (buf->conv != NULL) { | 593 if (buf->conv != NULL) { |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 */ | 1157 */ |
| 1144 int | 1158 int |
| 1145 htmlSaveFileFormat(const char *filename, xmlDocPtr cur, | 1159 htmlSaveFileFormat(const char *filename, xmlDocPtr cur, |
| 1146 const char *encoding, int format) { | 1160 const char *encoding, int format) { |
| 1147 xmlOutputBufferPtr buf; | 1161 xmlOutputBufferPtr buf; |
| 1148 xmlCharEncodingHandlerPtr handler = NULL; | 1162 xmlCharEncodingHandlerPtr handler = NULL; |
| 1149 int ret; | 1163 int ret; |
| 1150 | 1164 |
| 1151 if ((cur == NULL) || (filename == NULL)) | 1165 if ((cur == NULL) || (filename == NULL)) |
| 1152 return(-1); | 1166 return(-1); |
| 1153 | 1167 |
| 1154 xmlInitParser(); | 1168 xmlInitParser(); |
| 1155 | 1169 |
| 1156 if (encoding != NULL) { | 1170 if (encoding != NULL) { |
| 1157 xmlCharEncoding enc; | 1171 xmlCharEncoding enc; |
| 1158 | 1172 |
| 1159 enc = xmlParseCharEncoding(encoding); | 1173 enc = xmlParseCharEncoding(encoding); |
| 1160 if (enc != cur->charset) { | 1174 if (enc != cur->charset) { |
| 1161 if (cur->charset != XML_CHAR_ENCODING_UTF8) { | 1175 if (cur->charset != XML_CHAR_ENCODING_UTF8) { |
| 1162 /* | 1176 /* |
| 1163 * Not supported yet | 1177 * Not supported yet |
| 1164 */ | 1178 */ |
| 1165 return(-1); | 1179 return(-1); |
| 1166 } | 1180 } |
| 1167 | 1181 |
| 1168 handler = xmlFindCharEncodingHandler(encoding); | 1182 handler = xmlFindCharEncodingHandler(encoding); |
| 1169 if (handler == NULL) | 1183 if (handler == NULL) |
| 1170 return(-1); | 1184 return(-1); |
| 1171 htmlSetMetaEncoding(cur, (const xmlChar *) encoding); | |
| 1172 } | 1185 } |
| 1186 htmlSetMetaEncoding(cur, (const xmlChar *) encoding); |
| 1173 } else { | 1187 } else { |
| 1174 htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8"); | 1188 htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8"); |
| 1175 } | 1189 } |
| 1176 | 1190 |
| 1177 /* | 1191 /* |
| 1178 * Fallback to HTML or ASCII when the encoding is unspecified | 1192 * Fallback to HTML or ASCII when the encoding is unspecified |
| 1179 */ | 1193 */ |
| 1180 if (handler == NULL) | 1194 if (handler == NULL) |
| 1181 handler = xmlFindCharEncodingHandler("HTML"); | 1195 handler = xmlFindCharEncodingHandler("HTML"); |
| 1182 if (handler == NULL) | 1196 if (handler == NULL) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1208 int | 1222 int |
| 1209 htmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) { | 1223 htmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) { |
| 1210 return(htmlSaveFileFormat(filename, cur, encoding, 1)); | 1224 return(htmlSaveFileFormat(filename, cur, encoding, 1)); |
| 1211 } | 1225 } |
| 1212 | 1226 |
| 1213 #endif /* LIBXML_OUTPUT_ENABLED */ | 1227 #endif /* LIBXML_OUTPUT_ENABLED */ |
| 1214 | 1228 |
| 1215 #define bottom_HTMLtree | 1229 #define bottom_HTMLtree |
| 1216 #include "elfgcchack.h" | 1230 #include "elfgcchack.h" |
| 1217 #endif /* LIBXML_HTML_ENABLED */ | 1231 #endif /* LIBXML_HTML_ENABLED */ |
| OLD | NEW |