1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
22 #include "zypp/base/Easy.h"
23 #include "zypp/base/Flags.h"
24 #include "zypp/base/Iterator.h"
25 #include "zypp/base/NonCopyable.h"
26 #include "zypp/base/DefaultIntegral.h"
28 ///////////////////////////////////////////////////////////////////
30 { /////////////////////////////////////////////////////////////////
32 ///////////////////////////////////////////////////////////////////
34 { /////////////////////////////////////////////////////////////////
36 ///////////////////////////////////////////////////////////////////
40 /** Find pathnames matching a pattern.
42 * Glob glob( Glob::_BRACE );
43 * glob.add( "/somewherre/solverTestcase/ *{.xml,.xml.gz}" );
46 * std::list<Pathname> plist;
47 * Glob::collect( "/somewherre/solverTestcase/ *{.xml,.xml.gz}", Glob::_BRACE,
48 * std::back_inserter( plist ) );
50 * \see Manual page glob(3)
52 class Glob : private base::NonCopyable
55 typedef size_t size_type;
56 typedef const char * value_type;
58 /** Iterate NULL terminated \c char* array. */
59 class const_iterator : public boost::iterator_adaptor<
60 const_iterator // Derived
63 , boost::forward_traversal_tag // CategoryOrTraversal
64 , const value_type & // Reference
69 : const_iterator::iterator_adaptor_( 0 )
72 explicit const_iterator( char ** _idx )
73 : const_iterator::iterator_adaptor_( _idx && *_idx ? _idx : 0 )
77 friend class boost::iterator_core_access;
80 if ( base_reference() && !*(++base_reference()) )
84 ///////////////////////////////////////////////////////////////////
87 /** Individual bits to combine in \ref Flags. */
89 _ERR = GLOB_ERR, //!< Return on read errors.
90 _MARK = GLOB_MARK, //!< Append a slash to each name.
91 _NOSORT = GLOB_NOSORT, //!< Don't sort the names.
92 // unsupported _DOOFFS = GLOB_DOOFFS, //!< Insert PGLOB->gl_offs NULLs.
93 _NOCHECK = GLOB_NOCHECK, //!< If nothing matches, return the pattern.
94 // autoapplied _APPEND = GLOB_APPEND, //!< Append to results of a previous call.
95 _NOESCAPE = GLOB_NOESCAPE, //!< Backslashes don't quote metacharacters.
96 _PERIOD = GLOB_PERIOD, //!< Leading `.' can be matched by metachars.
97 // unsupported _MAGCHAR = GLOB_MAGCHAR,//!< Set in gl_flags if any metachars seen.
98 _ALTDIRFUNC = GLOB_ALTDIRFUNC, //!< Use gl_opendir et al functions.
99 _BRACE = GLOB_BRACE, //!< Expand "{a,b}" to "a" "b".
100 _NOMAGIC = GLOB_NOMAGIC, //!< If no magic chars, return the pattern.
101 _TILDE = GLOB_TILDE, //!< Expand ~user and ~ to home directories.
102 _ONLYDIR = GLOB_ONLYDIR, //!< Match only directories.
103 _TILDE_CHECK = GLOB_TILDE_CHECK, //!< Like GLOB_TILDE but return an error if the user name is not available.
106 /** type Flags: Type-safe OR-combination of \ref Bits. */
107 ZYPP_DECLARE_FLAGS( Flags, Bits );
110 /** Default ctor optionally taking the default flags.
111 * The flags passed here are the default for \ref add.
113 Glob( Flags flags_r = Flags() )
114 : _defaultFlags( flags_r )
117 /** Ctor adding pathnames matching \a pattern_r.
118 * The flags passed here are the default for \ref add.
120 explicit Glob( const std::string & pattern_r, Flags flags_r = Flags() )
121 : _defaultFlags( flags_r )
122 { add( pattern_r, flags_r ); }
126 { if ( _result ) ::globfree( &(*_result) ); }
128 /** Add pathnames matching \a pattern_r to the current result.
130 * The flags passed here override the global default passed to
131 * the ctor. GLOB_APPEND is atomatically added to the flags if needed.
133 * This invalidates all iterators.
134 * \see \ref setDefaultFlags
135 * \return the value returned by ::glob().
137 int add( const std::string & pattern_r, Flags flags_r = Flags() );
140 /** The default flags passed to \c ::glob(). */
141 Flags defaultFlags() const
142 { return _defaultFlags; }
144 /** Set the default flags passed to \c ::glob(). */
145 void setDefaultFlags( Flags flags_r = Flags() )
146 { _defaultFlags = flags_r; }
148 /** Returns the value returned by the last call to \c ::glob().
149 * \c Zero on successful completion. Otherwise \c GLOB_NOSPACE or \c GLOB_ABORTED
150 * or \c GLOB_NOMATCH.
152 int lastGlobReturn() const
153 { return _lastGlobReturn; }
156 /** Whether matches were found. */
158 { return ! ( _result && _result->gl_pathc ); }
160 /** The number of matches found so far. */
161 size_type size() const
162 { return( _result ? _result->gl_pathc : 0 ); }
164 /** Iterator pointing to the first result. */
165 const_iterator begin() const
166 { return( _result ? const_iterator( _result->gl_pathv ) : const_iterator() ); }
168 /** Iterator pointing behind the last result. */
169 const_iterator end() const
170 { return const_iterator(); }
174 /** \name Collecting Glob results to some _OutputIterator
176 * std::list<Pathname> p;
177 * Glob::collect( "/bin/m*", std::back_inserter(p) );
181 /** Write glob result to some \c OutputIterator. */
182 template<class _OutputIterator>
183 static int collect( const std::string & pattern_r, Flags flags_r, _OutputIterator result_r )
185 Glob glob( pattern_r, flags_r );
186 if ( glob.lastGlobReturn() == 0 )
187 for_( it, glob.begin(), glob.end() )
189 return glob.lastGlobReturn();
192 template<class _OutputIterator>
193 static int collect( const std::string & pattern_r, _OutputIterator result_r )
194 { return collect( pattern_r, Flags(), result_r ); }
199 scoped_ptr< ::glob_t> _result;
200 DefaultIntegral<int,0> _lastGlobReturn;
202 ///////////////////////////////////////////////////////////////////
204 /** \relates Glob Stream output */
205 std::ostream & operator<<( std::ostream & str, const Glob & obj );
207 ZYPP_DECLARE_OPERATORS_FOR_FLAGS( Glob::Flags );
209 ///////////////////////////////////////////////////////////////////
211 /////////////////////////////////////////////////////////////////
212 } // namespace filesystem
213 ///////////////////////////////////////////////////////////////////
214 /////////////////////////////////////////////////////////////////
216 ///////////////////////////////////////////////////////////////////
217 #endif // ZYPP_GLOB_H