sclang: ServerShmInterface - avoid object duplication in deepCopy
[supercollider.git] / external_libraries / boost / libs / regex / src / fileiter.cpp
blob38c0d2c3a5307967b65dab5767f4f4b182a584eb
1 /*
3 * Copyright (c) 1998-2002
4 * John Maddock
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
13 * LOCATION: see http://www.boost.org for most recent version.
14 * FILE: fileiter.cpp
15 * VERSION: see <boost/version.hpp>
16 * DESCRIPTION: Implements file io primitives + directory searching for class boost::RegEx.
20 #define BOOST_REGEX_SOURCE
22 #include <climits>
23 #include <stdexcept>
24 #include <string>
25 #include <boost/throw_exception.hpp>
26 #include <boost/regex/v4/fileiter.hpp>
27 #include <boost/regex/v4/regex_workaround.hpp>
28 #include <boost/regex/pattern_except.hpp>
30 #include <cstdio>
31 #if defined(BOOST_NO_STDC_NAMESPACE)
32 namespace std{
33 using ::sprintf;
34 using ::fseek;
35 using ::fread;
36 using ::ftell;
37 using ::fopen;
38 using ::fclose;
39 using ::FILE;
40 using ::strcpy;
41 using ::strcpy;
42 using ::strcat;
43 using ::strcmp;
44 using ::strlen;
46 #endif
49 #ifndef BOOST_REGEX_NO_FILEITER
51 #if defined(__CYGWIN__) || defined(__CYGWIN32__)
52 #include <sys/cygwin.h>
53 #endif
55 #ifdef BOOST_MSVC
56 # pragma warning(disable: 4800)
57 #endif
59 namespace boost{
60 namespace re_detail{
61 // start with the operating system specific stuff:
63 #if (defined(__BORLANDC__) || defined(BOOST_REGEX_FI_WIN32_DIR) || defined(BOOST_MSVC)) && !defined(BOOST_RE_NO_WIN32)
65 // platform is DOS or Windows
66 // directories are separated with '\\'
67 // and names are insensitive of case
69 BOOST_REGEX_DECL const char* _fi_sep = "\\";
70 const char* _fi_sep_alt = "/";
71 #define BOOST_REGEX_FI_TRANSLATE(c) std::tolower(c)
73 #else
75 // platform is not DOS or Windows
76 // directories are separated with '/'
77 // and names are sensitive of case
79 BOOST_REGEX_DECL const char* _fi_sep = "/";
80 const char* _fi_sep_alt = _fi_sep;
81 #define BOOST_REGEX_FI_TRANSLATE(c) c
83 #endif
85 #ifdef BOOST_REGEX_FI_WIN32_MAP
87 void mapfile::open(const char* file)
89 #if defined(BOOST_NO_ANSI_APIS)
90 int filename_size = strlen(file);
91 LPWSTR wide_file = (LPWSTR)_alloca( (filename_size + 1) * sizeof(WCHAR) );
92 if(::MultiByteToWideChar(CP_ACP, 0, file, filename_size, wide_file, filename_size + 1) == 0)
93 hfile = INVALID_HANDLE_VALUE;
94 else
95 hfile = CreateFileW(wide_file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
96 #elif defined(__CYGWIN__)||defined(__CYGWIN32__)
97 char win32file[ MAX_PATH ];
98 cygwin_conv_to_win32_path( file, win32file );
99 hfile = CreateFileA(win32file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
100 #else
101 hfile = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
102 #endif
103 if(hfile != INVALID_HANDLE_VALUE)
105 hmap = CreateFileMapping(hfile, 0, PAGE_READONLY, 0, 0, 0);
106 if((hmap == INVALID_HANDLE_VALUE) || (hmap == NULL))
108 CloseHandle(hfile);
109 hmap = 0;
110 hfile = 0;
111 std::runtime_error err("Unable to create file mapping.");
112 boost::re_detail::raise_runtime_error(err);
114 _first = static_cast<const char*>(MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0));
115 if(_first == 0)
117 CloseHandle(hmap);
118 CloseHandle(hfile);
119 hmap = 0;
120 hfile = 0;
121 std::runtime_error err("Unable to create file mapping.");
123 _last = _first + GetFileSize(hfile, 0);
125 else
127 hfile = 0;
128 #ifndef BOOST_NO_EXCEPTIONS
129 throw std::runtime_error("Unable to open file.");
130 #else
131 BOOST_REGEX_NOEH_ASSERT(hfile != INVALID_HANDLE_VALUE);
132 #endif
136 void mapfile::close()
138 if(hfile != INVALID_HANDLE_VALUE)
140 UnmapViewOfFile((void*)_first);
141 CloseHandle(hmap);
142 CloseHandle(hfile);
143 hmap = hfile = 0;
144 _first = _last = 0;
148 #elif !defined(BOOST_RE_NO_STL)
150 mapfile_iterator& mapfile_iterator::operator = (const mapfile_iterator& i)
152 if(file && node)
153 file->unlock(node);
154 file = i.file;
155 node = i.node;
156 offset = i.offset;
157 if(file)
158 file->lock(node);
159 return *this;
162 mapfile_iterator& mapfile_iterator::operator++ ()
164 if((++offset == mapfile::buf_size) && file)
166 ++node;
167 offset = 0;
168 file->lock(node);
169 file->unlock(node-1);
171 return *this;
174 mapfile_iterator mapfile_iterator::operator++ (int)
176 mapfile_iterator temp(*this);
177 if((++offset == mapfile::buf_size) && file)
179 ++node;
180 offset = 0;
181 file->lock(node);
182 file->unlock(node-1);
184 return temp;
187 mapfile_iterator& mapfile_iterator::operator-- ()
189 if((offset == 0) && file)
191 --node;
192 offset = mapfile::buf_size - 1;
193 file->lock(node);
194 file->unlock(node + 1);
196 else
197 --offset;
198 return *this;
201 mapfile_iterator mapfile_iterator::operator-- (int)
203 mapfile_iterator temp(*this);
204 if((offset == 0) && file)
206 --node;
207 offset = mapfile::buf_size - 1;
208 file->lock(node);
209 file->unlock(node + 1);
211 else
212 --offset;
213 return temp;
216 mapfile_iterator operator + (const mapfile_iterator& i, long off)
218 mapfile_iterator temp(i);
219 temp += off;
220 return temp;
223 mapfile_iterator operator - (const mapfile_iterator& i, long off)
225 mapfile_iterator temp(i);
226 temp -= off;
227 return temp;
230 mapfile::iterator mapfile::begin()const
232 return mapfile_iterator(this, 0);
235 mapfile::iterator mapfile::end()const
237 return mapfile_iterator(this, _size);
240 void mapfile::lock(pointer* node)const
242 BOOST_ASSERT(node >= _first);
243 BOOST_ASSERT(node <= _last);
244 if(node < _last)
246 if(*node == 0)
248 if(condemed.empty())
250 *node = new char[sizeof(int) + buf_size];
251 *(reinterpret_cast<int*>(*node)) = 1;
253 else
255 pointer* p = condemed.front();
256 condemed.pop_front();
257 *node = *p;
258 *p = 0;
259 *(reinterpret_cast<int*>(*node)) = 1;
262 std::size_t read_size = 0;
263 int read_pos = std::fseek(hfile, (node - _first) * buf_size, SEEK_SET);
265 if(0 == read_pos && node == _last - 1)
266 read_size = std::fread(*node + sizeof(int), _size % buf_size, 1, hfile);
267 else
268 read_size = std::fread(*node + sizeof(int), buf_size, 1, hfile);
269 #ifndef BOOST_NO_EXCEPTIONS
270 if((read_size == 0) || (std::ferror(hfile)))
272 throw std::runtime_error("Unable to read file.");
274 #else
275 BOOST_REGEX_NOEH_ASSERT((0 == std::ferror(hfile)) && (read_size != 0));
276 #endif
278 else
280 if(*reinterpret_cast<int*>(*node) == 0)
282 *reinterpret_cast<int*>(*node) = 1;
283 condemed.remove(node);
285 else
286 ++(*reinterpret_cast<int*>(*node));
291 void mapfile::unlock(pointer* node)const
293 BOOST_ASSERT(node >= _first);
294 BOOST_ASSERT(node <= _last);
295 if(node < _last)
297 if(--(*reinterpret_cast<int*>(*node)) == 0)
299 condemed.push_back(node);
304 long int get_file_length(std::FILE* hfile)
306 long int result;
307 std::fseek(hfile, 0, SEEK_END);
308 result = std::ftell(hfile);
309 std::fseek(hfile, 0, SEEK_SET);
310 return result;
314 void mapfile::open(const char* file)
316 hfile = std::fopen(file, "rb");
317 #ifndef BOOST_NO_EXCEPTIONS
318 try{
319 #endif
320 if(hfile != 0)
322 _size = get_file_length(hfile);
323 long cnodes = (_size + buf_size - 1) / buf_size;
325 // check that number of nodes is not too high:
326 if(cnodes > (long)((INT_MAX) / sizeof(pointer*)))
328 std::fclose(hfile);
329 hfile = 0;
330 _size = 0;
331 return;
334 _first = new pointer[(int)cnodes];
335 _last = _first + cnodes;
336 std::memset(_first, 0, cnodes*sizeof(pointer));
338 else
340 std::runtime_error err("Unable to open file.");
342 #ifndef BOOST_NO_EXCEPTIONS
343 }catch(...)
344 { close(); throw; }
345 #endif
348 void mapfile::close()
350 if(hfile != 0)
352 pointer* p = _first;
353 while(p != _last)
355 if(*p)
356 delete[] *p;
357 ++p;
359 delete[] _first;
360 _size = 0;
361 _first = _last = 0;
362 std::fclose(hfile);
363 hfile = 0;
364 condemed.erase(condemed.begin(), condemed.end());
369 #endif
371 inline _fi_find_handle find_first_file(const char* wild, _fi_find_data& data)
373 #ifdef BOOST_NO_ANSI_APIS
374 std::size_t wild_size = std::strlen(wild);
375 LPWSTR wide_wild = (LPWSTR)_alloca( (wild_size + 1) * sizeof(WCHAR) );
376 if (::MultiByteToWideChar(CP_ACP, 0, wild, wild_size, wide_wild, wild_size + 1) == 0)
377 return _fi_invalid_handle;
379 return FindFirstFileW(wide_wild, &data);
380 #else
381 return FindFirstFileA(wild, &data);
382 #endif
385 inline bool find_next_file(_fi_find_handle hf, _fi_find_data& data)
387 #ifdef BOOST_NO_ANSI_APIS
388 return FindNextFileW(hf, &data);
389 #else
390 return FindNextFileA(hf, &data);
391 #endif
394 inline void copy_find_file_result_with_overflow_check(const _fi_find_data& data, char* path, size_t max_size)
396 #ifdef BOOST_NO_ANSI_APIS
397 if (::WideCharToMultiByte(CP_ACP, 0, data.cFileName, -1, path, max_size, NULL, NULL) == 0)
398 re_detail::overflow_error_if_not_zero(1);
399 #else
400 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(path, max_size, data.cFileName));
401 #endif
404 inline bool is_not_current_or_parent_path_string(const _fi_find_data& data)
406 #ifdef BOOST_NO_ANSI_APIS
407 return (std::wcscmp(data.cFileName, L".") && std::wcscmp(data.cFileName, L".."));
408 #else
409 return (std::strcmp(data.cFileName, ".") && std::strcmp(data.cFileName, ".."));
410 #endif
414 file_iterator::file_iterator()
416 _root = _path = 0;
417 ref = 0;
418 #ifndef BOOST_NO_EXCEPTIONS
419 try{
420 #endif
421 _root = new char[MAX_PATH];
422 BOOST_REGEX_NOEH_ASSERT(_root)
423 _path = new char[MAX_PATH];
424 BOOST_REGEX_NOEH_ASSERT(_path)
425 ptr = _path;
426 *_path = 0;
427 *_root = 0;
428 ref = new file_iterator_ref();
429 BOOST_REGEX_NOEH_ASSERT(ref)
430 ref->hf = _fi_invalid_handle;
431 ref->count = 1;
432 #ifndef BOOST_NO_EXCEPTIONS
434 catch(...)
436 delete[] _root;
437 delete[] _path;
438 delete ref;
439 throw;
441 #endif
444 file_iterator::file_iterator(const char* wild)
446 _root = _path = 0;
447 ref = 0;
448 #ifndef BOOST_NO_EXCEPTIONS
449 try{
450 #endif
451 _root = new char[MAX_PATH];
452 BOOST_REGEX_NOEH_ASSERT(_root)
453 _path = new char[MAX_PATH];
454 BOOST_REGEX_NOEH_ASSERT(_path)
455 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, wild));
456 ptr = _root;
457 while(*ptr)++ptr;
458 while((ptr > _root) && (*ptr != *_fi_sep) && (*ptr != *_fi_sep_alt))--ptr;
459 if((ptr == _root) && ( (*ptr== *_fi_sep) || (*ptr==*_fi_sep_alt) ) )
461 _root[1]='\0';
462 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, _root));
464 else
466 *ptr = 0;
467 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, _root));
468 if(*_path == 0)
469 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, "."));
470 re_detail::overflow_error_if_not_zero(re_detail::strcat_s(_path, MAX_PATH, _fi_sep));
472 ptr = _path + std::strlen(_path);
474 ref = new file_iterator_ref();
475 BOOST_REGEX_NOEH_ASSERT(ref)
476 ref->hf = find_first_file(wild, ref->_data);
477 ref->count = 1;
479 if(ref->hf == _fi_invalid_handle)
481 *_path = 0;
482 ptr = _path;
484 else
486 copy_find_file_result_with_overflow_check(ref->_data, ptr, (MAX_PATH - (ptr - _path)));
487 if(ref->_data.dwFileAttributes & _fi_dir)
488 next();
490 #ifndef BOOST_NO_EXCEPTIONS
492 catch(...)
494 delete[] _root;
495 delete[] _path;
496 delete ref;
497 throw;
499 #endif
502 file_iterator::file_iterator(const file_iterator& other)
504 _root = _path = 0;
505 ref = 0;
506 #ifndef BOOST_NO_EXCEPTIONS
507 try{
508 #endif
509 _root = new char[MAX_PATH];
510 BOOST_REGEX_NOEH_ASSERT(_root)
511 _path = new char[MAX_PATH];
512 BOOST_REGEX_NOEH_ASSERT(_path)
513 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, other._root));
514 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, other._path));
515 ptr = _path + (other.ptr - other._path);
516 ref = other.ref;
517 #ifndef BOOST_NO_EXCEPTIONS
519 catch(...)
521 delete[] _root;
522 delete[] _path;
523 throw;
525 #endif
526 ++(ref->count);
529 file_iterator& file_iterator::operator=(const file_iterator& other)
531 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, other._root));
532 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, other._path));
533 ptr = _path + (other.ptr - other._path);
534 if(--(ref->count) == 0)
536 if(ref->hf != _fi_invalid_handle)
537 FindClose(ref->hf);
538 delete ref;
540 ref = other.ref;
541 ++(ref->count);
542 return *this;
546 file_iterator::~file_iterator()
548 delete[] _root;
549 delete[] _path;
550 if(--(ref->count) == 0)
552 if(ref->hf != _fi_invalid_handle)
553 FindClose(ref->hf);
554 delete ref;
558 file_iterator file_iterator::operator++(int)
560 file_iterator temp(*this);
561 next();
562 return temp;
566 void file_iterator::next()
568 if(ref->hf != _fi_invalid_handle)
570 bool cont = true;
571 while(cont)
573 cont = find_next_file(ref->hf, ref->_data);
574 if(cont && ((ref->_data.dwFileAttributes & _fi_dir) == 0))
575 break;
577 if(!cont)
579 // end of sequence
580 FindClose(ref->hf);
581 ref->hf = _fi_invalid_handle;
582 *_path = 0;
583 ptr = _path;
585 else
586 copy_find_file_result_with_overflow_check(ref->_data, ptr, MAX_PATH - (ptr - _path));
592 directory_iterator::directory_iterator()
594 _root = _path = 0;
595 ref = 0;
596 #ifndef BOOST_NO_EXCEPTIONS
597 try{
598 #endif
599 _root = new char[MAX_PATH];
600 BOOST_REGEX_NOEH_ASSERT(_root)
601 _path = new char[MAX_PATH];
602 BOOST_REGEX_NOEH_ASSERT(_path)
603 ptr = _path;
604 *_path = 0;
605 *_root = 0;
606 ref = new file_iterator_ref();
607 BOOST_REGEX_NOEH_ASSERT(ref)
608 ref->hf = _fi_invalid_handle;
609 ref->count = 1;
610 #ifndef BOOST_NO_EXCEPTIONS
612 catch(...)
614 delete[] _root;
615 delete[] _path;
616 delete ref;
617 throw;
619 #endif
622 directory_iterator::directory_iterator(const char* wild)
624 _root = _path = 0;
625 ref = 0;
626 #ifndef BOOST_NO_EXCEPTIONS
627 try{
628 #endif
629 _root = new char[MAX_PATH];
630 BOOST_REGEX_NOEH_ASSERT(_root)
631 _path = new char[MAX_PATH];
632 BOOST_REGEX_NOEH_ASSERT(_path)
633 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, wild));
634 ptr = _root;
635 while(*ptr)++ptr;
636 while((ptr > _root) && (*ptr != *_fi_sep) && (*ptr != *_fi_sep_alt))--ptr;
638 if((ptr == _root) && ( (*ptr== *_fi_sep) || (*ptr==*_fi_sep_alt) ) )
640 _root[1]='\0';
641 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, _root));
643 else
645 *ptr = 0;
646 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, _root));
647 if(*_path == 0)
648 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, "."));
649 re_detail::overflow_error_if_not_zero(re_detail::strcat_s(_path, MAX_PATH, _fi_sep));
651 ptr = _path + std::strlen(_path);
653 ref = new file_iterator_ref();
654 BOOST_REGEX_NOEH_ASSERT(ref)
655 ref->count = 1;
656 ref->hf = find_first_file(wild, ref->_data);
657 if(ref->hf == _fi_invalid_handle)
659 *_path = 0;
660 ptr = _path;
662 else
664 copy_find_file_result_with_overflow_check(ref->_data, ptr, MAX_PATH - (ptr - _path));
665 if(((ref->_data.dwFileAttributes & _fi_dir) == 0) || (std::strcmp(ptr, ".") == 0) || (std::strcmp(ptr, "..") == 0))
666 next();
668 #ifndef BOOST_NO_EXCEPTIONS
670 catch(...)
672 delete[] _root;
673 delete[] _path;
674 delete ref;
675 throw;
677 #endif
680 directory_iterator::~directory_iterator()
682 delete[] _root;
683 delete[] _path;
684 if(--(ref->count) == 0)
686 if(ref->hf != _fi_invalid_handle)
687 FindClose(ref->hf);
688 delete ref;
692 directory_iterator::directory_iterator(const directory_iterator& other)
694 _root = _path = 0;
695 ref = 0;
696 #ifndef BOOST_NO_EXCEPTIONS
697 try{
698 #endif
699 _root = new char[MAX_PATH];
700 BOOST_REGEX_NOEH_ASSERT(_root)
701 _path = new char[MAX_PATH];
702 BOOST_REGEX_NOEH_ASSERT(_path)
703 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, other._root));
704 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, other._path));
705 ptr = _path + (other.ptr - other._path);
706 ref = other.ref;
707 #ifndef BOOST_NO_EXCEPTIONS
709 catch(...)
711 delete[] _root;
712 delete[] _path;
713 throw;
715 #endif
716 ++(ref->count);
719 directory_iterator& directory_iterator::operator=(const directory_iterator& other)
721 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, other._root));
722 re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, other._path));
723 ptr = _path + (other.ptr - other._path);
724 if(--(ref->count) == 0)
726 if(ref->hf != _fi_invalid_handle)
727 FindClose(ref->hf);
728 delete ref;
730 ref = other.ref;
731 ++(ref->count);
732 return *this;
735 directory_iterator directory_iterator::operator++(int)
737 directory_iterator temp(*this);
738 next();
739 return temp;
742 void directory_iterator::next()
744 if(ref->hf != _fi_invalid_handle)
746 bool cont = true;
747 while(cont)
749 cont = find_next_file(ref->hf, ref->_data);
750 if(cont && (ref->_data.dwFileAttributes & _fi_dir))
752 if(is_not_current_or_parent_path_string(ref->_data))
753 break;
756 if(!cont)
758 // end of sequence
759 FindClose(ref->hf);
760 ref->hf = _fi_invalid_handle;
761 *_path = 0;
762 ptr = _path;
764 else
765 copy_find_file_result_with_overflow_check(ref->_data, ptr, MAX_PATH - (ptr - _path));
770 #ifdef BOOST_REGEX_FI_POSIX_DIR
772 struct _fi_priv_data
774 char root[MAX_PATH];
775 char* mask;
776 DIR* d;
777 _fi_priv_data(const char* p);
780 _fi_priv_data::_fi_priv_data(const char* p)
782 std::strcpy(root, p);
783 mask = root;
784 while(*mask) ++mask;
785 while((mask > root) && (*mask != *_fi_sep) && (*mask != *_fi_sep_alt)) --mask;
786 if(mask == root && ((*mask== *_fi_sep) || (*mask == *_fi_sep_alt)) )
788 root[1] = '\0';
789 std::strcpy(root+2, p+1);
790 mask = root+2;
792 else if(mask == root)
794 root[0] = '.';
795 root[1] = '\0';
796 std::strcpy(root+2, p);
797 mask = root+2;
799 else
801 *mask = 0;
802 ++mask;
806 bool iswild(const char* mask, const char* name)
808 while(*mask && *name)
810 switch(*mask)
812 case '?':
813 ++name;
814 ++mask;
815 continue;
816 case '*':
817 ++mask;
818 if(*mask == 0)
819 return true;
820 while(*name)
822 if(iswild(mask, name))
823 return true;
824 ++name;
826 return false;
827 case '.':
828 if(0 == *name)
830 ++mask;
831 continue;
833 // fall through:
834 default:
835 if(BOOST_REGEX_FI_TRANSLATE(*mask) != BOOST_REGEX_FI_TRANSLATE(*name))
836 return false;
837 ++mask;
838 ++name;
839 continue;
842 if(*mask != *name)
843 return false;
844 return true;
847 unsigned _fi_attributes(const char* root, const char* name)
849 char buf[MAX_PATH];
850 // verify that we can not overflow:
851 if(std::strlen(root) + std::strlen(_fi_sep) + std::strlen(name) >= MAX_PATH)
852 return 0;
853 int r;
854 if( ( (root[0] == *_fi_sep) || (root[0] == *_fi_sep_alt) ) && (root[1] == '\0') )
855 r = (std::sprintf)(buf, "%s%s", root, name);
856 else
857 r = (std::sprintf)(buf, "%s%s%s", root, _fi_sep, name);
858 if(r < 0)
859 return 0; // sprintf failed
860 DIR* d = opendir(buf);
861 if(d)
863 closedir(d);
864 return _fi_dir;
866 return 0;
869 _fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindFileData)
871 _fi_find_handle dat = new _fi_priv_data(lpFileName);
873 DIR* h = opendir(dat->root);
874 dat->d = h;
875 if(h != 0)
877 if(_fi_FindNextFile(dat, lpFindFileData))
878 return dat;
880 delete dat;
881 return 0;
884 bool _fi_FindNextFile(_fi_find_handle dat, _fi_find_data* lpFindFileData)
886 dirent* d;
889 d = readdir(dat->d);
890 } while(d && !iswild(dat->mask, d->d_name));
892 if(d)
894 std::strcpy(lpFindFileData->cFileName, d->d_name);
895 lpFindFileData->dwFileAttributes = _fi_attributes(dat->root, d->d_name);
896 return true;
898 return false;
901 bool _fi_FindClose(_fi_find_handle dat)
903 closedir(dat->d);
904 delete dat;
905 return true;
908 #endif
910 } // namespace re_detail
911 } // namspace boost
913 #endif // BOOST_REGEX_NO_FILEITER