Преглед изворни кода

support windows share names like \\myhost\myfile

David Rose пре 21 година
родитељ
комит
871351c82d
1 измењених фајлова са 35 додато и 0 уклоњено
  1. 35 0
      dtool/src/dtoolutil/filename.cxx

+ 35 - 0
dtool/src/dtoolutil/filename.cxx

@@ -75,6 +75,28 @@ extern "C" void cygwin_conv_to_win32_path(const char *path, char *win32);
 extern "C" void cygwin_conv_to_posix_path(const char *path, char *posix);
 extern "C" void cygwin_conv_to_posix_path(const char *path, char *posix);
 #endif
 #endif
 
 
+// Windows uses the convention \\hostname\path\to\file to represent a
+// pathname to a file on another share.  This redefines a pathname to
+// be something more complicated than a sequence of directory names
+// separated by slashes.  The Unix convention to represent the same
+// thing is, like everything else, to graft the reference to the
+// remote hostname into the one global filesystem, with something like
+// /hosts/hostname/path/to/file.  We observe the Unix convention for
+// internal names used in Panda; this makes operations like
+// Filename::get_dirname() simpler and more internally consistent.
+
+// This string hard-defines the prefix that we use internally to
+// indicate that the next directory component name should be treated
+// as a hostname.  It might be nice to use a ConfigVariable for this,
+// except that we haven't defined ConfigVariable by this point (and
+// indeed we can't, since we need to have a Filename class already
+// created in order to read the first config file).  Windows purists
+// might be tempted to define this to a double slash so that internal
+// Panda filenames more closely resemble their Windows counterparts.
+// That might actually work, but it will cause problems with
+// Filename::standardize().
+static const string hosts_prefix = "/hosts/";
+
 static string
 static string
 front_to_back_slash(const string &str) {
 front_to_back_slash(const string &str) {
   string result = str;
   string result = str;
@@ -177,6 +199,15 @@ convert_pathname(const string &unix_style_pathname, bool use_backslash) {
     windows_pathname =
     windows_pathname =
       string(1, (char)toupper(unix_style_pathname[1])) + ":" + remainder;
       string(1, (char)toupper(unix_style_pathname[1])) + ":" + remainder;
 
 
+  } else if (unix_style_pathname.length() > hosts_prefix.length() &&
+             unix_style_pathname.substr(0, hosts_prefix.length()) == hosts_prefix) {
+    // A filename like /hosts/fooby gets turned into \\fooby.
+    if (use_backslash) {
+      windows_pathname = "\\\\" + front_to_back_slash(unix_style_pathname.substr(hosts_prefix.length()));
+    } else {
+      windows_pathname = "//" + unix_style_pathname.substr(hosts_prefix.length());
+    }
+    
   } else {
   } else {
     // It starts with a slash, but the first part is not a single
     // It starts with a slash, but the first part is not a single
     // letter.
     // letter.
@@ -342,6 +373,10 @@ from_os_specific(const string &os_specific, Filename::Type type) {
     if (result.size() == 3) {
     if (result.size() == 3) {
       result = result.substr(0, 2);
       result = result.substr(0, 2);
     }
     }
+
+  } else if (result.substr(0, 2) == "//") {
+    // If the initial prefix is a double slash, convert it to /hosts/.
+    result = hosts_prefix + result.substr(2);
   }
   }
 
 
   Filename filename(result);
   Filename filename(result);