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
18 #include "argsparser.h"
20 #include "../objects/object_imp.h"
21 #include "../objects/object_holder.h"
27 void ArgsParser::initialize( const struct spec
* args
, int n
)
29 std::vector
<spec
> vect( args
, args
+ n
);
33 ArgsParser::ArgsParser()
37 ArgsParser::ArgsParser( const std::vector
<spec
>& args
)
42 void ArgsParser::initialize( const std::vector
<spec
>& 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
)
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
90 return ArgsParser::Invalid
;
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
127 // remove 0's from the output..
129 std::remove( ret
.begin(), ret
.end(),
130 static_cast<typename
Collection::value_type
>( 0 ) ),
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
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
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 ;)
181 kdDebug() << k_funcinfo
<< "no proper spec found :(" << endl
;
185 const ObjectImpType
* ArgsParser::impRequirement(
186 const ObjectImp
* o
, const Args
& parents
) const
188 spec s
= findSpec( o
, parents
);
192 std::string
ArgsParser::usetext( const ObjectImp
* obj
, const Args
& sel
) const
194 spec s
= findSpec( obj
, sel
);
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;
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
259 for ( uint i
= 0; i
< margs
.size(); ++i
)
262 return margs
[i
].selectstat
;
264 kdDebug() << k_funcinfo
<< "no proper select statement found :(" << endl
;