afb365feb78cee4ad17e86dd2062d365f5169140
[senf.git] / Console / Config.cc
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Config non-inline non-template implementation */
25
26 #include "Config.hh"
27 //#include "Config.ih"
28
29 // Custom includes
30
31 //#include "Config.mpp"
32 #define prefix_
33 ///////////////////////////////cc.p////////////////////////////////////////
34
35 ///////////////////////////////////////////////////////////////////////////
36 // senf::console::ConfigFile
37
38 #ifndef DOXYGEN
39
40 namespace {
41     struct BindPolicy
42     {
43         BindPolicy(senf::console::Executor & e, senf::console::Executor::SecurityPolicy p) 
44             : e_ (e) 
45             { e_.policy(p); }
46         
47         ~BindPolicy() 
48             { e_.policy(senf::console::Executor::SecurityPolicy()); }
49         
50         senf::console::Executor & e_;
51     };
52 }
53
54 #endif
55
56 prefix_ void senf::console::ConfigFile::parse(DirectoryNode & restrict)
57 {
58     DirectoryNode::ptr r (restrict.thisptr());
59     BindPolicy bp ( executor_, 
60                     boost::bind(&ConfigFile::policyCallback, this, r, _1, _2) );
61     if (! parser_.parseFile(filename_, boost::bind<void>( boost::ref(executor_),
62                                                           boost::ref(std::cerr),
63                                                           _1 )) )
64         throw SyntaxErrorException();
65     insertParsedNode(r);
66 }
67
68 prefix_ bool senf::console::ConfigFile::parsed(GenericNode & node)
69     const
70 {
71     ParsedNodes::const_iterator i (parsedNodes_.begin());
72     ParsedNodes::const_iterator const i_end (parsedNodes_.end());
73     for (; i != i_end; ++i)
74         if ( ! i->expired() && node.isChildOf(*(i->lock())) )
75             return true;
76     return false;
77 }
78
79 prefix_ void senf::console::ConfigFile::policyCallback(DirectoryNode::ptr restrict,
80                                                        DirectoryNode & dir,
81                                                        std::string const & name)
82 {
83     if (dir.hasChild(name)) {
84         GenericNode & item (dir.get(name));
85         if (restrict && ! item.isChildOf(*restrict)) {
86             DirectoryNode * itemdir (dynamic_cast<DirectoryNode*>(&item));
87             if (! itemdir || ! restrict->isChildOf(*itemdir))
88                 throw Executor::IgnoreCommandException();
89         }
90         if (parsed(item))
91             throw Executor::IgnoreCommandException();
92     }
93     else if (restrict && ! dir.isChildOf(*restrict))
94         throw Executor::IgnoreCommandException();
95 }
96
97 namespace {
98     struct RemoveNodesFn
99     {
100         RemoveNodesFn(senf::console::DirectoryNode::ptr newNode) : newNode_ (newNode) {}
101
102         bool operator()(senf::console::DirectoryNode::weak_ptr node) const
103             { return node.expired() || node.lock()->isChildOf(*newNode_); }
104
105         senf::console::DirectoryNode::ptr newNode_;
106     };
107 }
108
109 prefix_ void senf::console::ConfigFile::insertParsedNode(DirectoryNode::ptr node)
110 {
111     parsedNodes_.erase(
112         std::remove_if(parsedNodes_.begin(), parsedNodes_.end(), RemoveNodesFn(node)),
113         parsedNodes_.end());
114     parsedNodes_.push_back(node);
115 }
116
117 ///////////////////////////////////////////////////////////////////////////
118
119 prefix_ void senf::console::readConfig(std::string const & filename, DirectoryNode & root)
120 {
121     ConfigFile cfg (filename, root);
122     cfg.parse();
123 }
124
125 ///////////////////////////////cc.e////////////////////////////////////////
126 #undef prefix_
127 //#include "Config.mpp"
128
129 \f
130 // Local Variables:
131 // mode: c++
132 // fill-column: 100
133 // comment-column: 40
134 // c-file-style: "senf"
135 // indent-tabs-mode: nil
136 // ispell-local-dictionary: "american"
137 // compile-command: "scons -u test"
138 // End: