1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/StrMatcher.h
12 #ifndef ZYPP_BASE_STRMATCHER_H
13 #define ZYPP_BASE_STRMATCHER_H
18 #include "zypp/base/PtrTypes.h"
19 #include "zypp/base/Exception.h"
21 ///////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////
26 /// \brief String matching option flags as used e.g. by \ref StrMatcher.
29 /// Match mode( Match::GLOB | Match::NOCASE );
31 ///////////////////////////////////////////////////////////////////
35 static const int _modemask;
36 static const int _flagmask;
39 /** Mode flags (mutual exclusive). */
42 NOTHING, //!< Match nothing
43 STRING, //!< Excat matching
44 STRINGSTART, //!< Match at string start
45 STRINGEND, //!< Match at string end
46 SUBSTRING, //!< Match substring
48 REGEX, //!< Regular Expression
49 OTHER //!< Something else.
52 /** \name \ref Option flags
53 * Most flags are actually \ref sat::LookupAttr specific, as they tell
54 * how to retrieve the attribute values from solv-files. The plain
55 * \ref StrMatcher will ignore those flags and use the ones related
56 * to string matching only.
59 static const Match NOCASE; //!< If set, match case insensitive.
62 /** \name \ref sat::LookupAttr option flags
63 * These flags are actually \ref sat::LookupAttr specific, as they tell
64 * how to retrieve the attribute values from solv-files. The plain
65 * \ref StrMatcher will ignore these flags and use the ones related
66 * to string matching only.
69 static const Match NO_STORAGE_SOLVABLE; //!< LookupAttr: internal
70 static const Match SUB; //!< LookupAttr: internal
71 static const Match ARRAYSENTINEL; //!< LookupAttr: internal
72 static const Match DISABLED_REPOS; //!< LookupAttr: internal
73 static const Match COMPLETE_FILELIST; //!< LookupAttr: internal
74 static const Match SKIP_KIND; //!< LookupAttr: skip any \c kind: prefix when looking at a \ref Solvable name.
75 static const Match FILES; //!< LookupAttr: match full path when matching in filelists, otherwise just the basenames.
76 static const Match CHECKSUMS; //!< LookupAttr: also look for matches in checksums
80 /** Default ctor \c 0 or \ref NOTHING. */
85 /** Ctor from \ref Mode value. */
87 : _val( modeval( val_r ) )
90 /** Just in case one needs it. */
91 explicit Match( int val_r )
95 /** Evaluate in a boolean context <tt>( != 0 )</tt>. */
96 explicit operator bool() const
100 /** Test whether \c all of the \a rhs bits are set (same mode if \a rhs has one). */
101 bool test( const Match & rhs ) const
102 { return ( ( flagval() & rhs.flagval() ) == rhs.flagval() ) && ( !rhs.modeval() || rhs.modeval() == modeval() ); }
104 /** Whether at least one of the \a rhs bits is set (or the same mode). */
105 bool testAnyOf( const Match & rhs ) const
106 { return ( flagval() & rhs.flagval() ) || ( rhs.modeval() && rhs.modeval() == modeval() ); }
108 /** Set all of the \a rhs bits (setting a new mode if \a rhs has one). */
109 void set( const Match & rhs )
112 _val = rhs._val | flagval(); // also set the rhs mode
114 _val |= rhs._val; // just set the flags
117 /** Unset all of the \a rhs bits (unsets mode if the same as \a rhs). */
118 void unset( const Match & rhs )
120 if ( modeval() == rhs.modeval() )
121 _val = flagval() & ~rhs.flagval(); // also unset mode
123 _val &= ~rhs.flagval(); // just unset falgs
126 /** Depending on the value of \a onoff, set or unset flags. */
127 void turn( const Match & rhs, bool onoff )
128 { onoff ? set( rhs ) : unset( rhs ); }
131 Match & operator|=( const Match & rhs )
132 { set( rhs ); return *this; }
135 Match & operator-=( const Match & rhs )
136 { unset( rhs ); return *this; }
139 /** Return the \c mode part. */
142 /** Return the \c flags part. */
144 { return Match( flagval() ); }
147 /** \name Low level integer representation. */
149 /** Return the integer representation. */
150 int get() const { return _val; }
151 /** Return the modes integer representation. */
152 int modeval() const { return _val & _modemask; }
153 /** Return the flags integer representation. */
154 int flagval() const { return _val & _flagmask; }
158 /** \name Mode flag manip/query convenience. */
160 /** Whether this has mode \a rhs */
161 bool isMode( Mode rhs ) const
162 { return modeval() == modeval( rhs ); }
163 /** Whether this has mode \ref STRING. */
164 bool isModeString() const
165 { return isMode( STRING ); }
166 /** Whether this has mode \ref STRINGSTART. */
167 bool isModeStringstart() const
168 { return isMode( STRINGSTART ); }
169 /** Whether this has mode \ref STRINGEND. */
170 bool isModeStringend() const
171 { return isMode( STRINGEND ); }
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 STRINGSTART. */
189 void setModeStringstart()
190 { setMode( STRINGSTART ); }
191 /** Set the mode \ref STRINGEND. */
192 void setModeStringend()
193 { setMode( STRINGEND ); }
194 /** Set the mode \ref SUBSTRING. */
195 void setModeSubstring()
196 { setMode( SUBSTRING ); }
197 /** Set the mode \ref GLOB. */
200 /** Set the mode \ref REGEX. */
202 { setMode( REGEX ); }
205 /** String representation. */
206 std::string asString() const;
209 /** Numeric value for enum (short for <tt>Match(m).get()</tt>). */
210 static int modeval( Mode mode_r );
216 /** \relates Match */
217 inline bool operator==( const Match & lhs, const Match & rhs )
218 { return lhs.get() == rhs.get(); }
219 /** \relates Match */
220 inline bool operator!=( const Match & lhs, const Match & rhs )
221 { return lhs.get() != rhs.get(); }
223 /** \relates Match */
224 inline Match operator|( const Match & lhs, const Match & rhs )
225 { return Match(lhs) |= rhs; }
226 /** \relates Match \overload to disambiguate 'int|int'. */
227 inline Match operator|( Match::Mode lhs, Match::Mode rhs )
228 { return Match(lhs) |= rhs; }
230 /** \relates Match */
231 inline Match operator-( const Match & lhs, const Match & rhs )
232 { return Match(lhs) -= rhs; }
233 /** \relates Match \overload to disambiguate 'int-int'. */
234 inline Match operator-( Match::Mode lhs, Match::Mode rhs )
235 { return Match(lhs) -= rhs; }
237 /** \relates Match::Mode Stream output */
238 std::ostream & operator<<( std::ostream & str, Match::Mode obj );
240 /** \relates Match Stream output */
241 std::ostream & operator<<( std::ostream & str, const Match & obj );
243 ///////////////////////////////////////////////////////////////////
244 /// \class MatchException
245 /// \brief Exceptions thrown from attribute matching.
246 ///////////////////////////////////////////////////////////////////
247 struct MatchException : public Exception
249 /** Supplied message. */
250 explicit MatchException( const std::string & msg_r ) : Exception( msg_r ) {}
253 ///////////////////////////////////////////////////////////////////
254 /// \class MatchUnknownModeException
255 /// \brief Unknown match mode.
256 ///////////////////////////////////////////////////////////////////
257 struct MatchUnknownModeException : public MatchException
259 /** Supplied message. */
260 explicit MatchUnknownModeException( const std::string & msg_r ) : MatchException( msg_r ) {}
262 /** Build message including the \a mode and optional the pattern string. */
263 MatchUnknownModeException( const Match & mode_r, const std::string & msg_r = std::string() );
266 ///////////////////////////////////////////////////////////////////
267 /// \class MatchInvalidRegexException
268 /// \brief Invalid regular expression (failed ::regcomp).
269 ///////////////////////////////////////////////////////////////////
270 struct MatchInvalidRegexException : public MatchException
272 /** Supplied message. */
273 explicit MatchInvalidRegexException( const std::string & msg_r ) : MatchException( msg_r ) {}
275 /** Build message including the \a regex and \c ::regcomp returncode (use \c 0 if unknown). */
276 MatchInvalidRegexException( const std::string & regex_r, int regcomp_r );
279 ///////////////////////////////////////////////////////////////////
280 /// \class StrMatcher
281 /// \brief String matching (STRING|SUBSTRING|GLOB|REGEX).
283 /// Used by e.g. \ref PoolQuery and \ref LookupAttr for queries,
284 /// but it can also be used for matching arbitrary strings.
287 /// StrMatcher matches( "foo", Match::SUBSTRING );
288 /// for_( it, stringlist.begin(), stringlist().end() )
290 /// if ( matches( *it ) )
291 /// cout << *it << " has substring 'foo'" << endl;
295 /// \Note Those flags are always set: <tt>REG_EXTENDED | REG_NOSUB | REG_NEWLINE</tt>
296 ///////////////////////////////////////////////////////////////////
299 friend std::ostream & operator<<( std::ostream & str, const StrMatcher & obj );
302 typedef MatchException Exception;
305 /** Implementation */
309 /** Default ctor matches nothing. */
312 /** Ctor from string matches in \ref Match::STRING mode per default. */
313 StrMatcher( const std::string & search_r );
314 /** \overload for rvalues */
315 StrMatcher( std::string && search_r );
317 /** Ctor taking string and \ref Match flags. */
318 StrMatcher( const std::string & search_r, const Match & flags_r );
319 /** \overload for rvalues */
320 StrMatcher( std::string && search_r, const Match & flags_r );
322 /** Ctor taking string and \ref Match::Mode.
323 * Needed because we want them to be treated as \ref Match,
324 * and not as \ref int as the compiler woud do.
326 StrMatcher( const std::string & search_r, const Match::Mode & flags_r );
327 /** \overload for rvalues */
328 StrMatcher( std::string && search_r, const Match::Mode & flags_r );
330 /** Low level interface wraps \a flags into \ref Match. */
331 StrMatcher( const std::string & search_r, int flags_r );
332 /** \overload for rvalues */
333 StrMatcher( std::string && search_r, int flags_r );
335 /** Evaluate in a boolean context <tt>( ! searchstring().empty() )</tt>. */
336 explicit operator bool() const
337 { return !searchstring().empty(); }
340 /** Return whether string matches.
341 * You can use it with any class that impements \c c_str.
342 * (\c std::string, \ref Pathname, \ref IdString, ...).
343 * \Note \c NULL never matches.
346 bool operator()( const Tp & string_r ) const
347 { return doMatch( string_r.c_str() ); }
349 bool operator()( const char * string_r ) const
350 { return doMatch( string_r ); }
353 /** The current searchstring. */
354 const std::string & searchstring() const;
356 /** Set a new searchstring. */
357 void setSearchstring( const std::string & string_r );
358 /** \overload for rvalues */
359 void setSearchstring( std::string && string_r );
361 /** Set a new searchstring and flags. */
362 void setSearchstring( const std::string & string_r, const Match & flags_r );
363 /** \overload for rvalues */
364 void setSearchstring( std::string && string_r, const Match & flags_r );
366 /** The current search flags. */
367 const Match & flags() const;
369 /** Set new search flags. */
370 void setFlags( const Match & flags_r );
373 /** Compile the pattern e.g. in case of \c REGEX.
374 * \throws MatchUnknownModeException If the \ref Match flag more than
376 * \throws MatchInvalidRegexException If \ref Match::REGEX is set
377 * and \ref searchstring is not a valid regular expression.
379 void compile() const;
381 /** Whether the \ref StrMatcher is already compiled. */
382 bool isCompiled() const;
384 /** Return whether string matches.
385 * Compiles the \ref StrMatcher if this was not yet done.
386 * \throws MatchException Any of the exceptions thrown by \ref StrMatcher::compile.
388 bool doMatch( const char * string_r ) const;
391 /** Pointer to implementation */
392 RWCOW_pointer<Impl> _pimpl;
395 /** \relates StrMatcher Stream output */
396 std::ostream & operator<<( std::ostream & str, const StrMatcher & obj );
398 /** \relates StrMatcher */
399 bool operator==( const StrMatcher & lhs, const StrMatcher & rhs );
401 /** \relates StrMatcher */
402 inline bool operator!=( const StrMatcher & lhs, const StrMatcher & rhs )
403 { return !( lhs == rhs ); }
405 /** \relates StrMatcher Arbitrary order for std::container. */
406 bool operator<( const StrMatcher & lhs, const StrMatcher & rhs );
409 ///////////////////////////////////////////////////////////////////
410 #endif // ZYPP_BASE_STRMATCHER_H