Directory.cxx 5.57 KB
Newer Older
1
2
3
/*============================================================================
  KWSys - Kitware System Library
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4

5
6
  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.
7

8
9
10
11
  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
12
13
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Directory.hxx)
14

15
#include KWSYS_HEADER(Configure.hxx)
Brad King's avatar
Brad King committed
16

17
18
#include KWSYS_HEADER(Encoding.hxx)

19
20
#include KWSYS_HEADER(stl/string)
#include KWSYS_HEADER(stl/vector)
21

22
23
24
25
26
// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "Directory.hxx.in"
# include "Configure.hxx.in"
27
# include "Encoding.hxx.in"
28
29
# include "kwsys_stl.hxx.in"
# include "kwsys_stl_string.hxx.in"
30
# include "kwsys_stl_vector.hxx.in"
31
32
#endif

33
34
35
36
37
38
39
40
namespace KWSYS_NAMESPACE
{

//----------------------------------------------------------------------------
class DirectoryInternals
{
public:
  // Array of Files
41
  kwsys_stl::vector<kwsys_stl::string> Files;
Mathieu Malaterre's avatar
Mathieu Malaterre committed
42

43
  // Path to Open'ed directory
44
  kwsys_stl::string Path;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
};

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

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

//----------------------------------------------------------------------------
60
unsigned long Directory::GetNumberOfFiles() const
61
{
Brad King's avatar
Brad King committed
62
  return static_cast<unsigned long>(this->Internal->Files.size());
63
64
65
}

//----------------------------------------------------------------------------
66
const char* Directory::GetFile(unsigned long dindex) const
67
68
69
70
71
72
73
74
{
  if ( dindex >= this->Internal->Files.size() )
    {
    return 0;
    }
  return this->Internal->Files[dindex].c_str();
}

75
76
77
78
79
80
//----------------------------------------------------------------------------
const char* Directory::GetPath() const
{
  return this->Internal->Path.c_str();
}

81
82
83
//----------------------------------------------------------------------------
void Directory::Clear()
{
84
  this->Internal->Path.resize(0);
85
86
87
  this->Internal->Files.clear();
}

88
89
} // namespace KWSYS_NAMESPACE

90
91
// First microsoft compilers

92
#if defined(_MSC_VER) || defined(__WATCOMC__)
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <windows.h>
#include <io.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

namespace KWSYS_NAMESPACE
{

bool Directory::Load(const char* name)
{
108
  this->Clear();
109
110
111
112
113
#if _MSC_VER < 1300
  long srchHandle;
#else
  intptr_t srchHandle;
#endif
114
115
  char* buf;
  size_t n = strlen(name);
116
  if ( name[n - 1] == '/' || name[n - 1] == '\\' )
117
118
119
    {
    buf = new char[n + 1 + 1];
    sprintf(buf, "%s*", name);
Mathieu Malaterre's avatar
Mathieu Malaterre committed
120
    }
121
122
  else
    {
123
124
    // Make sure the slashes in the wildcard suffix are consistent with the
    // rest of the path
125
    buf = new char[n + 2 + 1];
126
127
128
129
130
131
132
133
    if ( strchr(name, '\\') )
      {
      sprintf(buf, "%s\\*", name);
      }
    else
      {
      sprintf(buf, "%s/*", name);
      }
134
    }
135
  struct _wfinddata_t data;      // data of current file
Mathieu Malaterre's avatar
Mathieu Malaterre committed
136

137
  // Now put them into the file array
138
  srchHandle = _wfindfirst((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
139
  delete [] buf;
Mathieu Malaterre's avatar
Mathieu Malaterre committed
140

141
142
143
144
  if ( srchHandle == -1 )
    {
    return 0;
    }
Mathieu Malaterre's avatar
Mathieu Malaterre committed
145

146
  // Loop through names
Mathieu Malaterre's avatar
Mathieu Malaterre committed
147
  do
148
    {
149
    this->Internal->Files.push_back(Encoding::ToNarrow(data.name));
Mathieu Malaterre's avatar
Mathieu Malaterre committed
150
    }
151
  while ( _wfindnext(srchHandle, &data) != -1 );
152
  this->Internal->Path = name;
153
154
155
  return _findclose(srchHandle) != -1;
}

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
{
#if _MSC_VER < 1300
  long srchHandle;
#else
  intptr_t srchHandle;
#endif
  char* buf;
  size_t n = strlen(name);
  if ( name[n - 1] == '/' )
    {
    buf = new char[n + 1 + 1];
    sprintf(buf, "%s*", name);
    }
  else
    {
    buf = new char[n + 2 + 1];
    sprintf(buf, "%s/*", name);
    }
175
  struct _wfinddata_t data;      // data of current file
176
177

  // Now put them into the file array
178
  srchHandle = _wfindfirst((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
179
180
181
182
183
184
185
186
187
188
189
190
191
  delete [] buf;

  if ( srchHandle == -1 )
    {
    return 0;
    }

  // Loop through names
  unsigned long count = 0;
  do
    {
    count++;
    }
192
  while ( _wfindnext(srchHandle, &data) != -1 );
193
194
195
196
  _findclose(srchHandle);
  return count;
}

197
198
199
200
201
202
203
204
} // namespace KWSYS_NAMESPACE

#else

// Now the POSIX style directory access

#include <sys/types.h>
#include <dirent.h>
205

Alexander Neundorf's avatar
   
Alexander Neundorf committed
206
207
208
209
210
211
212
213
214
/* There is a problem with the Portland compiler, large file
support and glibc/Linux system headers: 
http://www.pgroup.com/userforum/viewtopic.php?
p=1992&sid=f16167f51964f1a68fe5041b8eb213b6
*/
#if defined(__PGI) && defined(__USE_FILE_OFFSET64)
# define dirent dirent64
#endif

215
216
217
218
219
namespace KWSYS_NAMESPACE
{

bool Directory::Load(const char* name)
{
220
  this->Clear();
221
222
223
224
225
   
  if (!name)
    {
    return 0;
    }
226
227
228
229
230
231
232
233
234
  DIR* dir = opendir(name);

  if (!dir)
    {
    return 0;
    }

  for (dirent* d = readdir(dir); d; d = readdir(dir) )
    {
235
    this->Internal->Files.push_back(d->d_name);
236
    }
237
  this->Internal->Path = name;
238
239
240
  closedir(dir);
  return 1;
}
241

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
{
  DIR* dir = opendir(name);

  if (!dir)
    {
    return 0;
    }

  unsigned long count = 0;
  for (dirent* d = readdir(dir); d; d = readdir(dir) )
    {
    count++;
    }
  closedir(dir);
  return count;
}

260
261
262
} // namespace KWSYS_NAMESPACE

#endif