aboutsummaryrefslogtreecommitdiffstats
path: root/src/xml.c
diff options
context:
space:
mode:
authorPaul Eggert2012-04-09 15:54:59 -0700
committerPaul Eggert2012-04-09 15:54:59 -0700
commit45e9f7da84c1bd3fc0d36d05c5708ed3b2d3a193 (patch)
tree5bc87a8b5a3c754b8eb44a612cc6c03561d6b968 /src/xml.c
parent9d6b4d53469a9ffd67bd770fabc6fe254e35c21d (diff)
parent05920a43fc18e696b464387e781e7cfdcea5b5af (diff)
downloademacs-45e9f7da84c1bd3fc0d36d05c5708ed3b2d3a193.tar.gz
emacs-45e9f7da84c1bd3fc0d36d05c5708ed3b2d3a193.zip
Merge from trunk.
Diffstat (limited to 'src/xml.c')
-rw-r--r--src/xml.c132
1 files changed, 118 insertions, 14 deletions
diff --git a/src/xml.c b/src/xml.c
index 8c88226b505..e462a1adf57 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -28,6 +28,97 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
28#include "lisp.h" 28#include "lisp.h"
29#include "buffer.h" 29#include "buffer.h"
30 30
31
32static Lisp_Object Qlibxml2_dll;
33
34#ifdef WINDOWSNT
35
36#include <windows.h>
37#include "w32.h"
38
39/* Macro for defining functions that will be loaded from the libxml2 DLL. */
40#define DEF_XML2_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
41
42/* Macro for loading libxml2 functions from the library. */
43#define LOAD_XML2_FN(lib,func) { \
44 fn_##func = (void *) GetProcAddress (lib, #func); \
45 if (!fn_##func) goto bad_library; \
46 }
47
48DEF_XML2_FN (htmlDocPtr, htmlReadMemory,
49 (const char *, int, const char *, const char *, int));
50DEF_XML2_FN (xmlDocPtr, xmlReadMemory,
51 (const char *, int, const char *, const char *, int));
52DEF_XML2_FN (xmlNodePtr, xmlDocGetRootElement, (xmlDocPtr));
53DEF_XML2_FN (void, xmlFreeDoc, (xmlDocPtr));
54DEF_XML2_FN (void, xmlCleanupParser, (void));
55DEF_XML2_FN (void, xmlCheckVersion, (int));
56
57static int
58libxml2_loaded_p (void)
59{
60 Lisp_Object found = Fassq (Qlibxml2_dll, Vlibrary_cache);
61
62 if (CONSP (found))
63 return EQ (XCDR (found), Qt) ? 1 : 0;
64 return 0;
65}
66
67#else /* !WINDOWSNT */
68
69#define fn_htmlReadMemory htmlReadMemory
70#define fn_xmlReadMemory xmlReadMemory
71#define fn_xmlDocGetRootElement xmlDocGetRootElement
72#define fn_xmlFreeDoc xmlFreeDoc
73#define fn_xmlCleanupParser xmlCleanupParser
74#define fn_xmlCheckVersion xmlCheckVersion
75
76static inline int
77libxml2_loaded_p (void)
78{
79 return 1;
80}
81
82#endif /* !WINDOWSNT */
83
84static int
85init_libxml2_functions (Lisp_Object libraries)
86{
87#ifdef WINDOWSNT
88 if (libxml2_loaded_p ())
89 return 1;
90 else
91 {
92 HMODULE library;
93
94 if (!(library = w32_delayed_load (libraries, Qlibxml2_dll)))
95 {
96 message ("%s", "libxml2 library not found");
97 return 0;
98 }
99
100 /* LOAD_XML2_FN jumps to bad_library if it fails to find the
101 named function. */
102 LOAD_XML2_FN (library, htmlReadMemory);
103 LOAD_XML2_FN (library, xmlReadMemory);
104 LOAD_XML2_FN (library, xmlDocGetRootElement);
105 LOAD_XML2_FN (library, xmlFreeDoc);
106 LOAD_XML2_FN (library, xmlCleanupParser);
107 LOAD_XML2_FN (library, xmlCheckVersion);
108
109 Vlibrary_cache = Fcons (Fcons (Qlibxml2_dll, Qt), Vlibrary_cache);
110 return 1;
111 }
112
113 bad_library:
114 Vlibrary_cache = Fcons (Fcons (Qlibxml2_dll, Qnil), Vlibrary_cache);
115
116 return 0;
117#else /* !WINDOWSNT */
118 return 1;
119#endif /* !WINDOWSNT */
120}
121
31static Lisp_Object 122static Lisp_Object
32make_dom (xmlNode *node) 123make_dom (xmlNode *node)
33{ 124{
@@ -92,7 +183,7 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html
92 ptrdiff_t bytes; 183 ptrdiff_t bytes;
93 ptrdiff_t istart, iend; 184 ptrdiff_t istart, iend;
94 185
95 LIBXML_TEST_VERSION; 186 fn_xmlCheckVersion (LIBXML_VERSION);
96 187
97 validate_region (&start, &end); 188 validate_region (&start, &end);
98 189
@@ -111,16 +202,16 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html
111 bytes = CHAR_TO_BYTE (iend) - CHAR_TO_BYTE (istart); 202 bytes = CHAR_TO_BYTE (iend) - CHAR_TO_BYTE (istart);
112 203
113 if (htmlp) 204 if (htmlp)
114 doc = htmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), 205 doc = fn_htmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)),
115 bytes, burl, "utf-8", 206 bytes, burl, "utf-8",
116 HTML_PARSE_RECOVER|HTML_PARSE_NONET| 207 HTML_PARSE_RECOVER|HTML_PARSE_NONET|
117 HTML_PARSE_NOWARNING|HTML_PARSE_NOERROR| 208 HTML_PARSE_NOWARNING|HTML_PARSE_NOERROR|
118 HTML_PARSE_NOBLANKS); 209 HTML_PARSE_NOBLANKS);
119 else 210 else
120 doc = xmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), 211 doc = fn_xmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)),
121 bytes, burl, "utf-8", 212 bytes, burl, "utf-8",
122 XML_PARSE_NONET|XML_PARSE_NOWARNING| 213 XML_PARSE_NONET|XML_PARSE_NOWARNING|
123 XML_PARSE_NOBLANKS |XML_PARSE_NOERROR); 214 XML_PARSE_NOBLANKS |XML_PARSE_NOERROR);
124 215
125 if (doc != NULL) 216 if (doc != NULL)
126 { 217 {
@@ -139,19 +230,26 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html
139 if (NILP (result)) { 230 if (NILP (result)) {
140 /* The document isn't just comments, so get the tree the 231 /* The document isn't just comments, so get the tree the
141 proper way. */ 232 proper way. */
142 xmlNode *node = xmlDocGetRootElement (doc); 233 xmlNode *node = fn_xmlDocGetRootElement (doc);
143 if (node != NULL) 234 if (node != NULL)
144 result = make_dom (node); 235 result = make_dom (node);
145 } else 236 } else
146 result = Fcons (intern ("top"), 237 result = Fcons (intern ("top"),
147 Fcons (Qnil, Fnreverse (Fcons (r, result)))); 238 Fcons (Qnil, Fnreverse (Fcons (r, result))));
148 239
149 xmlFreeDoc (doc); 240 fn_xmlFreeDoc (doc);
150 } 241 }
151 242
152 return result; 243 return result;
153} 244}
154 245
246void
247xml_cleanup_parser (void)
248{
249 if (libxml2_loaded_p ())
250 fn_xmlCleanupParser ();
251}
252
155DEFUN ("libxml-parse-html-region", Flibxml_parse_html_region, 253DEFUN ("libxml-parse-html-region", Flibxml_parse_html_region,
156 Slibxml_parse_html_region, 254 Slibxml_parse_html_region,
157 2, 3, 0, 255 2, 3, 0,
@@ -159,7 +257,9 @@ DEFUN ("libxml-parse-html-region", Flibxml_parse_html_region,
159If BASE-URL is non-nil, it is used to expand relative URLs. */) 257If BASE-URL is non-nil, it is used to expand relative URLs. */)
160 (Lisp_Object start, Lisp_Object end, Lisp_Object base_url) 258 (Lisp_Object start, Lisp_Object end, Lisp_Object base_url)
161{ 259{
162 return parse_region (start, end, base_url, 1); 260 if (init_libxml2_functions (Vdynamic_library_alist))
261 return parse_region (start, end, base_url, 1);
262 return Qnil;
163} 263}
164 264
165DEFUN ("libxml-parse-xml-region", Flibxml_parse_xml_region, 265DEFUN ("libxml-parse-xml-region", Flibxml_parse_xml_region,
@@ -169,7 +269,9 @@ DEFUN ("libxml-parse-xml-region", Flibxml_parse_xml_region,
169If BASE-URL is non-nil, it is used to expand relative URLs. */) 269If BASE-URL is non-nil, it is used to expand relative URLs. */)
170 (Lisp_Object start, Lisp_Object end, Lisp_Object base_url) 270 (Lisp_Object start, Lisp_Object end, Lisp_Object base_url)
171{ 271{
172 return parse_region (start, end, base_url, 0); 272 if (init_libxml2_functions (Vdynamic_library_alist))
273 return parse_region (start, end, base_url, 0);
274 return Qnil;
173} 275}
174 276
175 277
@@ -181,6 +283,8 @@ syms_of_xml (void)
181{ 283{
182 defsubr (&Slibxml_parse_html_region); 284 defsubr (&Slibxml_parse_html_region);
183 defsubr (&Slibxml_parse_xml_region); 285 defsubr (&Slibxml_parse_xml_region);
286
287 DEFSYM (Qlibxml2_dll, "libxml2");
184} 288}
185 289
186#endif /* HAVE_LIBXML2 */ 290#endif /* HAVE_LIBXML2 */