From 3d384f172cb5fcabf441bd1c64cb4760df013781 Mon Sep 17 00:00:00 2001 From: Francois Gouget Date: Mon, 17 Nov 2008 19:29:32 +0100 Subject: [PATCH] msxml3: Dynamically load libxslt.so and only call xsltInit() if present. --- configure | 142 ++++++------------------------------ configure.ac | 13 +--- dlls/msxml3/Makefile.in | 2 +- dlls/msxml3/main.c | 57 ++++++++++++--- dlls/msxml3/msxml_private.h | 21 ++++++ dlls/msxml3/node.c | 21 ++---- include/config.h.in | 9 +-- 7 files changed, 103 insertions(+), 162 deletions(-) diff --git a/configure b/configure index 8fac4cb6e8..45ba7b1c5b 100755 --- a/configure +++ b/configure @@ -682,7 +682,6 @@ sane_devel GNUTLSINCL HALINCL XSLTINCL -XSLTLIBS XML2INCL XML2LIBS NASLIBS @@ -12171,8 +12170,6 @@ XML2LIBS="" XML2INCL="" -XSLTLIBS="" - XSLTINCL="" if test "x$with_xml" != "xno" @@ -12654,14 +12651,14 @@ done CPPFLAGS="$ac_save_CPPFLAGS" if test "$ac_cv_header_libxslt_transform_h" = "yes" then - { $as_echo "$as_me:$LINENO: checking for xsltCompilePattern in -lxslt" >&5 -$as_echo_n "checking for xsltCompilePattern in -lxslt... " >&6; } -if test "${ac_cv_lib_xslt_xsltCompilePattern+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for -lxslt" >&5 +$as_echo_n "checking for -lxslt... " >&6; } +if test "${ac_cv_lib_soname_xslt+set}" = set; then $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS + ac_check_soname_save_LIBS=$LIBS LIBS="-lxslt $ac_xslt_libs $LIBS" -cat >conftest.$ac_ext <<_ACEOF + cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -12704,138 +12701,41 @@ $as_echo "$ac_try_echo") >&5 test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then - ac_cv_lib_xslt_xsltCompilePattern=yes + case "$LIBEXT" in + dll) ;; + dylib) ac_cv_lib_soname_xslt=`otool -L conftest$ac_exeext | grep "libxslt\\.[0-9A-Za-z.]*dylib" | sed -e "s/^.*\/\(libxslt\.[0-9A-Za-z.]*dylib\).*$/\1/"';2,$d'` ;; + *) ac_cv_lib_soname_xslt=`$ac_cv_path_LDD conftest$ac_exeext | grep "libxslt\\.$LIBEXT" | sed -e "s/^.*\(libxslt\.$LIBEXT[^ ]*\).*$/\1/"';2,$d'` ;; + esac else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_cv_lib_xslt_xsltCompilePattern=no + fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + LIBS=$ac_check_soname_save_LIBS fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_xslt_xsltCompilePattern" >&5 -$as_echo "$ac_cv_lib_xslt_xsltCompilePattern" >&6; } -if test "x$ac_cv_lib_xslt_xsltCompilePattern" = x""yes; then +if test "x$ac_cv_lib_soname_xslt" = "x"; then + { $as_echo "$as_me:$LINENO: result: not found" >&5 +$as_echo "not found" >&6; } -cat >>confdefs.h <<\_ACEOF -#define HAVE_LIBXSLT 1 -_ACEOF - - XSLTLIBS="$ac_xslt_libs" - XSLTINCL="$ac_xslt_cflags" - ac_save_LIBS="$LIBS" - LIBS="$LIBS $ac_xslt_libs" - -for ac_func in xsltInit -do -as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 -$as_echo_n "checking for $ac_func... " >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func + { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_soname_xslt" >&5 +$as_echo "$ac_cv_lib_soname_xslt" >&6; } -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then - eval "$as_ac_var=yes" -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -rf conftest.dSYM -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -as_val=`eval 'as_val=${'$as_ac_var'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +cat >>confdefs.h <<_ACEOF +#define SONAME_LIBXSLT "$ac_cv_lib_soname_xslt" _ACEOF -fi -done - - LIBS="$ac_save_LIBS" + XSLTINCL="$ac_xslt_cflags" fi fi fi -if test "$ac_cv_lib_xslt_xsltCompilePattern" != "yes"; then +if test "x$ac_cv_lib_soname_xslt" = "x"; then case "x$with_xslt" in x) wine_warnings="$wine_warnings|libxslt ${notice_platform}development files not found, xslt won't be supported." ;; xno) ;; diff --git a/configure.ac b/configure.ac index 947bde9876..76393d1271 100644 --- a/configure.ac +++ b/configure.ac @@ -833,7 +833,6 @@ dnl **** Check for libxml2 **** AC_SUBST(XML2LIBS,"") AC_SUBST(XML2INCL,"") -AC_SUBST(XSLTLIBS,"") AC_SUBST(XSLTINCL,"") if test "x$with_xml" != "xno" then @@ -881,17 +880,11 @@ then CPPFLAGS="$ac_save_CPPFLAGS" if test "$ac_cv_header_libxslt_transform_h" = "yes" then - AC_CHECK_LIB(xslt, xsltCompilePattern, - [AC_DEFINE(HAVE_LIBXSLT, 1, [Define if you have the libxslt library]) - XSLTLIBS="$ac_xslt_libs" - XSLTINCL="$ac_xslt_cflags" - ac_save_LIBS="$LIBS" - LIBS="$LIBS $ac_xslt_libs" - AC_CHECK_FUNCS(xsltInit) - LIBS="$ac_save_LIBS"],,$ac_xslt_libs) + WINE_CHECK_SONAME(xslt,xsltCompilePattern, + [XSLTINCL="$ac_xslt_cflags"],,[$ac_xslt_libs]) fi fi -WINE_WARNING_WITH(xslt,[test "$ac_cv_lib_xslt_xsltCompilePattern" != "yes"], +WINE_WARNING_WITH(xslt,[test "x$ac_cv_lib_soname_xslt" = "x"], [libxslt ${notice_platform}development files not found, xslt won't be supported.]) dnl **** Check for libhal **** diff --git a/dlls/msxml3/Makefile.in b/dlls/msxml3/Makefile.in index c4293ddd33..8997f1bb56 100644 --- a/dlls/msxml3/Makefile.in +++ b/dlls/msxml3/Makefile.in @@ -5,7 +5,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = msxml3.dll IMPORTS = uuid urlmon shlwapi oleaut32 ole32 user32 advapi32 kernel32 -EXTRALIBS = @XML2LIBS@ @XSLTLIBS@ +EXTRALIBS = @XML2LIBS@ EXTRAINCL = @XML2INCL@ @XSLTINCL@ C_SRCS = \ diff --git a/dlls/msxml3/main.c b/dlls/msxml3/main.c index 8dbacbfa6a..308462577c 100644 --- a/dlls/msxml3/main.c +++ b/dlls/msxml3/main.c @@ -20,6 +20,7 @@ */ #include "config.h" +#include "wine/port.h" #define COBJMACROS @@ -32,13 +33,10 @@ #include "msxml2.h" #include "wine/debug.h" +#include "wine/library.h" #include "msxml_private.h" -#ifdef HAVE_LIBXSLT -#include -#endif - WINE_DEFAULT_DEBUG_CHANNEL(msxml); HRESULT WINAPI DllCanUnloadNow(void) @@ -47,6 +45,44 @@ HRESULT WINAPI DllCanUnloadNow(void) return S_FALSE; } + +void* libxslt_handle = NULL; +#ifdef SONAME_LIBXSLT +# define DECL_FUNCPTR(f) typeof(f) * p##f = NULL +DECL_FUNCPTR(xsltInit); +DECL_FUNCPTR(xsltApplyStylesheet); +DECL_FUNCPTR(xsltCleanupGlobals); +DECL_FUNCPTR(xsltFreeStylesheet); +DECL_FUNCPTR(xsltParseStylesheetDoc); +# undef MAKE_FUNCPTR +#endif + +static void init_libxslt(void) +{ +#ifdef SONAME_LIBXSLT + libxslt_handle = wine_dlopen(SONAME_LIBXSLT, RTLD_NOW, NULL, 0); + if (!libxslt_handle) + return; + +#define LOAD_FUNCPTR(f, needed) if ((p##f = wine_dlsym(libxslt_handle, #f, NULL, 0)) == NULL && needed) { WARN("Can't find symbol %s\n", #f); goto sym_not_found; } + LOAD_FUNCPTR(xsltInit, 0); + LOAD_FUNCPTR(xsltApplyStylesheet, 1); + LOAD_FUNCPTR(xsltCleanupGlobals, 1); + LOAD_FUNCPTR(xsltFreeStylesheet, 1); + LOAD_FUNCPTR(xsltParseStylesheetDoc, 1); +#undef LOAD_FUNCPTR + + if (pxsltInit) + pxsltInit(); + return; + + sym_not_found: + wine_dlclose(libxslt_handle, NULL, 0); + libxslt_handle = NULL; +#endif +} + + BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { switch(fdwReason) @@ -60,14 +96,17 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) xmlTreeIndentString = "\t"; xmlThrDefTreeIndentString("\t"); #endif -#ifdef HAVE_XSLTINIT - xsltInit(); -#endif + init_libxslt(); DisableThreadLibraryCalls(hInstDLL); break; case DLL_PROCESS_DETACH: -#ifdef HAVE_LIBXSLT - xsltCleanupGlobals(); +#ifdef SONAME_LIBXSLT + if (libxslt_handle) + { + pxsltCleanupGlobals(); + wine_dlclose(libxslt_handle, NULL, 0); + libxslt_handle = NULL; + } #endif #ifdef HAVE_LIBXML2 xmlCleanupParser(); diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 45d68cf659..56a5b39856 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -92,6 +92,27 @@ extern HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 #endif +void* libxslt_handle; +#ifdef SONAME_LIBXSLT +# ifdef HAVE_LIBXSLT_PATTERN_H +# include +# endif +# ifdef HAVE_LIBXSLT_TRANSFORM_H +# include +# endif +# include +# include +# include + +# define MAKE_FUNCPTR(f) extern typeof(f) * p##f +MAKE_FUNCPTR(xsltInit); +MAKE_FUNCPTR(xsltApplyStylesheet); +MAKE_FUNCPTR(xsltCleanupGlobals); +MAKE_FUNCPTR(xsltFreeStylesheet); +MAKE_FUNCPTR(xsltParseStylesheetDoc); +# undef MAKE_FUNCPTR +#endif + extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText, LONG line, LONG linepos, LONG filepos ); extern HRESULT DOMDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj ); diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index f2c6154cba..19cee8f3f8 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -33,17 +33,6 @@ #include "msxml_private.h" -#ifdef HAVE_LIBXSLT -# ifdef HAVE_LIBXSLT_PATTERN_H -# include -# endif -# ifdef HAVE_LIBXSLT_TRANSFORM_H -# include -# endif -# include -# include -#endif - #ifdef HAVE_LIBXML2 # include #endif @@ -1278,7 +1267,7 @@ static HRESULT WINAPI xmlnode_transformNode( IXMLDOMNode* styleSheet, BSTR* xmlString) { -#ifdef HAVE_LIBXSLT +#ifdef SONAME_LIBXSLT xmlnode *This = impl_from_IXMLDOMNode( iface ); xmlnode *pStyleSheet = NULL; xsltStylesheetPtr xsltSS = NULL; @@ -1287,6 +1276,8 @@ static HRESULT WINAPI xmlnode_transformNode( TRACE("%p %p %p\n", This, styleSheet, xmlString); + if (!libxslt_handle) + return E_NOTIMPL; if(!styleSheet || !xmlString) return E_INVALIDARG; @@ -1296,10 +1287,10 @@ static HRESULT WINAPI xmlnode_transformNode( { pStyleSheet = impl_from_IXMLDOMNode( ssNew ); - xsltSS = xsltParseStylesheetDoc( pStyleSheet->node->doc); + xsltSS = pxsltParseStylesheetDoc( pStyleSheet->node->doc); if(xsltSS) { - result = xsltApplyStylesheet(xsltSS, This->node->doc, NULL); + result = pxsltApplyStylesheet(xsltSS, This->node->doc, NULL); if(result) { const xmlChar *pContent; @@ -1337,7 +1328,7 @@ static HRESULT WINAPI xmlnode_transformNode( /* libxslt "helpfully" frees the XML document the stylesheet was generated from, too */ xsltSS->doc = NULL; - xsltFreeStylesheet(xsltSS); + pxsltFreeStylesheet(xsltSS); } IXMLDOMNode_Release(ssNew); diff --git a/include/config.h.in b/include/config.h.in index 016ee8ecd1..8f2c78e6ae 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -333,9 +333,6 @@ /* Define if you have the X Shape extension */ #undef HAVE_LIBXSHAPE -/* Define if you have the libxslt library */ -#undef HAVE_LIBXSLT - /* Define to 1 if you have the header file. */ #undef HAVE_LIBXSLT_PATTERN_H @@ -1002,9 +999,6 @@ /* Define if Xrender has the XRenderSetPictureTransform function */ #undef HAVE_XRENDERSETPICTURETRANSFORM -/* Define to 1 if you have the `xsltInit' function. */ -#undef HAVE_XSLTINIT - /* Define to 1 if you have the `_pclose' function. */ #undef HAVE__PCLOSE @@ -1128,6 +1122,9 @@ /* Define to the soname of the libXrender library. */ #undef SONAME_LIBXRENDER +/* Define to the soname of the libxslt library. */ +#undef SONAME_LIBXSLT + /* Define to the soname of the libXxf86vm library. */ #undef SONAME_LIBXXF86VM