3 * Author : Chris Koeritz
5 * A utility that shows the directory tree specified on the command line.
7 * Copyright (c) 2004-$now By Author. This program is free software; you can
8 * redistribute it and/or modify it under the terms of the GNU General Public
9 * License as published by the Free Software Foundation; either version 2 of
10 * the License or (at your option) any later version. This is online at:
11 * http://www.fsf.org/copyleft/gpl.html
12 * Please send any updates to: fred@gruntose.com
15 #include <application/hoople_main.h>
16 #include <basis/guards.h>
17 #include <filesystem/directory_tree.h>
18 #include <filesystem/filename.h>
19 #include <loggers/console_logger.h>
20 #include <structures/static_memory_gremlin.h>
21 #include <structures/string_array.h>
22 #include <textual/string_manipulation.h>
24 using namespace application;
25 using namespace basis;
26 using namespace filesystem;
27 using namespace loggers;
28 using namespace structures;
29 using namespace textual;
31 #define LOG(to_print) EMERGENCY_LOG(program_wide_logger::get(), to_print)
33 class dirtree : public application_shell
36 dirtree() : application_shell() {}
37 DEFINE_CLASS_NAME("dirtree");
39 int print_instructions_and_exit() {
41 %s: This utility requires a directory name on the command line.\n\
42 The subdirectories under that directory will be shown. If a second paramter\n\
43 is provided, it is taken as a pattern that will be used to show the files in\n\
44 those directories also. Otherwise, just the tree of directories is shown.\n\
45 ", filename(application::_global_argv[0]).basename().raw().s()));
50 astring hier_prefix(int depth, int kids)
52 astring indent = string_manipulation::indentation( (depth - 1) * 2);
53 if (!depth) return "";
54 else if (!kids) return indent + "|--";
55 else return indent + "+--";
58 int dirtree::execute()
64 if (application::_global_argc < 2) {
65 return print_instructions_and_exit();
68 path = application::_global_argv[1];
70 // check if we should show any of the files.
71 bool show_files = false;
73 if (application::_global_argc >= 3)
74 pattern = application::_global_argv[2];
79 // log(astring("Scanning directory tree at \"") + path + "\"");
80 // log(astring("Using pattern-match \"") + pattern + "\"");
82 directory_tree dir(path, pattern.s(), !show_files);
84 continuable_error(class_name(), "tree construction",
85 "the directory could not be read");
89 dir_tree_iterator *ted = dir.start(directory_tree::prefix);
90 // create our iterator to traverse the tree in prefix order.
92 filename curr; // the current path the iterator is at.
93 string_array files; // the filenames held at the iterator.
94 int depth; // current depth in tree.
95 int kids; // number of children below this node.
97 while (directory_tree::current(*ted, curr, files)) {
98 // we have a good directory to show.
99 directory_tree::depth(*ted, depth);
100 directory_tree::children(*ted, kids);
101 astring name_to_log = curr.basename().raw();
103 name_to_log = curr.raw();
104 LOG(hier_prefix(depth, kids) + name_to_log);
107 for (int i = 0; i < files.length(); i++) names += files[i] + " ";
108 if (names.length()) {
110 string_manipulation::split_lines(names, split, depth * 2 + 2);
115 // go to the next place.
116 directory_tree::next(*ted);
119 directory_tree::throw_out(ted);
123 HOOPLE_MAIN(dirtree, )
125 #ifdef __BUILD_STATIC_APPLICATION__
126 // static dependencies found by buildor_gen_deps.sh:
127 #include <application/application_shell.cpp>
128 #include <application/command_line.cpp>
129 #include <application/windoze_helper.cpp>
130 #include <basis/astring.cpp>
131 #include <basis/common_outcomes.cpp>
132 #include <basis/environment.cpp>
133 #include <basis/guards.cpp>
134 #include <basis/mutex.cpp>
135 #include <basis/utf_conversion.cpp>
136 #include <configuration/application_configuration.cpp>
137 #include <configuration/configurator.cpp>
138 #include <configuration/ini_configurator.cpp>
139 #include <configuration/ini_parser.cpp>
140 #include <configuration/table_configurator.cpp>
141 #include <configuration/variable_tokenizer.cpp>
142 #include <filesystem/byte_filer.cpp>
143 #include <filesystem/directory.cpp>
144 #include <filesystem/directory_tree.cpp>
145 #include <filesystem/file_info.cpp>
146 #include <filesystem/file_time.cpp>
147 #include <filesystem/filename.cpp>
148 #include <filesystem/filename_list.cpp>
149 #include <filesystem/filename_tree.cpp>
150 #include <filesystem/huge_file.cpp>
151 #include <loggers/combo_logger.cpp>
152 #include <loggers/console_logger.cpp>
153 #include <loggers/critical_events.cpp>
154 #include <loggers/file_logger.cpp>
155 #include <loggers/program_wide_logger.cpp>
156 #include <nodes/node.cpp>
157 #include <nodes/packable_tree.cpp>
158 #include <nodes/path.cpp>
159 #include <nodes/tree.cpp>
160 #include <structures/bit_vector.cpp>
161 #include <structures/checksums.cpp>
162 #include <structures/object_packers.cpp>
163 #include <structures/static_memory_gremlin.cpp>
164 #include <structures/string_hasher.cpp>
165 #include <structures/string_table.cpp>
166 #include <structures/version_record.cpp>
167 #include <textual/byte_formatter.cpp>
168 #include <textual/parser_bits.cpp>
169 #include <textual/string_manipulation.cpp>
170 #include <timely/earth_time.cpp>
171 #include <timely/time_stamp.cpp>
172 #endif // __BUILD_STATIC_APPLICATION__