feisty meow concerns codebase  2.140
dirtree.cpp
Go to the documentation of this file.
1 /*
2 * Name : dirtree
3 * Author : Chris Koeritz
4 * Purpose:
5 * A utility that shows the directory tree specified on the command line.
6 
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
13 */
14 
16 #include <basis/guards.h>
18 #include <filesystem/filename.h>
19 #include <loggers/console_logger.h>
23 
24 using namespace application;
25 using namespace basis;
26 using namespace filesystem;
27 using namespace loggers;
28 using namespace structures;
29 using namespace textual;
30 
31 #define LOG(to_print) EMERGENCY_LOG(program_wide_logger::get(), to_print)
32 
33 class dirtree : public application_shell
34 {
35 public:
36  dirtree() : application_shell() {}
37  DEFINE_CLASS_NAME("dirtree");
38  int execute();
40  LOG(a_sprintf("\
41 %s: This utility shows the sub-directory structure for a chosen directory.\n\
42 It expects a directory name to be provided on the command line. If no\n\
43 directory is provided, then the current directory is assumed. The sub-\n\
44 directories under the chosen directory will be displayed on the console in a\n\
45 stylized textual tree. If a second parameter is provided, it is taken as a\n\
46 file pattern that causes matching files to be displayed. Without a pattern,\n\
47 just the directory tree is shown.\n\
48 For example:\n\
49  dirtree\n\
50  => shows the directory structure of the current directory.\n\
51  dirtree udon\n\
52  => shows the structure of directory 'udon'\n\
53  dirtree soba \"*.txt\"\n\
54  => displays all text files and sub-directories of 'soba'\n\
55 ", filename(application::_global_argv[0]).basename().raw().s()));
56  return 23;
57  }
58 };
59 
60 astring hier_prefix(int depth, int kids)
61 {
62  astring indent = string_manipulation::indentation( (depth - 1) * 2);
63  if (!depth) return "";
64  else if (!kids) return indent + "|--";
65  else return indent + "+--";
66 }
67 
68 int dirtree::execute()
69 {
70  astring path;
71 
72 //hmmm: we really need an abstraction to do some checking if they want --help;
73 // this comparison way of doing it is lame.
74 astring helpword = astring("--help");
75 
76  if (application::_global_argc <= 1) {
77  // plug in our default path if they gave us no parameters.
78  path = ".";
79  } else {
80  // they gave us some parameters. but are they asking for help?
81  if (helpword == astring(application::_global_argv[1])) {
83  } else {
84  // this seems like a serious path request.
86  }
87  }
88 
89  // check if we should show any of the files.
90  bool show_files = false;
91  astring pattern;
92  if (application::_global_argc >= 3) {
93  pattern = application::_global_argv[2];
94  }
95  if (pattern.t()) {
96  show_files = true;
97  }
98 
99 // log(astring("Scanning directory tree at \"") + path + "\"");
100 // log(astring("Using pattern-match \"") + pattern + "\"");
101 
102  directory_tree dir(path, pattern.s(), !show_files);
103  if (!dir.good()) {
104  continuable_error(class_name(), "tree construction",
105  "the directory could not be read");
107  }
108 
109  dir_tree_iterator *ted = dir.start(directory_tree::prefix);
110  // create our iterator to traverse the tree in prefix order.
111 
112  filename curr; // the current path the iterator is at.
113  string_array files; // the filenames held at the iterator.
114  int depth; // current depth in tree.
115  int kids; // number of children below this node.
116 
117  while (directory_tree::current(*ted, curr, files)) {
118  // we have a good directory to show.
119  directory_tree::depth(*ted, depth);
120  directory_tree::children(*ted, kids);
121  astring name_to_log = curr.basename().raw();
122  if (!depth) {
123  name_to_log = curr.raw();
124  }
125  LOG(hier_prefix(depth, kids) + name_to_log);
126  if (show_files) {
127  astring names;
128  for (int i = 0; i < files.length(); i++) names += files[i] + " ";
129  if (names.length()) {
130  astring split;
131  string_manipulation::split_lines(names, split, depth * 2 + 2);
132  // strip eol chars off the string we got back, since we already add that in log.
133  while (parser_bits::is_eol(split[split.end()])) {
134  split.zap(split.end(), split.end());
135  }
136  LOG(split);
137  }
138  }
139 
140  // go to the next place.
141  directory_tree::next(*ted);
142  }
143 
144  directory_tree::throw_out(ted);
145  return 0;
146 }
147 
148 HOOPLE_MAIN(dirtree, )
149 
150 #ifdef __BUILD_STATIC_APPLICATION__
151  // static dependencies found by buildor_gen_deps.sh:
155  #include <basis/astring.cpp>
156  #include <basis/common_outcomes.cpp>
157  #include <basis/environment.cpp>
158  #include <basis/guards.cpp>
159  #include <basis/mutex.cpp>
160  #include <basis/utf_conversion.cpp>
167  #include <filesystem/byte_filer.cpp>
168  #include <filesystem/directory.cpp>
170  #include <filesystem/file_info.cpp>
171  #include <filesystem/file_time.cpp>
172  #include <filesystem/filename.cpp>
175  #include <filesystem/huge_file.cpp>
176  #include <loggers/combo_logger.cpp>
177  #include <loggers/console_logger.cpp>
178  #include <loggers/critical_events.cpp>
179  #include <loggers/file_logger.cpp>
181  #include <nodes/node.cpp>
182  #include <nodes/packable_tree.cpp>
183  #include <nodes/path.cpp>
184  #include <nodes/tree.cpp>
185  #include <structures/bit_vector.cpp>
186  #include <structures/checksums.cpp>
190  #include <structures/string_table.cpp>
192  #include <textual/byte_formatter.cpp>
193  #include <textual/parser_bits.cpp>
195  #include <timely/earth_time.cpp>
196  #include <timely/time_stamp.cpp>
197 #endif // __BUILD_STATIC_APPLICATION__
198 
int print_instructions_and_exit(char *program_name)
Definition: bytedump.cpp:42
The application_shell is a base object for console programs.
a_sprintf is a specialization of astring that provides printf style support.
Definition: astring.h:440
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
Definition: astring.h:113
bool t() const
t() is a shortcut for the string being "true", as in non-empty.
Definition: astring.h:97
virtual void zap(int start, int end)
Deletes the characters between "start" and "end" inclusively.
Definition: astring.cpp:521
int end() const
returns the index of the last (non-null) character in the string.
Definition: astring.h:86
int length() const
Returns the current length of the string.
Definition: astring.cpp:132
An object that traverses directory trees and provides a view of all files.
Provides operations commonly needed on file names.
Definition: filename.h:64
const basis::astring & raw() const
returns the astring that we're holding onto for the path.
Definition: filename.cpp:97
filename basename() const
returns the base of the filename; no directory.
Definition: filename.cpp:385
An array of strings with some additional helpful methods.
Definition: string_array.h:32
#define continuable_error(c, f, i)
#define LOG(to_print)
Definition: dirtree.cpp:31
astring hier_prefix(int depth, int kids)
Definition: dirtree.cpp:60
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
Definition: enhance_cpp.h:45
Provides macros that implement the 'main' program of an application.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
Definition: hoople_main.h:61
Implements an application lock to ensure only one is running at once.
char ** _global_argv
The guards collection helps in testing preconditions and reporting errors.
Definition: array.h:30
list files
Definition: eml_to_txt.py:157
string path
Definition: eml_to_txt.py:139
A platform independent way to obtain the timestamp of a file.
Definition: byte_filer.cpp:37
A logger that sends to the console screen using the standard output device.
None split_lines(str unsplit_line)
A dynamic container class that holds any kind of object via pointers.
Definition: amorph.h:55
bool is_eol(char to_check)