Fix error in the Win32 implementation pointed out by Howard Su.
[oota-llvm.git] / lib / System / Win32 / Path.inc
index 35bae337da7f5e0f1f5bed3595c3654ffdc9ddb3..683c94bba44eea5a40303ba549a8095c197fb787 100644 (file)
@@ -1,4 +1,4 @@
-//===- llvm/System/Linux/Path.cpp - Linux Path Implementation ---*- C++ -*-===//
+//===- llvm/System/Win32/Path.cpp - Win32 Path Implementation ---*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -21,6 +21,7 @@
 
 #include "Win32.h"
 #include <malloc.h>
+#include <cstdio>
 
 // We need to undo a macro defined in Windows.h, otherwise we won't compile:
 #undef CopyFile
@@ -46,6 +47,23 @@ namespace llvm {
 namespace sys {
 const char PathSeparator = ';';
 
+Path::Path(const std::string& p)
+  : path(p) {
+  FlipBackSlashes(path);
+}
+
+Path::Path(const char *StrStart, unsigned StrLen)
+  : path(StrStart, StrLen) {
+  FlipBackSlashes(path);
+}
+
+Path&
+Path::operator=(const std::string &that) {
+  path = that;
+  FlipBackSlashes(path);
+  return *this;
+}
+
 bool
 Path::isValid() const {
   if (path.empty())
@@ -107,6 +125,20 @@ Path::isValid() const {
   return true;
 }
 
+bool
+Path::isAbsolute(const char *NameStart, unsigned NameLen) {
+  assert(NameStart);
+  switch (NameLen) {
+  case 0:
+    return false;
+  case 1:
+  case 2:
+    return NameStart[0] == '/';
+  default:
+    return NameStart[0] == '/' || (NameStart[1] == ':' && NameStart[2] == '/');
+  }
+}
+
 bool 
 Path::isAbsolute() const {
   switch (path.length()) {
@@ -216,7 +248,9 @@ Path::GetCurrentDirectory() {
 /// GetMainExecutable - Return the path to the main executable, given the
 /// value of argv[0] from program startup.
 Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
-  return Path();
+  char pathname[MAX_PATH];
+  DWORD ret = ::GetModuleFileNameA(NULL, pathname, MAX_PATH);
+  return ret != MAX_PATH ? Path(pathname) : Path();
 }
 
 
@@ -229,7 +263,9 @@ Path::isRootDirectory() const {
   return len > 0 && path[len-1] == '/';
 }
 
-std::string Path::getDirname() const { return getDirnameCharSep('\\'); }
+std::string Path::getDirname() const {
+  return getDirnameCharSep(path, '/');
+}
 
 std::string
 Path::getBasename() const {
@@ -247,6 +283,22 @@ Path::getBasename() const {
     return path.substr(slash, dot - slash);
 }
 
+std::string
+Path::getSuffix() const {
+  // Find the last slash
+  size_t slash = path.rfind('/');
+  if (slash == std::string::npos)
+    slash = 0;
+  else
+    slash++;
+
+  size_t dot = path.rfind('.');
+  if (dot == std::string::npos || dot < slash)
+    return std::string();
+  else
+    return path.substr(dot + 1);
+}
+
 bool
 Path::exists() const {
   DWORD attr = GetFileAttributes(path.c_str());
@@ -670,7 +722,7 @@ Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
   if (!MoveFileEx(path.c_str(), newName.c_str(), MOVEFILE_REPLACE_EXISTING))
     return MakeErrMsg(ErrMsg, "Can't move '" + path + "' to '" + newName.path 
         + "': ");
-  return true;
+  return false;
 }
 
 bool