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());