Panda3D
Loading...
Searching...
No Matches
cvsSourceDirectory.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file cvsSourceDirectory.cxx
10 * @author drose
11 * @date 2000-10-31
12 */
13
14#include "cvsSourceDirectory.h"
15#include "cvsSourceTree.h"
16#include "string_utils.h"
17
18#include "pnotify.h"
19
20using std::string;
21
22/**
23 *
24 */
25CVSSourceDirectory::
26CVSSourceDirectory(CVSSourceTree *tree, CVSSourceDirectory *parent,
27 const string &dirname) :
28 _tree(tree),
29 _parent(parent),
30 _dirname(dirname)
31{
32 if (_parent == nullptr) {
33 _depth = 0;
34 } else {
35 _depth = _parent->_depth + 1;
36 }
37}
38
39/**
40 *
41 */
42CVSSourceDirectory::
43~CVSSourceDirectory() {
44 Children::iterator ci;
45 for (ci = _children.begin(); ci != _children.end(); ++ci) {
46 delete (*ci);
47 }
48}
49
50/**
51 * Returns the local name of this particular directory.
52 */
54get_dirname() const {
55 return _dirname;
56}
57
58/**
59 * Returns the full pathname to this particular directory.
60 */
62get_fullpath() const {
63 if (_parent == nullptr) {
64 return _tree->get_root_fullpath();
65 }
66 return Filename(_parent->get_fullpath(), _dirname);
67}
68
69/**
70 * Returns the relative pathname to this particular directory, as seen from
71 * the root of the tree.
72 */
74get_path() const {
75 if (_parent == nullptr) {
76 return _dirname;
77 }
78 return Filename(_parent->get_path(), _dirname);
79}
80
81/**
82 * Returns the relative path to the other directory from this one. This does
83 * not include a trailing slash.
84 */
86get_rel_to(const CVSSourceDirectory *other) const {
87 const CVSSourceDirectory *a = this;
88 const CVSSourceDirectory *b = other;
89
90 if (a == b) {
91 return ".";
92 }
93
94 string prefix, postfix;
95 while (a->_depth > b->_depth) {
96 prefix += "../";
97 a = a->_parent;
98 nassertr(a != nullptr, string());
99 }
100
101 while (b->_depth > a->_depth) {
102 postfix = b->_dirname + "/" + postfix;
103 b = b->_parent;
104 nassertr(b != nullptr, string());
105 }
106
107 while (a != b) {
108 prefix += "../";
109 postfix = b->_dirname + "/" + postfix;
110 a = a->_parent;
111 b = b->_parent;
112 nassertr(a != nullptr, string());
113 nassertr(b != nullptr, string());
114 }
115
116 string result = prefix + postfix;
117 nassertr(!result.empty(), string());
118 return result.substr(0, result.length() - 1);
119}
120
121/**
122 * Returns the number of subdirectories below this directory.
123 */
125get_num_children() const {
126 return _children.size();
127}
128
129/**
130 * Returns the nth subdirectory below this directory.
131 */
133get_child(int n) const {
134 nassertr(n >= 0 && n < (int)_children.size(), nullptr);
135 return _children[n];
136}
137
138/**
139 * Returns the source directory that corresponds to the given relative path
140 * from this directory, or NULL if there is no match.
141 */
143find_relpath(const string &relpath) {
144 if (relpath.empty()) {
145 return this;
146 }
147
148 size_t slash = relpath.find('/');
149 string first = relpath.substr(0, slash);
150 string rest;
151 if (slash != string::npos) {
152 rest = relpath.substr(slash + 1);
153 }
154
155 if (first.empty() || first == ".") {
156 return find_relpath(rest);
157
158 } else if (first == "..") {
159 if (_parent != nullptr) {
160 return _parent->find_relpath(rest);
161 }
162 // Tried to back out past the root directory.
163 return nullptr;
164 }
165
166 // Check for a child with the name indicated by first.
167 Children::const_iterator ci;
168 for (ci = _children.begin(); ci != _children.end(); ++ci) {
169 if (cmp_nocase((*ci)->get_dirname(), first) == 0) {
170 return (*ci)->find_relpath(rest);
171 }
172 }
173
174 // No match.
175 return nullptr;
176}
177
178/**
179 * Returns the source directory that corresponds to the given local directory
180 * name, or NULL if there is no match.
181 */
183find_dirname(const string &dirname) {
184 if (cmp_nocase(dirname, _dirname) == 0) {
185 return this;
186 }
187
188 Children::const_iterator ci;
189 for (ci = _children.begin(); ci != _children.end(); ++ci) {
190 CVSSourceDirectory *result = (*ci)->find_dirname(dirname);
191 if (result != nullptr) {
192 return result;
193 }
194 }
195
196 return nullptr;
197}
198
199/**
200 * Recursively scans the contents of the source directory. Fullpath is the
201 * full path name to the directory; key_filename is the name of a file that
202 * must exist in each subdirectory for it to be considered part of the
203 * hierarchy. Returns true on success, false on failure.
204 */
206scan(const Filename &directory, const string &key_filename) {
207 vector_string contents;
208 if (!directory.scan_directory(contents)) {
209 nout << "Unable to scan directory " << directory << "\n";
210 return false;
211 }
212
213 vector_string::const_iterator fi;
214 for (fi = contents.begin(); fi != contents.end(); ++fi) {
215 const string &basename = (*fi);
216
217 // Is this possibly a subdirectory name?
218 Filename next_path(directory, basename);
219 Filename key(next_path, key_filename);
220
221 if (key.exists()) {
222 CVSSourceDirectory *subdir =
223 new CVSSourceDirectory(_tree, this, basename);
224 _children.push_back(subdir);
225
226 if (!subdir->scan(next_path, key_filename)) {
227 return false;
228 }
229
230 } else {
231 // It's not a subdirectory; call it a regular file.
232 _tree->add_file(basename, this);
233 }
234 }
235
236 return true;
237}
This represents one particular directory in the hierarchy of source directory files.
bool scan(const Filename &directory, const std::string &key_filename)
Recursively scans the contents of the source directory.
CVSSourceDirectory * find_dirname(const std::string &dirname)
Returns the source directory that corresponds to the given local directory name, or NULL if there is ...
CVSSourceDirectory * get_child(int n) const
Returns the nth subdirectory below this directory.
Filename get_rel_to(const CVSSourceDirectory *other) const
Returns the relative path to the other directory from this one.
std::string get_dirname() const
Returns the local name of this particular directory.
Filename get_fullpath() const
Returns the full pathname to this particular directory.
CVSSourceDirectory * find_relpath(const std::string &relpath)
Returns the source directory that corresponds to the given relative path from this directory,...
Filename get_path() const
Returns the relative pathname to this particular directory, as seen from the root of the tree.
int get_num_children() const
Returns the number of subdirectories below this directory.
This represents the root of the tree of source directory files.
Filename get_root_fullpath()
Returns the full path from the root to the top of the source hierarchy.
void add_file(const std::string &basename, CVSSourceDirectory *dir)
Adds a new file to the set of known files.
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
bool scan_directory(vector_string &contents) const
Attempts to open the named filename as if it were a directory and looks for the non-hidden files with...
bool exists() const
Returns true if the filename exists on the physical disk, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.