Forráskód Böngészése

*** empty log message ***

David Rose 25 éve
szülő
commit
4ec063c088

+ 38 - 0
dtool/src/dtoolutil/executionEnvironment.cxx

@@ -6,6 +6,14 @@
 #include "executionEnvironment.h"
 #include <assert.h>
 
+#ifdef WIN32_VC
+// Windows requires this for getcwd().
+#include <direct.h>
+#define getcwd _getcwd
+#endif
+
+#include <errno.h>
+
 // We define the symbol PREREAD_ENVIRONMENT if we cannot rely on
 // getenv() to read environment variables at static init time.  In
 // this case, we must read all of the environment variables directly
@@ -44,6 +52,36 @@ ExecutionEnvironment() {
   read_args();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: ExecutionEnviroment::get_cwd
+//       Access: Public, Static
+//  Description: Returns the name of the current working directory.
+////////////////////////////////////////////////////////////////////
+string ExecutionEnvironment::
+get_cwd() {
+  // getcwd() requires us to allocate a dynamic buffer and grow it on
+  // demand.
+  static size_t bufsize = 1024;
+  static char *buffer = NULL;
+
+  if (buffer == (char *)NULL) {
+    buffer = new char[bufsize];
+  }
+
+  while (getcwd(buffer, bufsize) == (char *)NULL) {
+    if (errno != ERANGE) {
+      perror("getcwd");
+      return string();
+    }
+    delete[] buffer;
+    bufsize = bufsize * 2;
+    buffer = new char[bufsize];
+    assert(buffer != (char *)NULL);
+  }
+
+  return string(buffer);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: ExecutionEnvironment::ns_has_environment_variable
 //       Access: Private

+ 2 - 0
dtool/src/dtoolutil/executionEnvironment.h

@@ -33,6 +33,8 @@ public:
   
   INLINE static string get_binary_name();
 
+  static string get_cwd();
+
 private:
   bool ns_has_environment_variable(const string &var) const;
   string ns_get_environment_variable(const string &var) const;

+ 113 - 21
dtool/src/dtoolutil/filename.cxx

@@ -32,6 +32,31 @@
 
 #include <direct.h>
 
+static const string & 
+get_panda_root() {
+  static string panda_root;
+  static bool got_panda_root = false;
+  
+  if (!got_panda_root) {
+    const char *envvar = getenv("PANDA_ROOT");
+    if (envvar == (const char *)NULL) {
+      envvar = getenv("CYGWIN_ROOT");
+    }
+    
+    if (envvar != (const char *)NULL) {
+      panda_root = front_to_back_slash(envvar);
+    }
+    
+    if (!panda_root.empty() && panda_root[panda_root.length() - 1] != '\\') {
+      panda_root += '\\';
+    }
+    
+    got_panda_root = true;
+  }
+
+  return panda_root;
+}
+
 static string
 front_to_back_slash(const string &str) {
   string result = str;
@@ -45,6 +70,19 @@ front_to_back_slash(const string &str) {
   return result;
 }
 
+static string
+back_to_front_slash(const string &str) {
+  string result = str;
+  string::iterator si;
+  for (si = result.begin(); si != result.end(); ++si) {
+    if ((*si) == '\\') {
+      (*si) = '/';
+    }
+  }
+
+  return result;
+}
+
 static string
 convert_pathname(const string &unix_style_pathname) {
   if (unix_style_pathname.empty()) {
@@ -82,27 +120,9 @@ convert_pathname(const string &unix_style_pathname) {
 
   } else {
     // It does not begin with a single letter, so prefix "PANDA_ROOT".
-    static string panda_root;
-    static bool got_panda_root = false;
-
-    if (!got_panda_root) {
-      const char *envvar = getenv("PANDA_ROOT");
-      if (envvar == (const char *)NULL) {
-	envvar = getenv("CYGWIN_ROOT");
-      }
-
-      if (envvar != (const char *)NULL) {
-	panda_root = front_to_back_slash(envvar);
-      }
-
-      if (!panda_root.empty() && panda_root[panda_root.length() - 1] != '\\') {
-	panda_root += '\\';
-      }
-
-      got_panda_root = true;
-    }
-
-    windows_pathname = panda_root + front_to_back_slash(unix_style_pathname);
+    
+    windows_pathname = 
+      get_panda_root() + front_to_back_slash(unix_style_pathname);
   }
 
   return windows_pathname;
@@ -179,6 +199,78 @@ Filename(const Filename &dirname, const Filename &basename) {
   _flags = 0;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Filename::from_os_specific
+//       Access: Public, Static
+//  Description: This named constructor returns a Panda-style filename
+//               (that is, using forward slashes, and no drive letter)
+//               based on the supplied filename string that describes
+//               a filename in the local system conventions (for
+//               instance, on Windows, it may use backslashes or begin
+//               with a drive letter and a colon).
+//
+//               Use this function to create a Filename from an
+//               externally-given filename string.  Use
+//               to_os_specific() again later to reconvert it back to
+//               the local operating system's conventions.
+//
+//               This function will do the right thing even if the
+//               filename is partially local conventions and partially
+//               Panda conventions; e.g. some backslashes and some
+//               forward slashes.
+////////////////////////////////////////////////////////////////////
+Filename Filename::
+from_os_specific(const string &os_specific, Filename::Type type) {
+#if defined(WIN32)
+  string result = back_to_front_slash(os_specific);
+  const string &panda_root = get_panda_root();
+
+  // If the initial prefix is the same as panda_root, remove it.
+  if (!panda_root.empty() && panda_root.length() < result.length()) {
+    bool matches = true;
+    size_t p;
+    for (p = 0; p < panda_root.length() && matches; p++) {
+      char c = tolower(panda_root[p]);
+      if (c == '\\') {
+	c = '/';
+      }
+      matches = (c == tolower(result[p]));
+    }
+    
+    if (matches) {
+      // The initial prefix matches!  Replace the initial bit with a
+      // leading slash.
+      result = result.substr(panda_root.length());
+      assert(!result.empty());
+      if (result[0] != '/') {
+	result = '/' + result;
+      }
+      Filename filename(result);
+      filename.set_type(type);
+      return filename;
+    }
+  }
+
+  // All right, the initial prefix was not under panda_root.  But
+  // maybe it begins with a drive letter.
+  if (result.size() >= 3 && isalpha(result[0]) &&
+      result[1] == ':' && result[2] == '/') {
+    result[1] = tolower(result[0]);
+    result[0] = '/';
+  }
+
+  Filename filename(result);
+  filename.set_type(type);
+  return filename;
+
+#else
+  // Generic Unix-style filenames--no conversion necessary.
+  Filename filename(os_specific);
+  filename.set_type(type);
+  return filename;
+#endif
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Filename::set_fullpath
 //       Access: Public

+ 3 - 0
dtool/src/dtoolutil/filename.h

@@ -68,6 +68,9 @@ public:
   INLINE static Filename dso_filename(const string &filename);
   INLINE static Filename executable_filename(const string &filename);
 
+  static Filename from_os_specific(const string &os_specific, 
+				   Type type = T_general);
+
   // Assignment is via the = operator.
   INLINE Filename &operator = (const string &filename);
   INLINE Filename &operator = (const char *filename);