浏览代码

make mayacopy, fltcopy be case-insensitive

David Rose 21 年之前
父节点
当前提交
a6b259e40d

+ 14 - 14
pandatool/src/cvscopy/cvsCopy.cxx

@@ -110,10 +110,10 @@ CVSCopy() {
 //               copy the file, if it does not already exist
 //               elsewhere.
 //
-//               On success, returns the CVSSourceDirectory it was
-//               actually copied to.  On failure, returns NULL.
+//               On success, returns the FilePath it was actually
+//               copied to.  On failure, returns an invalid FilePath.
 ////////////////////////////////////////////////////////////////////
-CVSSourceDirectory *CVSCopy::
+CVSSourceTree::FilePath CVSCopy::
 import(const Filename &source, void *extra_data,
        CVSSourceDirectory *suggested_dir) {
   CopiedFiles::const_iterator ci;
@@ -125,30 +125,30 @@ import(const Filename &source, void *extra_data,
 
   if (!source.exists()) {
     nout << "Source filename " << source << " does not exist!\n";
-    return (CVSSourceDirectory *)NULL;
+    return CVSSourceTree::FilePath();
   }
 
   string basename = filter_filename(source.get_basename());
 
-  CVSSourceDirectory *dir =
+  CVSSourceTree::FilePath path =
     _tree.choose_directory(basename, suggested_dir, _force, _interactive);
-  nassertr(dir != (CVSSourceDirectory *)NULL, dir);
+  nassertr(path.is_valid(), path);
 
-  _copied_files[source] = dir;
-  Filename dest = dir->get_fullpath() + "/" + basename;
+  _copied_files[source] = path;
+  Filename dest = path.get_fullpath();
 
   bool new_file = !dest.exists();
-  if (!new_file && verify_file(source, dest, dir, extra_data)) {
+  if (!new_file && verify_file(source, dest, path._dir, extra_data)) {
     // The file is unchanged.
-    nout << dir->get_path() + "/" + basename << " is unchanged.\n";
+    nout << path.get_path() << " is unchanged.\n";
 
   } else {
     // The file has changed.
-    nout << "Copying " << basename << " to " << dir->get_path() << "\n";
+    nout << "Copying " << basename << " to " << path.get_path() << "\n";
 
-    if (!copy_file(source, dest, dir, extra_data, new_file)) {
+    if (!copy_file(source, dest, path._dir, extra_data, new_file)) {
       if (!continue_after_error()) {
-        return (CVSSourceDirectory *)NULL;
+        return CVSSourceTree::FilePath();
       }
     } else {
       if (new_file) {
@@ -157,7 +157,7 @@ import(const Filename &source, void *extra_data,
     }
   }
 
-  return dir;
+  return path;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 2
pandatool/src/cvscopy/cvsCopy.h

@@ -38,7 +38,7 @@ class CVSCopy : public ProgramBase {
 public:
   CVSCopy();
 
-  CVSSourceDirectory *
+  CVSSourceTree::FilePath
   import(const Filename &source, void *extra_data,
          CVSSourceDirectory *suggested_dir);
 
@@ -89,7 +89,7 @@ protected:
   CVSSourceDirectory *_model_dir;
   CVSSourceDirectory *_map_dir;
 
-  typedef pmap<string, CVSSourceDirectory *> CopiedFiles;
+  typedef pmap<string, CVSSourceTree::FilePath> CopiedFiles;
   CopiedFiles _copied_files;
 };
 

+ 12 - 11
pandatool/src/cvscopy/cvsSourceDirectory.cxx

@@ -18,6 +18,7 @@
 
 #include "cvsSourceDirectory.h"
 #include "cvsSourceTree.h"
+#include "string_utils.h"
 
 #include "notify.h"
 
@@ -69,12 +70,12 @@ get_dirname() const {
 //  Description: Returns the full pathname to this particular
 //               directory.
 ////////////////////////////////////////////////////////////////////
-string CVSSourceDirectory::
+Filename CVSSourceDirectory::
 get_fullpath() const {
   if (_parent == (CVSSourceDirectory *)NULL) {
     return _tree->get_root_fullpath();
   }
-  return _parent->get_fullpath() + "/" + _dirname;
+  return Filename(_parent->get_fullpath(), _dirname);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -83,12 +84,12 @@ get_fullpath() const {
 //  Description: Returns the relative pathname to this particular
 //               directory, as seen from the root of the tree.
 ////////////////////////////////////////////////////////////////////
-string CVSSourceDirectory::
+Filename CVSSourceDirectory::
 get_path() const {
   if (_parent == (CVSSourceDirectory *)NULL) {
     return _dirname;
   }
-  return _parent->get_path() + "/" + _dirname;
+  return Filename(_parent->get_path(), _dirname);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -97,7 +98,7 @@ get_path() const {
 //  Description: Returns the relative path to the other directory from
 //               this one.  This does not include a trailing slash.
 ////////////////////////////////////////////////////////////////////
-string CVSSourceDirectory::
+Filename CVSSourceDirectory::
 get_rel_to(const CVSSourceDirectory *other) const {
   const CVSSourceDirectory *a = this;
   const CVSSourceDirectory *b = other;
@@ -189,7 +190,7 @@ find_relpath(const string &relpath) {
   // Check for a child with the name indicated by first.
   Children::const_iterator ci;
   for (ci = _children.begin(); ci != _children.end(); ++ci) {
-    if ((*ci)->get_dirname() == first) {
+    if (cmp_nocase((*ci)->get_dirname(), first) == 0) {
       return (*ci)->find_relpath(rest);
     }
   }
@@ -207,7 +208,7 @@ find_relpath(const string &relpath) {
 ////////////////////////////////////////////////////////////////////
 CVSSourceDirectory *CVSSourceDirectory::
 find_dirname(const string &dirname) {
-  if (dirname == _dirname) {
+  if (cmp_nocase(dirname, _dirname) == 0) {
     return this;
   }
 
@@ -242,15 +243,15 @@ scan(const Filename &directory, const string &key_filename) {
 
   vector_string::const_iterator fi;
   for (fi = contents.begin(); fi != contents.end(); ++fi) {
-    const string &filename = (*fi);
+    const string &basename = (*fi);
 
     // Is this possibly a subdirectory name?
-    Filename next_path(directory, filename);
+    Filename next_path(directory, basename);
     Filename key(next_path, key_filename);
 
     if (key.exists()) {
       CVSSourceDirectory *subdir =
-        new CVSSourceDirectory(_tree, this, filename);
+        new CVSSourceDirectory(_tree, this, basename);
       _children.push_back(subdir);
 
       if (!subdir->scan(next_path, key_filename)) {
@@ -259,7 +260,7 @@ scan(const Filename &directory, const string &key_filename) {
 
     } else {
       // It's not a subdirectory; call it a regular file.
-      _tree->add_file(filename, this);
+      _tree->add_file(basename, this);
     }
   }
 

+ 11 - 3
pandatool/src/cvscopy/cvsSourceDirectory.h

@@ -32,6 +32,14 @@ class CVSSourceTree;
 //               hierarchy of source directory files.  We must scan
 //               the source directory to identify where the related
 //               files have previously been copied.
+//
+//               The tree is maintained in a case-insensitive manner,
+//               even on a non-Windows system, since you might want to
+//               eventually check out the CVS tree onto a Windows
+//               system--and if you do, you'll be sad if there are
+//               case conflicts within the tree.  So we make an effort
+//               to ensure this doesn't happen by treating two files
+//               with a different case as the same file.
 ////////////////////////////////////////////////////////////////////
 class CVSSourceDirectory {
 public:
@@ -40,9 +48,9 @@ public:
   ~CVSSourceDirectory();
 
   string get_dirname() const;
-  string get_fullpath() const;
-  string get_path() const;
-  string get_rel_to(const CVSSourceDirectory *other) const;
+  Filename get_fullpath() const;
+  Filename get_path() const;
+  Filename get_rel_to(const CVSSourceDirectory *other) const;
 
   int get_num_children() const;
   CVSSourceDirectory *get_child(int n) const;

+ 160 - 62
pandatool/src/cvscopy/cvsSourceTree.cxx

@@ -22,6 +22,7 @@
 #include "filename.h"
 #include "executionEnvironment.h"
 #include "notify.h"
+#include "string_utils.h"
 
 #include <algorithm>
 #include <ctype.h>
@@ -112,7 +113,7 @@ find_directory(const Filename &path) {
   // path is a subdirectory within the source hierarchy if and only if
   // root_fullpath is an initial prefix of fullpath.
   if (root_fullpath.length() > fullpath.length() ||
-      fullpath.substr(0, root_fullpath.length()) != root_fullpath) {
+      cmp_nocase(fullpath.substr(0, root_fullpath.length()), root_fullpath) != 0) {
     // Nope!
     return (CVSSourceDirectory *)NULL;
   }
@@ -147,7 +148,7 @@ find_relpath(const string &relpath) {
     rest = relpath.substr(slash + 1);
   }
 
-  if (first == _root->get_dirname()) {
+  if (cmp_nocase(first, _root->get_dirname()) == 0) {
     return _root->find_relpath(rest);
   }
 
@@ -176,23 +177,23 @@ find_dirname(const string &dirname) {
 //               matching files are found, prompts the user for the
 //               directory, or uses suggested_dir.
 ////////////////////////////////////////////////////////////////////
-CVSSourceDirectory *CVSSourceTree::
-choose_directory(const Filename &filename, CVSSourceDirectory *suggested_dir,
+CVSSourceTree::FilePath CVSSourceTree::
+choose_directory(const string &basename, CVSSourceDirectory *suggested_dir,
                  bool force, bool interactive) {
-  static Directories empty_dirs;
+  static FilePaths empty_paths;
 
-  Filenames::const_iterator fi;
-  fi = _filenames.find(filename);
-  if (fi != _filenames.end()) {
+  Basenames::const_iterator bi;
+  bi = _basenames.find(downcase(basename));
+  if (bi != _basenames.end()) {
     // The filename already exists somewhere.
-    const Directories &dirs = (*fi).second;
+    const FilePaths &paths = (*bi).second;
 
-    return prompt_user(filename, suggested_dir, dirs,
+    return prompt_user(basename, suggested_dir, paths,
                        force, interactive);
   }
 
   // Now we have to prompt the user for a suitable place to put it.
-  return prompt_user(filename, suggested_dir, empty_dirs,
+  return prompt_user(basename, suggested_dir, empty_paths,
                      force, interactive);
 }
 
@@ -232,8 +233,9 @@ get_root_dirname() const {
 //               should not be called directly by the user.
 ////////////////////////////////////////////////////////////////////
 void CVSSourceTree::
-add_file(const Filename &filename, CVSSourceDirectory *dir) {
-  _filenames[filename].push_back(dir);
+add_file(const string &basename, CVSSourceDirectory *dir) {
+  FilePath file_path(dir, basename);
+  _basenames[downcase(basename)].push_back(file_path);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -283,27 +285,27 @@ restore_cwd() {
 //  Description: Prompts the user, if necessary, to choose a directory
 //               to import the given file into.
 ////////////////////////////////////////////////////////////////////
-CVSSourceDirectory *CVSSourceTree::
-prompt_user(const string &filename, CVSSourceDirectory *suggested_dir,
-            const CVSSourceTree::Directories &dirs,
+CVSSourceTree::FilePath CVSSourceTree::
+prompt_user(const string &basename, CVSSourceDirectory *suggested_dir,
+            const CVSSourceTree::FilePaths &paths,
             bool force, bool interactive) {
-  if (dirs.size() == 1) {
+  if (paths.size() == 1) {
     // The file already exists in exactly one place.
     if (!interactive) {
-      return dirs[0];
+      return paths[0];
     }
-    CVSSourceDirectory *result = ask_existing(filename, dirs[0]);
-    if (result != (CVSSourceDirectory *)NULL) {
+    FilePath result = ask_existing(basename, paths[0]);
+    if (result.is_valid()) {
       return result;
     }
 
-  } else if (dirs.size() > 1) {
+  } else if (paths.size() > 1) {
     // The file already exists in multiple places.
     if (force && !interactive) {
-      return dirs[0];
+      return paths[0];
     }
-    CVSSourceDirectory *result = ask_existing(filename, dirs, suggested_dir);
-    if (result != (CVSSourceDirectory *)NULL) {
+    FilePath result = ask_existing(basename, paths, suggested_dir);
+    if (result.is_valid()) {
       return result;
     }
   }
@@ -311,18 +313,29 @@ prompt_user(const string &filename, CVSSourceDirectory *suggested_dir,
   // The file does not already exist, or the user declined to replace
   // an existing file.
   if (force && !interactive) {
-    return suggested_dir;
+    return FilePath(suggested_dir, basename);
+  }
+
+  // Is the file already in the suggested directory?  If not, prompt
+  // the user to put it there.
+  bool found_dir = false;
+  FilePaths::const_iterator pi;
+  for (pi = paths.begin(); pi != paths.end(); ++pi) {
+    if ((*pi)._dir == suggested_dir) {
+      found_dir = true;
+      break;
+    }
   }
 
-  if (find(dirs.begin(), dirs.end(), suggested_dir) == dirs.end()) {
-    CVSSourceDirectory *result = ask_new(filename, suggested_dir);
-    if (result != (CVSSourceDirectory *)NULL) {
+  if (!found_dir) {
+    FilePath result = ask_new(basename, suggested_dir);
+    if (result.is_valid()) {
       return result;
     }
   }
 
   // Ask the user where the damn thing should go.
-  return ask_any(filename);
+  return ask_any(basename, paths);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -331,18 +344,18 @@ prompt_user(const string &filename, CVSSourceDirectory *suggested_dir,
 //  Description: Asks the user if he wants to replace an existing
 //               file.
 ////////////////////////////////////////////////////////////////////
-CVSSourceDirectory *CVSSourceTree::
-ask_existing(const string &filename, CVSSourceDirectory *dir) {
+CVSSourceTree::FilePath CVSSourceTree::
+ask_existing(const string &basename, const CVSSourceTree::FilePath &path) {
   while (true) {
-    nout << filename << " found in tree at "
-         << dir->get_path() + "/" + filename << ".\n";
+    nout << basename << " found in tree at "
+         << path.get_path() << ".\n";
     string result = prompt("Overwrite this file (y/n)? ");
-    nassertr(!result.empty(), (CVSSourceDirectory *)NULL);
+    nassertr(!result.empty(), FilePath());
     if (result.size() == 1) {
       if (tolower(result[0]) == 'y') {
-        return dir;
+        return path;
       } else if (tolower(result[0]) == 'n') {
-        return NULL;
+        return FilePath();
       }
     }
 
@@ -356,30 +369,32 @@ ask_existing(const string &filename, CVSSourceDirectory *dir) {
 //  Description: Asks the user which of several existing files he
 //               wants to replace.
 ////////////////////////////////////////////////////////////////////
-CVSSourceDirectory *CVSSourceTree::
-ask_existing(const string &filename, const CVSSourceTree::Directories &dirs,
+CVSSourceTree::FilePath CVSSourceTree::
+ask_existing(const string &basename, const CVSSourceTree::FilePaths &paths,
              CVSSourceDirectory *suggested_dir) {
   while (true) {
-    nout << filename << " found in tree at more than one place:\n";
+    nout << basename << " found in tree at more than one place:\n";
 
     bool any_suggested = false;
-    for (int i = 0; i < (int)dirs.size(); i++) {
+    for (int i = 0; i < (int)paths.size(); i++) {
       nout << "  " << (i + 1) << ". "
-           << dirs[i]->get_path() + "/" + filename << "\n";
-      if (dirs[i] == suggested_dir) {
+           << paths[i].get_path() << "\n";
+      if (paths[i]._dir == suggested_dir) {
         any_suggested = true;
       }
     }
 
-    int next_option = dirs.size() + 1;
+    int next_option = paths.size() + 1;
     int suggested_option = -1;
 
     if (!any_suggested) {
+      // If it wasn't already in the suggested directory, offer to put
+      // it there.
       suggested_option = next_option;
       next_option++;
       nout << "\n" << suggested_option
            << ". create "
-           << suggested_dir->get_path() + "/" + filename
+           << Filename(suggested_dir->get_path(), basename)
            << "\n";
     }
 
@@ -387,19 +402,19 @@ ask_existing(const string &filename, const CVSSourceTree::Directories &dirs,
     nout << other_option << ". Other\n";
 
     string result = prompt("Choose an option: ");
-    nassertr(!result.empty(), (CVSSourceDirectory *)NULL);
+    nassertr(!result.empty(), FilePath());
     const char *nptr = result.c_str();
     char *endptr;
     int option = strtol(nptr, &endptr, 10);
     if (*endptr == '\0') {
-      if (option >= 1 && option <= (int)dirs.size()) {
-        return dirs[option - 1];
+      if (option >= 1 && option <= (int)paths.size()) {
+        return paths[option - 1];
 
       } else if (option == suggested_option) {
-        return suggested_dir;
+        return FilePath(suggested_dir, basename);
 
       } else if (option == other_option) {
-        return NULL;
+        return FilePath();
       }
     }
 
@@ -410,21 +425,20 @@ ask_existing(const string &filename, const CVSSourceTree::Directories &dirs,
 ////////////////////////////////////////////////////////////////////
 //     Function: CVSSourceTree::ask_new
 //       Access: Private
-//  Description: Asks the user if he wants to replace an existing
-//               file.
+//  Description: Asks the user if he wants to create a new file.
 ////////////////////////////////////////////////////////////////////
-CVSSourceDirectory *CVSSourceTree::
-ask_new(const string &filename, CVSSourceDirectory *dir) {
+CVSSourceTree::FilePath CVSSourceTree::
+ask_new(const string &basename, CVSSourceDirectory *dir) {
   while (true) {
-    nout << filename << " will be created in "
+    nout << basename << " will be created in "
          << dir->get_path() << ".\n";
     string result = prompt("Create this file (y/n)? ");
-    nassertr(!result.empty(), (CVSSourceDirectory *)NULL);
+    nassertr(!result.empty(), FilePath());
     if (result.size() == 1) {
       if (tolower(result[0]) == 'y') {
-        return dir;
+        return FilePath(dir, basename);
       } else if (tolower(result[0]) == 'n') {
-        return NULL;
+        return FilePath();
       }
     }
 
@@ -438,12 +452,13 @@ ask_new(const string &filename, CVSSourceDirectory *dir) {
 //  Description: Asks the user to type in the name of the directory in
 //               which to store the file.
 ////////////////////////////////////////////////////////////////////
-CVSSourceDirectory *CVSSourceTree::
-ask_any(const string &filename) {
+CVSSourceTree::FilePath CVSSourceTree::
+ask_any(const string &basename,
+        const CVSSourceTree::FilePaths &paths) {
   while (true) {
     string result =
-      prompt("Enter the name of the directory to copy " + filename + " to: ");
-    nassertr(!result.empty(), (CVSSourceDirectory *)NULL);
+      prompt("Enter the name of the directory to copy " + basename + " to: ");
+    nassertr(!result.empty(), FilePath());
 
     // The user might enter a fully-qualified path to the directory,
     // or a relative path from the root (with or without the root's
@@ -457,7 +472,18 @@ ask_any(const string &filename) {
     }
 
     if (dir != (CVSSourceDirectory *)NULL) {
-      return dir;
+      // If the file is already in this directory, we must preserve
+      // its existing case.
+      FilePaths::const_iterator pi;
+      for (pi = paths.begin(); pi != paths.end(); ++pi) {
+        if ((*pi)._dir == dir) {
+          return (*pi);
+        }
+      }
+
+      // Otherwise, since we're creating a new file, keep the original
+      // case.
+      return FilePath(dir, basename);
     }
 
     nout << "*** Not a valid directory name: " << result << "\n\n";
@@ -524,3 +550,75 @@ get_start_fullpath() {
   }
   return _start_fullpath;
 }
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: CVSSourceTree::FilePath::Constructor
+//       Access: Public
+//  Description: Creates an invalid FilePath specification.
+////////////////////////////////////////////////////////////////////
+CVSSourceTree::FilePath::
+FilePath() :
+  _dir(NULL)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CVSSourceTree::FilePath::Constructor
+//       Access: Public
+//  Description: Creates a valid FilePath specification with the
+//               indicated directory and basename.
+////////////////////////////////////////////////////////////////////
+CVSSourceTree::FilePath::
+FilePath(CVSSourceDirectory *dir, const string &basename) :
+  _dir(dir),
+  _basename(basename)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CVSSourceTree::FilePath::is_valid
+//       Access: Public
+//  Description: Returns true if this FilePath represents a valid
+//               file, or false if it represents an error return.
+////////////////////////////////////////////////////////////////////
+bool CVSSourceTree::FilePath::
+is_valid() const {
+  return (_dir != (CVSSourceDirectory *)NULL);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CVSSourceTree::FilePath::get_path
+//       Access: Public
+//  Description: Returns the relative path to this file from the root
+//               of the source tree.
+////////////////////////////////////////////////////////////////////
+Filename CVSSourceTree::FilePath::
+get_path() const {
+  nassertr(_dir != (CVSSourceDirectory *)NULL, Filename());
+  return Filename(_dir->get_path(), _basename);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CVSSourceTree::FilePath::get_fullpath
+//       Access: Public
+//  Description: Returns the full path to this file.
+////////////////////////////////////////////////////////////////////
+Filename CVSSourceTree::FilePath::
+get_fullpath() const {
+  nassertr(_dir != (CVSSourceDirectory *)NULL, Filename());
+  return Filename(_dir->get_fullpath(), _basename);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CVSSourceTree::FilePath::get_rel_from
+//       Access: Public
+//  Description: Returns the relative path to this file as seen from
+//               the indicated source directory.
+////////////////////////////////////////////////////////////////////
+Filename CVSSourceTree::FilePath::
+get_rel_from(const CVSSourceDirectory *other) const {
+  nassertr(_dir != (CVSSourceDirectory *)NULL, Filename());
+  return Filename(other->get_rel_to(_dir), _basename);
+}
+

+ 42 - 17
pandatool/src/cvscopy/cvsSourceTree.h

@@ -31,6 +31,14 @@ class CVSSourceDirectory;
 //       Class : CVSSourceTree
 // Description : This represents the root of the tree of source
 //               directory files.
+//
+//               The tree is maintained in a case-insensitive manner,
+//               even on a non-Windows system, since you might want to
+//               eventually check out the CVS tree onto a Windows
+//               system--and if you do, you'll be sad if there are
+//               case conflicts within the tree.  So we make an effort
+//               to ensure this doesn't happen by treating two files
+//               with a different case as the same file.
 ////////////////////////////////////////////////////////////////////
 class CVSSourceTree {
 public:
@@ -45,9 +53,28 @@ public:
   CVSSourceDirectory *find_relpath(const string &relpath);
   CVSSourceDirectory *find_dirname(const string &dirname);
 
-  CVSSourceDirectory *choose_directory(const Filename &filename,
-                                       CVSSourceDirectory *suggested_dir,
-                                       bool force, bool interactive);
+  // This nested class represents the selection of a particular
+  // directory in which to place a given file, given its basename.
+  // The basename of the file is returned as part of the answer,
+  // because it might have changed in case from the original basename
+  // (in order to match the case of an existing file in the selected
+  // directory).
+  class FilePath {
+  public:
+    FilePath();
+    FilePath(CVSSourceDirectory *dir, const string &basename);
+    bool is_valid() const;
+    Filename get_path() const;
+    Filename get_fullpath() const;
+    Filename get_rel_from(const CVSSourceDirectory *other) const;
+
+    CVSSourceDirectory *_dir;
+    string _basename;
+  };
+
+  FilePath choose_directory(const string &basename,
+                            CVSSourceDirectory *suggested_dir,
+                            bool force, bool interactive);
 
   Filename get_root_fullpath();
   Filename get_root_dirname() const;
@@ -56,22 +83,20 @@ public:
   static void restore_cwd();
 
 public:
-  void add_file(const Filename &filename, CVSSourceDirectory *dir);
+  void add_file(const string &basename, CVSSourceDirectory *dir);
 
 private:
-  typedef pvector<CVSSourceDirectory *> Directories;
+  typedef pvector<FilePath> FilePaths;
 
-  CVSSourceDirectory *
-  prompt_user(const string &filename, CVSSourceDirectory *suggested_dir,
-              const Directories &dirs, bool force, bool interactive);
+  FilePath
+  prompt_user(const string &basename, CVSSourceDirectory *suggested_dir,
+              const FilePaths &paths, bool force, bool interactive);
 
-  CVSSourceDirectory *ask_existing(const string &filename,
-                                   CVSSourceDirectory *dir);
-  CVSSourceDirectory *ask_existing(const string &filename,
-                                   const Directories &dirs,
-                                   CVSSourceDirectory *suggested_dir);
-  CVSSourceDirectory *ask_new(const string &filename, CVSSourceDirectory *dir);
-  CVSSourceDirectory *ask_any(const string &filename);
+  FilePath ask_existing(const string &filename, const FilePath &path);
+  FilePath ask_existing(const string &filename, const FilePaths &paths,
+                        CVSSourceDirectory *suggested_dir);
+  FilePath ask_new(const string &filename, CVSSourceDirectory *dir);
+  FilePath ask_any(const string &filename, const FilePaths &paths);
 
   string prompt(const string &message);
 
@@ -82,8 +107,8 @@ private:
   Filename _path;
   CVSSourceDirectory *_root;
 
-  typedef pmap<Filename, Directories> Filenames;
-  Filenames _filenames;
+  typedef pmap<string, FilePaths> Basenames;
+  Basenames _basenames;
 
   static bool _got_start_fullpath;
   static Filename _start_fullpath;

+ 8 - 10
pandatool/src/fltprogs/fltCopy.cxx

@@ -61,8 +61,8 @@ run() {
     ExtraData ed;
     ed._type = FT_flt;
 
-    CVSSourceDirectory *dest = import(*fi, &ed, _model_dir);
-    if (dest == (CVSSourceDirectory *)NULL) {
+    CVSSourceTree::FilePath dest = import(*fi, &ed, _model_dir);
+    if (!dest.is_valid()) {
       exit(1);
     }
   }
@@ -131,16 +131,15 @@ copy_flt_file(const Filename &source, const Filename &dest,
       ExtraData ed;
       ed._type = FT_flt;
 
-      CVSSourceDirectory *ref_dir =
+      CVSSourceTree::FilePath ref_path =
         import(ref_filename, &ed, _model_dir);
-      if (ref_dir == (CVSSourceDirectory *)NULL) {
+      if (!ref_path.is_valid()) {
         return false;
       }
 
       // Update the reference to point to the new flt filename, relative
       // to the base flt file.
-      ref->set_ref_filename(dir->get_rel_to(ref_dir) + "/" +
-			    ref_filename.get_basename());
+      ref->set_ref_filename(ref_path.get_rel_from(dir));
     }
   }
 
@@ -162,16 +161,15 @@ copy_flt_file(const Filename &source, const Filename &dest,
       ed._type = FT_texture;
       ed._texture = tex;
 
-      CVSSourceDirectory *texture_dir =
+      CVSSourceTree::FilePath texture_path =
         import(texture_filename, &ed, _map_dir);
-      if (texture_dir == (CVSSourceDirectory *)NULL) {
+      if (!texture_path.is_valid()) {
         return false;
       }
 
       // Update the texture reference to point to the new texture
       // filename, relative to the flt file.
-      tex->set_texture_filename(dir->get_rel_to(texture_dir) + "/" +
-				texture_filename.get_basename());
+      tex->set_texture_filename(texture_path.get_rel_from(dir));
       header->add_texture(tex);
     }
   }

+ 8 - 8
pandatool/src/mayaprogs/mayaCopy.cxx

@@ -82,8 +82,8 @@ run() {
     ExtraData ed;
     ed._type = FT_maya;
 
-    CVSSourceDirectory *dest = import(*fi, &ed, _model_dir);
-    if (dest == (CVSSourceDirectory *)NULL) {
+    CVSSourceTree::FilePath path = import(*fi, &ed, _model_dir);
+    if (!path.is_valid()) {
       nout << "\nUnable to copy, aborting!\n\n";
       exit(1);
     }
@@ -205,8 +205,8 @@ copy_maya_file(const Filename &source, const Filename &dest,
     ExtraData ed;
     ed._type = FT_maya;
 
-    CVSSourceDirectory *dest = import(filename, &ed, _model_dir);
-    if (dest == (CVSSourceDirectory *)NULL) {
+    CVSSourceTree::FilePath path = import(filename, &ed, _model_dir);
+    if (!path.is_valid()) {
       exit(1);
     }
     */
@@ -238,16 +238,16 @@ extract_texture(MayaShaderColorDef &color_def, CVSSourceDirectory *dir) {
       ExtraData ed;
       ed._type = FT_texture;
       
-      CVSSourceDirectory *texture_dir =
+      CVSSourceTree::FilePath texture_path =
         import(texture_filename, &ed, _map_dir);
-      if (texture_dir == (CVSSourceDirectory *)NULL) {
+
+      if (!texture_path.is_valid()) {
         return false;
       }
       
       // Update the texture reference to point to the new texture
       // filename, relative to the maya file.
-      Filename new_filename = dir->get_rel_to(texture_dir) + "/" +
-        filter_filename(texture_filename.get_basename());
+      Filename new_filename = texture_path.get_rel_from(dir);
       color_def.reset_maya_texture(new_filename);
     }
   }