Implemented global cross-reference generation
g0dil [Thu, 18 Jan 2007 10:28:43 +0000 (10:28 +0000)]
Updated documentation templates to include cross-reference
Fixed documentation build (especially regarding cleanup)
Cleaned up BUG, FIXME, TODO and IDEA items
More SocketLibrary documentation

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

43 files changed:
Doxyfile
Mainpage.dox
Packets/EthernetPacket.cc
Packets/GenericPacket.ct
Packets/Packet.cc
Packets/Packet.cci
Packets/Packet.ct
Packets/Packet.cti
Packets/Packet.hh
Packets/PacketRegistry.hh
Packets/ParseListS.ct
Packets/ParseVec.ct
Packets/ParserBase.test.cc
Packets/RTCPPacket.test.cc
SConstruct
Scheduler/ReadHelper.hh
Scheduler/Scheduler.cc
Scheduler/Scheduler.hh
Socket/BSDSocketProtocol.cc
Socket/BufferingPolicy.hh
Socket/ClientSocketHandle.ct
Socket/ClientSocketHandle.hh
Socket/FileHandle.hh
Socket/INetAddressing.cc
Socket/INetAddressing.cci
Socket/INetAddressing.hh
Socket/INetProtocol.hh
Socket/LLAddressing.cci
Socket/Mainpage.dox
Socket/PacketSocketHandle.cc
Socket/PacketSocketHandle.test.cc
Socket/ReadWritePolicy.hh
Socket/SocketHandle.cc
Socket/SocketHandle.hh
Socket/SocketProtocol.hh
Socket/TCPSocketHandle.hh
doclib/Doxyfile.global
doclib/senf.css
senfscons/Doxygen.py
senfscons/SENFSCons.py
senfscons/functions.xsl [new file with mode: 0644]
senfscons/xrefhtml.xslt [new file with mode: 0644]
senfscons/xrefxtract.xslt [new file with mode: 0644]

index 3247d4e..57cdd8d 100644 (file)
--- a/Doxyfile
+++ b/Doxyfile
@@ -5,6 +5,7 @@ OUTPUT_DIRECTORY       = doc
 INPUT                  = .
 FILE_PATTERNS          = *.dox
 IMAGE_PATH             = .
+EXAMPLE_PATH           = Sniffer
 HTML_HEADER            = doclib/doxy-header-overview.html
 HTML_FOOTER            = doclib/doxy-footer.html
 GENERATE_LATEX         = NO
index 51f2515..2ded007 100644 (file)
@@ -30,6 +30,7 @@
 
     \see \ref usage\n
          \ref example\n
+         <a href="xref.html">Current status: Cross reference of action points</a>\n
          <a class="ext" href="http://developer.berlios.de/projects/senf">The BerliOS project page</a>\n
          <a class="ext" href="http://openfacts.berlios.de/index-en.phtml?title=SENF+Network+Framework">The SENF Wiki at BerliOS</a>
 */
index 60c122e..4727474 100644 (file)
@@ -40,8 +40,8 @@ namespace {
 prefix_ void senf::EthernetPacket::v_nextInterpreter()
     const
 {
-    // TODO: Add LLC/SNAP support -> only use the registry
-    // for type() values >=1536, otherwise expect an LLC header
+    /** \todo Add LLC/SNAP support -> only use the registry
+       for type() values >=1536, otherwise expect an LLC header */
     registerInterpreter(type(),begin()+bytes(),end());
 }
 
@@ -85,8 +85,7 @@ prefix_ void senf::EthernetPacket::v_finalize()
 prefix_ void senf::EthVLanPacket::v_nextInterpreter()
     const
 {
-    // TODO: Add LLC/SNAP support -> only use the registry
-    // for type() values >=1536, otherwise expect an LLC header
+    /** \todo Add LLC/SNAP support (see above) */
     registerInterpreter(type(),begin()+bytes(),end());
 }
 
index 0a9768c..bfc4c53 100644 (file)
@@ -44,7 +44,7 @@ template <unsigned HEADER, unsigned TRAILER>
 prefix_ void senf::GenericPacket<HEADER,TRAILER>::v_dump(std::ostream & os)
     const
 {
-    // TODO: implement v_dump()
+    /// \todo implement v_dump()
 }
 
 ///////////////////////////////ct.e////////////////////////////////////////
index ef5752f..828e530 100644 (file)
@@ -187,8 +187,8 @@ prefix_ senf::Packet::ptr senf::Packet::next()
     if (n == this->impl_->interpreters_.end()) {
         if (this->parsed_)
             return ptr(0);
-        // FIXME: v_nextInterpreter return bool? new Interpreter to be
-        // added ? hmm ... this however is quite suboptimal ...
+        /* \fixme v_nextInterpreter return bool? new Interpreter to be
+          added ? hmm ... this however is quite suboptimal ... */
         this->v_nextInterpreter();
         this->parsed_ = true;
         n = boost::next(this->self_);
@@ -270,8 +270,8 @@ prefix_ void senf::Packet::erase(iterator first, iterator last)
     size_type index(first-impl_->data_.begin());
     size_type sz(last-first);
     BOOST_ASSERT( index >= begin_ && index < end_ && sz <= end_-index );
-    // FIXME: Here we should assert, that no bytes belonging to the
-    // next iterator are deleted ...
+    /** \fixme Here we should assert, that no bytes belonging to the
+       next iterator are deleted ... */
     impl_->data_.erase(first,last);
     impl_->updateIterators(index,-sz,self_,INSIDE);
 }
index 5a299df..ea63a07 100644 (file)
@@ -154,10 +154,10 @@ prefix_ senf::Packet::ptr senf::Packet::head()
 
 prefix_  senf::Packet::~Packet()
 {
-    // FIXME: This is bad ... we cannot check this since this
-    // assertion fails at the moment if the Packet constructor throws
-    // ... hrmpf ... we really need to initialize refcount_ to 0 and
-    // remove the 'false' argument to the ptr constructor in ::create
+    /** \fixme This is bad ... we cannot check this since this
+       assertion fails at the moment if the Packet constructor throws
+       ... hrmpf ... we really need to initialize refcount_ to 0 and
+       remove the 'false' argument to the ptr constructor in create */
     // BOOST_ASSERT( !this->refcount_  && !this->impl_ );
     SATCOM_PKF_REFC_MSG("] Packet::~Packet (" << this << ")\n");
 }
index ecb2fde..948698d 100644 (file)
@@ -56,8 +56,8 @@ template <class OuterPacket>
 prefix_ typename senf::Packet::ptr_t<OuterPacket>::ptr
 senf::Packet::create(Packet::ptr payload)
 {
-    // TODO: should I instead of using head() throw away all
-    // interpreters before payload? ... probably yes ...
+    /** \todo should I instead of using head() throw away all
+       interpreters before payload? ... probably yes ... */
     payload->insert(payload->head()->begin(),min_bytes<OuterPacket>(),0);
     typename ptr_t<OuterPacket>::ptr p (new OuterPacket(PacketOp_set(payload->impl_)));
     p->init();
index 79c32fa..163b931 100644 (file)
@@ -50,9 +50,9 @@ prefix_ senf::Packet::Packet(Operation const & arg)
       parsed_(false), refcount_(1)
 {
     SATCOM_PKF_REFC_MSG("] Packet::Packet (" << this << "): refcount_ = 1\n");
-    // FIXME: This is not exception safe, if an exception is thrown in
-    // the derived class constuctor, the effects of this call must be
-    // undone which is not possible in a simple way.
+    /** \fixme This is not exception safe, if an exception is thrown in
+       the derived class constuctor, the effects of this call must be
+       undone which is not possible in a simple way. */
     arg(this);
 }
 
index 2511c8a..bcf5c5e 100644 (file)
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// TODO: Implement assign() method akin to reinterpret(). However,
-// instead of using the data already present, assign() will replace
-// the date of the current packet with the given Packet.
+/** \file
+    \brief Main packet interface
 
-// TODO: Implement wrapping-constructor. Somehow we want to have a
-// constructor, which allows creating a chain of packet interpreters
-// with as little overhead as possible.
+    \todo Implement assign() method akin to reinterpret(). However,
+    instead of using the data already present, assign() will replace
+    the date of the current packet with the given Packet.
 
-// TODO: Document the additional concrete Packet facade requirements
-// explicitly and not only within the Parser requirements (check(),
-// bytes() and min_bytes() members ...)
+    \todo Implement wrapping-constructor. Somehow we want to have a
+    constructor, which allows creating a chain of packet interpreters
+    with as little overhead as possible.
 
-// TODO: Implement special container replacing vector which manages
-// some headroom to allow efficient insertion of elements at the
-// beginning. This really is just another type of deque
-// implementation.
+    \todo Document the additional concrete Packet facade requirements
+    explicitly and not only within the Parser requirements (check(),
+    bytes() and min_bytes() members ...)
 
-/** \file
-    \brief Main packet interface
+    \todo Implement special container replacing vector which manages
+    some headroom to allow efficient insertion of elements at the
+    beginning. This really is just another type of deque
+    implementation.
  */
 
 #ifndef HH_Packet_
@@ -76,7 +76,7 @@ namespace senf {
         counted smart pointer, so resource management is quasi
         automatic.
 
-        \image html "../../structure.png" Overview
+        \image html structure.png Overview
         
         Internally, every Packet references a PacketImpl instance which
         manages the raw packet data and the interpreter list. This raw
@@ -260,6 +260,8 @@ namespace senf {
         intrusive_ptr is only the size of an ordinary pointer, a
         smart_ptr has the size of two pointers).
 
+        \fixme Make all data mutators protected
+
         \nosubgrouping
       */
     class Packet : boost::noncopyable
@@ -395,8 +397,8 @@ namespace senf {
             OtherPacket. 
 
             \attention This invalidates the packet instance \e
-            this</b>. You must ensure, not to use the Packet instance
-            any further after this call
+            this. You must ensure, not to use the Packet instance any
+            further after this call
 
             \return smart pointer to a \e new packet facade
             \throws TruncatedPacketException there is not enough data
@@ -439,8 +441,6 @@ namespace senf {
 
         // Modifying the raw packet data
 
-        // FIXME: Make all data mutators protected
-
         typedef enum { AUTO, BEFORE, INSIDE, OUTSIDE, AFTER } Whence;
 
         /** \brief insert single byte \a v before pos
index 96370a1..49c086e 100644 (file)
@@ -20,7 +20,6 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// TODO: Add parameterless create() method
 
 #ifndef HH_PacketRegistryImpl_
 #define HH_PacketRegistryImpl_ 1
@@ -79,17 +78,20 @@ namespace senf {
         constructor during global construction time.
 
         The PacketRegistry's purpose is mostly to assist in
-        implementing the \v v_nextInterpreter() member of packet
+        implementing the v_nextInterpreter() member of packet
         facades. This is further supported by the PacketRegistryMixin
         class.
+
+       \todo Add parameterless create() method
      */
     template <class Tag>
     class PacketRegistry
     {
     public:
-        // TODO: This fails to work within a library since the linker will
-        // remove all unused object files ...
         /** \brief Statically register a packet type in a PacketRegistry
+
+           \fixme This fails to work within a library since the linker will
+           remove all unused object files ...
          */
         template <class OtherPacket>
         struct RegistrationProxy
index 297f2c4..53e3d8a 100644 (file)
@@ -82,7 +82,7 @@ prefix_ void
 senf::Parse_ListS_wrapper<Parser,Sentinel,Container>::insert(iterator pos,
                                                                     Value const & t)
 {
-    // FIXME: What, if pos == end() / default constructed iterator ?
+    /** \fixme What, if pos == end() / default constructed iterator ? */
     size_type ix (pos.raw()-container_.begin());
     container_.insert(pos.raw(),t.bytes(),0);
     Parser(container_.begin()+ix).value(t);
index 51ad0be..b8368ab 100644 (file)
@@ -61,8 +61,9 @@ senf::Parse_Vector_wrapper<Parser,SizeParser,Container>::insert(iterator pos,
                                                                        InputIterator f,
                                                                        InputIterator l)
 {
-    // FIXME: This is HORRIBLY inefficient ... we need to specialize 
-    // for random_aPacketRegistry.ess and forward iterators, where we can count the distance
+    /** \fixme This might be horribly inefficient ... we need to
+       specialize for random_access and forward iterators, where we
+       can count the distance */
 
     size_type ix(pos.raw()-container_.begin());
     for (;f!=l;++f) {
index f0e410a..916da23 100644 (file)
@@ -40,7 +40,7 @@
 
 BOOST_AUTO_UNIT_TEST(parserBase_inherited)
 {
-    // TODO: Implement
+    /** \todo Implement */
 }
 
 namespace {
index 3e168f6..f5705a4 100644 (file)
@@ -69,7 +69,7 @@ BOOST_AUTO_UNIT_TEST(rtcpPacket_parser)
     BOOST_CHECK_EQUAL(p_1.rr().socount(),        0x0dc8u     );
 
 
-    // TODO RTCP RR
+    /// \todo RTCP RR
     unsigned char data_2[] = { 
                              0x82, 0xc8, 0x00, 0x06, 
                              0xe5, 0x70, 0xaa, 0x18, 
@@ -201,7 +201,7 @@ BOOST_AUTO_UNIT_TEST(rtcpPacket_parser)
     BOOST_CHECK_EQUAL( j->DLSR(),     0x20212223u  );
 #endif
 
-    // TODO RTCP SDES
+    /// \todo RTCP SDES
 
     unsigned char data_4[] = { 
                              0x81, 0xca, 0x00, 0x04, 
@@ -225,7 +225,7 @@ BOOST_AUTO_UNIT_TEST(rtcpPacket_parser)
 #if 0
     Parse_RTCP_SDES::Parse_itemList::iterator j_4 (p_4.sdes().chunkVec().begin());
 
-// TODO  -> ask Stefan
+/// \todo ask Stefan
 
  // BOOST_CHECK_EQUAL( p_4.sdes().chunkList()[0].ssrc(), 0xe570aa18u);
  // BOOST_CHECK_EQUAL( p_4.sdes().chunkList()[0].itemList().size(), 0x01u);
index 3b38904..3d8d8a1 100644 (file)
@@ -13,8 +13,6 @@ env = SENFSCons.MakeEnvironment()
 env.Append(
    CPPPATH = [ '#' ],
    LIBS = [ 'iberty' ],
-   DOXYFILES = [ '#/doclib/doxy-header.html', '#/doclib/doxy-footer.html',
-                 '#/doclib/Doxyfile.global' ]
 )
 
 Export('env')
@@ -24,5 +22,10 @@ SConscript(glob.glob("*/SConscript"))
 SENFSCons.StandardTargets(env)
 SENFSCons.GlobalTargets(env)
 SENFSCons.Doxygen(env)
+SENFSCons.DoxyXRef(env,
+                   TYPES = ('bug','fixme','todo','idea'),
+                   HTML_HEADER = '#/doclib/doxy-header-overview.html',
+                   HTML_FOOTER = '#/doclib/doxy-footer.html')
 
-if not os.path.exists("Doxyfile.local") : Execute(Touch("Doxyfile.local"))
+if not env.GetOption('clean') and not os.path.exists("Doxyfile.local"):
+    Execute(Touch("Doxyfile.local"))
index 8fb80bf..39ea480 100644 (file)
@@ -2,7 +2,6 @@
 //
 // Copyright (C) 2006 
 
-// TODO: Move all not Handle dependent members to a ReadHandleBase class
 
 #ifndef HH_ReadHelper_
 #define HH_ReadHelper_ 1
 namespace senf {
 
 
+    /** \brief
+
+       \todo Move all not Handle dependent members to a ReadHandleBase class
+     */
     template <class Handle>
     class ReadHelper
        : public senf::intrusive_refcount
index 62a5dfe..01e33c8 100644 (file)
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// TODO: Implement signal handling
+/** \file
+
+    \idea Implement signal handling (See source for more discussion
+    about this) 
+
+    \idea Multithreading support: To support multithreading, the
+    static member Scheduler::instance() must return a thread-local
+    value (that is Scheduler::instance() must allocate one Scheduler
+    instance per thread)
+
+    \fixme Test2
+ */
+
 // Here a basic concept of how to add signal support to the scheduler:
 //
 // Every signal to be reported by the scheduler will be asigned a
 // scheduler must be blocked as soon as it is registered with the
 // scheduler.
 
-// TODO: Multithreading support
-// To support multithreading, the static member Scheduler::instance()
-// must return a thread-local value (that is Scheduler::instance()
-// must allocate one Scheduler instance per thread)
-
 // Definition of non-inline non-template functions
 
 #include "Scheduler.hh"
index a54bed8..819d70e 100644 (file)
@@ -20,9 +20,6 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// TODO: Fix EventId parameter (probably to int) to allow |-ing without casting ...
-
-
 /** \mainpage The SENF Scheduler library
 
  */
@@ -52,6 +49,9 @@ namespace senf {
         descriptiors with this class and pass callback functions to be
         called on input, output or error. This functions are specified
         using boost::function objects
+
+       \todo Fix EventId parameter (probably to int) to allow |-ing
+       without casting ...
       */
     class Scheduler
         : boost::noncopyable
index bb595ac..d8f5163 100644 (file)
@@ -59,8 +59,8 @@ prefix_ void senf::BSDSocketProtocol::linger(bool enable, unsigned timeout)
 prefix_ struct timeval senf::BSDSocketProtocol::timestamp()
     const
 {
-    // BUG: Check, why this fails with ENOFILE (!!!!) at least when
-    // called from a tcp socket. Further investigation necessary ...
+    /** \bug Check, why this fails with ENOFILE (!!!!) at least when
+       called from a tcp socket. Further investigation necessary ... */
     struct timeval tv;
     if (::ioctl(body().fd(), SIOCGSTAMP, &tv) < 0)
         throw SystemException(errno);
index 6eb705c..0260dbb 100644 (file)
 namespace senf {
 
 
-    // TODO: Should this be dependent on Read / WritePolicy ?
+    /** \brief
+
+       \todo Shouldn't this be dependent on Read / WritePolicy ?
+     */
     struct SocketBufferingPolicy : public BufferingPolicyBase
     {
         static unsigned rcvbuf(FileHandle handle);
index acd736b..0c6b61b 100644 (file)
@@ -43,7 +43,7 @@ prefix_ void senf::ClientSocketHandle<Policy>::read(std::string & buffer, unsign
     unsigned nread = available();
     if (limit>0 && nread>limit) 
        nread = limit;
-    // FIXME: This is not necessary correct and more or less a hack ...
+    /** \fixme This is not necessary correct and more or less a hack ... */
     buffer.assign(nread,0);
     unsigned rv = this->read(const_cast<char *>(buffer.data()),nread);
     if (rv < nread)
@@ -65,7 +65,7 @@ prefix_ void senf::ClientSocketHandle<Policy>::
 readfrom(std::string & buffer, typename Policy::AddressingPolicy::Address & from)
 {
     unsigned nread = available();
-    // FIXME: This is not necessary correct and more or less a hack ...
+    /** \fixme This is not necessary correct and more or less a hack ... */
     buffer.assign(nread,0);
     unsigned rv = this->readfrom(const_cast<char *>(buffer.data()), nread, from);
     if (rv < nread)
index a4280e8..1a120b7 100644 (file)
@@ -20,9 +20,6 @@
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// TODO: Move all not template-parameter dependent code into a
-// non-template base class
-
 #ifndef HH_ClientSocketHandle_
 #define HH_ClientSocketHandle_ 1
 
@@ -39,6 +36,9 @@ namespace senf {
     template <class Policy> class ServerSocketHandle;
 
     /** \brief
+       
+       \todo Move all not template-parameter dependent code into a
+       non-template base class
       */
     template <class Policy>
     class ClientSocketHandle
index d11f2ee..9a8c7e7 100644 (file)
 namespace senf {
 
     
-    /** \brief
+    /** \brief Basic file handle wrapper
+
+       senf::FileHandle provides a simple wrapper for arbitrary file handles. It exposes only a
+       minimal interface which does \e not include reading or writing (since some filehandles are
+       not readable or writable or only using special function calls like sendto).
+       
+       The FileHandle class provides handle/body handling and uses automatic reference
+       counting. The senf::FileHandle istance is very lightweight and should be used like a
+       built-in type.
+
+       \attention You should mostly pass around senf::FileHandle objects by \e value und not by
+       reference.
+
+       The FileHandle abstraction is only applicable to real filehandles. It is \e not possible to
+       wrap any provider or consumer into a filehandle like interface using this wrapper. The
+       wrapper will forward some calls directly to the underlying API without relying on virtual
+       methods. This allows important members to be inlined.
+
+       It is not possible to use the senf::FileHandle class directly since it does not have any
+       public constructor. The FileHandle class is however the baseclass of all handle classes of
+       the socket library.
+
+       \section filehandle_new Writing senf::FileHandle derived classes
+
+       To build a new FileHandle type you need to derive from senf::FileHandle. The derived class
+       will have to call the protocted FileHandle constructor passing a new senf::FileBody
+       instance. This instance may either be a simple senf::FileBody or a class derived from
+       senf::FileBody.
+       
+       \todo Add public default constructor to allow declaration of (empty) senf::FileHandle
+       variables.
      */
     class FileHandle
        : public SafeBool<FileHandle>
@@ -56,37 +86,54 @@ namespace senf {
 
         ///@}
         ///////////////////////////////////////////////////////////////////////////
-        
-        void close();
-        void terminate();
 
-        bool readable() const;
-        void waitReadable() const;
-        bool writeable() const;
-        void waitWriteable() const;
+        void close();                ///< Close filehandle
+                                    /**< \throws senf::SystemException */
+        void terminate();            ///< Close filehandle ignoring error conditions
 
-        bool blocking() const;
-        void blocking(bool status);
+        bool readable() const;       ///< Check, wether a read on the handle would not block
+                                    ///< (ignoring blocking state)
+        void waitReadable() const;   ///< Wait, until read on the handle would not block (ignoring
+                                    ///< blocking state)
+        bool writeable() const;      ///< Check, wether a write on the handle would not block
+                                    ///< (ignoring blocking state)
+        void waitWriteable() const;  ///< Wait, until a write on the handle would not block
+                                    ///< (ignoring blocking state)
 
-        bool eof() const;
-        bool valid() const;
+        bool blocking() const;       ///< Return current blocking state
+        void blocking(bool status);  ///< Set blocking state
 
-       bool boolean_test() const;
+        bool eof() const;            ///< Check EOF condition
+                                    /**< Depending on the socket type, this might never return \p
+                                       true */
+        bool valid() const;          ///< Check filehandle validity
+                                    /**< Any operation besides valid() will fail on an invalid
+                                       FileHandle */
 
-        int fd() const;
+       bool boolean_test() const;  ///< Short for valid() && ! eof()
+                                   /**< This is called when using a FileHandle instance in a boolen
+                                      context */
 
-        static FileHandle cast_static(FileHandle handle);
-        static FileHandle cast_dynamic(FileHandle handle);
+        int fd() const;             ///< Return the raw FileHandle
+
+        static FileHandle cast_static(FileHandle handle);  ///< \internal
+        static FileHandle cast_dynamic(FileHandle handle); ///< \internal
 
     protected:
         explicit FileHandle(std::auto_ptr<FileBody> body);
+                                   ///< create new FileHandle instance
+                                   /**< The FileHandle instance will take over ownership over the
+                                      given FileBody instance which must have been allocated using
+                                      \c new. To configure the FileHandle behavior, A derived class
+                                      may provide any class derived from FileBody here. */
 
-        FileBody & body();
-        FileBody const & body() const;
-        static FileBody & body(FileHandle & handle);
-        static FileBody const & body(FileHandle const & handle);
+        FileBody & body();          ///< Access body
+        FileBody const & body() const; ///< Access body in const context
+        static FileBody & body(FileHandle & handle); ///< Access body of another FileHandle instance
+        static FileBody const & body(FileHandle const & handle); ///< Access body of another
+                                   ///< FileHandle instance in const context  
 
-        void fd(int fd);
+        void fd(int fd);           ///< Set raw filehandle
 
     private:
         FileBody::ptr body_;
@@ -106,4 +153,5 @@ namespace senf {
 // Local Variables:
 // mode: c++
 // c-file-style: "senf"
+// fill-column: 100
 // End:
index 404f865..3081cc5 100644 (file)
@@ -38,7 +38,7 @@
 prefix_ senf::INet4Address::INet4Address(std::string host, unsigned port)
 {
     clear();
-    // TODO: gethostbyname einbauen
+    /** \todo  gethostbyname support */
     if (::inet_aton(host.c_str(), &addr_.sin_addr) == 0)
         throw InvalidINetAddressException();
     addr_.sin_port = htons(port);
@@ -61,7 +61,7 @@ prefix_ void senf::INet4Address::clear()
 prefix_ void senf::INet4Address::assignString(std::string address)
 {
     clear();
-    // TODO: gethostbyname einbauen
+    /** \todo  gethostbyname support */
     unsigned i = address.find(':');
     if (i == std::string::npos)
         throw InvalidINetAddressException();
index 7089881..81ac9f1 100644 (file)
@@ -53,7 +53,7 @@ prefix_ bool senf::INet4Address::operator==(INet4Address const & other)
 prefix_ std::string senf::INet4Address::host()
     const
 {
-    // FIXME: thread safety?
+    /** \fixme thread safety? */
     return std::string(::inet_ntoa(addr_.sin_addr));
 }
 
index 60a71a2..9b8b160 100644 (file)
 namespace senf {
 
 
-    // TODO: Implement real INet4Address datatype and 
-    // rename this one to INet4SockAddress ...
+    /** \brief
+       
+       \todo Implement real INet4Address datatype and 
+       rename this one to INet4SockAddress ... 
 
+       \todo Implement more complete interface
+     */
     class INet4Address
     {
     public:
@@ -55,8 +59,6 @@ namespace senf {
         std::string host() const;
         unsigned port() const;
 
-        // TODO: Interface
-
         void clear();
 
         struct sockaddr * sockaddr_p();
@@ -71,9 +73,12 @@ namespace senf {
 
     std::ostream & operator<<(std::ostream & os, INet4Address const & addr);
 
+    /** \brief
+
+       \todo Implement
+     */
     class INet6Address
     {
-        // TODO: Implement
     };
     
     struct INet4AddressingPolicy 
@@ -88,11 +93,13 @@ namespace senf {
         using GenericAddressingPolicy<INet4Address>::bind;
     };
 
+    /** \brief
+
+       \todo Implement
+     */
     struct INet6AddressingPolicy : public AddressingPolicyBase
     {
         typedef INet6Address Address;
-
-        // TODO: Implement
     };
 
     struct InvalidINetAddressException : public std::exception
index 5c6bc7a..79a514c 100644 (file)
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// TODO: what about OOB data? das OOB Data block receipt of normal data ?
+/** \file
 
-// TODO: Implement IP_RECVERR / MSG_ERRQUEUE. This should be placed
-// into an additional protocol class since IP_RECVERR is only valid
-// for SOCK_DGRAM (UDP) and not SOCK_STREAM (TCP) sockets
+    \todo what about OOB data? 
+
+    \todo Implement IP_RECVERR / MSG_ERRQUEUE. This should be placed
+    into an additional protocol class since IP_RECVERR is only valid
+    for SOCK_DGRAM (UDP) and not SOCK_STREAM (TCP) sockets
+ */
 
 #ifndef HH_INetProtocol_
 #define HH_INetProtocol_ 1
 namespace senf {
 
 
+    /** \brief
+
+       \todo Is it safe, not to allow setting the interface index on
+       add/drop? what does it do (especially if the local addres is
+       given ?). What have I been thinking here ???
+       
+       \todo move all multicast-methods into an extra
+       IPv4MulticastProtocol class
+     */
     class IPv4Protocol 
         : public virtual SocketProtocol
     {
@@ -54,13 +66,6 @@ namespace senf {
         bool mcLoop() const;
         void mcLoop(bool value) const;
 
-        // TODO: Is it safe, not to allow setting the interface
-        // index on add/drop? what does it do (especially if
-        // the local addres is given ?)
-       
-        // TODO: move all multicast-methods into an extra
-        // IPv4MulticastProtocol class
-
         void mcAddMembership(INet4Address const & mcAddr) const;
         void mcAddMembership(INet4Address const & mcAddr, INet4Address const & localAddr) const;
 
index f7dfdf9..228b474 100644 (file)
@@ -62,16 +62,16 @@ prefix_ unsigned senf::LLSocketAddress::protocol()
 prefix_ unsigned senf::LLSocketAddress::arptype()
     const
 {
-    // TODO: Check, wether this is returned in network or host byte
-    // order
+    /** \todo make sure, that the value really is in network byte
+       order */
     return ntohs(addr_.sll_hatype);
 }
 
 prefix_ unsigned senf::LLSocketAddress::pkttype()
     const
 {
-    // TODO: Check, wether this is returned in network or host byte
-    // order
+    /** \todo make sure, that the value really is in network byte
+       order */
     return ntohs(addr_.sll_pkttype);
 }
 
index 30e9f07..2721d36 100644 (file)
     information on how to implement that policy.
 
     <table class="senf">
-      <tr><th>SocketHandle member</th><th>Policy member</th></tr>
+      <tr><th>SocketHandle member</th>                  <th>Policy member</th></tr>
       <tr><td>senf::ClientSocketHandle::read</td>       <td>ReadPolicy::read (\ref senf::ReadPolicyBase)</td></tr>
       <tr><td>senf::ClientSocketHandle::readfrom</td>   <td>ReadPolicy::readfrom (\ref senf::ReadPolicyBase)</td></tr>
       <tr><td>senf::ClientSocketHandle::write</td>      <td>WritePolicy::write (\ref senf::WritePolicyBase)</td></tr>
index 59bbab0..b995959 100644 (file)
@@ -78,6 +78,8 @@ prefix_ bool senf::PacketProtocol::eof()
 prefix_ void senf::PacketProtocol::promisc(std::string interface, PromiscMode mode)
     const
 {
+    /** \bug There are some failures here ... need to investigate */
+
     // The interface is really stupid: as far as i understand, it is possible to 
     // enable PROMISC and ALLMULTI seperately, however PROMISC is really a superset
     // of ALLMULTI ... grmpf ... therefore we allways set/reset both to implement sane
index 4e8ca91..61d47a1 100644 (file)
@@ -55,8 +55,7 @@ BOOST_AUTO_UNIT_TEST(packetSocketHandle)
 
         // How am I supposed to test read and write .. grmpf ..
         
-        // BUG: There are some failures here ... need to investigate
-        /*
+       /*
         BOOST_CHECK_NO_THROW( sock.protocol().promisc(
                                   "lo",senf::PacketProtocol::Promiscuous) );
         BOOST_CHECK_NO_THROW( sock.protocol().promisc(
index e5203ae..644ad87 100644 (file)
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+/** \file
+
+    \todo ReadWritePolicy.test.cc 
+ */
+
 #ifndef HH_ReadWritePolicy_
 #define HH_ReadWritePolicy_ 1
 
@@ -31,7 +36,6 @@
 //#include "ReadWritePolicy.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
 
-// TODO: ReadWritePolicy.test.cc ...
 
 struct sockaddr;
 
index 1400d35..3f8a0ce 100644 (file)
@@ -99,14 +99,14 @@ prefix_ bool senf::detail::StateMapOrdering::operator()(std::string a1, std::str
             return false;
         if (contains(i2,i2_end,'.'))
             // the longer string is a sub-'directory' of the shorter
-           // FIXME: shouldn't this be *i2 == '.' ?
+           /** \fixme shouldn't this be *i2 == '.' ? */
             return true;
         return *i1 < *i2;
     }
     else if (i2 == i2_end) { // && i1 != i1_end
         if (contains(i1,i1_end,'.'))
             // the longer string is a sub-'directory' of the shorter
-           // FIXME: shouldn't this be *i1 == '.' ?
+           /** \fixme shouldn't this be *i1 == '.' ? */
             return false;
         return *i1 < *i2;
     }
index 9c1fd1c..7304ff1 100644 (file)
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// TODO: Create a SocketHandleBase class and move some non-Policy
-// dependent code there
-
-
 #ifndef HH_SocketHandle_
 #define HH_SocketHandle_ 1
 
@@ -41,7 +37,10 @@ namespace senf {
 
 
     /** \brief
-      */
+
+       \todo Create a SocketHandleBase class and move some non-Policy
+       dependent code there
+     */
     template <class SocketPolicy>
     class SocketHandle
         : public FileHandle
index 008716e..fe42ee8 100644 (file)
@@ -25,7 +25,7 @@
 
 // Custom includes
 #include <boost/utility.hpp>
-// FIXME: this is really bad. The includes and predefs should be restructured
+/** \fixme this is not nice. The includes and predefs should be restructured */
 #include "SocketHandle.ih"
 
 //#include "SocketProtocol.mpp"
index 0181981..b8354ca 100644 (file)
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// TODO: Implement possibly non-blocking connect and SO_ERROR in the
-// protocol interface
+/** \file
+
+    \todo Implement possibly non-blocking connect and SO_ERROR in the
+    protocol interface
+ */
 
 #ifndef HH_TCPSocketHandle_
 #define HH_TCPSocketHandle_ 1
@@ -86,7 +89,7 @@ namespace senf {
           public BSDSocketProtocol,
           public AddressableBSDSocketProtocol
     {
-        // TODO: Implement
+        /** \todo Implement */
     };
 
     typedef ProtocolClientSocketHandle<TCPv6SocketProtocol> TCPv6ClientSocketHandle;
index 31a0c0f..5b9b918 100644 (file)
@@ -3,10 +3,11 @@ INPUT                  = .
 FILE_PATTERNS          = *.c *.cc *.cci *.ct *.cti *.h *.hh *.ih *.mmc *.dox
 EXCLUDE_PATTERNS       = *.test.cc .*
 IMAGE_PATH             = .
-HTML_HEADER            = ../doclib/doxy-header.html
-HTML_FOOTER            = ../doclib/doxy-footer.html
 
-REPEAT_BRIEF           = NO
+ALIASES                = "fixme=\xrefitem fixme \"Fixme\" \"Fixmes\"" \
+                        "idea=\xrefitem idea \"Idea\" \"Ideas\""
+REPEAT_BRIEF           = YES
+ALWAYS_DETAILED_SEC    = YES
 MULTILINE_CPP_IS_BRIEF = YES
 DETAILS_AT_TOP         = YES
 BUILTIN_STL_SUPPORT    = YES
@@ -15,16 +16,21 @@ EXTRACT_PRIVATE        = YES
 EXTRACT_STATIC         = YES
 INTERNAL_DOCS          = YES
 SOURCE_BROWSER         = YES
+STRIP_CODE_COMMENTS    = NO
 ALPHABETICAL_INDEX     = YES
 COLS_IN_ALPHA_INDEX    = 3
-GENERATE_LATEX         = NO
-GENERATE_MAN           = NO
 
 MACRO_EXPANSION        = YES
 EXPAND_ONLY_PREDEF     = YES
 PREDEFINED             = DOXYGEN
 EXPAND_AS_DEFINED      = prefix_
 
+HTML_HEADER            = ../doclib/doxy-header.html
+HTML_FOOTER            = ../doclib/doxy-footer.html
+GENERATE_LATEX         = NO
+GENERATE_MAN           = NO
+GENERATE_XML           = YES
+
 HAVE_DOT               = YES
 CLASS_GRAPH            = YES
 COLLABORATION_GRAPH    = YES
index 8a72a57..19e5b11 100644 (file)
@@ -186,3 +186,32 @@ table.senf th {
        text-align: center;
        font-weight: bold;
 }
+
+dl.bug { 
+       border: 1px solid #EE0000;
+       border-left-width: 4px;
+       background-color: #FFDDDD;
+       padding: 0 10px;
+}
+
+dl.fixme { 
+       border: 1px solid #EEEE00;
+       border-left-width: 4px;
+       background-color: #FFFFDD;
+       padding: 0 10px;
+}
+
+dl.todo { 
+       border: 1px solid #00AA00;
+       border-left-width: 4px;
+       background-color: #DDFFDD;
+       padding: 0 10px;
+}
+
+dl.idea { 
+       border: 1px solid #AAAAAA;
+       border-left-width: 4px;
+       background-color: #EEEEEE;
+       padding: 0 10px;
+}
+
index f379f91..705e22a 100644 (file)
@@ -40,7 +40,7 @@ def DoxyfileParse_(file, data):
       lex = shlex.shlex(instream=open(file), posix=True)
       lex.wordchars += "*+./-:@~"
       lex.whitespace = lex.whitespace.replace("\n", "")
-      lex.escape = ""
+      lex.escape = "\\"
 
       lineno = lex.lineno
       token = lex.get_token()
@@ -161,7 +161,13 @@ def DoxyEmitter(source, target, env):
    data = DoxyfileParse(source[0].abspath)
 
    targets = []
-   out_dir = data.get("OUTPUT_DIRECTORY", ".")
+   if data.has_key("OUTPUT_DIRECTORY"):
+      out_dir = data["OUTPUT_DIRECTORY"]
+      dir = env.Dir( os.path.join(source[0].dir.abspath, out_dir) )
+      dir.sources = source
+      targets.append(dir)
+   else:
+      out_dir = '.'
 
    # add our output locations
    for (k, v) in output_formats.iteritems():
@@ -169,13 +175,16 @@ def DoxyEmitter(source, target, env):
          # 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(str(source[0].dir), out_dir, data.get(k + "_OUTPUT", v[1])) )
-         node = env.File( os.path.join(str(dir), ".stamp" ) )
-         env.Clean(node, dir)
-         targets.append( node )
+         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, ".stamp" ) )
+         targets.append(node)
+         targets.append(dir)
 
    if data.has_key("GENERATE_TAGFILE"):
-      targets.append(env.File( os.path.join(str(source[0].dir), data["GENERATE_TAGFILE"]) ))
+      targets.append(env.File( os.path.join(source[0].dir.abspath, data["GENERATE_TAGFILE"]) ))
 
    # don't clobber targets
    for node in targets:
index 7308c0e..3460414 100644 (file)
@@ -1,4 +1,5 @@
-import os.path, SCons.Options, SCons.Environment, SCons.Script.SConscript, glob
+import os.path, glob
+import  SCons.Options, SCons.Environment, SCons.Script.SConscript, SCons.Node.FS, SCons.Defaults
 
 SCONS_TOOLS = [
     "Doxygen",
@@ -117,12 +118,7 @@ def StandardTargets(env):
     env.Depends(all, '.')
 
 def GlobalTargets(env):
-    command = "find -name .svn -prune -o \( -name '*.hh' -o -name '*.ih' -o -name '*.cc' -o -name '*.cci' -o -name '*.ct' -o -name '*.cti' -o -name '*.mpp' \) -print " \
-              "| xargs -r awk -F '//' '/%s/{print ARGV[ARGIND] \":\" FNR \":\" $2}' > $TARGET"
-    env.AlwaysBuild(env.Command('TODOS',None,[ command % 'TODO' ]))
-    env.AlwaysBuild(env.Command('FIXMES',None,[ command % ' FIXME' ]))
-    env.AlwaysBuild(env.Command('BUGS',None,[ command % 'BUG' ] ))
-    env.Alias('status',[ 'TODOS', 'FIXMES', 'BUGS' ])
+    pass
 
 def LibPath(lib): return '$LOCALLIBDIR/lib%s.a' % lib
     
@@ -152,20 +148,88 @@ def Objects(env, sources, testSources = None, LIBS = []):
 
 def Doxygen(env, doxyfile = "Doxyfile", extra_sources = []):
     docs = env.Doxygen(doxyfile)
-    # The last target is the (optional) tagfile
-    if os.path.basename(str(docs[-1])) != '.stamp':
+    for doc in docs:
+        if isinstance(doc,SCons.Node.FS.Dir): continue
+        if os.path.basename(str(doc)) == '.stamp' : continue # file stamp
+        # otherwise it must be the tag file
+        break
+    else:
+        doc = None
+    if doc:
         # Postprocess the tag file to remove the (broken) namespace
         # references
         env.AddPostAction(
-            docs,
-            env.Action([ "xsltproc -o ${TARGETS[-1]}.temp %s ${TARGETS[-1]}"
+            doc,
+            env.Action([ "xsltproc -o TARGET.temp %s TARGET"
                          % os.path.join(basedir,"tagmunge.xsl"),
-                         "mv ${TARGETS[-1]}.temp ${TARGETS[-1]}" ]))
-        env.Clean(docs[-1],"$TARGET.temp")
+                         "mv TARGET.temp TARGET" ]))
+        env.Clean(doc,"$TARGET.temp")
     env.Depends(docs,extra_sources)
-    env.Alias('all_docs', *docs)
+    for doc in docs :
+        env.Alias('all_docs', doc)
+        env.Clean('all_docs', doc)
+        env.Clean('all', doc)
     return docs
 
+def DoxyXRef(env, 
+             TYPES = ('bug','todo'),
+             HTML_HEADER = None, HTML_FOOTER = None,
+             TITLE = "Cross-reference of action points"):
+    # Hmm .. this looks a bit scary :-) ...
+    xrefis = []
+
+    # This iterates over all doc targets. These are all .stamp and .tag files
+    for node in env.Alias('all_docs')[0].sources:
+        # We are only interested in the xml targets. This is Doxyfile dependent :-(
+        if node.abspath.endswith('/xml/.stamp'):
+            # This is the list of xref categories
+            for type in TYPES:
+                # Here we construct the pathname of the xml file for the category
+                xref = os.path.join(node.dir.abspath,type+'.xml')
+                # And now apply the xrefxtract.xslt tempalte to it. However, we must
+                # only call xsltproc if the source xml file is not empty (therefore the
+                # 'test')
+                xrefi = env.Command(xref+'i', [ xref, '%s/xrefxtract.xslt' % basedir, node ],
+                                    [ "test -s $SOURCE && xsltproc -o $TARGET" +
+                                      " --stringparam module $MODULE" + 
+                                      " --stringparam type $TYPE" +
+                                      " ${SOURCES[1]} $SOURCE || touch $TARGET" ],
+                                    MODULE = node.dir.dir.dir.name,
+                                    TYPE = type)
+                # If the xref xml file does not exist we create it here as an empty
+                # file since doxygen will only create it if it is non-empty.
+                if not env.GetOption('clean') and not os.path.exists(xref):
+                    if not os.path.exists(node.dir.abspath):
+                        env.Execute(SCons.Defaults.Mkdir(node.dir.abspath))
+                    env.Execute(SCons.Defaults.Touch(xref))
+                xrefis.append(xrefi)
+
+    # And here we can now simply combine all the xrefi files
+    xref = env.Command("doc/html/xref.xml", xrefis,
+                       [ "echo -e '<?xml version=\"1.0\"?>\\n<xref>' >$TARGET",
+                         "cat $SOURCES >> $TARGET",
+                         "echo '</xref>' >>$TARGET" ])
+
+    # Lastly we create the html file
+    sources = [ xref, "%s/xrefhtml.xslt" % basedir ]
+    if HTML_HEADER : sources.append(HTML_HEADER)
+    if HTML_FOOTER : sources.append(HTML_FOOTER)
+
+    commands = []
+    if HTML_HEADER:
+        commands.append(
+            "sed -e 's/\\$$title/$TITLE/g' -e 's/\\$$projectname/Overview/g' ${SOURCES[2]} > $TARGET")
+    commands.append("xsltproc --stringparam title '$TITLE' ${SOURCES[1]} $SOURCE >> $TARGET")
+    if HTML_FOOTER:
+        commands.append(
+            "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)
+
+    env.Alias('all_docs',xref)
+    return xref
+
 def Lib(env, library, sources, testSources = None, LIBS = []):
     objects = Objects(env,sources,testSources,LIBS=LIBS)
     lib = None
diff --git a/senfscons/functions.xsl b/senfscons/functions.xsl
new file mode 100644 (file)
index 0000000..f8e22f4
--- /dev/null
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>\r
+<xsl:stylesheet \r
+  version="1.0"\r
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
+  xmlns:str="http://exslt.org/strings"\r
+  xmlns:func="http://exslt.org/functions"\r
+  xmlns:exsl="http://exslt.org/common"\r
+  extension-element-prefixes="str exsl func">\r
+  \r
+  <!-- ==================================================================== -->\r
+  <!-- node-set str:replace(string,object,object)                           -->\r
+  <!--                                                                      -->\r
+  <!-- This implements the EXSLT str:replace function                       -->\r
+  <!--                                                                      -->\r
+  <!-- Copyright Jeni Tenison                                               -->\r
+  <!-- ==================================================================== -->\r
+\r
+  <func:function name="str:replace">\r
+     <xsl:param name="string" select="''" />\r
+     <xsl:param name="search" select="/.." />\r
+     <xsl:param name="replace" select="/.." />\r
+     <xsl:choose>\r
+        <xsl:when test="not($string)">\r
+          <func:result select="/.." />\r
+        </xsl:when>\r
+        <xsl:when test="function-available('exsl:node-set')">\r
+           <!-- this converts the search and replace arguments to node sets\r
+                if they are one of the other XPath types -->\r
+           <xsl:variable name="search-nodes-rtf">\r
+             <xsl:copy-of select="$search" />\r
+           </xsl:variable>\r
+           <xsl:variable name="replace-nodes-rtf">\r
+             <xsl:copy-of select="$replace" />\r
+           </xsl:variable>\r
+           <xsl:variable name="replacements-rtf">\r
+              <xsl:for-each select="exsl:node-set($search-nodes-rtf)/node()">\r
+                 <xsl:variable name="pos" select="position()" />\r
+                 <replace search="{.}">\r
+                    <xsl:copy-of select="exsl:node-set($replace-nodes-rtf)/node()[$pos]" />\r
+                 </replace>\r
+              </xsl:for-each>\r
+           </xsl:variable>\r
+           <xsl:variable name="sorted-replacements-rtf">\r
+              <xsl:for-each select="exsl:node-set($replacements-rtf)/replace">\r
+                 <xsl:sort select="string-length(@search)" data-type="number" order="descending" />\r
+                 <xsl:copy-of select="." />\r
+              </xsl:for-each>\r
+           </xsl:variable>\r
+           <xsl:variable name="result">\r
+             <xsl:choose>\r
+                <xsl:when test="not($search)">\r
+                  <xsl:value-of select="$string" />\r
+                </xsl:when>\r
+               <xsl:otherwise>\r
+                 <xsl:call-template name="str:_replace">\r
+                    <xsl:with-param name="string" select="$string" />\r
+                    <xsl:with-param name="replacements" select="exsl:node-set($sorted-replacements-rtf)/replace" />\r
+                 </xsl:call-template>\r
+               </xsl:otherwise>\r
+             </xsl:choose>\r
+           </xsl:variable>\r
+           <func:result select="exsl:node-set($result)/node()" />\r
+        </xsl:when>\r
+        <xsl:otherwise>\r
+           <xsl:message terminate="yes">\r
+              ERROR: function implementation of str:replace() relies on exsl:node-set().\r
+           </xsl:message>\r
+        </xsl:otherwise>\r
+     </xsl:choose>\r
+  </func:function>\r
+\r
+  <xsl:template name="str:_replace">\r
+    <xsl:param name="string" select="''" />\r
+    <xsl:param name="replacements" select="/.." />\r
+    <xsl:choose>\r
+      <xsl:when test="not($string)" />\r
+      <xsl:when test="not($replacements)">\r
+        <xsl:value-of select="$string" />\r
+      </xsl:when>\r
+      <xsl:otherwise>\r
+        <xsl:variable name="replacement" select="$replacements[1]" />\r
+        <xsl:variable name="search" select="$replacement/@search" />\r
+        <xsl:choose>\r
+          <xsl:when test="not(string($search))">\r
+            <xsl:value-of select="substring($string, 1, 1)" />\r
+            <xsl:copy-of select="$replacement/node()" />\r
+            <xsl:call-template name="str:_replace">\r
+              <xsl:with-param name="string" select="substring($string, 2)" />\r
+              <xsl:with-param name="replacements" select="$replacements" />\r
+            </xsl:call-template>\r
+          </xsl:when>\r
+          <xsl:when test="contains($string, $search)">\r
+            <xsl:call-template name="str:_replace">\r
+              <xsl:with-param name="string" select="substring-before($string, $search)" />\r
+              <xsl:with-param name="replacements" select="$replacements[position() > 1]" />\r
+            </xsl:call-template>      \r
+            <xsl:copy-of select="$replacement/node()" />\r
+            <xsl:call-template name="str:_replace">\r
+              <xsl:with-param name="string" select="substring-after($string, $search)" />\r
+              <xsl:with-param name="replacements" select="$replacements" />\r
+            </xsl:call-template>\r
+          </xsl:when>\r
+          <xsl:otherwise>\r
+            <xsl:call-template name="str:_replace">\r
+              <xsl:with-param name="string" select="$string" />\r
+              <xsl:with-param name="replacements" select="$replacements[position() > 1]" />\r
+            </xsl:call-template>\r
+          </xsl:otherwise>\r
+        </xsl:choose>\r
+      </xsl:otherwise>\r
+    </xsl:choose>\r
+  </xsl:template>\r
+\r
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/senfscons/xrefhtml.xslt b/senfscons/xrefhtml.xslt
new file mode 100644 (file)
index 0000000..3d4dcbc
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<xsl:stylesheet\r
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
+  xmlns:fn="http://senf.berlios.de/xml/Extensions"\r
+  xmlns:exsl="http://exslt.org/common"\r
+  xmlns:str="http://exslt.org/strings"\r
+  extension-element-prefixes="str fn exsl"\r
+  version="1.0">\r
+\r
+  <xsl:include href="functions.xsl"/>\r
+\r
+  <xsl:output method="html"/>\r
+  <xsl:strip-space elements="*"/>\r
+  <xsl:param name="title" select="''"/>\r
+\r
+  <xsl:template match="/">\r
+    <h1><xsl:value-of select="$title"/></h1>\r
+    <xsl:apply-templates/>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="xreflist">\r
+    <xsl:if test="string(preceding::xreflist[1]/@module)!=string(@module)">\r
+      <xsl:if test="preceding::xreflist">\r
+        <hr/>\r
+      </xsl:if>\r
+      <h2>The <xsl:element name="a">\r
+        <xsl:attribute name="href">../../<xsl:value-of select="@module"/>/doc/html/index.html</xsl:attribute>\r
+        <xsl:value-of select="@module"/>\r
+      </xsl:element> module</h2>\r
+    </xsl:if>\r
+    <xsl:element name="dl">\r
+      <xsl:attribute name="class"><xsl:value-of select="@type"/></xsl:attribute>\r
+      <dt><h3><xsl:value-of select="translate(@type,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/> items</h3></dt>\r
+      <xsl:apply-templates/>\r
+    </xsl:element>\r
+  </xsl:template>\r
+\r
+  <fn:nsquote>\r
+    <fn:replacement>\r
+      <fn:match>_1_1</fn:match>\r
+      <fn:replace>_2</fn:replace>\r
+    </fn:replacement>\r
+  </fn:nsquote>\r
+\r
+  <xsl:variable name="nsquote" select="document('')//fn:nsquote/fn:replacement"/>\r
+  \r
+  <xsl:template match="compound">\r
+    <!-- Yuck ... I HATE this .. why doesn't xsltproc support XPath 2.0 ... grmpf -->\r
+    <xsl:variable name="quoted">\r
+      <xsl:apply-templates select="str:replace(@id,$nsquote/fn:match,$nsquote/fn:replace)"/>\r
+    </xsl:variable>\r
+    <xsl:variable name="anchor" select="substring-after($quoted,'_1')"/>\r
+    <xsl:variable name="file">\r
+      <xsl:apply-templates select="str:replace(substring($quoted,1,string-length($quoted) - number(boolean($anchor))*2 - string-length($anchor)),$nsquote/fn:replace,$nsquote/fn:match)"/>\r
+    </xsl:variable>\r
+    <xsl:variable name="sep" select="substring('#',2-number(boolean($anchor)))"/>\r
+    <dt>\r
+      <xsl:element name="a">\r
+        <xsl:attribute name="href">../../<xsl:value-of select="ancestor::xreflist/@module"/>/doc/html/<xsl:value-of select="$file"/>.html<xsl:value-of select="$sep"/><xsl:value-of select="$anchor"/></xsl:attribute>\r
+        <b><xsl:value-of select="@name"/></b>\r
+      </xsl:element>\r
+    </dt>\r
+    <dd>\r
+      <xsl:apply-templates/>\r
+    </dd>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="item">\r
+    <p><xsl:apply-templates/></p>\r
+  </xsl:template>\r
+\r
+</xsl:stylesheet>\r
diff --git a/senfscons/xrefxtract.xslt b/senfscons/xrefxtract.xslt
new file mode 100644 (file)
index 0000000..e09ff4f
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
+                version="1.0">\r
+\r
+  <xsl:output method="xml" omit-xml-declaration="yes"/>\r
+  <xsl:param name="module" select="''"/>\r
+  <xsl:param name="type" select="'todo'"/>\r
+  <xsl:strip-space elements="*"/>\r
+\r
+  <xsl:template match="variablelist">\r
+    <xsl:if test="string(preceding::variablelist[1]/varlistentry/term/ref/@refid)!=string(varlistentry/term/ref/@refid)">\r
+      <xsl:element name="compound">\r
+        <xsl:attribute name="id">\r
+          <xsl:value-of select="varlistentry/term/ref/@refid"/>\r
+        </xsl:attribute>\r
+        <xsl:attribute name="name">\r
+          <xsl:value-of select="string(varlistentry/term)"/>\r
+        </xsl:attribute>\r
+        <xsl:text>&#xA;</xsl:text>\r
+        <xsl:variable name="curid" select="varlistentry/term/ref/@refid"/>\r
+        <xsl:apply-templates \r
+          select="//variablelist[varlistentry/term/ref/@refid=$curid]"\r
+          mode="inlist"/>\r
+      </xsl:element>\r
+      <xsl:text>&#xA;</xsl:text>\r
+    </xsl:if>\r
+  </xsl:template>\r
+  \r
+  <xsl:template match="variablelist" mode="inlist">\r
+    <item>\r
+      <xsl:value-of select="string(listitem)"/>\r
+    </item>\r
+    <xsl:text>&#xA;</xsl:text>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="/">\r
+    <xsl:element name="xreflist">\r
+      <xsl:attribute name="type">\r
+        <xsl:value-of select="$type"/>\r
+      </xsl:attribute>\r
+      <xsl:attribute name="module">\r
+        <xsl:value-of select="$module"/>\r
+      </xsl:attribute>\r
+      <xsl:text>&#xA;</xsl:text>\r
+      <xsl:apply-templates/>\r
+    </xsl:element>\r
+  </xsl:template>\r
+\r
+  <xsl:template match="compoundname"/>\r
+  <xsl:template match="title"/>\r
+  <xsl:template match="anchor"/>\r
+\r
+</xsl:stylesheet>\r