Directory.cxx 5.29 KB
Newer Older
Kitware Robot's avatar
Kitware Robot committed
1 2
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
Kitware Robot's avatar
Kitware Robot committed
3 4 5 6 7
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Directory.hxx)

#include KWSYS_HEADER(Configure.hxx)

Kitware Robot's avatar
Kitware Robot committed
8 9
#include KWSYS_HEADER(Encoding.hxx)

Kitware Robot's avatar
Kitware Robot committed
10 11 12
// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
Kitware Robot's avatar
Kitware Robot committed
13 14 15
#  include "Configure.hxx.in"
#  include "Directory.hxx.in"
#  include "Encoding.hxx.in"
Kitware Robot's avatar
Kitware Robot committed
16 17
#endif

Kitware Robot's avatar
Kitware Robot committed
18 19 20
#include <string>
#include <vector>

Kitware Robot's avatar
Kitware Robot committed
21
namespace KWSYS_NAMESPACE {
Kitware Robot's avatar
Kitware Robot committed
22 23 24 25 26

class DirectoryInternals
{
public:
  // Array of Files
Kitware Robot's avatar
Kitware Robot committed
27
  std::vector<std::string> Files;
Kitware Robot's avatar
Kitware Robot committed
28 29

  // Path to Open'ed directory
Kitware Robot's avatar
Kitware Robot committed
30
  std::string Path;
Kitware Robot's avatar
Kitware Robot committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
};

Directory::Directory()
{
  this->Internal = new DirectoryInternals;
}

Directory::~Directory()
{
  delete this->Internal;
}

unsigned long Directory::GetNumberOfFiles() const
{
  return static_cast<unsigned long>(this->Internal->Files.size());
}

const char* Directory::GetFile(unsigned long dindex) const
{
Kitware Robot's avatar
Kitware Robot committed
50
  if (dindex >= this->Internal->Files.size()) {
Kitware Robot's avatar
Kitware Robot committed
51
    return KWSYS_NULLPTR;
Kitware Robot's avatar
Kitware Robot committed
52
  }
Kitware Robot's avatar
Kitware Robot committed
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
  return this->Internal->Files[dindex].c_str();
}

const char* Directory::GetPath() const
{
  return this->Internal->Path.c_str();
}

void Directory::Clear()
{
  this->Internal->Path.resize(0);
  this->Internal->Files.clear();
}

} // namespace KWSYS_NAMESPACE

Kitware Robot's avatar
Kitware Robot committed
69
// First Windows platforms
Kitware Robot's avatar
Kitware Robot committed
70

Kitware Robot's avatar
Kitware Robot committed
71
#if defined(_WIN32) && !defined(__CYGWIN__)
Kitware Robot's avatar
Kitware Robot committed
72
#  include <windows.h>
Kitware Robot's avatar
Kitware Robot committed
73

Kitware Robot's avatar
Kitware Robot committed
74 75 76 77 78 79 80 81
#  include <ctype.h>
#  include <fcntl.h>
#  include <io.h>
#  include <stdio.h>
#  include <stdlib.h>
#  include <string.h>
#  include <sys/stat.h>
#  include <sys/types.h>
Kitware Robot's avatar
Kitware Robot committed
82

Kitware Robot's avatar
Kitware Robot committed
83
// Wide function names can vary depending on compiler:
Kitware Robot's avatar
Kitware Robot committed
84 85 86 87 88 89 90
#  ifdef __BORLANDC__
#    define _wfindfirst_func __wfindfirst
#    define _wfindnext_func __wfindnext
#  else
#    define _wfindfirst_func _wfindfirst
#    define _wfindnext_func _wfindnext
#  endif
Kitware Robot's avatar
Kitware Robot committed
91

Kitware Robot's avatar
Kitware Robot committed
92
namespace KWSYS_NAMESPACE {
Kitware Robot's avatar
Kitware Robot committed
93

Kitware Robot's avatar
Kitware Robot committed
94
bool Directory::Load(const std::string& name)
Kitware Robot's avatar
Kitware Robot committed
95 96
{
  this->Clear();
Kitware Robot's avatar
Kitware Robot committed
97
#  if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__)
Kitware Robot's avatar
Kitware Robot committed
98
  // Older Visual C++ and Embarcadero compilers.
Kitware Robot's avatar
Kitware Robot committed
99
  long srchHandle;
Kitware Robot's avatar
Kitware Robot committed
100
#  else // Newer Visual C++
Kitware Robot's avatar
Kitware Robot committed
101
  intptr_t srchHandle;
Kitware Robot's avatar
Kitware Robot committed
102
#  endif
Kitware Robot's avatar
Kitware Robot committed
103
  char* buf;
Kitware Robot's avatar
Kitware Robot committed
104
  size_t n = name.size();
Kitware Robot's avatar
Kitware Robot committed
105
  if (name.back() == '/' || name.back() == '\\') {
Kitware Robot's avatar
Kitware Robot committed
106
    buf = new char[n + 1 + 1];
Kitware Robot's avatar
Kitware Robot committed
107
    sprintf(buf, "%s*", name.c_str());
Kitware Robot's avatar
Kitware Robot committed
108
  } else {
Kitware Robot's avatar
Kitware Robot committed
109 110
    // Make sure the slashes in the wildcard suffix are consistent with the
    // rest of the path
Kitware Robot's avatar
Kitware Robot committed
111
    buf = new char[n + 2 + 1];
Kitware Robot's avatar
Kitware Robot committed
112
    if (name.find('\\') != std::string::npos) {
Kitware Robot's avatar
Kitware Robot committed
113
      sprintf(buf, "%s\\*", name.c_str());
Kitware Robot's avatar
Kitware Robot committed
114
    } else {
Kitware Robot's avatar
Kitware Robot committed
115
      sprintf(buf, "%s/*", name.c_str());
Kitware Robot's avatar
Kitware Robot committed
116
    }
Kitware Robot's avatar
Kitware Robot committed
117 118
  }
  struct _wfinddata_t data; // data of current file
Kitware Robot's avatar
Kitware Robot committed
119 120

  // Now put them into the file array
Kitware Robot's avatar
Kitware Robot committed
121 122
  srchHandle = _wfindfirst_func(
    (wchar_t*)Encoding::ToWindowsExtendedPath(buf).c_str(), &data);
Kitware Robot's avatar
Kitware Robot committed
123
  delete[] buf;
Kitware Robot's avatar
Kitware Robot committed
124

Kitware Robot's avatar
Kitware Robot committed
125
  if (srchHandle == -1) {
Kitware Robot's avatar
Kitware Robot committed
126
    return 0;
Kitware Robot's avatar
Kitware Robot committed
127
  }
Kitware Robot's avatar
Kitware Robot committed
128 129

  // Loop through names
Kitware Robot's avatar
Kitware Robot committed
130
  do {
Kitware Robot's avatar
Kitware Robot committed
131
    this->Internal->Files.push_back(Encoding::ToNarrow(data.name));
Kitware Robot's avatar
Kitware Robot committed
132
  } while (_wfindnext_func(srchHandle, &data) != -1);
Kitware Robot's avatar
Kitware Robot committed
133 134 135 136
  this->Internal->Path = name;
  return _findclose(srchHandle) != -1;
}

Kitware Robot's avatar
Kitware Robot committed
137
unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
Kitware Robot's avatar
Kitware Robot committed
138
{
Kitware Robot's avatar
Kitware Robot committed
139
#  if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__)
Kitware Robot's avatar
Kitware Robot committed
140
  // Older Visual C++ and Embarcadero compilers.
Kitware Robot's avatar
Kitware Robot committed
141
  long srchHandle;
Kitware Robot's avatar
Kitware Robot committed
142
#  else // Newer Visual C++
Kitware Robot's avatar
Kitware Robot committed
143
  intptr_t srchHandle;
Kitware Robot's avatar
Kitware Robot committed
144
#  endif
Kitware Robot's avatar
Kitware Robot committed
145
  char* buf;
Kitware Robot's avatar
Kitware Robot committed
146
  size_t n = name.size();
Kitware Robot's avatar
Kitware Robot committed
147
  if (name.back() == '/') {
Kitware Robot's avatar
Kitware Robot committed
148
    buf = new char[n + 1 + 1];
Kitware Robot's avatar
Kitware Robot committed
149
    sprintf(buf, "%s*", name.c_str());
Kitware Robot's avatar
Kitware Robot committed
150
  } else {
Kitware Robot's avatar
Kitware Robot committed
151
    buf = new char[n + 2 + 1];
Kitware Robot's avatar
Kitware Robot committed
152
    sprintf(buf, "%s/*", name.c_str());
Kitware Robot's avatar
Kitware Robot committed
153 154
  }
  struct _wfinddata_t data; // data of current file
Kitware Robot's avatar
Kitware Robot committed
155 156

  // Now put them into the file array
Kitware Robot's avatar
Kitware Robot committed
157 158 159
  srchHandle =
    _wfindfirst_func((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
  delete[] buf;
Kitware Robot's avatar
Kitware Robot committed
160

Kitware Robot's avatar
Kitware Robot committed
161
  if (srchHandle == -1) {
Kitware Robot's avatar
Kitware Robot committed
162
    return 0;
Kitware Robot's avatar
Kitware Robot committed
163
  }
Kitware Robot's avatar
Kitware Robot committed
164 165 166

  // Loop through names
  unsigned long count = 0;
Kitware Robot's avatar
Kitware Robot committed
167
  do {
Kitware Robot's avatar
Kitware Robot committed
168
    count++;
Kitware Robot's avatar
Kitware Robot committed
169
  } while (_wfindnext_func(srchHandle, &data) != -1);
Kitware Robot's avatar
Kitware Robot committed
170 171 172 173 174 175 176 177 178 179
  _findclose(srchHandle);
  return count;
}

} // namespace KWSYS_NAMESPACE

#else

// Now the POSIX style directory access

Kitware Robot's avatar
Kitware Robot committed
180
#  include <sys/types.h>
Kitware Robot's avatar
Kitware Robot committed
181

Kitware Robot's avatar
Kitware Robot committed
182
#  include <dirent.h>
Kitware Robot's avatar
Kitware Robot committed
183

Kitware Robot's avatar
Kitware Robot committed
184 185 186 187
// PGI with glibc has trouble with dirent and large file support:
//  http://www.pgroup.com/userforum/viewtopic.php?
//  p=1992&sid=f16167f51964f1a68fe5041b8eb213b6
// Work around the problem by mapping dirent the same way as readdir.
Kitware Robot's avatar
Kitware Robot committed
188 189 190 191 192 193 194 195 196
#  if defined(__PGI) && defined(__GLIBC__)
#    define kwsys_dirent_readdir dirent
#    define kwsys_dirent_readdir64 dirent64
#    define kwsys_dirent kwsys_dirent_lookup(readdir)
#    define kwsys_dirent_lookup(x) kwsys_dirent_lookup_delay(x)
#    define kwsys_dirent_lookup_delay(x) kwsys_dirent_##x
#  else
#    define kwsys_dirent dirent
#  endif
Kitware Robot's avatar
Kitware Robot committed
197

Kitware Robot's avatar
Kitware Robot committed
198
namespace KWSYS_NAMESPACE {
Kitware Robot's avatar
Kitware Robot committed
199

Kitware Robot's avatar
Kitware Robot committed
200
bool Directory::Load(const std::string& name)
Kitware Robot's avatar
Kitware Robot committed
201 202
{
  this->Clear();
Kitware Robot's avatar
Kitware Robot committed
203

Kitware Robot's avatar
Kitware Robot committed
204
  DIR* dir = opendir(name.c_str());
Kitware Robot's avatar
Kitware Robot committed
205

Kitware Robot's avatar
Kitware Robot committed
206
  if (!dir) {
Kitware Robot's avatar
Kitware Robot committed
207
    return 0;
Kitware Robot's avatar
Kitware Robot committed
208
  }
Kitware Robot's avatar
Kitware Robot committed
209

Kitware Robot's avatar
Kitware Robot committed
210
  for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) {
Kitware Robot's avatar
Kitware Robot committed
211
    this->Internal->Files.push_back(d->d_name);
Kitware Robot's avatar
Kitware Robot committed
212
  }
Kitware Robot's avatar
Kitware Robot committed
213 214 215 216 217
  this->Internal->Path = name;
  closedir(dir);
  return 1;
}

Kitware Robot's avatar
Kitware Robot committed
218
unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
Kitware Robot's avatar
Kitware Robot committed
219
{
Kitware Robot's avatar
Kitware Robot committed
220
  DIR* dir = opendir(name.c_str());
Kitware Robot's avatar
Kitware Robot committed
221

Kitware Robot's avatar
Kitware Robot committed
222
  if (!dir) {
Kitware Robot's avatar
Kitware Robot committed
223
    return 0;
Kitware Robot's avatar
Kitware Robot committed
224
  }
Kitware Robot's avatar
Kitware Robot committed
225

Kitware Robot's avatar
Kitware Robot committed
226
  unsigned long count = 0;
Kitware Robot's avatar
Kitware Robot committed
227
  for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) {
Kitware Robot's avatar
Kitware Robot committed
228
    count++;
Kitware Robot's avatar
Kitware Robot committed
229
  }
Kitware Robot's avatar
Kitware Robot committed
230 231 232 233 234 235 236
  closedir(dir);
  return count;
}

} // namespace KWSYS_NAMESPACE

#endif