Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

pandatool/src/cvscopy/cvsSourceDirectory.cxx

Go to the documentation of this file.
00001 // Filename: cvsSourceDirectory.cxx
00002 // Created by:  drose (31Oct00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "cvsSourceDirectory.h"
00020 #include "cvsSourceTree.h"
00021 
00022 #include <notify.h>
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function: CVSSourceDirectory::Constructor
00026 //       Access: Public
00027 //  Description:
00028 ////////////////////////////////////////////////////////////////////
00029 CVSSourceDirectory::
00030 CVSSourceDirectory(CVSSourceTree *tree, CVSSourceDirectory *parent,
00031                    const string &dirname) :
00032   _tree(tree),
00033   _parent(parent),
00034   _dirname(dirname)
00035 {
00036   if (_parent == (CVSSourceDirectory *)NULL) {
00037     _depth = 0;
00038   } else {
00039     _depth = _parent->_depth + 1;
00040   }
00041 }
00042 
00043 ////////////////////////////////////////////////////////////////////
00044 //     Function: CVSSourceDirectory::Destructor
00045 //       Access: Public
00046 //  Description:
00047 ////////////////////////////////////////////////////////////////////
00048 CVSSourceDirectory::
00049 ~CVSSourceDirectory() {
00050   Children::iterator ci;
00051   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00052     delete (*ci);
00053   }
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: CVSSourceDirectory::get_dirname
00058 //       Access: Public
00059 //  Description: Returns the local name of this particular directory.
00060 ////////////////////////////////////////////////////////////////////
00061 string CVSSourceDirectory::
00062 get_dirname() const {
00063   return _dirname;
00064 }
00065 
00066 ////////////////////////////////////////////////////////////////////
00067 //     Function: CVSSourceDirectory::get_fullpath
00068 //       Access: Public
00069 //  Description: Returns the full pathname to this particular
00070 //               directory.
00071 ////////////////////////////////////////////////////////////////////
00072 string CVSSourceDirectory::
00073 get_fullpath() const {
00074   if (_parent == (CVSSourceDirectory *)NULL) {
00075     return _tree->get_root_fullpath();
00076   }
00077   return _parent->get_fullpath() + "/" + _dirname;
00078 }
00079 
00080 ////////////////////////////////////////////////////////////////////
00081 //     Function: CVSSourceDirectory::get_path
00082 //       Access: Public
00083 //  Description: Returns the relative pathname to this particular
00084 //               directory, as seen from the root of the tree.
00085 ////////////////////////////////////////////////////////////////////
00086 string CVSSourceDirectory::
00087 get_path() const {
00088   if (_parent == (CVSSourceDirectory *)NULL) {
00089     return _dirname;
00090   }
00091   return _parent->get_path() + "/" + _dirname;
00092 }
00093 
00094 ////////////////////////////////////////////////////////////////////
00095 //     Function: CVSSourceDirectory::get_rel_to
00096 //       Access: Public
00097 //  Description: Returns the relative path to the other directory from
00098 //               this one.  This does not include a trailing slash.
00099 ////////////////////////////////////////////////////////////////////
00100 string CVSSourceDirectory::
00101 get_rel_to(const CVSSourceDirectory *other) const {
00102   const CVSSourceDirectory *a = this;
00103   const CVSSourceDirectory *b = other;
00104 
00105   if (a == b) {
00106     return ".";
00107   }
00108 
00109   string prefix, postfix;
00110   while (a->_depth > b->_depth) {
00111     prefix += "../";
00112     a = a->_parent;
00113     nassertr(a != (CVSSourceDirectory *)NULL, string());
00114   }
00115 
00116   while (b->_depth > a->_depth) {
00117     postfix = b->_dirname + "/" + postfix;
00118     b = b->_parent;
00119     nassertr(b != (CVSSourceDirectory *)NULL, string());
00120   }
00121 
00122   while (a != b) {
00123     prefix += "../";
00124     postfix = b->_dirname + "/" + postfix;
00125     a = a->_parent;
00126     b = b->_parent;
00127     nassertr(a != (CVSSourceDirectory *)NULL, string());
00128     nassertr(b != (CVSSourceDirectory *)NULL, string());
00129   }
00130 
00131   string result = prefix + postfix;
00132   nassertr(!result.empty(), string());
00133   return result.substr(0, result.length() - 1);
00134 }
00135 
00136 ////////////////////////////////////////////////////////////////////
00137 //     Function: CVSSourceDirectory::get_num_children
00138 //       Access: Public
00139 //  Description: Returns the number of subdirectories below this
00140 //               directory.
00141 ////////////////////////////////////////////////////////////////////
00142 int CVSSourceDirectory::
00143 get_num_children() const {
00144   return _children.size();
00145 }
00146 
00147 ////////////////////////////////////////////////////////////////////
00148 //     Function: CVSSourceDirectory::get_child
00149 //       Access: Public
00150 //  Description: Returns the nth subdirectory below this directory.
00151 ////////////////////////////////////////////////////////////////////
00152 CVSSourceDirectory *CVSSourceDirectory::
00153 get_child(int n) const {
00154   nassertr(n >= 0 && n < (int)_children.size(), NULL);
00155   return _children[n];
00156 }
00157 
00158 ////////////////////////////////////////////////////////////////////
00159 //     Function: CVSSourceDirectory::find_relpath
00160 //       Access: Public
00161 //  Description: Returns the source directory that corresponds to the
00162 //               given relative path from this directory, or NULL if
00163 //               there is no match.
00164 ////////////////////////////////////////////////////////////////////
00165 CVSSourceDirectory *CVSSourceDirectory::
00166 find_relpath(const string &relpath) {
00167   if (relpath.empty()) {
00168     return this;
00169   }
00170 
00171   size_t slash = relpath.find('/');
00172   string first = relpath.substr(0, slash);
00173   string rest;
00174   if (slash != string::npos) {
00175     rest = relpath.substr(slash + 1);
00176   }
00177 
00178   if (first.empty() || first == ".") {
00179     return find_relpath(rest);
00180 
00181   } else if (first == "..") {
00182     if (_parent != NULL) {
00183       return _parent->find_relpath(rest);
00184     }
00185     // Tried to back out past the root directory.
00186     return (CVSSourceDirectory *)NULL;
00187   }
00188 
00189   // Check for a child with the name indicated by first.
00190   Children::const_iterator ci;
00191   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00192     if ((*ci)->get_dirname() == first) {
00193       return (*ci)->find_relpath(rest);
00194     }
00195   }
00196 
00197   // No match.
00198   return (CVSSourceDirectory *)NULL;
00199 }
00200 
00201 ////////////////////////////////////////////////////////////////////
00202 //     Function: CVSSourceDirectory::find_dirname
00203 //       Access: Public
00204 //  Description: Returns the source directory that corresponds to the
00205 //               given local directory name, or NULL if there is no
00206 //               match.
00207 ////////////////////////////////////////////////////////////////////
00208 CVSSourceDirectory *CVSSourceDirectory::
00209 find_dirname(const string &dirname) {
00210   if (dirname == _dirname) {
00211     return this;
00212   }
00213 
00214   Children::const_iterator ci;
00215   for (ci = _children.begin(); ci != _children.end(); ++ci) {
00216     CVSSourceDirectory *result = (*ci)->find_dirname(dirname);
00217     if (result != (CVSSourceDirectory *)NULL) {
00218       return result;
00219     }
00220   }
00221 
00222   return (CVSSourceDirectory *)NULL;
00223 }
00224 
00225 ////////////////////////////////////////////////////////////////////
00226 //     Function: CVSSourceDirectory::scan
00227 //       Access: Public
00228 //  Description: Recursively scans the contents of the source
00229 //               directory.  Fullpath is the full path name to the
00230 //               directory; key_filename is the name of a file that
00231 //               must exist in each subdirectory for it to be
00232 //               considered part of the hierarchy.  Returns true on
00233 //               success, false on failure.
00234 ////////////////////////////////////////////////////////////////////
00235 bool CVSSourceDirectory::
00236 scan(const Filename &directory, const string &key_filename) {
00237   vector_string contents;
00238   if (!directory.scan_directory(contents)) {
00239     nout << "Unable to scan directory " << directory << "\n";
00240     return false;
00241   }
00242 
00243   vector_string::const_iterator fi;
00244   for (fi = contents.begin(); fi != contents.end(); ++fi) {
00245     const string &filename = (*fi);
00246 
00247     // Is this possibly a subdirectory name?
00248     Filename next_path(directory, filename);
00249     Filename key(next_path, key_filename);
00250 
00251     if (key.exists()) {
00252       CVSSourceDirectory *subdir =
00253         new CVSSourceDirectory(_tree, this, filename);
00254       _children.push_back(subdir);
00255 
00256       if (!subdir->scan(next_path, key_filename)) {
00257         return false;
00258       }
00259 
00260     } else {
00261       // It's not a subdirectory; call it a regular file.
00262       _tree->add_file(filename, this);
00263     }
00264   }
00265 
00266   return true;
00267 }

Generated on Fri May 2 03:17:02 2003 for Panda-Tool by doxygen1.3