diff --git a/Scheduler/SConfig b/SConfig similarity index 100% rename from Scheduler/SConfig rename to SConfig diff --git a/SConstruct b/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..4b95deca49c35f00c85d27ed745d861158208687 --- /dev/null +++ b/SConstruct @@ -0,0 +1,25 @@ +import sys, os, os.path, glob +satscons = os.getcwd() +while satscons!='/' and not os.path.isdir(os.path.join(satscons,"satscons")): satscons = os.path.dirname(satscons) +if satscons=='/': print "satscons directory not found"; Exit(1) +satscons = os.path.join(satscons,"satscons") +sys.path.append(satscons) +import SatSCons + +########################################################################### + +SatSCons.UseBoost(); +SatSCons.UseSTLPort(); +SatSCons.UseDoxygen(); +env = SatSCons.MakeEnvironment(); + +env.Append( + CPPPATH = [ '#..', '#' ] +) + +Export('env satscons') + +SConscript(glob.glob("*/SConscript")) + +SatSCons.StandardTargets(env) +SatSCons.AllTests(env) diff --git a/Scheduler/SConscript b/Scheduler/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..7246732b8527501748f2b00ede98b521b798ad49 --- /dev/null +++ b/Scheduler/SConscript @@ -0,0 +1,11 @@ +Import('env satscons') +import sys +sys.path.append(satscons) +import SatSCons + +########################################################################### + +SatSCons.StandardLib(env, + library = 'Scheduler', + sources = SatSCons.GlobSources(), + LIBS = [ '$LIB_Utils' ]) diff --git a/Scheduler/Scheduler.cc b/Scheduler/Scheduler.cc new file mode 100644 index 0000000000000000000000000000000000000000..71cfb3b981bfa92c5343480c74d20e39c2b4b7db --- /dev/null +++ b/Scheduler/Scheduler.cc @@ -0,0 +1,116 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// Definition of non-inline non-template functions + +#include "Scheduler.hh" +//#include "Scheduler.ih" + +// Custom includes +#include <errno.h> +#include <sys/epoll.h> +#include "SatLib/Utils/Exception.hh" + +static const int EPollInitialSize = 16; + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +prefix_ satcom::lib::Scheduler::Scheduler & satcom::lib::Scheduler::instance() +{ + static Scheduler instance; + return instance; +} + +prefix_ satcom::lib::Scheduler::Scheduler() + : epollFd_(epoll_create(EPollInitialSize)) +{ + if (epollFd_<0) + throw SystemException(errno); +} + +prefix_ void satcom::lib::Scheduler::set(int fd, Callback const & cb, EventId eventMask) +{ + FdTable::iterator i (fdTable_.find(fd)); + int action (EPOLL_CTL_MOD); + if (i == fdTable_.end()) { + action = EPOLL_CTL_ADD; + i = fdTable_.insert(std::make_pair(fd, EventSpec())).first; + } + + if (eventMask | EV_READ) i->second.cb_read = cb; + if (eventMask | EV_WRITE) i->second.cb_write = cb; + if (eventMask | EV_HUP) i->second.cb_hup = cb; + if (eventMask | EV_ERR) i->second.cb_err = cb; + + epoll_event ev; + memset(&ev,0,sizeof(ev)); + ev.events = i->second.epollMask(); + + if (epoll_ctl(epollFd_, action, fd, &ev)<0) + throw SystemException(errno); +} + +prefix_ void satcom::lib::Scheduler::unset(int fd, EventId eventMask) +{ + FdTable::iterator i (fdTable_.find(fd)); + if (i == fdTable_.end()) + return; + + if (eventMask | EV_READ) i->second.cb_read = 0; + if (eventMask | EV_WRITE) i->second.cb_write = 0; + if (eventMask | EV_HUP) i->second.cb_hup = 0; + if (eventMask | EV_ERR) i->second.cb_err = 0; + + epoll_event ev; + memset(&ev,0,sizeof(ev)); + ev.events = i->second.epollMask(); + + int action (EPOLL_CTL_MOD); + if (ev.events==0) { + action = EPOLL_CTL_DEL; + fdTable_.erase(i); + } + + if (epoll_ctl(epollFd_, action, fd, &ev)<0) + throw SystemException(errno); +} + +prefix_ int satcom::lib::Scheduler::EventSpec::epollMask() + const +{ + int mask (0); + if (cb_read) mask |= EPOLLIN | EPOLLPRI; + if (cb_write) mask |= EPOLLOUT; + if (cb_hup) mask |= EPOLLHUP; + if (cb_err) mask |= EPOLLERR; + return mask; +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Scheduler/Scheduler.hh b/Scheduler/Scheduler.hh new file mode 100644 index 0000000000000000000000000000000000000000..d7238183732d13ea4cc5d8aefe230cbfbbe614f9 --- /dev/null +++ b/Scheduler/Scheduler.hh @@ -0,0 +1,108 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef HH_Scheduler_ +#define HH_Scheduler_ 1 + +// Custom includes +#include <map> +#include <boost/function.hpp> +#include <boost/utility.hpp> + +//#include "scheduler.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace satcom { +namespace lib { + + /** \brief Singleton class to manage the event loop + + This class manages a single select() type event loop. A + customer of this class may register any number of file + descriptiors with this class and pass callback functions to be + called on input, output or error. This functions are specified + using boost::function objects + */ + class Scheduler + : boost::noncopyable + { + public: + /////////////////////////////////////////////////////////////////////////// + // Types + + enum EventId { EV_NONE=0, + EV_READ=1, EV_WRITE=2, EV_HUP=4, EV_ERR=8, + EV_ALL=15 }; + typedef boost::function<void (int fd, EventId event)> Callback; + + /////////////////////////////////////////////////////////////////////////// + ///\name Structors and default members + ///@{ + + // private default constructor + // no copy constructor + // no copy assignment + // default destructor + // no conversion constructors + + static Scheduler & instance(); + + ///@} + /////////////////////////////////////////////////////////////////////////// + + void set(int fd, Callback const & cb, EventId eventMask = EV_ALL); + void unset(int fd, EventId eventMask = EV_ALL); + + protected: + + private: + Scheduler(); + + struct EventSpec + { + Callback cb_read; + Callback cb_write; + Callback cb_hup; + Callback cb_err; + + int epollMask() const; + }; + + typedef std::map<int,EventSpec> FdTable; + + FdTable fdTable_; + int epollFd_; + }; + +}} + +///////////////////////////////hh.e//////////////////////////////////////// +//#include "Scheduler.cci" +//#include "Scheduler.ct" +//#include "Scheduler.cti" +#endif + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Scheduler/scheduler.test.cc b/Scheduler/Scheduler.test.cc similarity index 96% rename from Scheduler/scheduler.test.cc rename to Scheduler/Scheduler.test.cc index 4ce4d75ce167684c74dee57ba62c0480f1fea238..43b0931db9ca2456783e35d3e559428112ecdaf1 100644 --- a/Scheduler/scheduler.test.cc +++ b/Scheduler/Scheduler.test.cc @@ -26,6 +26,7 @@ //#include "scheduler.test.ih" // Custom includes +#include "Scheduler.hh" #include <boost/test/auto_unit_test.hpp> #include <boost/test/test_tools.hpp> @@ -33,7 +34,7 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -using namespace sastcom::lib; +using namespace satcom::lib; BOOST_AUTO_UNIT_TEST(scheduler) { diff --git a/Scheduler/scheduler.cc b/Scheduler/scheduler.cc deleted file mode 100644 index f17d169181a626f80e47f5a5bfdc033e7b393127..0000000000000000000000000000000000000000 --- a/Scheduler/scheduler.cc +++ /dev/null @@ -1,62 +0,0 @@ -// $Id$ -// -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund <stefan.bund@fokus.fraunhofer.de> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -// Definition of non-inline non-template functions - -//#include "scheduler.hh" -//#include "scheduler.ih" - -// Custom includes -#include <errno..h> -#include <sys/epoll.h> - -static const int EPollInitialSize = 16; - -#define prefix_ -///////////////////////////////cc.p//////////////////////////////////////// - -prefix_ Scheduler & satcom::lib::Scheduler::instance() -{ - static Scheduler instance; - return instance; -} - -prefix_ satcom::lib::Scheduler::Scheduler() - : epollFd_(epoll_create(EPollInitialSize)) -{ - -} - -prefix_ char const * satcom::SystemException::what() - const throw() -{ - return strerror(this->errno); -} - -///////////////////////////////cc.e//////////////////////////////////////// -#undef prefix_ - - -// Local Variables: -// mode: c++ -// c-file-style: "satcom" -// End: diff --git a/Scheduler/scheduler.hh b/Scheduler/scheduler.hh deleted file mode 100644 index 769876022667c67641679c383ea36ed54cadbb74..0000000000000000000000000000000000000000 --- a/Scheduler/scheduler.hh +++ /dev/null @@ -1,388 +0,0 @@ -// $Id$ -// -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund <stefan.bund@fokus.fraunhofer.de> -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HH_scheduler_ -#define HH_scheduler_ 1 - -// Custom includes -#include <boost/function.hpp> -#include <boost/utility.hpp> -#include "SatLib/Utils/Exception.hh" - -//#include "scheduler.mpp" -///////////////////////////////hh.p//////////////////////////////////////// - -namespace satcom { -namespace lib { - - /** \brief Singleton class to manage the event loop - - This class manages a single select() type event loop. A - customer of this class may register any number of file - descriptiors with this class and pass callback functions to be - called on input, output or error. This functions are specified - using boost::function objects - */ - class Scheduler - : boost::noncopyable - { - public: - /////////////////////////////////////////////////////////////////////////// - // Types - - typedef boost::function<void (int fd)> callback; - enum events { EV_READ=1, EV_WRITE=2, EV_HUP=4, EV_ERR=8, EV_ALL= }; - - /////////////////////////////////////////////////////////////////////////// - ///\name Structors and default members - ///@{ - - // private default constructor - // no copy constructor - // no copy assignment - // default destructor - // no conversion constructors - - static Scheduler & instance(); - - ///@} - /////////////////////////////////////////////////////////////////////////// - - void add(int fd, callback const & cb, events eventMask = EV_ALL); - void remove(int fd, events eventMask = EV_ALL); - - protected: - - private: - Scheduler(); - - struct EventSpec - { - callback cb_read; - callback cb_write; - callback cb_hup; - callback cb_err; - }; - - typedef std::map<int,EventSpec> FdTable; - - FdTable fdTable_; - int epollFd_; - }; - - - \param b begin iterator of byte range to create the Packet - from - \param e corresponding end iterator - \return smart pointer to new packet - \throws TruncatedPacketException The data cannot be parsed - securely (the data might be trunctated or just - plain invalid) - */ - template <class OtherPacket, class InputIterator> - static typename ptr_t<OtherPacket>::ptr create(InputIterator b, InputIterator e); - -# define BOOST_PP_ITERATION_PARAMS_1 (4, (1, 9, "Packet.mpp", 5)) -# include BOOST_PP_ITERATE() - - ///@} - - ///\name Interpreter chain - ///@{ - - /** \brief get next packet from the interpreter chain - \return smart pointer to next packet or 0 if last packet */ - ptr next() const; - /** \brief get previous packet from the interpreter chain - \return smart pointer to previous packet or 0 if last packet */ - ptr prev() const; - /** \brief first packet of the interpreter chain - \return smart pointer to first packet */ - ptr head() const; - /** \brief get last packet of the interpreter chain - \return smart pointer to last packet */ - ptr last() const; - - /** \brief first packet of given type after the current packet - \return smart pointer to first following packet of type \a - OtherPacket or 0, if no such packet exists */ - template <class OtherPacket> typename ptr_t<OtherPacket>::ptr find_next() const; - /** \brief first packet of given type before the current packet - \return smart pointer to first preceding packet of type \a - OtherPacket or 0, if no such packet exists */ - template <class OtherPacket> typename ptr_t<OtherPacket>::ptr find_prev() const; - - /** \brief first packet of given type after the current packet - \return smart pointer to first following packet of type \a - OtherPacket. \e Assert's, that a packet of this type exists */ - template <class OtherPacket> typename ptr_t<OtherPacket>::ptr get_next() const; - /** \brief first packet of given type before the current packet - \return smart pointer to first preceding packet of type \a - OtherPacket. \e Assert's, that a packet of this type exists */ - template <class OtherPacket> typename ptr_t<OtherPacket>::ptr get_prev() const; - - /** \brief check, wether the packet is of the given type - \return true, if packt is of type \a OtherPacket, false - otherwise */ - template <class OtherPacket> bool is() const; - /** \brief cast packet pointer to the given type - \return a properly cast smart pointer if packet is of type - \a OtherPacket. Otherwise return 0 */ - template <class OtherPacket> typename ptr_t<OtherPacket>::ptr as(); - - /** \brief replace current packet interpreter - - This method will \e replace the current packet facade in - the interpreter list with a new interpreter given by \a - 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 overload is used, if the \a OtherPacket constructor - takes no further arguments beyond the data range. If the - constructor needs further arguments, provide these - arguments to the \a reinterpret call. The compiler will - select the correct \a reinterpret overload to use. - - \return smart pointer to a \e new packet facade - \throws TruncatedPacketException there is not enough data - to savely interpret the packet as the given type. The - original packet is \e not invalidated - */ - template <class OtherPacket> - typename ptr_t<OtherPacket>::ptr reinterpret(); - template <class OtherPacket, class A0> - typename ptr_t<OtherPacket>::ptr reinterpret(A0 const & a0); - -# define BOOST_PP_ITERATION_PARAMS_1 (4, (2, 9, "Packet.mpp", 1)) -# include BOOST_PP_ITERATE() - - ///@} - - ///\name Raw packet data - ///@{ - - /** \brief begin interator of raw packet data - - This iterator allows access to the raw data interpreted by - the packet facade. This \e includes any header possibly - interpreted by the derived packet instance. To access the - payload of the packet, use next()->begin(). - - \return random access iterator to the begin of the raw - data */ - iterator begin() const; - /** \brief past-the-end iterator of raw packet data - - This iterator allows access to the raw data interpreted by - the packet facade. This \e includes any header possibly - interpreted by the derived packet instance. To access the - payload of the packet, use next()->end(). - - \return random access past-the-end iterator of the raw - data */ - iterator end() const; - /** \brief raw data size of packet - \return size of the raw data interpreted by this - packet in bytes. This is \e not necessarily the size of - the complete packet, use head()->size() for this. */ - size_t size() const; - - // Modifying the raw packet data - - // FIXME: Make all data mutators protected? - - /** \brief insert single byte \a v - - \attention The change will \e not be validated by the - derived packet instance. This method is mostly to be used - by the derived class implementation and their helper - classes. */ - void insert(iterator pos, byte v); - /** \brief insert \a n copies of byte \a v - \attention The change will \e not be validated by the - derived packet instance. This method is mostly to be used - by the derived class implementation and their helper - classes. */ - void insert(iterator pos, size_type n, byte v); - /** \brief insert a copy of the given range - \attention The change will \e not be validated by the - derived packet instance. This method is mostly to be used - by the derived class implementation and their helper - classes. */ - template <class InputIterator> - void insert(iterator pos, InputIterator f, InputIterator l); - - /** \brief erase single byte - \attention The change will \e not be validated by the - derived packet instance. This method is mostly to be used - by the derived class implementation and their helper - classes. */ - void erase(iterator pos); - /** \brief erase range - \attention The change will \e not be validated by the - derived packet instance. This method is mostly to be used - by the derived class implementation and their helper - classes. */ - void erase(iterator first, iterator last); - - ///@} - - protected: - ///\name Derived class interface - ///@{ - - /** \brief create new interpreter facade for an existing packet - - This constructor is called, when a new interpreter is to - be added to the interpreter chain. The constructor is - called indirectly from registerInterpreter() or - reinterpret() via the derived classes template - constructor. - */ - template <class Operation> - Packet(Operation const & arg); - virtual ~Packet(); - - private: - /** \brief create next packet interpreter - - This method is called by next(), last() or find_next() to - create any missing interpreters in the interpreter - chain. This method must be overridden in the derived class - to register the next packet interpreter in the interpreter - chain with the packet framework. - - To register the new interpreter, use - registerInterpreter() to create the new Packet - instance. The new instance is automatically added to the - interpreter chain after the current interpreter. - - See also satcom::pkf::PacketRegistryMixin on how to - use a Registry to find the next interpreters implementing - class. - */ - virtual void v_nextInterpreter() const = 0; - - /** \brief finalize packet for sending - - This method is called by the packet framework to let the - interpreter facade do some final calculations/packet - cleanup before the packet is sent out or digested in some - other way. This is the place to calcaulate checksums and - such. - - This method is autmatically called for all interpreters on - the interpreter chain. - */ - virtual void v_finalize() = 0; - - protected: - /** \brief add interpreter to interpreter chain - - This method is used by v_nextInterpreter() in the derived - classes to add a new interpreter to the interpreter - chain. This method will call \c OtherPacket's constructor - with the correct arguments and insert the new interpreter - into the interpreter list. This method is used, if no - further arguments are to be passed to the \c OtherPacket - constructor. If additional arguments are necessary, just - add them after \c end. The compiler will then choose the - correct overload to use. - */ - template <class OtherPacket> - typename ptr_t<OtherPacket>::ptr registerInterpreter( - raw_container::iterator begin, raw_container::iterator end) const; - template <class OtherPacket, class A0> - typename ptr_t<OtherPacket>::ptr registerInterpreter( - raw_container::iterator begin, raw_container::iterator end, - A0 const & a0) const; - -# define BOOST_PP_ITERATION_PARAMS_1 (4, (2, 9, "Packet.mpp", 3)) -# include BOOST_PP_ITERATE() - - ///@} - - private: - - ///\name Implementation - ///@{ - - void add_ref() const; - bool release(); - bool unlink(); - - struct PacketOp_register; - friend class PacketOp_register; - void i_registerInterpreter(Packet * p) const; - - struct PacketOp_replace; - friend class PacketOp_replace; - void i_replaceInterpreter(Packet * p); - - struct PacketOp_set; - friend class PacketOp_set; - void i_setInterpreter(impl::PacketImpl * i); - - private: - friend class impl::PacketImpl; - template <class OtherPacket> friend class impl::PkReg_EntryImpl; - - impl::PacketImpl* impl_; - size_type begin_; - size_type end_; - interpreter_list::iterator self_; - mutable bool parsed_; - mutable refcount_t refcount_; - - ///@} - }; - - /** \brief smart pointer handling - \relates Packet */ - void intrusive_ptr_add_ref(Packet const *); - /** \brief smart pointer handling - \relates Packet */ - void intrusive_ptr_release(Packet *); - - struct SystemException : public std::exception - { - SystemException(errno_) : errno(errno_) {}; - virtual char const * what() const throw(); - int errno; - } - -}} - -///////////////////////////////hh.e//////////////////////////////////////// -//#include "scheduler.cci" -//#include "scheduler.ct" -//#include "scheduler.cti" -#endif - - -// Local Variables: -// mode: c++ -// c-file-style: "satcom" -// End: diff --git a/Utils/Exception.cc b/Utils/Exception.cc index fc48e4d779a508980a5b7a985b9ac5924577ac30..a5349100137cb5434ff65ec61c6565953b3bbd3c 100644 --- a/Utils/Exception.cc +++ b/Utils/Exception.cc @@ -22,18 +22,19 @@ // Definition of non-inline non-template functions -//#include "Exception.hh" +#include "Exception.hh" //#include "Exception.ih" // Custom includes +#include <cstring> #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ char const * satcom::SystemException::what() +prefix_ char const * satcom::lib::SystemException::what() const throw() { - return strerror(this->errno); + return std::strerror(this->err); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Utils/Exception.hh b/Utils/Exception.hh index 7ec23e23efdef650fddb4508a87c033ae3d3d0c4..6c3e8b13ec260fdf53736d7f3b9ab242587e0724 100644 --- a/Utils/Exception.hh +++ b/Utils/Exception.hh @@ -24,6 +24,7 @@ #define HH_Exception_ 1 // Custom includes +#include <exception> //#include "Exception.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -33,10 +34,10 @@ namespace lib { struct SystemException : public std::exception { - SystemException(errno_) : errno(errno_) {}; + SystemException(int err_) : err(err_) {}; virtual char const * what() const throw(); - int errno; - } + int err; + }; }} diff --git a/Utils/SConscript b/Utils/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..cb1cb296def07f01b33fefa47792b1801329875e --- /dev/null +++ b/Utils/SConscript @@ -0,0 +1,8 @@ +Import('env satscons') +import sys +sys.path.append(satscons) +import SatSCons + +########################################################################### + +SatSCons.StandardLib(env, 'Utils', SatSCons.GlobSources()) diff --git a/satscons/BoostUnitTests.py b/satscons/BoostUnitTests.py index a3209287c961c1d6c2fae298479bab89730b9f91..74a97ff120444f0935c27ff9a99360a818db2d83 100644 --- a/satscons/BoostUnitTests.py +++ b/satscons/BoostUnitTests.py @@ -3,16 +3,19 @@ import SCons.Defaults import os.path import os -def BoostUnitTests(env, target, source, test_sources=None, **kw): +def BoostUnitTests(env, target, source, test_source=None, LIBS = [], DEPENDS = [], **kw): path, name = os.path.split(target) - if test_sources: - if type(test_sources) is not type([]): - test_sources = [ test_sources ] + if test_source: + if type(test_source) is not type([]): + test_source = [ test_source ] else: - test_sources = [] + test_source = [] testEnv = env.Copy(**kw) testEnv.Append(LIBS = '$BOOSTTESTLIB') - testRunner = testEnv.Program('test', env.Object(source) + test_sources) + testEnv.Append(LIBS = LIBS) + testRunner = testEnv.Program('test', env.Object(source) + test_source) + if DEPENDS: + env.Depends(testRunner, DEPENDS) return env.Alias(target, env.Command(os.path.join(path,'.'+name+'.stamp'), testRunner, [ './$SOURCE $BOOSSTTESTARGS', 'touch $TARGET' ])) diff --git a/satscons/Doxygen.py b/satscons/Doxygen.py index d28e3b30e9aa3cf2a00095101589aa689a4ec17f..be6c7a40ac19ddd9abe8c60d8be22352dcd684ec 100644 --- a/satscons/Doxygen.py +++ b/satscons/Doxygen.py @@ -7,7 +7,7 @@ def replace_ext(n,ext): base,ext = os.path.splitext(n) return base+ext -def Doxygen(env, target, source, image): +def Doxygen(env, target, source, image=[]): path, name = os.path.split(str(target)) stamp = os.path.join(path, '.'+name+'.stamp') alias = env.Alias(target, diff --git a/satscons/SatSCons.py b/satscons/SatSCons.py new file mode 100644 index 0000000000000000000000000000000000000000..0a6d8d0c290fd1ad323112dbcabea08b5b3f16d6 --- /dev/null +++ b/satscons/SatSCons.py @@ -0,0 +1,128 @@ +import os.path, SCons.Options, SCons.Environment, SCons.Script.SConscript, glob + +opts = None +finalizers = [] + +testTargets = [] + +def InitOpts(): + global opts + if opts is not None: return + opts = SCons.Options.Options('SConfig') + opts.Add('CXX', 'C++ compiler to use', 'g++') + opts.Add(SCons.Options.BoolOption('final','Enable optimization',0)) + +def Finalizer(f): + global finalizers + finalizers.append(f) + +def UseBoost(): + global opts + InitOpts() + opts.Add('BOOST_INCLUDES', 'Boost include directory', '') + opts.Add('BOOST_VARIANT', 'The boost variant to use', '') + opts.Add('BOOST_LIBDIR', 'The directory of the boost libraries', '') + Finalizer(FinalizeBoost) + +def FinalizeBoost(env): + env.Tool('BoostUnitTests', [os.path.split(__file__)[0]]) + env['BOOSTTESTLIB'] = 'libboost_unit_test_framework' + env['BOOST_VARIANT'] + env.Append(LIBPATH = [ '$BOOST_LIBDIR' ], + CPPPATH = [ '$BOOST_INCLUDES' ]) + +def UseSTLPort(): + global opts + InitOpts() + opts.Add('STLPORT_INCLUDES', 'STLport include directory', '') + opts.Add('STLPORT_LIB', 'Name of the stlport library or empty to not use stlport', '') + opts.Add('STLPORT_LIBDIR', 'The directory of the stlport libraries','') + Finalizer(FinalizeSTLPort) + +def FinalizeSTLPort(env): + env['STLPORT_DEBUGLIB'] = '' + if env['STLPORT_LIB']: + env['STLPORT_DEBUGLIB'] = env['STLPORT_LIB'] + '_stldebug' + env.Append(LIBPATH = [ '$STLPORT_LIBDIR' ], + CPPPATH = [ '$STLPORT_INCLUDES' ]) + if env['final']: + env.Append(LIBS = [ '$STLPORT_LIB' ]) + else: + env.Append(LIBS = [ '$STLPORT_DEBUGLIB' ], + CPPDEFINES = [ '_STLP_DEBUG' ]) + +def UseDoxygen(): + Finalizer(FinalizeDoxygen) + +def FinalizeDoxygen(env): + env.Tool('Doxygen', [os.path.split(__file__)[0]]) + +def MakeEnvironment(): + global opts, finalizers + InitOpts() + env = SCons.Environment.Environment(options=opts) + env.Help(opts.GenerateHelpText(env)) + conf = env.Configure() + if os.environ.has_key('SSH_AUTH_SOCK'): + conf.env.Append( ENV = { 'SSH_AUTH_SOCK': os.environ['SSH_AUTH_SOCK'] } ) + + for finalizer in finalizers: + finalizer(conf.env) + + conf.env.Append(CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long', + '-pedantic', '-ansi' ]) + + if conf.env['final']: + conf.env.Append(CXXFLAGS = [ '-O3' ]) + else: + conf.env.Append(CXXFLAGS = [ '-O0', '-g', '-fno-inline' ], + LINKFLAGS = [ '-g' ]) + + return conf.Finish() + +def GlobSources(): + testSources = glob.glob("*.test.cc") + sources = [ x for x in glob.glob("*.cc") if x not in testSources ] + return (sources, testSources) + +def StandardTargets(env): + all = env.Alias('all') + env.Clean(all, [ '.sconsign', '.sconf_temp', 'config.log', 'ChangeLog.bak', '.clean' + ] + glob.glob("*~")) + env.Depends(all, '.') + #env.AlwaysBuild(env.Command('ChangeLog', '', [ "cvs2cl -rS --no-wrap --summary" ])) + +def StandardObjects(env, sources, testSources = None, LIBS = []): + global testTargets + if type(sources) == type(()): + testSources = sources[1] + sources = sources[0] + + StandardTargets(env) + + objects = env.Object(sources) + + LOCAL_LIBS = [ x for x in LIBS if x.startswith('$LIB_') ] + LIBS = [ x for x in LIBS if x not in LOCAL_LIBS ] + if testSources: + testTargets.append(env.BoostUnitTests( + target = 'test', + source = sources, + test_source = testSources + LOCAL_LIBS, + LIBS = LIBS, + DEPENDS = LOCAL_LIBS)) + + env.Doxygen( + target = 'doc', + source = sources ) + + return objects + +def StandardLib(env, library, sources, testSources = None, LIBS = []): + objects = StandardObjects(env,sources,testSources,LIBS=LIBS) + lib = env.Library(library,objects) + env.Default(lib) + env.Append(**{ 'LIB_' + library : lib }) + +def AllTests(env): + tests = env.Alias('tests') + env.Depends(tests, testTargets)