//===-- Path.cpp - Implement OS Path Concept --------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This header file implements the operating system Path concept.
//
//===----------------------------------------------------------------------===//

#include "llvm/System/Path.h"
#include "llvm/Config/config.h"
#include <cassert>
#include <cstring>
#include <ostream>
using namespace llvm;
using namespace sys;

//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only TRULY operating system
//===          independent code.
//===----------------------------------------------------------------------===//

bool Path::operator==(const Path &that) const {
  return path == that.path;
}

bool Path::operator<(const Path& that) const {
  return path < that.path;
}

Path
Path::GetLLVMConfigDir() {
  Path result;
#ifdef LLVM_ETCDIR
  if (result.set(LLVM_ETCDIR))
    return result;
#endif
  return GetLLVMDefaultConfigDir();
}

LLVMFileType
sys::IdentifyFileType(const char *magic, unsigned length) {
  assert(magic && "Invalid magic number string");
  assert(length >=4 && "Invalid magic number length");
  switch ((unsigned char)magic[0]) {
    case 0xDE:  // 0x0B17C0DE = BC wraper
      if (magic[1] == (char)0xC0 && magic[2] == (char)0x17 &&
          magic[3] == (char)0x0B)
        return Bitcode_FileType;
      break;
    case 'B':
      if (magic[1] == 'C' && magic[2] == (char)0xC0 && magic[3] == (char)0xDE)
        return Bitcode_FileType;
      break;
    case '!':
      if (length >= 8)
        if (memcmp(magic,"!<arch>\n",8) == 0)
          return Archive_FileType;
      break;
      
    case '\177':
      if (magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') {
        if (length >= 18 && magic[17] == 0)
          switch (magic[16]) {
            default: break;
            case 1: return ELF_Relocatable_FileType;
            case 2: return ELF_Executable_FileType;
            case 3: return ELF_SharedObject_FileType;
            case 4: return ELF_Core_FileType;
          }
      }
      break;

    case 0xCA:
      if (magic[1] == char(0xFE) && magic[2] == char(0xBA) && 
          magic[3] == char(0xBE)) {
        // This is complicated by an overlap with Java class files. 
        // See the Mach-O section in /usr/share/file/magic for details.
        if (length >= 8 && magic[7] < 43) 
          // FIXME: Universal Binary of any type.
          return Mach_O_DynamicallyLinkedSharedLib_FileType;
      }
      break;

    case 0xFE:
    case 0xCE: {
      uint16_t type = 0;
      if (magic[0] == char(0xFE) && magic[1] == char(0xED) && 
          magic[2] == char(0xFA) && magic[3] == char(0xCE)) {
        /* Native endian */
        if (length >= 16) type = magic[14] << 8 | magic[15];
      } else if (magic[0] == char(0xCE) && magic[1] == char(0xFA) && 
                 magic[2] == char(0xED) && magic[3] == char(0xFE)) {
        /* Reverse endian */
        if (length >= 14) type = magic[13] << 8 | magic[12];
      }
      switch (type) {
        default: break;      
        case 1: return Mach_O_Object_FileType; 
        case 2: return Mach_O_Executable_FileType;
        case 3: return Mach_O_FixedVirtualMemorySharedLib_FileType;
        case 4: return Mach_O_Core_FileType;
        case 5: return Mach_O_PreloadExectuable_FileType;
        case 6: return Mach_O_DynamicallyLinkedSharedLib_FileType;
        case 7: return Mach_O_DynamicLinker_FileType;
        case 8: return Mach_O_Bundle_FileType;
        case 9: return Mach_O_DynamicallyLinkedSharedLibStub_FileType;
        case 10: break; // FIXME: MH_DSYM companion file with only debug.
      }
      break;
    }
    case 0xF0: // PowerPC Windows
    case 0x83: // Alpha 32-bit
    case 0x84: // Alpha 64-bit
    case 0x66: // MPS R4000 Windows
    case 0x50: // mc68K
    case 0x4c: // 80386 Windows
      if (magic[1] == 0x01)
        return COFF_FileType;

    case 0x90: // PA-RISC Windows
    case 0x68: // mc68K Windows
      if (magic[1] == 0x02)
        return COFF_FileType;
      break;

    default:
      break;
  }
  return Unknown_FileType;
}

bool
Path::isArchive() const {
  if (canRead())
    return hasMagicNumber("!<arch>\012");
  return false;
}

bool
Path::isDynamicLibrary() const {
  if (canRead()) {
    std::string Magic;
    if (getMagicNumber(Magic, 64))
      switch (IdentifyFileType(Magic.c_str(),
                               static_cast<unsigned>(Magic.length()))) {
        default: return false;
        case Mach_O_FixedVirtualMemorySharedLib_FileType:
        case Mach_O_DynamicallyLinkedSharedLib_FileType:
        case Mach_O_DynamicallyLinkedSharedLibStub_FileType:
        case ELF_SharedObject_FileType:
        case COFF_FileType:  return true;
      }
  }
  return false;
}

Path
Path::FindLibrary(std::string& name) {
  std::vector<sys::Path> LibPaths;
  GetSystemLibraryPaths(LibPaths);
  for (unsigned i = 0; i < LibPaths.size(); ++i) {
    sys::Path FullPath(LibPaths[i]);
    FullPath.appendComponent("lib" + name + LTDL_SHLIB_EXT);
    if (FullPath.isDynamicLibrary())
      return FullPath;
    FullPath.eraseSuffix();
    FullPath.appendSuffix("a");
    if (FullPath.isArchive())
      return FullPath;
  }
  return sys::Path();
}

StringRef Path::GetDLLSuffix() {
  return LTDL_SHLIB_EXT;
}

bool
Path::isBitcodeFile() const {
  std::string actualMagic;
  if (!getMagicNumber(actualMagic, 4))
    return false;
  LLVMFileType FT =
    IdentifyFileType(actualMagic.c_str(),
                     static_cast<unsigned>(actualMagic.length()));
  return FT == Bitcode_FileType;
}

bool Path::hasMagicNumber(StringRef Magic) const {
  std::string actualMagic;
  if (getMagicNumber(actualMagic, static_cast<unsigned>(Magic.size())))
    return Magic == actualMagic;
  return false;
}

static void getPathList(const char*path, std::vector<Path>& Paths) {
  const char* at = path;
  const char* delim = strchr(at, PathSeparator);
  Path tmpPath;
  while (delim != 0) {
    std::string tmp(at, size_t(delim-at));
    if (tmpPath.set(tmp))
      if (tmpPath.canRead())
        Paths.push_back(tmpPath);
    at = delim + 1;
    delim = strchr(at, PathSeparator);
  }

  if (*at != 0)
    if (tmpPath.set(std::string(at)))
      if (tmpPath.canRead())
        Paths.push_back(tmpPath);
}

static StringRef getDirnameCharSep(StringRef path, const char *Sep) {
  assert(Sep[0] != '\0' && Sep[1] == '\0' &&
         "Sep must be a 1-character string literal.");
  if (path.empty())
    return ".";
  
  // If the path is all slashes, return a single slash.
  // Otherwise, remove all trailing slashes.
  
  signed pos = static_cast<signed>(path.size()) - 1;
  
  while (pos >= 0 && path[pos] == Sep[0])
    --pos;
  
  if (pos < 0)
    return path[0] == Sep[0] ? Sep : ".";
  
  // Any slashes left?
  signed i = 0;
  
  while (i < pos && path[i] != Sep[0])
    ++i;
  
  if (i == pos) // No slashes?  Return "."
    return ".";
  
  // There is at least one slash left.  Remove all trailing non-slashes.  
  while (pos >= 0 && path[pos] != Sep[0])
    --pos;
  
  // Remove any trailing slashes.
  while (pos >= 0 && path[pos] == Sep[0])
    --pos;
  
  if (pos < 0)
    return path[0] == Sep[0] ? Sep : ".";
  
  return path.substr(0, pos+1);
}

// Include the truly platform-specific parts of this class.
#if defined(LLVM_ON_UNIX)
#include "Unix/Path.inc"
#endif
#if defined(LLVM_ON_WIN32)
#include "Win32/Path.inc"
#endif

