3
* Copyright (c) 1998-2002
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.
17
* LOCATION: see http://www.boost.org for most recent version.
19
* VERSION: see <boost/version.hpp>
20
* DESCRIPTION: Implements file io primitives + directory searching for class boost::RegEx.
24
#define BOOST_REGEX_SOURCE
28
#include <boost/regex/v3/fileiter.hpp>
30
#ifndef BOOST_REGEX_NO_FILEITER
32
#if defined(__CYGWIN__) || defined(__CYGWIN32__)
33
#include <sys/cygwin.h>
37
# pragma warning(disable: 4800)
42
// start with the operating system specific stuff:
44
#if (defined(__BORLANDC__) || defined(BOOST_REGEX_FI_WIN32_DIR) || defined(BOOST_MSVC)) && !defined(BOOST_RE_NO_WIN32)
46
// platform is DOS or Windows
47
// directories are separated with '\\'
48
// and names are insensitive of case
50
const char* _fi_sep = "\\";
51
const char* _fi_sep_alt = "/";
52
#define BOOST_REGEX_FI_TRANSLATE(c) std::tolower(c)
56
// platform is not DOS or Windows
57
// directories are separated with '/'
58
// and names are sensitive of case
60
const char* _fi_sep = "/";
61
const char* _fi_sep_alt = _fi_sep;
62
#define BOOST_REGEX_FI_TRANSLATE(c) c
66
#ifdef BOOST_REGEX_FI_WIN32_MAP
68
void mapfile::open(const char* file)
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);
76
hfile = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
78
if(hfile != INVALID_HANDLE_VALUE)
80
hmap = CreateFileMapping(hfile, 0, PAGE_READONLY, 0, 0, 0);
81
if((hmap == INVALID_HANDLE_VALUE) || (hmap == NULL))
86
#ifndef BOOST_NO_EXCEPTIONS
87
throw std::runtime_error("Unable to create file mapping.");
89
BOOST_REGEX_NOEH_ASSERT(hmap != INVALID_HANDLE_VALUE);
92
_first = static_cast<const char*>(MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0));
99
#ifndef BOOST_NO_EXCEPTIONS
100
throw std::runtime_error("Unable to create file mapping.");
102
BOOST_REGEX_NOEH_ASSERT(_first != 0);
105
_last = _first + GetFileSize(hfile, 0);
110
#ifndef BOOST_NO_EXCEPTIONS
111
throw std::runtime_error("Unable to open file.");
113
BOOST_REGEX_NOEH_ASSERT(hfile != INVALID_HANDLE_VALUE);
118
void mapfile::close()
121
if(hfile != INVALID_HANDLE_VALUE)
123
UnmapViewOfFile((void*)_first);
131
#elif !defined(BOOST_RE_NO_STL)
133
mapfile_iterator& mapfile_iterator::operator = (const mapfile_iterator& i)
146
mapfile_iterator& mapfile_iterator::operator++ ()
149
if((++offset == mapfile::buf_size) && file)
154
file->unlock(node-1);
159
mapfile_iterator mapfile_iterator::operator++ (int)
162
mapfile_iterator temp(*this);
163
if((++offset == mapfile::buf_size) && file)
168
file->unlock(node-1);
173
mapfile_iterator& mapfile_iterator::operator-- ()
176
if((offset == 0) && file)
179
offset = mapfile::buf_size - 1;
181
file->unlock(node + 1);
188
mapfile_iterator mapfile_iterator::operator-- (int)
191
mapfile_iterator temp(*this);
192
if((offset == 0) && file)
195
offset = mapfile::buf_size - 1;
197
file->unlock(node + 1);
204
mapfile_iterator operator + (const mapfile_iterator& i, long off)
207
mapfile_iterator temp(i);
212
mapfile_iterator operator - (const mapfile_iterator& i, long off)
215
mapfile_iterator temp(i);
220
mapfile::iterator mapfile::begin()const
223
return mapfile_iterator(this, 0);
226
mapfile::iterator mapfile::end()const
229
return mapfile_iterator(this, _size);
232
void mapfile::lock(pointer* node)const
235
assert(node >= _first);
236
assert(node <= _last);
243
*node = new char[sizeof(int) + buf_size];
244
*(reinterpret_cast<int*>(*node)) = 1;
248
pointer* p = condemed.front();
249
condemed.pop_front();
252
*(reinterpret_cast<int*>(*node)) = 1;
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);
258
std::fread(*node + sizeof(int), buf_size, 1, hfile);
262
if(*reinterpret_cast<int*>(*node) == 0)
264
*reinterpret_cast<int*>(*node) = 1;
265
condemed.remove(node);
268
++(*reinterpret_cast<int*>(*node));
273
void mapfile::unlock(pointer* node)const
276
assert(node >= _first);
277
assert(node <= _last);
280
if(--(*reinterpret_cast<int*>(*node)) == 0)
282
condemed.push_back(node);
287
long int get_file_length(std::FILE* hfile)
291
std::fseek(hfile, 0, SEEK_END);
292
result = std::ftell(hfile);
293
std::fseek(hfile, 0, SEEK_SET);
298
void mapfile::open(const char* file)
301
hfile = std::fopen(file, "rb");
302
#ifndef BOOST_NO_EXCEPTIONS
307
_size = get_file_length(hfile);
308
long cnodes = (_size + buf_size - 1) / buf_size;
310
// check that number of nodes is not too high:
311
if(cnodes > (long)((INT_MAX) / sizeof(pointer*)))
319
_first = new pointer[(int)cnodes];
320
_last = _first + cnodes;
321
std::memset(_first, 0, cnodes*sizeof(pointer));
325
#ifndef BOOST_NO_EXCEPTIONS
326
throw std::runtime_error("Unable to open file.");
328
BOOST_REGEX_NOEH_ASSERT(hfile != 0);
331
#ifndef BOOST_NO_EXCEPTIONS
337
void mapfile::close()
354
condemed.erase(condemed.begin(), condemed.end());
362
file_iterator::file_iterator()
367
#ifndef BOOST_NO_EXCEPTIONS
370
_root = new char[MAX_PATH];
371
BOOST_REGEX_NOEH_ASSERT(_root)
372
_path = new char[MAX_PATH];
373
BOOST_REGEX_NOEH_ASSERT(_path)
377
ref = new file_iterator_ref();
378
BOOST_REGEX_NOEH_ASSERT(ref)
379
ref->hf = _fi_invalid_handle;
381
#ifndef BOOST_NO_EXCEPTIONS
393
file_iterator::file_iterator(const char* wild)
398
#ifndef BOOST_NO_EXCEPTIONS
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);
408
while((ptr > _root) && (*ptr != *_fi_sep) && (*ptr != *_fi_sep_alt))--ptr;
411
std::strcpy(_path, _root);
413
std::strcpy(_path, ".");
414
std::strcat(_path, _fi_sep);
415
ptr = _path + std::strlen(_path);
417
if((ptr == _root) && ( (*ptr== *_fi_sep) || (*ptr==*_fi_sep_alt) ) )
420
std::strcpy(_path, _root);
421
ptr = _path + std::strlen(_path);
426
std::strcpy(_path, _root);
428
std::strcpy(_path, ".");
429
std::strcat(_path, _fi_sep);
430
ptr = _path + std::strlen(_path);
434
ref = new file_iterator_ref();
435
BOOST_REGEX_NOEH_ASSERT(ref)
436
ref->hf = FindFirstFileA(wild, &(ref->_data));
439
if(ref->hf == _fi_invalid_handle)
446
std::strcpy(ptr, ref->_data.cFileName);
447
if(ref->_data.dwFileAttributes & _fi_dir)
450
#ifndef BOOST_NO_EXCEPTIONS
462
file_iterator::file_iterator(const file_iterator& other)
467
#ifndef BOOST_NO_EXCEPTIONS
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);
478
#ifndef BOOST_NO_EXCEPTIONS
490
file_iterator& file_iterator::operator=(const file_iterator& other)
493
std::strcpy(_root, other._root);
494
std::strcpy(_path, other._path);
495
ptr = _path + (other.ptr - other._path);
496
if(--(ref->count) == 0)
498
if(ref->hf != _fi_invalid_handle)
508
file_iterator::~file_iterator()
513
if(--(ref->count) == 0)
515
if(ref->hf != _fi_invalid_handle)
521
file_iterator file_iterator::operator++(int)
524
file_iterator temp(*this);
530
void file_iterator::next()
533
if(ref->hf != _fi_invalid_handle)
538
cont = FindNextFileA(ref->hf, &(ref->_data));
539
if(cont && ((ref->_data.dwFileAttributes & _fi_dir) == 0))
546
ref->hf = _fi_invalid_handle;
551
std::strcpy(ptr, ref->_data.cFileName);
557
directory_iterator::directory_iterator()
562
#ifndef BOOST_NO_EXCEPTIONS
565
_root = new char[MAX_PATH];
566
BOOST_REGEX_NOEH_ASSERT(_root)
567
_path = new char[MAX_PATH];
568
BOOST_REGEX_NOEH_ASSERT(_path)
572
ref = new file_iterator_ref();
573
BOOST_REGEX_NOEH_ASSERT(ref)
574
ref->hf = _fi_invalid_handle;
576
#ifndef BOOST_NO_EXCEPTIONS
588
directory_iterator::directory_iterator(const char* wild)
593
#ifndef BOOST_NO_EXCEPTIONS
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);
603
while((ptr > _root) && (*ptr != *_fi_sep) && (*ptr != *_fi_sep_alt))--ptr;
606
std::strcpy(_path, _root);
608
std::strcpy(_path, ".");
609
std::strcat(_path, _fi_sep);
610
ptr = _path + std::strlen(_path);
612
if((ptr == _root) && ( (*ptr== *_fi_sep) || (*ptr==*_fi_sep_alt) ) )
615
std::strcpy(_path, _root);
616
ptr = _path + std::strlen(_path);
621
std::strcpy(_path, _root);
623
std::strcpy(_path, ".");
624
std::strcat(_path, _fi_sep);
625
ptr = _path + std::strlen(_path);
628
ref = new file_iterator_ref();
629
BOOST_REGEX_NOEH_ASSERT(ref)
631
ref->hf = FindFirstFileA(wild, &(ref->_data));
632
if(ref->hf == _fi_invalid_handle)
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))
643
#ifndef BOOST_NO_EXCEPTIONS
655
directory_iterator::~directory_iterator()
660
if(--(ref->count) == 0)
662
if(ref->hf != _fi_invalid_handle)
668
directory_iterator::directory_iterator(const directory_iterator& other)
673
#ifndef BOOST_NO_EXCEPTIONS
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);
684
#ifndef BOOST_NO_EXCEPTIONS
696
directory_iterator& directory_iterator::operator=(const directory_iterator& other)
699
std::strcpy(_root, other._root);
700
std::strcpy(_path, other._path);
701
ptr = _path + (other.ptr - other._path);
702
if(--(ref->count) == 0)
704
if(ref->hf != _fi_invalid_handle)
713
directory_iterator directory_iterator::operator++(int)
716
directory_iterator temp(*this);
721
void directory_iterator::next()
724
if(ref->hf != _fi_invalid_handle)
729
cont = FindNextFileA(ref->hf, &(ref->_data));
730
if(cont && (ref->_data.dwFileAttributes & _fi_dir))
732
if(std::strcmp(ref->_data.cFileName, ".") && std::strcmp(ref->_data.cFileName, ".."))
740
ref->hf = _fi_invalid_handle;
745
std::strcpy(ptr, ref->_data.cFileName);
750
#ifdef BOOST_REGEX_FI_POSIX_DIR
757
_fi_priv_data(const char* p);
760
_fi_priv_data::_fi_priv_data(const char* p)
763
std::strcpy(root, p);
766
while((mask > root) && (*mask != *_fi_sep) && (*mask != *_fi_sep_alt)) --mask;
767
if(mask == root && ((*mask== *_fi_sep) || (*mask == *_fi_sep_alt)) )
770
std::strcpy(root+2, p+1);
773
else if(mask == root)
777
std::strcpy(root+2, p);
787
bool iswild(const char* mask, const char* name)
790
while(*mask && *name)
804
if(iswild(mask, name))
817
if(BOOST_REGEX_FI_TRANSLATE(*mask) != BOOST_REGEX_FI_TRANSLATE(*name))
829
unsigned _fi_attributes(const char* root, const char* name)
833
if( ( (root[0] == *_fi_sep) || (root[0] == *_fi_sep_alt) ) && (root[1] == '\0') )
834
std::sprintf(buf, "%s%s", root, name);
836
std::sprintf(buf, "%s%s%s", root, _fi_sep, name);
837
DIR* d = opendir(buf);
846
_fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindFileData)
849
_fi_find_handle dat = new _fi_priv_data(lpFileName);
851
DIR* h = opendir(dat->root);
855
if(_fi_FindNextFile(dat, lpFindFileData))
862
bool _fi_FindNextFile(_fi_find_handle dat, _fi_find_data* lpFindFileData)
869
} while(d && !iswild(dat->mask, d->d_name));
873
std::strcpy(lpFindFileData->cFileName, d->d_name);
874
lpFindFileData->dwFileAttributes = _fi_attributes(dat->root, d->d_name);
880
bool _fi_FindClose(_fi_find_handle dat)
890
} // namespace re_detail
893
#endif // BOOST_REGEX_NO_FILEITER