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.
This commit is contained in:
Eli Zaretskii 2012-04-07 16:57:36 +03:00
parent e4ecc6a217
commit 9078ead6ce
14 changed files with 263 additions and 22 deletions

View file

@ -14,6 +14,14 @@ and NEWS.1-17 for changes in older Emacs versions.
You can narrow news to a specific version by calling `view-emacs-news'
with a prefix argument or by typing C-u C-h C-n.
* Changes in Emacs 24.2 on non-free operating systems
** New configure.bat options on MS-Windows:
*** --without-libxml2 omits support for libxml2, even if its presence
is detected.
* Installation Changes in Emacs 24.1

View file

@ -1,3 +1,7 @@
2012-04-07 Eli Zaretskii <eliz@gnu.org>
* makefile.w32-in (obj): Add xml.o.
2012-04-07 Eli Zaretskii <eliz@gnu.org>
* makefile.w32-in (ALL): Now the list of executables, not of phony

View file

@ -135,7 +135,7 @@ obj = dosfns.o msdos.o \
process.o callproc.o unexw32.o \
region-cache.o sound.o atimer.o \
doprnt.o intervals.o textprop.o composite.o \
gnutls.o
gnutls.o xml.o
#
# These are the lisp files that are loaded up in loadup.el

View file

@ -1,3 +1,7 @@
2012-04-07 Eli Zaretskii <eliz@gnu.org>
* term/w32-win.el (dynamic-library-alist): Add libxml2 DLLs.
2012-04-05 Lars Magne Ingebrigtsen <larsi@gnus.org>
* window.el (shrink-window): Mention the `window-min-height'

View file

@ -210,7 +210,8 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
'(gdk-pixbuf "libgdk_pixbuf-2.0-0.dll")
'(glib "libglib-2.0-0.dll")
'(gobject "libgobject-2.0-0.dll")
'(gnutls "libgnutls-28.dll" "libgnutls-26.dll")))
'(gnutls "libgnutls-28.dll" "libgnutls-26.dll")
'(libxml2 "libxml2-2.dll" "libxml2.dll")))
;;; multi-tty support
(defvar w32-initialized nil

View file

@ -1,3 +1,10 @@
2012-04-07 Eli Zaretskii <eliz@gnu.org>
* configure.bat: Support building with libxml2.
* INSTALL:
* README.W32: Add information about libxml2.
2012-04-07 Eli Zaretskii <eliz@gnu.org>
* makefile.w32-in: Convert to Unix EOL format.

View file

@ -367,6 +367,40 @@
You can get pre-built binaries (including any required DLL and the
header files) at http://sourceforge.net/projects/ezwinports/files/.
* Optional libxml2 support
If configure.bat finds the libxml/HTMLparser.h file in the include path,
Emacs is built with libxml2 support by default; to avoid that you can
pass the argument --without-libxml2.
In order to support libxml2 at runtime, a libxml2-enabled Emacs must
be able to find the relevant DLLs during startup; failure to do so
is not an error, but libxml2 features won't be available to the
running session.
One place where you can get pre-built Windows binaries of libxml2
(including any required DLL and the header files) is here:
http://sourceforge.net/projects/ezwinports/files/
To compile Emacs with libxml2 from that site, you will need to pass
the "--cflags -I/path/to/include/libxml2" option to configure.bat,
because libxml2 header files are installed in the include/libxml2
subdirectory of the directory where you unzip the binary
distribution. Other binary distributions might use other
directories, although include/libxml2 is the canonical place where
libxml2 headers are installed on Posix platforms.
You will also need to install the libiconv "development" tarball,
because the libiconv headers need to be available to the compiler
when you compile with libxml2 support. A MinGW port of libiconv can
be found on the MinGW site:
http://sourceforge.net/projects/mingw/files/MinGW/Base/libiconv/
You need the libiconv-X.Y.Z-N-mingw32-dev.tar.lzma tarball from that
site.
* Experimental SVG support
SVG support is currently experimental, and not built by default.

View file

@ -172,6 +172,16 @@ See the end of the file for license conditions.
You can get pre-built binaries (including any required DLL and the
header files) at http://sourceforge.net/projects/ezwinports/files/.
* libxml2 support
In order to support libxml2 at runtime, a libxml2-enabled Emacs must
be able to find the relevant DLLs during startup; failure to do so
is not an error, but libxml2 features won't be available to the
running session.
You can get pre-built binaries (including any required DLL and the
header files) at http://sourceforge.net/projects/ezwinports/files/.
* Uninstalling Emacs
If you should need to uninstall Emacs, simply delete all the files

View file

@ -131,6 +131,7 @@ if "%1" == "--without-jpeg" goto withoutjpeg
if "%1" == "--without-gif" goto withoutgif
if "%1" == "--without-tiff" goto withouttiff
if "%1" == "--without-gnutls" goto withoutgnutls
if "%1" == "--without-libxml2" goto withoutlibxml2
if "%1" == "--without-xpm" goto withoutxpm
if "%1" == "--with-svg" goto withsvg
if "%1" == "--distfiles" goto distfiles
@ -156,6 +157,7 @@ echo. --without-gif do not use GIF library even if it is installed
echo. --without-tiff do not use TIFF library even if it is installed
echo. --without-xpm do not use XPM library even if it is installed
echo. --without-gnutls do not use GnuTLS library even if it is installed
echo. --without-libxml2 do not use libxml2 library even if it is installed
echo. --with-svg use the RSVG library (experimental)
echo. --distfiles path to files for make dist, e.g. libXpm.dll
if "%use_extensions%" == "0" goto end
@ -317,6 +319,14 @@ goto again
rem ----------------------------------------------------------------------
:withoutlibxml2
set libxml2support=N
set HAVE_LIBXML2=
shift
goto again
rem ----------------------------------------------------------------------
:withouttiff
set tiffsupport=N
set HAVE_TIFF=
@ -569,6 +579,28 @@ set HAVE_GNUTLS=1
:tlsDone
rm -f junk.c junk.obj
if (%libxml2support%) == (N) goto xml2Done
echo Checking for libxml2....
echo #include "libxml/HTMLparser.h" >junk.c
echo main(){} >>junk.c
echo %COMPILER% %usercflags% %mingwflag% -c junk.c -o junk.obj >>config.log
%COMPILER% %usercflags% %mingwflag% -c junk.c -o junk.obj >junk.out 2>>config.log
if exist junk.obj goto havelibxml2
echo ...libxml/HTMLparser.h not found, building without libxml2 support
echo The failed program was: >>config.log
type junk.c >>config.log
set HAVE_LIBXML2=
goto xml2Done
:havelibxml2
echo ...libxml2 header available, building with libxml2 support
set HAVE_LIBXML2=1
:xml2Done
rm -f junk.c junk.obj
if (%jpegsupport%) == (N) goto jpegDone
echo Checking for jpeg-6b...
@ -757,6 +789,7 @@ if (%doldflags%) == (Y) echo #define USER_LDFLAGS " %escuserldflags%">>config.tm
if (%profile%) == (Y) echo #define PROFILING 1 >>config.tmp
if not "(%HAVE_PNG%)" == "()" echo #define HAVE_PNG 1 >>config.tmp
if not "(%HAVE_GNUTLS%)" == "()" echo #define HAVE_GNUTLS 1 >>config.tmp
if not "(%HAVE_LIBXML2%)" == "()" echo #define HAVE_LIBXML2 1 >>config.tmp
if not "(%HAVE_JPEG%)" == "()" echo #define HAVE_JPEG 1 >>config.tmp
if not "(%HAVE_GIF%)" == "()" echo #define HAVE_GIF 1 >>config.tmp
if not "(%HAVE_TIFF%)" == "()" echo #define HAVE_TIFF 1 >>config.tmp
@ -896,6 +929,7 @@ set HAVE_DISTFILES=
set distFilesOk=
set pngsupport=
set tlssupport=
set libxml2support=
set jpegsupport=
set gifsupport=
set tiffsupport=

View file

@ -1,3 +1,31 @@
2012-04-07 Eli Zaretskii <eliz@gnu.org>
Support building on MS-Windows with libxml2.
* makefile.w32-in (OBJ2): Add xml.$(O).
(GLOBAL_SOURCES): Add xml.c.
($(BLD)/xml.$(O)): New dependency list.
* 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.
* emacs.c: Don't include libxml/parser.h.
(shut_down_emacs): Call xml_cleanup_parser, instead of calling
xmlCleanupParser directly.
* lisp.h [HAVE_LIBXML2]: Add prototype for xml_cleanup_parser.
2012-04-07 Eli Zaretskii <eliz@gnu.org>
* indent.c (Fvertical_motion): If there is a display string at

View file

@ -82,10 +82,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <sys/personality.h>
#endif
#ifdef HAVE_LIBXML2
#include <libxml/parser.h>
#endif
#ifndef O_RDWR
#define O_RDWR 2
#endif
@ -2124,7 +2120,7 @@ shut_down_emacs (int sig, int no_x, Lisp_Object stuff)
#endif
#ifdef HAVE_LIBXML2
xmlCleanupParser ();
xml_cleanup_parser ();
#endif
}

View file

@ -3549,6 +3549,7 @@ EXFUN (Fmsdos_downcase_filename, 1);
#ifdef HAVE_LIBXML2
/* Defined in xml.c */
extern void syms_of_xml (void);
extern void xml_cleanup_parser (void);
#endif
#ifdef HAVE_MENUS

View file

@ -128,6 +128,7 @@ OBJ2 = $(BLD)/sysdep.$(O) \
$(BLD)/image.$(O) \
$(BLD)/terminal.$(O) \
$(BLD)/menu.$(O) \
$(BLD)/xml.$(O) \
$(BLD)/w32term.$(O) \
$(BLD)/w32xfns.$(O) \
$(BLD)/w32fns.$(O) \
@ -225,7 +226,7 @@ GLOBAL_SOURCES = dosfns.c msdos.c \
process.c callproc.c unexw32.c \
region-cache.c sound.c atimer.c \
doprnt.c intervals.c textprop.c composite.c \
gnutls.c
gnutls.c xml.c
SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o dbusbind.o
obj = $(GLOBAL_SOURCES:.c=.o)
@ -940,6 +941,13 @@ $(BLD)/gnutls.$(O) : \
$(LISP_H) \
$(PROCESS_H)
$(BLD)/xml.$(O) : \
$(SRC)/xml.c \
$(SRC)/w32.h \
$(CONFIG_H) \
$(LISP_H) \
$(SRC)/buffer.h
$(BLD)/image.$(O) : \
$(SRC)/image.c \
$(SRC)/epaths.h \

134
src/xml.c
View file

@ -28,6 +28,99 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "lisp.h"
#include "buffer.h"
static Lisp_Object Qlibxml2_dll;
#ifdef WINDOWSNT
#include <windows.h>
#include "w32.h"
/* Macro for defining functions that will be loaded from the libxml2 DLL. */
#define DEF_XML2_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
/* Macro for loading libxml2 functions from the library. */
#define LOAD_XML2_FN(lib,func) { \
fn_##func = (void *) GetProcAddress (lib, #func); \
if (!fn_##func) goto bad_library; \
}
DEF_XML2_FN (htmlDocPtr, htmlReadMemory,
(const char *, int, const char *, const char *, int));
DEF_XML2_FN (xmlDocPtr, xmlReadMemory,
(const char *, int, const char *, const char *, int));
DEF_XML2_FN (xmlNodePtr, xmlDocGetRootElement, (xmlDocPtr));
DEF_XML2_FN (void, xmlFreeDoc, (xmlDocPtr));
DEF_XML2_FN (void, xmlCleanupParser, (void));
DEF_XML2_FN (void, xmlCheckVersion, (int));
static int
libxml2_loaded_p (void)
{
Lisp_Object found = Fassq (Qlibxml2_dll, Vlibrary_cache);
if (CONSP (found))
return EQ (XCDR (found), Qt) ? 1 : 0;
return 0;
}
#else /* !WINDOWSNT */
#define fn_htmlReadMemory htmlReadMemory
#define fn_xmlReadMemory xmlReadMemory
#define fn_xmlDocGetRootElement xmlDocGetRootElement
#define fn_xmlFreeDoc xmlFreeDoc
#define fn_xmlCleanupParser xmlCleanupParser
#define fn_xmlCheckVersion xmlCheckVersion
static inine int
libxml2_loaded_p (void)
{
return 1;
}
#endif /* !WINDOWSNT */
static int
init_libxml2_functions (Lisp_Object libraries)
{
#ifdef WINDOWSNT
Lisp_Object found = Fassq (Qlibxml2_dll, Vlibrary_cache);
if (libxml2_loaded_p ())
return 1;
else
{
HMODULE library;
if (!(library = w32_delayed_load (libraries, Qlibxml2_dll)))
{
message ("%s", "libxml2 library not found");
return 0;
}
/* LOAD_XML2_FN jumps to bad_library if it fails to find the
named function. */
LOAD_XML2_FN (library, htmlReadMemory);
LOAD_XML2_FN (library, xmlReadMemory);
LOAD_XML2_FN (library, xmlDocGetRootElement);
LOAD_XML2_FN (library, xmlFreeDoc);
LOAD_XML2_FN (library, xmlCleanupParser);
LOAD_XML2_FN (library, xmlCheckVersion);
Vlibrary_cache = Fcons (Fcons (Qlibxml2_dll, Qt), Vlibrary_cache);
return 1;
}
bad_library:
Vlibrary_cache = Fcons (Fcons (Qlibxml2_dll, Qnil), Vlibrary_cache);
return 0;
#else /* !WINDOWSNT */
return 1;
#endif /* !WINDOWSNT */
}
static Lisp_Object
make_dom (xmlNode *node)
{
@ -92,7 +185,7 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html
EMACS_INT bytes;
EMACS_INT istart, iend;
LIBXML_TEST_VERSION;
fn_xmlCheckVersion (LIBXML_VERSION);
validate_region (&start, &end);
@ -111,16 +204,16 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html
bytes = CHAR_TO_BYTE (iend) - CHAR_TO_BYTE (istart);
if (htmlp)
doc = htmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)),
bytes, burl, "utf-8",
HTML_PARSE_RECOVER|HTML_PARSE_NONET|
HTML_PARSE_NOWARNING|HTML_PARSE_NOERROR|
HTML_PARSE_NOBLANKS);
doc = fn_htmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)),
bytes, burl, "utf-8",
HTML_PARSE_RECOVER|HTML_PARSE_NONET|
HTML_PARSE_NOWARNING|HTML_PARSE_NOERROR|
HTML_PARSE_NOBLANKS);
else
doc = xmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)),
bytes, burl, "utf-8",
XML_PARSE_NONET|XML_PARSE_NOWARNING|
XML_PARSE_NOBLANKS |XML_PARSE_NOERROR);
doc = fn_xmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)),
bytes, burl, "utf-8",
XML_PARSE_NONET|XML_PARSE_NOWARNING|
XML_PARSE_NOBLANKS |XML_PARSE_NOERROR);
if (doc != NULL)
{
@ -139,19 +232,26 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html
if (NILP (result)) {
/* The document isn't just comments, so get the tree the
proper way. */
xmlNode *node = xmlDocGetRootElement (doc);
xmlNode *node = fn_xmlDocGetRootElement (doc);
if (node != NULL)
result = make_dom (node);
} else
result = Fcons (intern ("top"),
Fcons (Qnil, Fnreverse (Fcons (r, result))));
xmlFreeDoc (doc);
fn_xmlFreeDoc (doc);
}
return result;
}
void
xml_cleanup_parser (void)
{
if (libxml2_loaded_p ())
fn_xmlCleanupParser ();
}
DEFUN ("libxml-parse-html-region", Flibxml_parse_html_region,
Slibxml_parse_html_region,
2, 3, 0,
@ -159,7 +259,9 @@ DEFUN ("libxml-parse-html-region", Flibxml_parse_html_region,
If BASE-URL is non-nil, it is used to expand relative URLs. */)
(Lisp_Object start, Lisp_Object end, Lisp_Object base_url)
{
return parse_region (start, end, base_url, 1);
if (init_libxml2_functions (Vdynamic_library_alist))
return parse_region (start, end, base_url, 1);
return Qnil;
}
DEFUN ("libxml-parse-xml-region", Flibxml_parse_xml_region,
@ -169,7 +271,9 @@ DEFUN ("libxml-parse-xml-region", Flibxml_parse_xml_region,
If BASE-URL is non-nil, it is used to expand relative URLs. */)
(Lisp_Object start, Lisp_Object end, Lisp_Object base_url)
{
return parse_region (start, end, base_url, 0);
if (init_libxml2_functions (Vdynamic_library_alist))
return parse_region (start, end, base_url, 0);
return Qnil;
}
@ -181,6 +285,8 @@ syms_of_xml (void)
{
defsubr (&Slibxml_parse_html_region);
defsubr (&Slibxml_parse_xml_region);
DEFSYM (Qlibxml2_dll, "libxml2");
}
#endif /* HAVE_LIBXML2 */