GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
file_tree.cpp
[詳解]
1
3
4// Copyright(c) 2023-2025 Design Engineering Laboratory, Saitama University
5// Released under the MIT license
6// https://opensource.org/licenses/mit-license.php
7
8#include "file_tree.h"
9
10#include <filesystem>
11
12#include "cassert_define.h"
13#include "cmdio_util.h"
14
15
16namespace designlab
17{
18
19void FileTree::DisplayFileTree(const std::string& path, int max_depth) const
20{
21 FileTreeData tree = MakeFileTree(path, max_depth, "", "sim");
22
23 int count = 0;
24 OutputFileTree(tree, 0, true, &count);
25}
26
27bool FileTree::SelectFile(const std::string& path, int max_depth,
28 const std::string& extension, const std::string keyword,
29 std::string* output) const
30{
31 assert(output != nullptr);
32
33 // ファイルツリーを作成
34 FileTreeData tree = MakeFileTree(path, max_depth, extension, keyword);
35
36 // ファイルツリーを表示
38
39 int count = 0;
40 OutputFileTree(tree, 0, true, &count);
44
45 // ファイルを選択
46 std::vector<std::string> file_list = MakeFileList(tree);
47
48 if (file_list.empty())
49 {
50 CmdIOUtil::Output("The file did not exist.", OutputDetail::kSystem);
51 return false;
52 }
53
54 while (true)
55 {
56 int select_index =
57 CmdIOUtil::InputInt(0, static_cast<int>(file_list.size()) - 1, 0,
58 "Please select a file. Enter an integer.");
59
61 CmdIOUtil::Output("The selected file is " + file_list[static_cast<size_t>(select_index)],
63
64 if (CmdIOUtil::InputYesNo("Are you sure?"))
65 {
66 *output = file_list[static_cast<size_t>(select_index)];
67 break;
68 }
69
71 }
72
73 return true;
74}
75
76FileTree::FileTreeData FileTree::MakeFileTree(const std::string& path, int max_depth,
77 const std::string& extension,
78 const std::string keyword) const
79{
80 FileTreeData tree;
81
82 tree.path = path;
83
84 assert(std::filesystem::exists(tree.path));
85
86 for (const auto& entry : std::filesystem::directory_iterator(path))
87 {
88 if (entry.is_directory())
89 {
90 // ディレクトリの場合、再帰的にファイルツリーを作成
91 if (max_depth == 0)
92 {
93 tree.directory.push_back(
94 FileTreeData{ entry.path().string(), {}, {} });
95 }
96 else
97 {
98 tree.directory.push_back(
99 MakeFileTree(entry.path().string(), max_depth - 1, extension, keyword));
100 }
101 }
102 else if (entry.is_regular_file())
103 {
104 // ファイルの場合、ファイル名を追加
105
106 if (!extension.empty())
107 {
108 if (!(entry.path().extension().string() == extension ||
109 entry.path().extension().string() == "." + extension))
110 {
111 continue;
112 }
113 }
114
115 if (!keyword.empty())
116 {
117 if (entry.path().filename().string().find(keyword) == std::string::npos)
118 {
119 continue;
120 }
121 }
122
123 tree.file.push_back(entry.path().filename().string());
124 }
125 }
126
127 return tree;
128}
129
130void FileTree::OutputFileTree(const FileTreeData& tree, int depth,
131 bool not_display_empty, int* file_count) const
132{
133 assert(file_count != nullptr);
134
135 std::string indent = "";
136 for (int i = 0; i < depth; ++i)
137 {
138 indent += "| ";
139 }
140
141 // 空 かつ 空のディレクトリを表示しない設定 でないならば表示する
142 if (!(not_display_empty && tree.file.empty() && tree.directory.empty()))
143 {
144 // ディレクトリ名を出力する際に,パスの階層を削除する
145
147
148 std::string::size_type pos = tree.path.find_last_of("/\\");
149 std::string dir_name = ((depth == 0) ? "" : "- ");
150 dir_name += std::string("[ ") + tree.path.substr(pos + 1) + std::string(" ]");
151
152 CmdIOUtil::Output(indent + dir_name, OutputDetail::kSystem);
153 }
154
155 for (const auto& directory : tree.directory)
156 {
157 OutputFileTree(directory, depth + 1, not_display_empty, file_count);
158 }
159
160 if (!tree.file.empty())
161 {
163
164 for (const auto& file : tree.file)
165 {
166 CmdIOUtil::Output(indent + "|- " + file + " [-" + std::to_string(*file_count) + "-]",
168
169 (*file_count)++;
170 }
171 }
172}
173
174std::vector<std::string> FileTree::MakeFileList(const FileTreeData& tree) const
175{
176 std::vector<std::string> file_list;
177
178 for (const auto& directory : tree.directory)
179 {
180 std::vector<std::string> tmp = MakeFileList(directory);
181
182 file_list.insert(file_list.end(), tmp.begin(), tmp.end());
183 }
184
185 for (const auto& file : tree.file)
186 {
187 file_list.push_back(tree.path + "\\" + file);
188 }
189
190 return file_list;
191}
192
193} // namespace designlab
static void Output(const std::string &str, OutputDetail detail)
コマンドラインに文字を出力する関数. SetOutputLimit() で設定した出力の許可範囲内であれば出力される. 必ず SetOutputLimit() を呼び出してから使うこと.
static int InputInt(int min, int max, int default_num, const std::string &str="Please enter an integer.")
整数を入力させる関数. 出力される文字列は,必ず OutputDetail::kSystem で出力される.
static void OutputNewLine(int num, OutputDetail detail)
コマンドラインで改行をする関数.
static void OutputHorizontalLine(const std::string &line_visual, OutputDetail detail)
コマンドラインに水平線を出力する関数.
static bool InputYesNo(const std::string &str="Are you sure?")
yesかnoを入力させる関数.返り値で yes なら true,noなら falseを返す. 出力される文字列は,必ず OutputDetail::kSystem で出力される.
void DisplayFileTree(const std::string &path, int max_depth) const
ファイルツリーを表示する.
Definition file_tree.cpp:19
bool SelectFile(const std::string &path, int max_depth, const std::string &extension, const std::string keyword, std::string *output) const
ディレクトリの中から,ファイルを一つ選択する.
Definition file_tree.cpp:27
@ kSystem
システムメッセージ,常に出力する.
Definition com_type.h:24