00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "cvsSourceDirectory.h"
00020 #include "cvsSourceTree.h"
00021
00022 #include <notify.h>
00023
00024
00025
00026
00027
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
00045
00046
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
00058
00059
00060
00061 string CVSSourceDirectory::
00062 get_dirname() const {
00063 return _dirname;
00064 }
00065
00066
00067
00068
00069
00070
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
00082
00083
00084
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
00096
00097
00098
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
00138
00139
00140
00141
00142 int CVSSourceDirectory::
00143 get_num_children() const {
00144 return _children.size();
00145 }
00146
00147
00148
00149
00150
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
00160
00161
00162
00163
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
00186 return (CVSSourceDirectory *)NULL;
00187 }
00188
00189
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
00198 return (CVSSourceDirectory *)NULL;
00199 }
00200
00201
00202
00203
00204
00205
00206
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
00227
00228
00229
00230
00231
00232
00233
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
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
00262 _tree->add_file(filename, this);
00263 }
00264 }
00265
00266 return true;
00267 }