[libxml++] patch to allow building without glibmm



 Hello,

 I've searched this list archives for the reasons as to why libxml++
requires glibmm when it would seem that it hardly uses any of its
functionality but couldn't find any real answer. Sorry if I missed
something but to me it looks that std::string could be used instead of
Glib::ustring just as well: indeed, I've even seen in the archives a
suggestion to typedef Glib::ustring as std::string instead of using the
real class. Unfortunately, it's not quite that simple as in a few places
Glib::ustring::bytes() is used and std::string doesn't have (nor need) this
method. Also, I wanted to have a clean way to build libxml++ without glibmm
and so I've created the attached patch to do it.

 The patch is rather short so you can probably read it quicker than I can
explain it, but nevertheless here is the summary:

1. add --without-ustring configure option (off by default), when it is used
   the (new) stub file libxml++/glibmm/ustring.h is used instead of the real
   one
2. define LIBXML_USE_STD_STRING when this option is used, this can be also
   used by MSVC users to build without glibmm under Windows
3. use LIBXML_USE_STD_STRING in a few places in the code to select between
   Glib::ustring::bytes() and std::string::size(): this is a bit ugly, of
   course, but the only other alternatives are to either derive
   Glib::ustring from std::string or to define some STRING_BYTES() macro
   and both of them have their problems as well -- but if it would be
   preferrable to do it like this, please let me know and I'll redo the
   patch
4. updated the docs to mention the changes above (not sure if the file
   docs/manual/libxml++_without_code.xml is the right one to update, again,
   please let me know if it isn't and I'll redo it)


 I sincerely hope this patch can be applied as it makes building the
library on non-Linux systems (even other Unices such as Darwin or HP-UX,
IRIX, ... are problematic without speaking about building glibmm and all
its dependencies under Windows) much, much simpler and so I believe this
patch could attract more users to this (otherwise excellent!) library.

 Thanks in advance,
VZ
diff -x autom4te.cache -x bin -x '*.sw?' -x .svn -x Makefile.in -N -r -u /tmp/libxml++-2.12.0/configure.in ./configure.in
--- /tmp/libxml++-2.12.0/configure.in	2005-09-07 22:41:25.000000000 +0200
+++ ./configure.in	2005-10-25 20:59:17.000000000 +0200
@@ -90,9 +90,25 @@
 
 AC_CHECK_HEADERS(string list map, , exit)
 
-PKG_CHECK_MODULES(LIBXML, libxml-2.0 >= 2.6.1 glibmm-2.4 >= 2.4.0)
+PKG_CHECK_MODULES(LIBXML, libxml-2.0 >= 2.6.1)
 
-GLIBMM_CHECK_PERL([5.6.0])
+AC_ARG_WITH(ustring,
+    AC_HELP_STRING([--without-ustring],
+                   [use std::string instead of Glib::ustring]),
+    ac_cv_use_glibustring="$withval"
+)
+if test "$ac_cv_use_glibustring" != "no"; then
+    PKG_CHECK_MODULES(GLIBMM, glibmm-2.4 >= 2.4.0, ,
+        AC_MSG_ERROR(dnl
+[Glib::ustring needed but not available: ${GLIBMM_PKG_ERRORS-please see error message above}.
+
+You may specify --without-ustring to use std::string instead.])
+    )
+    GLIBMM_CHECK_PERL([5.6.0])
+else
+    GLIBMM_CFLAGS="-I\$(top_srcdir)/glibmm"
+    AC_DEFINE(LIBXML_USE_STD_STRING)
+fi
 
 # Dummy conditional just to make automake-1.4 happy.
 # We need an always-false condition in docs/Makefile.am.
diff -x autom4te.cache -x bin -x '*.sw?' -x .svn -x Makefile.in -N -r -u /tmp/libxml++-2.12.0/examples/dom_parser_raw/main.cc ./examples/dom_parser_raw/main.cc
--- /tmp/libxml++-2.12.0/examples/dom_parser_raw/main.cc	2004-12-25 16:48:56.000000000 +0100
+++ ./examples/dom_parser_raw/main.cc	2005-10-26 16:42:36.000000000 +0200
@@ -23,7 +23,10 @@
 
 #include <iostream>
 #include <fstream>
-#include <glibmm/convert.h>
+
+#ifndef LIBXML_USE_STD_STRING
+  #include <glibmm/convert.h>
+#endif
 
 
 void print_node(const xmlpp::Node* node, unsigned int indentation = 0)
@@ -76,6 +79,20 @@
     std::string contents = read_from_disk(filepath);
     std::string contents_ucs2;
 
+#ifdef LIBXML_USE_STD_STRING
+    size_t wcSize = mbstowcs(NULL, contents.c_str(), 0);
+    wchar_t *ws = new wchar_t[wcSize+1];
+    if ( mbstowcs(ws, contents.c_str(), wcSize) == (size_t)-1 )
+    {
+      std::cerr << "mbstowcs() failed" << std::endl;
+    }
+    else
+    {
+      const char * const s = (char *)ws;
+      contents_ucs2.assign(s, s + wcslen(ws)*sizeof(wchar_t)/sizeof(char) + 1);
+    }
+    delete [] ws;
+#else // !LIBXML_USE_STD_STRING
     try
     {
       contents_ucs2 = Glib::convert(contents, "UCS-2", "UTF-8");
@@ -84,6 +101,7 @@
     {
       std::cerr << "Glib::convert failed: " << ex.what() << std::endl;
     }
+#endif // LIBXML_USE_STD_STRING/!LIBXML_USE_STD_STRING
 
     parser.parse_memory_raw((const unsigned char*)contents_ucs2.c_str(), contents_ucs2.size());
 
diff -x autom4te.cache -x bin -x '*.sw?' -x .svn -x Makefile.in -N -r -u /tmp/libxml++-2.12.0/glibmm/ustring.h ./glibmm/ustring.h
--- /tmp/libxml++-2.12.0/glibmm/ustring.h	1970-01-01 01:00:00.000000000 +0100
+++ ./glibmm/ustring.h	2005-10-25 20:50:00.000000000 +0200
@@ -0,0 +1,25 @@
+/* glibmm/ustring.h
+ * this file is part of libxml++
+ *
+ * copyright (C) 2005 by the libxml++ development team
+ *
+ * this file is covered by the GNU Lesser General Public License,
+ * which should be included with libxml++ as the file COPYING.
+ */
+
+/*
+   This is a replacement header used instead of the real glibmm/ustring.h when
+   we're configured to use std::string instead of Glib::ustring.
+ */
+#ifndef LIBXMLPP_GLIBMM_USTRING_H_
+#define LIBXMLPP_GLIBMM_USTRING_H_
+
+#ifndef LIBXML_USE_STD_STRING
+    #error "LIBXML_USE_STD_STRING must be defined if this header is included."
+#endif
+
+#include <string>
+
+namespace Glib { typedef std::string ustring; }
+
+#endif // LIBXMLPP_GLIBMM_USTRING_H_
diff -x autom4te.cache -x bin -x '*.sw?' -x .svn -x Makefile.in -N -r -u /tmp/libxml++-2.12.0/libxml++/Makefile.am ./libxml++/Makefile.am
--- /tmp/libxml++-2.12.0/libxml++/Makefile.am	2005-08-25 00:20:51.000000000 +0200
+++ ./libxml++/Makefile.am	2005-10-25 20:58:48.000000000 +0200
@@ -1,6 +1,6 @@
 SUBDIRS = parsers exceptions nodes io validators
 
-INCLUDES = -I$(top_srcdir) @LIBXML_CFLAGS@
+INCLUDES = -I$(top_srcdir) @LIBXML_CFLAGS@ @GLIBMM_CFLAGS@
 
 h_sources_public = libxml++.h attribute.h dtd.h document.h noncopyable.h keepblanks.h
 h_sources_private = 
@@ -21,7 +21,8 @@
                          exceptions/libexceptions.la \
                          nodes/libnodes.la \
                          io/libio.la \
-						 @LIBXML_LIBS@
+                         @LIBXML_LIBS@ \
+                         @GLIBMM_LIBS@
 libxml___2_6_la_SOURCES = $(cc_sources) $(h_sources_public) $(h_sources_private) $(cc_sources_private)
 
 # Install the headers:
diff -x autom4te.cache -x bin -x '*.sw?' -x .svn -x Makefile.in -N -r -u /tmp/libxml++-2.12.0/libxml++/parsers/domparser.cc ./libxml++/parsers/domparser.cc
--- /tmp/libxml++-2.12.0/libxml++/parsers/domparser.cc	2005-04-24 17:18:32.000000000 +0200
+++ ./libxml++/parsers/domparser.cc	2005-10-25 20:48:28.000000000 +0200
@@ -80,7 +80,13 @@
 
 void DomParser::parse_memory(const Glib::ustring& contents)
 {
-  parse_memory_raw((const unsigned char*)contents.c_str(), contents.bytes());
+  parse_memory_raw((const unsigned char*)contents.c_str(),
+#ifdef LIBXML_USE_STD_STRING
+                    contents.size()
+#else
+                    contents.bytes()
+#endif
+                    );
 }
 
 void DomParser::parse_context()
diff -x autom4te.cache -x bin -x '*.sw?' -x .svn -x Makefile.in -N -r -u /tmp/libxml++-2.12.0/libxml++/parsers/saxparser.cc ./libxml++/parsers/saxparser.cc
--- /tmp/libxml++-2.12.0/libxml++/parsers/saxparser.cc	2005-04-24 17:05:49.000000000 +0200
+++ ./libxml++/parsers/saxparser.cc	2005-10-25 20:49:51.000000000 +0200
@@ -186,7 +186,13 @@
   
 void SaxParser::parse_memory(const Glib::ustring& contents)
 {
-  parse_memory_raw((const unsigned char*)contents.c_str(), contents.bytes());
+  parse_memory_raw((const unsigned char*)contents.c_str(),
+#ifdef LIBXML_USE_STD_STRING
+                    contents.size()
+#else
+                    contents.bytes()
+#endif
+                   );
 }
 
 void SaxParser::parse_stream(std::istream& in)
@@ -242,7 +248,13 @@
   }
   
   if(!exception_)
-    xmlParseChunk(context_, chunk.c_str(), chunk.bytes(), 0 /* don't terminate */);
+    xmlParseChunk(context_, chunk.c_str(),
+#ifdef LIBXML_USE_STD_STRING
+                  chunk.size()
+#else
+                  chunk.bytes()
+#endif
+                  , 0 /* don't terminate */);
 
   check_for_exception();
 }
--- /tmp/libxml++-2.12.0/docs/manual/libxml++_without_code.xml	2005-02-11 14:25:14.000000000 +0100
+++ docs/manual/libxml++_without_code.xml	2005-10-27 02:30:34.000000000 +0200
@@ -53,6 +53,15 @@
     <para>Because Standard C++ has no string class that can fully handle UTF-8, libxml++ uses the Glib::ustring class from the glibmm library. Glib::ustring has almost exactly the same API as std::string, but methods such as length() and operator[] deal with whole UTF-8 characters rather than raw bytes.</para>
     <para>There are implicit conversions between std::string and Glib::ustring, so you can use std::string wherever you see a Glib::ustring in the API, if you really don't care about any locale other than English. However, that is unlikely in today's connected world.</para>
     <para>glibmm also provides useful API to convert between encodings and locales.</para>
+    <para>
+        All this being said, if you are absolutely sure that you don't need any
+        extra functionality of Glib::ustring, you can build the library without
+        glibmm and its dependencies. Under Unix this is done by specifying
+        <literal>--without-ustring</literal> in configure arguments and under
+        Windows you have to ensure that <literal>LIBXML_USE_STD_STRING</literal>
+        is defined in your project options and the directory glibmm is in the
+        compiler include path.
+    </para>
     </sect2>
  
     </sect1>





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]