libzypp  10.5.0
Glob.h
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
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     //  CLASS NAME : Glob
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                // Derived
00066             , char **                       // Base
00067             , value_type                    // Value
00068             , boost::forward_traversal_tag  // CategoryOrTraversal
00069             , const value_type              // Reference
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           // unsupported _DOOFFS = GLOB_DOOFFS, //!< Insert PGLOB->gl_offs NULLs.
00100           _NOCHECK      = GLOB_NOCHECK,         
00101           // autoapplied _APPEND = GLOB_APPEND, //!< Append to results of a previous call.
00102           _NOESCAPE     = GLOB_NOESCAPE,        
00103           _PERIOD       = GLOB_PERIOD,          
00104           // unsupported _MAGCHAR = GLOB_MAGCHAR,//!< Set in gl_flags if any metachars seen.
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   } // namespace filesystem
00269 } // namespace zypp
00271 #endif // ZYPP_GLOB_H