Again some doc-build fixes
g0dil [Sat, 20 Jan 2007 23:45:42 +0000 (23:45 +0000)]
Extend the CSS rules some more for advanced browsers (probably everyone except IE)

Finish FileHandle documentation
Complete SocketHandle documentation

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@181 270642c3-0616-0410-b53a-bc976706d245

14 files changed:
SConstruct
Socket/FileHandle.cc
Socket/FileHandle.cci
Socket/FileHandle.hh
Socket/FileHandle.ih
Socket/SocketHandle.cc
Socket/SocketHandle.cci
Socket/SocketHandle.ct
Socket/SocketHandle.cti
Socket/SocketHandle.hh
Socket/SocketHandle.ih
doclib/senf.css
senfscons/Doxygen.py
senfscons/SENFSCons.py

index c3cd824..ca3fad0 100644 (file)
@@ -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')
 
index 687bde7..c482e6d 100644 (file)
@@ -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
 {
index f69d3e0..0fc5f3e 100644 (file)
@@ -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"
 
index 9a8c7e7..d2c93b6 100644 (file)
 // 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);
index 9ca832d..24c0528 100644 (file)
 // 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
 
 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:
index 3f8a0ce..f2225a8 100644 (file)
@@ -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());
index 60a5220..e138ec2 100644 (file)
@@ -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"
 
index 0082ffb..eac4a09 100644 (file)
@@ -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"
 
index f573e43..e93ec63 100644 (file)
@@ -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"
 
index 7304ff1..8f10b4a 100644 (file)
 // 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
 
 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:
index 5ad2b99..c72b54d 100644 (file)
 // 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:
index e2086c9..f5f2de4 100644 (file)
@@ -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%;
+}
index bd493a3..9e8f1c6 100644 (file)
 # 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"]) ))
index 91bac5b..d2e0c48 100644 (file)
@@ -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