00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00051 #ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE
00052 #define UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE
00053
00054 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00055 # define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_MAJOR 5
00056 # define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_MINOR 1
00057 # define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_REVISION 2
00058 # define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_GLOB_SEQUENCE_EDIT 142
00059 #endif
00060
00061
00062
00063
00064
00065 #ifndef UNIXSTL_INCL_UNIXSTL_H_UNIXSTL
00066 # include <unixstl/unixstl.h>
00067 #endif
00068 #ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
00069 # include <unixstl/filesystem/filesystem_traits.hpp>
00070 #endif
00071 #ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER
00072 # include <unixstl/filesystem/file_path_buffer.hpp>
00073 #endif
00074 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00075 # include <stlsoft/util/std/iterator_helper.hpp>
00076 #endif
00077 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
00078 # include <stlsoft/memory/auto_buffer.hpp>
00079 #endif
00080 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR
00081 # include <stlsoft/memory/allocator_selector.hpp>
00082 #endif
00083 #ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SCOPED_HANDLE
00084 # include <stlsoft/smartptr/scoped_handle.hpp>
00085 #endif
00086 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_TOKENISER_FUNCTIONS
00087
00088 #endif
00089 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00090 # include <stlsoft/collections/util/collections.hpp>
00091 #endif
00092 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
00093 # include <stlsoft/util/std_swap.hpp>
00094 #endif
00095
00096 #ifndef STLSOFT_INCL_SYS_H_TYPES
00097 # define STLSOFT_INCL_SYS_H_TYPES
00098 # include <sys/types.h>
00099 #endif
00100 #ifndef STLSOFT_INCL_SYS_H_STAT
00101 # define STLSOFT_INCL_SYS_H_STAT
00102 # include <sys/stat.h>
00103 #endif
00104 #ifndef STLSOFT_INCL_H_ERRNO
00105 # define STLSOFT_INCL_H_ERRNO
00106 # include <errno.h>
00107 #endif
00108 #ifndef STLSOFT_INCL_H_GLOB
00109 # define STLSOFT_INCL_H_GLOB
00110 # include <glob.h>
00111 #endif
00112
00113 #ifndef STLSOFT_INCL_ALGORITHM
00114 # define STLSOFT_INCL_ALGORITHM
00115 # include <algorithm>
00116 #endif
00117 #ifndef STLSOFT_INCL_EXCEPTION
00118 # define STLSOFT_INCL_EXCEPTION
00119 # include <exception>
00120 #endif
00121 #ifndef STLSOFT_INCL_STDEXCEPT
00122 # define STLSOFT_INCL_STDEXCEPT
00123 # include <stdexcept>
00124 #endif
00125
00126 #ifdef STLSOFT_UNITTEST
00127 # include <stlsoft/string/simple_string.hpp>
00128 #endif
00129
00130
00131
00132
00133
00134 #ifndef GLOB_ONLYDIR
00135 # undef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
00136 #endif
00137
00138
00139
00140
00141
00142
00143
00144
00145 #ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
00146 # define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
00147 #elif defined(STLSOFT_COMPILER_IS_CUSTOM)
00148 # define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
00149 #elif defined(STLSOFT_COMPILER_IS_UNKNOWN)
00150 # define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
00151 #elif defined(STLSOFT_COMPILER_IS_BORLAND)
00152 # define GLOB_SEQUENCE_CTOR_OLD_FORM
00153 #elif defined(STLSOFT_COMPILER_IS_COMO)
00154 # define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
00155 #elif defined(STLSOFT_COMPILER_IS_DMC)
00156 # define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
00157 #elif defined(STLSOFT_COMPILER_IS_GCC)
00158 # define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
00159 #elif defined(STLSOFT_COMPILER_IS_INTEL)
00160 # define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
00161 #elif defined(STLSOFT_COMPILER_IS_MSVC)
00162 # if _MSC_VER >= 1310
00163 # define GLOB_SEQUENCE_CTOR_PRIMARY_FORM
00164 # elif _MSC_VER >= 1020
00165 # define GLOB_SEQUENCE_CTOR_ALT_FORM
00166 # else
00167 # define GLOB_SEQUENCE_CTOR_OLD_FORM
00168 # endif
00169 #elif defined(STLSOFT_COMPILER_IS_MWERKS)
00170 # define GLOB_SEQUENCE_CTOR_ALT_FORM
00171 #elif defined(STLSOFT_COMPILER_IS_VECTORC)
00172 # define GLOB_SEQUENCE_CTOR_ALT_FORM
00173 #elif defined(STLSOFT_COMPILER_IS_WATCOM)
00174 # define GLOB_SEQUENCE_CTOR_OLD_FORM
00175 #else
00176 # error Unrecognised compiler
00177 #endif
00178
00179
00180
00181
00182
00183 #ifndef _UNIXSTL_NO_NAMESPACE
00184 # if defined(_STLSOFT_NO_NAMESPACE) || \
00185 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00186
00187 namespace unixstl
00188 {
00189 # else
00190
00191
00192 namespace stlsoft
00193 {
00194
00195 namespace unixstl_project
00196 {
00197
00198 # endif
00199 #endif
00200
00201
00202
00203
00204
00205 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00206
00210 class glob_sequence_exception
00211 #if defined(STLSOFT_COMPILER_IS_DMC)
00212 : public std::exception
00213 #else
00214 : public unixstl_ns_qual_std(exception)
00215 #endif
00216 {
00219 public:
00220 #if defined(STLSOFT_COMPILER_IS_DMC)
00221 typedef std::exception parent_class_type;
00222 #else
00223 typedef unixstl_ns_qual_std(exception) parent_class_type;
00224 #endif
00225 typedef glob_sequence_exception class_type;
00227
00230 public:
00231 ss_explicit_k glob_sequence_exception(us_int_t globStatus, us_int_t errno_) stlsoft_throw_0()
00232 : m_globStatus(globStatus)
00233 , m_errno(errno_)
00234 {}
00236
00239 public:
00240 #if defined(STLSOFT_COMPILER_IS_DMC)
00241 char const *what() const throw()
00242 #else
00243 char const *what() const stlsoft_throw_0()
00244 #endif
00245 {
00246 return "glob_sequence failure";
00247 }
00248
00249 us_int_t get_globstatus() const stlsoft_throw_0()
00250 {
00251 return m_globStatus;
00252 }
00253 us_int_t get_errno() const stlsoft_throw_0()
00254 {
00255 return m_errno;
00256 }
00258
00261 private:
00262 us_int_t const m_globStatus;
00263 us_int_t const m_errno;
00265
00268 private:
00269 class_type& operator =(class_type const&);
00271 };
00272
00273 #endif
00274
00282 class glob_sequence
00283 : public stlsoft_ns_qual(stl_collection_tag)
00284 {
00287 public:
00289 typedef glob_sequence class_type;
00291 typedef us_char_a_t char_type;
00292
00293 typedef filesystem_traits<char_type> traits_type;
00295 typedef char_type const *value_type;
00297 typedef value_type const &const_reference;
00299 typedef value_type const *const_pointer;
00301 typedef us_size_t size_type;
00303 typedef us_ptrdiff_t difference_type;
00305 typedef stlsoft_ns_qual(allocator_selector)<value_type>::allocator_type allocator_type;
00306
00308 typedef stlsoft_ns_qual(pointer_iterator)< value_type const
00309 , const_pointer
00310 , const_reference
00311 >::type const_iterator;
00312
00313 #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
00315 typedef stlsoft_ns_qual(reverse_iterator_base) < const_iterator
00316 , value_type
00317 , const_reference
00318 , const_pointer
00319 , difference_type
00320 > const_reverse_iterator;
00321 #endif
00323
00326 public:
00327 enum search_flags
00328 {
00329 includeDots = 0x0008
00330 , directories = 0x0010
00331 , files = 0x0020
00332 , noSort = 0x0100
00333 , markDirs = 0x0200
00334 , absolutePath = 0x0400
00336 , breakOnError = 0x0800
00337 , noEscape = 0x1000
00339 #ifdef GLOB_PERIOD
00340 , matchPeriod = 0x2000
00341 #endif
00342 #ifdef GLOB_BRACE
00343 , bracePatterns = 0x4000
00344 #endif
00345 #ifdef GLOB_TILDE
00346 , expandTilde = 0x8000
00347 #endif
00348 };
00350
00353 public:
00354 #if defined(GLOB_SEQUENCE_CTOR_PRIMARY_FORM)
00365 template<ss_typename_param_k S>
00366 ss_explicit_k glob_sequence(S const& pattern, us_int_t flags = noSort)
00367 : m_flags(validate_flags_(flags))
00368 , m_buffer(1)
00369 {
00370 m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));
00371
00372 UNIXSTL_ASSERT(is_valid());
00373 }
00374
00375 # ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00376 template<ss_typename_param_k S>
00377 glob_sequence(S const& pattern, search_flags flag)
00378 : m_flags(validate_flags_(flag))
00379 , m_buffer(1)
00380 {
00381 m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));
00382
00383 UNIXSTL_ASSERT(is_valid());
00384 }
00385 # endif
00386
00398 template< ss_typename_param_k S1
00399 , ss_typename_param_k S2
00400 >
00401 glob_sequence(S1 const& directory, S2 const& pattern, us_int_t flags = noSort)
00402 : m_flags(validate_flags_(flags))
00403 , m_buffer(1)
00404 {
00405 m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));
00406
00407 UNIXSTL_ASSERT(is_valid());
00408 }
00409
00410 # ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00411 template< ss_typename_param_k S1
00412 , ss_typename_param_k S2
00413 >
00414 glob_sequence(S1 const& directory, S2 const& pattern, search_flags flag)
00415 : m_flags(validate_flags_(flag))
00416 , m_buffer(1)
00417 {
00418 m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));
00419
00420 UNIXSTL_ASSERT(is_valid());
00421 }
00422 # endif
00423
00424 #elif defined(GLOB_SEQUENCE_CTOR_ALT_FORM)
00425
00426 template<ss_typename_param_k S>
00427 ss_explicit_k glob_sequence(S const& pattern)
00428 : m_flags(validate_flags_())
00429 , m_buffer(1)
00430 {
00431 m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));
00432
00433 UNIXSTL_ASSERT(is_valid());
00434 }
00435
00436 template<ss_typename_param_k S>
00437 glob_sequence(S const& pattern, us_int_t flags )
00438 : m_flags(validate_flags_(flags))
00439 , m_buffer(1)
00440 {
00441 m_cItems = init_glob_(NULL, stlsoft_ns_qual(c_str_ptr)(pattern));
00442
00443 UNIXSTL_ASSERT(is_valid());
00444 }
00445
00446 glob_sequence(char_type const* directory, char_type const* pattern, us_int_t flags = noSort);
00447
00448 template<ss_typename_param_k S>
00449 glob_sequence(S const& directory, char const* pattern, us_int_t flags = noSort)
00450 : m_flags(validate_flags_(flags))
00451 , m_buffer(1)
00452 {
00453 m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));
00454
00455 UNIXSTL_ASSERT(is_valid());
00456 }
00457
00458 template<ss_typename_param_k S>
00459 glob_sequence(S const& directory, S const& pattern, us_int_t flags = noSort)
00460 : m_flags(validate_flags_(flags))
00461 , m_buffer(1)
00462 {
00463 m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));
00464
00465 UNIXSTL_ASSERT(is_valid());
00466 }
00467
00468 #elif defined(GLOB_SEQUENCE_CTOR_OLD_FORM)
00469
00470 ss_explicit_k glob_sequence(char_type const* pattern, us_int_t flags = noSort);
00471
00472 glob_sequence(char_type const* directory, char_type const* pattern, us_int_t flags = noSort);
00473
00474 #else
00475 # error Constructor form not recognised
00476 #endif
00477
00478 #if 0
00490 glob_sequence(char_type const* directory, char_type const* pattern, char_type delim, us_int_t flags = noSort);
00491 #endif
00492
00494 ~glob_sequence() stlsoft_throw_0();
00496
00499 public:
00501 us_size_t size() const;
00502
00504 us_bool_t empty() const;
00506
00509 public:
00513 const_reference operator [](size_type index) const;
00515
00518 public:
00522 const_iterator begin() const;
00526 const_iterator end() const;
00527
00528 #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
00532 const_reverse_iterator rbegin() const;
00536 const_reverse_iterator rend() const;
00537 #endif
00539
00542 private:
00543
00544 us_bool_t is_valid() const;
00545
00546
00547 static us_int_t validate_flags_(us_int_t flags = noSort);
00548
00549
00550 static us_bool_t is_path_separator_(char_type ch);
00551
00552
00553 static us_bool_t is_end_of_path_elements_(char_type const* pch, difference_type index);
00554
00555
00556 static us_bool_t is_dots_maybe_slashed_(char_type const* s, us_bool_t &bTwoDots);
00557
00558
00559 us_size_t init_glob_(char_type const* directory, char_type const* pattern);
00561
00564 private:
00565 typedef stlsoft_ns_qual(auto_buffer_old)< char_type const*
00566 , allocator_type
00567 , 128
00568 > buffer_type_;
00569
00570 us_int_t const m_flags;
00571 char_type const** m_base;
00572 us_size_t m_cItems;
00573 buffer_type_ m_buffer;
00574 glob_t m_glob;
00576
00579 private:
00580 glob_sequence(class_type const&);
00581 class_type const& operator =(class_type const&);
00583 };
00584
00586
00587
00588 #ifdef STLSOFT_UNITTEST
00589 # include "./unittest/glob_sequence_unittest_.h"
00590 #endif
00591
00592
00593
00594
00595
00596 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00597
00598 #if defined(GLOB_SEQUENCE_CTOR_OLD_FORM)
00599 inline glob_sequence::glob_sequence(glob_sequence::char_type const* pattern, us_int_t flags )
00600 : m_flags(validate_flags_(flags))
00601 , m_buffer(1)
00602 {
00603 m_cItems = init_glob_(NULL, pattern);
00604
00605 UNIXSTL_ASSERT(is_valid());
00606 }
00607 #endif
00608
00609 #if defined(GLOB_SEQUENCE_CTOR_OLD_FORM) || \
00610 defined(GLOB_SEQUENCE_CTOR_ALT_FORM)
00611 inline glob_sequence::glob_sequence(glob_sequence::char_type const* directory, glob_sequence::char_type const* pattern, us_int_t flags )
00612 : m_flags(validate_flags_(flags))
00613 , m_buffer(1)
00614 {
00615 m_cItems = init_glob_(directory, pattern);
00616
00617 UNIXSTL_ASSERT(is_valid());
00618 }
00619 #endif
00620
00621 #if 0
00622 template< ss_typename_param_k S1
00623 , ss_typename_param_k S2
00624 >
00625 inline glob_sequence::glob_sequence(S1 const& directory, S2 const& pattern, us_int_t flags )
00626 : m_flags(validate_flags_(flags))
00627 , m_buffer(1)
00628 {
00629 m_cItems = init_glob_(stlsoft_ns_qual(c_str_ptr)(directory), stlsoft_ns_qual(c_str_ptr)(pattern));
00630
00631 UNIXSTL_ASSERT(is_valid());
00632 }
00633 #endif
00634
00635 #if 0
00636 inline glob_sequence::glob_sequence(char_type const* directory, char_type const* pattern, char_type delim, us_int_t flags )
00637 : m_flags(validate_flags_(flags))
00638 , m_buffer(1)
00639 {
00640
00641 m_cItems = init_glob_(NULL, pattern);
00642
00643 UNIXSTL_ASSERT(is_valid());
00644 }
00645 #endif
00646
00647 inline glob_sequence::~glob_sequence() stlsoft_throw_0()
00648 {
00649 UNIXSTL_ASSERT(is_valid());
00650
00651 if(NULL != m_base)
00652 {
00653 ::globfree(&m_glob);
00654 }
00655 }
00656
00657 inline us_size_t glob_sequence::size() const
00658 {
00659 return m_cItems;
00660 }
00661
00662 inline us_bool_t glob_sequence::empty() const
00663 {
00664 return 0 == size();
00665 }
00666
00667 inline glob_sequence::const_reference glob_sequence::operator [](glob_sequence::size_type index) const
00668 {
00669 UNIXSTL_MESSAGE_ASSERT("index access out of range in glob_sequence", index < 1 + size());
00670
00671 return m_base[index];
00672 }
00673
00674 inline glob_sequence::const_iterator glob_sequence::begin() const
00675 {
00676 return m_base;
00677 }
00678
00679 inline glob_sequence::const_iterator glob_sequence::end() const
00680 {
00681 return m_base + m_cItems;
00682 }
00683
00684 #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
00685 inline glob_sequence::const_reverse_iterator glob_sequence::rbegin() const
00686 {
00687 return const_reverse_iterator(end());
00688 }
00689
00690 inline glob_sequence::const_reverse_iterator glob_sequence::rend() const
00691 {
00692 return const_reverse_iterator(begin());
00693 }
00694 #endif
00695
00696 inline us_bool_t glob_sequence::is_valid() const
00697 {
00698 if((0 != m_cItems) && (NULL == m_base))
00699 {
00700 return false;
00701 }
00702
00703 return true;
00704 }
00705
00706
00707 inline us_int_t glob_sequence::validate_flags_(us_int_t flags)
00708 {
00709 const us_int_t validFlags = 0
00710 | includeDots
00711 | directories
00712 | files
00713 | noSort
00714 | markDirs
00715 | absolutePath
00716 | breakOnError
00717 | noEscape
00718 #ifdef GLOB_PERIOD
00719 | matchPeriod
00720 #endif
00721 #ifdef GLOB_BRACE
00722 | bracePatterns
00723 #endif
00724 #ifdef GLOB_TILDE
00725 | expandTilde
00726 #endif
00727 | 0;
00728
00729 UNIXSTL_MESSAGE_ASSERT("Specification of unrecognised/unsupported flags", flags == (flags & validFlags));
00730 STLSOFT_SUPPRESS_UNUSED(validFlags);
00731
00732 if(0 == (flags & (directories | files)))
00733 {
00734 flags |= (directories | files);
00735 }
00736
00737 #ifndef UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK
00738
00739
00740
00741
00742 if(0 == (flags & directories))
00743 {
00744
00745
00746 flags |= includeDots;
00747
00748
00749
00750
00751 flags |= markDirs;
00752 }
00753 #endif
00754
00755 return flags;
00756 }
00757
00758 inline us_bool_t glob_sequence::is_path_separator_(glob_sequence::char_type ch)
00759 {
00760 return ch == '/'
00761 #if defined(_UNIXSTL_COMPILER_IS_UNKNOWN) && \
00762 !defined(_UNIXSTL_GLOB_SEQUENCE_NO_BACK_SLASH_TERMINATOR)
00763 || ch == '\\'
00764 #endif
00765 ;
00766 }
00767
00768
00769 inline us_bool_t glob_sequence::is_end_of_path_elements_(glob_sequence::char_type const* pch, glob_sequence::difference_type index)
00770 {
00771 return pch[index] == '\0' ||
00772 ( pch[index + 1] == '\0' &&
00773 is_path_separator_(pch[index]));
00774 }
00775
00776 inline us_bool_t glob_sequence::is_dots_maybe_slashed_(glob_sequence::char_type const* s, us_bool_t &bTwoDots)
00777 {
00778 UNIXSTL_ASSERT(NULL != s);
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791 const us_size_t len = traits_type::str_len(s);
00792 us_size_t lastNameChar = len -1;
00793
00794 UNIXSTL_ASSERT(len > 0);
00795
00796 if(is_path_separator_(s[lastNameChar]))
00797 {
00798 --lastNameChar;
00799 }
00800 if( 0 < lastNameChar &&
00801 '.' == s[lastNameChar])
00802 {
00803 --lastNameChar;
00804
00805 if( 0 == lastNameChar ||
00806 is_path_separator_(s[lastNameChar]))
00807 {
00808 bTwoDots = false;
00809 return true;
00810 }
00811 else if( 0 < lastNameChar &&
00812 '.' == s[lastNameChar])
00813 {
00814 --lastNameChar;
00815
00816 if( 0 == lastNameChar ||
00817 is_path_separator_(s[lastNameChar]))
00818 {
00819 bTwoDots = true;
00820 return true;
00821 }
00822 else
00823 {
00824 return false;
00825 }
00826 }
00827 }
00828
00829 return false;
00830 }
00831
00832 inline us_size_t glob_sequence::init_glob_(glob_sequence::char_type const* directory, glob_sequence::char_type const* pattern)
00833 {
00834 UNIXSTL_MESSAGE_ASSERT("Null pattern given to glob_sequence", NULL != pattern);
00835
00836 us_int_t glob_flags = 0;
00837 basic_file_path_buffer<char_type> scratch_;
00838
00839 #ifndef STLSOFT_CF_EXCEPTION_SUPPORT
00840 if(0 == scratch_.size())
00841 {
00842 m_base = NULL;
00843
00844 return 0;
00845 }
00846 #endif
00847
00848 if( NULL == directory &&
00849 absolutePath == (m_flags & absolutePath))
00850 {
00851 static const char_type s_thisDir[] = { '.', '\0' };
00852
00853 directory = s_thisDir;
00854 }
00855
00856
00857 if( NULL != directory &&
00858 '\0' != *directory)
00859 {
00860 us_size_t dirLen;
00861
00862
00863 if(absolutePath == (m_flags & absolutePath))
00864 {
00865 dirLen = traits_type::get_full_path_name(directory, scratch_.size(), &scratch_[0]);
00866 }
00867 else
00868 {
00869 dirLen = traits_type::str_len(directory);
00870
00871 traits_type::char_copy(&scratch_[0], directory, dirLen);
00872 scratch_[dirLen] = '\0';
00873 }
00874
00875
00876 traits_type::ensure_dir_end(&scratch_[0] + (dirLen ? dirLen - 1 : 0));
00877
00878
00879 size_type scratchLen = traits_type::str_len(scratch_.data());
00880 size_type patternLen = traits_type::str_len(pattern);
00881 traits_type::char_copy(&scratch_[0] + scratchLen, pattern, patternLen);
00882 scratch_[scratchLen + patternLen] = '\0';
00883 pattern = scratch_.c_str();
00884 }
00885
00886 if(m_flags & noSort)
00887 {
00888
00889 glob_flags |= GLOB_NOSORT;
00890 }
00891
00892 if(m_flags & markDirs)
00893 {
00894
00895 glob_flags |= GLOB_MARK;
00896 }
00897
00898 #ifdef GLOB_ONLYDIR // If this is not defined, we rely on stat
00899 if(directories == (m_flags & (directories | files)))
00900 {
00901
00902 glob_flags |= GLOB_ONLYDIR;
00903 }
00904 #endif
00905
00906 #ifdef GLOB_ONLYFILE // If this is not defined, we rely on stat
00907 if(files == (m_flags & (directories | files)))
00908 {
00909
00910 glob_flags |= GLOB_ONLYFILE;
00911 }
00912 #endif
00913
00914 #ifdef GLOB_ERR
00915 if(m_flags & breakOnError)
00916 {
00917 glob_flags |= GLOB_ERR;
00918 }
00919 #endif
00920
00921 #ifdef GLOB_NOESCAPE
00922 if(m_flags & noEscape)
00923 {
00924 glob_flags |= GLOB_NOESCAPE;
00925 }
00926 #endif
00927
00928 #ifdef GLOB_PERIOD
00929 if(m_flags & matchPeriod)
00930 {
00931 glob_flags |= GLOB_PERIOD;
00932 }
00933 #endif
00934
00935 #ifdef GLOB_BRACE
00936 if(m_flags & bracePatterns)
00937 {
00938 glob_flags |= GLOB_BRACE;
00939 }
00940 #endif
00941
00942 #ifdef GLOB_TILDE
00943 if(m_flags & expandTilde)
00944 {
00945 glob_flags |= GLOB_TILDE;
00946 }
00947 #endif
00948
00949 int gr = ::glob(pattern, glob_flags, NULL, &m_glob);
00950
00951 if(0 != gr)
00952 {
00953 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00954 # ifdef GLOB_NOMATCH
00955
00956
00957
00958 if(GLOB_NOMATCH != gr)
00959 # endif
00960 {
00961 STLSOFT_THROW_X(glob_sequence_exception(gr, 0));
00962 }
00963 #endif
00964
00965 m_base = NULL;
00966
00967 return 0;
00968 }
00969 else
00970 {
00971
00972
00973
00974
00975
00976 stlsoft_ns_qual(scoped_handle)<glob_t*> cleanup(&m_glob, ::globfree);
00977
00978 char_type **base = m_glob.gl_pathv;
00979 us_size_t cItems = static_cast<us_size_t>(m_glob.gl_pathc);
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990 if( 0 == (m_flags & includeDots) ||
00991 #ifndef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
00992 directories == (m_flags & (directories | files)) ||
00993 #endif
00994 files == (m_flags & (directories | files)))
00995 {
00996 if(!m_buffer.resize(cItems))
00997 {
00998 #ifndef STLSOFT_CF_EXCEPTION_SUPPORT
00999 m_base = NULL;
01000
01001 return 0;
01002 #endif
01003 }
01004
01005 UNIXSTL_ASSERT(m_buffer.size() == cItems);
01006
01007 base = static_cast<char_type**>(memcpy(&m_buffer[0], base, m_buffer.size() * sizeof(char_type*)));
01008 }
01009
01010
01011 if(0 == (m_flags & includeDots))
01012 {
01013
01014
01015
01016
01017
01018 us_bool_t bFoundDot1 = false;
01019 us_bool_t bFoundDot2 = false;
01020 char_type **begin = base;
01021 char_type **end = begin + cItems;
01022
01023 for(; begin != end; ++begin)
01024 {
01025 us_bool_t bTwoDots = false;
01026
01027 if(is_dots_maybe_slashed_(*begin, bTwoDots))
01028 {
01029
01030 if(begin != base)
01031 {
01032 stlsoft_ns_qual(std_swap)(*begin, *base);
01033 }
01034 ++base;
01035 --cItems;
01036
01037
01038 (bTwoDots ? bFoundDot2 : bFoundDot1) = true;
01039
01040 if( bFoundDot1 &&
01041 bFoundDot2)
01042 {
01043 break;
01044 }
01045 }
01046 }
01047 }
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 #ifndef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
01058 if((m_flags & (directories | files)) != (directories | files))
01059 #else
01060 if((m_flags & (directories | files)) == files)
01061 #endif
01062 {
01063
01064
01065
01066 basic_file_path_buffer<char_type> buffer;
01067
01068 char_type **begin = base;
01069 char_type **end = begin + cItems;
01070
01071 #ifndef STLSOFT_CF_EXCEPTION_SUPPORT
01072 if(0 == buffer.size())
01073 {
01074 m_base = NULL;
01075
01076 return 0;
01077 }
01078 #endif
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091 for(; begin != end; ++begin)
01092 {
01093
01094 struct stat st;
01095 int res;
01096 char_type const* entry = *begin;
01097
01098
01099 if(files == (m_flags & (directories | files)))
01100 {
01101 UNIXSTL_ASSERT(markDirs == (m_flags & markDirs));
01102
01103 if(!traits_type::has_dir_end(entry))
01104 {
01105 continue;
01106 }
01107 #ifndef UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK
01108 else
01109 {
01110 res = ::stat(entry, &st);
01111
01112 if(0 != res)
01113 {
01114
01115
01116
01117
01118 }
01119 else
01120 {
01121 if(S_IFREG == (st.st_mode & S_IFREG))
01122 {
01123 continue;
01124 }
01125 }
01126 }
01127 #endif
01128 }
01129 else
01130 {
01131 UNIXSTL_ASSERT(directories == (m_flags & (directories | files)));
01132
01133 #ifdef UNIXSTL_GLOB_SEQUENCE_TRUST_ONLYDIR
01134 UNIXSTL_MESSAGE_ASSERT("Cannot get here, since trusting GLOB_ONLYDIR", 0);
01135 #endif
01136
01137 if(markDirs == (m_flags & markDirs))
01138 {
01139 if(traits_type::has_dir_end(entry))
01140 {
01141 continue;
01142 }
01143 }
01144 #ifndef UNIXSTL_GLOB_SEQUENCE_DONT_TRUST_MARK
01145 else
01146 #endif
01147 {
01148
01149 res = stat(entry, &st);
01150
01151 if(0 != res)
01152 {
01153
01154
01155
01156
01157 }
01158 else
01159 {
01160 if(S_IFDIR == (st.st_mode & S_IFDIR))
01161 {
01162 continue;
01163 }
01164 }
01165 }
01166
01167 }
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178 stlsoft_ns_qual(std_swap)(*begin, *base);
01179 ++base;
01180 --cItems;
01181 }
01182 }
01183
01184
01185 if( 0 == (m_flags & noSort) &&
01186 cItems != static_cast<us_size_t>(m_glob.gl_pathc))
01187 {
01188 unixstl_ns_qual_std(sort)(base, base + cItems);
01189 }
01190
01191
01192
01193
01194
01195 m_base = const_cast<char_type const**>(base);
01196
01197
01198
01199 cleanup.detach();
01200
01201 return cItems;
01202 }
01203 }
01204
01205 #endif
01206
01207
01208
01209 #ifndef _UNIXSTL_NO_NAMESPACE
01210 # if defined(_STLSOFT_NO_NAMESPACE) || \
01211 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01212 }
01213 # else
01214 }
01215 }
01216 # endif
01217 #endif
01218
01219
01220
01221 #endif
01222
01223