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