1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/sat/AttrMatcher.h
12 #ifndef ZYPP_SAT_ATTRMATCHER_H
13 #define ZYPP_SAT_ATTRMATCHER_H
23 #include "zypp/base/PtrTypes.h"
24 #include "zypp/base/SafeBool.h"
25 #include "zypp/base/Exception.h"
27 ///////////////////////////////////////////////////////////////////
29 { /////////////////////////////////////////////////////////////////
31 ///////////////////////////////////////////////////////////////////
35 /** String matching option flags as used e.g. by \ref sat::AttrMatcher.
40 * Match mode( Match::GLOB | Match::NOCASE );
43 class Match : private base::SafeBool<Match>
46 static const int _modemask;
47 static const int _flagmask;
50 /** Mode flags (mutual exclusive). */
53 NOTHING, //!< Match nothing
54 STRING, //!< Excat matching
55 SUBSTRING, //!< Match substring
57 REGEX, //!< Regular Expression
58 OTHER //!< Something else.
61 /** \name Option flags
62 * Some flags are actually \ref sat::LookupAttr specific, as they tell
63 * how to retrieve the attribute values. The plain \ref sat::AttrMatcher
64 * will ignore those flags and use the ones related to string matching only
68 /** If set, match case insensitive. */
69 static const Match NOCASE;
71 static const Match NO_STORAGE_SOLVABLE;
73 static const Match SUB;
75 static const Match ARRAYSENTINEL;
76 /** If set, skip any \c kind: prefix when looking at a \ref Solvable name. */
77 static const Match SKIP_KIND;
78 /** If set, match full path when matching in filelists, otherwise just the basenames. */
79 static const Match FILES;
83 /** Default ctor \c 0 or \ref NOTHING. */
88 /** Ctor from \ref Mode value. */
90 : _val( modeval( val_r ) )
93 /** Just in case one needs it. */
94 explicit Match( int val_r )
98 #ifndef SWIG // Swig treats it as syntax error
99 /** Evaluate in a boolean context <tt>( != 0 )</tt>. */
100 using base::SafeBool<Match>::operator bool_type;
104 /** Test whether \c all of the \a rhs bits are set (same mode if \a rhs has one). */
105 bool test( const Match & rhs ) const
106 { return ( ( flagval() & rhs.flagval() ) == rhs.flagval() )
107 && ( !rhs.modeval() || rhs.modeval() == modeval() ); }
109 /** Whether at least one of the \a rhs bits is set (or the same mode). */
110 bool testAnyOf( const Match & rhs ) const
111 { return ( flagval() & rhs.flagval() )
112 || ( rhs.modeval() && rhs.modeval() == modeval() ); }
114 /** Set all of the \a rhs bits (setting a new mode if \a rhs has one). */
115 void set( const Match & rhs )
118 _val = rhs._val | flagval(); // also set the rhs mode
120 _val |= rhs._val; // just set the flags
123 /** Unset all of the \a rhs bits (unsets mode if the same as \a rhs). */
124 void unset( const Match & rhs )
126 if ( modeval() == rhs.modeval() )
127 _val = flagval() & ~rhs.flagval(); // also unset mode
129 _val &= ~rhs.flagval(); // just unset falgs
132 /** Depending on the value of \a onoff, set or unset flags. */
133 void turn( const Match & rhs, bool onoff )
134 { onoff ? set( rhs ) : unset( rhs ); }
137 Match & operator|=( const Match & rhs )
138 { set( rhs ); return *this; }
141 Match & operator-=( const Match & rhs )
142 { unset( rhs ); return *this; }
145 /** Return the \c mode part. */
148 /** Return the \c flags part. */
150 { return Match( flagval() ); }
153 /** \name Low level integer representation. */
155 /** Return the integer representation. */
156 int get() const { return _val; }
157 /** Return the modes integer representation. */
158 int modeval() const { return _val & _modemask; }
159 /** Return the flags integer representation. */
160 int flagval() const { return _val & _flagmask; }
164 /** \name Mode flag manip/query convenience. */
166 /** Whether this has mode \a rhs */
167 bool isMode( Mode rhs ) const
168 { return modeval() == modeval( rhs ); }
169 /** Whether this has mode \ref STRING. */
170 bool isModeString() const
171 { return isMode( STRING ); }
172 /** Whether this has mode \ref SUBSTRING. */
173 bool isModeSubstring() const
174 { return isMode( SUBSTRING ); }
175 /** Whether this has mode \ref GLOB. */
176 bool isModeGlob() const
177 { return isMode( GLOB ); }
178 /** Whether this has mode \ref REGEX. */
179 bool isModeRegex() const
180 { return isMode( REGEX ); }
182 /** Set the mode part to \a rhs . */
183 void setMode( Mode rhs )
184 { _val = modeval( rhs ) | flagval(); }
185 /** Set the mode \ref STRING. */
187 { setMode( STRING ); }
188 /** Set the mode \ref SUBSTRING. */
189 void setModeSubstring()
190 { setMode( SUBSTRING ); }
191 /** Set the mode \ref GLOB. */
194 /** Set the mode \ref REGEX. */
196 { setMode( REGEX ); }
199 /** String representation. */
200 std::string asString() const;
203 friend base::SafeBool<Match>::operator bool_type() const;
204 bool boolTest() const { return _val; }
206 /** Numeric value for enum (short for <tt>Match(m).get()</tt>). */
207 static int modeval( Mode mode_r );
213 /** \relates Match */
214 inline bool operator==( const Match & lhs, const Match & rhs )
215 { return lhs.get() == rhs.get(); }
216 /** \relates Match */
217 inline bool operator!=( const Match & lhs, const Match & rhs )
218 { return lhs.get() != rhs.get(); }
220 /** \relates Match */
221 inline Match operator|( const Match & lhs, const Match & rhs )
222 { return Match(lhs) |= rhs; }
223 /** \relates Match \overload to disambiguate 'int|int'. */
224 inline Match operator|( Match::Mode lhs, Match::Mode rhs )
225 { return Match(lhs) |= rhs; }
227 /** \relates Match */
228 inline Match operator-( const Match & lhs, const Match & rhs )
229 { return Match(lhs) -= rhs; }
230 /** \relates Match \overload to disambiguate 'int-int'. */
231 inline Match operator-( Match::Mode lhs, Match::Mode rhs )
232 { return Match(lhs) -= rhs; }
234 /** \relates Match::Mode Stream output */
235 std::ostream & operator<<( std::ostream & str, Match::Mode obj );
237 /** \relates Match Stream output */
238 std::ostream & operator<<( std::ostream & str, const Match & obj );
241 ///////////////////////////////////////////////////////////////////
243 ///////////////////////////////////////////////////////////////////
245 // CLASS NAME : MatchException
247 /** Exceptions thrown from attribute matching. */
248 struct MatchException : public Exception
250 /** Supplied message. */
251 explicit MatchException( const std::string & msg_r ) : Exception( msg_r ) {}
254 /** Unknown match mode. */
255 struct MatchUnknownModeException : public MatchException
257 /** Supplied message. */
258 explicit MatchUnknownModeException( const std::string & msg_r ) : MatchException( msg_r ) {}
260 /** Build message including the \a mode and optional the pattern string. */
261 MatchUnknownModeException( const Match & mode_r, const std::string & msg_r = std::string() );
264 /** Invalid regular expression (failed ::regcomp). */
265 struct MatchInvalidRegexException : public MatchException
267 /** Supplied message. */
268 explicit MatchInvalidRegexException( const std::string & msg_r ) : MatchException( msg_r ) {}
270 /** Build message including the \a regex and \c ::regcomp returncode (use \c 0 if unknown). */
271 MatchInvalidRegexException( const std::string & regex_r, int regcomp_r );
274 ///////////////////////////////////////////////////////////////////
276 ///////////////////////////////////////////////////////////////////
278 { /////////////////////////////////////////////////////////////////
280 ///////////////////////////////////////////////////////////////////
282 // CLASS NAME : AttrMatcher
284 /** String matching (STRING|SUBSTRING|GLOB|REGEX).
286 * Used by e.g. \ref PoolQuery and \ref LookupAttr for queries,
287 * but it can also be used for matching arbitrary strings.
290 * AttrMatcher matches( "foo" );
291 * for_( it, stringlist.begin(), stringlist().end() )
293 * if ( matches( *it ) )
294 * cout << *it << " has substring 'foo'" << endl;
298 * \Note Those flags are always set: <tt>REG_EXTENDED | REG_NOSUB | REG_NEWLINE</tt>
300 class AttrMatcher : private base::SafeBool<AttrMatcher>
302 friend std::ostream & operator<<( std::ostream & str, const AttrMatcher & obj );
305 typedef MatchException Exception;
308 /** Implementation */
312 /** Default ctor matches nothing. */
315 /** Ctor from string matches in \ref Match::STRING mode per default. */
316 AttrMatcher( const std::string & search_r );
318 /** Ctor taking string and \ref Match flags. */
319 AttrMatcher( const std::string & search_r, const Match & flags_r );
321 /** Low level interface wraps \a flags into \ref Match. */
322 AttrMatcher( const std::string & search_r, int flags_r );
324 #ifndef SWIG // Swig treats it as syntax error
325 /** Evaluate in a boolean context <tt>( ! searchstring().empty() )</tt>. */
326 using base::SafeBool<AttrMatcher>::operator bool_type;
330 /** Return whether string matches.
331 * You can use it with any class that impements \c c_str.
332 * (\c std::string, \ref Pathname, \ref IdString, ...).
333 * \Note \c NULL never matches.
336 bool operator()( const _Tp & string_r ) const
337 { return doMatch( string_r.c_str() ); }
339 bool operator()( const char * string_r ) const
340 { return doMatch( string_r ); }
343 /** The current searchstring. */
344 const std::string & searchstring() const;
346 /** Set a new searchstring. */
347 void setSearchstring( const std::string & string_r );
349 /** Set a new searchstring and flags. */
350 void setSearchstring( const std::string & string_r, const Match & flags_r );
352 /** The current search flags. */
353 const Match & flags() const;
355 /** Set new search flags. */
356 void setFlags( const Match & flags_r );
359 /** Compile the pattern e.g. in case of \c REGEX.
360 * \throws MatchUnknownModeException If the \ref Match flag more than
362 * \throws MatchInvalidRegexException If \ref Match::REGEX is set
363 * and \ref searchstring is not a valid regular expression.
365 void compile() const;
367 /** Whether the \ref AttrMatcher is already compiled. */
368 bool isCompiled() const;
370 /** Return whether string matches.
371 * Compiles the \ref AttrMatcher if this was not yet done.
372 * \throws MatchException Any of the exceptions thrown by \ref AttrMatcher::compile.
374 bool doMatch( const char * string_r ) const;
377 friend base::SafeBool<AttrMatcher>::operator bool_type() const;
378 bool boolTest() const
379 { return !searchstring().empty(); }
382 /** Pointer to implementation */
383 RWCOW_pointer<Impl> _pimpl;
385 ///////////////////////////////////////////////////////////////////
387 /** \relates AttrMatcher Stream output */
388 std::ostream & operator<<( std::ostream & str, const AttrMatcher & obj );
390 /////////////////////////////////////////////////////////////////
392 ///////////////////////////////////////////////////////////////////
393 /////////////////////////////////////////////////////////////////
395 ///////////////////////////////////////////////////////////////////
396 #endif // ZYPP_SAT_ATTRMATCHER_H