moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kig / misc / argsparser.cpp
blobad5894cada3144935d14916006b9664bfa34dea7
1 // Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
16 // 02111-1307, USA.
18 #include "argsparser.h"
20 #include "../objects/object_imp.h"
21 #include "../objects/object_holder.h"
23 #include <cassert>
24 #include <algorithm>
25 #include <kdebug.h>
27 void ArgsParser::initialize( const struct spec* args, int n )
29 std::vector<spec> vect( args, args + n );
30 initialize( vect );
33 ArgsParser::ArgsParser()
37 ArgsParser::ArgsParser( const std::vector<spec>& args )
39 initialize( args );
42 void ArgsParser::initialize( const std::vector<spec>& args )
44 margs = args;
47 ArgsParser::ArgsParser( const spec* args, int n )
49 initialize( args, n );
52 static bool hasimp( const ObjectCalcer& o, const ObjectImpType* imptype )
54 return o.imp()->inherits( imptype );
57 static bool hasimp( const ObjectImp& o, const ObjectImpType* imptype )
59 return o.inherits( imptype );
62 static bool isvalid( const ObjectImp& o )
64 return o.valid();
67 static bool isvalid( const ObjectCalcer& o )
69 return o.imp()->valid();
72 // we use a template method that is used for both Objects and Args to
73 // not have to write the same thing twice..
74 template <class Collection>
75 static int check( const Collection& c, const std::vector<ArgsParser::spec>& margs )
77 std::vector<bool> found( margs.size() );
79 for ( typename Collection::const_iterator o = c.begin(); o != c.end(); ++o )
81 for ( uint i = 0; i < margs.size(); ++i )
83 if ( hasimp( **o, margs[i].type ) && !found[i] )
85 // object o is of a type that we're looking for
86 found[i] = true;
87 goto matched;
90 return ArgsParser::Invalid;
91 matched:
94 for( uint i = 0; i < margs.size(); ++i )
95 if ( !found[i] ) return ArgsParser::Valid;
96 return ArgsParser::Complete;
99 int ArgsParser::check( const Args& os ) const
101 return ::check( os, margs );
104 int ArgsParser::check( const std::vector<ObjectCalcer*>& os ) const
106 return ::check( os, margs );
109 template <typename Collection>
110 static Collection parse( const Collection& os,
111 const std::vector<ArgsParser::spec> margs )
113 Collection ret( margs.size(), static_cast<typename Collection::value_type>( 0 ) );
115 for ( typename Collection::const_iterator o = os.begin(); o != os.end(); ++o )
117 for( uint i = 0; i < margs.size(); ++i )
118 if ( hasimp( **o, margs[i].type ) && ret[i] == 0 )
120 // object o is of a type that we're looking for
121 ret[i] = *o;
122 goto added;
124 added:
127 // remove 0's from the output..
128 ret.erase(
129 std::remove( ret.begin(), ret.end(),
130 static_cast<typename Collection::value_type>( 0 ) ),
131 ret.end() );
132 return ret;
135 Args ArgsParser::parse( const Args& os ) const
137 return ::parse( os, margs );
140 std::vector<ObjectCalcer*> ArgsParser::parse( const std::vector<ObjectCalcer*>& os ) const
142 return ::parse( os, margs );
145 ArgsParser ArgsParser::without( const ObjectImpType* type ) const
147 std::vector<spec> ret;
148 ret.reserve( margs.size() - 1 );
149 for ( uint i = 0; i < margs.size(); ++i )
150 if ( margs[i].type != type )
151 ret.push_back( margs[i] );
152 return ArgsParser( ret );
155 ArgsParser::spec ArgsParser::findSpec( const ObjectImp* obj, const Args& parents ) const
157 spec ret;
158 ret.type = 0;
160 std::vector<bool> found( margs.size(), false );
162 for ( Args::const_iterator o = parents.begin();
163 o != parents.end(); ++o )
165 for ( uint i = 0; i < margs.size(); ++i )
167 if ( (*o)->inherits( margs[i].type ) && !found[i] )
169 // object o is of a type that we're looking for
170 found[i] = true;
171 if ( *o == obj ) return margs[i];
172 // i know that "goto's are *evil*", but they're very useful
173 // and completely harmless if you use them as better "break;"
174 // statements.. trust me ;)
175 goto matched;
178 matched:
181 kdDebug() << k_funcinfo << "no proper spec found :(" << endl;
182 return ret;
185 const ObjectImpType* ArgsParser::impRequirement(
186 const ObjectImp* o, const Args& parents ) const
188 spec s = findSpec( o, parents );
189 return s.type;
192 std::string ArgsParser::usetext( const ObjectImp* obj, const Args& sel ) const
194 spec s = findSpec( obj, sel );
195 return s.usetext;
198 template<typename Collection>
199 static bool checkArgs( const Collection& os, uint min, const std::vector<ArgsParser::spec>& argsspec )
201 assert( os.size() <= argsspec.size() );
202 if( os.size() < min ) return false;
203 uint checknum = os.size();
204 for ( uint i = 0; i < checknum; ++i )
206 if( !isvalid( *os[i] ) ) return false;
207 if( !hasimp( *os[i], argsspec[i].type ) ) return false;
209 return true;
212 bool ArgsParser::checkArgs( const Args& os ) const
214 return checkArgs( os, margs.size() );
217 bool ArgsParser::checkArgs( const Args& os, uint min ) const
219 return ::checkArgs( os, min, margs );
222 bool ArgsParser::checkArgs( const std::vector<ObjectCalcer*>& os ) const
224 return checkArgs( os, margs.size() );
227 bool ArgsParser::checkArgs( const std::vector<ObjectCalcer*>& os, uint minobjects ) const
229 return ::checkArgs( os, minobjects, margs );
232 ArgsParser::~ArgsParser()
236 bool ArgsParser::isDefinedOnOrThrough( const ObjectImp* o, const Args& parents ) const
238 spec s = findSpec( o, parents );
239 return s.onOrThrough;
242 std::string ArgsParser::selectStatement( const Args& selection ) const
244 std::vector<bool> found( margs.size(), false );
246 for ( Args::const_iterator o = selection.begin();
247 o != selection.end(); ++o )
249 for ( uint i = 0; i < margs.size(); ++i )
251 if ( (*o)->inherits( margs[i].type ) && !found[i] )
253 // object o is of a type that we're looking for
254 found[i] = true;
255 break;
259 for ( uint i = 0; i < margs.size(); ++i )
261 if ( !found[i] )
262 return margs[i].selectstat;
264 kdDebug() << k_funcinfo << "no proper select statement found :(" << endl;
265 return 0;