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