]> cygwin.com Git - cygwin-apps/setup.git/blob - find.cc
Use solver to check for problems and produce a list of package transactions
[cygwin-apps/setup.git] / find.cc
1 /*
2 * Copyright (c) 2002, Robert Collins.
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>
13 * Rewritten by Robert Collins <rbtcollins@hotmail.com>
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
20 #include "win32.h"
21 #include "filemanip.h"
22 #include "find.h"
23
24 #include "FindVisitor.h"
25 #include <stdexcept>
26
27 using namespace std;
28
29 Find::Find(const std::string& starting_dir)
30 : h(INVALID_HANDLE_VALUE)
31 {
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 += '/';
38 }
39
40 Find::~Find()
41 {
42 if (h != INVALID_HANDLE_VALUE && h)
43 FindClose (h);
44 }
45
46 void
47 Find::accept (FindVisitor &aVisitor, int level)
48 {
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;
60
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);
67
68 if (h == INVALID_HANDLE_VALUE)
69 return;
70
71 do
72 {
73 if (wcscmp (w_wfd.cFileName, L".") == 0
74 || wcscmp (w_wfd.cFileName, L"..") == 0)
75 continue;
76
77 /* TODO: make a non-win32 file and dir info class and have that as the
78 * visited node
79 */
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);
84 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
85 aVisitor.visitDirectory (_start_dir, &wfd, level);
86 else
87 aVisitor.visitFile (_start_dir, &wfd);
88 }
89 while (FindNextFileW (h, &w_wfd));
90 }
This page took 0.03829 seconds and 5 git commands to generate.