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.
38 * Match mode( Match::GLOB | Match::NOCASE );
41 class Match : private base::SafeBool<Match>
44 static const int _modemask;
45 static const int _flagmask;
48 /** Mode flags (mutual exclusive). */
51 NOTHING, //!< Match nothing
52 STRING, //!< Excat matching
53 SUBSTRING, //!< Match substring
55 REGEX, //!< Regular Expression
56 OTHER //!< Something else.
59 /** \name Option flags
60 * Some flags are actually \ref sat::LookupAttr specific, as they tell
61 * how to retrieve the attribute values. The plain \ref sat::AttrMatcher
62 * will ignore those flags and use the ones related to string matching only
66 /** If set, match case insensitive. */
67 static const Match NOCASE;
69 static const Match NO_STORAGE_SOLVABLE;
71 static const Match SUB;
73 static const Match ARRAYSENTINEL;
74 /** If set, skip any \c kind: prefix when looking at a \ref Solvable name. */
75 static const Match SKIP_KIND;
76 /** If set, match full path when matching in filelists, otherwise just the basenames. */
77 static const Match FILES;
81 /** Default ctor \c 0 or \ref NOTHING. */
86 /** Ctor from \ref Mode value. */
88 : _val( modeval( val_r ) )
91 /** Just in case one needs it. */
92 explicit Match( int val_r )
96 #ifndef SWIG // Swig treats it as syntax error
97 /** Evaluate in a boolean context <tt>( != 0 )</tt>. */
98 using base::SafeBool<Match>::operator bool_type;
102 /** Test whether \c all of the \a rhs bits are set (same mode if \a rhs has one). */
103 bool test( const Match & rhs ) const
104 { return ( ( flagval() & rhs.flagval() ) == rhs.flagval() )
105 && ( !rhs.modeval() || rhs.modeval() == modeval() ); }
107 /** Whether at least one of the \a rhs bits is set (or the same mode). */
108 bool testAnyOf( const Match & rhs ) const
109 { return ( flagval() & rhs.flagval() )
110 || ( rhs.modeval() && rhs.modeval() == modeval() ); }
112 /** Set all of the \a rhs bits (setting a new mode if \a rhs has one). */
113 void set( const Match & rhs )
116 _val = rhs._val | flagval(); // also set the rhs mode
118 _val |= rhs._val; // just set the flags
121 /** Unset all of the \a rhs bits (unsets mode if the same as \a rhs). */
122 void unset( const Match & rhs )
124 if ( modeval() == rhs.modeval() )
125 _val = flagval() & ~rhs.flagval(); // also unset mode
127 _val &= ~rhs.flagval(); // just unset falgs
130 /** Depending on the value of \a onoff, set or unset flags. */
131 void turn( const Match & rhs, bool onoff )
132 { onoff ? set( rhs ) : unset( rhs ); }
135 Match & operator|=( const Match & rhs )
136 { set( rhs ); return *this; }
139 Match & operator-=( const Match & rhs )
140 { unset( rhs ); return *this; }
143 /** Return the \c mode part. */
146 /** Return the \c flags part. */
148 { return Match( flagval() ); }
151 /** \name Low level integer representation. */
153 /** Return the integer representation. */
154 int get() const { return _val; }
155 /** Return the modes integer representation. */
156 int modeval() const { return _val & _modemask; }
157 /** Return the flags integer representation. */
158 int flagval() const { return _val & _flagmask; }
162 /** \name Mode flag manip/query convenience. */
164 /** Whether this has mode \a rhs */
165 bool isMode( Mode rhs ) const
166 { return modeval() == modeval( rhs ); }
167 /** Whether this has mode \ref STRING. */
168 bool isModeString() const
169 { return isMode( STRING ); }
170 /** Whether this has mode \ref SUBSTRING. */
171 bool isModeSubstring() const
172 { return isMode( SUBSTRING ); }
173 /** Whether this has mode \ref GLOB. */
174 bool isModeGlob() const
175 { return isMode( GLOB ); }
176 /** Whether this has mode \ref REGEX. */
177 bool isModeRegex() const
178 { return isMode( REGEX ); }
180 /** Set the mode part to \a rhs . */
181 void setMode( Mode rhs )
182 { _val = modeval( rhs ) | flagval(); }
183 /** Set the mode \ref STRING. */
185 { setMode( STRING ); }
186 /** Set the mode \ref SUBSTRING. */
187 void setModeSubstring()
188 { setMode( SUBSTRING ); }
189 /** Set the mode \ref GLOB. */
192 /** Set the mode \ref REGEX. */
194 { setMode( REGEX ); }
197 /** String representation. */
198 std::string asString() const;
201 friend base::SafeBool<Match>::operator bool_type() const;
202 bool boolTest() const { return _val; }
204 /** Numeric value for enum (short for <tt>Match(m).get()</tt>). */
205 static int modeval( Mode mode_r );
211 /** \relates Match */
212 inline bool operator==( const Match & lhs, const Match & rhs )
213 { return lhs.get() == rhs.get(); }
214 /** \relates Match */
215 inline bool operator!=( const Match & lhs, const Match & rhs )
216 { return lhs.get() != rhs.get(); }
218 /** \relates Match */
219 inline Match operator|( const Match & lhs, const Match & rhs )
220 { return Match(lhs) |= rhs; }
221 /** \relates Match \overload to disambiguate 'int|int'. */
222 inline Match operator|( Match::Mode lhs, Match::Mode rhs )
223 { return Match(lhs) |= rhs; }
225 /** \relates Match */
226 inline Match operator-( const Match & lhs, const Match & rhs )
227 { return Match(lhs) -= rhs; }
228 /** \relates Match \overload to disambiguate 'int-int'. */
229 inline Match operator-( Match::Mode lhs, Match::Mode rhs )
230 { return Match(lhs) -= rhs; }
232 /** \relates Match::Mode Stream output */
233 std::ostream & operator<<( std::ostream & str, Match::Mode obj );
235 /** \relates Match Stream output */
236 std::ostream & operator<<( std::ostream & str, const Match & obj );
239 ///////////////////////////////////////////////////////////////////
241 ///////////////////////////////////////////////////////////////////
243 // CLASS NAME : MatchException
245 /** Exceptions thrown from attribute matching. */
246 struct MatchException : public Exception
248 /** Supplied message. */
249 explicit MatchException( const std::string & msg_r ) : Exception( msg_r ) {}
252 /** Unknown match mode. */
253 struct MatchUnknownModeException : public MatchException
255 /** Supplied message. */
256 explicit MatchUnknownModeException( const std::string & msg_r ) : MatchException( msg_r ) {}
258 /** Build message including the \a mode and optional the pattern string. */
259 MatchUnknownModeException( const Match & mode_r, const std::string & msg_r = std::string() );
262 /** Invalid regular expression (failed ::regcomp). */
263 struct MatchInvalidRegexException : public MatchException
265 /** Supplied message. */
266 explicit MatchInvalidRegexException( const std::string & msg_r ) : MatchException( msg_r ) {}
268 /** Build message including the \a regex and \c ::regcomp returncode (use \c 0 if unknown). */
269 MatchInvalidRegexException( const std::string & regex_r, int regcomp_r );
272 ///////////////////////////////////////////////////////////////////
274 ///////////////////////////////////////////////////////////////////
276 { /////////////////////////////////////////////////////////////////
278 ///////////////////////////////////////////////////////////////////
280 // CLASS NAME : AttrMatcher
282 /** String matching (STRING|SUBSTRING|GLOB|REGEX).
284 * Used by e.g. \ref PoolQuery and \ref LookupAttr for queries,
285 * but it can also be used for matching arbitrary strings.
288 * AttrMatcher matches( "foo" );
289 * for_( it, stringlist.begin(), stringlist().end() )
291 * if ( matches( *it ) )
292 * cout << *it << " has substring 'foo'" << endl;
296 * \Note Those flags are always set: <tt>REG_EXTENDED | REG_NOSUB | REG_NEWLINE</tt>
298 class AttrMatcher : private base::SafeBool<AttrMatcher>
300 friend std::ostream & operator<<( std::ostream & str, const AttrMatcher & obj );
303 typedef MatchException Exception;
306 /** Implementation */
310 /** Default ctor matches nothing. */
313 /** Ctor from string matches in \ref Match::STRING mode per default. */
314 AttrMatcher( const std::string & search_r );
316 /** Ctor taking string and \ref Match flags. */
317 AttrMatcher( const std::string & search_r, const Match & flags_r );
319 /** Low level interface wraps \a flags into \ref Match. */
320 AttrMatcher( const std::string & search_r, int flags_r );
322 #ifndef SWIG // Swig treats it as syntax error
323 /** Evaluate in a boolean context <tt>( ! searchstring().empty() )</tt>. */
324 using base::SafeBool<AttrMatcher>::operator bool_type;
328 /** Return whether string matches.
329 * You can use it with any class that impements \c c_str.
330 * (\c std::string, \ref Pathname, \ref IdString, ...).
331 * \Note \c NULL never matches.
334 bool operator()( const _Tp & string_r ) const
335 { return doMatch( string_r.c_str() ); }
337 bool operator()( const char * string_r ) const
338 { return doMatch( string_r ); }
341 /** The current searchstring. */
342 const std::string & searchstring() const;
344 /** Set a new searchstring. */
345 void setSearchstring( const std::string & string_r );
347 /** Set a new searchstring and flags. */
348 void setSearchstring( const std::string & string_r, const Match & flags_r );
350 /** The current search flags. */
351 const Match & flags() const;
353 /** Set new search flags. */
354 void setFlags( const Match & flags_r );
357 /** Compile the pattern e.g. in case of \c REGEX.
358 * \throws MatchUnknownModeException If the \ref Match flag more than
360 * \throws MatchInvalidRegexException If \ref Match::REGEX is set
361 * and \ref searchstring is not a valid regular expression.
363 void compile() const;
365 /** Whether the \ref AttrMatcher is already compiled. */
366 bool isCompiled() const;
368 /** Return whether string matches.
369 * Compiles the \ref AttrMatcher if this was not yet done.
370 * \throws MatchException Any of the exceptions thrown by \ref AttrMatcher::compile.
372 bool doMatch( const char * string_r ) const;
375 friend base::SafeBool<AttrMatcher>::operator bool_type() const;
376 bool boolTest() const
377 { return !searchstring().empty(); }
380 /** Pointer to implementation */
381 RWCOW_pointer<Impl> _pimpl;
383 ///////////////////////////////////////////////////////////////////
385 /** \relates AttrMatcher Stream output */
386 std::ostream & operator<<( std::ostream & str, const AttrMatcher & obj );
388 /////////////////////////////////////////////////////////////////
390 ///////////////////////////////////////////////////////////////////
391 /////////////////////////////////////////////////////////////////
393 ///////////////////////////////////////////////////////////////////
394 #endif // ZYPP_SAT_ATTRMATCHER_H