From da53432c335d1dabbc890e632d99c22b5eab71f2 Mon Sep 17 00:00:00 2001
From: g0dil <g0dil@wiback.org>
Date: Sat, 20 Jan 2007 23:45:42 +0000
Subject: [PATCH] Again some doc-build fixes Extend the CSS rules some more for
 advanced browsers (probably everyone except IE)

Finish FileHandle documentation
Complete SocketHandle documentation
---
 SConstruct              |   2 +-
 Socket/FileHandle.cc    |   7 +-
 Socket/FileHandle.cci   |   4 +-
 Socket/FileHandle.hh    |  20 ++++-
 Socket/FileHandle.ih    |  57 ++++++++++++--
 Socket/SocketHandle.cc  |   7 +-
 Socket/SocketHandle.cci |   4 +-
 Socket/SocketHandle.ct  |   4 +-
 Socket/SocketHandle.cti |   4 +-
 Socket/SocketHandle.hh  | 139 +++++++++++++++++++++++++++++++---
 Socket/SocketHandle.ih  | 163 ++++++++++++++++++++++++++++++----------
 doclib/senf.css         |  99 ++++++++++++------------
 senfscons/Doxygen.py    |  37 +++++++--
 senfscons/SENFSCons.py  |   3 +-
 14 files changed, 420 insertions(+), 130 deletions(-)

diff --git a/SConstruct b/SConstruct
index c3cd8246e..ca3fad0ac 100644
--- a/SConstruct
+++ b/SConstruct
@@ -23,7 +23,7 @@ SConscript(glob.glob("*/SConscript"))
 SENFSCons.StandardTargets(env)
 SENFSCons.GlobalTargets(env)
 SENFSCons.Doxygen(env)
-SENFSCons.DoxyXRef(env, env.Alias('all_docs')[0].sources,
+SENFSCons.DoxyXRef(env, 
                    HTML_HEADER = '#/doclib/doxy-header-overview.html',
                    HTML_FOOTER = '#/doclib/doxy-footer.html')
 
diff --git a/Socket/FileHandle.cc b/Socket/FileHandle.cc
index 687bde711..c482e6db6 100644
--- a/Socket/FileHandle.cc
+++ b/Socket/FileHandle.cc
@@ -20,7 +20,9 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of non-inline non-template functions
+/** \file
+    \brief senf::FileHandle non-inline non-template implementation
+ */
 
 #include "FileHandle.hh"
 //#include "FileHandle.ih"
@@ -76,6 +78,9 @@ prefix_ void senf::FileBody::blocking(bool status)
     if (::fcntl(fd(), F_SETFL, flags) < 0) throw SystemException(errno);
 }
 
+/* We don't take POLLIN/POLLOUT as argument to avoid having to include
+   sys/poll.h in the .cci file (and therefore indirectly into the .hh
+   and then every file which uses FileHandle) */
 prefix_ bool senf::FileBody::pollCheck(int fd, bool incoming, bool block)
     const
 {
diff --git a/Socket/FileHandle.cci b/Socket/FileHandle.cci
index f69d3e01c..0fc5f3e52 100644
--- a/Socket/FileHandle.cci
+++ b/Socket/FileHandle.cci
@@ -20,7 +20,9 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of inline non-template functions
+/** \file
+    \brief senf::FileHandle inline non-template implementation
+ */
 
 //#include "FileHandle.ih"
 
diff --git a/Socket/FileHandle.hh b/Socket/FileHandle.hh
index 9a8c7e7d5..d2c93b61c 100644
--- a/Socket/FileHandle.hh
+++ b/Socket/FileHandle.hh
@@ -20,6 +20,10 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+/** \file 
+    \brief senf::FileHandle public header
+ */
+
 #ifndef HH_FileHandle_
 #define HH_FileHandle_ 1
 
@@ -105,19 +109,27 @@ namespace senf {
 
         bool eof() const;            ///< Check EOF condition
 	                             /**< Depending on the socket type, this might never return \p
-					true */
+					true.
+					
+					This member is somewhat problematic performance wise if
+					called frequently since it relies on virtual
+					functions. However, since the eof() handling is extremely
+					protocol dependent, a policy based implementation does not
+					seam feasible. */
         bool valid() const;          ///< Check filehandle validity
 	                             /**< Any operation besides valid() will fail on an invalid
 					FileHandle */
 
 	bool boolean_test() const;  ///< Short for valid() && ! eof()
 	                            /**< This is called when using a FileHandle instance in a boolen
-				       context */
+				       context 
+
+				       See the performance comments for the eof() member */
 
         int fd() const;             ///< Return the raw FileHandle
 
-        static FileHandle cast_static(FileHandle handle);  ///< \internal
-        static FileHandle cast_dynamic(FileHandle handle); ///< \internal
+        static FileHandle cast_static(FileHandle handle);  /**< \internal */
+        static FileHandle cast_dynamic(FileHandle handle); /**< \internal */
 
     protected:
         explicit FileHandle(std::auto_ptr<FileBody> body);
diff --git a/Socket/FileHandle.ih b/Socket/FileHandle.ih
index 9ca832d98..24c05283c 100644
--- a/Socket/FileHandle.ih
+++ b/Socket/FileHandle.ih
@@ -20,6 +20,10 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+/** \file
+    \brief senf::FileHandle internal header
+ */
+
 #ifndef IH_FileHandle_
 #define IH_FileHandle_ 1
 
@@ -32,7 +36,29 @@
 namespace senf {
 
 
-    /** \brief
+    /** \brief senf::FileHandle referenced body
+	
+	\internal
+
+	The senf::FileBody class formes the body part of the handle/body structure of the FileHandle
+	interface. It manages the FileHandle data and is referenced by senf::FileHandle. It is
+	automatically managed using reference counting.
+
+	Since the senf::FileHandle class forwards most calls directly to the underlying
+	senf::FileBody instance, most members are documented in senf::FileHandle.
+
+	\section filebody_new Writing senf::FileBody derived classes
+
+	It is possible to write customized senf::FileBody derived body implementations. This
+	implementation can then be used be a senf::FileHandle derived class to customize the
+	FileHandle behavior. Handling the body directly by the handle class ensures, that no invalid
+	handles can be created (a senf::FileHandle derived handle expecting a specific body type but
+	pointing to a different body type).
+
+	To customize the behavior, a virtual interface is provided. This interface only covers some
+	basic funcionality which is only used infrequently during the lifetime of a FileHandle
+	instance.
+
       */
     class FileBody
         : public senf::intrusive_refcount
@@ -47,7 +73,11 @@ namespace senf {
         ///\name Structors and default members
         ///@{
         
-        explicit FileBody(int fd=-1);
+        explicit FileBody(int fd=-1);	///< Create new instance
+					/**< You need to pass a real file descriptor to this
+					   constructor not some arbitrary id even if you overload
+					   all the virtual members. If the file descriptor is -1 the
+					   resulting body/handle is not valid() */
         virtual ~FileBody();
 
         // no copy
@@ -77,11 +107,23 @@ namespace senf {
         ///////////////////////////////////////////////////////////////////////////
         // Virtual interface for subclasses to override
 
-        virtual void v_close();
-        virtual void v_terminate();
-        virtual bool v_eof() const;
-        virtual bool v_valid() const;
-        
+        virtual void v_close();		///< Called to close the file descriptor
+					/**< You should probably always call the global ::close()
+					   function in this member, however you might want to do
+					   some additional cleanup here. If the operation fails, you
+					   are allowed to throw (preferably a
+					   senf::SystemException).
+
+					\throws senf::SystemException */
+        virtual void v_terminate();	///< Called to forcibly close the file descriptor
+					/**< This member is called by the destructor (and by
+					   terminate()) to close the descriptor. This member must \e
+					   never throw, it should probably just ignore error
+					   conditions (there's not much else you can do) */
+        virtual bool v_eof() const;	///< Called by eof()
+        virtual bool v_valid() const;	///< Called by valid()
+					/**< This member is only called, if the file descriptor is
+					   not -1 */
 
     protected:
         
@@ -100,4 +142,5 @@ namespace senf {
 // Local Variables:
 // mode: c++
 // c-file-style: "senf"
+// fill-column: 100
 // End:
diff --git a/Socket/SocketHandle.cc b/Socket/SocketHandle.cc
index 3f8a0ce87..f2225a8e3 100644
--- a/Socket/SocketHandle.cc
+++ b/Socket/SocketHandle.cc
@@ -20,7 +20,9 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of non-inline non-template functions
+/** \file
+    \brief senf::SocketHandle non-inline non-template implementation
+ */
 
 #include "SocketHandle.hh"
 #include "SocketHandle.ih"
@@ -85,7 +87,8 @@ namespace {
     }
 }
 
-prefix_ bool senf::detail::StateMapOrdering::operator()(std::string a1, std::string a2)
+prefix_ bool senf::detail::StateMapOrdering::operator()(std::string const & a1,
+                                                        std::string const & a2)
     const
 {
     std::string::iterator i1 (a1.begin());
diff --git a/Socket/SocketHandle.cci b/Socket/SocketHandle.cci
index 60a522095..e138ec263 100644
--- a/Socket/SocketHandle.cci
+++ b/Socket/SocketHandle.cci
@@ -20,7 +20,9 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of inline non-template functions
+/** \file
+    \brief senf::SocketHandle inline non-template implementation
+ */
 
 #include "SocketHandle.ih"
 
diff --git a/Socket/SocketHandle.ct b/Socket/SocketHandle.ct
index 0082ffbc8..eac4a09e8 100644
--- a/Socket/SocketHandle.ct
+++ b/Socket/SocketHandle.ct
@@ -20,7 +20,9 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of non-inline template functions
+/** \file
+    \brief senf::SocketHandle non-inline template implementation
+ */
 
 #include "SocketHandle.ih"
 
diff --git a/Socket/SocketHandle.cti b/Socket/SocketHandle.cti
index f573e4386..e93ec630b 100644
--- a/Socket/SocketHandle.cti
+++ b/Socket/SocketHandle.cti
@@ -20,7 +20,9 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of inline template functions
+/** \file
+    \brief senf::SocketHandle inline template implementation
+ */
 
 #include "SocketHandle.ih"
 
diff --git a/Socket/SocketHandle.hh b/Socket/SocketHandle.hh
index 7304ff1f5..8f10b4a83 100644
--- a/Socket/SocketHandle.hh
+++ b/Socket/SocketHandle.hh
@@ -20,6 +20,10 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+/** \file
+    \brief senf::SocketHandle public header
+ */
+
 #ifndef HH_SocketHandle_
 #define HH_SocketHandle_ 1
 
@@ -36,10 +40,26 @@
 namespace senf {
 
 
-    /** \brief
+    /** \brief basic SocketHandle supporting protocol and policy abstraction
+
+	The senf::SocketHandle class introduces the two abstraction layers of the socket
+	library. senf::SocketHandle does \e not provide socket functions it only provides the
+	infrastructure necessary to support both, the protocol and the policy interface.
+
+	senf::SocketHandle takes the socket policy as a template argument. senf::SocketHandle also
+	introduces the protocol class. However, the class has no public constructors (see the
+	derived classes senf::ProtocolClientSocketHandle and senf::ProtocolServerSocketHandle).
+
+	The most important functionality provided by senf::SocketHandle is the conversion
+	constructor. This allows to implicitly convert between compatible socket handle types as
+	specified by the socket policy. The conversion constructor is defined in such a way, that
+	only valid conversions are possible (see the implementation source for a more complete
+	discussion).
 
-	\todo Create a SocketHandleBase class and move some non-Policy
-	dependent code there
+	\note This class is \e not meant to be used as a base-class outside the library
+	implementation; The protected interface is for internal use only.
+
+	\todo Create a SocketHandleBase class and move some non-Policy dependent code there
      */
     template <class SocketPolicy>
     class SocketHandle
@@ -51,6 +71,12 @@ namespace senf {
 
         typedef SocketPolicy Policy;
 
+	/** \brief Check policy compatibility
+
+	    IsCompatible is a template meta-function which will check some other socket policy for
+	    conversion compatibility. This check is used in the senf::SocketPolicy implementation to
+	    restrict the conversion operator.
+	 */
         template <class OtherPolicy>
         struct IsCompatible
             : public boost::enable_if< SocketPolicyIsBaseOf<SocketPolicy,OtherPolicy>,
@@ -66,45 +92,137 @@ namespace senf {
         // default destructor
 
         // conversion constructors
+	
         template <class OtherPolicy>
         SocketHandle(SocketHandle<OtherPolicy> other, 
                      typename IsCompatible<OtherPolicy>::type * = 0);
+	                                ///< Convert from other socket handle checking policy
+	                                ///< compatibility
 
         ///@}
         ///////////////////////////////////////////////////////////////////////////
 
         template <class OtherPolicy>
         typename IsCompatible<OtherPolicy>::type const & operator=(SocketHandle<OtherPolicy> other);
-
-        static SocketHandle cast_static(FileHandle handle);
-        static SocketHandle cast_dynamic(FileHandle handle);
+	                                ///< Assign from other socket handle checking policy
+	                                ///< compatibility
 
         void state(SocketStateMap & map, unsigned lod=0);
+	                                ///< Inquire state information of socket handle
+	                                /**< The map argument (a string to string mapping) will be
+					   filled with information coverning the current state of
+					   the socket. The information provided depends on the
+					   socket protocol. The amount of information returned can
+					   be controlled using the \p lod value.
+
+					   See senf::SocketProtocol::state() for more information,
+					   how the Information is generated.
+
+					   \param map string to string mapping to be filled with
+					       state information
+					   \param lod level of detail requesten. The interpretation
+					       of this value is protocol specific */
         std::string dumpState(unsigned lod=0);
+	                                ///< Format complete state information as string
+	                                /**< Formats the complete state map value and returns it as
+					   a single multi-line string. */
 
     protected:
         explicit SocketHandle(std::auto_ptr<SocketProtocol> protocol, bool isServer);
+	                                ///< Initialize SocketHandle providing the protocol
+	                                /**< \param protocol Protocol class of the protocol
+					         implemented by this socket handle
+					     \param isServer \c true, if this SocketHandle instance
+					         implements a server handle, \c false otherwise */
         SocketHandle(FileHandle other, bool isChecked);
-        
-        SocketBody & body();
-        SocketBody const & body() const;
+                                        ///< Initialize SocketHandle from arbitrary checked
+                                        ///< FileHandle
+	                                /**< This constructor is used to support up- and downcasting
+					   of SocketHandle instances.
+
+					   \warning It is absolutely necessary to ensure, that the
+					   FileHandle passed in is \e really a SocketHandle holding
+					   a SocketBody (and not a simple FileBody)
+					   instance. Additionally. the SocketPolicy absolutely must
+					   be compatible.
+
+					   \param other FileHandle to assign
+					   \param isChecked has to be \c true
+
+					   \todo Answer, why the heck I need the \c isChecked
+					   parameter ??
+					*/
+
+        SocketBody & body();		///< Access socket body
+                                        /**< This member replaces the corresponding FileHandle
+					   member and returns an appropriately cast body reference */
+        SocketBody const & body() const; ///< Access socket body in const context
+                                        /**< This member replaces the corresponding FileHandle
+					   member and returns an appropriately cast body reference */
         SocketProtocol const & protocol() const;
+                                        ///< Access protocol class
+
+        void assign(FileHandle other);	/**< \internal */
 
-        void assign(FileHandle other);
+    public:
+        static SocketHandle cast_static(FileHandle handle);
+        static SocketHandle cast_dynamic(FileHandle handle);
 
     private:
 
     };
 
+    /** \brief Write stream status dump to output stream
+
+	Write senf::SocketHandle::dumpState() to \c os
+
+	\related senf::SocketHandle
+     */
     template <class Policy>
     std::ostream & operator<<(std::ostream & os, SocketHandle<Policy> handle);
 
+    /** \brief static socket (down-)cast
+	
+	This function is like \c static_cast but for socket handles. It allows to downcast any
+	FileHandle to any SocketHandle (and its derived types). static_socket_cast will \e not check
+	the validity of the cast, it will assume, that the cast is valid.
+
+	The function will however check, that the cast is possible. Casting between (at compile
+	time) known incompatible types (like casting a SocketHandle with a communication policy of
+	ConnectedCommunicationPolicy to a SocketHandle with UnconnectedCommunicationPolicy will fail
+	at compile time).
+
+	\warning
+	If the type you cast to is not really a compatible socket handle type you will get undefined
+	behavior, probably your program will crash (You will get an assertion in debug builds).
+
+	\related senf::SocketHandle
+     */
     template <class Target, class Source>
     Target static_socket_cast(Source handle);
 
+    /** \brief dynamic socket (down-)cast
+
+	This function is like \c dynamic_cast but for socket handles. It is a runtime typechecked
+	version of static_socket_cast.
+	
+	\throws std::bad_cast You have tried to perform an invalid down- or crosscast.
+	
+	\related senf::SocketHandle
+     */
     template <class Target, class Source>
     Target dynamic_socket_cast(Source handle);
 
+    /** \brief dynamically check cast validity
+
+	This function will check, wether the given cast is valid. This is the same as checking, that
+	dynamic_socket_cast does not throw.
+
+	This member is needed, since there is no 'null' SocketHandle (comparable to a null pointer)
+	which could be returned by a non-throwing variant of dynamic_socket_cast.
+
+	\related senf::SocketHandle
+     */
     template <class Target, class Source>
     bool check_socket_cast(Source handle);
 }
@@ -119,4 +237,5 @@ namespace senf {
 // Local Variables:
 // mode: c++
 // c-file-style: "senf"
+// fill-column: 100
 // End:
diff --git a/Socket/SocketHandle.ih b/Socket/SocketHandle.ih
index 5ad2b9924..c72b54ddd 100644
--- a/Socket/SocketHandle.ih
+++ b/Socket/SocketHandle.ih
@@ -20,6 +20,10 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+/** \file
+    \brief senf::SocketHandle internal header
+ */
+
 #ifndef IH_SocketHandle_
 #define IH_SocketHandle_ 1
 
@@ -38,65 +42,141 @@ namespace senf {
 
     namespace detail {
 
+	/** \brief String supporting automatic type conversion
+
+	    The ConvertibleString class is used to simplify creating a text representation of
+	    arbitrary values. ConvertibleString is an ordinary string with an additional constructor
+	    which allows constructing the string from any arbitrary, streamable type.
+	    
+	    \note It is generally not advisable to derive from the standard library container
+	    classes. However, in this concrete case, the derivation is safe since only the
+	    additional functionality is added. It is absolutely safe to convert the derived class
+	    back to the base type.
+	 */
         class ConvertibleString : public std::string
         {
         public:
             ConvertibleString();
-            ConvertibleString(bool v);
+            ConvertibleString(bool v);	///< Bool conversion constructor
+					/**< The bool conversion is defined explicitly to use a
+					   specialized representation (the strings 'true' and
+					   'false') */
             template <class T>
             ConvertibleString(T const & other);
-            template <class T>
-            ConvertibleString & operator+= (ConvertibleString const & other);
-        };
-        
-        struct StateMapOrdering
-            : public std::binary_function<std::string,std::string,bool>
-        {
-            bool operator()(std::string a1, std::string a2) const;
-        };
-        
+                                        ///< Conversion constructor
+                                        /**< This constructor will assign the string from any
+					   arbitrary type. It will use boost::lexical_cast to
+					   convert the argument to its string representation. */
+
+	    template <class T>
+	    ConvertibleString & operator+= (ConvertibleString const & other);
+                                        ///< Add additional values with separator
+                                        /**< This operator facilitates the representation of
+					   multiple values in a single string. Each value is first
+					   converted to a string (using the type conversion
+					   machinery of C++ and the ConvertibleString conversion
+					   constructors). It is then appended to the current string
+					   with ', ' as a separator (if the current string is
+					   non-empty). */
+	};
+
+	/** \brief Special ordering for the SocketStateMap
+	    \internal
+
+	    This special ordering will sort 'hierarchical' strings correctly. A hierarchical string
+	    in this context is a string like a path- or hostname with '.' as the hierarchical
+	    separator.
+	 */
+	struct StateMapOrdering
+	    : public std::binary_function<std::string,std::string,bool>
+	{
+	    bool operator()(std::string const & a1, std::string const & a2) const;
+	};
+
     }
 
     typedef std::map< std::string, detail::ConvertibleString, detail::StateMapOrdering > SocketStateMap;
 
     namespace detail {
-        std::string dumpState(SocketStateMap const & map);
+	/** \brief Helper to convert SocketStateMap to multiline string representation
+	    \internal
+	 */
+	std::string dumpState(SocketStateMap const & map);
     }
 
+    /** \brief senf::SocketHandle referenced body
+	
+	\internal
+
+	senf::SocketBody is the extended (relatively to senf::FileBody) body of
+	senf::SocketHandle. Every SocketHandle must have a SocketBody as it's body (and not a simple
+	FileBody). The casting and conversion operators defined will ensure this if used
+	properly. If this invariant is violated, your Program will probably crash.
+     */
     class SocketBody
-        : public FileBody
+	: public FileBody
     {
     public:
-        ///////////////////////////////////////////////////////////////////////////
-        // Types
-        
-        typedef boost::intrusive_ptr<SocketBody> ptr;
-
-        ///////////////////////////////////////////////////////////////////////////
-        ///\name Structors and default members
-        ///@{
-
-        explicit SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer);
-        SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer, int fd);
-
-        // no copy
-        // no conversion constructors
-
-        ///@}
-        ///////////////////////////////////////////////////////////////////////////
-
-        SocketProtocol const & protocol() const;
-        bool isServer();
-        
-        void state(SocketStateMap & map, unsigned lod);
+	///////////////////////////////////////////////////////////////////////////
+	// Types
+
+	typedef boost::intrusive_ptr<SocketBody> ptr;
+
+	///////////////////////////////////////////////////////////////////////////
+	///\name Structors and default members
+	///@{
+
+	SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer);
+                                        /**< 
+					   \param protocol Protocol class implementing the desired
+					   protocol 
+					   \param isServer \c true, if this socket is a server
+					   socket, false otherwise */
+	SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer, int fd);
+                                        /**< 
+					   \param protocol Protocol class implementing the desired
+					   protocol 
+					   \param isServer \c true, if this socket is a server
+					   socket, false otherwise
+					   \param fd socket file descriptor */
+
+	// no copy
+	// no conversion constructors
+
+	///@}
+	///////////////////////////////////////////////////////////////////////////
+
+	SocketProtocol const & protocol() const;
+                                        ///< Access the protocol instance
+	bool isServer();		///< Check socket type
+                                        /**< \return \c true, if this is a server socket, \c false
+					   otherwise */
+
+	void state(SocketStateMap & map, unsigned lod);
+                                        /**< \todo Move state into a virtual body member (which is
+					   ok, since SocketBody already has virtual members). This
+					   makes in unnecessary to reimplement dumpState and state
+					   in every SocketHandle derived class */
 
     private:
-        virtual void v_close();
-        virtual void v_terminate();
-        virtual bool v_eof() const;
-
-        boost::scoped_ptr<SocketProtocol> protocol_;
-        bool isServer_;
+	virtual void v_close();		///< Close socket
+                                        /**< This override will automatically \c shutdown() the
+					   socket whenever it is closed.
+					   \throws senf::SystemException */
+	virtual void v_terminate();	///< Forcibly close socket
+                                        /**< This override will automatically \c shutfown() the
+					   socket whenever it is called. Additionally it will
+					   disable SO_LINGER to ensure, that v_terminate will not
+					   block. Like the overriden method, this member will ignore
+					   failures and will never throw. It therefore safe to be
+					   called from a destructor. */
+	virtual bool v_eof() const;	///< Check for eof condition
+                                        /**< Since the eof check for sockets is very protocol
+					   dependent, this member will forward the call to
+					   senf::SocketPolicy::eof() */
+
+	boost::scoped_ptr<SocketProtocol> protocol_;
+	bool isServer_;
     };
 
 }
@@ -108,4 +188,5 @@ namespace senf {
 // Local Variables:
 // mode: c++
 // c-file-style: "senf"
+// fill-column: 100
 // End:
diff --git a/doclib/senf.css b/doclib/senf.css
index e2086c960..f5f2de4e5 100644
--- a/doclib/senf.css
+++ b/doclib/senf.css
@@ -106,25 +106,6 @@ div.tabs ul li a:hover, div.tabs ul li#current a {
 	background-color: #EDE497;
 }
 
-div.nav { 
-	width: auto;
-	background-color: white;
-	border: none;
-	border-bottom: 1px solid #AF9D00;
-	padding: 5px 0;
-	margin: 0;	
-}
-
-div.qindex {
-	width: auto;
-	background-color: #e8eef2;
-	border: 1px solid #84b0c7;
-	text-align: center;
-	margin: 2px;
-	padding: 2px;
-	line-height: 140%;
-}
-
 #footer { 
 	clear: both;
 	padding: 4px 10px 4px 142px;
@@ -187,74 +168,88 @@ table.senf th {
 	font-weight: bold;
 }
 
-dl.bug { 
+dl.bug, dl.fixme, dl.todo, dl.idea { 
 	border: 1px solid #EE0000;
 	border-left-width: 4px;
 	background-color: #FFDDDD;
 	padding: 0 10px;
 }
 
-dl:contains("Bug:") { 
+dl:contains("Bug:"), dl:contains("Fix:"), dl:contains("Todo:"), dl:contains("Idea:") { 
 	border: 1px solid #CC8888;
-	padding: 5px;
+	padding: 4px;
 	background-color: #FFEEEE;
 	color: #666666;
+	font-size: 6px;
+	line-height: 6px;
+	overflow: hidden;
+	height: 6px;
+}
+
+dl:contains("Bug:"):hover, dl:contains("Fix:"):hover, 
+dl:contains("Todo:"):hover, dl:contains("Idea:"):hover { 
+	line-height: inherit;
+	font-size: inherit;
+	height: auto;
 }
 
-dl:contains("Bug:") a { 
+dl:contains("Bug:") a, dl:contains("Fix:") a, dl:contains("Todo:") a, dl:contains("Idea:") a { 
 	color: #6666FF;
 }
 
 dl.fixme { 
-	border: 1px solid #EEEE00;
-	border-left-width: 4px;
+	border-color: #EEEE00;
 	background-color: #FFFFDD;
-	padding: 0 10px;
 }
 
 dl:contains("Fix:") { 
-	border: 1px solid #CCCC88;
-	padding: 5px;
+	border-color: #CCCC88;
 	background-color: #FFFFEE;
-	color: #666666;
-}
-
-dl:contains("Fix:") a { 
-	color: #6666FF;
 }
 
 dl.todo { 
-	border: 1px solid #00AA00;
-	border-left-width: 4px;
+	border-color: #00AA00;
 	background-color: #DDFFDD;
-	padding: 0 10px;
 }
 
 dl:contains("Todo:") { 
-	border: 1px solid #88CC88;
-	padding: 5px;
+	border-color: #88CC88;
 	background-color: #EEFFEE;
-	color: #666666;
-}
-
-dl:contains("Todo:") a { 
-	color: #6666FF;
 }
 
 dl.idea { 
-	border: 1px solid #AAAAAA;
-	border-left-width: 4px;
+	border-color: #AAAAAA;
 	background-color: #EEEEEE;
-	padding: 0 10px;
 }
 
 dl:contains("Idea:") { 
-	border: 1px solid #CCCCCC;
-	padding: 5px;
+	border-color:  #CCCCCC;
 	background-color: #F8F8F8;
-	color: #666666;
 }
 
-dl:contains("Idea:") a { 
-	color: #6666FF;
-}
\ No newline at end of file
+table {
+	width: 100%;
+}
+
+div.ah { 
+	margin-right: 10px;
+}
+
+div.nav { 
+	width: auto;
+	background-color: white;
+	border: none;
+	border-bottom: 1px solid #AF9D00;
+	padding: 5px 0;
+	margin: 0;	
+}
+
+div.qindex {
+	width: auto;
+	background-color: #e8eef2;
+	border: 1px solid #84b0c7;
+	text-align: center;
+	margin: 2px 0;
+	padding: 2px;
+	line-height: 140%;
+}
diff --git a/senfscons/Doxygen.py b/senfscons/Doxygen.py
index bd493a341..9e8f1c684 100644
--- a/senfscons/Doxygen.py
+++ b/senfscons/Doxygen.py
@@ -15,6 +15,34 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+# I have been fighting 4 problems in this implementation:
+# - A Directory target will *not* call any source scanners
+# - A Directory target will interpret the directory contents as
+#   sources not targets. This means, that if a command creates that
+#   directory plus contents, the target will never be up-to-date
+#   (since the directory contents will change with every call of
+#   scons)
+# - Theres a bug in SCons which will produce an error message for
+#   directory targets if dir.sources is not set explicitly
+# - the first argument to env.Clean() must be the command line target,
+#   with which the scons was invoked. This does not help to add
+#   aditional files or directories to be cleaned if you don't know
+#   that target (it's not possible to say 'if you clean this file,
+#   also clean that one' hich is, what I had expected env.Clean to
+#   do).
+#
+# Together, these problems have produced several difficulties. I have
+# solved them by
+# - Adding an (empty) stamp file as a (file) target. This target will
+#   cause source scanners to be invoked
+# - Adding the documentation directory as a target (so it will be
+#   cleaned up which env.Clean doesn't help me to do), but *only* if
+#   scons is called to with the -c option
+# - Setting dir.sources to the known source-list to silence the error
+#   message whenever a directory is added as a target
+#
+# You will find all this in the DoxyEmitter
+
 import os, sys, traceback
 import os.path
 import glob
@@ -165,23 +193,18 @@ def DoxyEmitter(source, target, env):
       out_dir = data["OUTPUT_DIRECTORY"]
       dir = env.Dir( os.path.join(source[0].dir.abspath, out_dir) )
       dir.sources = source
-      targets.append(dir)
+      if env.GetOption('clean'): targets.append(dir)
    else:
       out_dir = '.'
 
    # add our output locations
    for (k, v) in output_formats.iteritems():
       if data.get("GENERATE_" + k, v[0]).upper() == "YES":
-         # Grmpf ... need to use a File object here. The problem is, that
-         # Dir.scan() is implemented to just return the directory entries
-         # and does *not* invoke the source-file scanners .. ARGH !!
          dir = env.Dir( os.path.join(source[0].dir.abspath, out_dir, data.get(k + "_OUTPUT", v[1])) )
-         # This is needed to silence the (wrong) 'Multiple ways to
-         # build the same target' message
          dir.sources = source
          node = env.File( os.path.join(dir.abspath, k.lower()+".stamp" ) )
          targets.append(node)
-         targets.append(dir)
+         if env.GetOption('clean'): targets.append(dir)
 
    if data.has_key("GENERATE_TAGFILE"):
       targets.append(env.File( os.path.join(source[0].dir.abspath, data["GENERATE_TAGFILE"]) ))
diff --git a/senfscons/SENFSCons.py b/senfscons/SENFSCons.py
index 91bac5b7a..d2e0c4882 100644
--- a/senfscons/SENFSCons.py
+++ b/senfscons/SENFSCons.py
@@ -218,7 +218,8 @@ def DoxyXRef(env, docs=None,
             "sed -e 's/\\$$title/$TITLE/g' -e 's/\\$$projectname/Overview/g' ${SOURCES[%d]} >> $TARGET"
             % (HTML_HEADER and 3 or 2))
     
-    xref = env.Command("doc/html/xref.html", sources, commands)
+    xref = env.Command("doc/html/xref.html", sources, commands,
+                       TITLE = TITLE)
 
     env.Alias('all_docs',xref)
     return xref
-- 
GitLab