00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "cvsSourceDirectory.h"
00016 #include "cvsSourceTree.h"
00017 #include "string_utils.h"
00018
00019 #include "pnotify.h"
00020
00021
00022
00023
00024
00025
00026 CVSSourceDirectory::
00027 CVSSourceDirectory(CVSSourceTree *tree, CVSSourceDirectory *parent,
00028 const string &dirname) :
00029 _tree(tree),
00030 _parent(parent),
00031 _dirname(dirname)
00032 {
00033 if (_parent == (CVSSourceDirectory *)NULL) {
00034 _depth = 0;
00035 } else {
00036 _depth = _parent->_depth + 1;
00037 }
00038 }
00039
00040
00041
00042
00043
00044
00045 CVSSourceDirectory::
00046 ~CVSSourceDirectory() {
00047 Children::iterator ci;
00048 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00049 delete (*ci);
00050 }
00051 }
00052
00053
00054
00055
00056
00057
00058 string CVSSourceDirectory::
00059 get_dirname() const {
00060 return _dirname;
00061 }
00062
00063
00064
00065
00066
00067
00068
00069 Filename CVSSourceDirectory::
00070 get_fullpath() const {
00071 if (_parent == (CVSSourceDirectory *)NULL) {
00072 return _tree->get_root_fullpath();
00073 }
00074 return Filename(_parent->get_fullpath(), _dirname);
00075 }
00076
00077
00078
00079
00080
00081
00082
00083 Filename CVSSourceDirectory::
00084 get_path() const {
00085 if (_parent == (CVSSourceDirectory *)NULL) {
00086 return _dirname;
00087 }
00088 return Filename(_parent->get_path(), _dirname);
00089 }
00090
00091
00092
00093
00094
00095
00096
00097 Filename CVSSourceDirectory::
00098 get_rel_to(const CVSSourceDirectory *other) const {
00099 const CVSSourceDirectory *a = this;
00100 const CVSSourceDirectory *b = other;
00101
00102 if (a == b) {
00103 return ".";
00104 }
00105
00106 string prefix, postfix;
00107 while (a->_depth > b->_depth) {
00108 prefix += "../";
00109 a = a->_parent;
00110 nassertr(a != (CVSSourceDirectory *)NULL, string());
00111 }
00112
00113 while (b->_depth > a->_depth) {
00114 postfix = b->_dirname + "/" + postfix;
00115 b = b->_parent;
00116 nassertr(b != (CVSSourceDirectory *)NULL, string());
00117 }
00118
00119 while (a != b) {
00120 prefix += "../";
00121 postfix = b->_dirname + "/" + postfix;
00122 a = a->_parent;
00123 b = b->_parent;
00124 nassertr(a != (CVSSourceDirectory *)NULL, string());
00125 nassertr(b != (CVSSourceDirectory *)NULL, string());
00126 }
00127
00128 string result = prefix + postfix;
00129 nassertr(!result.empty(), string());
00130 return result.substr(0, result.length() - 1);
00131 }
00132
00133
00134
00135
00136
00137
00138
00139 int CVSSourceDirectory::
00140 get_num_children() const {
00141 return _children.size();
00142 }
00143
00144
00145
00146
00147
00148
00149 CVSSourceDirectory *CVSSourceDirectory::
00150 get_child(int n) const {
00151 nassertr(n >= 0 && n < (int)_children.size(), NULL);
00152 return _children[n];
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162 CVSSourceDirectory *CVSSourceDirectory::
00163 find_relpath(const string &relpath) {
00164 if (relpath.empty()) {
00165 return this;
00166 }
00167
00168 size_t slash = relpath.find('/');
00169 string first = relpath.substr(0, slash);
00170 string rest;
00171 if (slash != string::npos) {
00172 rest = relpath.substr(slash + 1);
00173 }
00174
00175 if (first.empty() || first == ".") {
00176 return find_relpath(rest);
00177
00178 } else if (first == "..") {
00179 if (_parent != NULL) {
00180 return _parent->find_relpath(rest);
00181 }
00182
00183 return (CVSSourceDirectory *)NULL;
00184 }
00185
00186
00187 Children::const_iterator ci;
00188 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00189 if (cmp_nocase((*ci)->get_dirname(), first) == 0) {
00190 return (*ci)->find_relpath(rest);
00191 }
00192 }
00193
00194
00195 return (CVSSourceDirectory *)NULL;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205 CVSSourceDirectory *CVSSourceDirectory::
00206 find_dirname(const string &dirname) {
00207 if (cmp_nocase(dirname, _dirname) == 0) {
00208 return this;
00209 }
00210
00211 Children::const_iterator ci;
00212 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00213 CVSSourceDirectory *result = (*ci)->find_dirname(dirname);
00214 if (result != (CVSSourceDirectory *)NULL) {
00215 return result;
00216 }
00217 }
00218
00219 return (CVSSourceDirectory *)NULL;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 bool CVSSourceDirectory::
00233 scan(const Filename &directory, const string &key_filename) {
00234 vector_string contents;
00235 if (!directory.scan_directory(contents)) {
00236 nout << "Unable to scan directory " << directory << "\n";
00237 return false;
00238 }
00239
00240 vector_string::const_iterator fi;
00241 for (fi = contents.begin(); fi != contents.end(); ++fi) {
00242 const string &basename = (*fi);
00243
00244
00245 Filename next_path(directory, basename);
00246 Filename key(next_path, key_filename);
00247
00248 if (key.exists()) {
00249 CVSSourceDirectory *subdir =
00250 new CVSSourceDirectory(_tree, this, basename);
00251 _children.push_back(subdir);
00252
00253 if (!subdir->scan(next_path, key_filename)) {
00254 return false;
00255 }
00256
00257 } else {
00258
00259 _tree->add_file(basename, this);
00260 }
00261 }
00262
00263 return true;
00264 }