tree.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00032
00033 #include <cxxtls/file.h>
00034 #include <iostream>
00035 #include <iomanip>
00036 #include <cxxtls/options.h>
00037 #include <set>
00038
00039 extern "C"
00040 {
00041 #include <fnmatch.h>
00042 };
00043
00044
00045 using namespace std;
00046 using namespace cxxtls;
00047
00048 typedef FileName::Tree Tree;
00049 typedef std::auto_ptr<Tree> TreePtr;
00050 typedef Tree::children_t::const_iterator const_iterator;
00051 typedef Tree::children_t::iterator iterator;
00052
00053 bool include_attributes=false;
00054 bool include_time=false;
00055 bool include_size=false;
00056
00057 set<string> ignored_names;
00058 set<string> name_filters;
00059
00060 void print_children(Tree const* p, string prefix)
00061 {
00062 const_iterator f=p->children().begin(), l = p->children().end();
00063
00064 while(f != l)
00065 {
00066 Tree const *child = *f++;
00067
00068
00069 {
00070
00071
00072 set<string>::const_iterator a, b;
00073
00074 bool match=false;
00075
00076 for(a = ignored_names.begin(), b = ignored_names.end(); a != b; ++a)
00077 {
00078 if(0 == fnmatch(const_cast<char*>(a->c_str()),
00079 const_cast<char*>(child->name().c_str()),
00080 1) )
00081 {
00082 match=true;
00083 break;
00084 }
00085 }
00086
00087 if(match)
00088 continue;
00089
00090 }
00091
00092 if(!child->status().mode.is_dir())
00093 {
00094
00095
00096 set<string>::const_iterator a, b;
00097
00098 bool match=false;
00099
00100 for(a = name_filters.begin(), b = name_filters.end(); a != b; ++a)
00101 {
00102 if(0 != fnmatch(const_cast<char*>(a->c_str()),
00103 const_cast<char*>(child->name().c_str()),
00104 1) )
00105 {
00106 match=true;
00107 break;
00108 }
00109 }
00110
00111 if(match)
00112 continue;
00113
00114 }
00115
00116
00117
00118 bool is_last = (f==l);
00119
00120 char c = is_last ? '`' : '|';
00121
00122 if(include_attributes)
00123 cout << child->status().mode << " ";
00124
00125 if(include_time)
00126 cout << child->status().time << " ";
00127
00128 if(include_size)
00129 cout << setw(8) << child->status().size << " ";
00130
00131 cout << prefix << c << "-- " << child->name() << endl;
00132
00133 string new_prefix = prefix;
00134
00135 if(is_last)
00136 new_prefix += " ";
00137 else
00138 new_prefix += "| ";
00139
00140
00141 print_children(child, new_prefix);
00142
00143 }
00144
00145
00146 }
00147
00148
00149 int main(int argc, char **argv, char **environ)
00150 {
00151
00152 ProgramOptions options("-d,-h,-a,-t,-s,-i;-p;", argc, argv, environ);
00153
00154 if(options.option("-h"))
00155 {
00156 cout << "tree.exe: Output a directory tree either starting with the\n"
00157 << " current directory or with a named directory.\n"
00158 << "\n"
00159 << "Usage:\n"
00160 << "\n"
00161 << " tree.exe [options] [directory_name]\n"
00162 << "\n"
00163 << "Options:\n"
00164 << " -h: produce this help message\n"
00165 << " -d: show only directories in the output\n"
00166 << " -a: include file attributes\n"
00167 << " -t: include file modification time\n"
00168 << " -s: include file size\n"
00169 << " -i pattern: ignore files/dirs with this filename pattern\n"
00170 << " -p pattern: only show files named 'n'\n"
00171 << endl;
00172 return 0;
00173 }
00174
00175 if(options.option("-a"))
00176 include_attributes=true;
00177
00178 string dirp=".";
00179
00180 if(options.argv.size() > 1)
00181 dirp = options.argv[1];
00182
00183 bool only_dirs = false;
00184
00185 if(options.option("-d"))
00186 only_dirs = true;
00187
00188 if(options.option("-t"))
00189 include_time = true;
00190
00191 if(options.option("-a"))
00192 include_attributes = true;
00193
00194 if(options.option("-s"))
00195 include_size = true;
00196
00197 if(options.option("-i"))
00198 {
00199 ProgramOptions::value_iterator f, l;
00200
00201 f = options.option("-i").begin();
00202 l = options.option("-i").end();
00203
00204 while(f !=l)
00205 {
00206 ignored_names.insert(*f);
00207 ++f;
00208 }
00209
00210
00211 }
00212
00213 if(options.option("-p"))
00214 {
00215 ProgramOptions::value_iterator f, l;
00216
00217 f = options.option("-p").begin();
00218 l = options.option("-p").end();
00219
00220 while(f !=l)
00221 {
00222 name_filters.insert(*f);
00223 ++f;
00224 }
00225
00226
00227 }
00228
00229
00230 FileName dir(dirp);
00231
00232 TreePtr tree(dir.tree(only_dirs));
00233
00234 cout << tree->name() << endl;
00235
00236 print_children(tree.get(), "");
00237
00238
00239 }