33 bool CVSSourceTree::_got_start_fullpath =
false;
34 Filename CVSSourceTree::_start_fullpath;
42 _got_root_fullpath =
false;
50 if (_root !=
nullptr) {
61 nassertv(_path.empty());
72 nassertr(_root ==
nullptr,
false);
75 return _root->
scan(_path, key_filename);
93 string fullpath = get_actual_fullpath(path);
97 if (root_fullpath.length() > fullpath.length() ||
98 cmp_nocase(fullpath.substr(0, root_fullpath.length()), root_fullpath) != 0) {
104 Filename relpath = fullpath.substr(root_fullpath.length());
117 if (result !=
nullptr) {
123 size_t slash = relpath.find(
'/');
124 Filename first = relpath.substr(0, slash);
126 if (slash != string::npos) {
127 rest = relpath.substr(slash + 1);
130 if (cmp_nocase(first, _root->
get_dirname()) == 0) {
154 bool force,
bool interactive) {
157 Basenames::const_iterator bi;
158 bi = _basenames.find(
downcase(basename));
159 if (bi != _basenames.end()) {
163 return prompt_user(basename, suggested_dir, paths,
168 return prompt_user(basename, suggested_dir, empty_paths,
177 nassertr(!_path.empty(),
Filename());
178 if (!_got_root_fullpath) {
179 _root_fullpath = get_actual_fullpath(_path);
180 _got_root_fullpath =
true;
182 return _root_fullpath;
190 nassertr(_root !=
nullptr,
Filename());
201 _basenames[
downcase(basename)].push_back(file_path);
213 get_start_fullpath();
216 if (chdir(os_path.c_str()) < 0) {
227 Filename start_fullpath = get_start_fullpath();
230 if (chdir(os_path.c_str()) < 0) {
232 perror(os_path.c_str());
233 nout <<
"Can't continue, aborting.\n";
246 bool force,
bool interactive) {
247 if (paths.size() == 1) {
252 FilePath result = ask_existing(basename, paths[0]);
253 if (result.is_valid()) {
257 }
else if (paths.size() > 1) {
259 if (force && !interactive) {
262 FilePath result = ask_existing(basename, paths, suggested_dir);
263 if (result.is_valid()) {
270 if (force && !interactive) {
271 return FilePath(suggested_dir, basename);
276 bool found_dir =
false;
277 FilePaths::const_iterator pi;
278 for (pi = paths.begin(); pi != paths.end(); ++pi) {
279 if ((*pi)._dir == suggested_dir) {
286 FilePath result = ask_new(basename, suggested_dir);
287 if (result.is_valid()) {
293 return ask_any(basename, paths);
302 nout << basename <<
" found in tree at " 304 string result = prompt(
"Overwrite this file (y/n)? ");
305 nassertr(!result.empty(), FilePath());
306 if (result.size() == 1) {
307 if (tolower(result[0]) ==
'y') {
309 }
else if (tolower(result[0]) ==
'n') {
314 nout <<
"*** Invalid response: " << result <<
"\n\n";
325 nout << basename <<
" found in tree at more than one place:\n";
327 bool any_suggested =
false;
328 for (
int i = 0; i < (int)paths.size(); i++) {
329 nout <<
" " << (i + 1) <<
". " 330 << paths[i].get_path() <<
"\n";
331 if (paths[i]._dir == suggested_dir) {
332 any_suggested =
true;
336 int next_option = paths.size() + 1;
337 int suggested_option = -1;
339 if (!any_suggested) {
342 suggested_option = next_option;
344 nout <<
"\n" << suggested_option
350 int other_option = next_option;
351 nout << other_option <<
". Other\n";
353 string result = prompt(
"Choose an option: ");
354 nassertr(!result.empty(), FilePath());
355 const char *nptr = result.c_str();
357 int option = strtol(nptr, &endptr, 10);
358 if (*endptr ==
'\0') {
359 if (option >= 1 && option <= (
int)paths.size()) {
360 return paths[option - 1];
362 }
else if (option == suggested_option) {
363 return FilePath(suggested_dir, basename);
365 }
else if (option == other_option) {
370 nout <<
"*** Invalid response: " << result <<
"\n\n";
380 nout << basename <<
" will be created in " 382 string result = prompt(
"Create this file (y/n)? ");
383 nassertr(!result.empty(), FilePath());
384 if (result.size() == 1) {
385 if (tolower(result[0]) ==
'y') {
386 return FilePath(dir, basename);
387 }
else if (tolower(result[0]) ==
'n') {
392 nout <<
"*** Invalid response: " << result <<
"\n\n";
401 ask_any(
const string &basename,
405 prompt(
"Enter the name of the directory to copy " + basename +
" to: ");
406 nassertr(!result.empty(), FilePath());
412 if (dir ==
nullptr) {
415 if (dir ==
nullptr) {
419 if (dir !=
nullptr) {
422 FilePaths::const_iterator pi;
423 for (pi = paths.begin(); pi != paths.end(); ++pi) {
424 if ((*pi)._dir == dir) {
430 return FilePath(dir, basename);
433 nout <<
"*** Not a valid directory name: " << result <<
"\n\n";
441 string CVSSourceTree::
442 prompt(
const string &message) {
445 std::cerr << message << std::flush;
446 std::string response;
447 std::getline(std::cin, response);
451 while (p < response.length() && isspace(response[p])) {
455 size_t q = response.length();
456 while (q > p && isspace(response[q - 1])) {
461 return response.substr(p, q - p);
470 get_actual_fullpath(
const Filename &path) {
482 get_start_fullpath() {
483 if (!_got_start_fullpath) {
487 return _start_fullpath;
517 return (_dir !=
nullptr);
525 nassertr(_dir !=
nullptr,
Filename());
526 return Filename(_dir->get_path(), _basename);
534 nassertr(_dir !=
nullptr,
Filename());
535 return Filename(_dir->get_fullpath(), _basename);
544 nassertr(_dir !=
nullptr,
Filename());
bool is_valid() const
Returns true if this FilePath represents a valid file, or false if it represents an error return.
void add_file(const std::string &basename, CVSSourceDirectory *dir)
Adds a new file to the set of known files.
Filename get_root_dirname() const
Returns the local directory name of the root of the tree.
get_cwd
Returns the name of the current working directory.
Filename get_path() const
Returns the relative path to this file from the root of the source tree.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_root(const Filename &root_path)
Sets the root of the source directory.
Filename get_root_fullpath()
Returns the full path from the root to the top of the source hierarchy.
FilePath choose_directory(const std::string &basename, CVSSourceDirectory *suggested_dir, bool force, bool interactive)
Determines where an externally referenced model file of the indicated name should go.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
string downcase(const string &s)
Returns the input string with all uppercase letters converted to lowercase.
bool make_canonical()
Converts this filename to a canonical name by replacing the directory part with the fully-qualified d...
std::string get_dirname() const
Returns the local name of this particular directory.
CVSSourceDirectory * find_directory(const Filename &path)
Returns the source directory that corresponds to the given path, or NULL if there is no such director...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Filename get_rel_to(const CVSSourceDirectory *other) const
Returns the relative path to the other directory from this one.
This is our own Panda specialization on the default STL vector.
bool scan(const Filename &directory, const std::string &key_filename)
Recursively scans the contents of the source directory.
Filename get_path() const
Returns the relative pathname to this particular directory, as seen from the root of the tree.
This represents one particular directory in the hierarchy of source directory files.
The name of a file, such as a texture file or an Egg file.
CVSSourceDirectory * find_dirname(const std::string &dirname)
Returns the source directory that corresponds to the given local directory name, or NULL if there is ...
static bool temp_chdir(const Filename &path)
Temporarily changes the current directory to the named path.
CVSSourceDirectory * find_dirname(const std::string &dirname)
Returns the source directory that corresponds to the given local directory name, or NULL if there is ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string get_basename() const
Returns the basename part of the filename.
CVSSourceDirectory * find_relpath(const std::string &relpath)
Returns the source directory that corresponds to the given relative path from the root,...
bool scan(const Filename &key_filename)
Scans the complete source directory starting at the indicated pathname.
Filename get_fullpath() const
Returns the full path to this file.
CVSSourceDirectory * find_relpath(const std::string &relpath)
Returns the source directory that corresponds to the given relative path from this directory,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Filename get_rel_from(const CVSSourceDirectory *other) const
Returns the relative path to this file as seen from the indicated source directory.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void restore_cwd()
Restores the current directory after changing it from temp_chdir().
std::string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
FilePath()
Creates an invalid FilePath specification.
CVSSourceDirectory * get_root() const
Returns the root directory of the hierarchy.