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
\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>
*/
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());
}
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());
}
prefix_ void senf::GenericPacket<HEADER,TRAILER>::v_dump(std::ostream & os)
const
{
- // TODO: implement v_dump()
+ /// \todo implement v_dump()
}
///////////////////////////////ct.e////////////////////////////////////////
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_);
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);
}
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");
}
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();
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);
}
// 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_
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
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
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
// 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
// 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
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
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);
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) {
BOOST_AUTO_UNIT_TEST(parserBase_inherited)
{
- // TODO: Implement
+ /** \todo Implement */
}
namespace {
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,
BOOST_CHECK_EQUAL( j->DLSR(), 0x20212223u );
#endif
- // TODO RTCP SDES
+ /// \todo RTCP SDES
unsigned char data_4[] = {
0x81, 0xca, 0x00, 0x04,
#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);
env.Append(
CPPPATH = [ '#' ],
LIBS = [ 'iberty' ],
- DOXYFILES = [ '#/doclib/doxy-header.html', '#/doclib/doxy-footer.html',
- '#/doclib/Doxyfile.global' ]
)
Export('env')
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"))
//
// 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
// 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"
// 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
*/
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
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);
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);
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)
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)
// 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
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
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>
///@}
///////////////////////////////////////////////////////////////////////////
-
- 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_;
// Local Variables:
// mode: c++
// c-file-style: "senf"
+// fill-column: 100
// End:
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);
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();
prefix_ std::string senf::INet4Address::host()
const
{
- // FIXME: thread safety?
+ /** \fixme thread safety? */
return std::string(::inet_ntoa(addr_.sin_addr));
}
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:
std::string host() const;
unsigned port() const;
- // TODO: Interface
-
void clear();
struct sockaddr * sockaddr_p();
std::ostream & operator<<(std::ostream & os, INet4Address const & addr);
+ /** \brief
+
+ \todo Implement
+ */
class INet6Address
{
- // TODO: Implement
};
struct INet4AddressingPolicy
using GenericAddressingPolicy<INet4Address>::bind;
};
+ /** \brief
+
+ \todo Implement
+ */
struct INet6AddressingPolicy : public AddressingPolicyBase
{
typedef INet6Address Address;
-
- // TODO: Implement
};
struct InvalidINetAddressException : public std::exception
// 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
{
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;
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);
}
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>
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
// 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(
// 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
//#include "ReadWritePolicy.mpp"
///////////////////////////////hh.p////////////////////////////////////////
-// TODO: ReadWritePolicy.test.cc ...
struct sockaddr;
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;
}
// 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
/** \brief
- */
+
+ \todo Create a SocketHandleBase class and move some non-Policy
+ dependent code there
+ */
template <class SocketPolicy>
class SocketHandle
: public FileHandle
// 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"
// 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
public BSDSocketProtocol,
public AddressableBSDSocketProtocol
{
- // TODO: Implement
+ /** \todo Implement */
};
typedef ProtocolClientSocketHandle<TCPv6SocketProtocol> TCPv6ClientSocketHandle;
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
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
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;
+}
+
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()
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():
# 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:
-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",
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
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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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>
</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>
</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>
</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>
</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