tree.cxx

Go to the documentation of this file.
00001 //
00002 // Copyright 2004, Lowell Boggs Jr.
00003 //
00004 // This file or directory, containing source code for a computer program,
00005 // is Copyrighted by Lowell Boggs, Jr.  987 Regency Drive, Lewisville
00006 // TX (USA), 75067.  You may use, copy, modify, and distribute this
00007 // source file without charge or obligation so long as you agree to
00008 // the following:
00009 //
00010 //  1.  You must indemnify Lowell Boggs against any and all financial
00011 //      obligations caused by its use, misuse, function, or malfunction.
00012 //      Further, you acknowledge that there is no warranty of any kind,
00013 //      whatsoever.
00014 //
00015 //  2.  You agree not to attempt to patent any portion of this original
00016 //      work -- though you may attempt to patent your own extensions to
00017 //      it if you so choose.
00018 //
00019 //  3.  You keep this copyright notice with the file and all copies
00020 //      of the file and do not change it anyway except language translation.
00021 //
00022 // You are responsible for enforcing your own compliance with these
00023 // conditions and may not use this source file if you cannot agree to the
00024 // above terms and conditions.
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       // compare the current file name against all ignore patterns
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       // compare the current file name against all required patterns
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 }
Generated on Wed Feb 29 22:50:03 2012 for CXXUtilities by  doxygen 1.6.3