Merge lp:~zorba-coders/zorba/bug-986580 into lp:zorba
- bug-986580
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Rodolfo Ochoa | ||||
Approved revision: | 10794 | ||||
Merged at revision: | 10801 | ||||
Proposed branch: | lp:~zorba-coders/zorba/bug-986580 | ||||
Merge into: | lp:zorba | ||||
Diff against target: |
1326 lines (+298/-764) 16 files modified
CMakeLists.txt (+7/-0) NOTICE.txt (+0/-18) NOTICE.xml (+0/-16) src/api/fileimpl.cpp (+6/-17) src/api/fileimpl.h (+3/-4) src/unit_tests/CMakeLists.txt (+1/-0) src/unit_tests/test_fs_iterator.cpp (+54/-0) src/unit_tests/unit_test_list.h (+1/-0) src/unit_tests/unit_tests.cpp (+1/-0) src/util/CMakeLists.txt (+0/-1) src/util/dir.cpp (+0/-175) src/util/dir.h (+0/-100) src/util/file.cpp (+3/-1) src/util/fs_util.cpp (+129/-31) src/util/fs_util.h (+93/-29) src/util/win32/dirent.h (+0/-372) |
||||
To merge this branch: | bzr merge lp:~zorba-coders/zorba/bug-986580 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Rodolfo Ochoa | Approve | ||
Cezar Andrei | Approve | ||
Review via email: mp+103552@code.launchpad.net |
This proposal supersedes a proposal from 2012-04-25.
Commit message
Better implementation of listing files in a directory.
Description of the change
Better implementation of listing files in a directory.
Rodolfo Ochoa (rodolfo-ochoa) : Posted in a previous version of this proposal | # |
Cezar Andrei (cezar-andrei) wrote : Posted in a previous version of this proposal | # |
Cezar Andrei (cezar-andrei) : Posted in a previous version of this proposal | # |
Rodolfo Ochoa (rodolfo-ochoa) : Posted in a previous version of this proposal | # |
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
The attempt to merge lp:~zorba-coders/zorba/bug-986580 into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job bug-986580-2012-04-
final status was:
No tests were run - build or configure step must have failed.
Not commiting changes.
Error in read script: /home/ceej/
Paul J. Lucas (paul-lucas) wrote : | # |
I didn't realize that the util-jvm module used file::lsdir(), so I put that function back. However, I think that API ought to change as well, but that can be done separately.
Cezar Andrei (cezar-andrei) : | # |
Rodolfo Ochoa (rodolfo-ochoa) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job bug-986580-2012-04-
All tests succeeded!
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2012-04-24 12:39:38 +0000 |
3 | +++ CMakeLists.txt 2012-04-25 19:52:28 +0000 |
4 | @@ -309,6 +309,13 @@ |
5 | MESSAGE (STATUS "") |
6 | |
7 | # |
8 | +# shlwapi |
9 | +# |
10 | +IF(WIN32) |
11 | + SET(requiredlibs ${requiredlibs} "shlwapi") |
12 | +ENDIF(WIN32) |
13 | + |
14 | +# |
15 | # SWIG |
16 | # |
17 | IF (NOT ZORBA_SUPPRESS_SWIG) |
18 | |
19 | === modified file 'NOTICE.txt' |
20 | --- NOTICE.txt 2012-04-18 15:34:39 +0000 |
21 | +++ NOTICE.txt 2012-04-25 19:52:28 +0000 |
22 | @@ -459,24 +459,6 @@ |
23 | suitability of this software for any purpose. It is provided "as is" |
24 | without express or implied warranty. |
25 | |
26 | ----------------------------------------------------- |
27 | - |
28 | -src/util/win32/dirent.h |
29 | - |
30 | -Copyright: 2006 Toni Ronkko |
31 | - |
32 | - |
33 | - Permission is hereby granted, free of charge, to any person obtaining |
34 | - a copy of this software and associated documentation files (the |
35 | - ``Software''), to deal in the Software without restriction, including |
36 | - without limitation the rights to use, copy, modify, merge, publish, |
37 | - distribute, sublicense, and/or sell copies of the Software, and to |
38 | - permit persons to whom the Software is furnished to do so, subject to |
39 | - the following conditions: |
40 | - |
41 | - The above copyright notice and this permission notice shall be included |
42 | - in all copies or substantial portions of the Software. |
43 | - |
44 | |
45 | External libraries used by this project: |
46 | ---------------------------------------------------- |
47 | |
48 | === modified file 'NOTICE.xml' |
49 | --- NOTICE.xml 2012-04-24 12:39:38 +0000 |
50 | +++ NOTICE.xml 2012-04-25 19:52:28 +0000 |
51 | @@ -423,22 +423,6 @@ |
52 | without express or implied warranty. |
53 | </foreign-notice> |
54 | </foreign-files> |
55 | - <foreign-files> |
56 | - <file>src/util/win32/dirent.h</file> |
57 | - <copyright>2006 Toni Ronkko</copyright> |
58 | - <foreign-notice> |
59 | - Permission is hereby granted, free of charge, to any person obtaining |
60 | - a copy of this software and associated documentation files (the |
61 | - ``Software''), to deal in the Software without restriction, including |
62 | - without limitation the rights to use, copy, modify, merge, publish, |
63 | - distribute, sublicense, and/or sell copies of the Software, and to |
64 | - permit persons to whom the Software is furnished to do so, subject to |
65 | - the following conditions: |
66 | - |
67 | - The above copyright notice and this permission notice shall be included |
68 | - in all copies or substantial portions of the Software. |
69 | - </foreign-notice> |
70 | - </foreign-files> |
71 | |
72 | <external-lib mandatory="true"> |
73 | <name>LIBXML2</name> |
74 | |
75 | === modified file 'src/api/fileimpl.cpp' |
76 | --- src/api/fileimpl.cpp 2012-04-24 12:39:38 +0000 |
77 | +++ src/api/fileimpl.cpp 2012-04-25 19:52:28 +0000 |
78 | @@ -29,44 +29,33 @@ |
79 | #ifdef WIN32 |
80 | #include <util/ascii_util.h> |
81 | #endif |
82 | -#include <util/dir.h> |
83 | |
84 | #include "util/uri_util.h" |
85 | #include "zorbaimpl.h" |
86 | |
87 | namespace zorba { |
88 | |
89 | -DirectoryIteratorImpl::DirectoryIteratorImpl(std::string const& aPath) |
90 | -{ |
91 | - theInternalDirIter = new dir_iterator(aPath); |
92 | -} |
93 | - |
94 | -DirectoryIteratorImpl::~DirectoryIteratorImpl() |
95 | -{ |
96 | - delete theInternalDirIter; |
97 | +DirectoryIteratorImpl::DirectoryIteratorImpl(std::string const& aPath) : |
98 | + theInternalDirIter( aPath.c_str() ) |
99 | +{ |
100 | } |
101 | |
102 | bool |
103 | DirectoryIteratorImpl::next(std::string& aPathStr) const |
104 | { |
105 | - if (theInternalDirIter->end()) { |
106 | + if (!theInternalDirIter.next()) { |
107 | return false; |
108 | } |
109 | |
110 | // get the current pointed entry |
111 | - aPathStr = *(*theInternalDirIter); |
112 | - |
113 | - // advance to the next entry |
114 | - ++(*theInternalDirIter); |
115 | + aPathStr = theInternalDirIter.entry_name(); |
116 | |
117 | return true; |
118 | } |
119 | |
120 | void DirectoryIteratorImpl::reset() |
121 | { |
122 | - std::string aPath = theInternalDirIter->dirpath; |
123 | - delete theInternalDirIter; |
124 | - theInternalDirIter = new dir_iterator(aPath); |
125 | + theInternalDirIter.reset(); |
126 | } |
127 | |
128 | FileImpl::FileImpl(std::string const& path) |
129 | |
130 | === modified file 'src/api/fileimpl.h' |
131 | --- src/api/fileimpl.h 2012-04-24 12:39:38 +0000 |
132 | +++ src/api/fileimpl.h 2012-04-25 19:52:28 +0000 |
133 | @@ -20,10 +20,11 @@ |
134 | #include <iostream> |
135 | #include <zorba/file.h> |
136 | |
137 | +#include "util/fs_util.h" |
138 | + |
139 | namespace zorba { |
140 | |
141 | class file; |
142 | - class dir_iterator; |
143 | class DiagnosticHandler; |
144 | |
145 | |
146 | @@ -31,14 +32,12 @@ |
147 | { |
148 | private: |
149 | |
150 | - dir_iterator* theInternalDirIter; |
151 | + mutable fs::iterator theInternalDirIter; |
152 | |
153 | public: |
154 | |
155 | DirectoryIteratorImpl(std::string const& aPath); |
156 | |
157 | - ~DirectoryIteratorImpl(); |
158 | - |
159 | bool next(std::string& aPathStr) const; |
160 | void reset(); |
161 | }; |
162 | |
163 | === modified file 'src/unit_tests/CMakeLists.txt' |
164 | --- src/unit_tests/CMakeLists.txt 2012-04-24 12:39:38 +0000 |
165 | +++ src/unit_tests/CMakeLists.txt 2012-04-25 19:52:28 +0000 |
166 | @@ -20,6 +20,7 @@ |
167 | unit_tests.cpp |
168 | test_uri.cpp |
169 | json_parser.cpp |
170 | + test_fs_iterator.cpp |
171 | ) |
172 | |
173 | IF (NOT ZORBA_NO_FULL_TEXT) |
174 | |
175 | === added file 'src/unit_tests/test_fs_iterator.cpp' |
176 | --- src/unit_tests/test_fs_iterator.cpp 1970-01-01 00:00:00 +0000 |
177 | +++ src/unit_tests/test_fs_iterator.cpp 2012-04-25 19:52:28 +0000 |
178 | @@ -0,0 +1,54 @@ |
179 | +/* |
180 | + * Copyright 2006-2010 The FLWOR Foundation. |
181 | + * |
182 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
183 | + * you may not use this file except in compliance with the License. |
184 | + * You may obtain a copy of the License at |
185 | + * |
186 | + * http://www.apache.org/licenses/LICENSE-2.0 |
187 | + * |
188 | + * Unless required by applicable law or agreed to in writing, software |
189 | + * distributed under the License is distributed on an "AS IS" BASIS, |
190 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
191 | + * See the License for the specific language governing permissions and |
192 | + * limitations under the License. |
193 | + */ |
194 | + |
195 | +#include "stdafx.h" |
196 | + |
197 | +#include <iostream> |
198 | +#include <zorba/zorba_exception.h> |
199 | + |
200 | +#include "util/fs_util.h" |
201 | + |
202 | +using namespace std; |
203 | +using namespace zorba; |
204 | + |
205 | +/////////////////////////////////////////////////////////////////////////////// |
206 | + |
207 | +namespace zorba { |
208 | +namespace UnitTests { |
209 | + |
210 | +int test_fs_iterator( int argc, char *argv[] ) { |
211 | + int result = 0; |
212 | + try { |
213 | +#ifndef WIN32 |
214 | + fs::iterator dir_iter( "/" ); |
215 | +#else |
216 | + fs::iterator dir_iter( "C:\\" ); |
217 | +#endif /* WIN32 */ |
218 | + while ( dir_iter.next() ) |
219 | + cout << dir_iter.entry_name() << " (" << dir_iter.entry_type() << ')' << endl; |
220 | + } |
221 | + catch ( ZorbaException const &e ) { |
222 | + cerr << e << endl; |
223 | + result = 2; |
224 | + } |
225 | + |
226 | + return result; |
227 | +} |
228 | + |
229 | +} // namespace UnitTests |
230 | +} // namespace zorba |
231 | + |
232 | +/* vim:set et sw=2 ts=2: */ |
233 | |
234 | === modified file 'src/unit_tests/unit_test_list.h' |
235 | --- src/unit_tests/unit_test_list.h 2012-04-24 12:39:38 +0000 |
236 | +++ src/unit_tests/unit_test_list.h 2012-04-25 19:52:28 +0000 |
237 | @@ -28,6 +28,7 @@ |
238 | int runDebuggerProtocolTest(int argc, char* argv[]); |
239 | int test_string( int, char*[] ); |
240 | int test_unique_ptr( int, char*[] ); |
241 | + int test_fs_iterator( int, char*[] ); |
242 | #ifndef ZORBA_NO_FULL_TEXT |
243 | int test_stemmer( int, char*[] ); |
244 | int test_thesaurus( int, char*[] ); |
245 | |
246 | === modified file 'src/unit_tests/unit_tests.cpp' |
247 | --- src/unit_tests/unit_tests.cpp 2012-04-24 12:39:38 +0000 |
248 | +++ src/unit_tests/unit_tests.cpp 2012-04-25 19:52:28 +0000 |
249 | @@ -39,6 +39,7 @@ |
250 | void initializeTestList() { |
251 | libunittests["string"] = test_string; |
252 | libunittests["uri"] = runUriTest; |
253 | + libunittests["fs_iterator"] = test_fs_iterator; |
254 | #ifndef ZORBA_NO_ICU |
255 | libunittests["icu_streambuf"] = test_icu_streambuf; |
256 | #endif /* ZORBA_NO_ICU */ |
257 | |
258 | === modified file 'src/util/CMakeLists.txt' |
259 | --- src/util/CMakeLists.txt 2012-04-24 12:39:38 +0000 |
260 | +++ src/util/CMakeLists.txt 2012-04-25 19:52:28 +0000 |
261 | @@ -17,7 +17,6 @@ |
262 | dynamic_bitset.cpp |
263 | error_util.cpp |
264 | file.cpp |
265 | - dir.cpp |
266 | fs_util.cpp |
267 | indent.cpp |
268 | json_parser.cpp |
269 | |
270 | === removed file 'src/util/dir.cpp' |
271 | --- src/util/dir.cpp 2012-04-24 12:39:38 +0000 |
272 | +++ src/util/dir.cpp 1970-01-01 00:00:00 +0000 |
273 | @@ -1,175 +0,0 @@ |
274 | -/* |
275 | - * Copyright 2006-2008 The FLWOR Foundation. |
276 | - * |
277 | - * Licensed under the Apache License, Version 2.0 (the "License"); |
278 | - * you may not use this file except in compliance with the License. |
279 | - * You may obtain a copy of the License at |
280 | - * |
281 | - * http://www.apache.org/licenses/LICENSE-2.0 |
282 | - * |
283 | - * Unless required by applicable law or agreed to in writing, software |
284 | - * distributed under the License is distributed on an "AS IS" BASIS, |
285 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
286 | - * See the License for the specific language governing permissions and |
287 | - * limitations under the License. |
288 | - */ |
289 | -#include "stdafx.h" |
290 | - |
291 | -#include "util/dir.h" |
292 | - |
293 | -#ifndef _WIN32_WCE |
294 | -#include <errno.h> |
295 | -#include <sys/stat.h> |
296 | -#include <sys/types.h> |
297 | -#else |
298 | -#include <types.h> |
299 | -#endif |
300 | -#include <stdio.h> |
301 | - |
302 | -#if defined (WIN32) |
303 | -#include <tchar.h> |
304 | -#ifndef _WIN32_WCE |
305 | -#include <io.h> |
306 | -#include <direct.h> |
307 | -#endif |
308 | -#else |
309 | -#include <sys/param.h> |
310 | -#include <unistd.h> |
311 | -#endif |
312 | - |
313 | -#ifndef _WIN32_WCE |
314 | -#include <fcntl.h> |
315 | -#endif |
316 | -#include <sstream> |
317 | - |
318 | -#include "diagnostics/xquery_diagnostics.h" |
319 | - |
320 | -using namespace std; |
321 | - |
322 | -namespace zorba { |
323 | - |
324 | -// dir_iterator |
325 | - |
326 | -#define END true |
327 | - |
328 | -dir_iterator |
329 | -directory::begin() |
330 | -{ |
331 | - return dir_iterator(getPathString()); |
332 | -} |
333 | - |
334 | -dir_iterator |
335 | -directory::end() |
336 | -{ |
337 | - return dir_iterator(getPathString(), END); |
338 | -} |
339 | - |
340 | -dir_iterator::dir_iterator( |
341 | - string const& path, |
342 | - bool end_iterator) |
343 | -: |
344 | - dirpath(path) |
345 | -#ifndef WIN32 |
346 | - ,dirent(0) |
347 | -#endif |
348 | -{ |
349 | -#ifndef WIN32 |
350 | - dir = opendir(path.c_str()); |
351 | - if (dir==0) { |
352 | - throw ZORBA_IO_EXCEPTION( "opendir()", path ); |
353 | - } |
354 | - if (!end_iterator) operator++(); |
355 | -#else |
356 | - if(!end_iterator) { |
357 | - std::string path_star = path + "\\*.*"; |
358 | - WCHAR wpath_str[1024]; |
359 | - wpath_str[0] = 0; |
360 | - if(MultiByteToWideChar(CP_UTF8, |
361 | - 0, path_star.c_str(), -1, |
362 | - wpath_str, sizeof(wpath_str)/sizeof(WCHAR)) == 0) |
363 | - {//probably there is some invalid utf8 char, try the Windows ACP |
364 | - MultiByteToWideChar(CP_ACP, |
365 | - 0, path_star.c_str(), -1, |
366 | - wpath_str, sizeof(wpath_str)/sizeof(WCHAR)); |
367 | - } |
368 | - win32_dir = FindFirstFileW(wpath_str, &win32_direntry); |
369 | - if(win32_dir == INVALID_HANDLE_VALUE) { |
370 | - throw ZORBA_IO_EXCEPTION( "FindFirstFile()", path ); |
371 | - } |
372 | - if (wcscmp(win32_direntry.cFileName, L".") == 0 || |
373 | - wcscmp(win32_direntry.cFileName, L"..") == 0) { |
374 | - operator ++(); |
375 | - } |
376 | - } else { |
377 | - win32_dir = INVALID_HANDLE_VALUE; |
378 | - wcscpy(win32_direntry.cFileName, L""); |
379 | - } |
380 | -#endif |
381 | - |
382 | -} |
383 | - |
384 | -dir_iterator::~dir_iterator() |
385 | -{ |
386 | -#if ! defined (WIN32) |
387 | - if (dir!=0) closedir(dir); |
388 | -#else |
389 | - if(win32_dir != INVALID_HANDLE_VALUE) { |
390 | - FindClose(win32_dir); |
391 | - } |
392 | -#endif |
393 | -} |
394 | - |
395 | - |
396 | -void |
397 | -dir_iterator::operator++() |
398 | -{ |
399 | -#ifndef WIN32 |
400 | - if (dir!=0) { |
401 | - while (true) { |
402 | - dirent = readdir(dir); |
403 | - if (dirent==0) { |
404 | - closedir(dir); |
405 | - dir = 0; |
406 | - break; |
407 | - } |
408 | - if (strcmp(dirent->d_name,".") && |
409 | - strcmp(dirent->d_name,"..")) { |
410 | - break; |
411 | - } |
412 | - } |
413 | - } |
414 | -#else |
415 | - if(win32_dir != INVALID_HANDLE_VALUE) { |
416 | - while(true) { |
417 | - if(!FindNextFileW(win32_dir, &win32_direntry)) { |
418 | - FindClose(win32_dir); |
419 | - win32_dir = INVALID_HANDLE_VALUE; |
420 | - wcscpy(win32_direntry.cFileName, L""); |
421 | - break; |
422 | - } |
423 | - if (wcscmp(win32_direntry.cFileName, L".") && |
424 | - wcscmp(win32_direntry.cFileName, L"..")) { |
425 | - break; |
426 | - } |
427 | - } |
428 | - } |
429 | -#endif |
430 | -} |
431 | - |
432 | -bool operator!=( |
433 | - dir_iterator const& x, |
434 | - dir_iterator const& y) |
435 | -{ |
436 | -#ifndef WIN32 |
437 | - if (x.dirpath==y.dirpath) return false; |
438 | - if (x.dirent==y.dirent) return false; |
439 | - return true; |
440 | -#else |
441 | - if (x.dirpath==y.dirpath) return false; |
442 | - if (!wcscmp(x.win32_direntry.cFileName, y.win32_direntry.cFileName)) return false; |
443 | - return true; |
444 | -#endif |
445 | -} |
446 | - |
447 | -} // namespace |
448 | -/* vim:set et sw=2 ts=2: */ |
449 | |
450 | === removed file 'src/util/dir.h' |
451 | --- src/util/dir.h 2012-04-24 12:39:38 +0000 |
452 | +++ src/util/dir.h 1970-01-01 00:00:00 +0000 |
453 | @@ -1,100 +0,0 @@ |
454 | -/* |
455 | - * Copyright 2006-2008 The FLWOR Foundation. |
456 | - * |
457 | - * Licensed under the Apache License, Version 2.0 (the "License"); |
458 | - * you may not use this file except in compliance with the License. |
459 | - * You may obtain a copy of the License at |
460 | - * |
461 | - * http://www.apache.org/licenses/LICENSE-2.0 |
462 | - * |
463 | - * Unless required by applicable law or agreed to in writing, software |
464 | - * distributed under the License is distributed on an "AS IS" BASIS, |
465 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
466 | - * See the License for the specific language governing permissions and |
467 | - * limitations under the License. |
468 | - */ |
469 | -#pragma once |
470 | -#ifndef ZORBA_UTIL_DIR_H |
471 | -#define ZORBA_UTIL_DIR_H |
472 | - |
473 | -#include "zorba/util/file.h" |
474 | -#include "zorbatypes/rchandle.h" |
475 | - |
476 | -#ifdef UNIX |
477 | -#include <dirent.h> |
478 | -#endif |
479 | - |
480 | -namespace zorba { |
481 | - |
482 | - class dir_iterator : public SimpleRCObject |
483 | - { |
484 | - |
485 | - public: |
486 | - |
487 | - std::string dirpath; |
488 | - std::string path; |
489 | -#ifndef WIN32 |
490 | - DIR *dir; |
491 | - struct dirent *dirent; |
492 | -#else |
493 | - HANDLE win32_dir; |
494 | - WIN32_FIND_DATAW win32_direntry; |
495 | - mutable char temp_file_name[1024]; |
496 | -#endif |
497 | - |
498 | - public: |
499 | - |
500 | - dir_iterator(const std::string& path, bool end_iterator = false); |
501 | - ~dir_iterator(); |
502 | - |
503 | - public: // iterator interface |
504 | - |
505 | - void operator++(); |
506 | - |
507 | - bool end() const { |
508 | -#ifndef WIN32 |
509 | - return dir == 0; |
510 | -#else |
511 | - return win32_dir == INVALID_HANDLE_VALUE; |
512 | -#endif |
513 | - } |
514 | - |
515 | -#ifndef WIN32 |
516 | - const char* operator*() { |
517 | - return dirent->d_name; |
518 | - } |
519 | -#else |
520 | - const char* operator*() { |
521 | - WideCharToMultiByte(CP_UTF8, 0, win32_direntry.cFileName, -1, temp_file_name, sizeof(temp_file_name), NULL, NULL); |
522 | - return temp_file_name; |
523 | - } |
524 | -#endif |
525 | - |
526 | - public: |
527 | -#ifndef WIN32 |
528 | - const char* get_name() const { |
529 | - return dirent?dirent->d_name:0; |
530 | - } |
531 | -#else |
532 | - const char* get_name() const { |
533 | - if (win32_dir == INVALID_HANDLE_VALUE) |
534 | - return NULL; |
535 | - WideCharToMultiByte(CP_UTF8, 0, win32_direntry.cFileName, -1, temp_file_name, sizeof(temp_file_name), NULL, NULL); |
536 | - return temp_file_name; |
537 | - } |
538 | -#endif |
539 | - }; |
540 | - |
541 | - class directory : public file { |
542 | - |
543 | - public: |
544 | - dir_iterator begin(); |
545 | - dir_iterator end(); |
546 | - |
547 | - friend bool operator!=(dir_iterator const& x, dir_iterator const& y); |
548 | - |
549 | - }; |
550 | - |
551 | -} |
552 | -#endif |
553 | -/* vim:set et sw=2 ts=2: */ |
554 | |
555 | === modified file 'src/util/file.cpp' |
556 | --- src/util/file.cpp 2012-04-24 12:39:38 +0000 |
557 | +++ src/util/file.cpp 2012-04-25 19:52:28 +0000 |
558 | @@ -280,7 +280,9 @@ |
559 | void file::lsdir(std::vector<std::string> &list) { |
560 | #ifdef ZORBA_WITH_FILE_ACCESS |
561 | try { |
562 | - fs::lsdir( c_str(), list ); |
563 | + fs::iterator dir_iter( c_str() ); |
564 | + while ( dir_iter.next() ) |
565 | + list.push_back( dir_iter.entry_name() ); |
566 | set_filetype( type_directory ); |
567 | } |
568 | catch ( fs::exception const &e ) { |
569 | |
570 | === modified file 'src/util/fs_util.cpp' |
571 | --- src/util/fs_util.cpp 2012-04-24 12:39:38 +0000 |
572 | +++ src/util/fs_util.cpp 2012-04-25 19:52:28 +0000 |
573 | @@ -23,6 +23,8 @@ |
574 | # include <sys/types.h> |
575 | # include <sys/stat.h> |
576 | # include <unistd.h> /* for chdir(2) */ |
577 | +#else |
578 | +# include <shlwapi.h> |
579 | #endif /* WIN32 */ |
580 | |
581 | #include "diagnostics/xquery_diagnostics.h" |
582 | @@ -38,6 +40,17 @@ |
583 | namespace zorba { |
584 | namespace fs { |
585 | |
586 | +/////////////////////////////////////////////////////////////////////////////// |
587 | + |
588 | +char const *const type_string[] = { |
589 | + "non_existant", |
590 | + "directory", |
591 | + "file", |
592 | + "link", |
593 | + "volume", |
594 | + "other" |
595 | +}; |
596 | + |
597 | ////////// helper functions /////////////////////////////////////////////////// |
598 | |
599 | inline void replace_foreign( zstring *path ) { |
600 | @@ -56,16 +69,21 @@ |
601 | |
602 | #ifdef ZORBA_WITH_FILE_ACCESS |
603 | |
604 | +static type map_type( DWORD dwFileAttributes ) { |
605 | + if ( dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) |
606 | + return directory; |
607 | + if ( dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ) |
608 | + return link; |
609 | + return file; |
610 | +} |
611 | + |
612 | static type get_type( LPCWSTR wpath, size_type *size = nullptr ) { |
613 | WIN32_FILE_ATTRIBUTE_DATA data; |
614 | if ( ::GetFileAttributesEx( wpath, GetFileExInfoStandard, (void*)&data ) ) { |
615 | - if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) |
616 | - return directory; |
617 | - if ( data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ) |
618 | - return link; |
619 | - if ( size ) |
620 | + type const t = map_type( data.dwFileAttributes ); |
621 | + if ( t == file && size ) |
622 | *size = ((size_type)data.nFileSizeHigh << 32) | data.nFileSizeLow; |
623 | - return file; |
624 | + return t; |
625 | } |
626 | return non_existent; |
627 | } |
628 | @@ -90,11 +108,13 @@ |
629 | to_wchar( path, wpath ); |
630 | WCHAR wfull_path[ MAX_PATH ]; |
631 | DWORD const result = ::GetFullPathName( |
632 | - wpath, sizeof( wpath ) / sizeof( wpath[0] ), wfull_path, NULL |
633 | + wpath, sizeof( wfull_path ) / sizeof( wfull_path[0] ), wfull_path, NULL |
634 | ); |
635 | if ( !result ) |
636 | throw ZORBA_IO_EXCEPTION( "GetFullPathName()", path ); |
637 | to_char( wfull_path, abs_path ); |
638 | +#else |
639 | + ::strcpy( abs_path, path ); |
640 | #endif /* WINCE */ |
641 | } |
642 | |
643 | @@ -153,7 +173,7 @@ |
644 | win32::to_char( wpath, path ); |
645 | if ( !is_absolute( path ) ) { |
646 | // GetCurrentDirectory() sometimes misses drive letter. |
647 | - filesystem_path fspath( path ); |
648 | + filesystem_path fspath( path ); |
649 | fspath.resolve_relative(); |
650 | return fspath.get_path(); |
651 | } |
652 | @@ -277,29 +297,107 @@ |
653 | #endif |
654 | } |
655 | |
656 | -void lsdir( char const *path, std::vector<std::string> &list ) |
657 | -{ |
658 | - DIR *dir; |
659 | - struct dirent *ent; |
660 | - |
661 | - dir = opendir (path); |
662 | - if (dir != NULL) |
663 | - { |
664 | - /* print all the files and directories within directory */ |
665 | - while ((ent = readdir (dir)) != NULL) |
666 | - { |
667 | - //printf ("%s\n", ent->d_name); |
668 | - std::string item(ent->d_name); |
669 | - list.push_back(item); |
670 | - } |
671 | - closedir (dir); |
672 | - } |
673 | - else |
674 | - { |
675 | - /* could not open directory */ |
676 | - throw fs::exception( "lsdir()", path ); |
677 | - } |
678 | -} |
679 | +iterator::iterator( char const *path ) : dir_path_( path ) { |
680 | + make_absolute( dir_path_ ); |
681 | +#ifndef WIN32 |
682 | + if ( !(dir_ = ::opendir( dir_path_.c_str() )) ) |
683 | + throw fs::exception( "iterator()", dir_path_.c_str() ); |
684 | +#else |
685 | + win32_opendir( dir_path_.c_str() ); |
686 | +#endif /* WIN32 */ |
687 | +} |
688 | + |
689 | +iterator::~iterator() { |
690 | +#ifndef WIN32 |
691 | + if ( ::closedir( dir_ ) != 0 ) |
692 | + throw fs::exception( "closedir()", path() ); |
693 | +#else |
694 | + win32_closedir(); |
695 | +#endif /* WIN32 */ |
696 | +} |
697 | + |
698 | +bool iterator::next() { |
699 | + while ( true ) { |
700 | +#ifndef WIN32 |
701 | + if ( (ent_ = ::readdir( dir_ )) ) { |
702 | + switch ( ent_->d_type ) { |
703 | + case DT_DIR: { |
704 | + char const *const name = ent_->d_name; |
705 | + // skip "." and ".." entries |
706 | + if ( name[0] == '.' && (!name[1] || name[1] == '.' && !name[2]) ) |
707 | + continue; |
708 | + ent_type_ = directory; |
709 | + break; |
710 | + } |
711 | + case DT_LNK: |
712 | + ent_type_ = link; |
713 | + break; |
714 | + case DT_REG: |
715 | + ent_type_ = file; |
716 | + break; |
717 | + default: |
718 | + ent_type_ = other; |
719 | + } |
720 | + return true; |
721 | + } |
722 | +#else |
723 | + if ( !dir_is_empty_ ) { |
724 | + if ( use_first_ ) |
725 | + use_first_ = false; |
726 | + else |
727 | + if ( !::FindNextFile( dir_, &ent_data_ ) ) { |
728 | + if ( ::GetLastError() != ERROR_NO_MORE_FILES ) |
729 | + throw fs::exception( "FindNextFile()", path() ); |
730 | + return false; |
731 | + } |
732 | + |
733 | + LPCWSTR const wname = ent_data_.cFileName; |
734 | + // skip "." and ".." entries |
735 | + if ( wname[0] == TEXT('.') && |
736 | + (!wname[1] || wname[1] == TEXT('.') && !wname[2]) ) |
737 | + continue; |
738 | + |
739 | + win32::to_char( wname, ent_name_ ); |
740 | + ent_type_ = win32::map_type( ent_data_.dwFileAttributes ); |
741 | + return true; |
742 | + } |
743 | +#endif /* WIN32 */ |
744 | + return false; |
745 | + } // while |
746 | +} |
747 | + |
748 | +void iterator::reset() { |
749 | +#ifndef WIN32 |
750 | + ::rewinddir( dir_ ); |
751 | +#else |
752 | + win32_closedir(); |
753 | + win32_opendir( dir_path_.c_str() ); |
754 | +#endif /* WIN32 */ |
755 | +} |
756 | + |
757 | +#ifdef WIN32 |
758 | +void iterator::win32_closedir() { |
759 | + if ( dir_ != INVALID_HANDLE_VALUE && !::FindClose( dir_ ) ) |
760 | + throw fs::exception( "FindClose()", path() ); |
761 | +} |
762 | + |
763 | +void iterator::win32_opendir( char const *path ) { |
764 | + WCHAR wpath[ MAX_PATH ]; |
765 | + win32::to_wchar( path, wpath ); |
766 | + WCHAR wpattern[ MAX_PATH ]; |
767 | + ::wcscpy( wpattern, wpath ); |
768 | + ::PathAppend( wpattern, TEXT("*") ); |
769 | + dir_ = ::FindFirstFile( wpattern, &ent_data_ ); |
770 | + if ( dir_ == INVALID_HANDLE_VALUE ) { |
771 | + if ( ::GetLastError() != ERROR_FILE_NOT_FOUND ) |
772 | + throw fs::exception( "FindFirstFile()", path ); |
773 | + dir_is_empty_ = true; |
774 | + } else { |
775 | + dir_is_empty_ = false; |
776 | + use_first_ = true; |
777 | + } |
778 | +} |
779 | +#endif /* WIN32 */ |
780 | |
781 | bool remove( char const *path ) { |
782 | #ifndef WIN32 |
783 | |
784 | === modified file 'src/util/fs_util.h' |
785 | --- src/util/fs_util.h 2012-04-24 12:39:38 +0000 |
786 | +++ src/util/fs_util.h 2012-04-25 19:52:28 +0000 |
787 | @@ -17,20 +17,14 @@ |
788 | #ifndef ZORBA_FS_UTIL_H |
789 | #define ZORBA_FS_UTIL_H |
790 | |
791 | -#include <vector> |
792 | - |
793 | -#ifdef WIN32 |
794 | -# include "win32/dirent.h" |
795 | -#else |
796 | -# include <dirent.h> /* for implementing lsdir */ |
797 | -#endif /* WIN32 */ |
798 | - |
799 | #include <zorba/config.h> |
800 | |
801 | +#include <iostream> |
802 | #include <stdexcept> |
803 | #ifdef WIN32 |
804 | # include <windows.h> |
805 | #else |
806 | +# include <dirent.h> |
807 | # include <sys/types.h> /* for off_t */ |
808 | #endif /* WIN32 */ |
809 | |
810 | @@ -82,6 +76,11 @@ |
811 | volume, |
812 | other // named pipe, character/block special, socket, etc. |
813 | }; |
814 | +extern char const *const type_string[]; |
815 | + |
816 | +inline std::ostream& operator<<( std::ostream &o, type t ) { |
817 | + return o << type_string[ t ]; |
818 | +} |
819 | |
820 | ////////// Windows //////////////////////////////////////////////////////////// |
821 | |
822 | @@ -152,25 +151,89 @@ |
823 | mkdir( path.c_str() ); |
824 | } |
825 | |
826 | -/** |
827 | - * List files in dir |
828 | - * |
829 | - * @param path The full path of the directory to list. |
830 | - * @throws fs::exception if the list fails. |
831 | - */ |
832 | -void lsdir( char const *path, std::vector<std::string> & list ); |
833 | - |
834 | -/** |
835 | - * List files in dir |
836 | - * |
837 | - * @tparam PathStringType The \a path string type. |
838 | - * @param path The full path of the directory to list. |
839 | - * @throws fs::exception if the list fails. |
840 | - */ |
841 | -template<class PathStringType> inline |
842 | -void lsdir( PathStringType const &path, std::vector<std::string> & list ) { |
843 | - lsdir( path.c_str(), list ); |
844 | -} |
845 | +////////// Directory iteration //////////////////////////////////////////////// |
846 | + |
847 | +/** |
848 | + * An fs::iterator iterates over the entries in a directory. |
849 | + */ |
850 | +class iterator { |
851 | +public: |
852 | + /** |
853 | + * Constructs an %itertor. |
854 | + * |
855 | + * @throws fs::exception if the construction failed, e.g., path not found. |
856 | + */ |
857 | + iterator( char const *path ); |
858 | + |
859 | + /** |
860 | + * Destroys this %iterator. |
861 | + */ |
862 | + ~iterator(); |
863 | + |
864 | + /** |
865 | + * Attempts to get the next directory entry. |
866 | + * |
867 | + * @return Returns \c true only if there is a next directory. |
868 | + */ |
869 | + bool next(); |
870 | + |
871 | + /** |
872 | + * Gets the name of the curent directory entry. |
873 | + * |
874 | + * @return Returns said name. |
875 | + */ |
876 | + char const* entry_name() const { |
877 | +# ifndef WIN32 |
878 | + return ent_->d_name; |
879 | +# else |
880 | + return ent_name_; |
881 | +# endif /* WIN32 */ |
882 | + } |
883 | + |
884 | + /** |
885 | + * Gets the type of the current directory entry. |
886 | + * |
887 | + * @return Returns said type. |
888 | + */ |
889 | + type entry_type() const { |
890 | + return ent_type_; |
891 | + } |
892 | + |
893 | + /** |
894 | + * Gets the directory's path. |
895 | + * |
896 | + * @return Returns said path. |
897 | + */ |
898 | + char const* path() const { |
899 | + return dir_path_.c_str(); |
900 | + } |
901 | + |
902 | + /** |
903 | + * Resets this iterator to the beginning. |
904 | + */ |
905 | + void reset(); |
906 | + |
907 | +private: |
908 | + zstring dir_path_; |
909 | + type ent_type_; |
910 | +#ifndef WIN32 |
911 | + DIR *dir_; |
912 | + struct dirent *ent_; |
913 | +#else |
914 | + HANDLE dir_; |
915 | + bool dir_is_empty_; |
916 | + WIN32_FIND_DATA ent_data_; |
917 | + char ent_name_[ MAX_PATH ]; |
918 | + bool use_first_; |
919 | + |
920 | + void win32_opendir( char const *path ); |
921 | + void win32_closedir(); |
922 | +#endif /* WIN32 */ |
923 | + |
924 | + // forbid |
925 | + iterator( iterator const& ); |
926 | + iterator& operator=( iterator const& ); |
927 | +}; |
928 | |
929 | #endif /* ZORBA_WITH_FILE_ACCESS */ |
930 | |
931 | @@ -182,7 +245,7 @@ |
932 | * Creates the given file. |
933 | * |
934 | * @param path The full path of the file to create. |
935 | - * *throws fs::exception if the creation failed. |
936 | + * @throws fs::exception if the creation failed. |
937 | */ |
938 | void create( char const *path ); |
939 | |
940 | @@ -572,7 +635,8 @@ |
941 | void make_absolute( PathStringType &path ) { |
942 | if ( !is_absolute( path ) ) { |
943 | #ifndef WIN32 |
944 | - path.insert( 0, 1, '/' ); |
945 | + typedef typename PathStringType::size_type size_type; |
946 | + path.insert( static_cast<size_type>(0), static_cast<size_type>(1), '/' ); |
947 | path.insert( 0, curdir().c_str() ); |
948 | #else |
949 | char temp[ MAX_PATH ]; |
950 | |
951 | === removed file 'src/util/win32/dirent.h' |
952 | --- src/util/win32/dirent.h 2012-03-08 23:20:54 +0000 |
953 | +++ src/util/win32/dirent.h 1970-01-01 00:00:00 +0000 |
954 | @@ -1,372 +0,0 @@ |
955 | -/***************************************************************************** |
956 | - * dirent.h - dirent API for Microsoft Visual Studio |
957 | - * |
958 | - * Copyright (C) 2006 Toni Ronkko |
959 | - * |
960 | - * Permission is hereby granted, free of charge, to any person obtaining |
961 | - * a copy of this software and associated documentation files (the |
962 | - * ``Software''), to deal in the Software without restriction, including |
963 | - * without limitation the rights to use, copy, modify, merge, publish, |
964 | - * distribute, sublicense, and/or sell copies of the Software, and to |
965 | - * permit persons to whom the Software is furnished to do so, subject to |
966 | - * the following conditions: |
967 | - * |
968 | - * The above copyright notice and this permission notice shall be included |
969 | - * in all copies or substantial portions of the Software. |
970 | - * |
971 | - * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS |
972 | - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
973 | - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
974 | - * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR |
975 | - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
976 | - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
977 | - * OTHER DEALINGS IN THE SOFTWARE. |
978 | - * |
979 | - * Mar 15, 2011, Toni Ronkko |
980 | - * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0. |
981 | - * |
982 | - * Aug 11, 2010, Toni Ronkko |
983 | - * Added d_type and d_namlen fields to dirent structure. The former is |
984 | - * especially useful for determining whether directory entry represents a |
985 | - * file or a directory. For more information, see |
986 | - * http://www.delorie.com/gnu/docs/glibc/libc_270.html |
987 | - * |
988 | - * Aug 11, 2010, Toni Ronkko |
989 | - * Improved conformance to the standards. For example, errno is now set |
990 | - * properly on failure and assert() is never used. Thanks to Peter Brockam |
991 | - * for suggestions. |
992 | - * |
993 | - * Aug 11, 2010, Toni Ronkko |
994 | - * Fixed a bug in rewinddir(): when using relative directory names, change |
995 | - * of working directory no longer causes rewinddir() to fail. |
996 | - * |
997 | - * Dec 15, 2009, John Cunningham |
998 | - * Added rewinddir member function |
999 | - * |
1000 | - * Jan 18, 2008, Toni Ronkko |
1001 | - * Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string |
1002 | - * between multi-byte and unicode representations. This makes the |
1003 | - * code simpler and also allows the code to be compiled under MingW. Thanks |
1004 | - * to Azriel Fasten for the suggestion. |
1005 | - * |
1006 | - * Mar 4, 2007, Toni Ronkko |
1007 | - * Bug fix: due to the strncpy_s() function this file only compiled in |
1008 | - * Visual Studio 2005. Using the new string functions only when the |
1009 | - * compiler version allows. |
1010 | - * |
1011 | - * Nov 2, 2006, Toni Ronkko |
1012 | - * Major update: removed support for Watcom C, MS-DOS and Turbo C to |
1013 | - * simplify the file, updated the code to compile cleanly on Visual |
1014 | - * Studio 2005 with both unicode and multi-byte character strings, |
1015 | - * removed rewinddir() as it had a bug. |
1016 | - * |
1017 | - * Aug 20, 2006, Toni Ronkko |
1018 | - * Removed all remarks about MSVC 1.0, which is antiqued now. Simplified |
1019 | - * comments by removing SGML tags. |
1020 | - * |
1021 | - * May 14 2002, Toni Ronkko |
1022 | - * Embedded the function definitions directly to the header so that no |
1023 | - * source modules need to be included in the Visual Studio project. Removed |
1024 | - * all the dependencies to other projects so that this very header can be |
1025 | - * used independently. |
1026 | - * |
1027 | - * May 28 1998, Toni Ronkko |
1028 | - * First version. |
1029 | - *****************************************************************************/ |
1030 | -#ifndef DIRENT_H |
1031 | -#define DIRENT_H |
1032 | - |
1033 | -#define WIN32_LEAN_AND_MEAN |
1034 | -#include <windows.h> |
1035 | -#include <string.h> |
1036 | -#include <stdlib.h> |
1037 | -#include <sys/types.h> |
1038 | -#include <sys/stat.h> |
1039 | -#include <errno.h> |
1040 | - |
1041 | -/* Entries missing from MSVC 6.0 */ |
1042 | -#if !defined(FILE_ATTRIBUTE_DEVICE) |
1043 | -# define FILE_ATTRIBUTE_DEVICE 0x40 |
1044 | -#endif |
1045 | - |
1046 | -/* File type and permission flags for stat() */ |
1047 | -#if defined(_MSC_VER) && !defined(S_IREAD) |
1048 | -# define S_IFMT _S_IFMT /* file type mask */ |
1049 | -# define S_IFDIR _S_IFDIR /* directory */ |
1050 | -# define S_IFCHR _S_IFCHR /* character device */ |
1051 | -# define S_IFFIFO _S_IFFIFO /* pipe */ |
1052 | -# define S_IFREG _S_IFREG /* regular file */ |
1053 | -# define S_IREAD _S_IREAD /* read permission */ |
1054 | -# define S_IWRITE _S_IWRITE /* write permission */ |
1055 | -# define S_IEXEC _S_IEXEC /* execute permission */ |
1056 | -#endif |
1057 | -#define S_IFBLK 0 /* block device */ |
1058 | -#define S_IFLNK 0 /* link */ |
1059 | -#define S_IFSOCK 0 /* socket */ |
1060 | - |
1061 | -#if defined(_MSC_VER) |
1062 | -# define S_IRUSR S_IREAD /* read, user */ |
1063 | -# define S_IWUSR S_IWRITE /* write, user */ |
1064 | -# define S_IXUSR 0 /* execute, user */ |
1065 | -# define S_IRGRP 0 /* read, group */ |
1066 | -# define S_IWGRP 0 /* write, group */ |
1067 | -# define S_IXGRP 0 /* execute, group */ |
1068 | -# define S_IROTH 0 /* read, others */ |
1069 | -# define S_IWOTH 0 /* write, others */ |
1070 | -# define S_IXOTH 0 /* execute, others */ |
1071 | -#endif |
1072 | - |
1073 | -/* Indicates that d_type field is available in dirent structure */ |
1074 | -#define _DIRENT_HAVE_D_TYPE |
1075 | - |
1076 | -/* File type flags for d_type */ |
1077 | -#define DT_UNKNOWN 0 |
1078 | -#define DT_REG S_IFREG |
1079 | -#define DT_DIR S_IFDIR |
1080 | -#define DT_FIFO S_IFFIFO |
1081 | -#define DT_SOCK S_IFSOCK |
1082 | -#define DT_CHR S_IFCHR |
1083 | -#define DT_BLK S_IFBLK |
1084 | - |
1085 | -/* Macros for converting between st_mode and d_type */ |
1086 | -#define IFTODT(mode) ((mode) & S_IFMT) |
1087 | -#define DTTOIF(type) (type) |
1088 | - |
1089 | -/* |
1090 | - * File type macros. Note that block devices, sockets and links cannot be |
1091 | - * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are |
1092 | - * only defined for compatibility. These macros should always return false |
1093 | - * on Windows. |
1094 | - */ |
1095 | -#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO) |
1096 | -#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) |
1097 | -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) |
1098 | -#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) |
1099 | -#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) |
1100 | -#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) |
1101 | -#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) |
1102 | - |
1103 | -#ifdef __cplusplus |
1104 | -extern "C" { |
1105 | -#endif |
1106 | - |
1107 | - |
1108 | -typedef struct dirent |
1109 | -{ |
1110 | - char d_name[MAX_PATH + 1]; /* File name */ |
1111 | - size_t d_namlen; /* Length of name without \0 */ |
1112 | - int d_type; /* File type */ |
1113 | -} dirent; |
1114 | - |
1115 | - |
1116 | -typedef struct DIR |
1117 | -{ |
1118 | - dirent curentry; /* Current directory entry */ |
1119 | - WIN32_FIND_DATAA find_data; /* Private file data */ |
1120 | - int cached; /* True if data is valid */ |
1121 | - HANDLE search_handle; /* Win32 search handle */ |
1122 | - char patt[MAX_PATH + 3]; /* Initial directory name */ |
1123 | -} DIR; |
1124 | - |
1125 | - |
1126 | -/* Forward declarations */ |
1127 | -static DIR *opendir(const char *dirname); |
1128 | -static struct dirent *readdir(DIR *dirp); |
1129 | -static int closedir(DIR *dirp); |
1130 | -static void rewinddir(DIR* dirp); |
1131 | - |
1132 | - |
1133 | -/* Use the new safe string functions introduced in Visual Studio 2005 */ |
1134 | -#if defined(_MSC_VER) && _MSC_VER >= 1400 |
1135 | -# define DIRENT_STRNCPY(dest,src,size) strncpy_s((dest),(size),(src),_TRUNCATE) |
1136 | -#else |
1137 | -# define DIRENT_STRNCPY(dest,src,size) strncpy((dest),(src),(size)) |
1138 | -#endif |
1139 | - |
1140 | -/* Set errno variable */ |
1141 | -#if defined(_MSC_VER) |
1142 | -#define DIRENT_SET_ERRNO(x) _set_errno (x) |
1143 | -#else |
1144 | -#define DIRENT_SET_ERRNO(x) (errno = (x)) |
1145 | -#endif |
1146 | - |
1147 | - |
1148 | -/***************************************************************************** |
1149 | - * Open directory stream DIRNAME for read and return a pointer to the |
1150 | - * internal working area that is used to retrieve individual directory |
1151 | - * entries. |
1152 | - */ |
1153 | -static DIR *opendir(const char *dirname) |
1154 | -{ |
1155 | - DIR *dirp; |
1156 | - |
1157 | - /* ensure that the resulting search pattern will be a valid file name */ |
1158 | - if (dirname == NULL) { |
1159 | - DIRENT_SET_ERRNO (ENOENT); |
1160 | - return NULL; |
1161 | - } |
1162 | - if (strlen (dirname) + 3 >= MAX_PATH) { |
1163 | - DIRENT_SET_ERRNO (ENAMETOOLONG); |
1164 | - return NULL; |
1165 | - } |
1166 | - |
1167 | - /* construct new DIR structure */ |
1168 | - dirp = (DIR*) malloc (sizeof (struct DIR)); |
1169 | - if (dirp != NULL) { |
1170 | - int error; |
1171 | - |
1172 | - /* |
1173 | - * Convert relative directory name to an absolute one. This |
1174 | - * allows rewinddir() to function correctly when the current working |
1175 | - * directory is changed between opendir() and rewinddir(). |
1176 | - */ |
1177 | - if (GetFullPathNameA (dirname, MAX_PATH, dirp->patt, NULL)) { |
1178 | - char *p; |
1179 | - |
1180 | - /* append the search pattern "\\*\0" to the directory name */ |
1181 | - p = strchr (dirp->patt, '\0'); |
1182 | - if (dirp->patt < p && *(p-1) != '\\' && *(p-1) != ':') { |
1183 | - *p++ = '\\'; |
1184 | - } |
1185 | - *p++ = '*'; |
1186 | - *p = '\0'; |
1187 | - |
1188 | - /* open directory stream and retrieve the first entry */ |
1189 | - dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data); |
1190 | - if (dirp->search_handle != INVALID_HANDLE_VALUE) { |
1191 | - /* a directory entry is now waiting in memory */ |
1192 | - dirp->cached = 1; |
1193 | - error = 0; |
1194 | - } else { |
1195 | - /* search pattern is not a directory name? */ |
1196 | - DIRENT_SET_ERRNO (ENOENT); |
1197 | - error = 1; |
1198 | - } |
1199 | - } else { |
1200 | - /* buffer too small */ |
1201 | - DIRENT_SET_ERRNO (ENOMEM); |
1202 | - error = 1; |
1203 | - } |
1204 | - |
1205 | - if (error) { |
1206 | - free (dirp); |
1207 | - dirp = NULL; |
1208 | - } |
1209 | - } |
1210 | - |
1211 | - return dirp; |
1212 | -} |
1213 | - |
1214 | - |
1215 | -/***************************************************************************** |
1216 | - * Read a directory entry, and return a pointer to a dirent structure |
1217 | - * containing the name of the entry in d_name field. Individual directory |
1218 | - * entries returned by this very function include regular files, |
1219 | - * sub-directories, pseudo-directories "." and "..", but also volume labels, |
1220 | - * hidden files and system files may be returned. |
1221 | - */ |
1222 | -static struct dirent *readdir(DIR *dirp) |
1223 | -{ |
1224 | - DWORD attr; |
1225 | - if (dirp == NULL) { |
1226 | - /* directory stream did not open */ |
1227 | - DIRENT_SET_ERRNO (EBADF); |
1228 | - return NULL; |
1229 | - } |
1230 | - |
1231 | - /* get next directory entry */ |
1232 | - if (dirp->cached != 0) { |
1233 | - /* a valid directory entry already in memory */ |
1234 | - dirp->cached = 0; |
1235 | - } else { |
1236 | - /* get the next directory entry from stream */ |
1237 | - if (dirp->search_handle == INVALID_HANDLE_VALUE) { |
1238 | - return NULL; |
1239 | - } |
1240 | - if (FindNextFileA (dirp->search_handle, &dirp->find_data) == FALSE) { |
1241 | - /* the very last entry has been processed or an error occured */ |
1242 | - FindClose (dirp->search_handle); |
1243 | - dirp->search_handle = INVALID_HANDLE_VALUE; |
1244 | - return NULL; |
1245 | - } |
1246 | - } |
1247 | - |
1248 | - /* copy as a multibyte character string */ |
1249 | - DIRENT_STRNCPY ( dirp->curentry.d_name, |
1250 | - dirp->find_data.cFileName, |
1251 | - sizeof(dirp->curentry.d_name) ); |
1252 | - dirp->curentry.d_name[MAX_PATH] = '\0'; |
1253 | - |
1254 | - /* compute the length of name */ |
1255 | - dirp->curentry.d_namlen = strlen (dirp->curentry.d_name); |
1256 | - |
1257 | - /* determine file type */ |
1258 | - attr = dirp->find_data.dwFileAttributes; |
1259 | - if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { |
1260 | - dirp->curentry.d_type = DT_CHR; |
1261 | - } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
1262 | - dirp->curentry.d_type = DT_DIR; |
1263 | - } else { |
1264 | - dirp->curentry.d_type = DT_REG; |
1265 | - } |
1266 | - return &dirp->curentry; |
1267 | -} |
1268 | - |
1269 | - |
1270 | -/***************************************************************************** |
1271 | - * Close directory stream opened by opendir() function. Close of the |
1272 | - * directory stream invalidates the DIR structure as well as any previously |
1273 | - * read directory entry. |
1274 | - */ |
1275 | -static int closedir(DIR *dirp) |
1276 | -{ |
1277 | - if (dirp == NULL) { |
1278 | - /* invalid directory stream */ |
1279 | - DIRENT_SET_ERRNO (EBADF); |
1280 | - return -1; |
1281 | - } |
1282 | - |
1283 | - /* release search handle */ |
1284 | - if (dirp->search_handle != INVALID_HANDLE_VALUE) { |
1285 | - FindClose (dirp->search_handle); |
1286 | - dirp->search_handle = INVALID_HANDLE_VALUE; |
1287 | - } |
1288 | - |
1289 | - /* release directory structure */ |
1290 | - free (dirp); |
1291 | - return 0; |
1292 | -} |
1293 | - |
1294 | - |
1295 | -/***************************************************************************** |
1296 | - * Resets the position of the directory stream to which dirp refers to the |
1297 | - * beginning of the directory. It also causes the directory stream to refer |
1298 | - * to the current state of the corresponding directory, as a call to opendir() |
1299 | - * would have done. If dirp does not refer to a directory stream, the effect |
1300 | - * is undefined. |
1301 | - */ |
1302 | -static void rewinddir(DIR* dirp) |
1303 | -{ |
1304 | - if (dirp != NULL) { |
1305 | - /* release search handle */ |
1306 | - if (dirp->search_handle != INVALID_HANDLE_VALUE) { |
1307 | - FindClose (dirp->search_handle); |
1308 | - } |
1309 | - |
1310 | - /* open new search handle and retrieve the first entry */ |
1311 | - dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data); |
1312 | - if (dirp->search_handle != INVALID_HANDLE_VALUE) { |
1313 | - /* a directory entry is now waiting in memory */ |
1314 | - dirp->cached = 1; |
1315 | - } else { |
1316 | - /* failed to re-open directory: no directory entry in memory */ |
1317 | - dirp->cached = 0; |
1318 | - } |
1319 | - } |
1320 | -} |
1321 | - |
1322 | - |
1323 | -#ifdef __cplusplus |
1324 | -} |
1325 | -#endif |
1326 | -#endif /*DIRENT_H*/ |
Looks good, please do remove the dirent.h copyright/license from NOTICE.txt/xml files since you removed dirent.h.