--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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.
+
+/** \file
+ \brief Config non-inline non-template implementation */
+
+#include "Config.hh"
+//#include "Config.ih"
+
+// Custom includes
+
+//#include "Config.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::ConfigFile
+
+prefix_ void senf::console::ConfigFile::parse()
+{
+ if (! parser_.parseFile(filename_, boost::bind<void>( boost::ref(executor_),
+ boost::ref(std::cerr),
+ _1 )) )
+ throw SyntaxErrorException();
+}
+
+prefix_ void senf::console::ConfigFile::parse(DirectoryNode & restrict)
+{
+ restrict_ = restrict.thisptr();
+ parse();
+ parsedNodes_.push_back(restrict_);
+ restrict_.reset();
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+prefix_ void senf::console::readConfig(std::string const & filename)
+{
+ ConfigFile cfg (filename);
+ cfg.parse();
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "Config.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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.
+
+/** \file
+ \brief Config inline non-template implementation */
+
+//#include "Config.ih"
+
+// Custom includes
+#include "../Utils/membind.hh"
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::ConfigFile
+
+prefix_ senf::console::ConfigFile::ConfigFile(std::string const & filename)
+ : filename_ (filename)
+{
+ executor_.policy(senf::membind(&ConfigFile::policyCallback, this));
+}
+
+prefix_ void senf::console::ConfigFile::policyCallback(DirectoryNode & dir,
+ std::string const & name)
+{
+ if (dir.hasChild(name)) {
+ GenericNode & item (dir.get(name));
+ if (restrict_ && ! item.isChildOf(*restrict_)) {
+ DirectoryNode * itemdir (dynamic_cast<DirectoryNode*>(&item));
+ if (! itemdir || ! restrict_->isChildOf(*itemdir))
+ throw Executor::IgnoreCommandException();
+ }
+ ParsedNodes::const_iterator i (parsedNodes_.begin());
+ ParsedNodes::const_iterator const i_end (parsedNodes_.end());
+ for (; i != i_end; ++i) {
+ if ( ! i->expired() && item.isChildOf(*(i->lock())) )
+ throw Executor::IgnoreCommandException();
+ }
+ }
+ else {
+ if (restrict_ && ! dir.isChildOf(*restrict_))
+ throw Executor::IgnoreCommandException();
+ }
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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.
+
+/** \file
+ \brief Config public header */
+
+#ifndef HH_Console_Config_
+#define HH_Console_Config_ 1
+
+// Custom includes
+#include <boost/utility.hpp>
+#include "Parse.hh"
+#include "Executor.hh"
+
+//#include "Config.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace console {
+
+ /** \brief
+ */
+ class ConfigFile
+ : boost::noncopyable
+ {
+ public:
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Structors and default members
+ ///@{
+
+ explicit ConfigFile(std::string const & filename);
+
+ ///@}
+ ///////////////////////////////////////////////////////////////////////////
+
+ void parse();
+ void parse(DirectoryNode & restrict);
+
+ protected:
+
+ private:
+ void policyCallback(DirectoryNode & dir, std::string const & item);
+
+ typedef std::vector<DirectoryNode::weak_ptr> ParsedNodes;
+
+ std::string filename_;
+ CommandParser parser_;
+ Executor executor_;
+
+ DirectoryNode::ptr restrict_;
+ ParsedNodes parsedNodes_;
+ };
+
+ void readConfig(std::string const & filename);
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "Config.cci"
+//#include "Config.ct"
+//#include "Config.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.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.
+
+/** \file
+ \brief Config.test unit tests */
+
+//#include "Config.test.hh"
+//#include "Config.test.ih"
+
+// Custom includes
+#include "Config.hh"
+#include <fstream>
+#include "ScopedDirectory.hh"
+#include "ParsedCommand.hh"
+#include <boost/filesystem/operations.hpp>
+
+#include "../Utils/auto_unit_test.hh"
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+
+ int var1 (0);
+ bool var2 (false);
+
+ void fun1(int v) { var1 = v; }
+ void fun2() { var2 = true; }
+
+ class TempFile
+ {
+ public:
+ TempFile(std::string const & name) : name_ (name), file_ (name_.c_str()) {}
+ ~TempFile() { file_.close(); boost::filesystem::remove(name_); }
+
+ template <class T> TempFile & operator<<(T const & v) { file_ << v; return *this; }
+ enum Closer { close }; void operator<<(Closer) { file_.close(); }
+ std::string const & name() { return name_; }
+
+ private:
+ std::string name_;
+ std::ofstream file_;
+ };
+
+
+}
+
+BOOST_AUTO_UNIT_TEST(configFile)
+{
+ TempFile cfgf ("test.cfg");
+ cfgf << "dir1/fun1 10;\n"
+ << TempFile::close;
+
+ senf::console::ScopedDirectory<> dir1;
+ senf::console::root().add("dir1", dir1);
+ dir1.add("fun1",&fun1);
+
+ {
+ var1 = 0;
+ senf::console::ConfigFile cfg (cfgf.name());
+ SENF_CHECK_NO_THROW( cfg.parse() )
+ BOOST_CHECK_EQUAL( var1, 10 );
+ }
+}
+
+BOOST_AUTO_UNIT_TEST(configFileRestrict)
+{
+ TempFile cfgf ("test.cfg");
+ cfgf << "dir1/fun1 10;\n"
+ << "dir2/fun2;\n"
+ << TempFile::close;
+
+ senf::console::ScopedDirectory<> dir1;
+ senf::console::root().add("dir1", dir1);
+ dir1.add("fun1",&fun1);
+
+ {
+ var1 = 0;
+ var2 = false;
+ senf::console::ConfigFile cfg (cfgf.name());
+ SENF_CHECK_NO_THROW( cfg.parse(dir1.node()) );
+ BOOST_CHECK_EQUAL( var1, 10 );
+ BOOST_CHECK_EQUAL( var2, false );
+
+ senf::console::ScopedDirectory<> dir2;
+ senf::console::root().add("dir2", dir2);
+ dir2.add("fun2",&fun2);
+
+ var1 = 0;
+ var2 = false;
+ SENF_CHECK_NO_THROW( cfg.parse() );
+ BOOST_CHECK_EQUAL( var1, 0 );
+ BOOST_CHECK_EQUAL( var2, true );
+ }
+}
+
+BOOST_AUTO_UNIT_TEST(configFileSkipGroup)
+{
+ TempFile cfgf ("test.cfg");
+ cfgf << "dir1/fun1 10;\n"
+ << "dir2 { dir3 { fun2; } fun1 5; }"
+ << TempFile::close;
+
+ senf::console::ScopedDirectory<> dir1;
+ senf::console::root().add("dir1", dir1);
+ dir1.add("fun1",&fun1);
+
+ senf::console::ScopedDirectory<> dir2;
+ senf::console::root().add("dir2", dir2);
+
+ dir2.mkdir("dir3").add("fun2", &fun2);
+ dir2.add("fun1", &fun1);
+
+ {
+ var1 = 0;
+ var2 = false;
+ senf::console::ConfigFile cfg (cfgf.name());
+ SENF_CHECK_NO_THROW( cfg.parse(dir1.node()) );
+ BOOST_CHECK_EQUAL( var1, 10 );
+ BOOST_CHECK_EQUAL( var2, false );
+
+ var1 = 0;
+ var2 = false;
+ SENF_CHECK_NO_THROW( cfg.parse(dir2["dir3"]) );
+ BOOST_CHECK_EQUAL( var1, 0 );
+ BOOST_CHECK_EQUAL( var2, true );
+
+ var1 = 0;
+ var2 = false;
+ SENF_CHECK_NO_THROW( cfg.parse() );
+ BOOST_CHECK_EQUAL( var1, 5 );
+ BOOST_CHECK_EQUAL( var2, false );
+ }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
#include "Server.hh"
#include "ParsedCommand.hh"
#include "ScopedDirectory.hh"
+#include "Config.hh"
///////////////////////////////hh.e////////////////////////////////////////
//#include "Console.cci"
try {
switch(command.builtin()) {
case ParseCommandInfo::NoBuiltin : {
+ if (skipping_)
+ break;
GenericNode & node ( traverseCommand(command.commandPath()) );
DirectoryNode * dir ( dynamic_cast<DirectoryNode*>(&node) );
if ( dir ) {
}
case ParseCommandInfo::BuiltinCD :
- if ( command.arguments() ) {
- if (command.arguments().begin()->size() == 1
- && command.arguments().begin()->begin()->value() == "-") {
- if (oldCwd_.expired() || ! oldCwd_.lock()->active()) {
+ if (skipping_)
+ break;
+ try {
+ if ( command.arguments() ) {
+ if (command.arguments().begin()->size() == 1
+ && command.arguments().begin()->begin()->value() == "-") {
+ if (oldCwd_.expired() || ! oldCwd_.lock()->active()) {
+ oldCwd_ = cwd_;
+ cwd_ = root_;
+ } else
+ swap(cwd_, oldCwd_);
+ }
+ else {
oldCwd_ = cwd_;
- cwd_ = root_;
- } else
- swap(cwd_, oldCwd_);
- }
- else {
- oldCwd_ = cwd_;
cwd_ = traverseDirectory(*command.arguments().begin()).thisptr();
+ }
}
}
+ catch (IgnoreCommandException &) {
+ throw SyntaxErrorException(
+ "'cd' cannot be skipped (don't use 'cd' in conf-files)");
+ }
break;
case ParseCommandInfo::BuiltinLS : {
+ if (skipping_)
+ break;
DirectoryNode const & dir ( command.arguments()
? traverseDirectory(*command.arguments().begin())
: cwd() );
}
case ParseCommandInfo::BuiltinPUSHD :
- dirstack_.push_back(cwd_);
- if ( command.arguments() )
- cwd_ = traverseDirectory(*command.arguments().begin()).thisptr();
+ dirstack_.push_back(DirEntry(cwd_, skipping_));
+ if ( ! skipping_ && command.arguments() ) {
+ try {
+ cwd_ = traverseDirectory(*command.arguments().begin()).thisptr();
+ }
+ catch (IgnoreCommandException &) {
+ cwd_.reset();
+ skipping_ = true;
+ }
+ }
break;
case ParseCommandInfo::BuiltinPOPD :
if (! dirstack_.empty()) {
- cwd_ = dirstack_.back();
+ cwd_ = dirstack_.back().dir;
+ skipping_ = dirstack_.back().skip;
dirstack_.pop_back();
}
break;
case ParseCommandInfo::BuiltinEXIT :
+ if (skipping_)
+ break;
throw ExitException();
case ParseCommandInfo::BuiltinHELP :
+ if (skipping_)
+ break;
GenericNode const & node (command.arguments()
? traverseNode(*command.arguments().begin())
: cwd());
prefix_ senf::console::Executor::Executor()
: root_(senf::console::root().thisptr()), cwd_ (root_), oldCwd_ (cwd_),
- autocd_ (false), autocomplete_ (false)
+ autocd_ (false), autocomplete_ (false), skipping_ (false)
{}
prefix_ void senf::console::Executor::operator()(std::ostream & output,
SecurityPolicy policy_;
DirectoryNode::weak_ptr cwd_;
DirectoryNode::weak_ptr oldCwd_;
- typedef std::vector<DirectoryNode::weak_ptr> DirStack;
+ struct DirEntry {
+ DirEntry(DirectoryNode::weak_ptr dir_, bool skip_) : dir(dir_), skip(skip_) {}
+ DirectoryNode::weak_ptr dir;
+ bool skip;
+ };
+ typedef std::vector<DirEntry> DirStack;
DirStack dirstack_;
bool autocd_;
bool autocomplete_;
+
+ bool skipping_;
};
}
}
-prefix_ void senf::console::Client::v_write(boost::posix_time::ptime timestamp,
+prefix_ void senf::console::Client::v_write(senf::log::time_type timestamp,
std::string const & stream,
std::string const & area, unsigned level,
std::string const & message)
void translate(std::string & data);
void handleInput(std::string input);
- virtual void v_write(boost::posix_time::ptime timestamp, std::string const & stream,
+ virtual void v_write(senf::log::time_type timestamp, std::string const & stream,
std::string const & area, unsigned level,
std::string const & message);
CONFIG_FILES_OPTS = configFilesOpts,
CLEAN_PATTERNS = [ '*~', '#*#', '*.pyc', 'semantic.cache', '.sconsign', '.sconsign.dblite' ],
BUILDPACKAGE_COMMAND = "dpkg-buildpackage -us -uc -rfakeroot -I.svn -I_templates $CONFIG_FILES_OPTS",
- TOP_INCLUDES = [ 'Packets', 'PPI', 'Scheduler', 'Socket', 'Utils',
+ TOP_INCLUDES = [ 'Packets', 'PPI', 'Scheduler', 'Socket', 'Utils', 'Console',
'config.hh', 'local_config.hh' ],
)
# Create Doxyfile.local otherwise doxygen will barf on this non-existent file
# Create it even when cleaning, to silence the doxygen builder warnings
-if not os.path.exists("Doxyfile.local"):
+if not env.GetOption('clean') and not os.path.exists("Doxyfile.local"):
Execute(Touch("Doxyfile.local"))
# Create local_config.h
env.Alias('install_all', env.Install('$LIBINSTALLDIR', libsenf))
-env.Clean('all', [ os.path.join(path,f)
- for path, subdirs, files in os.walk('.')
- for pattern in env['CLEAN_PATTERNS']
- for f in fnmatch.filter(files,pattern) ])
+if env.GetOption('clean'):
+ env.Clean('all', [ os.path.join(path,f)
+ for path, subdirs, files in os.walk('.')
+ for pattern in env['CLEAN_PATTERNS']
+ for f in fnmatch.filter(files,pattern) ])
PhonyTarget(env, 'deb', [
checkLocalConf,
///////////////////////////////////////////////////////////////////////////
// senf::SchedulerLogTimeSource
-prefix_ boost::posix_time::ptime senf::SchedulerLogTimeSource::operator()()
+prefix_ senf::log::time_type senf::SchedulerLogTimeSource::operator()()
const
{
- return ClockService::abstime(Scheduler::instance().eventTime());
+ return Scheduler::instance().eventTime();
}
///////////////////////////////cc.e////////////////////////////////////////
*/
struct SchedulerLogTimeSource : public senf::log::TimeSource
{
- boost::posix_time::ptime operator()() const;
+ senf::log::time_type operator()() const;
};
}
#define COMPILE_FAIL(n) void n()
+#define SENF_CHECK_NO_THROW(expr) \
+ BOOST_CHECK_NO_THROW( \
+ try { (void) expr ; } \
+ catch (std::exception & e) { std::cerr << e.what() << std::endl; throw; } )
+
///////////////////////////////hh.e////////////////////////////////////////
//#include "auto_unit_test.cci"
//#include "auto_unit_test.ct"