]>
Commit | Line | Data |
---|---|---|
23c9e63c | 1 | /* |
b401ef47 | 2 | * Copyright (c) 2002, Robert Collins. |
23c9e63c DD |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * A copy of the GNU General Public License can be found at | |
10 | * http://www.gnu.org/ | |
11 | * | |
12 | * Written by DJ Delorie <dj@cygnus.com> | |
b401ef47 | 13 | * Rewritten by Robert Collins <rbtcollins@hotmail.com> |
23c9e63c DD |
14 | * |
15 | */ | |
16 | ||
17 | /* The purpose of this file is to doa recursive find on a given | |
18 | directory, calling a given function for each file found. */ | |
19 | ||
7cc4d95e CV |
20 | #include "win32.h" |
21 | #include "filemanip.h" | |
b401ef47 | 22 | #include "find.h" |
23c9e63c | 23 | |
b401ef47 RC |
24 | #include "FindVisitor.h" |
25 | #include <stdexcept> | |
26 | ||
6625e635 RC |
27 | using namespace std; |
28 | ||
fd93eff9 | 29 | Find::Find(const std::string& starting_dir) |
feee2f2b | 30 | : h(INVALID_HANDLE_VALUE) |
b401ef47 | 31 | { |
feee2f2b BD |
32 | _start_dir = starting_dir; |
33 | int l = _start_dir.size (); | |
34 | ||
35 | /* Ensure that _start_dir has a trailing slash if it doesn't already. */ | |
36 | if (l < 1 || (starting_dir[l - 1] != '/' && starting_dir[l - 1] != '\\')) | |
37 | _start_dir += '/'; | |
b401ef47 | 38 | } |
3c054baf | 39 | |
b401ef47 RC |
40 | Find::~Find() |
41 | { | |
42 | if (h != INVALID_HANDLE_VALUE && h) | |
43 | FindClose (h); | |
44 | } | |
23c9e63c | 45 | |
b401ef47 | 46 | void |
9d0dd17b | 47 | Find::accept (FindVisitor &aVisitor, int level) |
23c9e63c | 48 | { |
7cc4d95e CV |
49 | /* The usage of multibyte strings within setup is so entangled into |
50 | the various C++ classes, it's very hard to disentangle it and use | |
51 | UNICODE strings throughout without ripping everything apart. | |
52 | On the other hand, we want to support paths > MAX_PATH, but this is | |
53 | only supported by the UNICODE API. | |
54 | What you see here is nothing less than a hack. We get the string | |
55 | as a multibyte string, convert it, call the UNICODE FindFile functions, | |
56 | then convert the returned structure back to multibyte to call the | |
57 | visitor methods, which in turn call other methods expecting multibyte | |
58 | strings. */ | |
59 | WIN32_FIND_DATAW w_wfd; | |
23c9e63c | 60 | |
7cc4d95e CV |
61 | size_t len = _start_dir.size() + 9; |
62 | WCHAR wstart[len]; | |
63 | mklongpath (wstart, _start_dir.c_str (), len); | |
64 | wcscat (wstart, L"\\*"); | |
65 | ||
66 | h = FindFirstFileW (wstart, &w_wfd); | |
23c9e63c DD |
67 | |
68 | if (h == INVALID_HANDLE_VALUE) | |
b401ef47 RC |
69 | return; |
70 | ||
b24c88b3 RC |
71 | do |
72 | { | |
7cc4d95e CV |
73 | if (wcscmp (w_wfd.cFileName, L".") == 0 |
74 | || wcscmp (w_wfd.cFileName, L"..") == 0) | |
b24c88b3 | 75 | continue; |
23c9e63c | 76 | |
b401ef47 RC |
77 | /* TODO: make a non-win32 file and dir info class and have that as the |
78 | * visited node | |
79 | */ | |
7cc4d95e CV |
80 | WIN32_FIND_DATAA wfd; |
81 | memcpy (&wfd, &w_wfd, sizeof (wfd)); | |
82 | WideCharToMultiByte (CP_UTF8, 0, w_wfd.cFileName, MAX_PATH, | |
83 | wfd.cFileName, MAX_PATH, NULL, NULL); | |
b24c88b3 | 84 | if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
9d0dd17b | 85 | aVisitor.visitDirectory (_start_dir, &wfd, level); |
b24c88b3 | 86 | else |
feee2f2b | 87 | aVisitor.visitFile (_start_dir, &wfd); |
b24c88b3 | 88 | } |
7cc4d95e | 89 | while (FindNextFileW (h, &w_wfd)); |
23c9e63c | 90 | } |