msxml3: Dynamically load libxslt.so and only call xsltInit() if present. (try 2)

Francois Gouget fgouget at codeweavers.com
Mon Nov 17 12:29:32 CST 2008


---

So the preferred solution is to dynamically load the libxslt library 
altogether.


 configure.ac                |   12 ++-------
 dlls/msxml3/Makefile.in     |    2 +-
 dlls/msxml3/main.c          |   55 ++++++++++++++++++++++++++++++++++++------
 dlls/msxml3/msxml_private.h |   21 ++++++++++++++++
 dlls/msxml3/node.c          |   19 ++++-----------
 include/config.h.in         |    6 ++--
 6 files changed, 80 insertions(+), 35 deletions(-)

diff --git a/configure.ac b/configure.ac
index 71c2a45..55cc32d 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,12 @@ then
     CPPFLAGS="$ac_save_CPPFLAGS"
     if test "$ac_cv_header_libxslt_transform_h" = "yes"
     then
-        AC_CHECK_LIB(xslt, xsltCompilePattern,
+        WINE_CHECK_SONAME(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)
+             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 c4293dd..8997f1b 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 8dbacbf..d76a189 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 <libxslt/xslt.h>
-#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 HAVE_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()
+{
+#ifdef HAVE_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();
+        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 45d68cf..b2ed59d 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 HAVE_LIBXSLT
+# ifdef HAVE_LIBXSLT_PATTERN_H
+#  include <libxslt/pattern.h>
+# endif
+# ifdef HAVE_LIBXSLT_TRANSFORM_H
+#  include <libxslt/transform.h>
+# endif
+# include <libxslt/xsltutils.h>
+# include <libxslt/xsltInternals.h>
+# include <libxslt/xslt.h>
+
+# 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 f2c6154..c3f504b 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 <libxslt/pattern.h>
-# endif
-# ifdef HAVE_LIBXSLT_TRANSFORM_H
-#  include <libxslt/transform.h>
-# endif
-# include <libxslt/xsltutils.h>
-# include <libxslt/xsltInternals.h>
-#endif
-
 #ifdef HAVE_LIBXML2
 # include <libxml/HTMLtree.h>
 #endif
@@ -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 016ee8e..234e177 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -1002,9 +1002,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 +1125,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
 
-- 
1.5.6.5




More information about the wine-patches mailing list