15 #include "cvsSourceTree.h"
16 #include "cvsSourceDirectory.h"
19 #include "executionEnvironment.h"
21 #include "string_utils.h"
32 bool CVSSourceTree::_got_start_fullpath =
false;
33 Filename CVSSourceTree::_start_fullpath;
43 _got_root_fullpath =
false;
67 nassertv(_path.empty());
84 return _root->
scan(_path, key_filename);
107 string fullpath = get_actual_fullpath(path);
111 if (root_fullpath.length() > fullpath.length() ||
112 cmp_nocase(fullpath.substr(0, root_fullpath.length()), root_fullpath) != 0) {
118 Filename relpath = fullpath.substr(root_fullpath.length());
140 size_t slash = relpath.find(
'/');
141 Filename first = relpath.substr(0, slash);
143 if (slash != string::npos) {
144 rest = relpath.substr(slash + 1);
147 if (cmp_nocase(first, _root->
get_dirname()) == 0) {
178 bool force,
bool interactive) {
181 Basenames::const_iterator bi;
182 bi = _basenames.find(downcase(basename));
183 if (bi != _basenames.end()) {
187 return prompt_user(basename, suggested_dir, paths,
192 return prompt_user(basename, suggested_dir, empty_paths,
204 nassertr(!_path.empty(),
Filename());
205 if (!_got_root_fullpath) {
206 _root_fullpath = get_actual_fullpath(_path);
207 _got_root_fullpath =
true;
209 return _root_fullpath;
234 _basenames[downcase(basename)].push_back(file_path);
249 get_start_fullpath();
252 if (chdir(os_path.c_str()) < 0) {
266 Filename start_fullpath = get_start_fullpath();
269 if (chdir(os_path.c_str()) < 0) {
271 perror(os_path.c_str());
272 nout <<
"Can't continue, aborting.\n";
287 bool force,
bool interactive) {
288 if (paths.size() == 1) {
293 FilePath result = ask_existing(basename, paths[0]);
294 if (result.is_valid()) {
298 }
else if (paths.size() > 1) {
300 if (force && !interactive) {
303 FilePath result = ask_existing(basename, paths, suggested_dir);
304 if (result.is_valid()) {
311 if (force && !interactive) {
312 return FilePath(suggested_dir, basename);
317 bool found_dir =
false;
318 FilePaths::const_iterator pi;
319 for (pi = paths.begin(); pi != paths.end(); ++pi) {
320 if ((*pi)._dir == suggested_dir) {
327 FilePath result = ask_new(basename, suggested_dir);
328 if (result.is_valid()) {
334 return ask_any(basename, paths);
346 nout << basename <<
" found in tree at "
348 string result = prompt(
"Overwrite this file (y/n)? ");
349 nassertr(!result.empty(), FilePath());
350 if (result.size() == 1) {
351 if (tolower(result[0]) ==
'y') {
353 }
else if (tolower(result[0]) ==
'n') {
358 nout <<
"*** Invalid response: " << result <<
"\n\n";
372 nout << basename <<
" found in tree at more than one place:\n";
374 bool any_suggested =
false;
375 for (
int i = 0; i < (int)paths.size(); i++) {
376 nout <<
" " << (i + 1) <<
". "
377 << paths[i].get_path() <<
"\n";
378 if (paths[i]._dir == suggested_dir) {
379 any_suggested =
true;
383 int next_option = paths.size() + 1;
384 int suggested_option = -1;
386 if (!any_suggested) {
389 suggested_option = next_option;
391 nout <<
"\n" << suggested_option
397 int other_option = next_option;
398 nout << other_option <<
". Other\n";
400 string result = prompt(
"Choose an option: ");
401 nassertr(!result.empty(), FilePath());
402 const char *nptr = result.c_str();
404 int option = strtol(nptr, &endptr, 10);
405 if (*endptr ==
'\0') {
406 if (option >= 1 && option <= (
int)paths.size()) {
407 return paths[option - 1];
409 }
else if (option == suggested_option) {
410 return FilePath(suggested_dir, basename);
412 }
else if (option == other_option) {
417 nout <<
"*** Invalid response: " << result <<
"\n\n";
429 nout << basename <<
" will be created in "
431 string result = prompt(
"Create this file (y/n)? ");
432 nassertr(!result.empty(), FilePath());
433 if (result.size() == 1) {
434 if (tolower(result[0]) ==
'y') {
435 return FilePath(dir, basename);
436 }
else if (tolower(result[0]) ==
'n') {
441 nout <<
"*** Invalid response: " << result <<
"\n\n";
452 ask_any(
const string &basename,
456 prompt(
"Enter the name of the directory to copy " + basename +
" to: ");
457 nassertr(!result.empty(), FilePath());
473 FilePaths::const_iterator pi;
474 for (pi = paths.begin(); pi != paths.end(); ++pi) {
475 if ((*pi)._dir == dir) {
482 return FilePath(dir, basename);
485 nout <<
"*** Not a valid directory name: " << result <<
"\n\n";
496 string CVSSourceTree::
497 prompt(
const string &message) {
500 cerr << message << flush;
502 getline(cin, response);
506 while (p < response.length() && isspace(response[p])) {
510 size_t q = response.
length();
511 while (q > p && isspace(response[q - 1])) {
516 return response.substr(p, q - p);
528 get_actual_fullpath(
const Filename &path) {
542 get_start_fullpath() {
543 if (!_got_start_fullpath) {
547 return _start_fullpath;
595 return Filename(_dir->get_path(), _basename);
606 return Filename(_dir->get_fullpath(), _basename);
CVSSourceDirectory * find_dirname(const string &dirname)
Returns the source directory that corresponds to the given local directory name, or NULL if there is ...
Filename get_fullpath() const
Returns the full path to this file.
FilePath choose_directory(const string &basename, CVSSourceDirectory *suggested_dir, bool force, bool interactive)
Determines where an externally referenced model file of the indicated name should go...
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.
CVSSourceDirectory * find_relpath(const string &relpath)
Returns the source directory that corresponds to the given relative path from this directory...
bool make_canonical()
Converts this filename to a canonical name by replacing the directory part with the fully-qualified d...
Filename get_rel_from(const CVSSourceDirectory *other) const
Returns the relative path to this file as seen from the indicated source directory.
Filename get_path() const
Returns the relative pathname to this particular directory, as seen from the root of the tree...
Filename get_rel_to(const CVSSourceDirectory *other) const
Returns the relative path to the other directory from this one.
CVSSourceDirectory * find_directory(const Filename &path)
Returns the source directory that corresponds to the given path, or NULL if there is no such director...
This is our own Panda specialization on the default STL vector.
float length() const
Returns the length of the vector, by the Pythagorean theorem.
CVSSourceDirectory * find_dirname(const string &dirname)
Returns the source directory that corresponds to the given local directory name, or NULL if there is ...
CVSSourceDirectory * get_root() const
Returns the root directory of the hierarchy.
CVSSourceDirectory * find_relpath(const string &relpath)
Returns the source directory that corresponds to the given relative path from the root...
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.
Filename get_path() const
Returns the relative path to this file from the root of the source tree.
void add_file(const string &basename, CVSSourceDirectory *dir)
Adds a new file to the set of known files.
static bool temp_chdir(const Filename &path)
Temporarily changes the current directory to the named path.
Filename get_root_dirname() const
Returns the local directory name of the root of the tree.
string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
bool scan(const Filename &key_filename)
Scans the complete source directory starting at the indicated pathname.
bool is_valid() const
Returns true if this FilePath represents a valid file, or false if it represents an error return...
string get_basename() const
Returns the basename part of the filename.
static Filename get_cwd()
Returns the name of the current working directory.
static void restore_cwd()
Restores the current directory after changing it from temp_chdir().
FilePath()
Creates an invalid FilePath specification.
bool scan(const Filename &directory, const string &key_filename)
Recursively scans the contents of the source directory.
string get_dirname() const
Returns the local name of this particular directory.