00001
00002
00003
00004
00005
00006
00007
00008
00012 #ifndef ZYPP_GLOB_H
00013 #define ZYPP_GLOB_H
00014
00015 extern "C"
00016 {
00017 #include <glob.h>
00018 }
00019
00020 #include <iosfwd>
00021
00022 #include "zypp/base/Easy.h"
00023 #include "zypp/base/Flags.h"
00024 #include "zypp/base/Iterator.h"
00025 #include "zypp/base/NonCopyable.h"
00026 #include "zypp/base/DefaultIntegral.h"
00027
00028 #include "zypp/Pathname.h"
00029
00031 namespace zypp
00032 {
00033
00035 namespace filesystem
00036 {
00037
00039
00040
00041
00057 class Glob : private base::NonCopyable
00058 {
00059 public:
00060 typedef size_t size_type;
00061 typedef const char * value_type;
00062
00064 class const_iterator : public boost::iterator_adaptor<
00065 const_iterator
00066 , char **
00067 , value_type
00068 , boost::forward_traversal_tag
00069 , const value_type
00070 >
00071 {
00072 public:
00073 const_iterator()
00074 : const_iterator::iterator_adaptor_( 0 )
00075 {}
00076
00077 explicit const_iterator( char ** _idx )
00078 : const_iterator::iterator_adaptor_( _idx && *_idx ? _idx : 0 )
00079 {}
00080
00081 private:
00082 friend class boost::iterator_core_access;
00083 void increment()
00084 {
00085 if ( base_reference() && !*(++base_reference()) )
00086 base_reference() = 0;
00087 }
00088 reference dereference() const
00089 { return( base() ? *base() : 0 ); }
00090 };
00092
00093 public:
00095 enum Bits {
00096 _ERR = GLOB_ERR,
00097 _MARK = GLOB_MARK,
00098 _NOSORT = GLOB_NOSORT,
00099
00100 _NOCHECK = GLOB_NOCHECK,
00101
00102 _NOESCAPE = GLOB_NOESCAPE,
00103 _PERIOD = GLOB_PERIOD,
00104
00105 _ALTDIRFUNC = GLOB_ALTDIRFUNC,
00106 _BRACE = GLOB_BRACE,
00107 _NOMAGIC = GLOB_NOMAGIC,
00108 _TILDE = GLOB_TILDE,
00109 _ONLYDIR = GLOB_ONLYDIR,
00110 _TILDE_CHECK = GLOB_TILDE_CHECK,
00111 };
00112
00114 ZYPP_DECLARE_FLAGS( Flags, Bits );
00115
00116 public:
00121 Glob( Flags flags_r = Flags() )
00122 : _defaultFlags( flags_r )
00123 {}
00124
00129 explicit Glob( const Pathname & pattern_r, Flags flags_r = Flags() )
00130 : _defaultFlags( flags_r )
00131 { add( pattern_r, flags_r ); }
00133 explicit Glob( const std::string & pattern_r, Flags flags_r = Flags() )
00134 : _defaultFlags( flags_r )
00135 { add( pattern_r, flags_r ); }
00137 explicit Glob( const char * pattern_r, Flags flags_r = Flags() )
00138 : _defaultFlags( flags_r )
00139 { add( pattern_r, flags_r ); }
00140
00142 ~Glob()
00143 { if ( _result ) ::globfree( &(*_result) ); }
00144
00155 int add( const Pathname & pattern_r, Flags flags_r = Flags() )
00156 { return add( pattern_r.c_str(), flags_r ); }
00158 int add( const std::string & pattern_r, Flags flags_r = Flags() )
00159 { return add( pattern_r.c_str(), flags_r ); }
00161 int add( const char * pattern_r, Flags flags_r = Flags() );
00162
00164 void clear();
00165
00167 void reset( Flags flags_r = Flags() )
00168 { clear(); setDefaultFlags( flags_r ); }
00169
00170
00171 public:
00173 Flags defaultFlags() const
00174 { return _defaultFlags; }
00175
00177 void setDefaultFlags( Flags flags_r = Flags() )
00178 { _defaultFlags = flags_r; }
00179
00184 int lastGlobReturn() const
00185 { return _lastGlobReturn; }
00186
00187 public:
00189 bool empty() const
00190 { return ! ( _result && _result->gl_pathc ); }
00191
00193 size_type size() const
00194 { return( _result ? _result->gl_pathc : 0 ); }
00195
00197 const_iterator begin() const
00198 { return( _result ? const_iterator( _result->gl_pathv ) : const_iterator() ); }
00199
00201 const_iterator end() const
00202 { return const_iterator(); }
00203
00204 public:
00205
00215 template<class _OutputIterator>
00216 static int collect( const Pathname & pattern_r, _OutputIterator result_r )
00217 { return collect( pattern_r.c_str(), Flags(), result_r ); }
00219 template<class _OutputIterator>
00220 static int collect( const std::string & pattern_r, _OutputIterator result_r )
00221 { return collect( pattern_r.c_str(), Flags(), result_r ); }
00223 template<class _OutputIterator>
00224 static int collect( const char * pattern_r, _OutputIterator result_r )
00225 { return collect( pattern_r, Flags(), result_r ); }
00226
00228 template<class _OutputIterator>
00229 static int collect( const Pathname & pattern_r, Flags flags_r, _OutputIterator result_r )
00230 { return collect( pattern_r.c_str(), flags_r, result_r ); }
00232 template<class _OutputIterator>
00233 static int collect( const std::string & pattern_r, Flags flags_r, _OutputIterator result_r )
00234 { return collect( pattern_r.c_str(), flags_r, result_r ); }
00236 template<class _OutputIterator>
00237 static int collect( const char * pattern_r, Flags flags_r, _OutputIterator result_r )
00238 {
00239 Glob glob( pattern_r, flags_r );
00240 if ( glob.lastGlobReturn() == 0 )
00241 for_( it, glob.begin(), glob.end() )
00242 (*result_r)++ = typename _OutputIterator::container_type::value_type(*it);
00243 return glob.lastGlobReturn();
00244 }
00246
00247 private:
00248 Flags _defaultFlags;
00249 scoped_ptr< ::glob_t> _result;
00250 DefaultIntegral<int,0> _lastGlobReturn;
00251 };
00253
00255 std::ostream & operator<<( std::ostream & str, const Glob & obj );
00256
00258 inline std::ostream & operator<<( std::ostream & str, const Glob::const_iterator & obj )
00259 { return str << *obj; }
00260
00261 ZYPP_DECLARE_OPERATORS_FOR_FLAGS( Glob::Flags );
00262
00264
00266 }
00269 }
00271 #endif // ZYPP_GLOB_H