]> git.lyx.org Git - lyx.git/blob - boost/libs/regex/src/fileiter.cpp
update
[lyx.git] / boost / libs / regex / src / fileiter.cpp
1 /*
2  *
3  * Copyright (c) 1998-2002
4  * Dr John Maddock
5  *
6  * Permission to use, copy, modify, distribute and sell this software
7  * and its documentation for any purpose is hereby granted without fee,
8  * provided that the above copyright notice appear in all copies and
9  * that both that copyright notice and this permission notice appear
10  * in supporting documentation.  Dr John Maddock makes no representations
11  * about the suitability of this software for any purpose.  
12  * It is provided "as is" without express or implied warranty.
13  *
14  */
15  
16  /*
17   *   LOCATION:    see http://www.boost.org for most recent version.
18   *   FILE:        fileiter.cpp
19   *   VERSION:     see <boost/version.hpp>
20   *   DESCRIPTION: Implements file io primitives + directory searching for class boost::RegEx.
21   */
22
23
24 #define BOOST_REGEX_SOURCE
25
26 #include <climits>
27 #include <stdexcept>
28 #include <boost/regex/detail/fileiter.hpp>
29
30 #ifndef BOOST_REGEX_NO_FILEITER
31
32 #if defined(__CYGWIN__) || defined(__CYGWIN32__)
33 #include <sys/cygwin.h>
34 #endif
35
36 #ifdef BOOST_MSVC
37 #  pragma warning(disable: 4800)
38 #endif
39
40 namespace boost{
41    namespace re_detail{
42 // start with the operating system specific stuff:
43
44 #if (defined(__BORLANDC__) || defined(BOOST_REGEX_FI_WIN32_DIR) || defined(BOOST_MSVC)) && !defined(BOOST_RE_NO_WIN32)
45
46 // platform is DOS or Windows
47 // directories are separated with '\\'
48 // and names are insensitive of case
49
50 const char* _fi_sep = "\\";
51 const char* _fi_sep_alt = "/";
52 #define BOOST_REGEX_FI_TRANSLATE(c) std::tolower(c)
53
54 #else
55
56 // platform is not DOS or Windows
57 // directories are separated with '/'
58 // and names are sensitive of case
59
60 const char* _fi_sep = "/";
61 const char* _fi_sep_alt = _fi_sep;
62 #define BOOST_REGEX_FI_TRANSLATE(c) c
63
64 #endif
65
66 #ifdef BOOST_REGEX_FI_WIN32_MAP
67
68 void mapfile::open(const char* file)
69 {
70    BOOST_RE_GUARD_STACK
71 #if defined(__CYGWIN__)||defined(__CYGWIN32__)
72    char win32file[ MAX_PATH ];
73    cygwin_conv_to_win32_path( file, win32file );
74    hfile = CreateFileA(win32file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
75 #else
76    hfile = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
77 #endif
78    if(hfile != INVALID_HANDLE_VALUE)
79    {
80       hmap = CreateFileMapping(hfile, 0, PAGE_READONLY, 0, 0, 0);
81       if((hmap == INVALID_HANDLE_VALUE) || (hmap == NULL))
82       {
83          CloseHandle(hfile);
84          hmap = 0;
85          hfile = 0;
86 #ifndef BOOST_NO_EXCEPTIONS
87          throw std::runtime_error("Unable to create file mapping.");
88 #else
89          BOOST_REGEX_NOEH_ASSERT(hmap != INVALID_HANDLE_VALUE);
90 #endif
91       }
92       _first = static_cast<const char*>(MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0));
93       if(_first == 0)
94       {
95          CloseHandle(hmap);
96          CloseHandle(hfile);
97          hmap = 0;
98          hfile = 0;
99 #ifndef BOOST_NO_EXCEPTIONS
100          throw std::runtime_error("Unable to create file mapping.");
101 #else
102          BOOST_REGEX_NOEH_ASSERT(_first != 0);
103 #endif
104       }
105       _last = _first + GetFileSize(hfile, 0);
106    }
107    else
108    {
109       hfile = 0;
110 #ifndef BOOST_NO_EXCEPTIONS
111       throw std::runtime_error("Unable to open file.");
112 #else
113       BOOST_REGEX_NOEH_ASSERT(hfile != INVALID_HANDLE_VALUE);
114 #endif
115    }
116 }
117
118 void mapfile::close()
119 {
120    BOOST_RE_GUARD_STACK
121    if(hfile != INVALID_HANDLE_VALUE)
122    {
123       UnmapViewOfFile((void*)_first);
124       CloseHandle(hmap);
125       CloseHandle(hfile);
126       hmap = hfile = 0;
127       _first = _last = 0;
128    }
129 }
130
131 #elif !defined(BOOST_RE_NO_STL)
132
133 mapfile_iterator& mapfile_iterator::operator = (const mapfile_iterator& i)
134 {
135    BOOST_RE_GUARD_STACK
136    if(file && node)
137       file->unlock(node);
138    file = i.file;
139    node = i.node;
140    offset = i.offset;
141    if(file)
142       file->lock(node);
143    return *this;
144 }
145
146 mapfile_iterator& mapfile_iterator::operator++ ()
147 {
148    BOOST_RE_GUARD_STACK
149    if((++offset == mapfile::buf_size) && file)
150    {
151       ++node;
152       offset = 0;
153       file->lock(node);
154       file->unlock(node-1);
155    }
156    return *this;
157 }
158
159 mapfile_iterator mapfile_iterator::operator++ (int)
160 {
161    BOOST_RE_GUARD_STACK
162    mapfile_iterator temp(*this);
163    if((++offset == mapfile::buf_size) && file)
164    {
165       ++node;
166       offset = 0;
167       file->lock(node);
168       file->unlock(node-1);
169    }
170    return temp;
171 }
172
173 mapfile_iterator& mapfile_iterator::operator-- ()
174 {
175    BOOST_RE_GUARD_STACK
176    if((offset == 0) && file)
177    {
178       --node;
179       offset = mapfile::buf_size - 1;
180       file->lock(node);
181       file->unlock(node + 1);
182    }
183    else
184       --offset;
185    return *this;
186 }
187
188 mapfile_iterator mapfile_iterator::operator-- (int)
189 {
190    BOOST_RE_GUARD_STACK
191    mapfile_iterator temp(*this);
192    if((offset == 0) && file)
193    {
194       --node;
195       offset = mapfile::buf_size - 1;
196       file->lock(node);
197       file->unlock(node + 1);
198    }
199    else
200       --offset;
201    return temp;
202 }
203
204 mapfile_iterator operator + (const mapfile_iterator& i, long off)
205 {
206    BOOST_RE_GUARD_STACK
207    mapfile_iterator temp(i);
208    temp += off;
209    return temp;
210 }
211
212 mapfile_iterator operator - (const mapfile_iterator& i, long off)
213 {
214    BOOST_RE_GUARD_STACK
215    mapfile_iterator temp(i);
216    temp -= off;
217    return temp;
218 }
219
220 mapfile::iterator mapfile::begin()const
221 {
222    BOOST_RE_GUARD_STACK
223    return mapfile_iterator(this, 0);
224 }
225
226 mapfile::iterator mapfile::end()const
227 {
228    BOOST_RE_GUARD_STACK
229    return mapfile_iterator(this, _size);
230 }
231
232 void mapfile::lock(pointer* node)const
233 {
234    BOOST_RE_GUARD_STACK
235    assert(node >= _first);
236    assert(node <= _last);
237    if(node < _last)
238    {
239       if(*node == 0)
240       {
241          if(condemed.empty())
242          {
243             *node = new char[sizeof(int) + buf_size];
244             *(reinterpret_cast<int*>(*node)) = 1;
245          }
246          else
247          {
248             pointer* p = condemed.front();
249             condemed.pop_front();
250             *node = *p;
251             *p = 0;
252             *(reinterpret_cast<int*>(*node)) = 1;
253          }
254          std::fseek(hfile, (node - _first) * buf_size, SEEK_SET);
255          if(node == _last - 1)
256             std::fread(*node + sizeof(int), _size % buf_size, 1, hfile);
257          else
258             std::fread(*node + sizeof(int), buf_size, 1, hfile);
259       }
260       else
261       {
262          if(*reinterpret_cast<int*>(*node) == 0)
263          {
264             *reinterpret_cast<int*>(*node) = 1;
265             condemed.remove(node);
266          }
267          else
268             ++(*reinterpret_cast<int*>(*node));
269       }
270    }
271 }
272
273 void mapfile::unlock(pointer* node)const
274 {
275    BOOST_RE_GUARD_STACK
276    assert(node >= _first);
277    assert(node <= _last);
278    if(node < _last)
279    {
280       if(--(*reinterpret_cast<int*>(*node)) == 0)
281       {
282          condemed.push_back(node);
283       }
284    }
285 }
286
287 long int get_file_length(std::FILE* hfile)
288 {
289    BOOST_RE_GUARD_STACK
290    long int result;
291    std::fseek(hfile, 0, SEEK_END);
292    result = std::ftell(hfile);
293    std::fseek(hfile, 0, SEEK_SET);
294    return result;
295 }
296
297
298 void mapfile::open(const char* file)
299 {
300    BOOST_RE_GUARD_STACK
301    hfile = std::fopen(file, "rb");
302 #ifndef BOOST_NO_EXCEPTIONS
303    try{
304 #endif
305    if(hfile != 0)
306    {
307       _size = get_file_length(hfile);
308       long cnodes = (_size + buf_size - 1) / buf_size;
309
310       // check that number of nodes is not too high:
311       if(cnodes > (long)((INT_MAX) / sizeof(pointer*)))
312       {
313          std::fclose(hfile);
314          hfile = 0;
315          _size = 0;
316          return;
317       }
318
319       _first = new pointer[(int)cnodes];
320       _last = _first + cnodes;
321       std::memset(_first, 0, cnodes*sizeof(pointer));
322    }
323    else
324    {
325 #ifndef BOOST_NO_EXCEPTIONS
326        throw std::runtime_error("Unable to open file.");
327 #else
328        BOOST_REGEX_NOEH_ASSERT(hfile != 0);
329 #endif
330    }
331 #ifndef BOOST_NO_EXCEPTIONS
332    }catch(...)
333    { close(); throw; }
334 #endif
335 }
336
337 void mapfile::close()
338 {
339    BOOST_RE_GUARD_STACK
340    if(hfile != 0)
341    {
342       pointer* p = _first;
343       while(p != _last)
344       {
345          if(*p)
346             delete[] *p;
347          ++p;
348       }
349       delete[] _first;
350       _size = 0;
351       _first = _last = 0;
352       std::fclose(hfile);
353       hfile = 0;
354       condemed.erase(condemed.begin(), condemed.end());
355    }
356 }
357
358
359 #endif
360
361
362 file_iterator::file_iterator()
363 {
364    BOOST_RE_GUARD_STACK
365    _root = _path = 0;
366    ref = 0;
367 #ifndef BOOST_NO_EXCEPTIONS
368    try{
369 #endif
370    _root = new char[MAX_PATH];
371    BOOST_REGEX_NOEH_ASSERT(_root)
372    _path = new char[MAX_PATH];
373    BOOST_REGEX_NOEH_ASSERT(_path)
374    ptr = _path;
375    *_path = 0;
376    *_root = 0;
377    ref = new file_iterator_ref();
378    BOOST_REGEX_NOEH_ASSERT(ref)
379    ref->hf = _fi_invalid_handle;
380    ref->count = 1;
381 #ifndef BOOST_NO_EXCEPTIONS
382    }
383    catch(...)
384    {
385       delete[] _root;
386       delete[] _path;
387       delete ref;
388       throw;
389    }
390 #endif
391 }
392
393 file_iterator::file_iterator(const char* wild)
394 {
395    BOOST_RE_GUARD_STACK
396    _root = _path = 0;
397    ref = 0;
398 #ifndef BOOST_NO_EXCEPTIONS
399    try{
400 #endif
401    _root = new char[MAX_PATH];
402    BOOST_REGEX_NOEH_ASSERT(_root)
403    _path = new char[MAX_PATH];
404    BOOST_REGEX_NOEH_ASSERT(_path)
405    std::strcpy(_root, wild);
406    ptr = _root;
407    while(*ptr)++ptr;
408    while((ptr > _root) && (*ptr != *_fi_sep) && (*ptr != *_fi_sep_alt))--ptr;
409    #if 0
410    *ptr = 0;
411    std::strcpy(_path, _root);
412    if(*_path == 0)
413       std::strcpy(_path, ".");
414    std::strcat(_path, _fi_sep);
415    ptr = _path + std::strlen(_path);
416    #else
417    if((ptr == _root) && ( (*ptr== *_fi_sep) || (*ptr==*_fi_sep_alt) ) )
418    {
419      _root[1]='\0';
420      std::strcpy(_path, _root);
421      ptr = _path + std::strlen(_path);
422    }
423    else
424    {
425      *ptr = 0;
426      std::strcpy(_path, _root);
427      if(*_path == 0)
428        std::strcpy(_path, ".");
429      std::strcat(_path, _fi_sep);
430      ptr = _path + std::strlen(_path);
431    }
432    #endif
433
434    ref = new file_iterator_ref();
435    BOOST_REGEX_NOEH_ASSERT(ref)
436    ref->hf = FindFirstFileA(wild, &(ref->_data));
437    ref->count = 1;
438
439    if(ref->hf == _fi_invalid_handle)
440    {
441       *_path = 0;
442       ptr = _path;
443    }
444    else
445    {
446       std::strcpy(ptr, ref->_data.cFileName);
447       if(ref->_data.dwFileAttributes & _fi_dir)
448          next();
449    }
450 #ifndef BOOST_NO_EXCEPTIONS
451    }
452    catch(...)
453    {
454       delete[] _root;
455       delete[] _path;
456       delete ref;
457       throw;
458    }
459 #endif
460 }
461
462 file_iterator::file_iterator(const file_iterator& other)
463 {
464    BOOST_RE_GUARD_STACK
465    _root = _path = 0;
466    ref = 0;
467 #ifndef BOOST_NO_EXCEPTIONS
468    try{
469 #endif
470    _root = new char[MAX_PATH];
471    BOOST_REGEX_NOEH_ASSERT(_root)
472    _path = new char[MAX_PATH];
473    BOOST_REGEX_NOEH_ASSERT(_path)
474    std::strcpy(_root, other._root);
475    std::strcpy(_path, other._path);
476    ptr = _path + (other.ptr - other._path);
477    ref = other.ref;
478 #ifndef BOOST_NO_EXCEPTIONS
479    }
480    catch(...)
481    {
482       delete[] _root;
483       delete[] _path;
484       throw;
485    }
486 #endif
487    ++(ref->count);
488 }
489
490 file_iterator& file_iterator::operator=(const file_iterator& other)
491 {
492    BOOST_RE_GUARD_STACK
493    std::strcpy(_root, other._root);
494    std::strcpy(_path, other._path);
495    ptr = _path + (other.ptr - other._path);
496    if(--(ref->count) == 0)
497    {
498       if(ref->hf != _fi_invalid_handle)
499          FindClose(ref->hf);
500       delete ref;
501    }
502    ref = other.ref;
503    ++(ref->count);
504    return *this;
505 }
506
507
508 file_iterator::~file_iterator()
509 {
510    BOOST_RE_GUARD_STACK
511    delete[] _root;
512    delete[] _path;
513    if(--(ref->count) == 0)
514    {
515       if(ref->hf != _fi_invalid_handle)
516          FindClose(ref->hf);
517       delete ref;
518    }
519 }
520
521 file_iterator file_iterator::operator++(int)
522 {
523    BOOST_RE_GUARD_STACK
524    file_iterator temp(*this);
525    next();
526    return temp;
527 }
528
529
530 void file_iterator::next()
531 {
532    BOOST_RE_GUARD_STACK
533    if(ref->hf != _fi_invalid_handle)
534    {
535       bool cont = true;
536       while(cont)
537       {
538          cont = FindNextFileA(ref->hf, &(ref->_data));
539          if(cont && ((ref->_data.dwFileAttributes & _fi_dir) == 0))
540             break;
541       }
542       if(!cont)
543       {
544          // end of sequence
545          FindClose(ref->hf);
546          ref->hf = _fi_invalid_handle;
547          *_path = 0;
548          ptr = _path;
549       }
550       else
551          std::strcpy(ptr, ref->_data.cFileName);
552    }
553 }
554
555
556
557 directory_iterator::directory_iterator()
558 {
559    BOOST_RE_GUARD_STACK
560    _root = _path = 0;
561    ref = 0;
562 #ifndef BOOST_NO_EXCEPTIONS
563    try{
564 #endif
565    _root = new char[MAX_PATH];
566    BOOST_REGEX_NOEH_ASSERT(_root)
567    _path = new char[MAX_PATH];
568    BOOST_REGEX_NOEH_ASSERT(_path)
569    ptr = _path;
570    *_path = 0;
571    *_root = 0;
572    ref = new file_iterator_ref();
573    BOOST_REGEX_NOEH_ASSERT(ref)
574    ref->hf = _fi_invalid_handle;
575    ref->count = 1;
576 #ifndef BOOST_NO_EXCEPTIONS
577    }
578    catch(...)
579    {
580       delete[] _root;
581       delete[] _path;
582       delete ref;
583       throw;
584    }
585 #endif
586 }
587
588 directory_iterator::directory_iterator(const char* wild)
589 {
590    BOOST_RE_GUARD_STACK
591    _root = _path = 0;
592    ref = 0;
593 #ifndef BOOST_NO_EXCEPTIONS
594    try{
595 #endif
596    _root = new char[MAX_PATH];
597    BOOST_REGEX_NOEH_ASSERT(_root)
598    _path = new char[MAX_PATH];
599    BOOST_REGEX_NOEH_ASSERT(_path)
600    std::strcpy(_root, wild);
601    ptr = _root;
602    while(*ptr)++ptr;
603    while((ptr > _root) && (*ptr != *_fi_sep) && (*ptr != *_fi_sep_alt))--ptr;
604    #if 0
605    *ptr = 0;
606    std::strcpy(_path, _root);
607    if(*_path == 0)
608       std::strcpy(_path, ".");
609    std::strcat(_path, _fi_sep);
610    ptr = _path + std::strlen(_path);
611    #else
612    if((ptr == _root) && ( (*ptr== *_fi_sep) || (*ptr==*_fi_sep_alt) ) )
613    {
614      _root[1]='\0';
615      std::strcpy(_path, _root);
616      ptr = _path + std::strlen(_path);
617    }
618    else
619    {
620      *ptr = 0;
621      std::strcpy(_path, _root);
622      if(*_path == 0)
623        std::strcpy(_path, ".");
624      std::strcat(_path, _fi_sep);
625      ptr = _path + std::strlen(_path);
626    }
627    #endif
628    ref = new file_iterator_ref();
629    BOOST_REGEX_NOEH_ASSERT(ref)
630    ref->count = 1;
631    ref->hf = FindFirstFileA(wild, &(ref->_data));
632    if(ref->hf == _fi_invalid_handle)
633    {
634       *_path = 0;
635       ptr = _path;
636    }
637    else
638    {
639       std::strcpy(ptr, ref->_data.cFileName);
640       if(((ref->_data.dwFileAttributes & _fi_dir) == 0) || (std::strcmp(ref->_data.cFileName, ".") == 0) || (std::strcmp(ref->_data.cFileName, "..") == 0))
641          next();
642    }
643 #ifndef BOOST_NO_EXCEPTIONS
644    }
645    catch(...)
646    {
647       delete[] _root;
648       delete[] _path;
649       delete ref;
650       throw;
651    }
652 #endif
653 }
654
655 directory_iterator::~directory_iterator()
656 {
657    BOOST_RE_GUARD_STACK
658    delete[] _root;
659    delete[] _path;
660    if(--(ref->count) == 0)
661    {
662       if(ref->hf != _fi_invalid_handle)
663          FindClose(ref->hf);
664       delete ref;
665    }
666 }
667
668 directory_iterator::directory_iterator(const directory_iterator& other)
669 {
670    BOOST_RE_GUARD_STACK
671    _root = _path = 0;
672    ref = 0;
673 #ifndef BOOST_NO_EXCEPTIONS
674    try{
675 #endif
676    _root = new char[MAX_PATH];
677    BOOST_REGEX_NOEH_ASSERT(_root)
678    _path = new char[MAX_PATH];
679    BOOST_REGEX_NOEH_ASSERT(_path)
680    std::strcpy(_root, other._root);
681    std::strcpy(_path, other._path);
682    ptr = _path + (other.ptr - other._path);
683    ref = other.ref;
684 #ifndef BOOST_NO_EXCEPTIONS
685    }
686    catch(...)
687    {
688       delete[] _root;
689       delete[] _path;
690       throw;
691    }
692 #endif
693    ++(ref->count);
694 }
695
696 directory_iterator& directory_iterator::operator=(const directory_iterator& other)
697 {
698    BOOST_RE_GUARD_STACK
699    std::strcpy(_root, other._root);
700    std::strcpy(_path, other._path);
701    ptr = _path + (other.ptr - other._path);
702    if(--(ref->count) == 0)
703    {
704       if(ref->hf != _fi_invalid_handle)
705          FindClose(ref->hf);
706       delete ref;
707    }
708    ref = other.ref;
709    ++(ref->count);
710    return *this;
711 }
712
713 directory_iterator directory_iterator::operator++(int)
714 {
715    BOOST_RE_GUARD_STACK
716    directory_iterator temp(*this);
717    next();
718    return temp;
719 }
720
721 void directory_iterator::next()
722 {
723    BOOST_RE_GUARD_STACK
724    if(ref->hf != _fi_invalid_handle)
725    {
726       bool cont = true;
727       while(cont)
728       {
729          cont = FindNextFileA(ref->hf, &(ref->_data));
730          if(cont && (ref->_data.dwFileAttributes & _fi_dir))
731          {
732             if(std::strcmp(ref->_data.cFileName, ".") && std::strcmp(ref->_data.cFileName, ".."))
733                break;
734          }
735       }
736       if(!cont)
737       {
738          // end of sequence
739          FindClose(ref->hf);
740          ref->hf = _fi_invalid_handle;
741          *_path = 0;
742          ptr = _path;
743       }
744       else
745          std::strcpy(ptr, ref->_data.cFileName);
746    }
747 }
748
749
750 #ifdef BOOST_REGEX_FI_POSIX_DIR
751
752 struct _fi_priv_data
753 {
754    char root[MAX_PATH];
755    char* mask;
756    DIR* d;
757    _fi_priv_data(const char* p);
758 };
759
760 _fi_priv_data::_fi_priv_data(const char* p)
761 {
762    BOOST_RE_GUARD_STACK
763    std::strcpy(root, p);
764    mask = root;
765    while(*mask) ++mask;
766    while((mask > root) && (*mask != *_fi_sep) && (*mask != *_fi_sep_alt)) --mask;
767    if(mask == root && ((*mask== *_fi_sep) || (*mask == *_fi_sep_alt)) )
768    {
769       root[1] = '\0';
770       std::strcpy(root+2, p+1);
771       mask = root+2;
772    }
773    else if(mask == root)
774    {
775       root[0] = '.';
776       root[1] = '\0';
777       std::strcpy(root+2, p);
778       mask = root+2;
779    }
780    else
781    {
782       *mask = 0;
783       ++mask;
784    }
785 }
786
787 bool iswild(const char* mask, const char* name)
788 {
789    BOOST_RE_GUARD_STACK
790    while(*mask && *name)
791    {
792       switch(*mask)
793       {
794       case '?':
795          ++name;
796          ++mask;
797          continue;
798       case '*':
799          ++mask;
800          if(*mask == 0)
801             return true;
802          while(*name)
803          {
804             if(iswild(mask, name))
805                return true;
806             ++name;
807          }
808          return false;
809       case '.':
810          if(0 == *name)
811          {
812             ++mask;
813             continue;
814          }
815          // fall through:
816       default:
817          if(BOOST_REGEX_FI_TRANSLATE(*mask) != BOOST_REGEX_FI_TRANSLATE(*name))
818             return false;
819          ++mask;
820          ++name;
821          continue;
822       }
823    }
824    if(*mask != *name)
825       return false;
826    return true;
827 }
828
829 unsigned _fi_attributes(const char* root, const char* name)
830 {
831    BOOST_RE_GUARD_STACK
832    char buf[MAX_PATH];
833    if( ( (root[0] == *_fi_sep) || (root[0] == *_fi_sep_alt) ) && (root[1] == '\0') )
834       std::sprintf(buf, "%s%s", root, name);
835    else
836       std::sprintf(buf, "%s%s%s", root, _fi_sep, name);
837    DIR* d = opendir(buf);
838    if(d)
839    {
840       closedir(d);
841       return _fi_dir;
842    }
843    return 0;
844 }
845
846 _fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindFileData)
847 {
848    BOOST_RE_GUARD_STACK
849    _fi_find_handle dat = new _fi_priv_data(lpFileName);
850
851    DIR* h = opendir(dat->root);
852    dat->d = h;
853    if(h != 0)
854    {
855       if(_fi_FindNextFile(dat, lpFindFileData))
856          return dat;
857    }
858    delete dat;
859    return 0;
860 }
861
862 bool _fi_FindNextFile(_fi_find_handle dat, _fi_find_data* lpFindFileData)
863 {
864    BOOST_RE_GUARD_STACK
865    dirent* d;
866    do
867    {
868       d = readdir(dat->d);
869    } while(d && !iswild(dat->mask, d->d_name));
870
871    if(d)
872    {
873       std::strcpy(lpFindFileData->cFileName, d->d_name);
874       lpFindFileData->dwFileAttributes = _fi_attributes(dat->root, d->d_name);
875       return true;
876    }
877    return false;
878 }
879
880 bool _fi_FindClose(_fi_find_handle dat)
881 {
882    BOOST_RE_GUARD_STACK
883    closedir(dat->d);
884    delete dat;
885    return true;
886 }
887
888 #endif
889
890 } // namespace re_detail
891 } // namspace boost
892
893 #endif    // BOOST_REGEX_NO_FILEITER
894
895
896
897
898
899
900
901
902