/*
 *
 * Copyright (c) 1998-2002
 * John Maddock
 *
 * Use, modification and distribution are subject to the 
 * Boost Software License, Version 1.0. (See accompanying file 
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 *
 */
 
 /*
  *   LOCATION:    see http://www.boost.org for most recent version.
  *   FILE:        fileiter.cpp
  *   VERSION:     see <boost/version.hpp>
  *   DESCRIPTION: Implements file io primitives + directory searching for class boost::RegEx.
  */


#define BOOST_REGEX_SOURCE

#include <climits>
#include <stdexcept>
#include <string>
#include <boost/throw_exception.hpp>
#include <boost/regex/v4/fileiter.hpp>
#include <boost/regex/v4/regex_workaround.hpp>
#include <boost/regex/pattern_except.hpp>

#include <cstdio>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
   using ::sprintf;
   using ::fseek;
   using ::fread;
   using ::ftell;
   using ::fopen;
   using ::fclose;
   using ::FILE;
   using ::strcpy;
   using ::strcpy;
   using ::strcat;
   using ::strcmp;
   using ::strlen;
}
#endif


#ifndef BOOST_REGEX_NO_FILEITER

#if defined(__CYGWIN__) || defined(__CYGWIN32__)
#include <sys/cygwin.h>
#endif

#ifdef BOOST_MSVC
#  pragma warning(disable: 4800)
#endif

namespace boost{
   namespace re_detail{
// start with the operating system specific stuff:

#if (defined(__BORLANDC__) || defined(BOOST_REGEX_FI_WIN32_DIR) || defined(BOOST_MSVC)) && !defined(BOOST_RE_NO_WIN32)

// platform is DOS or Windows
// directories are separated with '\\'
// and names are insensitive of case

BOOST_REGEX_DECL const char* _fi_sep = "\\";
const char* _fi_sep_alt = "/";
#define BOOST_REGEX_FI_TRANSLATE(c) std::tolower(c)

#else

// platform is not DOS or Windows
// directories are separated with '/'
// and names are sensitive of case

BOOST_REGEX_DECL const char* _fi_sep = "/";
const char* _fi_sep_alt = _fi_sep;
#define BOOST_REGEX_FI_TRANSLATE(c) c

#endif

#ifdef BOOST_REGEX_FI_WIN32_MAP

void mapfile::open(const char* file)
{
#if defined(BOOST_NO_ANSI_APIS)
   int filename_size = strlen(file);
   LPWSTR wide_file = (LPWSTR)_alloca( (filename_size + 1) * sizeof(WCHAR) );
   if(::MultiByteToWideChar(CP_ACP, 0,  file, filename_size,  wide_file, filename_size + 1) == 0)
      hfile = INVALID_HANDLE_VALUE;
   else
      hfile = CreateFileW(wide_file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
#elif defined(__CYGWIN__)||defined(__CYGWIN32__)
   char win32file[ MAX_PATH ];
   cygwin_conv_to_win32_path( file, win32file );
   hfile = CreateFileA(win32file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
#else
   hfile = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
#endif
   if(hfile != INVALID_HANDLE_VALUE)
   {
      hmap = CreateFileMapping(hfile, 0, PAGE_READONLY, 0, 0, 0);
      if((hmap == INVALID_HANDLE_VALUE) || (hmap == NULL))
      {
         CloseHandle(hfile);
         hmap = 0;
         hfile = 0;
         std::runtime_error err("Unable to create file mapping.");
         boost::re_detail::raise_runtime_error(err);
      }
      _first = static_cast<const char*>(MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0));
      if(_first == 0)
      {
         CloseHandle(hmap);
         CloseHandle(hfile);
         hmap = 0;
         hfile = 0;
         std::runtime_error err("Unable to create file mapping.");
      }
      _last = _first + GetFileSize(hfile, 0);
   }
   else
   {
      hfile = 0;
#ifndef BOOST_NO_EXCEPTIONS
      throw std::runtime_error("Unable to open file.");
#else
      BOOST_REGEX_NOEH_ASSERT(hfile != INVALID_HANDLE_VALUE);
#endif
   }
}

void mapfile::close()
{
   if(hfile != INVALID_HANDLE_VALUE)
   {
      UnmapViewOfFile((void*)_first);
      CloseHandle(hmap);
      CloseHandle(hfile);
      hmap = hfile = 0;
      _first = _last = 0;
   }
}

#elif !defined(BOOST_RE_NO_STL)

mapfile_iterator& mapfile_iterator::operator = (const mapfile_iterator& i)
{
   if(file && node)
      file->unlock(node);
   file = i.file;
   node = i.node;
   offset = i.offset;
   if(file)
      file->lock(node);
   return *this;
}

mapfile_iterator& mapfile_iterator::operator++ ()
{
   if((++offset == mapfile::buf_size) && file)
   {
      ++node;
      offset = 0;
      file->lock(node);
      file->unlock(node-1);
   }
   return *this;
}

mapfile_iterator mapfile_iterator::operator++ (int)
{
   mapfile_iterator temp(*this);
   if((++offset == mapfile::buf_size) && file)
   {
      ++node;
      offset = 0;
      file->lock(node);
      file->unlock(node-1);
   }
   return temp;
}

mapfile_iterator& mapfile_iterator::operator-- ()
{
   if((offset == 0) && file)
   {
      --node;
      offset = mapfile::buf_size - 1;
      file->lock(node);
      file->unlock(node + 1);
   }
   else
      --offset;
   return *this;
}

mapfile_iterator mapfile_iterator::operator-- (int)
{
   mapfile_iterator temp(*this);
   if((offset == 0) && file)
   {
      --node;
      offset = mapfile::buf_size - 1;
      file->lock(node);
      file->unlock(node + 1);
   }
   else
      --offset;
   return temp;
}

mapfile_iterator operator + (const mapfile_iterator& i, long off)
{
   mapfile_iterator temp(i);
   temp += off;
   return temp;
}

mapfile_iterator operator - (const mapfile_iterator& i, long off)
{
   mapfile_iterator temp(i);
   temp -= off;
   return temp;
}

mapfile::iterator mapfile::begin()const
{
   return mapfile_iterator(this, 0);
}

mapfile::iterator mapfile::end()const
{
   return mapfile_iterator(this, _size);
}

void mapfile::lock(pointer* node)const
{
   BOOST_ASSERT(node >= _first);
   BOOST_ASSERT(node <= _last);
   if(node < _last)
   {
      if(*node == 0)
      {
         if(condemed.empty())
         {
            *node = new char[sizeof(int) + buf_size];
            *(reinterpret_cast<int*>(*node)) = 1;
         }
         else
         {
            pointer* p = condemed.front();
            condemed.pop_front();
            *node = *p;
            *p = 0;
            *(reinterpret_cast<int*>(*node)) = 1;
         }
 
        std::size_t read_size = 0; 
        int read_pos = std::fseek(hfile, (node - _first) * buf_size, SEEK_SET); 

        if(0 == read_pos && node == _last - 1) 
           read_size = std::fread(*node + sizeof(int), _size % buf_size, 1, hfile); 
        else
           read_size = std::fread(*node + sizeof(int), buf_size, 1, hfile);
#ifndef BOOST_NO_EXCEPTIONS 
        if((read_size == 0) || (std::ferror(hfile)))
        { 
           throw std::runtime_error("Unable to read file."); 
        } 
#else 
        BOOST_REGEX_NOEH_ASSERT((0 == std::ferror(hfile)) && (read_size != 0)); 
#endif 
      }
      else
      {
         if(*reinterpret_cast<int*>(*node) == 0)
         {
            *reinterpret_cast<int*>(*node) = 1;
            condemed.remove(node);
         }
         else
            ++(*reinterpret_cast<int*>(*node));
      }
   }
}

void mapfile::unlock(pointer* node)const
{
   BOOST_ASSERT(node >= _first);
   BOOST_ASSERT(node <= _last);
   if(node < _last)
   {
      if(--(*reinterpret_cast<int*>(*node)) == 0)
      {
         condemed.push_back(node);
      }
   }
}

long int get_file_length(std::FILE* hfile)
{
   long int result;
   std::fseek(hfile, 0, SEEK_END);
   result = std::ftell(hfile);
   std::fseek(hfile, 0, SEEK_SET);
   return result;
}


void mapfile::open(const char* file)
{
   hfile = std::fopen(file, "rb");
#ifndef BOOST_NO_EXCEPTIONS
   try{
#endif
   if(hfile != 0)
   {
      _size = get_file_length(hfile);
      long cnodes = (_size + buf_size - 1) / buf_size;

      // check that number of nodes is not too high:
      if(cnodes > (long)((INT_MAX) / sizeof(pointer*)))
      {
         std::fclose(hfile);
         hfile = 0;
         _size = 0;
         return;
      }

      _first = new pointer[(int)cnodes];
      _last = _first + cnodes;
      std::memset(_first, 0, cnodes*sizeof(pointer));
   }
   else
   {
       std::runtime_error err("Unable to open file.");
   }
#ifndef BOOST_NO_EXCEPTIONS
   }catch(...)
   { close(); throw; }
#endif
}

void mapfile::close()
{
   if(hfile != 0)
   {
      pointer* p = _first;
      while(p != _last)
      {
         if(*p)
            delete[] *p;
         ++p;
      }
      delete[] _first;
      _size = 0;
      _first = _last = 0;
      std::fclose(hfile);
      hfile = 0;
      condemed.erase(condemed.begin(), condemed.end());
   }
}


#endif

inline _fi_find_handle find_first_file(const char* wild,  _fi_find_data& data)
{
#ifdef BOOST_NO_ANSI_APIS
   std::size_t wild_size = std::strlen(wild);
   LPWSTR wide_wild = (LPWSTR)_alloca( (wild_size + 1) * sizeof(WCHAR) );
   if (::MultiByteToWideChar(CP_ACP, 0,  wild, wild_size,  wide_wild, wild_size + 1) == 0)
      return _fi_invalid_handle;

   return FindFirstFileW(wide_wild, &data);
#else
   return FindFirstFileA(wild, &data);
#endif
}

inline bool find_next_file(_fi_find_handle hf,  _fi_find_data& data)
{
#ifdef BOOST_NO_ANSI_APIS
   return FindNextFileW(hf, &data);
#else
   return FindNextFileA(hf, &data);
#endif
}
   
inline void copy_find_file_result_with_overflow_check(const _fi_find_data& data,  char* path, size_t max_size)
{
#ifdef BOOST_NO_ANSI_APIS
   if (::WideCharToMultiByte(CP_ACP, 0,  data.cFileName, -1,  path, max_size,  NULL, NULL) == 0)
      re_detail::overflow_error_if_not_zero(1);
#else
   re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(path, max_size,  data.cFileName));
#endif
}

inline bool is_not_current_or_parent_path_string(const _fi_find_data& data)
{
#ifdef BOOST_NO_ANSI_APIS
   return (std::wcscmp(data.cFileName, L".") && std::wcscmp(data.cFileName, L".."));
#else
   return (std::strcmp(data.cFileName, ".") && std::strcmp(data.cFileName, ".."));
#endif
}


file_iterator::file_iterator()
{
   _root = _path = 0;
   ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
   try{
#endif
   _root = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_root)
   _path = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_path)
   ptr = _path;
   *_path = 0;
   *_root = 0;
   ref = new file_iterator_ref();
   BOOST_REGEX_NOEH_ASSERT(ref)
   ref->hf = _fi_invalid_handle;
   ref->count = 1;
#ifndef BOOST_NO_EXCEPTIONS
   }
   catch(...)
   {
      delete[] _root;
      delete[] _path;
      delete ref;
      throw;
   }
#endif
}

file_iterator::file_iterator(const char* wild)
{
   _root = _path = 0;
   ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
   try{
#endif
   _root = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_root)
   _path = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_path)
   re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, wild));
   ptr = _root;
   while(*ptr)++ptr;
   while((ptr > _root) && (*ptr != *_fi_sep) && (*ptr != *_fi_sep_alt))--ptr;
   if((ptr == _root) && ( (*ptr== *_fi_sep) || (*ptr==*_fi_sep_alt) ) )
   {
     _root[1]='\0';
     re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, _root));
   }
   else
   {
     *ptr = 0;
     re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, _root));
     if(*_path == 0)
       re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, "."));
     re_detail::overflow_error_if_not_zero(re_detail::strcat_s(_path, MAX_PATH, _fi_sep));
   }
   ptr = _path + std::strlen(_path);

   ref = new file_iterator_ref();
   BOOST_REGEX_NOEH_ASSERT(ref)
   ref->hf = find_first_file(wild,  ref->_data);
   ref->count = 1;

   if(ref->hf == _fi_invalid_handle)
   {
      *_path = 0;
      ptr = _path;
   }
   else
   {
      copy_find_file_result_with_overflow_check(ref->_data,  ptr, (MAX_PATH - (ptr - _path)));
      if(ref->_data.dwFileAttributes & _fi_dir)
         next();
   }
#ifndef BOOST_NO_EXCEPTIONS
   }
   catch(...)
   {
      delete[] _root;
      delete[] _path;
      delete ref;
      throw;
   }
#endif
}

file_iterator::file_iterator(const file_iterator& other)
{
   _root = _path = 0;
   ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
   try{
#endif
   _root = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_root)
   _path = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_path)
   re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, other._root));
   re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, other._path));
   ptr = _path + (other.ptr - other._path);
   ref = other.ref;
#ifndef BOOST_NO_EXCEPTIONS
   }
   catch(...)
   {
      delete[] _root;
      delete[] _path;
      throw;
   }
#endif
   ++(ref->count);
}

file_iterator& file_iterator::operator=(const file_iterator& other)
{
   re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, other._root));
   re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, other._path));
   ptr = _path + (other.ptr - other._path);
   if(--(ref->count) == 0)
   {
      if(ref->hf != _fi_invalid_handle)
         FindClose(ref->hf);
      delete ref;
   }
   ref = other.ref;
   ++(ref->count);
   return *this;
}


file_iterator::~file_iterator()
{
   delete[] _root;
   delete[] _path;
   if(--(ref->count) == 0)
   {
      if(ref->hf != _fi_invalid_handle)
         FindClose(ref->hf);
      delete ref;
   }
}

file_iterator file_iterator::operator++(int)
{
   file_iterator temp(*this);
   next();
   return temp;
}


void file_iterator::next()
{
   if(ref->hf != _fi_invalid_handle)
   {
      bool cont = true;
      while(cont)
      {
         cont = find_next_file(ref->hf, ref->_data);
         if(cont && ((ref->_data.dwFileAttributes & _fi_dir) == 0))
            break;
      }
      if(!cont)
      {
         // end of sequence
         FindClose(ref->hf);
         ref->hf = _fi_invalid_handle;
         *_path = 0;
         ptr = _path;
      }
      else
         copy_find_file_result_with_overflow_check(ref->_data,  ptr, MAX_PATH - (ptr - _path));
   }
}



directory_iterator::directory_iterator()
{
   _root = _path = 0;
   ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
   try{
#endif
   _root = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_root)
   _path = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_path)
   ptr = _path;
   *_path = 0;
   *_root = 0;
   ref = new file_iterator_ref();
   BOOST_REGEX_NOEH_ASSERT(ref)
   ref->hf = _fi_invalid_handle;
   ref->count = 1;
#ifndef BOOST_NO_EXCEPTIONS
   }
   catch(...)
   {
      delete[] _root;
      delete[] _path;
      delete ref;
      throw;
   }
#endif
}

directory_iterator::directory_iterator(const char* wild)
{
   _root = _path = 0;
   ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
   try{
#endif
   _root = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_root)
   _path = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_path)
   re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, wild));
   ptr = _root;
   while(*ptr)++ptr;
   while((ptr > _root) && (*ptr != *_fi_sep) && (*ptr != *_fi_sep_alt))--ptr;

   if((ptr == _root) && ( (*ptr== *_fi_sep) || (*ptr==*_fi_sep_alt) ) )
   {
     _root[1]='\0';
     re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, _root));
   }
   else
   {
     *ptr = 0;
     re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, _root));
     if(*_path == 0)
       re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, "."));
     re_detail::overflow_error_if_not_zero(re_detail::strcat_s(_path, MAX_PATH, _fi_sep));
   }
   ptr = _path + std::strlen(_path);

   ref = new file_iterator_ref();
   BOOST_REGEX_NOEH_ASSERT(ref)
   ref->count = 1;
   ref->hf = find_first_file(wild,  ref->_data);
   if(ref->hf == _fi_invalid_handle)
   {
      *_path = 0;
      ptr = _path;
   }
   else
   {
      copy_find_file_result_with_overflow_check(ref->_data,  ptr, MAX_PATH - (ptr - _path));
      if(((ref->_data.dwFileAttributes & _fi_dir) == 0) || (std::strcmp(ptr, ".") == 0) || (std::strcmp(ptr, "..") == 0))
         next();
   }
#ifndef BOOST_NO_EXCEPTIONS
   }
   catch(...)
   {
      delete[] _root;
      delete[] _path;
      delete ref;
      throw;
   }
#endif
}

directory_iterator::~directory_iterator()
{
   delete[] _root;
   delete[] _path;
   if(--(ref->count) == 0)
   {
      if(ref->hf != _fi_invalid_handle)
         FindClose(ref->hf);
      delete ref;
   }
}

directory_iterator::directory_iterator(const directory_iterator& other)
{
   _root = _path = 0;
   ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
   try{
#endif
   _root = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_root)
   _path = new char[MAX_PATH];
   BOOST_REGEX_NOEH_ASSERT(_path)
   re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, other._root));
   re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, other._path));
   ptr = _path + (other.ptr - other._path);
   ref = other.ref;
#ifndef BOOST_NO_EXCEPTIONS
   }
   catch(...)
   {
      delete[] _root;
      delete[] _path;
      throw;
   }
#endif
   ++(ref->count);
}

directory_iterator& directory_iterator::operator=(const directory_iterator& other)
{
   re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, other._root));
   re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, other._path));
   ptr = _path + (other.ptr - other._path);
   if(--(ref->count) == 0)
   {
      if(ref->hf != _fi_invalid_handle)
         FindClose(ref->hf);
      delete ref;
   }
   ref = other.ref;
   ++(ref->count);
   return *this;
}

directory_iterator directory_iterator::operator++(int)
{
   directory_iterator temp(*this);
   next();
   return temp;
}

void directory_iterator::next()
{
   if(ref->hf != _fi_invalid_handle)
   {
      bool cont = true;
      while(cont)
      {
         cont = find_next_file(ref->hf, ref->_data);
         if(cont && (ref->_data.dwFileAttributes & _fi_dir))
         {
            if(is_not_current_or_parent_path_string(ref->_data))
               break;
         }
      }
      if(!cont)
      {
         // end of sequence
         FindClose(ref->hf);
         ref->hf = _fi_invalid_handle;
         *_path = 0;
         ptr = _path;
      }
      else
         copy_find_file_result_with_overflow_check(ref->_data,  ptr, MAX_PATH - (ptr - _path));
   }
}


#ifdef BOOST_REGEX_FI_POSIX_DIR

struct _fi_priv_data
{
   char root[MAX_PATH];
   char* mask;
   DIR* d;
   _fi_priv_data(const char* p);
};

_fi_priv_data::_fi_priv_data(const char* p)
{
   std::strcpy(root, p);
   mask = root;
   while(*mask) ++mask;
   while((mask > root) && (*mask != *_fi_sep) && (*mask != *_fi_sep_alt)) --mask;
   if(mask == root && ((*mask== *_fi_sep) || (*mask == *_fi_sep_alt)) )
   {
      root[1] = '\0';
      std::strcpy(root+2, p+1);
      mask = root+2;
   }
   else if(mask == root)
   {
      root[0] = '.';
      root[1] = '\0';
      std::strcpy(root+2, p);
      mask = root+2;
   }
   else
   {
      *mask = 0;
      ++mask;
   }
}

bool iswild(const char* mask, const char* name)
{
   while(*mask && *name)
   {
      switch(*mask)
      {
      case '?':
         ++name;
         ++mask;
         continue;
      case '*':
         ++mask;
         if(*mask == 0)
            return true;
         while(*name)
         {
            if(iswild(mask, name))
               return true;
            ++name;
         }
         return false;
      case '.':
         if(0 == *name)
         {
            ++mask;
            continue;
         }
         // fall through:
      default:
         if(BOOST_REGEX_FI_TRANSLATE(*mask) != BOOST_REGEX_FI_TRANSLATE(*name))
            return false;
         ++mask;
         ++name;
         continue;
      }
   }
   if(*mask != *name)
      return false;
   return true;
}

unsigned _fi_attributes(const char* root, const char* name)
{
   char buf[MAX_PATH];
   if( ( (root[0] == *_fi_sep) || (root[0] == *_fi_sep_alt) ) && (root[1] == '\0') )
      (std::sprintf)(buf, "%s%s", root, name);
   else
      (std::sprintf)(buf, "%s%s%s", root, _fi_sep, name);
   DIR* d = opendir(buf);
   if(d)
   {
      closedir(d);
      return _fi_dir;
   }
   return 0;
}

_fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindFileData)
{
   _fi_find_handle dat = new _fi_priv_data(lpFileName);

   DIR* h = opendir(dat->root);
   dat->d = h;
   if(h != 0)
   {
      if(_fi_FindNextFile(dat, lpFindFileData))
         return dat;
   }
   delete dat;
   return 0;
}

bool _fi_FindNextFile(_fi_find_handle dat, _fi_find_data* lpFindFileData)
{
   dirent* d;
   do
   {
      d = readdir(dat->d);
   } while(d && !iswild(dat->mask, d->d_name));

   if(d)
   {
      std::strcpy(lpFindFileData->cFileName, d->d_name);
      lpFindFileData->dwFileAttributes = _fi_attributes(dat->root, d->d_name);
      return true;
   }
   return false;
}

bool _fi_FindClose(_fi_find_handle dat)
{
   closedir(dat->d);
   delete dat;
   return true;
}

#endif

} // namespace re_detail
} // namspace boost

#endif    // BOOST_REGEX_NO_FILEITER












