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]);
298 }
else if (paths.size() > 1) {
300 if (force && !interactive) {
303 FilePath result = ask_existing(basename, paths, suggested_dir);
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);
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') {
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) {
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;
string get_basename() const
Returns the basename part of the filename.
bool is_valid() const
Returns true if this FilePath represents a valid file, or false if it represents an error return...
CVSSourceDirectory * find_dirname(const string &dirname)
Returns the source directory that corresponds to the given local directory name, or NULL if there is ...
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...
Filename get_root_dirname() const
Returns the local directory name of the root of the tree.
Filename get_path() const
Returns the relative path to this file from the root of the source tree.
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...
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...
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.
Filename get_path() const
Returns the relative pathname to this particular directory, as seen from the root of the tree...
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 pathname to this particular directory.
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.
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.
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.
static Filename get_cwd()
Returns the name of the current working directory.
Filename get_rel_from(const CVSSourceDirectory *other) const
Returns the relative path to this file as seen from the indicated source directory.
static void restore_cwd()
Restores the current directory after changing it from temp_chdir().
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.
bool scan(const Filename &directory, const string &key_filename)
Recursively scans the contents of the source directory.
CVSSourceDirectory * get_root() const
Returns the root directory of the hierarchy.