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 #include "zypp/Pathname.h"
30 ///////////////////////////////////////////////////////////////////
32 { /////////////////////////////////////////////////////////////////
34 ///////////////////////////////////////////////////////////////////
36 { /////////////////////////////////////////////////////////////////
38 ///////////////////////////////////////////////////////////////////
42 /** Find pathnames matching a pattern.
44 * Glob glob( Glob::_BRACE );
45 * glob.add( "/somewhere/solverTestcase/ *{.xml,.xml.gz}" );
46 * glob.add( "/somewhere/else/a*" );
47 * for_( it, glob.begin(), glob.end() )
51 * std::list<Pathname> plist;
52 * Glob::collect( "/somewherre/solverTestcase/ *{.xml,.xml.gz}", Glob::_BRACE,
53 * std::back_inserter( plist ) );
55 * \see Manual page glob(3)
57 class Glob : private base::NonCopyable
60 typedef size_t size_type;
61 typedef const char * value_type;
63 /** Iterate NULL terminated \c char* array. */
64 class const_iterator : public boost::iterator_adaptor<
65 const_iterator // Derived
68 , boost::forward_traversal_tag // CategoryOrTraversal
69 , const value_type // Reference
74 : const_iterator::iterator_adaptor_( 0 )
77 explicit const_iterator( char ** _idx )
78 : const_iterator::iterator_adaptor_( _idx && *_idx ? _idx : 0 )
82 friend class boost::iterator_core_access;
85 if ( base_reference() && !*(++base_reference()) )
88 reference dereference() const
89 { return( base() ? *base() : 0 ); }
91 ///////////////////////////////////////////////////////////////////
94 /** Individual bits to combine in \ref Flags. */
96 _ERR = GLOB_ERR, //!< Return on read errors.
97 _MARK = GLOB_MARK, //!< Append a slash to each name.
98 _NOSORT = GLOB_NOSORT, //!< Don't sort the names.
99 // unsupported _DOOFFS = GLOB_DOOFFS, //!< Insert PGLOB->gl_offs NULLs.
100 _NOCHECK = GLOB_NOCHECK, //!< If nothing matches, return the pattern.
101 // autoapplied _APPEND = GLOB_APPEND, //!< Append to results of a previous call.
102 _NOESCAPE = GLOB_NOESCAPE, //!< Backslashes don't quote metacharacters.
103 _PERIOD = GLOB_PERIOD, //!< Leading `.' can be matched by metachars.
104 // unsupported _MAGCHAR = GLOB_MAGCHAR,//!< Set in gl_flags if any metachars seen.
105 _ALTDIRFUNC = GLOB_ALTDIRFUNC, //!< Use gl_opendir et al functions.
106 _BRACE = GLOB_BRACE, //!< Expand "{a,b}" to "a" "b".
107 _NOMAGIC = GLOB_NOMAGIC, //!< If no magic chars, return the pattern.
108 _TILDE = GLOB_TILDE, //!< Expand ~user and ~ to home directories.
109 _ONLYDIR = GLOB_ONLYDIR, //!< Match only directories.
110 _TILDE_CHECK = GLOB_TILDE_CHECK, //!< Like GLOB_TILDE but return an error if the user name is not available.
113 /** type Flags: Type-safe OR-combination of \ref Bits. */
114 ZYPP_DECLARE_FLAGS( Flags, Bits );
117 /** Default ctor optionally taking the default flags.
118 * The flags passed here are the default for \ref add.
119 * \see \ref setDefaultFlags
121 Glob( Flags flags_r = Flags() )
122 : _defaultFlags( flags_r )
125 /** Ctor adding pathnames matching \a pattern_r.
126 * The flags passed here are the default for \ref add.
127 * \see \ref setDefaultFlags
129 explicit Glob( const Pathname & pattern_r, Flags flags_r = Flags() )
130 : _defaultFlags( flags_r )
131 { add( pattern_r, flags_r ); }
133 explicit Glob( const std::string & pattern_r, Flags flags_r = Flags() )
134 : _defaultFlags( flags_r )
135 { add( pattern_r, flags_r ); }
137 explicit Glob( const char * pattern_r, Flags flags_r = Flags() )
138 : _defaultFlags( flags_r )
139 { add( pattern_r, flags_r ); }
143 { if ( _result ) ::globfree( &(*_result) ); }
145 /** Add pathnames matching \a pattern_r to the current result.
147 * Any flags passed here override the global default passed to
148 * the ctor. GLOB_APPEND is atomatically added to the flags
151 * This invalidates all iterators.
152 * \see \ref setDefaultFlags
153 * \return the value returned by ::glob().
155 int add( const Pathname & pattern_r, Flags flags_r = Flags() )
156 { return add( pattern_r.c_str(), flags_r ); }
158 int add( const std::string & pattern_r, Flags flags_r = Flags() )
159 { return add( pattern_r.c_str(), flags_r ); }
161 int add( const char * pattern_r, Flags flags_r = Flags() );
163 /** Clear all results found so far. \ref defaultFlags remain active. */
166 /** Clear all results and reset \ref defaultFlags. */
167 void reset( Flags flags_r = Flags() )
168 { clear(); setDefaultFlags( flags_r ); }
172 /** The default flags passed to \c ::glob(). */
173 Flags defaultFlags() const
174 { return _defaultFlags; }
176 /** Set the default flags passed to \c ::glob(). */
177 void setDefaultFlags( Flags flags_r = Flags() )
178 { _defaultFlags = flags_r; }
180 /** Returns the value returned by the last call to \c ::glob().
181 * \c Zero on successful completion. Otherwise \c GLOB_NOSPACE or \c GLOB_ABORTED
182 * or \c GLOB_NOMATCH.
184 int lastGlobReturn() const
185 { return _lastGlobReturn; }
188 /** Whether matches were found. */
190 { return ! ( _result && _result->gl_pathc ); }
192 /** The number of matches found so far. */
193 size_type size() const
194 { return( _result ? _result->gl_pathc : 0 ); }
196 /** Iterator pointing to the first result. */
197 const_iterator begin() const
198 { return( _result ? const_iterator( _result->gl_pathv ) : const_iterator() ); }
200 /** Iterator pointing behind the last result. */
201 const_iterator end() const
202 { return const_iterator(); }
206 /** \name Collecting Glob results to some _OutputIterator
208 * std::list<Pathname> p;
209 * Glob::collect( "/bin/a*.dat}", std::back_inserter(p) );
210 * Glob::collect( "/bin/a*{.xml,.xml.gz}", Glob::_BRACE, std::back_inserter(p) );
214 /** Write glob result to some \c OutputIterator. */
215 template<class _OutputIterator>
216 static int collect( const Pathname & pattern_r, _OutputIterator result_r )
217 { return collect( pattern_r.c_str(), Flags(), result_r ); }
219 template<class _OutputIterator>
220 static int collect( const std::string & pattern_r, _OutputIterator result_r )
221 { return collect( pattern_r.c_str(), Flags(), result_r ); }
223 template<class _OutputIterator>
224 static int collect( const char * pattern_r, _OutputIterator result_r )
225 { return collect( pattern_r, Flags(), result_r ); }
227 /** \overload With \ref Flags */
228 template<class _OutputIterator>
229 static int collect( const Pathname & pattern_r, Flags flags_r, _OutputIterator result_r )
230 { return collect( pattern_r.c_str(), flags_r, result_r ); }
232 template<class _OutputIterator>
233 static int collect( const std::string & pattern_r, Flags flags_r, _OutputIterator result_r )
234 { return collect( pattern_r.c_str(), flags_r, result_r ); }
236 template<class _OutputIterator>
237 static int collect( const char * pattern_r, Flags flags_r, _OutputIterator result_r )
239 Glob glob( pattern_r, flags_r );
240 if ( glob.lastGlobReturn() == 0 )
241 for_( it, glob.begin(), glob.end() )
242 (*result_r)++ = typename _OutputIterator::container_type::value_type(*it);
243 return glob.lastGlobReturn();
249 scoped_ptr< ::glob_t> _result;
250 DefaultIntegral<int,0> _lastGlobReturn;
252 ///////////////////////////////////////////////////////////////////
254 /** \relates Glob Stream output */
255 std::ostream & operator<<( std::ostream & str, const Glob & obj );
257 /** \relates Glob::const_iterator Stream output */
258 inline std::ostream & operator<<( std::ostream & str, const Glob::const_iterator & obj )
259 { return str << *obj; }
261 ZYPP_DECLARE_OPERATORS_FOR_FLAGS( Glob::Flags );
263 ///////////////////////////////////////////////////////////////////
265 /////////////////////////////////////////////////////////////////
266 } // namespace filesystem
267 ///////////////////////////////////////////////////////////////////
268 /////////////////////////////////////////////////////////////////
270 ///////////////////////////////////////////////////////////////////
271 #endif // ZYPP_GLOB_H