diff options
| author | Eli Zaretskii | 2012-04-07 16:57:36 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2012-04-07 16:57:36 +0300 |
| commit | 9078ead6ce0237eb566a2779016560c85fff5768 (patch) | |
| tree | 965a35cb3e4e5f7b83edfd65712ce40105dc1fd5 /src | |
| parent | e4ecc6a217dfe759fdb7859b38079e66368944d2 (diff) | |
| download | emacs-9078ead6ce0237eb566a2779016560c85fff5768.tar.gz emacs-9078ead6ce0237eb566a2779016560c85fff5768.zip | |
Support building on MS-Windows with libxml2.
src/makefile.w32-in (OBJ2): Add xml.$(O).
(GLOBAL_SOURCES): Add xml.c.
($(BLD)/xml.$(O)): New dependency list.
src/xml.c (DEF_XML2_FN, LOAD_XML2_FN) [WINDOWSNT]: New macros.
(fn_htmlReadMemory, fn_xmlReadMemory, fn_xmlDocGetRootElement)
(fn_xmlFreeDoc, fn_xmlCleanupParser, fn_xmlCheckVersion)
[!WINDOWSNT]: New macros.
(init_libxml2_functions, libxml2_loaded_p): New functions.
(parse_region): Call fn_xmlCheckVersion instead of using the macro
LIBXML_TEST_VERSION. Call libxml2 functions via the fn_* macros.
(xml_cleanup_parser): New function, export for fn_xmlCleanupParser.
Calls xmlCleanupParser only if libxml2 was loaded (or statically
linked in).
(Flibxml_parse_html_region, Flibxml_parse_xml_region): Call
init_libxml2_functions before calling libxml2 functions.
(syms_of_xml) <Qlibxml2_dll>: DEFSYM it.
src/emacs.c: Don't include libxml/parser.h.
(shut_down_emacs): Call xml_cleanup_parser, instead of calling
xmlCleanupParser directly.
src/ lisp.h [HAVE_LIBXML2]: Add prototype for xml_cleanup_parser.
nt/configure.bat: Support building with libxml2.
nt/INSTALL:
nt/README.W32: Add information about libxml2.
lisp/term/w32-win.el (dynamic-library-alist): Add libxml2 DLLs.
lib-src/makefile.w32-in (obj): Add xml.o.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 28 | ||||
| -rw-r--r-- | src/emacs.c | 6 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/makefile.w32-in | 10 | ||||
| -rw-r--r-- | src/xml.c | 134 |
5 files changed, 159 insertions, 20 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 6bd946c0900..d60379b76b4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,33 @@ | |||
| 1 | 2012-04-07 Eli Zaretskii <eliz@gnu.org> | 1 | 2012-04-07 Eli Zaretskii <eliz@gnu.org> |
| 2 | 2 | ||
| 3 | Support building on MS-Windows with libxml2. | ||
| 4 | |||
| 5 | * makefile.w32-in (OBJ2): Add xml.$(O). | ||
| 6 | (GLOBAL_SOURCES): Add xml.c. | ||
| 7 | ($(BLD)/xml.$(O)): New dependency list. | ||
| 8 | |||
| 9 | * xml.c (DEF_XML2_FN, LOAD_XML2_FN) [WINDOWSNT]: New macros. | ||
| 10 | (fn_htmlReadMemory, fn_xmlReadMemory, fn_xmlDocGetRootElement) | ||
| 11 | (fn_xmlFreeDoc, fn_xmlCleanupParser, fn_xmlCheckVersion) | ||
| 12 | [!WINDOWSNT]: New macros. | ||
| 13 | (init_libxml2_functions, libxml2_loaded_p): New functions. | ||
| 14 | (parse_region): Call fn_xmlCheckVersion instead of using the macro | ||
| 15 | LIBXML_TEST_VERSION. Call libxml2 functions via the fn_* macros. | ||
| 16 | (xml_cleanup_parser): New function, export for fn_xmlCleanupParser. | ||
| 17 | Calls xmlCleanupParser only if libxml2 was loaded (or statically | ||
| 18 | linked in). | ||
| 19 | (Flibxml_parse_html_region, Flibxml_parse_xml_region): Call | ||
| 20 | init_libxml2_functions before calling libxml2 functions. | ||
| 21 | (syms_of_xml) <Qlibxml2_dll>: DEFSYM it. | ||
| 22 | |||
| 23 | * emacs.c: Don't include libxml/parser.h. | ||
| 24 | (shut_down_emacs): Call xml_cleanup_parser, instead of calling | ||
| 25 | xmlCleanupParser directly. | ||
| 26 | |||
| 27 | * lisp.h [HAVE_LIBXML2]: Add prototype for xml_cleanup_parser. | ||
| 28 | |||
| 29 | 2012-04-07 Eli Zaretskii <eliz@gnu.org> | ||
| 30 | |||
| 3 | * indent.c (Fvertical_motion): If there is a display string at | 31 | * indent.c (Fvertical_motion): If there is a display string at |
| 4 | point, use it.vpos to compute how many lines to backtrack after | 32 | point, use it.vpos to compute how many lines to backtrack after |
| 5 | move_it_to point. (Bug#11133) | 33 | move_it_to point. (Bug#11133) |
diff --git a/src/emacs.c b/src/emacs.c index 0e77223ee00..c36c7df7e45 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -82,10 +82,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 82 | #include <sys/personality.h> | 82 | #include <sys/personality.h> |
| 83 | #endif | 83 | #endif |
| 84 | 84 | ||
| 85 | #ifdef HAVE_LIBXML2 | ||
| 86 | #include <libxml/parser.h> | ||
| 87 | #endif | ||
| 88 | |||
| 89 | #ifndef O_RDWR | 85 | #ifndef O_RDWR |
| 90 | #define O_RDWR 2 | 86 | #define O_RDWR 2 |
| 91 | #endif | 87 | #endif |
| @@ -2124,7 +2120,7 @@ shut_down_emacs (int sig, int no_x, Lisp_Object stuff) | |||
| 2124 | #endif | 2120 | #endif |
| 2125 | 2121 | ||
| 2126 | #ifdef HAVE_LIBXML2 | 2122 | #ifdef HAVE_LIBXML2 |
| 2127 | xmlCleanupParser (); | 2123 | xml_cleanup_parser (); |
| 2128 | #endif | 2124 | #endif |
| 2129 | } | 2125 | } |
| 2130 | 2126 | ||
diff --git a/src/lisp.h b/src/lisp.h index bd19da55b2a..62695f15644 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3549,6 +3549,7 @@ EXFUN (Fmsdos_downcase_filename, 1); | |||
| 3549 | #ifdef HAVE_LIBXML2 | 3549 | #ifdef HAVE_LIBXML2 |
| 3550 | /* Defined in xml.c */ | 3550 | /* Defined in xml.c */ |
| 3551 | extern void syms_of_xml (void); | 3551 | extern void syms_of_xml (void); |
| 3552 | extern void xml_cleanup_parser (void); | ||
| 3552 | #endif | 3553 | #endif |
| 3553 | 3554 | ||
| 3554 | #ifdef HAVE_MENUS | 3555 | #ifdef HAVE_MENUS |
diff --git a/src/makefile.w32-in b/src/makefile.w32-in index d7ca325e223..da831d07a36 100644 --- a/src/makefile.w32-in +++ b/src/makefile.w32-in | |||
| @@ -128,6 +128,7 @@ OBJ2 = $(BLD)/sysdep.$(O) \ | |||
| 128 | $(BLD)/image.$(O) \ | 128 | $(BLD)/image.$(O) \ |
| 129 | $(BLD)/terminal.$(O) \ | 129 | $(BLD)/terminal.$(O) \ |
| 130 | $(BLD)/menu.$(O) \ | 130 | $(BLD)/menu.$(O) \ |
| 131 | $(BLD)/xml.$(O) \ | ||
| 131 | $(BLD)/w32term.$(O) \ | 132 | $(BLD)/w32term.$(O) \ |
| 132 | $(BLD)/w32xfns.$(O) \ | 133 | $(BLD)/w32xfns.$(O) \ |
| 133 | $(BLD)/w32fns.$(O) \ | 134 | $(BLD)/w32fns.$(O) \ |
| @@ -225,7 +226,7 @@ GLOBAL_SOURCES = dosfns.c msdos.c \ | |||
| 225 | process.c callproc.c unexw32.c \ | 226 | process.c callproc.c unexw32.c \ |
| 226 | region-cache.c sound.c atimer.c \ | 227 | region-cache.c sound.c atimer.c \ |
| 227 | doprnt.c intervals.c textprop.c composite.c \ | 228 | doprnt.c intervals.c textprop.c composite.c \ |
| 228 | gnutls.c | 229 | gnutls.c xml.c |
| 229 | SOME_MACHINE_OBJECTS = dosfns.o msdos.o \ | 230 | SOME_MACHINE_OBJECTS = dosfns.o msdos.o \ |
| 230 | xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o dbusbind.o | 231 | xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o dbusbind.o |
| 231 | obj = $(GLOBAL_SOURCES:.c=.o) | 232 | obj = $(GLOBAL_SOURCES:.c=.o) |
| @@ -940,6 +941,13 @@ $(BLD)/gnutls.$(O) : \ | |||
| 940 | $(LISP_H) \ | 941 | $(LISP_H) \ |
| 941 | $(PROCESS_H) | 942 | $(PROCESS_H) |
| 942 | 943 | ||
| 944 | $(BLD)/xml.$(O) : \ | ||
| 945 | $(SRC)/xml.c \ | ||
| 946 | $(SRC)/w32.h \ | ||
| 947 | $(CONFIG_H) \ | ||
| 948 | $(LISP_H) \ | ||
| 949 | $(SRC)/buffer.h | ||
| 950 | |||
| 943 | $(BLD)/image.$(O) : \ | 951 | $(BLD)/image.$(O) : \ |
| 944 | $(SRC)/image.c \ | 952 | $(SRC)/image.c \ |
| 945 | $(SRC)/epaths.h \ | 953 | $(SRC)/epaths.h \ |
| @@ -28,6 +28,99 @@ 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 | |||
| 32 | static 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 | |||
| 48 | DEF_XML2_FN (htmlDocPtr, htmlReadMemory, | ||
| 49 | (const char *, int, const char *, const char *, int)); | ||
| 50 | DEF_XML2_FN (xmlDocPtr, xmlReadMemory, | ||
| 51 | (const char *, int, const char *, const char *, int)); | ||
| 52 | DEF_XML2_FN (xmlNodePtr, xmlDocGetRootElement, (xmlDocPtr)); | ||
| 53 | DEF_XML2_FN (void, xmlFreeDoc, (xmlDocPtr)); | ||
| 54 | DEF_XML2_FN (void, xmlCleanupParser, (void)); | ||
| 55 | DEF_XML2_FN (void, xmlCheckVersion, (int)); | ||
| 56 | |||
| 57 | static int | ||
| 58 | libxml2_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 | |||
| 76 | static inine int | ||
| 77 | libxml2_loaded_p (void) | ||
| 78 | { | ||
| 79 | return 1; | ||
| 80 | } | ||
| 81 | |||
| 82 | #endif /* !WINDOWSNT */ | ||
| 83 | |||
| 84 | static int | ||
| 85 | init_libxml2_functions (Lisp_Object libraries) | ||
| 86 | { | ||
| 87 | #ifdef WINDOWSNT | ||
| 88 | Lisp_Object found = Fassq (Qlibxml2_dll, Vlibrary_cache); | ||
| 89 | |||
| 90 | if (libxml2_loaded_p ()) | ||
| 91 | return 1; | ||
| 92 | else | ||
| 93 | { | ||
| 94 | HMODULE library; | ||
| 95 | |||
| 96 | if (!(library = w32_delayed_load (libraries, Qlibxml2_dll))) | ||
| 97 | { | ||
| 98 | message ("%s", "libxml2 library not found"); | ||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 102 | /* LOAD_XML2_FN jumps to bad_library if it fails to find the | ||
| 103 | named function. */ | ||
| 104 | LOAD_XML2_FN (library, htmlReadMemory); | ||
| 105 | LOAD_XML2_FN (library, xmlReadMemory); | ||
| 106 | LOAD_XML2_FN (library, xmlDocGetRootElement); | ||
| 107 | LOAD_XML2_FN (library, xmlFreeDoc); | ||
| 108 | LOAD_XML2_FN (library, xmlCleanupParser); | ||
| 109 | LOAD_XML2_FN (library, xmlCheckVersion); | ||
| 110 | |||
| 111 | Vlibrary_cache = Fcons (Fcons (Qlibxml2_dll, Qt), Vlibrary_cache); | ||
| 112 | return 1; | ||
| 113 | } | ||
| 114 | |||
| 115 | bad_library: | ||
| 116 | Vlibrary_cache = Fcons (Fcons (Qlibxml2_dll, Qnil), Vlibrary_cache); | ||
| 117 | |||
| 118 | return 0; | ||
| 119 | #else /* !WINDOWSNT */ | ||
| 120 | return 1; | ||
| 121 | #endif /* !WINDOWSNT */ | ||
| 122 | } | ||
| 123 | |||
| 31 | static Lisp_Object | 124 | static Lisp_Object |
| 32 | make_dom (xmlNode *node) | 125 | make_dom (xmlNode *node) |
| 33 | { | 126 | { |
| @@ -92,7 +185,7 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html | |||
| 92 | EMACS_INT bytes; | 185 | EMACS_INT bytes; |
| 93 | EMACS_INT istart, iend; | 186 | EMACS_INT istart, iend; |
| 94 | 187 | ||
| 95 | LIBXML_TEST_VERSION; | 188 | fn_xmlCheckVersion (LIBXML_VERSION); |
| 96 | 189 | ||
| 97 | validate_region (&start, &end); | 190 | validate_region (&start, &end); |
| 98 | 191 | ||
| @@ -111,16 +204,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); | 204 | bytes = CHAR_TO_BYTE (iend) - CHAR_TO_BYTE (istart); |
| 112 | 205 | ||
| 113 | if (htmlp) | 206 | if (htmlp) |
| 114 | doc = htmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), | 207 | doc = fn_htmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), |
| 115 | bytes, burl, "utf-8", | 208 | bytes, burl, "utf-8", |
| 116 | HTML_PARSE_RECOVER|HTML_PARSE_NONET| | 209 | HTML_PARSE_RECOVER|HTML_PARSE_NONET| |
| 117 | HTML_PARSE_NOWARNING|HTML_PARSE_NOERROR| | 210 | HTML_PARSE_NOWARNING|HTML_PARSE_NOERROR| |
| 118 | HTML_PARSE_NOBLANKS); | 211 | HTML_PARSE_NOBLANKS); |
| 119 | else | 212 | else |
| 120 | doc = xmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), | 213 | doc = fn_xmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), |
| 121 | bytes, burl, "utf-8", | 214 | bytes, burl, "utf-8", |
| 122 | XML_PARSE_NONET|XML_PARSE_NOWARNING| | 215 | XML_PARSE_NONET|XML_PARSE_NOWARNING| |
| 123 | XML_PARSE_NOBLANKS |XML_PARSE_NOERROR); | 216 | XML_PARSE_NOBLANKS |XML_PARSE_NOERROR); |
| 124 | 217 | ||
| 125 | if (doc != NULL) | 218 | if (doc != NULL) |
| 126 | { | 219 | { |
| @@ -139,19 +232,26 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html | |||
| 139 | if (NILP (result)) { | 232 | if (NILP (result)) { |
| 140 | /* The document isn't just comments, so get the tree the | 233 | /* The document isn't just comments, so get the tree the |
| 141 | proper way. */ | 234 | proper way. */ |
| 142 | xmlNode *node = xmlDocGetRootElement (doc); | 235 | xmlNode *node = fn_xmlDocGetRootElement (doc); |
| 143 | if (node != NULL) | 236 | if (node != NULL) |
| 144 | result = make_dom (node); | 237 | result = make_dom (node); |
| 145 | } else | 238 | } else |
| 146 | result = Fcons (intern ("top"), | 239 | result = Fcons (intern ("top"), |
| 147 | Fcons (Qnil, Fnreverse (Fcons (r, result)))); | 240 | Fcons (Qnil, Fnreverse (Fcons (r, result)))); |
| 148 | 241 | ||
| 149 | xmlFreeDoc (doc); | 242 | fn_xmlFreeDoc (doc); |
| 150 | } | 243 | } |
| 151 | 244 | ||
| 152 | return result; | 245 | return result; |
| 153 | } | 246 | } |
| 154 | 247 | ||
| 248 | void | ||
| 249 | xml_cleanup_parser (void) | ||
| 250 | { | ||
| 251 | if (libxml2_loaded_p ()) | ||
| 252 | fn_xmlCleanupParser (); | ||
| 253 | } | ||
| 254 | |||
| 155 | DEFUN ("libxml-parse-html-region", Flibxml_parse_html_region, | 255 | DEFUN ("libxml-parse-html-region", Flibxml_parse_html_region, |
| 156 | Slibxml_parse_html_region, | 256 | Slibxml_parse_html_region, |
| 157 | 2, 3, 0, | 257 | 2, 3, 0, |
| @@ -159,7 +259,9 @@ DEFUN ("libxml-parse-html-region", Flibxml_parse_html_region, | |||
| 159 | If BASE-URL is non-nil, it is used to expand relative URLs. */) | 259 | If BASE-URL is non-nil, it is used to expand relative URLs. */) |
| 160 | (Lisp_Object start, Lisp_Object end, Lisp_Object base_url) | 260 | (Lisp_Object start, Lisp_Object end, Lisp_Object base_url) |
| 161 | { | 261 | { |
| 162 | return parse_region (start, end, base_url, 1); | 262 | if (init_libxml2_functions (Vdynamic_library_alist)) |
| 263 | return parse_region (start, end, base_url, 1); | ||
| 264 | return Qnil; | ||
| 163 | } | 265 | } |
| 164 | 266 | ||
| 165 | DEFUN ("libxml-parse-xml-region", Flibxml_parse_xml_region, | 267 | DEFUN ("libxml-parse-xml-region", Flibxml_parse_xml_region, |
| @@ -169,7 +271,9 @@ DEFUN ("libxml-parse-xml-region", Flibxml_parse_xml_region, | |||
| 169 | If BASE-URL is non-nil, it is used to expand relative URLs. */) | 271 | If BASE-URL is non-nil, it is used to expand relative URLs. */) |
| 170 | (Lisp_Object start, Lisp_Object end, Lisp_Object base_url) | 272 | (Lisp_Object start, Lisp_Object end, Lisp_Object base_url) |
| 171 | { | 273 | { |
| 172 | return parse_region (start, end, base_url, 0); | 274 | if (init_libxml2_functions (Vdynamic_library_alist)) |
| 275 | return parse_region (start, end, base_url, 0); | ||
| 276 | return Qnil; | ||
| 173 | } | 277 | } |
| 174 | 278 | ||
| 175 | 279 | ||
| @@ -181,6 +285,8 @@ syms_of_xml (void) | |||
| 181 | { | 285 | { |
| 182 | defsubr (&Slibxml_parse_html_region); | 286 | defsubr (&Slibxml_parse_html_region); |
| 183 | defsubr (&Slibxml_parse_xml_region); | 287 | defsubr (&Slibxml_parse_xml_region); |
| 288 | |||
| 289 | DEFSYM (Qlibxml2_dll, "libxml2"); | ||
| 184 | } | 290 | } |
| 185 | 291 | ||
| 186 | #endif /* HAVE_LIBXML2 */ | 292 | #endif /* HAVE_LIBXML2 */ |