Cleanup and remove deprecated interface methods
[platform/upstream/libzypp.git] / zypp / sat / AttrMatcher.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/AttrMatcher.h
10  *
11 */
12 #ifndef ZYPP_SAT_ATTRMATCHER_H
13 #define ZYPP_SAT_ATTRMATCHER_H
14
15 extern "C"
16 {
17 struct _Datamatcher;
18 }
19
20 #include <iosfwd>
21 #include <string>
22
23 #include "zypp/base/PtrTypes.h"
24 #include "zypp/base/SafeBool.h"
25 #include "zypp/base/Exception.h"
26
27 ///////////////////////////////////////////////////////////////////
28 namespace zypp
29 { /////////////////////////////////////////////////////////////////
30
31   ///////////////////////////////////////////////////////////////////
32   //
33   //    CLASS NAME : Match
34   //
35   /** String matching option flags as used e.g. by \ref sat::AttrMatcher.
36    *
37    * \code
38    * Match mode( Match::GLOB | Match::NOCASE );
39    * \endcode
40    */
41   class Match : private base::SafeBool<Match>
42   {
43     private:
44       static const int _modemask;
45       static const int _flagmask;
46
47     public:
48       /** Mode flags (mutual exclusive). */
49       enum Mode
50       {
51         NOTHING,        //!< Match nothing
52         STRING,         //!< Excat matching
53         SUBSTRING,      //!< Match substring
54         GLOB,           //!< Glob
55         REGEX,          //!< Regular Expression
56         OTHER           //!< Something else.
57       };
58
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
63        * (like \ref NOCASE).
64        */
65       //@{
66       /** If set, match case insensitive. */
67       static const Match NOCASE;
68       /** internal */
69       static const Match NO_STORAGE_SOLVABLE;
70       /** internal */
71       static const Match SUB;
72       /** internal */
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;
78       //@}
79
80     public:
81       /** Default ctor \c 0 or \ref NOTHING. */
82       Match()
83       : _val( 0 )
84       {}
85
86       /** Ctor from \ref Mode value. */
87       Match( Mode val_r )
88       : _val( modeval( val_r ) )
89       {}
90
91       /** Just in case one needs it. */
92       explicit Match( int val_r )
93       : _val( val_r )
94       {}
95
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;
99 #endif
100
101     public:
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() ); }
106
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() ); }
111
112       /** Set all of the \a rhs bits (setting a new mode if \a rhs has one). */
113       void set( const Match & rhs )
114       {
115         if ( rhs.modeval() )
116           _val = rhs._val | flagval(); // also set the rhs mode
117         else
118           _val |= rhs._val; // just set the flags
119       }
120
121       /** Unset all of the \a rhs bits (unsets mode if the same as \a rhs). */
122       void unset( const Match & rhs )
123       {
124         if ( modeval() == rhs.modeval() )
125           _val = flagval() & ~rhs.flagval(); // also unset mode
126         else
127           _val &= ~rhs.flagval(); // just unset falgs
128       }
129
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 ); }
133
134       /** Add flags. */
135       Match & operator|=( const Match & rhs )
136       { set( rhs ); return *this; }
137
138       /** Remove flags.*/
139       Match & operator-=( const Match & rhs )
140       { unset( rhs ); return *this; }
141
142     public:
143       /** Return the \c mode part. */
144       Mode mode() const;
145
146       /** Return the \c flags part. */
147       Match flags() const
148       { return Match( flagval() ); }
149
150     public:
151       /** \name Low level integer representation. */
152       //@{
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; }
159       //@}
160
161     public:
162       /** \name Mode flag manip/query convenience. */
163       //@{
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 ); }
179
180       /** Set the mode part to \a rhs . */
181       void setMode( Mode rhs )
182       { _val = modeval( rhs ) | flagval(); }
183       /** Set the mode \ref STRING. */
184       void setModeString()
185       { setMode( STRING ); }
186       /** Set the mode \ref SUBSTRING. */
187       void setModeSubstring()
188       { setMode( SUBSTRING ); }
189       /** Set the mode \ref GLOB. */
190       void setModeGlob()
191       { setMode( GLOB ); }
192       /** Set the mode \ref REGEX. */
193       void setModeRegex()
194       { setMode( REGEX ); }
195       //@}
196
197       /** String representation. */
198       std::string asString() const;
199
200     private:
201       friend base::SafeBool<Match>::operator bool_type() const;
202       bool boolTest() const     { return _val; }
203
204       /** Numeric value for enum (short for <tt>Match(m).get()</tt>). */
205       static int modeval( Mode mode_r );
206
207     private:
208       int _val;
209   };
210
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(); }
217
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; }
224
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; }
231
232   /** \relates Match::Mode Stream output */
233   std::ostream & operator<<( std::ostream & str, Match::Mode obj );
234
235   /** \relates Match Stream output */
236   std::ostream & operator<<( std::ostream & str, const Match & obj );
237
238
239   ///////////////////////////////////////////////////////////////////
240
241   ///////////////////////////////////////////////////////////////////
242   //
243   //    CLASS NAME : MatchException
244   //
245   /** Exceptions thrown from attribute matching. */
246   struct MatchException : public Exception
247   {
248     /** Supplied message. */
249     explicit MatchException( const std::string & msg_r ) : Exception( msg_r ) {}
250   };
251
252   /** Unknown match mode. */
253   struct MatchUnknownModeException : public MatchException
254   {
255     /** Supplied message. */
256     explicit MatchUnknownModeException( const std::string & msg_r ) : MatchException( msg_r ) {}
257
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() );
260   };
261
262   /** Invalid regular expression (failed ::regcomp). */
263   struct MatchInvalidRegexException : public MatchException
264   {
265     /** Supplied message. */
266     explicit MatchInvalidRegexException( const std::string & msg_r ) : MatchException( msg_r ) {}
267
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 );
270   };
271
272   ///////////////////////////////////////////////////////////////////
273
274   ///////////////////////////////////////////////////////////////////
275   namespace sat
276   { /////////////////////////////////////////////////////////////////
277
278     ///////////////////////////////////////////////////////////////////
279     //
280     //  CLASS NAME : AttrMatcher
281     //
282     /** String matching (STRING|SUBSTRING|GLOB|REGEX).
283      *
284      * Used by e.g. \ref PoolQuery and \ref LookupAttr for queries,
285      * but it can also be used for matching arbitrary strings.
286      *
287      * \code
288      *  AttrMatcher matches( "foo" );
289      *  for_( it, stringlist.begin(), stringlist().end() )
290      *  {
291      *    if ( matches( *it ) )
292      *      cout << *it << " has substring 'foo'" << endl;
293      *  }
294      * \endcode
295      *
296      * \Note Those flags are always set: <tt>REG_EXTENDED | REG_NOSUB | REG_NEWLINE</tt>
297      */
298     class AttrMatcher : private base::SafeBool<AttrMatcher>
299     {
300       friend std::ostream & operator<<( std::ostream & str, const AttrMatcher & obj );
301
302       public:
303         typedef MatchException Exception;
304
305       public:
306         /** Implementation  */
307         class Impl;
308
309       public:
310         /** Default ctor matches nothing. */
311         AttrMatcher();
312
313         /** Ctor from string matches in \ref Match::STRING mode per default. */
314         AttrMatcher( const std::string & search_r );
315
316         /** Ctor taking string and \ref Match flags. */
317         AttrMatcher( const std::string & search_r, const Match & flags_r );
318
319         /** Low level interface wraps \a flags into \ref Match. */
320         AttrMatcher( const std::string & search_r, int flags_r );
321
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;
325 #endif
326
327       public:
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.
332          */
333         template<class _Tp>
334             bool operator()( const _Tp & string_r ) const
335         { return doMatch( string_r.c_str() ); }
336         /** \overload */
337         bool operator()( const char * string_r ) const
338         { return doMatch( string_r ); }
339
340       public:
341         /** The current searchstring. */
342         const std::string & searchstring() const;
343
344         /** Set a new searchstring. */
345         void setSearchstring( const std::string & string_r );
346
347         /** Set a new searchstring and flags. */
348         void setSearchstring( const std::string & string_r, const Match & flags_r );
349
350         /** The current search flags. */
351         const Match & flags() const;
352
353         /** Set new search flags. */
354         void setFlags( const Match & flags_r );
355
356       public:
357         /** Compile the pattern e.g. in case of \c REGEX.
358          * \throws MatchUnknownModeException If the \ref Match flag more than
359          *         one mode bit set.
360          * \throws MatchInvalidRegexException If \ref Match::REGEX is set
361          *         and \ref searchstring is not a valid regular expression.
362          */
363         void compile() const;
364
365         /** Whether the \ref AttrMatcher is already compiled. */
366         bool isCompiled() const;
367
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.
371          */
372         bool doMatch( const char * string_r ) const;
373
374       private:
375         friend base::SafeBool<AttrMatcher>::operator bool_type() const;
376         bool boolTest() const
377         { return !searchstring().empty(); }
378
379       private:
380         /** Pointer to implementation */
381         RWCOW_pointer<Impl> _pimpl;
382     };
383     ///////////////////////////////////////////////////////////////////
384
385     /** \relates AttrMatcher Stream output */
386     std::ostream & operator<<( std::ostream & str, const AttrMatcher & obj );
387
388     /////////////////////////////////////////////////////////////////
389   } // namespace sat
390   ///////////////////////////////////////////////////////////////////
391   /////////////////////////////////////////////////////////////////
392 } // namespace zypp
393 ///////////////////////////////////////////////////////////////////
394 #endif // ZYPP_SAT_ATTRMATCHER_H