Translated using Weblate (Chinese (Simplified))
[cygwin-setup.git] / find.cc
blob9d4f6278155418c7ed155ee0770a875af8119675
1 /*
2 * Copyright (c) 2002, Robert Collins.
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.
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
12 * Written by DJ Delorie <dj@cygnus.com>
13 * Rewritten by Robert Collins <rbtcollins@hotmail.com>
17 /* The purpose of this file is to doa recursive find on a given
18 directory, calling a given function for each file found. */
20 #include "win32.h"
21 #include "filemanip.h"
22 #include "find.h"
24 #include "FindVisitor.h"
25 #include <stdexcept>
27 Find::Find(const std::string& starting_dir)
28 : h(INVALID_HANDLE_VALUE)
30 _start_dir = starting_dir;
31 int l = _start_dir.size ();
33 /* Ensure that _start_dir has a trailing slash if it doesn't already. */
34 if (l < 1 || (starting_dir[l - 1] != '/' && starting_dir[l - 1] != '\\'))
35 _start_dir += '/';
38 Find::~Find()
40 if (h != INVALID_HANDLE_VALUE && h)
41 FindClose (h);
44 void
45 Find::accept (FindVisitor &aVisitor, int level)
47 /* The usage of multibyte strings within setup is so entangled into
48 the various C++ classes, it's very hard to disentangle it and use
49 UNICODE strings throughout without ripping everything apart.
50 On the other hand, we want to support paths > MAX_PATH, but this is
51 only supported by the UNICODE API.
52 What you see here is nothing less than a hack. We get the string
53 as a multibyte string, convert it, call the UNICODE FindFile functions,
54 then convert the returned structure back to multibyte to call the
55 visitor methods, which in turn call other methods expecting multibyte
56 strings. */
57 WIN32_FIND_DATAW w_wfd;
59 size_t len = _start_dir.size() + 9;
60 WCHAR wstart[len];
61 mklongpath (wstart, _start_dir.c_str (), len);
62 wcscat (wstart, L"\\*");
64 h = FindFirstFileW (wstart, &w_wfd);
66 if (h == INVALID_HANDLE_VALUE)
67 return;
71 if (wcscmp (w_wfd.cFileName, L".") == 0
72 || wcscmp (w_wfd.cFileName, L"..") == 0)
73 continue;
75 /* TODO: make a non-win32 file and dir info class and have that as the
76 * visited node
78 WIN32_FIND_DATAA wfd;
79 memcpy (&wfd, &w_wfd, sizeof (wfd));
80 WideCharToMultiByte (CP_UTF8, 0, w_wfd.cFileName, MAX_PATH,
81 wfd.cFileName, MAX_PATH, NULL, NULL);
82 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
83 aVisitor.visitDirectory (_start_dir, &wfd, level);
84 else
85 aVisitor.visitFile (_start_dir, &wfd);
87 while (FindNextFileW (h, &w_wfd));