~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to boost/libs/regex/src/fileiter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/v3/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
 
 
903